field switch
This commit is contained in:
parent
a9177116aa
commit
428beabd5a
@ -51,6 +51,7 @@ import {
|
|||||||
createCollectionField,
|
createCollectionField,
|
||||||
createOrUpdateCollection,
|
createOrUpdateCollection,
|
||||||
createSchema,
|
createSchema,
|
||||||
|
removeSchema,
|
||||||
request,
|
request,
|
||||||
useCollectionContext,
|
useCollectionContext,
|
||||||
useDesignable,
|
useDesignable,
|
||||||
@ -58,7 +59,7 @@ import {
|
|||||||
} from '../';
|
} from '../';
|
||||||
import { uid } from '@formily/shared';
|
import { uid } from '@formily/shared';
|
||||||
import { useRequest } from 'ahooks';
|
import { useRequest } from 'ahooks';
|
||||||
import { SchemaField } from '../../components/schema-renderer';
|
import { getSchemaPath, SchemaField } from '../../components/schema-renderer';
|
||||||
import { useResourceContext } from '../';
|
import { useResourceContext } from '../';
|
||||||
import { cloneDeep } from 'lodash';
|
import { cloneDeep } from 'lodash';
|
||||||
import { options } from '../database-field/interfaces';
|
import { options } from '../database-field/interfaces';
|
||||||
@ -67,6 +68,7 @@ import { useDisplayFieldsContext } from '../form';
|
|||||||
import './style.less';
|
import './style.less';
|
||||||
import IconPicker from '../../components/icon-picker';
|
import IconPicker from '../../components/icon-picker';
|
||||||
import { barChartConfig, columnChartConfig } from './chart';
|
import { barChartConfig, columnChartConfig } from './chart';
|
||||||
|
import { isGridRowOrCol } from '../grid';
|
||||||
|
|
||||||
const generateGridBlock = (schema: ISchema) => {
|
const generateGridBlock = (schema: ISchema) => {
|
||||||
const name = schema.name || uid();
|
const name = schema.name || uid();
|
||||||
@ -659,9 +661,12 @@ AddNew.BlockItem = observer((props: any) => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
function FieldSwitch({ field, onChange, defaultChecked }) {
|
function SwitchField(props) {
|
||||||
const [checked, setChecked] = useState(defaultChecked);
|
const { field, onChange } = props;
|
||||||
const form = useForm();
|
const [checked, setChecked] = useState(props.checked);
|
||||||
|
useEffect(() => {
|
||||||
|
setChecked(props.checked);
|
||||||
|
}, [props.checked]);
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@ -669,35 +674,32 @@ function FieldSwitch({ field, onChange, defaultChecked }) {
|
|||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
}}
|
}}
|
||||||
onClick={(e) => {
|
onClick={async () => {
|
||||||
setChecked((value) => {
|
setChecked((checked) => {
|
||||||
onChange && onChange(!value);
|
onChange(!checked);
|
||||||
return !value;
|
return !checked;
|
||||||
});
|
});
|
||||||
console.log('FieldSwitch', form);
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span>{field?.uiSchema?.title || '未命名'}</span>
|
<span>{field.uiSchema.title}</span>
|
||||||
<Switch
|
<Switch checked={checked} size={'small'} />
|
||||||
onChange={(checked, e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
setChecked(checked);
|
|
||||||
onChange && onChange(checked);
|
|
||||||
}}
|
|
||||||
size={'small'}
|
|
||||||
checked={checked}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddNew.FormItem = observer((props: any) => {
|
AddNew.FormItem = observer((props: any) => {
|
||||||
const { ghost, defaultAction } = props;
|
const { ghost, defaultAction } = props;
|
||||||
const { schema, insertBefore, insertAfter, appendChild } = useDesignable();
|
const { schema, insertBefore, insertAfter, appendChild, deepRemove } =
|
||||||
|
useDesignable();
|
||||||
const path = useSchemaPath();
|
const path = useSchemaPath();
|
||||||
const { resource = {}, refresh } = useResourceContext();
|
const { resource = {}, refresh } = useResourceContext();
|
||||||
const [visible, setVisible] = useState(false);
|
const [visible, setVisible] = useState(false);
|
||||||
const { displayFields = [] } = useDisplayFieldsContext();
|
const {
|
||||||
|
displayFields,
|
||||||
|
hasDisplayField,
|
||||||
|
getDisplayField,
|
||||||
|
removeDisplayField,
|
||||||
|
} = useDisplayFieldsContext();
|
||||||
console.log({ displayFields });
|
console.log({ displayFields });
|
||||||
return (
|
return (
|
||||||
<Dropdown
|
<Dropdown
|
||||||
@ -713,11 +715,23 @@ AddNew.FormItem = observer((props: any) => {
|
|||||||
<Menu.ItemGroup className={'display-fields'} title={`要展示的字段`}>
|
<Menu.ItemGroup className={'display-fields'} title={`要展示的字段`}>
|
||||||
{resource?.fields?.map((field) => (
|
{resource?.fields?.map((field) => (
|
||||||
<Menu.Item key={field.key}>
|
<Menu.Item key={field.key}>
|
||||||
<FieldSwitch
|
<SwitchField
|
||||||
field={field}
|
field={field}
|
||||||
defaultChecked={displayFields.includes(field.name)}
|
checked={hasDisplayField(field.name)}
|
||||||
onChange={async (checked) => {
|
onChange={async (checked) => {
|
||||||
if (!checked) {
|
if (!checked) {
|
||||||
|
const s: any = getDisplayField(field.name);
|
||||||
|
const p = getSchemaPath(s);
|
||||||
|
const removed = deepRemove(p);
|
||||||
|
if (!removed) {
|
||||||
|
console.log('getSchemaPath', p, removed);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const last = removed.pop();
|
||||||
|
removeDisplayField(field.name);
|
||||||
|
if (isGridRowOrCol(last)) {
|
||||||
|
await removeSchema(last);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let data: ISchema = {
|
let data: ISchema = {
|
||||||
@ -869,7 +883,7 @@ AddNew.PaneItem = observer((props: any) => {
|
|||||||
const path = useSchemaPath();
|
const path = useSchemaPath();
|
||||||
const { resource = {}, refresh } = useResourceContext();
|
const { resource = {}, refresh } = useResourceContext();
|
||||||
const [visible, setVisible] = useState(false);
|
const [visible, setVisible] = useState(false);
|
||||||
const { displayFields = [] } = useDisplayFieldsContext();
|
const { displayFields } = useDisplayFieldsContext();
|
||||||
console.log({ displayFields });
|
console.log({ displayFields });
|
||||||
return (
|
return (
|
||||||
<Dropdown
|
<Dropdown
|
||||||
@ -978,8 +992,15 @@ AddNew.PaneItem = observer((props: any) => {
|
|||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
</Menu.ItemGroup>
|
</Menu.ItemGroup>
|
||||||
<Menu.ItemGroup title={'相关数据区块'}>
|
<Menu.ItemGroup title={'相关数据区块'}>
|
||||||
<Menu.Item style={{ minWidth: 150 }} icon={<IconPicker type={'HistoryOutlined'} />}>日志</Menu.Item>
|
<Menu.Item
|
||||||
<Menu.Item icon={<IconPicker type={'CommentOutlined'} />}>评论</Menu.Item>
|
style={{ minWidth: 150 }}
|
||||||
|
icon={<IconPicker type={'HistoryOutlined'} />}
|
||||||
|
>
|
||||||
|
日志
|
||||||
|
</Menu.Item>
|
||||||
|
<Menu.Item icon={<IconPicker type={'CommentOutlined'} />}>
|
||||||
|
评论
|
||||||
|
</Menu.Item>
|
||||||
</Menu.ItemGroup>
|
</Menu.ItemGroup>
|
||||||
<Menu.ItemGroup title={'多媒体区块'}>
|
<Menu.ItemGroup title={'多媒体区块'}>
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
|
@ -8,3 +8,4 @@ group:
|
|||||||
title: Schemas
|
title: Schemas
|
||||||
path: /client/schemas
|
path: /client/schemas
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ import constate from 'constate';
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { uid } from '@formily/shared';
|
import { uid } from '@formily/shared';
|
||||||
import { getSchemaPath } from '../../components/schema-renderer';
|
import { getSchemaPath } from '../../components/schema-renderer';
|
||||||
import { FormFieldUIDContext } from '.';
|
import { FormFieldUIDContext, useDisplayFieldsContext } from '.';
|
||||||
|
|
||||||
export const FieldDesignableBar = observer((props) => {
|
export const FieldDesignableBar = observer((props) => {
|
||||||
const field = useField();
|
const field = useField();
|
||||||
@ -42,6 +42,7 @@ export const FieldDesignableBar = observer((props) => {
|
|||||||
const [visible, setVisible] = useState(false);
|
const [visible, setVisible] = useState(false);
|
||||||
const { dragRef } = useContext(DraggableBlockContext);
|
const { dragRef } = useContext(DraggableBlockContext);
|
||||||
const fieldUid = useContext(FormFieldUIDContext);
|
const fieldUid = useContext(FormFieldUIDContext);
|
||||||
|
const { removeDisplayField } = useDisplayFieldsContext();
|
||||||
const fieldName = schema['x-component-props']?.['fieldName'];
|
const fieldName = schema['x-component-props']?.['fieldName'];
|
||||||
if (!designable) {
|
if (!designable) {
|
||||||
return null;
|
return null;
|
||||||
@ -93,8 +94,11 @@ export const FieldDesignableBar = observer((props) => {
|
|||||||
key={'delete'}
|
key={'delete'}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
const removed = deepRemove();
|
const removed = deepRemove();
|
||||||
console.log({ schema, removed });
|
const fieldName =
|
||||||
|
schema['x-component-props']?.['fieldName'];
|
||||||
|
console.log({ schema, removed, fieldName });
|
||||||
const last = removed.pop();
|
const last = removed.pop();
|
||||||
|
removeDisplayField(fieldName);
|
||||||
if (isGridRowOrCol(last)) {
|
if (isGridRowOrCol(last)) {
|
||||||
await removeSchema(last);
|
await removeSchema(last);
|
||||||
}
|
}
|
||||||
|
@ -39,15 +39,24 @@ import { FieldDesignableBar } from './Field.DesignableBar';
|
|||||||
import { createContext } from 'react';
|
import { createContext } from 'react';
|
||||||
import { BlockItem } from '../block-item';
|
import { BlockItem } from '../block-item';
|
||||||
import { Resource } from '../../resource';
|
import { Resource } from '../../resource';
|
||||||
|
import { useMap } from 'ahooks';
|
||||||
|
|
||||||
const [DisplayFieldsContextProvider, useDisplayFieldsContext] = constate(() => {
|
const [DisplayFieldsContextProvider, useDisplayFieldsContext] = constate(() => {
|
||||||
const [displayFields, setDisplayFields] = useState([]);
|
const [displayFields, { set, remove, get }] = useMap([]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
displayFields,
|
displayFields,
|
||||||
setDisplayFields,
|
hasDisplayField(fieldName) {
|
||||||
addDisplayField(fieldName) {
|
return !!get(fieldName);
|
||||||
setDisplayFields((fields) => fields.concat(fieldName));
|
},
|
||||||
|
addDisplayField(fieldName, schema) {
|
||||||
|
set(fieldName, schema);
|
||||||
|
},
|
||||||
|
getDisplayField(fieldName) {
|
||||||
|
return get(fieldName);
|
||||||
|
},
|
||||||
|
removeDisplayField(fieldName) {
|
||||||
|
remove(fieldName);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@ -65,7 +74,10 @@ export const Form: any = observer((props: any) => {
|
|||||||
const initialValues = useValues();
|
const initialValues = useValues();
|
||||||
const form = useMemo(() => {
|
const form = useMemo(() => {
|
||||||
console.log('Form.useMemo', initialValues);
|
console.log('Form.useMemo', initialValues);
|
||||||
return createForm({ initialValues, readPretty: schema['x-read-pretty'] });
|
return createForm({
|
||||||
|
initialValues,
|
||||||
|
readPretty: schema['x-read-pretty'],
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
const path = useSchemaPath();
|
const path = useSchemaPath();
|
||||||
const scope = useContext(SchemaExpressionScopeContext);
|
const scope = useContext(SchemaExpressionScopeContext);
|
||||||
@ -128,7 +140,7 @@ export const Form: any = observer((props: any) => {
|
|||||||
<DisplayFieldsContextProvider>{content}</DisplayFieldsContextProvider>
|
<DisplayFieldsContextProvider>{content}</DisplayFieldsContextProvider>
|
||||||
</ResourceContextProvider>
|
</ResourceContextProvider>
|
||||||
) : (
|
) : (
|
||||||
content
|
<DisplayFieldsContextProvider>{content}</DisplayFieldsContextProvider>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -143,9 +155,9 @@ Form.Field = observer((props: any) => {
|
|||||||
const { resource = {} } = useResourceContext();
|
const { resource = {} } = useResourceContext();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (fieldName) {
|
if (fieldName) {
|
||||||
addDisplayField && addDisplayField(fieldName);
|
addDisplayField && addDisplayField(fieldName, schema);
|
||||||
}
|
}
|
||||||
}, [fieldName]);
|
}, [fieldName, schema]);
|
||||||
if (!fieldName) {
|
if (!fieldName) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ import AddNew from '../add-new';
|
|||||||
import { isGridRowOrCol } from '../grid';
|
import { isGridRowOrCol } from '../grid';
|
||||||
import { options } from '../database-field/interfaces';
|
import { options } from '../database-field/interfaces';
|
||||||
import { Resource } from '../../resource';
|
import { Resource } from '../../resource';
|
||||||
import { useDisplayFieldsContext } from '../form';
|
import { DisplayFieldsContextProvider, useDisplayFieldsContext } from '../form';
|
||||||
|
|
||||||
interface TableRowProps {
|
interface TableRowProps {
|
||||||
index: number;
|
index: number;
|
||||||
@ -223,10 +223,39 @@ function useTableColumns(props?: any) {
|
|||||||
return columns;
|
return columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function SwitchField(props) {
|
||||||
|
const { field, onChange } = props;
|
||||||
|
const [checked, setChecked] = useState(props.checked);
|
||||||
|
useEffect(() => {
|
||||||
|
setChecked(props.checked);
|
||||||
|
}, [props.checked]);
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
}}
|
||||||
|
onClick={async () => {
|
||||||
|
setChecked((checked) => {
|
||||||
|
onChange(!checked);
|
||||||
|
return !checked;
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span>{field.uiSchema.title}</span>
|
||||||
|
<Switch checked={checked} size={'small'} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function AddColumn() {
|
function AddColumn() {
|
||||||
const [visible, setVisible] = useState(false);
|
const [visible, setVisible] = useState(false);
|
||||||
const { appendChild } = useDesignable();
|
const { appendChild, remove } = useDesignable();
|
||||||
const { resource = {}, refresh } = useResourceContext();
|
const { resource = {}, refresh } = useResourceContext();
|
||||||
|
const { hasDisplayField, removeDisplayField, getDisplayField } =
|
||||||
|
useDisplayFieldsContext();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dropdown
|
<Dropdown
|
||||||
trigger={['click']}
|
trigger={['click']}
|
||||||
@ -237,27 +266,29 @@ function AddColumn() {
|
|||||||
<Menu.ItemGroup className={'display-fields'} title={'要展示的字段'}>
|
<Menu.ItemGroup className={'display-fields'} title={'要展示的字段'}>
|
||||||
{resource?.fields?.map((field) => (
|
{resource?.fields?.map((field) => (
|
||||||
<Menu.Item style={{ minWidth: 150 }}>
|
<Menu.Item style={{ minWidth: 150 }}>
|
||||||
<div
|
<SwitchField
|
||||||
style={{
|
checked={hasDisplayField(field.name)}
|
||||||
display: 'flex',
|
field={field}
|
||||||
alignItems: 'center',
|
onChange={async (checked) => {
|
||||||
justifyContent: 'space-between',
|
if (checked) {
|
||||||
|
const data = appendChild({
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Table.Column',
|
||||||
|
'x-component-props': {
|
||||||
|
fieldName: field.name,
|
||||||
|
},
|
||||||
|
'x-designable-bar': 'Table.Column.DesignableBar',
|
||||||
|
});
|
||||||
|
await createSchema(data);
|
||||||
|
} else {
|
||||||
|
const s: any = getDisplayField(field.name);
|
||||||
|
const p = getSchemaPath(s);
|
||||||
|
const removed = remove(p);
|
||||||
|
await removeSchema(removed);
|
||||||
|
removeDisplayField(field.name);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
onClick={async () => {
|
/>
|
||||||
const data = appendChild({
|
|
||||||
type: 'void',
|
|
||||||
'x-component': 'Table.Column',
|
|
||||||
'x-component-props': {
|
|
||||||
fieldName: field.name,
|
|
||||||
},
|
|
||||||
'x-designable-bar': 'Table.Column.DesignableBar',
|
|
||||||
});
|
|
||||||
await createSchema(data);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<span>{field.uiSchema.title}</span>
|
|
||||||
<Switch size={'small'} />
|
|
||||||
</div>
|
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
))}
|
))}
|
||||||
</Menu.ItemGroup>
|
</Menu.ItemGroup>
|
||||||
@ -611,12 +642,16 @@ export const Table: any = observer((props: any) => {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
<ResourceContextProvider resourceName={resourceName}>
|
<ResourceContextProvider resourceName={resourceName}>
|
||||||
<TableContextProvider>
|
<TableContextProvider>
|
||||||
<TableContainer />
|
<DisplayFieldsContextProvider>
|
||||||
|
<TableContainer />
|
||||||
|
</DisplayFieldsContextProvider>
|
||||||
</TableContextProvider>
|
</TableContextProvider>
|
||||||
</ResourceContextProvider>
|
</ResourceContextProvider>
|
||||||
) : (
|
) : (
|
||||||
<TableContextProvider>
|
<TableContextProvider>
|
||||||
<TableContainer />
|
<DisplayFieldsContextProvider>
|
||||||
|
<TableContainer />
|
||||||
|
</DisplayFieldsContextProvider>
|
||||||
</TableContextProvider>
|
</TableContextProvider>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -710,8 +745,14 @@ Table.Cell = observer((props: any) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Table.Column = observer((props: any) => {
|
Table.Column = observer((props: any) => {
|
||||||
const resourceField = useContext(ResourceFieldContext) || {};
|
const resourceField = useContext(ResourceFieldContext);
|
||||||
const { schema, DesignableBar } = useDesignable();
|
const { schema, DesignableBar } = useDesignable();
|
||||||
|
const { addDisplayField } = useDisplayFieldsContext();
|
||||||
|
useEffect(() => {
|
||||||
|
if (resourceField?.name) {
|
||||||
|
addDisplayField(resourceField.name, schema);
|
||||||
|
}
|
||||||
|
}, [resourceField, schema]);
|
||||||
return (
|
return (
|
||||||
<div className={'nb-table-column'}>
|
<div className={'nb-table-column'}>
|
||||||
{schema.title || resourceField?.uiSchema?.title}
|
{schema.title || resourceField?.uiSchema?.title}
|
||||||
@ -725,6 +766,7 @@ Table.Column.DesignableBar = () => {
|
|||||||
// const fieldSchema = useFieldSchema();
|
// const fieldSchema = useFieldSchema();
|
||||||
const { schema, remove, refresh, insertAfter } = useDesignable();
|
const { schema, remove, refresh, insertAfter } = useDesignable();
|
||||||
const [visible, setVisible] = useState(false);
|
const [visible, setVisible] = useState(false);
|
||||||
|
const { removeDisplayField } = useDisplayFieldsContext();
|
||||||
return (
|
return (
|
||||||
<div className={cls('designable-bar', { active: visible })}>
|
<div className={cls('designable-bar', { active: visible })}>
|
||||||
<span
|
<span
|
||||||
@ -759,6 +801,8 @@ Table.Column.DesignableBar = () => {
|
|||||||
<Menu.Item
|
<Menu.Item
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
const s = remove();
|
const s = remove();
|
||||||
|
const fieldName = schema['x-component-props']?.['fieldName'];
|
||||||
|
removeDisplayField(fieldName);
|
||||||
await removeSchema(s);
|
await removeSchema(s);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
Loading…
Reference in New Issue
Block a user