From b656f69565f52581bd48fa2320d67d667f12de66 Mon Sep 17 00:00:00 2001 From: chenos Date: Thu, 17 Feb 2022 23:56:39 +0800 Subject: [PATCH] feat: improve schema Initializer --- packages/app/src/pages/index.tsx | 28 +- .../Configuration/schemas/roleCollections.ts | 6 +- .../src/acl/Configuration/schemas/roles.ts | 4 +- .../src/application/demos/demo2/index.tsx | 2 + .../CollectionManagerProvider.tsx | 49 +++- .../CollectionManagerShortcut.tsx | 21 +- .../Configuration/AddFieldAction.tsx | 134 +++++++++ .../Configuration/ConfigurationTable.tsx | 4 +- .../Configuration/index.tsx | 2 + .../Configuration/schemas/collectionFields.ts | 125 +++------ .../Configuration/schemas/collections.ts | 28 +- .../ResourceActionProvider.tsx | 16 +- .../src/collection-manager/action-hooks.ts | 36 ++- .../hooks/useCollectionField.ts | 1 - .../hooks/useCollectionManager.ts | 10 +- .../interfaces/chinaRegion.ts | 73 +++++ .../collection-manager/interfaces/index.ts | 4 + .../collection-manager/interfaces/input.ts | 28 ++ .../interfaces/properties/index.ts | 198 +++++++++++++ .../collection-manager/interfaces/textarea.ts | 19 ++ .../collection-manager/interfaces/types.ts | 12 + .../client/src/collection-manager/types.ts | 12 +- .../antd/action/Action.Link.tsx | 4 +- .../schema-component/antd/action/Action.tsx | 4 +- .../antd/array-table/Initializer.tsx | 58 ---- .../array-table/TableActionDesignable.tsx | 41 +++ .../array-table/TableActionDesignableBar.tsx | 4 + .../antd/array-table/TableColumnActionBar.tsx | 14 + .../antd/array-table/index.ts | 3 +- .../antd/block-item/BlockItem.tsx | 9 + .../src/schema-component/antd/grid/Grid.tsx | 5 - .../antd/grid/demos/demo2.tsx | 17 +- .../antd/grid/demos/demo3.tsx | 7 +- .../schema-component/hooks/useDesignable.tsx | 2 +- .../FormBlockInitializerItem.tsx | 260 ++++++++++++++++++ .../TableBlockInitializerItem.tsx | 135 +++++++++ .../Initializers/BlockInitializer/index.tsx} | 94 +------ .../DetailsActionInitializer/index.tsx | 84 ++++++ .../FormItemInitializer/index.tsx} | 6 +- .../RecordBlockInitializer/index.tsx | 142 ++++++++++ .../TableActionInitializer/index.tsx | 96 +++++++ .../TableColumnActionInitializer/index.tsx | 145 ++++++++++ .../TableColumnInitializer/index.tsx | 99 +++++++ .../schema-initializer/Initializers/index.ts | 8 + .../schema-initializer/SchemaInitializer.tsx | 38 +-- .../SchemaInitializerProvider.tsx | 7 + .../client/src/schema-initializer/index.ts | 1 + .../client/src/schema-initializer/types.ts | 1 + .../plugin-ui-routes-storage/src/index.ts | 6 +- 49 files changed, 1756 insertions(+), 346 deletions(-) create mode 100644 packages/client/src/collection-manager/Configuration/AddFieldAction.tsx create mode 100644 packages/client/src/collection-manager/interfaces/chinaRegion.ts create mode 100644 packages/client/src/collection-manager/interfaces/input.ts create mode 100644 packages/client/src/collection-manager/interfaces/properties/index.ts create mode 100644 packages/client/src/collection-manager/interfaces/textarea.ts create mode 100644 packages/client/src/collection-manager/interfaces/types.ts delete mode 100644 packages/client/src/schema-component/antd/array-table/Initializer.tsx create mode 100644 packages/client/src/schema-component/antd/array-table/TableActionDesignable.tsx create mode 100644 packages/client/src/schema-component/antd/array-table/TableActionDesignableBar.tsx create mode 100644 packages/client/src/schema-component/antd/array-table/TableColumnActionBar.tsx create mode 100644 packages/client/src/schema-initializer/Initializers/BlockInitializer/FormBlockInitializerItem.tsx create mode 100644 packages/client/src/schema-initializer/Initializers/BlockInitializer/TableBlockInitializerItem.tsx rename packages/client/src/{schema-component/antd/grid/AddBlockItem.tsx => schema-initializer/Initializers/BlockInitializer/index.tsx} (63%) create mode 100644 packages/client/src/schema-initializer/Initializers/DetailsActionInitializer/index.tsx rename packages/client/src/{schema-component/antd/grid/AddFormItem.tsx => schema-initializer/Initializers/FormItemInitializer/index.tsx} (96%) create mode 100644 packages/client/src/schema-initializer/Initializers/RecordBlockInitializer/index.tsx create mode 100644 packages/client/src/schema-initializer/Initializers/TableActionInitializer/index.tsx create mode 100644 packages/client/src/schema-initializer/Initializers/TableColumnActionInitializer/index.tsx create mode 100644 packages/client/src/schema-initializer/Initializers/TableColumnInitializer/index.tsx create mode 100644 packages/client/src/schema-initializer/Initializers/index.ts create mode 100644 packages/client/src/schema-initializer/SchemaInitializerProvider.tsx diff --git a/packages/app/src/pages/index.tsx b/packages/app/src/pages/index.tsx index 53ef50033..144e41ecf 100644 --- a/packages/app/src/pages/index.tsx +++ b/packages/app/src/pages/index.tsx @@ -5,17 +5,18 @@ import { AntdSchemaComponentProvider, APIClientProvider, AuthLayout, - CollectionManagerProvider, CollectionManagerShortcut, compose, DesignableSwitch, DocumentTitleProvider, i18n, PluginManagerProvider, + RemoteCollectionManagerProvider, RouteSchemaComponent, RouteSwitch, RouteSwitchProvider, SchemaComponentProvider, + SchemaInitializerProvider, SigninPage, SignupPage, SystemSettingsProvider, @@ -38,13 +39,32 @@ const providers = [ SystemSettingsProvider, [ PluginManagerProvider, - { components: { ACLShortcut, DesignableSwitch, CollectionManagerShortcut, SystemSettingsShortcut } }, + { + components: { + ACLShortcut, + DesignableSwitch, + CollectionManagerShortcut, + SystemSettingsShortcut, + }, + }, ], [SchemaComponentProvider, { components: { Link, NavLink } }], - CollectionManagerProvider, + RemoteCollectionManagerProvider, + SchemaInitializerProvider, AntdSchemaComponentProvider, [DocumentTitleProvider, { addonAfter: 'NocoBase' }], - [RouteSwitchProvider, { components: { AuthLayout, AdminLayout, RouteSchemaComponent, SigninPage, SignupPage } }], + [ + RouteSwitchProvider, + { + components: { + AuthLayout, + AdminLayout, + RouteSchemaComponent, + SigninPage, + SignupPage, + }, + }, + ], ]; const App = compose(...providers)(() => { diff --git a/packages/client/src/acl/Configuration/schemas/roleCollections.ts b/packages/client/src/acl/Configuration/schemas/roleCollections.ts index 18e7587c4..4878f5e38 100644 --- a/packages/client/src/acl/Configuration/schemas/roleCollections.ts +++ b/packages/client/src/acl/Configuration/schemas/roleCollections.ts @@ -2,6 +2,7 @@ import { ISchema } from '@formily/react'; const collection = { name: 'collections', + targetKey: 'name', filterTargetKey: 'name', fields: [ { @@ -42,6 +43,7 @@ export const roleCollectionsSchema: ISchema = { type: 'void', 'x-decorator': 'ResourceActionProvider', 'x-decorator-props': { + collection, association: { sourceKey: 'name', targetKey: 'name', @@ -58,10 +60,6 @@ export const roleCollectionsSchema: ISchema = { }, }, }, - 'x-component': 'CollectionProvider', - 'x-component-props': { - collection, - }, properties: { table1: { type: 'void', diff --git a/packages/client/src/acl/Configuration/schemas/roles.ts b/packages/client/src/acl/Configuration/schemas/roles.ts index 545540794..6c6b21039 100644 --- a/packages/client/src/acl/Configuration/schemas/roles.ts +++ b/packages/client/src/acl/Configuration/schemas/roles.ts @@ -38,9 +38,7 @@ export const roleSchema: ISchema = { type: 'void', 'x-decorator': 'ResourceActionProvider', 'x-decorator-props': { - collection: { - targetKey: 'name', - }, + collection, resourceName: 'roles', request: { resource: 'roles', diff --git a/packages/client/src/application/demos/demo2/index.tsx b/packages/client/src/application/demos/demo2/index.tsx index 4769026c2..217f1597a 100644 --- a/packages/client/src/application/demos/demo2/index.tsx +++ b/packages/client/src/application/demos/demo2/index.tsx @@ -16,6 +16,7 @@ import { RouteSwitch, RouteSwitchProvider, SchemaComponentProvider, + SchemaInitializerProvider, SigninPage, SignupPage, SystemSettingsProvider, @@ -42,6 +43,7 @@ const providers = [ [SchemaComponentProvider, { components: { Link, NavLink } }], CollectionManagerProvider, AntdSchemaComponentProvider, + SchemaInitializerProvider, [DocumentTitleProvider, { addonAfter: 'NocoBase' }], [RouteSwitchProvider, { components: { AuthLayout, AdminLayout, RouteSchemaComponent, SigninPage, SignupPage } }], ]; diff --git a/packages/client/src/collection-manager/CollectionManagerProvider.tsx b/packages/client/src/collection-manager/CollectionManagerProvider.tsx index 349ad765a..9092dbcc3 100644 --- a/packages/client/src/collection-manager/CollectionManagerProvider.tsx +++ b/packages/client/src/collection-manager/CollectionManagerProvider.tsx @@ -1,15 +1,54 @@ +import { Spin } from 'antd'; import React from 'react'; +import { useAPIClient, useRequest } from '../api-client'; import { CollectionManagerSchemaComponentProvider } from './CollectionManagerSchemaComponentProvider'; import { CollectionManagerContext } from './context'; +import * as defaultInterfaces from './interfaces'; import { CollectionManagerOptions } from './types'; export const CollectionManagerProvider: React.FC = (props) => { - const { interfaces, collections } = props; + const { service, interfaces, collections = [], refreshCM } = props; return ( - - - {props.children} - + { + if (refreshCM) { + await refreshCM(); + } + }, + }} + > + {props.children} ); }; + +export const RemoteCollectionManagerProvider = (props: any) => { + const api = useAPIClient(); + const options = { + resource: 'collections', + action: 'list', + params: { + perPage: 999, + appends: ['fields', 'fields.uiSchema'], + }, + }; + const service = useRequest(options); + if (service.loading) { + return ; + } + return ( + { + const { data } = await api.request(options); + service.mutate(data); + }} + {...props} + /> + ); +}; diff --git a/packages/client/src/collection-manager/CollectionManagerShortcut.tsx b/packages/client/src/collection-manager/CollectionManagerShortcut.tsx index 2604d2aa2..b5aa99182 100644 --- a/packages/client/src/collection-manager/CollectionManagerShortcut.tsx +++ b/packages/client/src/collection-manager/CollectionManagerShortcut.tsx @@ -1,23 +1,10 @@ import { DatabaseOutlined } from '@ant-design/icons'; -import { ISchema, useForm } from '@formily/react'; +import { ISchema } from '@formily/react'; import { uid } from '@formily/shared'; import React, { useState } from 'react'; import { PluginManager } from '../plugin-manager'; -import { ActionContext, SchemaComponent, useActionContext } from '../schema-component'; -import { ConfigurationTable } from './Configuration'; - -const useCloseAction = () => { - const { setVisible } = useActionContext(); - const form = useForm(); - return { - async run() { - setVisible(false); - form.submit((values) => { - console.log(values); - }); - }, - }; -}; +import { ActionContext, SchemaComponent } from '../schema-component'; +import { AddFieldAction, ConfigurationTable, EditFieldAction } from './Configuration'; const schema: ISchema = { type: 'object', @@ -46,7 +33,7 @@ export const CollectionManagerShortcut = () => { setVisible(true); }} /> - + ); }; diff --git a/packages/client/src/collection-manager/Configuration/AddFieldAction.tsx b/packages/client/src/collection-manager/Configuration/AddFieldAction.tsx new file mode 100644 index 000000000..fabf798b9 --- /dev/null +++ b/packages/client/src/collection-manager/Configuration/AddFieldAction.tsx @@ -0,0 +1,134 @@ +import { PlusOutlined } from '@ant-design/icons'; +import { ISchema } from '@formily/react'; +import { uid } from '@formily/shared'; +import { Button, Dropdown, Menu } from 'antd'; +import React, { useState } from 'react'; +import { useAPIClient } from '../../api-client'; +import { useRecord } from '../../record-provider'; +import { ActionContext, SchemaComponent } from '../../schema-component'; +import { useCollectionManager } from '../hooks'; +import { IField } from '../interfaces/types'; + +const getSchema = (schema: IField, useAction): ISchema => { + if (!schema) { + return; + } + return { + type: 'object', + properties: { + [uid()]: { + type: 'void', + 'x-component': 'Action.Drawer', + 'x-decorator': 'Form', + 'x-decorator-props': { + initialValue: { + ...schema.default, + name: `f_${uid()}`, + }, + }, + title: 'Drawer Title', + properties: { + type: { + 'x-component': 'CollectionField', + 'x-decorator': 'FormItem', + }, + title: { + 'x-component': 'CollectionField', + 'x-decorator': 'FormItem', + }, + name: { + 'x-component': 'CollectionField', + 'x-decorator': 'FormItem', + }, + // @ts-ignore + ...schema.properties, + footer: { + type: 'void', + 'x-component': 'Action.Drawer.Footer', + properties: { + action1: { + title: 'Cancel', + 'x-component': 'Action', + 'x-component-props': { + useAction: '{{ useCancelAction }}', + }, + }, + action2: { + title: 'Submit', + 'x-component': 'Action', + 'x-component-props': { + type: 'primary', + useAction, + }, + }, + }, + }, + }, + }, + }, + }; +}; + +export const AddFieldAction = () => { + const { getInterface } = useCollectionManager(); + const [visible, setVisible] = useState(false); + const [schema, setSchema] = useState({}); + return ( + + { + const schema = getSchema(getInterface(info.key), '{{ useCreateActionAndRefreshCM }}'); + setSchema(schema); + setVisible(true); + }} + > + + input + textarea + China region + + + } + > + + + + + ); +}; + +export const EditFieldAction = (props) => { + const record = useRecord(); + const { getInterface } = useCollectionManager(); + const [visible, setVisible] = useState(false); + const [schema, setSchema] = useState({}); + const api = useAPIClient(); + return ( + + { + const { data } = await api.resource('collections.fields', record.collectionName).get({ + filterByTk: record.name, + appends: ['uiSchema'], + }); + const schema = getSchema( + { + ...getInterface(record.interface), + default: data?.data, + }, + '{{ useUpdateActionAndRefreshCM }}', + ); + setSchema(schema); + setVisible(true); + }} + > + 编辑 + + + + ); +}; diff --git a/packages/client/src/collection-manager/Configuration/ConfigurationTable.tsx b/packages/client/src/collection-manager/Configuration/ConfigurationTable.tsx index cec996e73..0fe61b913 100644 --- a/packages/client/src/collection-manager/Configuration/ConfigurationTable.tsx +++ b/packages/client/src/collection-manager/Configuration/ConfigurationTable.tsx @@ -5,9 +5,7 @@ import { collectionSchema } from './schemas/collections'; export const ConfigurationTable = () => { return (
- +
); }; diff --git a/packages/client/src/collection-manager/Configuration/index.tsx b/packages/client/src/collection-manager/Configuration/index.tsx index 5cc856991..7494a4ebd 100644 --- a/packages/client/src/collection-manager/Configuration/index.tsx +++ b/packages/client/src/collection-manager/Configuration/index.tsx @@ -1 +1,3 @@ +export * from './AddFieldAction'; export * from './ConfigurationTable'; + diff --git a/packages/client/src/collection-manager/Configuration/schemas/collectionFields.ts b/packages/client/src/collection-manager/Configuration/schemas/collectionFields.ts index 90a3ed02d..eaaee30ea 100644 --- a/packages/client/src/collection-manager/Configuration/schemas/collectionFields.ts +++ b/packages/client/src/collection-manager/Configuration/schemas/collectionFields.ts @@ -20,6 +20,16 @@ const collection = { required: true, } as ISchema, }, + { + type: 'string', + name: 'interface', + interface: 'input', + uiSchema: { + title: '字段类型', + type: 'string', + 'x-component': 'Input', + }, + }, { type: 'string', name: 'title', @@ -54,6 +64,7 @@ export const collectionFieldSchema: ISchema = { sourceKey: 'name', targetKey: 'name', }, + collection, request: { resource: 'collections.fields', action: 'list', @@ -65,10 +76,10 @@ export const collectionFieldSchema: ISchema = { }, }, }, - 'x-component': 'CollectionProvider', - 'x-component-props': { - collection, - }, + // 'x-component': 'CollectionProvider', + // 'x-component-props': { + // collection, + // }, properties: { actions: { type: 'void', @@ -82,57 +93,14 @@ export const collectionFieldSchema: ISchema = { create: { type: 'void', title: '创建', - 'x-component': 'Action', + 'x-component': 'AddFieldAction', 'x-component-props': { type: 'primary', }, - properties: { - drawer: { - type: 'void', - 'x-component': 'Action.Drawer', - 'x-decorator': 'Form', - title: 'Drawer Title', - properties: { - type: { - 'x-component': 'CollectionField', - 'x-decorator': 'FormItem', - }, - title: { - 'x-component': 'CollectionField', - 'x-decorator': 'FormItem', - }, - name: { - 'x-component': 'CollectionField', - 'x-decorator': 'FormItem', - }, - footer: { - type: 'void', - 'x-component': 'Action.Drawer.Footer', - properties: { - action1: { - title: 'Cancel', - 'x-component': 'Action', - 'x-component-props': { - useAction: '{{ useCancelAction }}', - }, - }, - action2: { - title: 'Submit', - 'x-component': 'Action', - 'x-component-props': { - type: 'primary', - useAction: '{{ useCreateAction }}', - }, - }, - }, - }, - }, - }, - }, }, }, }, - table1: { + table: { type: 'void', 'x-uid': 'input', 'x-component': 'VoidTable', @@ -169,6 +137,18 @@ export const collectionFieldSchema: ISchema = { }, }, column3: { + type: 'void', + 'x-decorator': 'TableColumnDecorator', + 'x-component': 'VoidTable.Column', + properties: { + interface: { + type: 'string', + 'x-component': 'CollectionField', + 'x-read-pretty': true, + }, + }, + }, + column4: { type: 'void', title: 'Actions', 'x-component': 'VoidTable.Column', @@ -183,60 +163,17 @@ export const collectionFieldSchema: ISchema = { update: { type: 'void', title: '编辑', - 'x-component': 'Action.Link', + 'x-component': 'EditFieldAction', 'x-component-props': { type: 'primary', }, - properties: { - drawer: { - type: 'void', - 'x-component': 'Action.Drawer', - 'x-decorator': 'Form', - 'x-decorator-props': { - useValues: '{{ useValues }}', - }, - title: 'Drawer Title', - properties: { - title: { - 'x-component': 'CollectionField', - 'x-decorator': 'FormItem', - }, - name: { - 'x-component': 'CollectionField', - 'x-decorator': 'FormItem', - 'x-disabled': true, - }, - footer: { - type: 'void', - 'x-component': 'Action.Drawer.Footer', - properties: { - action1: { - title: 'Cancel', - 'x-component': 'Action', - 'x-component-props': { - useAction: '{{ useCancelAction }}', - }, - }, - action2: { - title: 'Submit', - 'x-component': 'Action', - 'x-component-props': { - type: 'primary', - useAction: '{{ useUpdateAction }}', - }, - }, - }, - }, - }, - }, - }, }, delete: { type: 'void', title: '删除', 'x-component': 'Action.Link', 'x-component-props': { - useAction: '{{ useDestroyAction }}', + useAction: '{{ useDestroyActionAndRefreshCM }}', }, }, }, diff --git a/packages/client/src/collection-manager/Configuration/schemas/collections.ts b/packages/client/src/collection-manager/Configuration/schemas/collections.ts index 8e1c48156..3a8d694b1 100644 --- a/packages/client/src/collection-manager/Configuration/schemas/collections.ts +++ b/packages/client/src/collection-manager/Configuration/schemas/collections.ts @@ -1,9 +1,11 @@ import { ISchema } from '@formily/react'; +import { CollectionOptions } from '../../types'; import { collectionFieldSchema } from './collectionFields'; -const collection = { +const collection: CollectionOptions = { name: 'collections', filterTargetKey: 'name', + targetKey: 'name', fields: [ { type: 'integer', @@ -14,7 +16,7 @@ const collection = { type: 'number', 'x-component': 'Input', required: true, - } as ISchema, + }, }, { type: 'string', @@ -25,7 +27,7 @@ const collection = { type: 'string', 'x-component': 'Input', description: '使用英文', - } as ISchema, + }, }, { type: 'hasMany', @@ -47,9 +49,7 @@ export const collectionSchema: ISchema = { 'x-collection': 'collections', 'x-decorator': 'ResourceActionProvider', 'x-decorator-props': { - collection: { - targetKey: 'name', - }, + collection, request: { resource: 'collections', action: 'list', @@ -61,10 +61,10 @@ export const collectionSchema: ISchema = { }, }, }, - 'x-component': 'CollectionProvider', - 'x-component-props': { - collection, - }, + // 'x-component': 'CollectionProvider', + // 'x-component-props': { + // collection, + // }, properties: { actions: { type: 'void', @@ -113,7 +113,7 @@ export const collectionSchema: ISchema = { 'x-component': 'Action', 'x-component-props': { type: 'primary', - useAction: '{{ useCreateAction }}', + useAction: '{{ useCreateActionAndRefreshCM }}', }, }, }, @@ -201,7 +201,7 @@ export const collectionSchema: ISchema = { 'x-component': 'Action.Drawer', 'x-decorator': 'Form', 'x-decorator-props': { - useValues: '{{ useValues }}', + useValues: '{{ useValuesFromRecord }}', }, title: 'Drawer Title', properties: { @@ -230,7 +230,7 @@ export const collectionSchema: ISchema = { 'x-component': 'Action', 'x-component-props': { type: 'primary', - useAction: '{{ useUpdateAction }}', + useAction: '{{ useUpdateActionAndRefreshCM }}', }, }, }, @@ -244,7 +244,7 @@ export const collectionSchema: ISchema = { title: '删除', 'x-component': 'Action.Link', 'x-component-props': { - useAction: '{{ useDestroyAction }}', + useAction: '{{ useDestroyActionAndRefreshCM }}', }, }, }, diff --git a/packages/client/src/collection-manager/ResourceActionProvider.tsx b/packages/client/src/collection-manager/ResourceActionProvider.tsx index e9cec25ab..4cbddba9d 100644 --- a/packages/client/src/collection-manager/ResourceActionProvider.tsx +++ b/packages/client/src/collection-manager/ResourceActionProvider.tsx @@ -1,6 +1,6 @@ import { Result } from 'ahooks/lib/useRequest/src/types'; import React, { createContext, useContext, useEffect } from 'react'; -import { useRecord } from '..'; +import { CollectionProvider, useRecord } from '..'; import { useAPIClient, useRequest } from '../api-client'; export const ResourceActionContext = createContext>(null); @@ -18,18 +18,20 @@ const CollectionResourceActionProvider = (props) => { const api = useAPIClient(); const service = useRequest(request, { uid, - refreshDeps: [request], + // refreshDeps: [request], }); const resource = api.resource(request.resource); return ( - {props.children} + + {props.children} + ); }; const AssociationResourceActionProvider = (props) => { - const { association, request, uid } = props; + const { collection, association, request, uid } = props; const api = useAPIClient(); const record = useRecord(); const resourceOf = record[association.sourceKey]; @@ -37,13 +39,15 @@ const AssociationResourceActionProvider = (props) => { { resourceOf, ...request }, { uid, - refreshDeps: [request, resourceOf], + // refreshDeps: [request, resourceOf], }, ); const resource = api.resource(request.resource, resourceOf); return ( - {props.children} + + {props.children} + ); }; diff --git a/packages/client/src/collection-manager/action-hooks.ts b/packages/client/src/collection-manager/action-hooks.ts index 9a3871aae..4f5a0633f 100644 --- a/packages/client/src/collection-manager/action-hooks.ts +++ b/packages/client/src/collection-manager/action-hooks.ts @@ -1,4 +1,5 @@ import { useForm } from '@formily/react'; +import { useCollectionManager } from '.'; import { useRequest } from '../api-client'; import { useRecord } from '../record-provider'; import { useActionContext } from '../schema-component'; @@ -60,10 +61,43 @@ export const useDestroyAction = () => { }; }; -export const useValues = (options) => { +export const useValuesFromRecord = (options) => { const record = useRecord(); return useRequest(() => Promise.resolve({ data: record }), { ...options, refreshDeps: [record], }); }; + +export const useCreateActionAndRefreshCM = () => { + const { run } = useCreateAction(); + const { refreshCM } = useCollectionManager(); + return { + async run() { + await run(); + await refreshCM(); + }, + }; +}; + +export const useUpdateActionAndRefreshCM = () => { + const { run } = useUpdateAction(); + const { refreshCM } = useCollectionManager(); + return { + async run() { + await run(); + await refreshCM(); + }, + }; +}; + +export const useDestroyActionAndRefreshCM = () => { + const { run } = useDestroyAction(); + const { refreshCM } = useCollectionManager(); + return { + async run() { + await run(); + await refreshCM(); + }, + }; +}; diff --git a/packages/client/src/collection-manager/hooks/useCollectionField.ts b/packages/client/src/collection-manager/hooks/useCollectionField.ts index 58b328648..0c52383d2 100644 --- a/packages/client/src/collection-manager/hooks/useCollectionField.ts +++ b/packages/client/src/collection-manager/hooks/useCollectionField.ts @@ -11,7 +11,6 @@ export const useCollectionField = () => { const ctx = useContext(CollectionFieldContext); const resourceName = `${ctx?.collectinName || collection?.name}.${ctx.name}`; const resource = api?.resource(resourceName, record[ctx.sourceKey]); - console.log({ resourceName }); return { ...ctx, resource, diff --git a/packages/client/src/collection-manager/hooks/useCollectionManager.ts b/packages/client/src/collection-manager/hooks/useCollectionManager.ts index 3a6216992..28c3a192b 100644 --- a/packages/client/src/collection-manager/hooks/useCollectionManager.ts +++ b/packages/client/src/collection-manager/hooks/useCollectionManager.ts @@ -1,11 +1,19 @@ +import { clone } from '@formily/shared'; import { useContext } from 'react'; import { CollectionManagerContext } from '../context'; export const useCollectionManager = () => { - const { collections } = useContext(CollectionManagerContext); + const { refreshCM, service, interfaces, collections } = useContext(CollectionManagerContext); return { + service, + interfaces, + collections, + refreshCM: () => refreshCM?.(), get(name: string) { return collections?.find((collection) => collection.name === name); }, + getInterface(name) { + return interfaces[name] ? clone(interfaces[name]) : null; + }, }; }; diff --git a/packages/client/src/collection-manager/interfaces/chinaRegion.ts b/packages/client/src/collection-manager/interfaces/chinaRegion.ts new file mode 100644 index 000000000..dbb80fc8d --- /dev/null +++ b/packages/client/src/collection-manager/interfaces/chinaRegion.ts @@ -0,0 +1,73 @@ +import { uid } from '@formily/shared'; +import { IField } from './types'; + +export const chinaRegion: IField = { + name: 'chinaRegion', + type: 'object', + group: 'choices', + order: 7, + title: '{{t("China region")}}', + isAssociation: true, + default: { + interface: 'chinaRegion', + type: 'belongsToMany', + target: 'chinaRegions', + targetKey: 'code', + // name, + uiSchema: { + type: 'array', + // title, + 'x-component': 'Cascader', + 'x-component-props': { + changeOnSelectLast: false, + labelInValue: true, + maxLevel: 3, + fieldNames: { + label: 'name', + value: 'code', + children: 'children', + }, + }, + }, + }, + initialize: (values: any) => { + if (!values.through) { + values.through = `t_${uid()}`; + } + if (!values.foreignKey) { + values.foreignKey = `f_${uid()}`; + } + if (!values.otherKey) { + values.otherKey = `f_${uid()}`; + } + if (!values.sourceKey) { + values.sourceKey = 'id'; + } + if (!values.targetKey) { + values.targetKey = 'id'; + } + }, + properties: { + 'uiSchema.x-component-props.maxLevel': { + type: 'number', + 'x-component': 'Radio.Group', + 'x-decorator': 'FormItem', + title: '{{t("Select level")}}', + default: 3, + enum: [ + { value: 1, label: '{{t("Province")}}' }, + { value: 2, label: '{{t("City")}}' }, + { value: 3, label: '{{t("Area")}}' }, + { value: 4, label: '{{t("Street")}}' }, + { value: 5, label: '{{t("Village")}}' }, + ], + }, + 'uiSchema.x-component-props.changeOnSelectLast': { + type: 'boolean', + 'x-component': 'Checkbox', + 'x-content': '{{t("Must select to the last level")}}', + 'x-decorator': 'FormItem', + }, + }, + operators: [{ label: '{{t("is")}}', value: 'code.in' }], +}; diff --git a/packages/client/src/collection-manager/interfaces/index.ts b/packages/client/src/collection-manager/interfaces/index.ts index e69de29bb..bddb0ff70 100644 --- a/packages/client/src/collection-manager/interfaces/index.ts +++ b/packages/client/src/collection-manager/interfaces/index.ts @@ -0,0 +1,4 @@ +export * from './chinaRegion'; +export * from './input'; +export * from './textarea'; + diff --git a/packages/client/src/collection-manager/interfaces/input.ts b/packages/client/src/collection-manager/interfaces/input.ts new file mode 100644 index 000000000..239025df7 --- /dev/null +++ b/packages/client/src/collection-manager/interfaces/input.ts @@ -0,0 +1,28 @@ +import { IField } from './types'; + +export const input: IField = { + name: 'string', + type: 'object', + group: 'basic', + order: 1, + title: '{{t("Single line text")}}', + sortable: true, + default: { + interface: 'input', + type: 'string', + uiSchema: { + type: 'string', + 'x-component': 'Input', + }, + }, + properties: { + }, + operators: [ + { label: '{{t("contains")}}', value: '$includes', selected: true }, + { label: '{{t("does not contain")}}', value: '$notIncludes' }, + { label: '{{t("is")}}', value: 'eq' }, + { label: '{{t("is not")}}', value: 'ne' }, + { label: '{{t("is empty")}}', value: '$null', noValue: true }, + { label: '{{t("is not empty")}}', value: '$notNull', noValue: true }, + ], +}; diff --git a/packages/client/src/collection-manager/interfaces/properties/index.ts b/packages/client/src/collection-manager/interfaces/properties/index.ts new file mode 100644 index 000000000..e59cbf3af --- /dev/null +++ b/packages/client/src/collection-manager/interfaces/properties/index.ts @@ -0,0 +1,198 @@ +import { ISchema } from '@formily/react'; + +export const type: ISchema = { + type: 'string', + title: '{{t("Storage type")}}', + required: true, + 'x-disabled': true, + 'x-decorator': 'FormItem', + 'x-component': 'Select', + enum: [ + { label: 'Boolean', value: 'boolean' }, + { label: 'String', value: 'string' }, + { label: 'Text', value: 'text' }, + { label: 'Integer', value: 'integer' }, + { label: 'Float', value: 'float' }, + { label: 'Decimal', value: 'decimal' }, + { label: 'Date', value: 'date' }, + { label: 'DateOnly', value: 'dateonly' }, + { label: 'Time', value: 'time' }, + { label: 'Virtual', value: 'virtual' }, + { label: 'JSON', value: 'json' }, + { label: 'Password', value: 'password' }, + { label: 'HasOne', value: 'hasOne' }, + { label: 'HasMany', value: 'hasMany' }, + { label: 'BelongsTo', value: 'belongsTo' }, + { label: 'BelongsToMany', value: 'belongsToMany' }, + ], +}; + +export const dateTimeProps: { [key: string]: ISchema } = { + 'uiSchema.x-component-props.dateFormat': { + type: 'string', + title: '{{t("Date format")}}', + 'x-component': 'Radio.Group', + 'x-decorator': 'FormItem', + default: 'YYYY-MM-DD', + enum: [ + { + label: '{{t("Year/Month/Day")}}', + value: 'YYYY/MM/DD', + }, + { + label: '{{t("Year-Month-Day")}}', + value: 'YYYY-MM-DD', + }, + { + label: '{{t("Day/Month/Year")}}', + value: 'DD/MM/YYYY', + }, + ], + }, + 'uiSchema.x-component-props.showTime': { + type: 'boolean', + 'x-decorator': 'FormItem', + 'x-component': 'Checkbox', + 'x-content': '{{t("Show time")}}', + 'x-reactions': [ + `{{(field) => { + field.query('..[].timeFormat').take(f => { + f.display = field.value ? 'visible' : 'none'; + }); + }}}`, + ], + }, + 'uiSchema.x-component-props.timeFormat': { + type: 'string', + title: '{{t("Time format")}}', + 'x-component': 'Radio.Group', + 'x-decorator': 'FormItem', + default: 'HH:mm:ss', + enum: [ + { + label: '{{t("12 hour")}}', + value: 'hh:mm:ss a', + }, + { + label: '{{t("24 hour")}}', + value: 'HH:mm:ss', + }, + ], + }, +}; + +export const dataSource: ISchema = { + type: 'array', + title: '{{t("Options")}}', + 'x-decorator': 'FormItem', + 'x-component': 'ArrayTable', + 'x-component-props': { + pagination: false, + // scroll: { x: '100%' }, + }, + items: { + type: 'object', + properties: { + column1: { + type: 'void', + 'x-component': 'ArrayTable.Column', + 'x-component-props': { width: 50, title: '', align: 'center' }, + properties: { + sort: { + type: 'void', + 'x-component': 'ArrayTable.SortHandle', + }, + }, + }, + column2: { + type: 'void', + 'x-component': 'ArrayTable.Column', + 'x-component-props': { title: '{{t("Option value")}}' }, + 'x-hidden': true, + properties: { + value: { + type: 'string', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + }, + }, + column3: { + type: 'void', + 'x-component': 'ArrayTable.Column', + 'x-component-props': { title: '{{t("Option label")}}' }, + properties: { + label: { + type: 'string', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + }, + }, + column4: { + type: 'void', + 'x-component': 'ArrayTable.Column', + 'x-component-props': { title: '{{t("Color")}}' }, + properties: { + color: { + type: 'string', + 'x-decorator': 'FormItem', + 'x-component': 'ColorSelect', + }, + }, + }, + column5: { + type: 'void', + 'x-component': 'ArrayTable.Column', + 'x-component-props': { + title: '', + dataIndex: 'operations', + fixed: 'right', + }, + properties: { + item: { + type: 'void', + 'x-component': 'FormItem', + properties: { + remove: { + type: 'void', + 'x-component': 'ArrayTable.Remove', + }, + }, + }, + }, + }, + }, + }, + properties: { + add: { + type: 'void', + 'x-component': 'ArrayTable.Addition', + 'x-component-props': { + randomValue: true, + }, + title: "{{t('Add option')}}", + }, + }, +}; + +export const defaultProps = { + 'uiSchema.title': { + type: 'string', + title: '{{t("Field display name")}}', + required: true, + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + name: { + type: 'string', + title: '{{t("Field name")}}', + required: true, + // 'x-disabled': true, + 'x-decorator': 'FormItem', + 'x-component': 'Input', + description: + "{{t('Randomly generated and can be modified. Support letters, numbers and underscores, must start with an letter.')}}", + }, + type, +}; diff --git a/packages/client/src/collection-manager/interfaces/textarea.ts b/packages/client/src/collection-manager/interfaces/textarea.ts new file mode 100644 index 000000000..2f81f37f6 --- /dev/null +++ b/packages/client/src/collection-manager/interfaces/textarea.ts @@ -0,0 +1,19 @@ +import { IField } from './types'; + +export const textarea: IField = { + name: 'textarea', + type: 'object', + group: 'basic', + order: 2, + title: '{{t("Long text")}}', + default: { + interface: 'textarea', + type: 'text', + // name, + uiSchema: { + type: 'string', + 'x-component': 'Input.TextArea', + }, + }, + properties: {}, +}; diff --git a/packages/client/src/collection-manager/interfaces/types.ts b/packages/client/src/collection-manager/interfaces/types.ts new file mode 100644 index 000000000..b616ae27c --- /dev/null +++ b/packages/client/src/collection-manager/interfaces/types.ts @@ -0,0 +1,12 @@ +import { ISchema } from '@formily/react'; + +interface IDefault { + type: string; + uiSchema?: ISchema; + [key: string]: any; +} + +export interface IField extends ISchema { + default?: IDefault; + [key: string]: any; +} diff --git a/packages/client/src/collection-manager/types.ts b/packages/client/src/collection-manager/types.ts index a9a4cd569..c010d4a2b 100644 --- a/packages/client/src/collection-manager/types.ts +++ b/packages/client/src/collection-manager/types.ts @@ -1,14 +1,24 @@ import { ISchema } from '@formily/react'; export interface CollectionManagerOptions { + service?: any; interfaces?: any; collections?: any[]; + refreshCM?: () => Promise; +} + +export interface FieldOptions { + type: string; + interface?: string; + uiSchema?: ISchema; + [key: string]: any; } export interface CollectionOptions { name?: string; filterTargetKey?: string; - fields?: any[]; + targetKey?: string; + fields?: FieldOptions[]; } export interface ICollectionProviderProps { diff --git a/packages/client/src/schema-component/antd/action/Action.Link.tsx b/packages/client/src/schema-component/antd/action/Action.Link.tsx index d28a15470..da4285cab 100644 --- a/packages/client/src/schema-component/antd/action/Action.Link.tsx +++ b/packages/client/src/schema-component/antd/action/Action.Link.tsx @@ -1,4 +1,4 @@ -import { observer, RecursionField, useField, useFieldSchema } from '@formily/react'; +import { observer, useField, useFieldSchema } from '@formily/react'; import React, { useState } from 'react'; import { Link } from 'react-router-dom'; import { ActionContext } from './context'; @@ -23,7 +23,7 @@ export const ActionLink: ComposedAction = observer((props: any) => { > {field.title} - + {props.children} ); }); diff --git a/packages/client/src/schema-component/antd/action/Action.tsx b/packages/client/src/schema-component/antd/action/Action.tsx index d94027398..158256489 100644 --- a/packages/client/src/schema-component/antd/action/Action.tsx +++ b/packages/client/src/schema-component/antd/action/Action.tsx @@ -1,4 +1,4 @@ -import { observer, RecursionField, useField, useFieldSchema } from '@formily/react'; +import { observer, useField, useFieldSchema } from '@formily/react'; import { Button } from 'antd'; import React, { useState } from 'react'; import ActionContainer from './Action.Container'; @@ -28,7 +28,7 @@ export const Action: ComposedAction = observer((props: any) => { > {field.title} - + {props.children} ); }); diff --git a/packages/client/src/schema-component/antd/array-table/Initializer.tsx b/packages/client/src/schema-component/antd/array-table/Initializer.tsx deleted file mode 100644 index cdad10729..000000000 --- a/packages/client/src/schema-component/antd/array-table/Initializer.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { observer } from '@formily/react'; -import React from 'react'; -import { SchemaInitializer } from '../../../schema-initializer'; - -const useTableColumnInitializerFields = () => { - const fields = [ - { - title: 'Field1', - name: 'field1', - component: ArrayTableColumnInitializer, - }, - { - title: 'Field2', - name: 'field2', - component: ArrayTableColumnInitializer, - }, - ].filter((field) => field.component); - return fields; -}; - -export const TableColumnInitializeButton = observer((props: any) => { - return ( - - Configure columns - - ); -}); - -export const ArrayTableColumnInitializer = SchemaInitializer.itemWrap((props) => { - const { insert } = props; - return ( - { - insert({ - type: 'void', - title: 'Name', - 'x-component': 'ArrayTable.Column', - properties: { - name: { - type: 'string', - 'x-component': 'Input', - 'x-read-pretty': true, - }, - }, - }); - }} - /> - ); -}); diff --git a/packages/client/src/schema-component/antd/array-table/TableActionDesignable.tsx b/packages/client/src/schema-component/antd/array-table/TableActionDesignable.tsx new file mode 100644 index 000000000..8554ccba1 --- /dev/null +++ b/packages/client/src/schema-component/antd/array-table/TableActionDesignable.tsx @@ -0,0 +1,41 @@ +import { observer, useFieldSchema } from '@formily/react'; +import React from 'react'; +import { createDesignable, useDesignable } from '../..'; +import { useAPIClient } from '../../../api-client'; + +export const TableActionDesignable = observer((props) => { + const fieldSchema = useFieldSchema(); + const api = useAPIClient(); + const { refresh } = useDesignable(); + return ( +
+ { + const spaceSchema = fieldSchema.reduceProperties((buf, schema) => { + if (schema['x-component'] === 'Space') { + return schema; + } + return buf; + }, null); + const dn = createDesignable({ + current: spaceSchema, + refresh, + api, + }); + dn.loadAPIClientEvents(); + dn.insertBeforeEnd({ + type: 'void', + title: '{{ t("Delete") }}', + 'x-component': 'Action.Link', + 'x-component-props': { + useAction: '{{ useDestroyAction }}', + }, + }); + }} + > + Edit + + {props.children} +
+ ); +}); diff --git a/packages/client/src/schema-component/antd/array-table/TableActionDesignableBar.tsx b/packages/client/src/schema-component/antd/array-table/TableActionDesignableBar.tsx new file mode 100644 index 000000000..b15e90d0f --- /dev/null +++ b/packages/client/src/schema-component/antd/array-table/TableActionDesignableBar.tsx @@ -0,0 +1,4 @@ +import React from 'react'; +export const TableActionDesignableBar = () => { + return
Edit
; +}; diff --git a/packages/client/src/schema-component/antd/array-table/TableColumnActionBar.tsx b/packages/client/src/schema-component/antd/array-table/TableColumnActionBar.tsx new file mode 100644 index 000000000..7e5a80b29 --- /dev/null +++ b/packages/client/src/schema-component/antd/array-table/TableColumnActionBar.tsx @@ -0,0 +1,14 @@ +import { observer, useFieldSchema } from '@formily/react'; +import React from 'react'; +import { useComponent } from '../..'; + +export const TableColumnActionBar = observer((props) => { + const fieldSchema = useFieldSchema(); + const ActionInitializer = useComponent(fieldSchema['x-action-initializer']); + return ( +
+ {ActionInitializer && } + {props.children} +
+ ); +}); diff --git a/packages/client/src/schema-component/antd/array-table/index.ts b/packages/client/src/schema-component/antd/array-table/index.ts index 0db23405e..8bde0aaf1 100644 --- a/packages/client/src/schema-component/antd/array-table/index.ts +++ b/packages/client/src/schema-component/antd/array-table/index.ts @@ -1,4 +1,5 @@ export * from './ArrayTable'; -export * from './Initializer'; +export * from './TableColumnActionBar'; export * from './TableColumnDecorator'; + diff --git a/packages/client/src/schema-component/antd/block-item/BlockItem.tsx b/packages/client/src/schema-component/antd/block-item/BlockItem.tsx index 69aefe9f9..276d3ca61 100644 --- a/packages/client/src/schema-component/antd/block-item/BlockItem.tsx +++ b/packages/client/src/schema-component/antd/block-item/BlockItem.tsx @@ -1,9 +1,18 @@ import React from 'react'; +import { useDesignable } from '../..'; import { SortableItem } from '../../common'; export const BlockItem: React.FC = (props) => { + const { remove } = useDesignable(); return ( + { + remove(); + }} + > + 删除 + {props.children} ); diff --git a/packages/client/src/schema-component/antd/grid/Grid.tsx b/packages/client/src/schema-component/antd/grid/Grid.tsx index 9c7119838..8b4b87efd 100644 --- a/packages/client/src/schema-component/antd/grid/Grid.tsx +++ b/packages/client/src/schema-component/antd/grid/Grid.tsx @@ -6,8 +6,6 @@ import cls from 'classnames'; import React, { createContext, useContext, useState } from 'react'; import { useComponent } from '../..'; import { DndContext } from '../../common/dnd-context'; -import { AddGridBlockItem } from './AddBlockItem'; -import { AddGridFormItem } from './AddFormItem'; const GridRowContext = createContext(null); const GridColContext = createContext(null); @@ -209,6 +207,3 @@ Grid.Col = observer((props: any) => { ); }); - -Grid.AddFormItem = AddGridFormItem; -Grid.AddBlockItem = AddGridBlockItem; diff --git a/packages/client/src/schema-component/antd/grid/demos/demo2.tsx b/packages/client/src/schema-component/antd/grid/demos/demo2.tsx index 5099cae54..32775003a 100644 --- a/packages/client/src/schema-component/antd/grid/demos/demo2.tsx +++ b/packages/client/src/schema-component/antd/grid/demos/demo2.tsx @@ -1,6 +1,15 @@ import { ISchema } from '@formily/react'; import { uid } from '@formily/shared'; -import { Form, FormItem, Grid, Input, Markdown, SchemaComponent, SchemaComponentProvider } from '@nocobase/client'; +import { + Form, + FormItem, + Grid, + Input, + Markdown, + SchemaComponent, + SchemaComponentProvider, + SchemaInitializerProvider +} from '@nocobase/client'; import React from 'react'; const schema: ISchema = { @@ -8,7 +17,7 @@ const schema: ISchema = { name: 'grid1', 'x-decorator': 'Form', 'x-component': 'Grid', - 'x-item-initializer': 'Grid.AddFormItem', + 'x-item-initializer': 'AddFormItem', 'x-uid': uid(), properties: { row1: { @@ -56,7 +65,9 @@ const schema: ISchema = { export default function App() { return ( - + + + ); } diff --git a/packages/client/src/schema-component/antd/grid/demos/demo3.tsx b/packages/client/src/schema-component/antd/grid/demos/demo3.tsx index 4bbe29673..a7da5e35f 100644 --- a/packages/client/src/schema-component/antd/grid/demos/demo3.tsx +++ b/packages/client/src/schema-component/antd/grid/demos/demo3.tsx @@ -9,6 +9,7 @@ import { Markdown, SchemaComponent, SchemaComponentProvider, + SchemaInitializerProvider, VoidTable } from '@nocobase/client'; import React from 'react'; @@ -29,7 +30,7 @@ const schema: ISchema = { grid: { type: 'void', 'x-component': 'Grid', - 'x-item-initializer': 'Grid.AddBlockItem', + 'x-item-initializer': 'AddBlockItem', 'x-uid': uid(), properties: {}, }, @@ -39,7 +40,9 @@ const schema: ISchema = { export default function App() { return ( - + + + ); } diff --git a/packages/client/src/schema-component/hooks/useDesignable.tsx b/packages/client/src/schema-component/hooks/useDesignable.tsx index ba52b39ba..9f6607c99 100644 --- a/packages/client/src/schema-component/hooks/useDesignable.tsx +++ b/packages/client/src/schema-component/hooks/useDesignable.tsx @@ -475,7 +475,7 @@ export function useDesignable() { update(key); refresh(); }, - remove(schema: any, options?: RemoveOptions) { + remove(schema?: any, options?: RemoveOptions) { dn.remove(schema, options); }, insertAdjacent(position: Position, schema: ISchema, options?: InsertAdjacentOptions) { diff --git a/packages/client/src/schema-initializer/Initializers/BlockInitializer/FormBlockInitializerItem.tsx b/packages/client/src/schema-initializer/Initializers/BlockInitializer/FormBlockInitializerItem.tsx new file mode 100644 index 000000000..cd1ce13c1 --- /dev/null +++ b/packages/client/src/schema-initializer/Initializers/BlockInitializer/FormBlockInitializerItem.tsx @@ -0,0 +1,260 @@ +import { TableOutlined } from '@ant-design/icons'; +import { ISchema } from '@formily/react'; +import { clone } from '@formily/shared'; +import React from 'react'; +import { SchemaInitializer } from '../../'; +import { CollectionOptions, useCollectionManager } from '../../../collection-manager'; + +const collection: CollectionOptions = { + name: 'collections', + filterTargetKey: 'name', + targetKey: 'name', + fields: [ + { + type: 'integer', + name: 'title', + interface: 'input', + uiSchema: { + title: '数据表名称', + type: 'number', + 'x-component': 'Input', + required: true, + }, + }, + { + type: 'string', + name: 'name', + interface: 'input', + uiSchema: { + title: '数据表标识', + type: 'string', + 'x-component': 'Input', + description: '使用英文', + }, + }, + { + type: 'hasMany', + name: 'fields', + target: 'fields', + collectionName: 'collections', + sourceKey: 'name', + targetKey: 'name', + uiSchema: {}, + }, + ], +}; + +export const collectionSchema: ISchema = { + type: 'void', + 'x-collection': 'collections', + 'x-component': 'CardItem', + 'x-decorator': 'ResourceActionProvider', + 'x-decorator-props': { + collection, + request: { + resource: 'collections', + action: 'list', + params: { + pageSize: 5, + filter: {}, + sort: ['sort'], + appends: [], + }, + }, + }, + properties: { + actions: { + type: 'void', + 'x-component': 'ActionBar', + 'x-action-initializer': 'AddActionButton', + properties: { + delete: { + type: 'void', + title: '删除', + 'x-component': 'Action', + }, + create: { + type: 'void', + title: '创建', + 'x-component': 'Action', + 'x-component-props': { + type: 'primary', + }, + properties: { + drawer: { + type: 'void', + 'x-component': 'Action.Drawer', + 'x-decorator': 'Form', + title: 'Drawer Title', + properties: { + title: { + 'x-component': 'CollectionField', + 'x-decorator': 'FormItem', + }, + name: { + 'x-component': 'CollectionField', + 'x-decorator': 'FormItem', + }, + footer: { + type: 'void', + 'x-component': 'Action.Drawer.Footer', + properties: { + action1: { + title: 'Cancel', + 'x-component': 'Action', + 'x-component-props': { + useAction: '{{ useCancelAction }}', + }, + }, + action2: { + title: 'Submit', + 'x-component': 'Action', + 'x-component-props': { + type: 'primary', + useAction: '{{ useCreateAction }}', + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + table1: { + type: 'void', + 'x-component': 'VoidTable', + 'x-component-props': { + rowKey: 'id', + rowSelection: { + type: 'checkbox', + }, + useDataSource: '{{ useDataSourceFromRAC }}', + }, + 'x-column-initializer': 'AddTableColumn', + properties: { + column3: { + type: 'void', + title: 'Actions', + 'x-component': 'VoidTable.Column', + properties: { + actions: { + type: 'void', + 'x-component': 'Space', + 'x-component-props': { + split: '|', + }, + properties: { + view: { + type: 'void', + title: '配置字段', + 'x-component': 'Action.Link', + 'x-component-props': {}, + properties: { + drawer: { + type: 'void', + 'x-component': 'Action.Drawer', + title: 'Drawer Title', + properties: {}, + }, + }, + }, + update: { + type: 'void', + title: '编辑', + 'x-component': 'Action.Link', + 'x-component-props': { + type: 'primary', + }, + properties: { + drawer: { + type: 'void', + 'x-component': 'Action.Drawer', + 'x-decorator': 'Form', + 'x-decorator-props': { + useValues: '{{ useValues }}', + }, + title: 'Drawer Title', + properties: { + title: { + 'x-component': 'CollectionField', + 'x-decorator': 'FormItem', + }, + name: { + 'x-component': 'CollectionField', + 'x-decorator': 'FormItem', + 'x-disabled': true, + }, + footer: { + type: 'void', + 'x-component': 'Action.Drawer.Footer', + properties: { + action1: { + title: 'Cancel', + 'x-component': 'Action', + 'x-component-props': { + useAction: '{{ useCancelAction }}', + }, + }, + action2: { + title: 'Submit', + 'x-component': 'Action', + 'x-component-props': { + type: 'primary', + useAction: '{{ useUpdateAction }}', + }, + }, + }, + }, + }, + }, + }, + }, + delete: { + type: 'void', + title: '删除', + 'x-component': 'Action.Link', + 'x-component-props': { + useAction: '{{ useDestroyAction }}', + }, + }, + }, + }, + }, + }, + }, + }, + }, +}; + +const itemWrap = SchemaInitializer.itemWrap; + +export const FormBlockInitializerItem = itemWrap((props) => { + const { insert } = props; + const { collections } = useCollectionManager(); + + return ( + } + onClick={() => { + insert(clone(collectionSchema)); + }} + items={[ + { + type: 'itemGroup', + title: 'select a data source', + children: collections?.map((item) => { + return { + type: 'item', + name: item.name, + title: item.title, + }; + }), + }, + ]} + > + Form + + ); +}); diff --git a/packages/client/src/schema-initializer/Initializers/BlockInitializer/TableBlockInitializerItem.tsx b/packages/client/src/schema-initializer/Initializers/BlockInitializer/TableBlockInitializerItem.tsx new file mode 100644 index 000000000..02ece97fe --- /dev/null +++ b/packages/client/src/schema-initializer/Initializers/BlockInitializer/TableBlockInitializerItem.tsx @@ -0,0 +1,135 @@ +import { TableOutlined } from '@ant-design/icons'; +import { ISchema } from '@formily/react'; +import { clone } from '@formily/shared'; +import React from 'react'; +import { SchemaInitializer } from '../..'; +import { CollectionOptions, useCollectionManager } from '../../../collection-manager'; + +const collection: CollectionOptions = { + name: 'collections', + filterTargetKey: 'name', + targetKey: 'name', + fields: [ + { + type: 'integer', + name: 'title', + interface: 'input', + uiSchema: { + title: '数据表名称', + type: 'number', + required: true, + 'x-component': 'Input', + }, + }, + { + type: 'string', + name: 'name', + interface: 'input', + uiSchema: { + title: '数据表标识', + type: 'string', + description: '使用英文', + 'x-component': 'Input', + }, + }, + { + type: 'hasMany', + name: 'fields', + target: 'fields', + collectionName: 'collections', + sourceKey: 'name', + targetKey: 'name', + uiSchema: {}, + }, + ], +}; + +export const collectionSchema: ISchema = { + type: 'void', + 'x-collection': 'collections', + 'x-component': 'CardItem', + 'x-decorator': 'ResourceActionProvider', + 'x-decorator-props': { + collection, + request: { + resource: 'collections', + action: 'list', + params: { + pageSize: 5, + filter: {}, + sort: ['sort'], + appends: [], + }, + }, + }, + properties: { + actions: { + type: 'void', + 'x-component': 'ActionBar', + 'x-action-initializer': 'TableActionInitializer', + properties: {}, + }, + table1: { + type: 'void', + 'x-component': 'VoidTable', + 'x-component-props': { + rowKey: 'id', + rowSelection: { + type: 'checkbox', + }, + useDataSource: '{{ useDataSourceFromRAC }}', + }, + 'x-column-initializer': 'TableColumnInitializer', + properties: { + actions: { + type: 'void', + title: 'Actions', + 'x-decorator': 'TableColumnActionBar', + 'x-component': 'VoidTable.Column', + 'x-action-initializer': 'TableColumnActionInitializer', + properties: { + actions: { + type: 'void', + 'x-component': 'Space', + 'x-component-props': { + split: '|', + }, + properties: {}, + }, + }, + }, + }, + }, + }, +}; + +const itemWrap = SchemaInitializer.itemWrap; + +export const TableBlockInitializerItem = itemWrap((props) => { + const { insert } = props; + const { collections } = useCollectionManager(); + + return ( + } + onClick={() => { + insert(clone(collectionSchema)); + }} + items={[ + { + type: 'itemGroup', + title: 'select a data source', + children: collections?.map((item) => { + return { + type: 'item', + name: item.name, + title: item.title, + }; + }), + }, + ]} + > + Table + + ); +}); diff --git a/packages/client/src/schema-component/antd/grid/AddBlockItem.tsx b/packages/client/src/schema-initializer/Initializers/BlockInitializer/index.tsx similarity index 63% rename from packages/client/src/schema-component/antd/grid/AddBlockItem.tsx rename to packages/client/src/schema-initializer/Initializers/BlockInitializer/index.tsx index e136abf71..31b9fbf06 100644 --- a/packages/client/src/schema-component/antd/grid/AddBlockItem.tsx +++ b/packages/client/src/schema-initializer/Initializers/BlockInitializer/index.tsx @@ -1,8 +1,10 @@ -import { FormOutlined, TableOutlined } from '@ant-design/icons'; +import { FormOutlined } from '@ant-design/icons'; import { ISchema, observer } from '@formily/react'; import { uid } from '@formily/shared'; import React from 'react'; -import { SchemaInitializer } from '../../../schema-initializer'; +import { SchemaInitializer } from '../..'; +import { FormBlockInitializerItem } from './FormBlockInitializerItem'; +import { TableBlockInitializerItem } from './TableBlockInitializerItem'; const gridRowColWrap = (schema: ISchema) => { return { @@ -22,87 +24,6 @@ const gridRowColWrap = (schema: ISchema) => { const itemWrap = SchemaInitializer.itemWrap; -const TableBlockInitializerItem = itemWrap((props) => { - const { insert } = props; - return ( - } - onClick={() => { - insert({ - type: 'void', - 'x-component': 'VoidTable', - 'x-decorator': 'CardItem', - }); - }} - items={[ - { - type: 'itemGroup', - title: 'select a data source', - children: [ - { - type: 'item', - name: 'users', - title: 'Users', - }, - { - type: 'item', - name: 'posts', - title: 'Posts', - }, - ], - }, - ]} - > - Table - - ); -}); - -const FormBlockInitializerItem = itemWrap((props) => { - const { insert } = props; - return ( - } - onClick={() => { - insert({ - type: 'void', - 'x-uid': uid(), - 'x-component': 'Form', - 'x-decorator': 'CardItem', - properties: { - [uid()]: { - type: 'void', - 'x-component': 'Grid', - 'x-item-initializer': 'Grid.AddFormItem', - 'x-uid': uid(), - }, - }, - }); - }} - items={[ - { - type: 'itemGroup', - title: 'select a data source', - children: [ - { - type: 'item', - name: 'users', - title: 'Users', - }, - { - type: 'item', - name: 'posts', - title: 'Posts', - }, - ], - }, - ]} - > - Form - - ); -}); - const TestInitializerItem = itemWrap((props) => { const { insert } = props; return ( @@ -193,7 +114,7 @@ const TestInitializerItem = itemWrap((props) => { ); }); -export const AddGridBlockItem = observer((props: any) => { +export const BlockInitializer = observer((props: any) => { return ( { title: 'Form', component: FormBlockInitializerItem, }, - { - type: 'item', - title: 'Test', - component: TestInitializerItem, - }, ], }, ]} diff --git a/packages/client/src/schema-initializer/Initializers/DetailsActionInitializer/index.tsx b/packages/client/src/schema-initializer/Initializers/DetailsActionInitializer/index.tsx new file mode 100644 index 000000000..3131d07bc --- /dev/null +++ b/packages/client/src/schema-initializer/Initializers/DetailsActionInitializer/index.tsx @@ -0,0 +1,84 @@ +import { observer, useFieldSchema } from '@formily/react'; +import { Switch } from 'antd'; +import React from 'react'; +import { SchemaInitializer } from '../..'; +import { useDesignable } from '../../../schema-component'; + +const useCurrentActionSchema = (action: string) => { + const fieldSchema = useFieldSchema(); + const { remove } = useDesignable(); + const schema = fieldSchema.reduceProperties((buf, s) => { + if (s['x-action'] === action) { + return s; + } + return buf; + }); + return { + schema, + exists: !!schema, + remove() { + schema && remove(schema); + }, + }; +}; + +const InitializeAction = SchemaInitializer.itemWrap((props) => { + const { item, insert } = props; + const { exists, remove } = useCurrentActionSchema(item.schema['x-action']); + return ( + { + if (exists) { + return remove(); + } + insert({ + type: 'void', + 'x-component': 'Action', + ...item.schema, + }); + }} + > +
+ {item.title} +
+
+ ); +}); + +export const DetailsActionInitializer = observer((props: any) => { + return ( + + Configure actions + + ); +}); diff --git a/packages/client/src/schema-component/antd/grid/AddFormItem.tsx b/packages/client/src/schema-initializer/Initializers/FormItemInitializer/index.tsx similarity index 96% rename from packages/client/src/schema-component/antd/grid/AddFormItem.tsx rename to packages/client/src/schema-initializer/Initializers/FormItemInitializer/index.tsx index 08ec048f3..abe1c355d 100644 --- a/packages/client/src/schema-component/antd/grid/AddFormItem.tsx +++ b/packages/client/src/schema-initializer/Initializers/FormItemInitializer/index.tsx @@ -2,8 +2,8 @@ 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'; +import { SchemaInitializer, SchemaInitializerItemOptions } from '../..'; +import { useDesignable } from '../../../schema-component'; const useFormItemInitializerFields = () => { return [ @@ -122,7 +122,7 @@ const InitializeTextFormItem = itemWrap((props) => { ); }); -export const AddGridFormItem = observer((props: any) => { +export const FormItemInitializer = observer((props: any) => { return ( { + return { + type: 'void', + 'x-component': 'Grid.Row', + properties: { + [uid()]: { + type: 'void', + 'x-component': 'Grid.Col', + properties: { + [schema.name || uid()]: schema, + }, + }, + }, + }; +}; + +const itemWrap = SchemaInitializer.itemWrap; + +const TestInitializerItem = itemWrap((props) => { + const { insert } = props; + return ( + } + onClick={() => { + insert({ + type: 'void', + name: uid(), + 'x-decorator': 'CardItem', + 'x-component': 'Grid', + 'x-uid': uid(), + properties: { + row1: { + type: 'void', + 'x-component': 'Grid.Row', + 'x-uid': uid(), + properties: { + col11: { + type: 'void', + 'x-component': 'Grid.Col', + properties: { + block1: { + type: 'void', + title: '1', + 'x-decorator': 'BlockItem', + 'x-component': 'Block', + }, + block2: { + type: 'void', + title: '2', + 'x-decorator': 'BlockItem', + 'x-component': 'Block', + }, + }, + }, + col12: { + type: 'void', + 'x-component': 'Grid.Col', + properties: { + block3: { + type: 'void', + title: '3', + 'x-decorator': 'BlockItem', + 'x-component': 'Block', + }, + }, + }, + }, + }, + row2: { + type: 'void', + 'x-component': 'Grid.Row', + 'x-uid': uid(), + properties: { + col21: { + type: 'void', + 'x-component': 'Grid.Col', + properties: { + block4: { + type: 'void', + title: '4', + 'x-decorator': 'BlockItem', + 'x-component': 'Block', + }, + }, + }, + col22: { + type: 'void', + 'x-component': 'Grid.Col', + properties: { + block5: { + type: 'void', + title: '5', + 'x-decorator': 'BlockItem', + 'x-component': 'Block', + }, + }, + }, + }, + }, + }, + }); + }} + > + Test + + ); +}); + +export const RecordBlockInitializer = observer((props: any) => { + return ( + + Add block + + ); +}); diff --git a/packages/client/src/schema-initializer/Initializers/TableActionInitializer/index.tsx b/packages/client/src/schema-initializer/Initializers/TableActionInitializer/index.tsx new file mode 100644 index 000000000..54e51556e --- /dev/null +++ b/packages/client/src/schema-initializer/Initializers/TableActionInitializer/index.tsx @@ -0,0 +1,96 @@ +import { observer, useFieldSchema } from '@formily/react'; +import { Switch } from 'antd'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { SchemaInitializer } from '../..'; +import { useDesignable } from '../../../schema-component'; + +const useCurrentActionSchema = (action: string) => { + const fieldSchema = useFieldSchema(); + const { remove } = useDesignable(); + const schema = fieldSchema.reduceProperties((buf, s) => { + if (s['x-action'] === action) { + return s; + } + return buf; + }); + return { + schema, + exists: !!schema, + remove() { + schema && remove(schema); + }, + }; +}; + +const InitializeAction = SchemaInitializer.itemWrap((props) => { + const { item, insert } = props; + const { exists, remove } = useCurrentActionSchema(item.schema['x-action']); + return ( + { + if (exists) { + return remove(); + } + insert({ + type: 'void', + 'x-component': 'Action', + ...item.schema, + }); + }} + > +
+ {item.title} + +
+
+ ); +}); + +export const TableActionInitializer = observer((props: any) => { + const { t } = useTranslation(); + return ( + + {t('Configure actions')} + + ); +}); diff --git a/packages/client/src/schema-initializer/Initializers/TableColumnActionInitializer/index.tsx b/packages/client/src/schema-initializer/Initializers/TableColumnActionInitializer/index.tsx new file mode 100644 index 000000000..5a740ae31 --- /dev/null +++ b/packages/client/src/schema-initializer/Initializers/TableColumnActionInitializer/index.tsx @@ -0,0 +1,145 @@ +import { observer, Schema, useFieldSchema } from '@formily/react'; +import { Switch } from 'antd'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { SchemaInitializer } from '../..'; +import { useAPIClient } from '../../../api-client'; +import { createDesignable, useDesignable } from '../../../schema-component'; + +const useCurrentActionSchema = (action: string) => { + const fieldSchema = useFieldSchema(); + const { remove } = useDesignable(); + const findActionSchema = (schema: Schema) => { + return schema.reduceProperties((buf, s) => { + if (s['x-action'] === action) { + return s; + } + const c = findActionSchema(s); + if (c) { + return c; + } + return buf; + }); + }; + const schema = findActionSchema(fieldSchema); + return { + schema, + exists: !!schema, + remove() { + schema && remove(schema); + }, + }; +}; + +const InitializeAction = SchemaInitializer.itemWrap((props) => { + const { item, insert } = props; + const { exists, remove } = useCurrentActionSchema(item.schema['x-action']); + return ( + { + console.log('InitializeAction', insert); + if (exists) { + return remove(); + } + insert({ + type: 'void', + 'x-component': 'Action.Link', + ...item.schema, + }); + }} + > +
+ {item.title} +
+
+ ); +}); + +export const TableColumnActionInitializer = observer((props: any) => { + const fieldSchema = useFieldSchema(); + const api = useAPIClient(); + const { refresh } = useDesignable(); + const { t } = useTranslation(); + return ( + { + const spaceSchema = fieldSchema.reduceProperties((buf, schema) => { + if (schema['x-component'] === 'Space') { + return schema; + } + return buf; + }, null); + if (!spaceSchema) { + return; + } + const dn = createDesignable({ + api, + refresh, + current: spaceSchema, + }); + dn.loadAPIClientEvents(); + dn.insertBeforeEnd(schema); + }} + items={[ + { + type: 'itemGroup', + title: t('Enable actions'), + children: [ + { + type: 'item', + title: t('View'), + component: InitializeAction, + schema: { + title: '{{ t("View") }}', + type: 'void', + 'x-action': 'view', + 'x-component': 'Action.Link', + 'x-component-props': {}, + properties: { + drawer: { + type: 'void', + 'x-component': 'Action.Drawer', + title: '{{ t("View record") }}', + properties: {}, + }, + }, + }, + }, + { + type: 'item', + title: t('Edit'), + component: InitializeAction, + schema: { + title: '{{ t("Edit") }}', + type: 'void', + 'x-action': 'update', + 'x-component': 'Action.Link', + 'x-component-props': {}, + properties: { + drawer: { + type: 'void', + 'x-component': 'Action.Drawer', + title: '{{ t("Edit record") }}', + properties: {}, + }, + }, + } + }, + { + type: 'item', + title: t('Delete'), + component: InitializeAction, + schema: { + title: '{{ t("Delete") }}', + 'x-action': 'destroy', + }, + }, + ], + }, + ]} + > + Configure + + ); +}); diff --git a/packages/client/src/schema-initializer/Initializers/TableColumnInitializer/index.tsx b/packages/client/src/schema-initializer/Initializers/TableColumnInitializer/index.tsx new file mode 100644 index 000000000..d9037cc93 --- /dev/null +++ b/packages/client/src/schema-initializer/Initializers/TableColumnInitializer/index.tsx @@ -0,0 +1,99 @@ +import { observer, Schema, useFieldSchema } from '@formily/react'; +import { Switch } from 'antd'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { SchemaInitializer, SchemaInitializerItemOptions } from '../..'; +import { useCollection, useDesignable } from '../../..'; + +const useTableColumnInitializerFields = () => { + const { name, fields } = useCollection(); + return fields + .filter((field) => field?.uiSchema?.title) + .map((field) => { + return { + type: 'item', + title: field?.uiSchema?.title, + schema: { + name: field.name, + 'x-collection-field': `${name}.${field.name}`, + 'x-component': 'CollectionField', + }, + component: ColumnInitializerItem, + } as SchemaInitializerItemOptions; + }); +}; + +const useCurrentColumnSchema = (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.parent); + }, + }; +}; + +const ColumnInitializerItem = SchemaInitializer.itemWrap((props) => { + const { item, insert } = props; + const { exists, remove } = useCurrentColumnSchema(item.schema['x-collection-field']); + return ( + { + if (exists) { + return remove(); + } + insert({ + type: 'void', + 'x-decorator': 'TableColumnDecorator', + 'x-component': 'VoidTable.Column', + properties: { + [item.schema.name]: { + 'x-read-pretty': true, + ...item.schema, + }, + }, + }); + }} + > +
+ {item.title} +
+
+ ); +}); + +/** + * 表格列配置器 + */ +export const TableColumnInitializer = observer((props: any) => { + const { t } = useTranslation(); + return ( + + {t('Configure columns')} + + ); +}); diff --git a/packages/client/src/schema-initializer/Initializers/index.ts b/packages/client/src/schema-initializer/Initializers/index.ts new file mode 100644 index 000000000..13b8ff42f --- /dev/null +++ b/packages/client/src/schema-initializer/Initializers/index.ts @@ -0,0 +1,8 @@ +export * from './BlockInitializer'; +export * from './DetailsActionInitializer'; +export * from './FormItemInitializer'; +export * from './RecordBlockInitializer'; +export * from './TableActionInitializer'; +export * from './TableColumnActionInitializer'; +export * from './TableColumnInitializer'; + diff --git a/packages/client/src/schema-initializer/SchemaInitializer.tsx b/packages/client/src/schema-initializer/SchemaInitializer.tsx index 0cabb87d6..d27305bdd 100644 --- a/packages/client/src/schema-initializer/SchemaInitializer.tsx +++ b/packages/client/src/schema-initializer/SchemaInitializer.tsx @@ -16,10 +16,16 @@ export const SchemaInitializerItemContext = createContext(null); export const SchemaInitializer = () => null; SchemaInitializer.Button = observer((props: SchemaInitializerButtonProps) => { - const { wrap = defaultWrap, items = [], insertPosition, dropdown, ...others } = props; - const { insertAdjacent, findComponent } = useDesignable(); + const { insert, wrap = defaultWrap, items = [], insertPosition, dropdown, ...others } = props; + let { insertAdjacent, findComponent } = useDesignable(); const [visible, setVisible] = useState(false); - + const insertSchema = (schema) => { + if (props.insert) { + props.insert(wrap(schema)); + } else { + insertAdjacent(insertPosition, wrap(schema)); + } + }; const menu = ( {items?.map((item, indexA) => { @@ -36,18 +42,10 @@ SchemaInitializer.Button = observer((props: SchemaInitializerButtonProps) => { index: indexA, item, info: item, - insert: (schema) => { - insertAdjacent(insertPosition, wrap(schema)); - }, + insert: insertSchema, }} > - { - insertAdjacent(insertPosition, wrap(schema)); - }} - /> + ) ); @@ -68,18 +66,10 @@ SchemaInitializer.Button = observer((props: SchemaInitializerButtonProps) => { index: indexB, item: child, info: child, - insert: (schema) => { - insertAdjacent(insertPosition, wrap(schema)); - }, + insert: insertSchema, }} > - { - insertAdjacent(insertPosition, wrap(schema)); - }} - /> + ) ); @@ -91,6 +81,8 @@ SchemaInitializer.Button = observer((props: SchemaInitializerButtonProps) => { ); + console.log('others', others); + return ( { + return {props.children}; +}; diff --git a/packages/client/src/schema-initializer/index.ts b/packages/client/src/schema-initializer/index.ts index d7c9df468..c67aed1dd 100644 --- a/packages/client/src/schema-initializer/index.ts +++ b/packages/client/src/schema-initializer/index.ts @@ -1,3 +1,4 @@ export * from './SchemaInitializer'; +export * from './SchemaInitializerProvider'; export * from './types'; diff --git a/packages/client/src/schema-initializer/types.ts b/packages/client/src/schema-initializer/types.ts index e73b61bf0..b3a15ef0b 100644 --- a/packages/client/src/schema-initializer/types.ts +++ b/packages/client/src/schema-initializer/types.ts @@ -2,6 +2,7 @@ import { ISchema } from '@formily/react'; import { ButtonProps, DropDownProps, MenuItemProps } from 'antd'; export interface SchemaInitializerButtonProps extends ButtonProps { + insert?: (s: ISchema) => void; wrap?: (s: ISchema) => ISchema; insertPosition?: 'beforeBegin' | 'afterBegin' | 'beforeEnd' | 'afterEnd'; items?: SchemaInitializerItemOptions[]; diff --git a/packages/plugin-ui-routes-storage/src/index.ts b/packages/plugin-ui-routes-storage/src/index.ts index 12526c35e..b9e9a4dd8 100644 --- a/packages/plugin-ui-routes-storage/src/index.ts +++ b/packages/plugin-ui-routes-storage/src/index.ts @@ -54,12 +54,12 @@ export class UiRoutesStoragePlugin extends Plugin { grid1: { type: 'void', 'x-component': 'Grid', - 'x-item-initializer': 'Grid.AddBlockItem', + 'x-item-initializer': 'BlockInitializer', properties: {}, }, }, - } - } + }, + }, }, item8: { type: 'void',