import React, {
Children,
createContext,
useContext,
useEffect,
useState,
} from 'react';
import { FormDialog, FormLayout } from '@formily/antd';
import {
connect,
observer,
mapProps,
mapReadPretty,
useField,
useFieldSchema,
RecursionField,
Schema,
ISchema,
useForm,
} from '@formily/react';
import {
Menu,
MenuProps,
MenuItemProps,
SubMenuProps,
DividerProps,
Dropdown,
Modal,
Button,
Spin,
Switch,
Checkbox,
} from 'antd';
import {
MenuOutlined,
GroupOutlined,
PlusOutlined,
LinkOutlined,
AppstoreAddOutlined,
EditOutlined,
DeleteOutlined,
ArrowRightOutlined,
SettingOutlined,
ArrowUpOutlined,
ArrowDownOutlined,
LoadingOutlined,
DownOutlined,
DatabaseOutlined,
} from '@ant-design/icons';
import {
createCollectionField,
createOrUpdateCollection,
createSchema,
removeSchema,
useDesignable,
useSchemaPath,
} from '../';
import { uid } from '@formily/shared';
import { getSchemaPath, SchemaField } from '../../components/schema-renderer';
import { cloneDeep } from 'lodash';
import { options } from '../database-field/interfaces';
import './style.less';
import IconPicker from '../../components/icon-picker';
import { barChartConfig, columnChartConfig } from './chart';
import { isGridRowOrCol } from '../grid';
import {
useCollectionContext,
useCollectionsContext,
useDisplayedMapContext,
} from '../../constate';
import SwitchMenuItem from '../../components/SwitchMenuItem';
const generateGridBlock = (schema: ISchema) => {
const name = schema.name || uid();
return {
type: 'void',
name: uid(),
'x-component': 'Grid.Row',
properties: {
[uid()]: {
type: 'void',
'x-component': 'Grid.Col',
properties: {
[name]: schema,
},
},
},
};
};
const isGrid = (schema: Schema) => {
return schema['x-component'] === 'Grid';
};
const isGridBlock = (schema: Schema) => {
if (schema.parent['x-component'] !== 'Grid.Col') {
return false;
}
// Grid.Col 里有多少 Block
if (Object.keys(schema.parent.properties).length > 1) {
return false;
}
// 有多少 Grid.Row
if (Object.keys(schema.parent.parent.properties).length > 1) {
return false;
}
return true;
};
function generateCardItemSchema(component) {
const defaults = {
'Markdown.Void': {
type: 'void',
default: '这是一段演示文字,**支持使用 Markdown 语法**',
'x-designable-bar': 'Markdown.Void.DesignableBar',
'x-decorator': 'CardItem',
'x-read-pretty': true,
'x-component': 'Markdown.Void',
},
Table: {
type: 'array',
'x-designable-bar': 'Table.DesignableBar',
'x-decorator': 'CardItem',
'x-component': 'Table',
default: [
// { key: uid(), field1: uid(), field2: uid() },
// { key: uid(), field1: uid(), field2: uid() },
// { key: uid(), field1: uid(), field2: uid() },
// { key: uid(), field1: uid(), field2: uid() },
// { key: uid(), field1: uid(), field2: uid() },
// { key: uid(), field1: uid(), field2: uid() },
// { key: uid(), field1: uid(), field2: uid() },
// { key: uid(), field1: uid(), field2: uid() },
],
'x-component-props': {
rowKey: 'id',
dragSort: true,
showIndex: true,
refreshRequestOnChange: true,
pagination: {
pageSize: 10,
},
},
properties: {
[uid()]: {
type: 'void',
'x-component': 'Table.ActionBar',
'x-designable-bar': 'Table.ActionBar.DesignableBar',
properties: {
[uid()]: {
type: 'void',
title: '筛选',
'x-decorator': 'AddNew.Displayed',
'x-decorator-props': {
displayName: 'filter',
},
'x-align': 'left',
'x-component': 'Table.Filter',
'x-designable-bar': 'Table.Filter.DesignableBar',
'x-component-props': {
fieldNames: [],
},
},
[uid()]: {
type: 'void',
name: 'action1',
title: '新增',
'x-align': 'right',
'x-decorator': 'AddNew.Displayed',
'x-decorator-props': {
displayName: 'create',
},
'x-component': 'Action',
'x-designable-bar': 'Table.Action.DesignableBar',
properties: {
modal: {
type: 'void',
title: '新增数据',
'x-decorator': 'Form',
'x-component': 'Action.Modal',
'x-component-props': {
useOkAction: '{{ Table.useTableCreateAction }}',
},
properties: {
[uid()]: {
type: 'void',
'x-component': 'Grid',
'x-component-props': {
addNewComponent: 'AddNew.FormItem',
},
},
},
},
},
},
[uid()]: {
type: 'void',
name: 'action1',
title: '删除',
'x-align': 'right',
'x-decorator': 'AddNew.Displayed',
'x-decorator-props': {
displayName: 'destroy',
},
'x-component': 'Action',
'x-designable-bar': 'Table.Action.DesignableBar',
'x-component-props': {
useAction: '{{ Table.useTableDestroyAction }}',
},
},
},
},
[uid()]: {
type: 'void',
title: '操作',
'x-component': 'Table.Column',
'x-component-props': {
className: 'nb-table-operation',
},
'x-designable-bar': 'Table.OperationDesignableBar',
properties: {
[uid()]: {
type: 'void',
'x-component': 'Action.Dropdown',
'x-component-props': {
buttonProps: {
icon: 'EllipsisOutlined',
},
},
properties: {
[uid()]: {
type: 'void',
title: '操作 1',
'x-component': 'Menu.Action',
'x-component-props': {
style: {
minWidth: 150,
},
disabled: true,
},
},
[uid()]: {
type: 'void',
name: 'action1',
title: '查看',
'x-component': 'Menu.Action',
'x-designable-bar': 'Table.Action.DesignableBar',
properties: {
[uid()]: {
type: 'void',
title: '查看',
'x-component': 'Action.Modal',
'x-component-props': {
bodyStyle: {
background: '#f0f2f5',
paddingTop: 0,
},
},
properties: {
[uid()]: {
type: 'void',
'x-component': 'Tabs',
properties: {
[uid()]: {
type: 'void',
'x-component': 'Tabs.TabPane',
'x-component-props': {
tab: 'Tab1',
},
properties: {
[uid()]: {
type: 'void',
'x-component': 'Grid',
'x-component-props': {
addNewComponent: 'AddNew.PaneItem',
},
},
},
},
},
},
},
},
},
},
[uid()]: {
type: 'void',
title: '编辑',
'x-component': 'Menu.Action',
'x-designable-bar': 'Table.Action.DesignableBar',
properties: {
[uid()]: {
type: 'void',
title: '编辑数据',
'x-decorator': 'Form',
'x-decorator-props': {
useResource: '{{ Table.useResource }}',
useValues: '{{ Table.useTableRowRecord }}',
},
'x-component': 'Action.Modal',
'x-component-props': {
useOkAction: '{{ Table.useTableUpdateAction }}',
},
properties: {
[uid()]: {
type: 'void',
'x-component': 'Grid',
'x-component-props': {
addNewComponent: 'AddNew.FormItem',
},
},
},
},
},
},
[uid()]: {
type: 'void',
title: '删除',
'x-component': 'Menu.Action',
'x-component-props': {
useAction: '{{ Table.useTableDestroyAction }}',
},
},
},
},
},
},
},
},
Form: {
type: 'void',
name: uid(),
'x-decorator': 'CardItem',
'x-component': 'Form',
'x-component-props': {
showDefaultButtons: true,
},
'x-designable-bar': 'Form.DesignableBar',
properties: {
[uid()]: {
type: 'void',
'x-component': 'Grid',
'x-component-props': {
addNewComponent: 'AddNew.FormItem',
},
},
},
},
'Chart.Column': {
type: 'void',
'x-decorator': 'CardItem',
'x-component': 'Chart.Column',
'x-designable-bar': 'Chart.DesignableBar',
'x-component-props': {
config: cloneDeep(columnChartConfig),
},
},
'Chart.Bar': {
type: 'void',
'x-decorator': 'CardItem',
'x-component': 'Chart.Bar',
'x-designable-bar': 'Chart.DesignableBar',
'x-component-props': {
config: cloneDeep(barChartConfig),
},
},
};
return defaults[component];
}
function generateFormItemSchema(component) {
const defaults = {
Markdown: {
type: 'string',
title: uid(),
'x-designable-bar': 'Markdown.DesignableBar',
'x-decorator': 'FormItem',
'x-component': 'Markdown',
'x-component-props': {},
},
};
return defaults[component];
}
const dbSchema = {
type: 'object',
properties: {
title: {
type: 'string',
title: '数据表名称',
required: true,
'x-decorator': 'FormItem',
'x-component': 'Input',
},
name: {
type: 'string',
title: '数据表标识',
'x-decorator': 'FormItem',
'x-component': 'Input',
'x-read-pretty': true,
},
fields: {
type: 'array',
title: '数据表字段',
'x-decorator': 'FormItem',
'x-component': 'DatabaseField',
default: [],
},
},
};
export const AddNew = () => null;
AddNew.CardItem = observer((props: any) => {
const { ghost, defaultAction } = props;
const { schema, insertBefore, insertAfter, appendChild } = useDesignable();
const path = useSchemaPath();
const { collections = [], loading, refresh } = useCollectionsContext();
return (
{
console.log('onVisibleChange', visible);
}}
overlay={
}
>
{ghost ? (
) : (
}>
新增区块
)}
);
});
AddNew.FormItem = observer((props: any) => {
const { ghost, defaultAction } = props;
const { schema, insertBefore, insertAfter, appendChild, deepRemove } =
useDesignable();
const path = useSchemaPath();
const { collection, fields, refresh } = useCollectionContext();
const [visible, setVisible] = useState(false);
const displayed = useDisplayedMapContext();
return (
{fields?.map((field) => (
{
if (!checked) {
const s: any = displayed.get(field.name);
const p = getSchemaPath(s);
const removed = deepRemove(p);
if (!removed) {
console.log('getSchemaPath', p, removed);
return;
}
const last = removed.pop();
displayed.remove(field.name);
if (isGridRowOrCol(last)) {
await removeSchema(last);
}
return;
}
let data: ISchema = {
key: uid(),
type: 'void',
'x-decorator': 'Form.Field.Item',
'x-designable-bar': 'Form.Field.DesignableBar',
'x-component': 'Form.Field',
'x-component-props': {
fieldName: field.name,
},
};
if (isGridBlock(schema)) {
path.pop();
path.pop();
data = generateGridBlock(data);
} else if (isGrid(schema)) {
data = generateGridBlock(data);
}
if (data) {
let s;
if (isGrid(schema)) {
s = appendChild(data, [...path]);
} else if (defaultAction === 'insertAfter') {
s = insertAfter(data, [...path]);
} else {
s = insertBefore(data, [...path]);
}
await createSchema(s);
}
}}
/>
))}
{options.map(
(option) =>
option.children.length > 0 && (
{option.children.map((item) => (
{
setVisible(false);
const values = await FormDialog(`新增字段`, () => {
return (
);
}).open({
initialValues: {
interface: item.name,
...item.default,
key: uid(),
name: `f_${uid()}`,
},
});
await createCollectionField(collection?.name, values);
await refresh();
let data: ISchema = cloneDeep(values.uiSchema);
data['name'] = values.name;
data['referenceKey'] = data['key'];
data['key'] = uid();
if (isGridBlock(schema)) {
path.pop();
path.pop();
data = generateGridBlock(data);
} else if (isGrid(schema)) {
data = generateGridBlock(data);
}
if (data) {
let s;
if (isGrid(schema)) {
s = appendChild(data, [...path]);
} else if (defaultAction === 'insertAfter') {
s = insertAfter(data, [...path]);
} else {
s = insertBefore(data, [...path]);
}
await createSchema(s);
}
}}
>
{item.title}
))}
),
)}
{/* */}
{
let data: ISchema = {
type: 'void',
default: '这是一段演示文字,**支持使用 Markdown 语法**',
'x-designable-bar': 'Markdown.Void.DesignableBar',
'x-decorator': 'FormItem',
'x-read-pretty': true,
'x-component': 'Markdown.Void',
};
if (schema['key']) {
data['key'] = uid();
}
if (isGridBlock(schema)) {
path.pop();
path.pop();
data = generateGridBlock(data);
} else if (isGrid(schema)) {
data = generateGridBlock(data);
}
if (data) {
let s;
if (isGrid(schema)) {
s = appendChild(data, [...path]);
} else if (defaultAction === 'insertAfter') {
s = insertAfter(data, [...path]);
} else {
s = insertBefore(data, [...path]);
}
console.log('ISchema', schema, data, path);
await createSchema(s);
}
setVisible(false);
}}
>
添加说明文字
}
>
{ghost ? (
) : (
}>
配置字段
)}
);
});
AddNew.PaneItem = observer((props: any) => {
const { ghost, defaultAction } = props;
const { schema, insertBefore, insertAfter, appendChild } = useDesignable();
const path = useSchemaPath();
const [visible, setVisible] = useState(false);
return (
}
onClick={async () => {
let data: ISchema = {
type: 'void',
name: uid(),
'x-decorator': 'CardItem',
'x-component': 'Form',
'x-read-pretty': true,
'x-component-props': {
useResource: '{{ Table.useResource }}',
useValues: '{{ Table.useTableRowRecord }}',
},
'x-designable-bar': 'Form.DesignableBar',
properties: {
[uid()]: {
type: 'void',
'x-component': 'Grid',
'x-component-props': {
addNewComponent: 'AddNew.FormItem',
},
},
},
};
if (isGridBlock(schema)) {
path.pop();
path.pop();
data = generateGridBlock(data);
} else if (isGrid(schema)) {
data = generateGridBlock(data);
}
if (data) {
let s;
if (isGrid(schema)) {
s = appendChild(data, [...path]);
} else if (defaultAction === 'insertAfter') {
s = insertAfter(data, [...path]);
} else {
s = insertBefore(data, [...path]);
}
await createSchema(s);
}
setVisible(false);
}}
style={{ minWidth: 150 }}
>
详情
}
onClick={async () => {
let data: ISchema = {
type: 'void',
name: uid(),
'x-decorator': 'CardItem',
'x-component': 'Form',
'x-component-props': {
useResource: '{{ Table.useResource }}',
useValues: '{{ Table.useTableRowRecord }}',
showDefaultButtons: true,
},
'x-designable-bar': 'Form.DesignableBar',
properties: {
[uid()]: {
type: 'void',
'x-component': 'Grid',
'x-component-props': {
addNewComponent: 'AddNew.FormItem',
},
},
},
};
if (isGridBlock(schema)) {
path.pop();
path.pop();
data = generateGridBlock(data);
} else if (isGrid(schema)) {
data = generateGridBlock(data);
}
if (data) {
let s;
if (isGrid(schema)) {
s = appendChild(data, [...path]);
} else if (defaultAction === 'insertAfter') {
s = insertAfter(data, [...path]);
} else {
s = insertBefore(data, [...path]);
}
await createSchema(s);
}
setVisible(false);
}}
>
表单
}
>
日志
}>
评论
}
onClick={async () => {
let data: ISchema = {
key: uid(),
type: 'void',
default: '这是一段演示文字,**支持使用 Markdown 语法**',
'x-designable-bar': 'Markdown.Void.DesignableBar',
'x-decorator': 'CardItem',
'x-read-pretty': true,
'x-component': 'Markdown.Void',
};
if (isGridBlock(schema)) {
path.pop();
path.pop();
data = generateGridBlock(data);
} else if (isGrid(schema)) {
data = generateGridBlock(data);
}
if (data) {
let s;
if (isGrid(schema)) {
s = appendChild(data, [...path]);
} else if (defaultAction === 'insertAfter') {
s = insertAfter(data, [...path]);
} else {
s = insertBefore(data, [...path]);
}
await createSchema(s);
}
setVisible(false);
}}
>
Markdown
}
>
{ghost ? (
) : (
}>
新增区块
)}
);
});
AddNew.Displayed = observer((props: any) => {
const { displayName, children } = props;
const displayed = useDisplayedMapContext();
const { schema } = useDesignable();
useEffect(() => {
if (displayName) {
displayed.set(displayName, schema);
}
}, [displayName, schema]);
return children;
});
export default AddNew;