From 022c173f7ea9a71901bae224c73d1c13ae94a7f5 Mon Sep 17 00:00:00 2001 From: chenos Date: Wed, 16 Feb 2022 15:11:24 +0800 Subject: [PATCH] feat(client): improve code --- .../collection-manager/CollectionField.tsx | 9 +- .../CollectionManagerProvider.tsx | 5 +- ...llectionManagerSchemaComponentProvider.tsx | 20 ++ .../ResourceActionProvider.tsx | 34 ++++ .../src/collection-manager/demos/demo4.tsx | 163 ++++++++++++++++ .../client/src/collection-manager/index.md | 1 + .../client/src/collection-manager/index.tsx | 7 +- .../antd/array-table/TableColumnDecorator.tsx | 54 ++++++ .../antd/array-table/index.ts | 1 + .../antd/void-table/demos/apiClient.ts | 5 +- .../antd/void-table/demos/demo2.tsx | 181 +++++++++--------- 11 files changed, 386 insertions(+), 94 deletions(-) create mode 100644 packages/client/src/collection-manager/CollectionManagerSchemaComponentProvider.tsx create mode 100644 packages/client/src/collection-manager/ResourceActionProvider.tsx create mode 100644 packages/client/src/collection-manager/demos/demo4.tsx create mode 100644 packages/client/src/schema-component/antd/array-table/TableColumnDecorator.tsx diff --git a/packages/client/src/collection-manager/CollectionField.tsx b/packages/client/src/collection-manager/CollectionField.tsx index a3361e53e..b8619f272 100644 --- a/packages/client/src/collection-manager/CollectionField.tsx +++ b/packages/client/src/collection-manager/CollectionField.tsx @@ -1,14 +1,15 @@ -import React, { useContext, useEffect } from 'react'; -import { connect, SchemaOptionsContext, useField, useFieldSchema, useForm } from '@formily/react'; -import { useCollectionField } from './hooks'; -import { CollectionFieldProvider } from './CollectionFieldProvider'; import { Field, FormPath } from '@formily/core'; +import { connect, SchemaOptionsContext, useField, useFieldSchema } from '@formily/react'; +import React, { useContext, useEffect } from 'react'; +import { CollectionFieldProvider } from './CollectionFieldProvider'; +import { useCollectionField } from './hooks'; // TODO: 初步适配 const InternalField: React.FC = (props) => { const field = useField(); const fieldSchema = useFieldSchema(); const { uiSchema } = useCollectionField(); + console.log('uiSchema', uiSchema); const options = useContext(SchemaOptionsContext); const component = FormPath.getIn(options?.components, uiSchema['x-component']); const setFieldProps = (key, value) => { diff --git a/packages/client/src/collection-manager/CollectionManagerProvider.tsx b/packages/client/src/collection-manager/CollectionManagerProvider.tsx index 78af714d5..349ad765a 100644 --- a/packages/client/src/collection-manager/CollectionManagerProvider.tsx +++ b/packages/client/src/collection-manager/CollectionManagerProvider.tsx @@ -1,12 +1,15 @@ import React from 'react'; -import { CollectionManagerOptions } from './types'; +import { CollectionManagerSchemaComponentProvider } from './CollectionManagerSchemaComponentProvider'; import { CollectionManagerContext } from './context'; +import { CollectionManagerOptions } from './types'; export const CollectionManagerProvider: React.FC = (props) => { const { interfaces, collections } = props; return ( + {props.children} + ); }; diff --git a/packages/client/src/collection-manager/CollectionManagerSchemaComponentProvider.tsx b/packages/client/src/collection-manager/CollectionManagerSchemaComponentProvider.tsx new file mode 100644 index 000000000..14d7659a3 --- /dev/null +++ b/packages/client/src/collection-manager/CollectionManagerSchemaComponentProvider.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { SchemaComponentOptions } from '../'; +import { + CollectionField, + CollectionFieldProvider, + CollectionProvider, + ResourceActionProvider, + useDataSourceFromRAC +} from './'; + +export const CollectionManagerSchemaComponentProvider: React.FC = (props) => { + return ( + + {props.children} + + ); +}; diff --git a/packages/client/src/collection-manager/ResourceActionProvider.tsx b/packages/client/src/collection-manager/ResourceActionProvider.tsx new file mode 100644 index 000000000..4cc5b9c69 --- /dev/null +++ b/packages/client/src/collection-manager/ResourceActionProvider.tsx @@ -0,0 +1,34 @@ +import { Result } from 'ahooks/lib/useRequest/src/types'; +import React, { createContext, useContext, useEffect } from 'react'; +import { useRequest } from '../api-client'; + +export const ResourceActionContext = createContext>(null); + +interface ResourceActionProviderProps { + request?: any; + uid?: string; +} + +export const ResourceActionProvider: React.FC = (props) => { + const { request, uid } = props; + console.log(request); + const service = useRequest(request, { + uid, + refreshDeps: [request], + }); + return {props.children}; +}; + +export const useResourceActionContext = () => { + return useContext(ResourceActionContext); +}; + +export const useDataSourceFromRAC = (options: any) => { + const service = useContext(ResourceActionContext); + useEffect(() => { + if (!service.loading) { + options?.onSuccess(service.data); + } + }, [service.loading]); + return service; +}; diff --git a/packages/client/src/collection-manager/demos/demo4.tsx b/packages/client/src/collection-manager/demos/demo4.tsx new file mode 100644 index 000000000..d465bb316 --- /dev/null +++ b/packages/client/src/collection-manager/demos/demo4.tsx @@ -0,0 +1,163 @@ +import { ISchema } from '@formily/react'; +import { + AntdSchemaComponentProvider, CollectionManagerProvider, + SchemaComponent, + SchemaComponentProvider +} from '@nocobase/client'; +import React from 'react'; + +const schema: ISchema = { + type: 'object', + properties: { + block1: { + type: 'void', + 'x-decorator': 'CollectionProvider', + 'x-decorator-props': { + name: 'posts', + }, + properties: { + createdBy: { + 'x-component': 'CollectionField', + 'x-read-pretty': true, + properties: { + rowSelection: { + 'x-component': 'RowSelection', + 'x-component-props': { + rowKey: 'id', + objectValue: true, + rowSelection: { + type: 'checkbox', + }, + dataSource: [ + { id: 1, name: 'Name1' }, + { id: 2, name: 'Name2' }, + { id: 3, name: 'Name3' }, + ], + }, + properties: { + column1: { + type: 'void', + title: 'Name', + 'x-component': 'RowSelection.Column', + properties: { + name: { + type: 'string', + 'x-component': 'Input', + 'x-read-pretty': true, + }, + }, + }, + }, + }, + item: { + 'x-component': 'RecordPicker.SelectedItem', + properties: { + drawer1: { + 'x-component': 'Action.Drawer', + type: 'void', + title: 'Drawer Title', + properties: { + hello1: { + 'x-content': 'Hello', + title: 'T1', + }, + footer1: { + 'x-component': 'Action.Drawer.Footer', + type: 'void', + properties: { + close1: { + type: 'void', + title: 'Close', + 'x-component': 'Action', + 'x-component-props': { + // useAction: '{{ useCloseAction }}', + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, +}; + +const collections = [ + { + name: 'posts', + fields: [ + { + type: 'integer', + name: 'id', + interface: 'input', + uiSchema: { + title: 'ID1', + type: 'number', + 'x-component': 'InputNumber', + required: true, + description: 'description1', + } as ISchema, + }, + { + type: 'string', + name: 'name', + interface: 'input', + uiSchema: { + title: 'Name1', + type: 'string', + 'x-component': 'Input', + required: true, + description: 'description1', + } as ISchema, + }, + { + type: 'string', + name: 'date', + interface: 'datetime', + uiSchema: { + type: 'boolean', + title: `Date1`, + 'x-read-pretty': true, + 'x-decorator': 'FormItem', + 'x-component': 'DatePicker', + 'x-component-props': { + dateFormat: 'YYYY/MM/DD', + // showTime: true, + }, + }, + }, + { + type: 'belongsToMany', + name: 'createdBy', + target: 'users', + foreignKey: 'createdById', + uiSchema: { + type: 'array', + title: `创建人`, + default: [ + { id: 1, name: 'name1' }, + { id: 2, name: 'name2' }, + ], + 'x-decorator': 'FormItem', + 'x-component': 'RecordPicker', + }, + }, + ], + }, +]; + +export default () => { + return ( + + + + + + + + ); +}; diff --git a/packages/client/src/collection-manager/index.md b/packages/client/src/collection-manager/index.md index ad827d03d..c85dcad72 100644 --- a/packages/client/src/collection-manager/index.md +++ b/packages/client/src/collection-manager/index.md @@ -142,3 +142,4 @@ const { name, uiSchema, resource } = useCollectionField(); resource 需要与 `` 搭配使用,用于提供当前数据表行记录的上下文。如: + diff --git a/packages/client/src/collection-manager/index.tsx b/packages/client/src/collection-manager/index.tsx index dcf55241c..e5689827d 100644 --- a/packages/client/src/collection-manager/index.tsx +++ b/packages/client/src/collection-manager/index.tsx @@ -1,8 +1,11 @@ +export * from './CollectionField'; export * from './CollectionFieldProvider'; export * from './CollectionManagerProvider'; +export * from './CollectionManagerSchemaComponentProvider'; +export * from './CollectionManagerShortcut'; export * from './CollectionProvider'; export * from './context'; export * from './hooks'; +export * from './ResourceActionProvider'; export * from './types'; -export * from './CollectionField'; -export * from './CollectionManagerShortcut'; + diff --git a/packages/client/src/schema-component/antd/array-table/TableColumnDecorator.tsx b/packages/client/src/schema-component/antd/array-table/TableColumnDecorator.tsx new file mode 100644 index 000000000..ec5e9a285 --- /dev/null +++ b/packages/client/src/schema-component/antd/array-table/TableColumnDecorator.tsx @@ -0,0 +1,54 @@ +import { useField, useFieldSchema } from '@formily/react'; +import { uid } from '@formily/shared'; +import React, { useEffect } from 'react'; +import { useCollection, useDesignable } from '../../../'; + +export const useColumnSchema = () => { + const { getField } = useCollection(); + const columnSchema = useFieldSchema(); + const fieldSchema = columnSchema.reduceProperties((buf, s) => { + if (s['x-component'] === 'CollectionField') { + return s; + } + return buf; + }, null); + if (!fieldSchema) { + return; + } + const collectionField = getField(fieldSchema.name); + return { columnSchema, fieldSchema, collectionField }; +}; + +export const TableColumnDecorator = (props) => { + const field = useField(); + const { columnSchema, fieldSchema, collectionField } = useColumnSchema(); + const { refresh } = useDesignable(); + useEffect(() => { + if (field.title) { + return; + } + if (!fieldSchema) { + return; + } + if (collectionField?.uiSchema?.title) { + field.title = collectionField?.uiSchema?.title; + } + }, []); + return ( + <> + {props.children} +
{ + field.title = uid(); + columnSchema.title = field.title = field.title; + refresh(); + field.query(`.*.${fieldSchema.name}`).take((f) => { + f.componentProps.dateFormat = 'YYYY-MM-DD'; + }); + }} + > + Edit +
+ + ); +}; 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 0a5379357..0db23405e 100644 --- a/packages/client/src/schema-component/antd/array-table/index.ts +++ b/packages/client/src/schema-component/antd/array-table/index.ts @@ -1,3 +1,4 @@ export * from './ArrayTable'; export * from './Initializer'; +export * from './TableColumnDecorator'; diff --git a/packages/client/src/schema-component/antd/void-table/demos/apiClient.ts b/packages/client/src/schema-component/antd/void-table/demos/apiClient.ts index 3517d836e..ffc6a7220 100644 --- a/packages/client/src/schema-component/antd/void-table/demos/apiClient.ts +++ b/packages/client/src/schema-component/antd/void-table/demos/apiClient.ts @@ -22,7 +22,10 @@ mock.onGet('/posts:list').reply(async (config) => { return { id: v + (page - 1) * pageSize, name: uid(), - date: '2022-01-02 22:22:22' + date: '2022-01-02 22:22:22', + createdBy: [ + { id: 1, name: 'name1' }, + ], }; }), meta: { diff --git a/packages/client/src/schema-component/antd/void-table/demos/demo2.tsx b/packages/client/src/schema-component/antd/void-table/demos/demo2.tsx index e05021507..05f20c0df 100644 --- a/packages/client/src/schema-component/antd/void-table/demos/demo2.tsx +++ b/packages/client/src/schema-component/antd/void-table/demos/demo2.tsx @@ -1,18 +1,13 @@ -import { ISchema, useField, useFieldSchema } from '@formily/react'; -import { uid } from '@formily/shared'; +import { ISchema, observer, useField, useFieldSchema } from '@formily/react'; import { AntdSchemaComponentProvider, APIClientProvider, - CollectionField, CollectionManagerProvider, - CollectionProvider, SchemaComponent, - SchemaComponentProvider, - useCollection, - useDesignable, - useRequest + SchemaComponentProvider } from '@nocobase/client'; -import React, { createContext, useContext, useEffect } from 'react'; +import { Button } from 'antd'; +import React from 'react'; import { apiClient } from './apiClient'; const schema: ISchema = { @@ -30,6 +25,7 @@ const schema: ISchema = { resource: 'posts', action: 'list', params: { + pageSize: 5, filter: {}, sort: [], appends: [], @@ -37,6 +33,9 @@ const schema: ISchema = { }, }, properties: { + settings: { + 'x-component': 'SimpleSettingsForm', + }, table1: { type: 'void', 'x-uid': 'input', @@ -88,6 +87,50 @@ const schema: ISchema = { }, }, }, + column4: { + type: 'void', + // title: 'Name', + 'x-decorator': 'TableColumnDecorator', + 'x-component': 'VoidTable.Column', + properties: { + createdBy: { + 'x-component': 'CollectionField', + 'x-read-pretty': true, + properties: { + item: { + 'x-component': 'RecordPicker.SelectedItem', + properties: { + drawer1: { + 'x-component': 'Action.Drawer', + type: 'void', + title: 'Drawer Title', + properties: { + hello1: { + 'x-content': 'Hello', + title: 'T1', + }, + footer1: { + 'x-component': 'Action.Drawer.Footer', + type: 'void', + properties: { + close1: { + type: 'void', + title: 'Close', + 'x-component': 'Action', + 'x-component-props': { + // useAction: '{{ useCloseAction }}', + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, }, }, }, @@ -95,56 +138,6 @@ const schema: ISchema = { }, }; -const useColumnSchema = () => { - const { getField } = useCollection(); - const columnSchema = useFieldSchema(); - const fieldSchema = columnSchema.reduceProperties((buf, s) => { - if (s['x-component'] === 'CollectionField') { - return s; - } - return buf; - }, null); - if (!fieldSchema) { - return; - } - const collectionField = getField(fieldSchema.name); - return { columnSchema, fieldSchema, collectionField }; -}; - -const TableColumnDecorator = (props) => { - const field = useField(); - const { columnSchema, fieldSchema, collectionField } = useColumnSchema(); - const { refresh } = useDesignable(); - useEffect(() => { - if (field.title) { - return; - } - if (!fieldSchema) { - return; - } - if (collectionField?.uiSchema?.title) { - field.title = collectionField?.uiSchema?.title; - } - }, []); - return ( - <> - {props.children} -
{ - field.title = uid(); - columnSchema.title = field.title = field.title; - refresh(); - field.query(`.*.${fieldSchema.name}`).take((f) => { - f.componentProps.dateFormat = 'YYYY-MM-DD'; - }); - }} - > - Edit -
- - ); -}; - const collections = [ { name: 'posts', @@ -189,41 +182,57 @@ const collections = [ }, }, }, + { + type: 'belongsToMany', + name: 'createdBy', + target: 'users', + foreignKey: 'createdById', + uiSchema: { + type: 'array', + title: `创建人`, + // default: [ + // { id: 1, name: 'name1' }, + // { id: 2, name: 'name2' }, + // ], + 'x-decorator': 'FormItem', + 'x-component': 'RecordPicker', + }, + }, ], }, ]; -const ResourceActionContext = createContext(null); - -const ResourceActionProvider = (props) => { - const { name } = useCollection(); - const { request } = props; - const service = useRequest(request); - return {props.children}; -}; - -const useDataSourceFromRAC = (options: any) => { - const { service } = useContext(ResourceActionContext); - useEffect(() => { - if (!service.loading) { - options?.onSuccess(service.data); - } - }, [service.loading]); - return service; -}; - -const componets = { CollectionProvider, TableColumnDecorator, ResourceActionProvider, CollectionField }; +const SimpleSettingsForm = observer(() => { + const field = useField(); + const fieldSchema = useFieldSchema(); + return ( +
+ +
+
+
+ ); +}); export default () => { return ( - - - - - - - + + + + + + + ); };