tachybase_todo/packages/client/src/schema-component/antd/grid/AddFormItem.tsx
2022-02-14 15:50:19 +08:00

150 lines
3.5 KiB
TypeScript

import { ISchema, observer, Schema, useFieldSchema } from '@formily/react';
import { uid } from '@formily/shared';
import { Switch } from 'antd';
import React from 'react';
import { SchemaInitializer, SchemaInitializerItemOptions } from '../../../schema-initializer';
import { useDesignable } from '../../hooks';
const useFormItemInitializerFields = () => {
return [
{
type: 'item',
title: 'Name',
component: InitializeFormItem,
schema: {
name: 'name',
type: 'string',
title: 'Name',
'x-component': 'Input',
'x-decorator': 'FormItem',
'x-collection-field': 'posts.name',
},
},
{
type: 'item',
title: 'Title',
component: InitializeFormItem,
schema: {
name: 'title',
type: 'string',
title: 'Title',
'x-component': 'Input',
'x-decorator': 'FormItem',
'x-collection-field': 'posts.title',
},
},
] as SchemaInitializerItemOptions[];
};
const gridRowColWrap = (schema: ISchema) => {
return {
type: 'void',
'x-component': 'Grid.Row',
properties: {
[uid()]: {
type: 'void',
'x-component': 'Grid.Col',
properties: {
[schema.name || uid()]: schema,
},
},
},
};
};
const useCurrentFieldSchema = (path: string) => {
const fieldSchema = useFieldSchema();
const { remove } = useDesignable();
const findFieldSchema = (schema: Schema) => {
return schema.reduceProperties((buf, s) => {
if (s['x-collection-field'] === path) {
return s;
}
const child = findFieldSchema(s);
if (child) {
return child;
}
return buf;
});
};
const schema = findFieldSchema(fieldSchema);
return {
schema,
exists: !!schema,
remove() {
schema &&
remove(schema, {
removeParentsIfNoChildren: true,
breakSchema: (s) => {
return s['x-component'] === 'Grid';
},
});
},
};
};
const itemWrap = SchemaInitializer.itemWrap;
const InitializeFormItem = itemWrap((props) => {
const { item, insert } = props;
const { schema, exists, remove } = useCurrentFieldSchema(item.schema['x-collection-field']);
return (
<SchemaInitializer.Item
onClick={() => {
if (exists) {
return remove();
}
insert({
...item.schema,
});
}}
>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
{item.title} <Switch size={'small'} checked={exists} />
</div>
</SchemaInitializer.Item>
);
});
const InitializeTextFormItem = itemWrap((props) => {
const { insert } = props;
return (
<SchemaInitializer.Item
onClick={() => {
insert({
type: 'void',
'x-component': 'Markdown.Void',
'x-decorator': 'FormItem',
// 'x-editable': false,
});
}}
/>
);
});
export const AddGridFormItem = observer((props: any) => {
return (
<SchemaInitializer.Button
wrap={gridRowColWrap}
insertPosition={'beforeEnd'}
items={[
{
type: 'itemGroup',
title: 'Display fields',
children: useFormItemInitializerFields(),
},
{
type: 'divider',
},
{
type: 'item',
title: 'Add text',
component: InitializeTextFormItem,
},
]}
>
Configure fields
</SchemaInitializer.Button>
);
});