From ac4c8f031d76f9884f770d7ac20f8c04c5bd1bf8 Mon Sep 17 00:00:00 2001 From: chenos Date: Fri, 4 Mar 2022 11:59:38 +0800 Subject: [PATCH] feat: improve schema initializer --- .../ResourceActionProvider.tsx | 54 ++++----- .../antd/action/Action.Drawer.tsx | 8 ++ .../LinkToCollectionFieldInitializer.tsx | 41 ++----- .../Items/RecordFormBlockInitializer.tsx | 7 +- .../Items/RecordRelationBlockInitializer.tsx | 79 +++++++++---- .../Initializers/RecordBlockInitializers.tsx | 108 +++++++++++------- .../TableRecordActionInitializers.tsx | 3 + 7 files changed, 174 insertions(+), 126 deletions(-) diff --git a/packages/client/src/collection-manager/ResourceActionProvider.tsx b/packages/client/src/collection-manager/ResourceActionProvider.tsx index 31e187076..6f610c4b1 100644 --- a/packages/client/src/collection-manager/ResourceActionProvider.tsx +++ b/packages/client/src/collection-manager/ResourceActionProvider.tsx @@ -8,13 +8,14 @@ export const ResourceActionContext = createContext & { state?: interface ResourceActionProviderProps { type?: 'association' | 'collection'; + collection?: any; request?: any; uid?: string; } const ResourceContext = createContext(null); -const InternalCollectionResourceActionProvider = (props) => { +const CollectionResourceActionProvider = (props) => { let { collection, request, uid } = props; const api = useAPIClient(); const service = useRequest( @@ -22,7 +23,7 @@ const InternalCollectionResourceActionProvider = (props) => { ...request, params: { ...request?.params, - appends: collection.fields.filter(field => field.target).map((field) => field.name), + appends: collection.fields.filter((field) => field.target).map((field) => field.name), }, }, { uid }, @@ -37,32 +38,26 @@ const InternalCollectionResourceActionProvider = (props) => { ); }; -const CollectionResourceActionProvider = (props) => { - let { collection, request, uid } = props; - const { getCollection } = useCollectionManager(); - if (typeof collection === 'string') { - collection = getCollection(collection); - } - if (!collection) { - return null; - } - return ; -}; - const AssociationResourceActionProvider = (props) => { let { collection, association, request, uid } = props; - const { get } = useCollectionManager(); const api = useAPIClient(); const record = useRecord(); const resourceOf = record[association.sourceKey]; - const service = useRequest({ resourceOf, ...request }, { uid }); + const service = useRequest( + { + resourceOf, + ...request, + params: { + ...request?.params, + appends: [ + ...collection?.fields?.filter?.((field) => field.target).map((field) => field.name), + ...request?.params?.appends, + ], + }, + }, + { uid }, + ); const resource = api.resource(request.resource, resourceOf); - if (typeof collection === 'string') { - collection = get(collection); - } - if (!collection) { - return null; - } return ( @@ -73,11 +68,18 @@ const AssociationResourceActionProvider = (props) => { }; export const ResourceActionProvider: React.FC = (props) => { - const { request } = props; - if (request?.resource?.includes('.')) { - return ; + let { collection, request } = props; + const { getCollection } = useCollectionManager(); + if (typeof collection === 'string') { + collection = getCollection(collection); } - return ; + if (!collection) { + return null; + } + if (request?.resource?.includes('.')) { + return ; + } + return ; }; export const useResourceActionContext = () => { diff --git a/packages/client/src/schema-component/antd/action/Action.Drawer.tsx b/packages/client/src/schema-component/antd/action/Action.Drawer.tsx index ddc60c4f7..e85ea0703 100644 --- a/packages/client/src/schema-component/antd/action/Action.Drawer.tsx +++ b/packages/client/src/schema-component/antd/action/Action.Drawer.tsx @@ -1,6 +1,7 @@ import { css } from '@emotion/css'; import { observer, RecursionField, useField, useFieldSchema } from '@formily/react'; import { Drawer } from 'antd'; +import classNames from 'classnames'; import React from 'react'; import { createPortal } from 'react-dom'; import { useActionContext } from './hooks'; @@ -27,6 +28,13 @@ export const ActionDrawer: ComposedActionDrawer = observer((props) => { destroyOnClose visible={visible} onClose={() => setVisible(false)} + className={classNames(others.className, css` + &.nb-action-popup { + .ant-drawer-content { + background: #f0f2f5; + } + } + `)} footer={ footerSchema && (
{ properties: { drawer1: { 'x-component': 'Action.Drawer', + 'x-component-props': { + }, type: 'void', title: 'Drawer Title', properties: { - details: { + tabs: { type: 'void', - 'x-collection': 'collections', - 'x-decorator': 'ResourceActionProvider', - 'x-decorator-props': { - collection: item.field.target, - request: { - resource: item.field.target, - action: 'get', - params: {}, - }, - }, - 'x-designer': 'Form.Designer', - 'x-component': 'CardItem', + 'x-component': 'Tabs', + 'x-component-props': {}, + 'x-initializer': 'TabPaneInitializers', properties: { - form: { + tab1: { type: 'void', - 'x-decorator': 'Form', - 'x-decorator-props': {}, + title: '详情', + 'x-component': 'Tabs.TabPane', + 'x-designer': 'Tabs.Designer', + 'x-component-props': {}, properties: { - actions: { - type: 'void', - 'x-initializer': 'FormActionInitializers', - 'x-component': 'ActionBar', - 'x-component-props': { - layout: 'one-column', - style: { - marginBottom: 16, - }, - }, - properties: {}, - }, grid: { type: 'void', 'x-component': 'Grid', - 'x-initializer': 'GridFormItemInitializers', + 'x-initializer': 'RecordBlockInitializers', properties: {}, }, }, diff --git a/packages/client/src/schema-initializer/Initializers/Items/RecordFormBlockInitializer.tsx b/packages/client/src/schema-initializer/Initializers/Items/RecordFormBlockInitializer.tsx index efa608f14..578b6d0ef 100644 --- a/packages/client/src/schema-initializer/Initializers/Items/RecordFormBlockInitializer.tsx +++ b/packages/client/src/schema-initializer/Initializers/Items/RecordFormBlockInitializer.tsx @@ -3,12 +3,11 @@ import { ISchema } from '@formily/react'; import React from 'react'; import { useTranslation } from 'react-i18next'; import { SchemaInitializer } from '../..'; -import { useCollectionManager } from '../../../collection-manager'; +import { useCollection } from '../../../collection-manager'; const createSchema = (collectionName) => { const schema: ISchema = { type: 'void', - 'x-collection': 'collections', 'x-decorator': 'ResourceActionProvider', 'x-decorator-props': { collection: collectionName, @@ -53,14 +52,14 @@ const createSchema = (collectionName) => { export const RecordFormBlockInitializer = (props) => { const { insert } = props; - const { collections } = useCollectionManager(); + const { name } = useCollection(); const { t } = useTranslation(); return ( } onClick={({ item }) => { - insert(createSchema(item.name)); + insert(createSchema(name)); }} /> ); diff --git a/packages/client/src/schema-initializer/Initializers/Items/RecordRelationBlockInitializer.tsx b/packages/client/src/schema-initializer/Initializers/Items/RecordRelationBlockInitializer.tsx index 9b2aa069f..747edaed1 100644 --- a/packages/client/src/schema-initializer/Initializers/Items/RecordRelationBlockInitializer.tsx +++ b/packages/client/src/schema-initializer/Initializers/Items/RecordRelationBlockInitializer.tsx @@ -4,45 +4,77 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { SchemaInitializer } from '../..'; import { useCollectionManager } from '../../../collection-manager'; +import { useRecord } from '../../../record-provider'; -const createSchema = (collectionName) => { +const createSchema = (field, record) => { + const resourceOf = record[field.sourceKey || 'id']; const schema: ISchema = { type: 'void', 'x-collection': 'collections', 'x-decorator': 'ResourceActionProvider', 'x-decorator-props': { - collection: collectionName, + collection: field.target, + association: { + name: field.name, + targetKey: field.targetKey, + sourceKey: field.sourceKey, + }, request: { - resource: collectionName, - action: 'get', - params: {}, + resource: `${field.collectionName}.${field.name}`, + // resourceOf, + action: 'list', + params: { + pageSize: 20, + filter: {}, + // sort: ['sort'], + appends: [], + }, }, }, - 'x-designer': 'Form.Designer', + 'x-designer': 'Table.Void.Designer', 'x-component': 'CardItem', properties: { - form: { + actions: { type: 'void', - 'x-decorator': 'Form', - 'x-decorator-props': {}, - properties: { - grid: { - type: 'void', - 'x-component': 'Grid', - 'x-initializer': 'GridFormItemInitializers', - properties: {}, + 'x-initializer': 'TableActionInitializers', + 'x-component': 'ActionBar', + 'x-component-props': { + style: { + marginBottom: 16, }, + }, + properties: {}, + }, + table: { + type: 'void', + 'x-component': 'Table.Void', + 'x-component-props': { + rowKey: 'id', + rowSelection: { + type: 'checkbox', + }, + useDataSource: '{{ cm.useDataSourceFromRAC }}', + }, + 'x-initializer': 'TableColumnInitializers', + properties: { actions: { type: 'void', - 'x-initializer': 'FormActionInitializers', - 'x-component': 'ActionBar', - 'x-component-props': { - layout: 'one-column', - style: { - marginTop: 24, + title: '{{ t("Actions") }}', + 'x-decorator': 'Table.Column.ActionBar', + 'x-component': 'Table.Column', + 'x-designer': 'Table.RowActionDesigner', + 'x-initializer': 'TableRecordActionInitializers', + properties: { + actions: { + type: 'void', + 'x-decorator': 'DndContext', + 'x-component': 'Space', + 'x-component-props': { + split: '|', + }, + properties: {}, }, }, - properties: {}, }, }, }, @@ -55,12 +87,13 @@ export const RecordRelationBlockInitializer = (props) => { const { insert } = props; const { collections } = useCollectionManager(); const { t } = useTranslation(); + const record = useRecord(); return ( } onClick={({ item }) => { - insert(createSchema(item.name)); + insert(createSchema(item.field, record)); }} /> ); diff --git a/packages/client/src/schema-initializer/Initializers/RecordBlockInitializers.tsx b/packages/client/src/schema-initializer/Initializers/RecordBlockInitializers.tsx index dc63d4324..8bd6a29cd 100644 --- a/packages/client/src/schema-initializer/Initializers/RecordBlockInitializers.tsx +++ b/packages/client/src/schema-initializer/Initializers/RecordBlockInitializers.tsx @@ -1,47 +1,67 @@ +import { useFieldSchema } from '@formily/react'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { SchemaInitializer, useCollection } from '../..'; +import { useAPIClient } from '../../api-client'; +import { useDesignable } from '../../schema-component'; import { gridRowColWrap } from './utils'; -// 当前行记录所在面板的添加区块 -export const RecordBlockInitializers = { - wrap: gridRowColWrap, - title: "{{t('Add block')}}", - items: [ - { - type: 'itemGroup', - title: 'Data blocks', - children: [ - { - type: 'item', - title: 'Details', - component: 'RecordFormBlockInitializer', - }, - { - type: 'item', - title: 'Form', - component: 'RecordFormBlockInitializer', - }, - ], - }, - { - type: 'itemGroup', - title: '关系数据区块', - children: [ - { - type: 'item', - title: '关系数据', - component: 'RecordRelationBlockInitializer', - }, - ], - }, - { - type: 'itemGroup', - title: 'Media', - children: [ - { - type: 'item', - title: 'Markdown', - component: 'MarkdownBlockInitializer', - }, - ], - }, - ], +const useRelationFields = () => { + const { fields } = useCollection(); + return fields.filter(field => field.interface === 'linkTo').map((field) => { + return { + type: 'item', + field, + title: field?.uiSchema?.title || field.name, + component: 'RecordRelationBlockInitializer', + }; + }) as any; +}; + +// 当前行记录所在面板的添加区块 +export const RecordBlockInitializers = (props: any) => { + const fieldSchema = useFieldSchema(); + const api = useAPIClient(); + const { refresh } = useDesignable(); + const { t } = useTranslation(); + return ( + + ); }; diff --git a/packages/client/src/schema-initializer/Initializers/TableRecordActionInitializers.tsx b/packages/client/src/schema-initializer/Initializers/TableRecordActionInitializers.tsx index d1faf9780..e98f0bb4a 100644 --- a/packages/client/src/schema-initializer/Initializers/TableRecordActionInitializers.tsx +++ b/packages/client/src/schema-initializer/Initializers/TableRecordActionInitializers.tsx @@ -63,6 +63,9 @@ export const TableRecordActionInitializers = (props: any) => { drawer: { type: 'void', 'x-component': 'Action.Drawer', + 'x-component-props': { + className: 'nb-action-popup', + }, title: '{{ t("View record") }}', properties: { tabs: {