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