From e6a2a292b3c0a4080f29f36594187c3d484f5670 Mon Sep 17 00:00:00 2001 From: chenos Date: Tue, 6 Jun 2023 19:33:04 +0800 Subject: [PATCH] feat: upgrade formily (#1880) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: upgrade formily * fix: upgrade @formily/json-schema * fix: optimizing performance * fix: performance code * refactor: `React.memo` and `observer` component add `displayName` property * fix: add cache to Schema.compile * feat: 优化代码 * fix: 修复卡顿最终的问题 * Update SchemaComponentProvider.tsx * feat: 再次优化代码 * feat: optimized code --------- Co-authored-by: dream2023 <1098626505@qq.com> --- docs/en-US/development/client/index.md | 1 + .../client/ui-schema-designer/demo1.tsx | 41 +- .../client/ui-schema-designer/designable.md | 10 +- .../extending-schema-components.md | 14 +- .../ui-schema-designer/insert-adjacent.md | 4 +- docs/en-US/welcome/release/v08-changelog.md | 1 + .../client/ui-schema-designer/demo1.tsx | 41 +- .../client/ui-schema-designer/designable.md | 8 +- .../extending-schema-components.md | 16 +- .../ui-schema-designer/insert-adjacent.md | 4 +- docs/zh-CN/development/client/index.md | 1 + .../client/ui-schema-designer/demo1.tsx | 41 +- .../client/ui-schema-designer/designable.md | 8 +- .../extending-schema-components.md | 16 +- .../ui-schema-designer/insert-adjacent.md | 4 +- docs/zh-CN/welcome/release/v08-changelog.md | 1 + .../cli/templates/plugin/src/client/index.tsx | 5 +- packages/core/client/intro.md | 28 +- packages/core/client/package.json | 6 +- .../client/src/application/Application.tsx | 2 + .../src/application/demos/demo1/Hello.tsx | 33 +- .../Configuration/CollectionFieldsTable.tsx | 67 +-- .../CollectionFieldsTableArray.tsx | 373 ++++++------ .../Configuration/ConfigurationTabs.tsx | 100 ++-- .../components/CollectionCategory.tsx | 25 +- .../components/CollectionFieldInterface.tsx | 19 +- .../components/CollectionTemplate.tsx | 17 +- .../Configuration/components/FieldSummary.tsx | 63 +- .../components/TemplateSummay.tsx | 63 +- .../Configuration/components/index.tsx | 220 +++---- .../src/collection-manager/sub-table.tsx | 206 +++---- .../templates/components/PreviewFields.tsx | 1 + .../antd/action/Action.Container.tsx | 36 +- .../antd/action/Action.Drawer.tsx | 214 +++---- .../antd/action/Action.Link.tsx | 9 +- .../antd/action/Action.Modal.tsx | 200 +++---- .../antd/action/Action.Page.tsx | 124 ++-- .../schema-component/antd/action/Action.tsx | 273 +++++---- .../antd/action/ActionBar.tsx | 135 ++--- .../antd/action/demos/demo3.tsx | 49 +- .../antd/action/demos/demo5.tsx | 93 +-- .../AssociationFieldProvider.tsx | 105 ++-- .../association-field/AssociationSelect.tsx | 69 +-- .../antd/association-field/Editable.tsx | 90 +-- .../antd/association-field/InternalPicker.tsx | 267 ++++----- .../antd/association-field/InternalViewer.tsx | 177 +++--- .../antd/association-field/Nester.tsx | 177 +++--- .../antd/association-field/ReadPretty.tsx | 42 +- .../antd/association-field/SubTable.tsx | 45 +- .../components/CreateRecordAction.tsx | 65 ++- .../antd/association-select/ReadPretty.tsx | 13 +- .../antd/block-item/demos/demo1.tsx | 21 +- .../antd/calendar/Calendar.tsx | 133 ++--- .../antd/calendar/DeleteEvent.tsx | 113 ++-- .../schema-component/antd/calendar/Event.tsx | 9 +- .../schema-component/antd/calendar/Nav.tsx | 25 +- .../schema-component/antd/calendar/Title.tsx | 37 +- .../schema-component/antd/calendar/Today.tsx | 33 +- .../antd/calendar/ViewSelect.tsx | 41 +- .../collection-select/CollectionSelect.tsx | 2 +- .../schema-component/antd/filter/Filter.tsx | 61 +- .../antd/filter/FilterAction.tsx | 155 ++--- .../antd/filter/FilterItem.tsx | 109 ++-- .../antd/filter/FilterItems.tsx | 31 +- .../antd/form-item/FormItem.tsx | 105 ++-- .../schema-component/antd/form-v2/Form.tsx | 39 +- .../antd/form-v2/FormField.tsx | 39 +- .../src/schema-component/antd/form/Form.tsx | 57 +- .../antd/form/demos/demo1.tsx | 11 +- .../antd/form/demos/demo2.tsx | 11 +- .../antd/form/demos/demo3.tsx | 11 +- .../antd/form/demos/demo4.tsx | 11 +- .../antd/form/demos/demo5.tsx | 11 +- .../antd/form/demos/demo6.tsx | 11 +- .../antd/form/demos/demo7.tsx | 11 +- .../schema-component/antd/g2plot/G2Plot.tsx | 83 +-- .../antd/gantt/components/gantt/Event.tsx | 9 +- .../src/schema-component/antd/grid/Block.tsx | 21 +- .../src/schema-component/antd/grid/Grid.tsx | 237 ++++---- .../antd/grid/demos/demo1.tsx | 21 +- .../antd/kanban/Kanban.Card.tsx | 181 +++--- .../antd/kanban/Kanban.CardViewer.tsx | 9 +- .../schema-component/antd/kanban/Kanban.tsx | 195 +++---- .../antd/markdown/Markdown.Void.tsx | 79 +-- .../antd/markdown/demos/demo2.tsx | 39 +- .../src/schema-component/antd/menu/Menu.tsx | 542 +++++++++--------- .../antd/pagination/index.tsx | 33 +- .../record-picker/ReadPrettyRecordPicker.tsx | 181 +++--- .../antd/remote-select/ReadPretty.tsx | 35 +- .../antd/select/ReadPretty.tsx | 51 +- .../antd/table-v2/Table.Column.ActionBar.tsx | 21 +- .../schema-component/antd/table-v2/Table.tsx | 485 ++++++++-------- .../antd/table-v2/TableField.tsx | 70 +-- .../antd/table-v2/demos/demo3.tsx | 41 +- .../antd/table/Table.Array.tsx | 179 +++--- .../antd/table/Table.Column.ActionBar.tsx | 21 +- .../antd/table/Table.RowSelection.tsx | 37 +- .../antd/table/Table.Void.tsx | 85 +-- .../antd/table/demos/demo4.tsx | 69 +-- .../src/schema-component/antd/tabs/Tabs.tsx | 70 +-- .../antd/tree-select/ReadPretty.tsx | 87 +-- .../common/dnd-context/index.tsx | 57 +- .../common/sortable-item/SortableItem.tsx | 33 +- .../core/SchemaComponentOptions.tsx | 20 +- .../core/SchemaComponentProvider.tsx | 24 +- .../src/schema-component/demos/demo1.tsx | 108 ++-- .../src/schema-component/hooks/useCompile.ts | 42 +- .../schema-initializer/SchemaInitializer.tsx | 257 +++++---- .../components/CreateRecordAction.tsx | 274 ++++----- .../src/schema-initializer/demos/demo1.tsx | 30 +- .../src/schema-items/GeneralSchemaItems.tsx | 287 +++++----- .../DataTemplates/FormDataTemplates.tsx | 361 ++++++------ .../components/DataTemplateTitle.tsx | 205 +++---- .../DataTemplates/components/Designer.tsx | 251 ++++---- .../EnableChildCollections/index.tsx | 179 +++--- .../LinkageRules/LinkageRuleAction.tsx | 220 +++---- .../LinkageRules/LinkageRuleActionGroup.tsx | 37 +- .../LinkageRules/components/LinkageHeader.tsx | 205 +++---- .../schema-settings/LinkageRules/index.tsx | 201 +++---- .../src/schema-settings/SchemaSettings.tsx | 1 + .../src/schema-templates/BlockTemplate.tsx | 37 +- .../client/src/settings-form/SettingsForm.tsx | 183 +++--- .../client/src/settings-form/demos/demo1.tsx | 23 +- .../src/client/components/AuditLogsField.tsx | 27 +- .../src/client/components/AuditLogsValue.tsx | 41 +- .../src/client/deplicated/AuditLogs.tsx | 181 +++--- .../src/client/ChartBlockInitializer.tsx | 39 +- packages/plugins/charts/src/client/index.tsx | 5 +- .../charts/src/client/select/ReadPretty.tsx | 47 +- packages/plugins/error-handler/package.json | 2 +- .../src/client/ExcelFormula/index.ts | 12 +- .../excel-formula-field/src/client/index.tsx | 6 +- .../src/client/StorageOptions.tsx | 31 +- .../formula-field/src/client/index.tsx | 5 +- .../src/client/GraphCollectionProvider.tsx | 1 + .../src/client/GraphDrawPage.tsx | 1 + .../src/client/action-hooks.tsx | 21 +- .../src/client/components/FieldSummary.tsx | 63 +- .../iframe-block/src/client/Iframe.tsx | 61 +- packages/plugins/map/src/client/index.tsx | 5 +- .../src/client/MathFormula/index.tsx | 12 +- .../math-formula-field/src/client/index.tsx | 5 +- .../oidc/src/client/RedirectURLInput.tsx | 37 +- .../saml/src/client/RedirectURLInput.tsx | 37 +- .../snapshot-field/src/client/index.tsx | 5 +- .../plugins/ui-schema-storage/package.json | 2 +- .../src/client/ProviderOptions.tsx | 38 +- .../client/components/CollectionFieldset.tsx | 219 +++---- .../client/components/DynamicExpression.tsx | 33 +- .../src/client/components/FieldsSelect.tsx | 39 +- .../src/client/nodes/manual/WorkflowTodo.tsx | 33 +- .../triggers/schedule/DateFieldsSelect.tsx | 39 +- packages/samples/command/src/client/index.tsx | 5 +- .../samples/custom-block/src/client/index.tsx | 5 +- .../src/client/index.tsx | 5 +- .../samples/custom-page/src/client/index.tsx | 5 +- .../custom-signup-page/src/client/index.tsx | 5 +- packages/samples/hello/src/client/index.tsx | 5 +- .../samples/ratelimit/src/client/index.tsx | 5 +- .../samples/shop-actions/src/client/index.tsx | 5 +- .../samples/shop-events/src/client/index.tsx | 5 +- .../samples/shop-i18n/src/client/index.tsx | 4 +- .../shop-modeling/src/client/index.tsx | 5 +- yarn.lock | 160 +++--- 164 files changed, 6226 insertions(+), 5660 deletions(-) diff --git a/docs/en-US/development/client/index.md b/docs/en-US/development/client/index.md index 83983e138..9f51ef40a 100644 --- a/docs/en-US/development/client/index.md +++ b/docs/en-US/development/client/index.md @@ -42,6 +42,7 @@ const HelloProvider = React.memo((props) => { } return <>{props.children} }); +HelloProvider.displayName = 'HelloProvider' app.use(HelloProvider); ``` diff --git a/docs/en-US/development/client/ui-schema-designer/demo1.tsx b/docs/en-US/development/client/ui-schema-designer/demo1.tsx index 25469fab9..0b6b08ce4 100644 --- a/docs/en-US/development/client/ui-schema-designer/demo1.tsx +++ b/docs/en-US/development/client/ui-schema-designer/demo1.tsx @@ -4,27 +4,30 @@ import { SchemaComponent, SchemaComponentProvider } from '@nocobase/client'; import { Table, TableColumnType } from 'antd'; import React from 'react'; -const ArrayTable = observer((props: any) => { - const { rowKey } = props; - const field = useField(); - const schema = useFieldSchema(); - const columnSchemas = schema.reduceProperties((buf, s) => { - if (s['x-component'] === 'ArrayTable.Column') { - buf.push(s); - } - return buf; - }, []); +const ArrayTable = observer( + (props: any) => { + const { rowKey } = props; + const field = useField(); + const schema = useFieldSchema(); + const columnSchemas = schema.reduceProperties((buf, s) => { + if (s['x-component'] === 'ArrayTable.Column') { + buf.push(s); + } + return buf; + }, []); - const columns = columnSchemas.map((s) => { - return { - render: (value, record) => { - return ; - }, - } as TableColumnType; - }); + const columns = columnSchemas.map((s) => { + return { + render: (value, record) => { + return ; + }, + } as TableColumnType; + }); - return ; -}); + return
; + }, + { displayName: 'ArrayTable' }, +); const Value = connect((props) => { return
  • value: {props.value}
  • ; diff --git a/docs/en-US/development/client/ui-schema-designer/designable.md b/docs/en-US/development/client/ui-schema-designer/designable.md index 87fc1919f..f725ecd79 100644 --- a/docs/en-US/development/client/ui-schema-designer/designable.md +++ b/docs/en-US/development/client/ui-schema-designer/designable.md @@ -180,11 +180,11 @@ const Hello = observer((props) => {
    {props.children}
    ); -}); +}, { displayName: 'Hello' }); const Page = observer((props) => { return
    {props.children}
    ; -}); +}, { displayName: 'Page' }); export default () => { return ( @@ -240,7 +240,7 @@ const useDragEnd = () => { const Page = observer((props) => { return {props.children}; -}); +}, { displayName: 'Page' }); function Draggable(props) { const { attributes, listeners, setNodeRef, transform } = useDraggable({ @@ -289,7 +289,7 @@ const Block = observer((props) => { ); -}); +}, { displayName: 'Block' }); export default function App() { return ( @@ -316,7 +316,7 @@ export default function App() { ); } ``` -## Applications of `x-designer` +## Applications of `x-designer` `x-designer` is usually used only in wrapper components such as BlockItem, CardItem, FormItem, etc. diff --git a/docs/en-US/development/client/ui-schema-designer/extending-schema-components.md b/docs/en-US/development/client/ui-schema-designer/extending-schema-components.md index 4e269a71c..6178f50ac 100644 --- a/docs/en-US/development/client/ui-schema-designer/extending-schema-components.md +++ b/docs/en-US/development/client/ui-schema-designer/extending-schema-components.md @@ -51,13 +51,13 @@ const ReadPretty = (props) => { }; const SingleText = connect( - Input, + Input, mapProps((props, field) => { return { ...props, suffix: '后缀', } - }), + }), mapReadPretty(ReadPretty), ); @@ -103,7 +103,7 @@ const SingleText = connect(Input); const UsedObserver = observer((props) => { const form = useForm(); return
    UsedObserver: {form.values.t1}
    -}); +}, { displayName: 'UsedObserver' }); const NotUsedObserver = (props) => { const form = useForm(); @@ -192,7 +192,7 @@ export default () => { }; ``` -Comparison of rendering results by property type +Comparison of rendering results by property type ```tsx import React from 'react'; @@ -310,7 +310,7 @@ const ArrayList = observer((props) => { ); -}); +}, { displayName: 'ArrayList' }); const Value = connect((props) => { return
  • value: {props.value}
  • @@ -367,7 +367,7 @@ const ArrayList = observer((props) => { })} ); -}); +}, { displayName: 'ArrayList' }); const Value = connect((props) => { return
  • value: {props.value}
  • @@ -432,7 +432,7 @@ const ArrayTable = observer((props: any) => { }); return
    ; -}); +}, { displayName: 'ArrayTable' }); const Value = connect((props) => { return
  • value: {props.value}
  • ; diff --git a/docs/en-US/development/client/ui-schema-designer/insert-adjacent.md b/docs/en-US/development/client/ui-schema-designer/insert-adjacent.md index f315f0c28..f910e012a 100644 --- a/docs/en-US/development/client/ui-schema-designer/insert-adjacent.md +++ b/docs/en-US/development/client/ui-schema-designer/insert-adjacent.md @@ -116,11 +116,11 @@ const Hello = observer((props) => {
    {props.children}
    ); -}); +}, { displayName: 'Hello' }); const Page = observer((props) => { return
    {props.children}
    ; -}); +}, { displayName: 'Page' }); export default () => { return ( diff --git a/docs/en-US/welcome/release/v08-changelog.md b/docs/en-US/welcome/release/v08-changelog.md index 97cee2d6e..24fc16581 100644 --- a/docs/en-US/welcome/release/v08-changelog.md +++ b/docs/en-US/welcome/release/v08-changelog.md @@ -182,6 +182,7 @@ const HelloProvider = React.memo((props) => { } return <>{props.children} }); +HelloProvider.displayName = 'HelloProvider' app.use(HelloProvider); diff --git a/docs/tr-TR/development/client/ui-schema-designer/demo1.tsx b/docs/tr-TR/development/client/ui-schema-designer/demo1.tsx index 25469fab9..0b6b08ce4 100644 --- a/docs/tr-TR/development/client/ui-schema-designer/demo1.tsx +++ b/docs/tr-TR/development/client/ui-schema-designer/demo1.tsx @@ -4,27 +4,30 @@ import { SchemaComponent, SchemaComponentProvider } from '@nocobase/client'; import { Table, TableColumnType } from 'antd'; import React from 'react'; -const ArrayTable = observer((props: any) => { - const { rowKey } = props; - const field = useField(); - const schema = useFieldSchema(); - const columnSchemas = schema.reduceProperties((buf, s) => { - if (s['x-component'] === 'ArrayTable.Column') { - buf.push(s); - } - return buf; - }, []); +const ArrayTable = observer( + (props: any) => { + const { rowKey } = props; + const field = useField(); + const schema = useFieldSchema(); + const columnSchemas = schema.reduceProperties((buf, s) => { + if (s['x-component'] === 'ArrayTable.Column') { + buf.push(s); + } + return buf; + }, []); - const columns = columnSchemas.map((s) => { - return { - render: (value, record) => { - return ; - }, - } as TableColumnType; - }); + const columns = columnSchemas.map((s) => { + return { + render: (value, record) => { + return ; + }, + } as TableColumnType; + }); - return
    ; -}); + return
    ; + }, + { displayName: 'ArrayTable' }, +); const Value = connect((props) => { return
  • value: {props.value}
  • ; diff --git a/docs/tr-TR/development/client/ui-schema-designer/designable.md b/docs/tr-TR/development/client/ui-schema-designer/designable.md index 2aaa16b4a..676405e3a 100644 --- a/docs/tr-TR/development/client/ui-schema-designer/designable.md +++ b/docs/tr-TR/development/client/ui-schema-designer/designable.md @@ -183,11 +183,11 @@ const Hello = observer((props) => {
    {props.children}
    ); -}); +}, { displayName: 'Hello' }); const Page = observer((props) => { return
    {props.children}
    ; -}); +}, { displayName: 'Page' }); export default () => { return ( @@ -243,7 +243,7 @@ const useDragEnd = () => { const Page = observer((props) => { return {props.children}; -}); +}, { displayName: 'Page' }); function Draggable(props) { const { attributes, listeners, setNodeRef, transform } = useDraggable({ @@ -292,7 +292,7 @@ const Block = observer((props) => { ); -}); +}, { displayName: 'Block' }); export default function App() { return ( diff --git a/docs/tr-TR/development/client/ui-schema-designer/extending-schema-components.md b/docs/tr-TR/development/client/ui-schema-designer/extending-schema-components.md index 5fc966819..89bf45c3e 100644 --- a/docs/tr-TR/development/client/ui-schema-designer/extending-schema-components.md +++ b/docs/tr-TR/development/client/ui-schema-designer/extending-schema-components.md @@ -51,13 +51,13 @@ const ReadPretty = (props) => { }; const SingleText = connect( - Input, + Input, mapProps((props, field) => { return { ...props, suffix: '后缀', } - }), + }), mapReadPretty(ReadPretty), ); @@ -103,7 +103,7 @@ const SingleText = connect(Input); const UsedObserver = observer((props) => { const form = useForm(); return
    UsedObserver: {form.values.t1}
    -}); +}, { displayName: 'UsedObserver' }); const NotUsedObserver = (props) => { const form = useForm(); @@ -193,7 +193,7 @@ export default () => { }; ``` -各类型 properties 渲染结果对比 +各类型 properties 渲染结果对比 ```tsx import React from 'react'; @@ -312,7 +312,7 @@ const ArrayList = observer((props) => { ); -}); +}, { displayName: 'ArrayList' }); const Value = connect((props) => { return
  • value: {props.value}
  • @@ -369,7 +369,7 @@ const ArrayList = observer((props) => { })} ); -}); +}, { displayName: 'ArrayList' }); const Value = connect((props) => { return
  • value: {props.value}
  • @@ -434,7 +434,7 @@ const ArrayTable = observer((props: any) => { }); return
    ; -}); +}, { displayName: 'ArrayTable' }); const Value = connect((props) => { return
  • value: {props.value}
  • ; @@ -515,4 +515,4 @@ export default () => { ); }; -``` \ No newline at end of file +``` diff --git a/docs/tr-TR/development/client/ui-schema-designer/insert-adjacent.md b/docs/tr-TR/development/client/ui-schema-designer/insert-adjacent.md index f315f0c28..f910e012a 100644 --- a/docs/tr-TR/development/client/ui-schema-designer/insert-adjacent.md +++ b/docs/tr-TR/development/client/ui-schema-designer/insert-adjacent.md @@ -116,11 +116,11 @@ const Hello = observer((props) => {
    {props.children}
    ); -}); +}, { displayName: 'Hello' }); const Page = observer((props) => { return
    {props.children}
    ; -}); +}, { displayName: 'Page' }); export default () => { return ( diff --git a/docs/zh-CN/development/client/index.md b/docs/zh-CN/development/client/index.md index d6d44e9fc..d33ac8b86 100644 --- a/docs/zh-CN/development/client/index.md +++ b/docs/zh-CN/development/client/index.md @@ -42,6 +42,7 @@ const HelloProvider = React.memo((props) => { } return <>{props.children} }); +HelloProvider.displayName = 'HelloProvider' app.use(HelloProvider); ``` diff --git a/docs/zh-CN/development/client/ui-schema-designer/demo1.tsx b/docs/zh-CN/development/client/ui-schema-designer/demo1.tsx index 25469fab9..0b6b08ce4 100644 --- a/docs/zh-CN/development/client/ui-schema-designer/demo1.tsx +++ b/docs/zh-CN/development/client/ui-schema-designer/demo1.tsx @@ -4,27 +4,30 @@ import { SchemaComponent, SchemaComponentProvider } from '@nocobase/client'; import { Table, TableColumnType } from 'antd'; import React from 'react'; -const ArrayTable = observer((props: any) => { - const { rowKey } = props; - const field = useField(); - const schema = useFieldSchema(); - const columnSchemas = schema.reduceProperties((buf, s) => { - if (s['x-component'] === 'ArrayTable.Column') { - buf.push(s); - } - return buf; - }, []); +const ArrayTable = observer( + (props: any) => { + const { rowKey } = props; + const field = useField(); + const schema = useFieldSchema(); + const columnSchemas = schema.reduceProperties((buf, s) => { + if (s['x-component'] === 'ArrayTable.Column') { + buf.push(s); + } + return buf; + }, []); - const columns = columnSchemas.map((s) => { - return { - render: (value, record) => { - return ; - }, - } as TableColumnType; - }); + const columns = columnSchemas.map((s) => { + return { + render: (value, record) => { + return ; + }, + } as TableColumnType; + }); - return
    ; -}); + return
    ; + }, + { displayName: 'ArrayTable' }, +); const Value = connect((props) => { return
  • value: {props.value}
  • ; diff --git a/docs/zh-CN/development/client/ui-schema-designer/designable.md b/docs/zh-CN/development/client/ui-schema-designer/designable.md index 2aaa16b4a..676405e3a 100644 --- a/docs/zh-CN/development/client/ui-schema-designer/designable.md +++ b/docs/zh-CN/development/client/ui-schema-designer/designable.md @@ -183,11 +183,11 @@ const Hello = observer((props) => {
    {props.children}
    ); -}); +}, { displayName: 'Hello' }); const Page = observer((props) => { return
    {props.children}
    ; -}); +}, { displayName: 'Page' }); export default () => { return ( @@ -243,7 +243,7 @@ const useDragEnd = () => { const Page = observer((props) => { return {props.children}; -}); +}, { displayName: 'Page' }); function Draggable(props) { const { attributes, listeners, setNodeRef, transform } = useDraggable({ @@ -292,7 +292,7 @@ const Block = observer((props) => { ); -}); +}, { displayName: 'Block' }); export default function App() { return ( diff --git a/docs/zh-CN/development/client/ui-schema-designer/extending-schema-components.md b/docs/zh-CN/development/client/ui-schema-designer/extending-schema-components.md index 5fc966819..89bf45c3e 100644 --- a/docs/zh-CN/development/client/ui-schema-designer/extending-schema-components.md +++ b/docs/zh-CN/development/client/ui-schema-designer/extending-schema-components.md @@ -51,13 +51,13 @@ const ReadPretty = (props) => { }; const SingleText = connect( - Input, + Input, mapProps((props, field) => { return { ...props, suffix: '后缀', } - }), + }), mapReadPretty(ReadPretty), ); @@ -103,7 +103,7 @@ const SingleText = connect(Input); const UsedObserver = observer((props) => { const form = useForm(); return
    UsedObserver: {form.values.t1}
    -}); +}, { displayName: 'UsedObserver' }); const NotUsedObserver = (props) => { const form = useForm(); @@ -193,7 +193,7 @@ export default () => { }; ``` -各类型 properties 渲染结果对比 +各类型 properties 渲染结果对比 ```tsx import React from 'react'; @@ -312,7 +312,7 @@ const ArrayList = observer((props) => { ); -}); +}, { displayName: 'ArrayList' }); const Value = connect((props) => { return
  • value: {props.value}
  • @@ -369,7 +369,7 @@ const ArrayList = observer((props) => { })} ); -}); +}, { displayName: 'ArrayList' }); const Value = connect((props) => { return
  • value: {props.value}
  • @@ -434,7 +434,7 @@ const ArrayTable = observer((props: any) => { }); return
    ; -}); +}, { displayName: 'ArrayTable' }); const Value = connect((props) => { return
  • value: {props.value}
  • ; @@ -515,4 +515,4 @@ export default () => { ); }; -``` \ No newline at end of file +``` diff --git a/docs/zh-CN/development/client/ui-schema-designer/insert-adjacent.md b/docs/zh-CN/development/client/ui-schema-designer/insert-adjacent.md index f315f0c28..f538666b8 100644 --- a/docs/zh-CN/development/client/ui-schema-designer/insert-adjacent.md +++ b/docs/zh-CN/development/client/ui-schema-designer/insert-adjacent.md @@ -116,11 +116,11 @@ const Hello = observer((props) => {
    {props.children}
    ); -}); +}, { displayName: 'Hello' }); const Page = observer((props) => { return
    {props.children}
    ; -}); +}, { displayName: 'Page' }); export default () => { return ( diff --git a/docs/zh-CN/welcome/release/v08-changelog.md b/docs/zh-CN/welcome/release/v08-changelog.md index c32fc777d..d715df275 100644 --- a/docs/zh-CN/welcome/release/v08-changelog.md +++ b/docs/zh-CN/welcome/release/v08-changelog.md @@ -176,6 +176,7 @@ const HelloProvider = React.memo((props) => { } return <>{props.children} }); +HelloProvider.displayName = 'HelloProvider' app.use(HelloProvider); ``` diff --git a/packages/core/cli/templates/plugin/src/client/index.tsx b/packages/core/cli/templates/plugin/src/client/index.tsx index db735f78d..c04046c36 100644 --- a/packages/core/cli/templates/plugin/src/client/index.tsx +++ b/packages/core/cli/templates/plugin/src/client/index.tsx @@ -1,5 +1,8 @@ import React from 'react'; -export default React.memo((props) => { +const CommonMemo = React.memo((props) => { return <>{props.children}; }); +CommonMemo.displayName = 'CommonMemo'; + +export default CommonMemo; diff --git a/packages/core/client/intro.md b/packages/core/client/intro.md index 2cf96c52f..106ff364d 100644 --- a/packages/core/client/intro.md +++ b/packages/core/client/intro.md @@ -168,11 +168,11 @@ const App: React.FC = () => { - 关闭 } @@ -262,8 +262,8 @@ export default function App() { }); }; return ( - @@ -374,7 +374,7 @@ const Action: any = observer((props: any) => { ); -}); +}, { displayName: 'Action' }); Action.Drawer = observer((props: any) => { const [visible, setVisible] = useContext(VisibleContext); @@ -411,13 +411,13 @@ Action.Drawer = observer((props: any) => { )} ); -}); +}, { displayName: 'Action.Drawer' }); Action.Drawer.Footer = observer((props: any) => { const field = useField(); const schema = useFieldSchema(); return ; -}); +}, { displayName: 'Action.Drawer.Footer' }); const schema: ISchema = { type: 'object', @@ -500,7 +500,7 @@ const Hello = observer(({ name }) => { >更新 ) -}); +}, { displayName: 'Hello' }); const RouteSchemaComponent = (props) => { const route = useRoute(); @@ -678,7 +678,7 @@ const useDragEnd = () => { const Page = observer((props) => { return {props.children}; -}); +}, { displayName: 'Page' }); function Draggable(props) { const { attributes, listeners, setNodeRef, transform } = useDraggable({ @@ -727,7 +727,7 @@ const Block = observer((props) => { ); -}); +}, { displayName: 'Block' }); export default function App() { return ( @@ -856,4 +856,4 @@ await respond(ctx); - Provider 的顺序怎么处理 - 如何动态的加载前端模块 -未完待续... \ No newline at end of file +未完待续... diff --git a/packages/core/client/package.json b/packages/core/client/package.json index 313f55d0a..796e1f1b2 100644 --- a/packages/core/client/package.json +++ b/packages/core/client/package.json @@ -10,9 +10,9 @@ "@dnd-kit/core": "^5.0.1", "@dnd-kit/sortable": "^6.0.0", "@emotion/css": "^11.7.1", - "@formily/antd": "2.0.20", - "@formily/core": "2.0.20", - "@formily/react": "2.0.20", + "@formily/antd": "2.2.24", + "@formily/core": "2.2.24", + "@formily/react": "2.2.24", "@nocobase/evaluators": "0.9.4-alpha.2", "@nocobase/sdk": "0.9.4-alpha.2", "@nocobase/utils": "0.9.4-alpha.2", diff --git a/packages/core/client/src/application/Application.tsx b/packages/core/client/src/application/Application.tsx index 79859225c..c1c8c5df8 100644 --- a/packages/core/client/src/application/Application.tsx +++ b/packages/core/client/src/application/Application.tsx @@ -61,6 +61,8 @@ const App = React.memo((props: any) => { return ; }); +App.displayName = 'App'; + export class Application { providers = []; mainComponent = null; diff --git a/packages/core/client/src/application/demos/demo1/Hello.tsx b/packages/core/client/src/application/demos/demo1/Hello.tsx index fe6340ecb..d035a8288 100644 --- a/packages/core/client/src/application/demos/demo1/Hello.tsx +++ b/packages/core/client/src/application/demos/demo1/Hello.tsx @@ -3,18 +3,21 @@ import { useDesignable } from '@nocobase/client'; import { Button } from 'antd'; import { observer } from '@formily/react'; -export const Hello: React.FC = observer(({ name }) => { - const { patch, remove } = useDesignable(); - return ( -
    -

    Hello {name}!

    - -
    - ); -}); +export const Hello: React.FC = observer( + ({ name }) => { + const { patch, remove } = useDesignable(); + return ( +
    +

    Hello {name}!

    + +
    + ); + }, + { displayName: 'Hello' }, +); diff --git a/packages/core/client/src/collection-manager/Configuration/CollectionFieldsTable.tsx b/packages/core/client/src/collection-manager/Configuration/CollectionFieldsTable.tsx index 0ca896157..632030811 100644 --- a/packages/core/client/src/collection-manager/Configuration/CollectionFieldsTable.tsx +++ b/packages/core/client/src/collection-manager/Configuration/CollectionFieldsTable.tsx @@ -31,36 +31,39 @@ const useDef = (options, props) => { } }; -export const CollectionFieldsTable: React.FC = observer((props) => { - const { rowKey = 'id', useDataSource = useDef, useSelectedRowKeys = useDefSelectedRowKeys } = props; - const field = useField(); - const fieldSchema = useFieldSchema(); - const form = useMemo(() => createForm(), []); - const f = useAttach(form.createArrayField({ ...field.props, basePath: '' })); - const result = useDataSource( - { - uid: fieldSchema['x-uid'], - onSuccess(data) { - form.setValues({ - [fieldSchema.name]: data?.data, - }); +export const CollectionFieldsTable: React.FC = observer( + (props) => { + const { rowKey = 'id', useDataSource = useDef, useSelectedRowKeys = useDefSelectedRowKeys } = props; + const field = useField(); + const fieldSchema = useFieldSchema(); + const form = useMemo(() => createForm(), []); + const f = useAttach(form.createArrayField({ ...field.props, basePath: '' })); + const result = useDataSource( + { + uid: fieldSchema['x-uid'], + onSuccess(data) { + form.setValues({ + [fieldSchema.name]: data?.data, + }); + }, }, - }, - props, - ); - return ( - - - - - - - - ); -}); + props, + ); + return ( + + + + + + + + ); + }, + { displayName: 'CollectionFieldsTable' }, +); diff --git a/packages/core/client/src/collection-manager/Configuration/CollectionFieldsTableArray.tsx b/packages/core/client/src/collection-manager/Configuration/CollectionFieldsTableArray.tsx index 1356dd31e..6ee23382c 100644 --- a/packages/core/client/src/collection-manager/Configuration/CollectionFieldsTableArray.tsx +++ b/packages/core/client/src/collection-manager/Configuration/CollectionFieldsTableArray.tsx @@ -79,149 +79,150 @@ interface CategorizeDataItem { data: Array; } -export const CollectionFieldsTableArray: React.FC = observer((props) => { - const sortKeyArr: Array = ['primaryAndForeignKey', 'relation', 'basic', 'systemInfo']; - const field = useField(); - const { name } = useRecord(); - const { t } = useTranslation(); - const compile = useCompile(); - const { getInterface, getInheritCollections, getCollection, getCurrentCollectionFields, getInheritedFields } = - useCollectionManager(); - const { - showIndex = true, - useSelectedRowKeys = useDef, - useDataSource = useDefDataSource, - onChange, - ...others - } = props; - const [selectedRowKeys, setSelectedRowKeys] = useSelectedRowKeys(); - const [categorizeData, setCategorizeData] = useState>([]); - const [expandedKeys, setExpendedKeys] = useState(selectedRowKeys); - const inherits = getInheritCollections(name); - const currentFields = getCurrentCollectionFields(name); - useDataSource({ - onSuccess(data) { - field.value = data?.data || []; - const tmpData: Array = []; - const categorizeMap = new Map(); - const addCategorizeVal = (categorizeKey: CategorizeKey, val) => { - let fieldArr = categorizeMap.get(categorizeKey); - if (!fieldArr) { - fieldArr = []; - } - fieldArr.push(val); - categorizeMap.set(categorizeKey, fieldArr); - }; - field.value.forEach((item) => { - const itemInterface = getInterface(item?.interface); - if (item?.primaryKey || item.isForeignKey) { - addCategorizeVal('primaryAndForeignKey', item); - return; - } - const group = itemInterface?.group as CategorizeKey; - switch (group) { - case 'systemInfo': - case 'relation': - addCategorizeVal(group, item); - break; - default: - addCategorizeVal('basic', item); - } - }); - if (inherits) { - inherits.forEach((v) => { - sortKeyArr.push(v); - const parentCollection = getCollection(v); - parentCollection.fields.map((k) => { - if (k.interface) { - addCategorizeVal(v, new Proxy(k, {})); - field.value.push(new Proxy(k, {})); - } - }); +export const CollectionFieldsTableArray: React.FC = observer( + (props) => { + const sortKeyArr: Array = ['primaryAndForeignKey', 'relation', 'basic', 'systemInfo']; + const field = useField(); + const { name } = useRecord(); + const { t } = useTranslation(); + const compile = useCompile(); + const { getInterface, getInheritCollections, getCollection, getCurrentCollectionFields, getInheritedFields } = + useCollectionManager(); + const { + showIndex = true, + useSelectedRowKeys = useDef, + useDataSource = useDefDataSource, + onChange, + ...others + } = props; + const [selectedRowKeys, setSelectedRowKeys] = useSelectedRowKeys(); + const [categorizeData, setCategorizeData] = useState>([]); + const [expandedKeys, setExpendedKeys] = useState(selectedRowKeys); + const inherits = getInheritCollections(name); + const currentFields = getCurrentCollectionFields(name); + useDataSource({ + onSuccess(data) { + field.value = data?.data || []; + const tmpData: Array = []; + const categorizeMap = new Map(); + const addCategorizeVal = (categorizeKey: CategorizeKey, val) => { + let fieldArr = categorizeMap.get(categorizeKey); + if (!fieldArr) { + fieldArr = []; + } + fieldArr.push(val); + categorizeMap.set(categorizeKey, fieldArr); + }; + field.value.forEach((item) => { + const itemInterface = getInterface(item?.interface); + if (item?.primaryKey || item.isForeignKey) { + addCategorizeVal('primaryAndForeignKey', item); + return; + } + const group = itemInterface?.group as CategorizeKey; + switch (group) { + case 'systemInfo': + case 'relation': + addCategorizeVal(group, item); + break; + default: + addCategorizeVal('basic', item); + } }); - } - sortKeyArr.forEach((key) => { - if (categorizeMap.get(key)?.length > 0) { - const parentCollection = getCollection(key); - tmpData.push({ - key, - name: - t(CategorizeKeyNameMap.get(key)) || - t(`Parent collection fields`) + `(${compile(parentCollection.title)})`, - data: categorizeMap.get(key), + if (inherits) { + inherits.forEach((v) => { + sortKeyArr.push(v); + const parentCollection = getCollection(v); + parentCollection.fields.map((k) => { + if (k.interface) { + addCategorizeVal(v, new Proxy(k, {})); + field.value.push(new Proxy(k, {})); + } + }); }); } - }); - setExpendedKeys(sortKeyArr); - setCategorizeData(tmpData); - }, - }); - const useTableColumns = () => { - const schema = useFieldSchema(); - const { exists, render } = useSchemaInitializer(schema['x-initializer']); - const columns = schema - .reduceProperties((buf, s) => { - if (isColumnComponent(s)) { - return buf.concat([s]); - } - }, []) - .map((s: Schema) => { - return { - title: , - dataIndex: s.name, - key: s.name, - render: (v, record) => { - const index = findIndex(field.value, record); - return ( - - - - - - ); - }, - } as TableColumnProps; - }); - if (!exists) { - return columns; - } - return columns.concat({ - title: render(), - dataIndex: 'TABLE_COLUMN_INITIALIZER', - key: 'TABLE_COLUMN_INITIALIZER', + sortKeyArr.forEach((key) => { + if (categorizeMap.get(key)?.length > 0) { + const parentCollection = getCollection(key); + tmpData.push({ + key, + name: + t(CategorizeKeyNameMap.get(key)) || + t(`Parent collection fields`) + `(${compile(parentCollection.title)})`, + data: categorizeMap.get(key), + }); + } + }); + setExpendedKeys(sortKeyArr); + setCategorizeData(tmpData); + }, }); - }; - - const ExpandedRowRender = (record: CategorizeDataItem, index, indent, expanded) => { - const columns = useTableColumns(); - if (!props.loading) { - if (inherits.includes(record.key)) { - columns.pop(); - columns.push({ - title: , - dataIndex: 'column4', - key: 'column4', - render: (v, record) => { - const index = findIndex(field.value, record); - return ( - - - - - - ); - }, + const useTableColumns = () => { + const schema = useFieldSchema(); + const { exists, render } = useSchemaInitializer(schema['x-initializer']); + const columns = schema + .reduceProperties((buf, s) => { + if (isColumnComponent(s)) { + return buf.concat([s]); + } + }, []) + .map((s: Schema) => { + return { + title: , + dataIndex: s.name, + key: s.name, + render: (v, record) => { + const index = findIndex(field.value, record); + return ( + + + + + + ); + }, + } as TableColumnProps; }); + if (!exists) { + return columns; } - const restProps = { - rowSelection: - props.rowSelection && !inherits.includes(record.key) - ? { + return columns.concat({ + title: render(), + dataIndex: 'TABLE_COLUMN_INITIALIZER', + key: 'TABLE_COLUMN_INITIALIZER', + }); + }; + + const ExpandedRowRender = (record: CategorizeDataItem, index, indent, expanded) => { + const columns = useTableColumns(); + if (!props.loading) { + if (inherits.includes(record.key)) { + columns.pop(); + columns.push({ + title: , + dataIndex: 'column4', + key: 'column4', + render: (v, record) => { + const index = findIndex(field.value, record); + return ( + + + + + + ); + }, + }); + } + const restProps = { + rowSelection: + props.rowSelection && !inherits.includes(record.key) + ? { type: 'checkbox', selectedRowKeys, onChange(selectedRowKeys: any[]) { @@ -229,52 +230,54 @@ export const CollectionFieldsTableArray: React.FC = observer((props) => { }, ...props.rowSelection, } - : undefined, - }; - return ( -
    - ); - } - }; - return ( -
    -
    { - let keys = []; - if (expanded) { - keys = expandedKeys.concat([record.key]); - } else { - keys = expandedKeys.filter((v) => { - return v !== record.key; - }); + : undefined, + }; + return ( +
    + ); + } + }; + return ( +
    -
    - ); -}); + `} + > +
    { + let keys = []; + if (expanded) { + keys = expandedKeys.concat([record.key]); + } else { + keys = expandedKeys.filter((v) => { + return v !== record.key; + }); + } + setExpendedKeys(keys); + }} + /> + + ); + }, + { displayName: 'CollectionFieldsTableArray' }, +); diff --git a/packages/core/client/src/collection-manager/Configuration/ConfigurationTabs.tsx b/packages/core/client/src/collection-manager/Configuration/ConfigurationTabs.tsx index 945e0a212..8d8324569 100644 --- a/packages/core/client/src/collection-manager/Configuration/ConfigurationTabs.tsx +++ b/packages/core/client/src/collection-manager/Configuration/ConfigurationTabs.tsx @@ -50,17 +50,20 @@ function Droppable(props) { ); } -const TabTitle = observer(({ item }: { item: any }) => { - return ( - -
    - - - -
    -
    - ); -}); +const TabTitle = observer( + ({ item }: { item: any }) => { + return ( + +
    + + + +
    +
    + ); + }, + { displayName: 'TabTitle' }, +); const TabBar = ({ item }) => { const compile = useCompile(); @@ -71,45 +74,48 @@ const TabBar = ({ item }) => { ); }; -const DndProvider = observer((props) => { - const [activeTab, setActiveId] = useState(null); - const { refresh } = useContext(CollectionCategroriesContext); - const { refresh: refreshCM } = useResourceActionContext(); - const api = useAPIClient(); - const onDragEnd = async (props: DragEndEvent) => { - const { active, over } = props; - setTimeout(() => { - setActiveId(null); - }); - if (over && over.id !== active.id) { - await api.resource('collectionCategories').move({ - sourceId: active.id, - targetId: over.id, +const DndProvider = observer( + (props) => { + const [activeTab, setActiveId] = useState(null); + const { refresh } = useContext(CollectionCategroriesContext); + const { refresh: refreshCM } = useResourceActionContext(); + const api = useAPIClient(); + const onDragEnd = async (props: DragEndEvent) => { + const { active, over } = props; + setTimeout(() => { + setActiveId(null); }); - await refresh(); - await refreshCM(); + if (over && over.id !== active.id) { + await api.resource('collectionCategories').move({ + sourceId: active.id, + targetId: over.id, + }); + await refresh(); + await refreshCM(); + } + }; + + function onDragStart(event) { + setActiveId(event.active?.data.current); } - }; - function onDragStart(event) { - setActiveId(event.active?.data.current); - } - - const mouseSensor = useSensor(MouseSensor, { - activationConstraint: { - distance: 10, - }, - }); - const sensors = useSensors(mouseSensor); - return ( - - {props.children} - - {activeTab ? {} : null} - - - ); -}); + const mouseSensor = useSensor(MouseSensor, { + activationConstraint: { + distance: 10, + }, + }); + const sensors = useSensors(mouseSensor); + return ( + + {props.children} + + {activeTab ? {} : null} + + + ); + }, + { displayName: 'DndProvider' }, +); export const ConfigurationTabs = () => { const { data, refresh } = useContext(CollectionCategroriesContext); const { refresh: refreshCM, run, defaultRequest, setState } = useResourceActionContext(); diff --git a/packages/core/client/src/collection-manager/Configuration/components/CollectionCategory.tsx b/packages/core/client/src/collection-manager/Configuration/components/CollectionCategory.tsx index e06c0c658..39e9d3e3f 100644 --- a/packages/core/client/src/collection-manager/Configuration/components/CollectionCategory.tsx +++ b/packages/core/client/src/collection-manager/Configuration/components/CollectionCategory.tsx @@ -3,14 +3,17 @@ import { Tag } from 'antd'; import React from 'react'; import { useCompile } from '../../../schema-component'; -export const CollectionCategory = observer((props: any) => { - const { value } = props; - const compile = useCompile(); - return ( - <> - {value.map((item) => { - return {compile(item?.name)}; - })} - - ); -}); +export const CollectionCategory = observer( + (props: any) => { + const { value } = props; + const compile = useCompile(); + return ( + <> + {value.map((item) => { + return {compile(item?.name)}; + })} + + ); + }, + { displayName: 'CollectionCategory' }, +); diff --git a/packages/core/client/src/collection-manager/Configuration/components/CollectionFieldInterface.tsx b/packages/core/client/src/collection-manager/Configuration/components/CollectionFieldInterface.tsx index ec9b4e6de..6b99c0ac6 100644 --- a/packages/core/client/src/collection-manager/Configuration/components/CollectionFieldInterface.tsx +++ b/packages/core/client/src/collection-manager/Configuration/components/CollectionFieldInterface.tsx @@ -4,13 +4,16 @@ import React from 'react'; import { useCompile } from '../../../schema-component'; import { useCollectionManager } from '../../hooks'; -export const CollectionFieldInterface = observer((props: any) => { - const { value } = props; - const { getInterface } = useCollectionManager(); - const compile = useCompile(); - const schema = getInterface(value); +export const CollectionFieldInterface = observer( + (props: any) => { + const { value } = props; + const { getInterface } = useCollectionManager(); + const compile = useCompile(); + const schema = getInterface(value); - if (!schema) return null; + if (!schema) return null; - return {compile(schema.title)}; -}); + return {compile(schema.title)}; + }, + { displayName: 'CollectionFieldInterface' }, +); diff --git a/packages/core/client/src/collection-manager/Configuration/components/CollectionTemplate.tsx b/packages/core/client/src/collection-manager/Configuration/components/CollectionTemplate.tsx index 984c0c305..f1f210452 100644 --- a/packages/core/client/src/collection-manager/Configuration/components/CollectionTemplate.tsx +++ b/packages/core/client/src/collection-manager/Configuration/components/CollectionTemplate.tsx @@ -4,11 +4,14 @@ import React from 'react'; import { useCompile } from '../../../schema-component'; import { useCollectionManager } from '../../hooks'; -export const CollectionTemplate = observer((props: any) => { - const { value } = props; - const { getTemplate } = useCollectionManager(); - const compile = useCompile(); - const schema = getTemplate(value); +export const CollectionTemplate = observer( + (props: any) => { + const { value } = props; + const { getTemplate } = useCollectionManager(); + const compile = useCompile(); + const schema = getTemplate(value); - return {compile(schema?.title || '{{t("General collection")}}')}; -}); + return {compile(schema?.title || '{{t("General collection")}}')}; + }, + { displayName: 'CollectionTemplate' }, +); diff --git a/packages/core/client/src/collection-manager/Configuration/components/FieldSummary.tsx b/packages/core/client/src/collection-manager/Configuration/components/FieldSummary.tsx index 846e00224..c42c1362e 100644 --- a/packages/core/client/src/collection-manager/Configuration/components/FieldSummary.tsx +++ b/packages/core/client/src/collection-manager/Configuration/components/FieldSummary.tsx @@ -6,36 +6,39 @@ import { useTranslation } from 'react-i18next'; import { useCompile } from '../../../schema-component'; import { useCollectionManager } from '../../hooks'; -export const FieldSummary = observer((props: any) => { - const { schemaKey } = props; - const { getInterface } = useCollectionManager(); - const compile = useCompile(); - const { t } = useTranslation(); - const schema = getInterface(schemaKey); +export const FieldSummary = observer( + (props: any) => { + const { schemaKey } = props; + const { getInterface } = useCollectionManager(); + const compile = useCompile(); + const { t } = useTranslation(); + const schema = getInterface(schemaKey); - if (!schema) return null; + if (!schema) return null; - return ( -
    -
    - {t('Field interface')}: {compile(schema.title)} -
    - {schema.description ? ( -
    - {compile(schema.description)} + return ( +
    +
    + {t('Field interface')}: {compile(schema.title)}
    - ) : null} -
    - ); -}); + {schema.description ? ( +
    + {compile(schema.description)} +
    + ) : null} +
    + ); + }, + { displayName: 'FieldSummary' }, +); diff --git a/packages/core/client/src/collection-manager/Configuration/components/TemplateSummay.tsx b/packages/core/client/src/collection-manager/Configuration/components/TemplateSummay.tsx index b6167ef67..a20e7dafb 100644 --- a/packages/core/client/src/collection-manager/Configuration/components/TemplateSummay.tsx +++ b/packages/core/client/src/collection-manager/Configuration/components/TemplateSummay.tsx @@ -6,36 +6,39 @@ import { useTranslation } from 'react-i18next'; import { useCompile } from '../../../schema-component'; import { useCollectionManager } from '../../hooks'; -export const TemplateSummay = observer((props: any) => { - const { schemaKey } = props; - const { getTemplate } = useCollectionManager(); - const compile = useCompile(); - const { t } = useTranslation(); - const schema = getTemplate(schemaKey); +export const TemplateSummay = observer( + (props: any) => { + const { schemaKey } = props; + const { getTemplate } = useCollectionManager(); + const compile = useCompile(); + const { t } = useTranslation(); + const schema = getTemplate(schemaKey); - if (!schema) return null; + if (!schema) return null; - return ( -
    -
    - {t('Collection template')}: {compile(schema.title)} -
    - {schema.description ? ( -
    - {compile(schema.description)} + return ( +
    +
    + {t('Collection template')}: {compile(schema.title)}
    - ) : null} -
    - ); -}); + {schema.description ? ( +
    + {compile(schema.description)} +
    + ) : null} +
    + ); + }, + { displayName: 'TemplateSummay' }, +); diff --git a/packages/core/client/src/collection-manager/Configuration/components/index.tsx b/packages/core/client/src/collection-manager/Configuration/components/index.tsx index d1626b1b9..65a03623f 100644 --- a/packages/core/client/src/collection-manager/Configuration/components/index.tsx +++ b/packages/core/client/src/collection-manager/Configuration/components/index.tsx @@ -6,109 +6,127 @@ import { useRecord } from '../../../record-provider'; import { useCompile } from '../../../schema-component'; import { useCollectionManager } from '../../hooks'; -export const SourceForeignKey = observer(() => { - const record = useRecord(); - const { getCollection } = useCollectionManager(); - const collection = record?.collectionName ? getCollection(record.collectionName) : record; - const field = useField(); - const form = useForm(); - const { getCollectionFields } = useCollectionManager(); - return ( -
    - field.type) + .map((field) => { + return { + label: field?.uiSchema?.title || field.name, + value: field.name, + }; + })} + /> +
    + ); + }, + { displayName: 'SourceForeignKey' }, +); -export const ThroughForeignKey = observer(() => { - const field = useField(); - const form = useForm(); - const { getCollectionFields } = useCollectionManager(); - return ( -
    - field.type) + .map((field) => { + return { + label: field?.uiSchema?.title || field.name, + value: field.name, + }; + })} + /> +
    + ); + }, + { displayName: 'ThroughForeignKey' }, +); -export const TargetForeignKey = observer(() => { - const field = useField(); - const form = useForm(); - const { getCollectionFields } = useCollectionManager(); - return ( -
    - field.type) + .map((field) => { + return { + label: field?.uiSchema?.title || field.name, + value: field.name, + }; + })} + /> +
    + ); + }, + { displayName: 'TargetForeignKey' }, +); -export const SourceCollection = observer(() => { - const record = useRecord(); - const { getCollection } = useCollectionManager(); - const collection = record?.collectionName ? getCollection(record.collectionName) : record; - const compile = useCompile(); - return ( -
    - +
    + ); + }, + { displayName: 'SourceCollection' }, +); -export const SourceKey = observer(() => { - return ( -
    - +
    + ); + }, + { displayName: 'SourceKey' }, +); -export const TargetKey = observer(() => { - return ( -
    - +
    + ); + }, + { displayName: 'TargetKey' }, +); diff --git a/packages/core/client/src/collection-manager/sub-table.tsx b/packages/core/client/src/collection-manager/sub-table.tsx index f69ed28c4..43aa7f146 100644 --- a/packages/core/client/src/collection-manager/sub-table.tsx +++ b/packages/core/client/src/collection-manager/sub-table.tsx @@ -166,107 +166,113 @@ export const ds = { useDestroyAction, }; -export const SubFieldDataSourceProvider = observer((props) => { - const [selectedRowKeys, setSelectedRowKeys] = useState([]); - const [dataSource, setDataSource] = useState([]); - const record = useRecord(); - const api = useAPIClient(); - const service = useRequest( - () => { - if (record.interface === 'subTable') { - if (record?.children?.length) { - return Promise.resolve({ - data: record?.children || [], - }); +export const SubFieldDataSourceProvider = observer( + (props) => { + const [selectedRowKeys, setSelectedRowKeys] = useState([]); + const [dataSource, setDataSource] = useState([]); + const record = useRecord(); + const api = useAPIClient(); + const service = useRequest( + () => { + if (record.interface === 'subTable') { + if (record?.children?.length) { + return Promise.resolve({ + data: record?.children || [], + }); + } + return api + .resource('fields') + .list({ + paginate: false, + // appends: ['uiSchema'], + sort: 'sort', + filter: { + parentKey: record.key, + }, + }) + .then((res) => res?.data); } - return api - .resource('fields') - .list({ - paginate: false, - // appends: ['uiSchema'], - sort: 'sort', - filter: { - parentKey: record.key, - }, - }) - .then((res) => res?.data); - } - return Promise.resolve({ - data: [], - }); - }, - { - onSuccess(data) { - console.log('dataSource1', data?.data); - setDataSource(data?.data); + return Promise.resolve({ + data: [], + }); }, - }, - ); - return ( - - - {props.children} - - - ); -}); + { + onSuccess(data) { + console.log('dataSource1', data?.data); + setDataSource(data?.data); + }, + }, + ); + return ( + + + {props.children} + + + ); + }, + { displayName: 'SubFieldDataSourceProvider' }, +); -export const DataSourceProvider = observer((props: any) => { - const { rowKey, collection, association } = props; - const [selectedRowKeys, setSelectedRowKeys] = useState([]); - const [dataSource, setDataSource] = useState([]); - const record = useRecord(); - const api = useAPIClient(); - const { getCollection } = useCollectionManager(); - const coll = getCollection(collection); - const resourceOf = record?.[association.targetKey || 'id']; - const service = useRequest( - () => { - if (resourceOf) { - return api - .request({ - resource: `${association.collectionName}.${association.name}`, - resourceOf, - action: 'list', - params: { - appends: coll?.fields?.filter((field) => field.target)?.map((field) => field.name), - }, - }) - .then((res) => res.data); - } - return Promise.resolve({ - data: record?.[association.name] || [], - }); - }, - { - onSuccess(data) { - setDataSource(data?.data); +export const DataSourceProvider = observer( + (props: any) => { + const { rowKey, collection, association } = props; + const [selectedRowKeys, setSelectedRowKeys] = useState([]); + const [dataSource, setDataSource] = useState([]); + const record = useRecord(); + const api = useAPIClient(); + const { getCollection } = useCollectionManager(); + const coll = getCollection(collection); + const resourceOf = record?.[association.targetKey || 'id']; + const service = useRequest( + () => { + if (resourceOf) { + return api + .request({ + resource: `${association.collectionName}.${association.name}`, + resourceOf, + action: 'list', + params: { + appends: coll?.fields?.filter((field) => field.target)?.map((field) => field.name), + }, + }) + .then((res) => res.data); + } + return Promise.resolve({ + data: record?.[association.name] || [], + }); }, - }, - ); - return ( - - - {props.children} - - - ); -}); + { + onSuccess(data) { + setDataSource(data?.data); + }, + }, + ); + return ( + + + {props.children} + + + ); + }, + { displayName: 'DataSourceProvider' }, +); diff --git a/packages/core/client/src/collection-manager/templates/components/PreviewFields.tsx b/packages/core/client/src/collection-manager/templates/components/PreviewFields.tsx index b34ae66a4..1dd317068 100644 --- a/packages/core/client/src/collection-manager/templates/components/PreviewFields.tsx +++ b/packages/core/client/src/collection-manager/templates/components/PreviewFields.tsx @@ -217,3 +217,4 @@ function areEqual(prevProps, nextProps) { } export const PreviewFields = React.memo(PreviewCom, areEqual); +PreviewFields.displayName = 'PreviewFields'; diff --git a/packages/core/client/src/schema-component/antd/action/Action.Container.tsx b/packages/core/client/src/schema-component/antd/action/Action.Container.tsx index ef09c4c9f..3671855c9 100644 --- a/packages/core/client/src/schema-component/antd/action/Action.Container.tsx +++ b/packages/core/client/src/schema-component/antd/action/Action.Container.tsx @@ -6,21 +6,27 @@ import { ActionModal } from './Action.Modal'; import { ActionPage } from './Action.Page'; import { ComposedActionDrawer } from './types'; -export const ActionContainer: ComposedActionDrawer = observer((props: any) => { - const { openMode } = useActionContext(); - if (openMode === 'drawer') { - return ; - } - if (openMode === 'modal') { - return ; - } - return ; -}); +export const ActionContainer: ComposedActionDrawer = observer( + (props: any) => { + const { openMode } = useActionContext(); + if (openMode === 'drawer') { + return ; + } + if (openMode === 'modal') { + return ; + } + return ; + }, + { displayName: 'ActionContainer' }, +); -ActionContainer.Footer = observer(() => { - const field = useField(); - const schema = useFieldSchema(); - return ; -}); +ActionContainer.Footer = observer( + () => { + const field = useField(); + const schema = useFieldSchema(); + return ; + }, + { displayName: 'ActionContainer.Footer' }, +); export default ActionContainer; diff --git a/packages/core/client/src/schema-component/antd/action/Action.Drawer.tsx b/packages/core/client/src/schema-component/antd/action/Action.Drawer.tsx index 2219e5847..6dc6be401 100644 --- a/packages/core/client/src/schema-component/antd/action/Action.Drawer.tsx +++ b/packages/core/client/src/schema-component/antd/action/Action.Drawer.tsx @@ -14,111 +14,117 @@ const openSizeWidthMap = new Map([ ['middle', '50%'], ['large', '70%'], ]); -export const ActionDrawer: ComposedActionDrawer = observer((props) => { - const { footerNodeName = 'Action.Drawer.Footer', ...others } = props; - const { t } = useTranslation(); - const { visible, setVisible, openSize = 'middle' } = useActionContext(); - const schema = useFieldSchema(); - const field = useField(); - const openSizeFromParent = schema.parent?.['x-component-props']?.['openSize']; - const finalOpenSize = openSizeFromParent || openSize; - const footerSchema = schema.reduceProperties((buf, s) => { - if (s['x-component'] === footerNodeName) { - return s; - } - return buf; - }); - return ( - <> - {createPortal( -
    { - e.stopPropagation(); - }} - > - setVisible(false, true)} - className={classNames( - others.className, - css` - &.nb-action-popup { - .ant-drawer-header { - display: none; - } - - .ant-drawer-body { - padding-top: 14px; - } - - .ant-drawer-content { - background: #f0f2f5; - } - } - - &.nb-record-picker-selector { - .nb-block-item { - margin-bottom: 24px; - - .general-schema-designer { - top: -8px; - bottom: -8px; - left: -8px; - right: -8px; - } - } - } - `, - )} - footer={ - footerSchema && ( -
    - { - return s['x-component'] === footerNodeName; - }} - /> -
    - ) - } +export const ActionDrawer: ComposedActionDrawer = observer( + (props) => { + const { footerNodeName = 'Action.Drawer.Footer', ...others } = props; + const { t } = useTranslation(); + const { visible, setVisible, openSize = 'middle' } = useActionContext(); + const schema = useFieldSchema(); + const field = useField(); + const openSizeFromParent = schema.parent?.['x-component-props']?.['openSize']; + const finalOpenSize = openSizeFromParent || openSize; + const footerSchema = schema.reduceProperties((buf, s) => { + if (s['x-component'] === footerNodeName) { + return s; + } + return buf; + }); + return ( + <> + {createPortal( +
    { + e.stopPropagation(); + }} > - { - return s['x-component'] !== footerNodeName; - }} - /> - -
    , - document.body, - )} - - ); -}); + setVisible(false, true)} + className={classNames( + others.className, + css` + &.nb-action-popup { + .ant-drawer-header { + display: none; + } -ActionDrawer.Footer = observer(() => { - const field = useField(); - const schema = useFieldSchema(); - return ; -}); + .ant-drawer-body { + padding-top: 14px; + } + + .ant-drawer-content { + background: #f0f2f5; + } + } + + &.nb-record-picker-selector { + .nb-block-item { + margin-bottom: 24px; + + .general-schema-designer { + top: -8px; + bottom: -8px; + left: -8px; + right: -8px; + } + } + } + `, + )} + footer={ + footerSchema && ( +
    + { + return s['x-component'] === footerNodeName; + }} + /> +
    + ) + } + > + { + return s['x-component'] !== footerNodeName; + }} + /> +
    +
    , + document.body, + )} + + ); + }, + { displayName: 'ActionDrawer' }, +); + +ActionDrawer.Footer = observer( + () => { + const field = useField(); + const schema = useFieldSchema(); + return ; + }, + { displayName: 'ActionDrawer.Footer' }, +); export default ActionDrawer; diff --git a/packages/core/client/src/schema-component/antd/action/Action.Link.tsx b/packages/core/client/src/schema-component/antd/action/Action.Link.tsx index bdd7f0609..0e9db75e3 100644 --- a/packages/core/client/src/schema-component/antd/action/Action.Link.tsx +++ b/packages/core/client/src/schema-component/antd/action/Action.Link.tsx @@ -3,6 +3,9 @@ import React from 'react'; import Action from './Action'; import { ComposedAction } from './types'; -export const ActionLink: ComposedAction = observer((props: any) => { - return ; -}); +export const ActionLink: ComposedAction = observer( + (props: any) => { + return ; + }, + { displayName: 'ActionLink' }, +); diff --git a/packages/core/client/src/schema-component/antd/action/Action.Modal.tsx b/packages/core/client/src/schema-component/antd/action/Action.Modal.tsx index 4ba67ad3c..d54774f90 100644 --- a/packages/core/client/src/schema-component/antd/action/Action.Modal.tsx +++ b/packages/core/client/src/schema-component/antd/action/Action.Modal.tsx @@ -12,104 +12,110 @@ const openSizeWidthMap = new Map([ ['middle', '60%'], ['large', '80%'], ]); -export const ActionModal: ComposedActionDrawer = observer((props) => { - const { footerNodeName = 'Action.Modal.Footer', width, ...others } = props; - const { visible, setVisible, openSize = 'large' } = useActionContext(); - const actualWidth = width ?? openSizeWidthMap.get(openSize); - const schema = useFieldSchema(); - const field = useField(); - const footerSchema = schema.reduceProperties((buf, s) => { - if (s['x-component'] === footerNodeName) { - return s; - } - return buf; - }); - return ( - <> - {createPortal( -
    { - e.stopPropagation(); - }} - > - setVisible(false, true)} - className={classNames( - others.className, - css` - &.nb-action-popup { - .ant-modal-header { - display: none; - } - - .ant-modal-body { - padding-top: 16px; - } - - .ant-modal-body { - background: #f0f2f5; - } - - .ant-modal-close-x { - width: 32px; - height: 32px; - line-height: 32px; - } - } - `, - )} - footer={ - footerSchema ? ( -
    - { - return s['x-component'] === footerNodeName; - }} - /> -
    - ) : ( - false - ) - } +export const ActionModal: ComposedActionDrawer = observer( + (props) => { + const { footerNodeName = 'Action.Modal.Footer', width, ...others } = props; + const { visible, setVisible, openSize = 'large' } = useActionContext(); + const actualWidth = width ?? openSizeWidthMap.get(openSize); + const schema = useFieldSchema(); + const field = useField(); + const footerSchema = schema.reduceProperties((buf, s) => { + if (s['x-component'] === footerNodeName) { + return s; + } + return buf; + }); + return ( + <> + {createPortal( +
    { + e.stopPropagation(); + }} > - { - return s['x-component'] !== footerNodeName; - }} - /> - -
    , - document.body, - )} - - ); -}); + setVisible(false, true)} + className={classNames( + others.className, + css` + &.nb-action-popup { + .ant-modal-header { + display: none; + } -ActionModal.Footer = observer(() => { - const field = useField(); - const schema = useFieldSchema(); - return ; -}); + .ant-modal-body { + padding-top: 16px; + } + + .ant-modal-body { + background: #f0f2f5; + } + + .ant-modal-close-x { + width: 32px; + height: 32px; + line-height: 32px; + } + } + `, + )} + footer={ + footerSchema ? ( +
    + { + return s['x-component'] === footerNodeName; + }} + /> +
    + ) : ( + false + ) + } + > + { + return s['x-component'] !== footerNodeName; + }} + /> +
    +
    , + document.body, + )} + + ); + }, + { displayName: 'ActionModal' }, +); + +ActionModal.Footer = observer( + () => { + const field = useField(); + const schema = useFieldSchema(); + return ; + }, + { displayName: 'ActionModal.Footer' }, +); export default ActionModal; diff --git a/packages/core/client/src/schema-component/antd/action/Action.Page.tsx b/packages/core/client/src/schema-component/antd/action/Action.Page.tsx index c4c3182c1..207f24d34 100644 --- a/packages/core/client/src/schema-component/antd/action/Action.Page.tsx +++ b/packages/core/client/src/schema-component/antd/action/Action.Page.tsx @@ -10,65 +10,71 @@ const useScope = (key: string) => { return scope[key]; }; -export const ActionPage: ComposedActionDrawer = observer((props: any) => { - const { footerNodeName = 'Action.Page.Footer', ...others } = props; - const { containerRefKey, visible, setVisible } = useActionContext(); - const containerRef = useScope(containerRefKey); - const schema = useFieldSchema(); - const field = useField(); - const footerSchema = schema.reduceProperties((buf, s) => { - if (s['x-component'] === footerNodeName) { - return s; - } - return buf; - }); - return ( - <> - {containerRef?.current && - visible && - createPortal( -
    - { - return s['x-component'] !== footerNodeName; - }} - /> - {footerSchema && ( -
    - { - return s['x-component'] === footerNodeName; - }} - /> -
    - )} -
    , - containerRef?.current, - )} - - ); -}); +export const ActionPage: ComposedActionDrawer = observer( + (props: any) => { + const { footerNodeName = 'Action.Page.Footer', ...others } = props; + const { containerRefKey, visible, setVisible } = useActionContext(); + const containerRef = useScope(containerRefKey); + const schema = useFieldSchema(); + const field = useField(); + const footerSchema = schema.reduceProperties((buf, s) => { + if (s['x-component'] === footerNodeName) { + return s; + } + return buf; + }); + return ( + <> + {containerRef?.current && + visible && + createPortal( +
    + { + return s['x-component'] !== footerNodeName; + }} + /> + {footerSchema && ( +
    + { + return s['x-component'] === footerNodeName; + }} + /> +
    + )} +
    , + containerRef?.current, + )} + + ); + }, + { displayName: 'ActionPage' }, +); -ActionPage.Footer = observer(() => { - const field = useField(); - const schema = useFieldSchema(); - return ; -}); +ActionPage.Footer = observer( + () => { + const field = useField(); + const schema = useFieldSchema(); + return ; + }, + { displayName: 'ActionPage.Footer' }, +); export default ActionPage; diff --git a/packages/core/client/src/schema-component/antd/action/Action.tsx b/packages/core/client/src/schema-component/antd/action/Action.tsx index 0b4fee8a4..504f21ccd 100644 --- a/packages/core/client/src/schema-component/antd/action/Action.tsx +++ b/packages/core/client/src/schema-component/antd/action/Action.tsx @@ -2,7 +2,7 @@ import { css } from '@emotion/css'; import { observer, RecursionField, useField, useFieldSchema, useForm } from '@formily/react'; import { Button, Modal, Popover } from 'antd'; import classnames from 'classnames'; -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; import { useActionContext } from '../..'; import { useDesignable } from '../../'; import { Icon } from '../../../icon'; @@ -64,139 +64,158 @@ export const actionDesignerCss = css` } `; -export const Action: ComposedAction = observer((props: any) => { - const { - popover, - confirm, - openMode: om, - containerRefKey, - component, - useAction = useA, - className, - icon, - title, - ...others - } = props; - const { onClick } = useProps(props); - const [visible, setVisible] = useState(false); - const [formValueChanged, setFormValueChanged] = useState(false); - const Designer = useDesigner(); - const field = useField(); - const { run } = useAction(); - const fieldSchema = useFieldSchema(); - const compile = useCompile(); - const form = useForm(); - const values = useRecord(); - const designerProps = fieldSchema['x-designer-props']; - const openMode = fieldSchema?.['x-component-props']?.['openMode']; - const disabled = form.disabled || field.disabled || props.disabled; - const openSize = fieldSchema?.['x-component-props']?.['openSize']; - const linkageRules = fieldSchema?.['x-linkage-rules'] || []; - const { designable } = useDesignable(); - const tarComponent = useComponent(component) || component; - useEffect(() => { - field.linkageProperty = {}; - linkageRules - .filter((k) => !k.disabled) - .forEach((v) => { - return v.actions?.map((h) => { - linkageAction(h.operator, field, v.condition, values); - }); - }); - }, [linkageRules, values, designable]); - - const renderButton = () => { - if (!designable && field?.data?.hidden) { +export const Action: ComposedAction = observer( + (props: any) => { + const { + popover, + confirm, + openMode: om, + containerRefKey, + component, + useAction = useA, + className, + icon, + title, + ...others + } = props; + const { onClick } = useProps(props); + const [visible, setVisible] = useState(false); + const [formValueChanged, setFormValueChanged] = useState(false); + const Designer = useDesigner(); + const field = useField(); + const { run } = useAction(); + const fieldSchema = useFieldSchema(); + const compile = useCompile(); + const form = useForm(); + const values = useRecord(); + const designerProps = fieldSchema['x-designer-props']; + const openMode = fieldSchema?.['x-component-props']?.['openMode']; + const disabled = form.disabled || field.disabled || props.disabled; + const openSize = fieldSchema?.['x-component-props']?.['openSize']; + const linkageRules = fieldSchema?.['x-linkage-rules'] || []; + const { designable } = useDesignable(); + const tarComponent = useComponent(component) || component; + const renderTitle = useMemo(() => { + if (title) { + return title; + } + if (fieldSchema.title) { + return compile(fieldSchema.title); + } return null; - } - return ( - } - disabled={disabled} - style={{ - opacity: designable && field?.data?.hidden && 0.1, - }} - onClick={(e: React.MouseEvent) => { - if (!disabled) { - e.preventDefault(); - e.stopPropagation(); - const onOk = () => { - onClick?.(e); - setVisible(true); - run(); - }; - if (confirm) { - Modal.confirm({ - ...confirm, - onOk, - }); - } else { - onOk(); + }, [compile, fieldSchema.title, title]); + + useEffect(() => { + field.linkageProperty = {}; + linkageRules + .filter((k) => !k.disabled) + .forEach((v) => { + return v.actions?.map((h) => { + linkageAction(h.operator, field, v.condition, values); + }); + }); + }, [linkageRules, values, designable]); + + const renderButton = () => { + if (!designable && field?.data?.hidden) { + return null; + } + return ( + } + disabled={disabled} + style={{ + opacity: designable && field?.data?.hidden && 0.1, + }} + onClick={(e: React.MouseEvent) => { + if (!disabled) { + e.preventDefault(); + e.stopPropagation(); + const onOk = () => { + onClick?.(e); + setVisible(true); + run(); + }; + if (confirm) { + Modal.confirm({ + ...confirm, + onOk, + }); + } else { + onOk(); + } } - } + }} + component={tarComponent || Button} + className={classnames(className, actionDesignerCss)} + > + {renderTitle} + + + ); + }; + + return ( + - {title || compile(fieldSchema.title)} - - + {popover && } + {!popover && renderButton()} + {!popover && props.children} + ); - }; + }, + { displayName: 'Action' }, +); - return ( - - {popover && } - {!popover && renderButton()} - {!popover && props.children} - - ); -}); +Action.Popover = observer( + (props) => { + const { button, visible, setVisible } = useActionContext(); + return ( + { + setVisible(visible); + }} + content={props.children} + > + {button} + + ); + }, + { displayName: 'Action.Popover' }, +); -Action.Popover = observer((props) => { - const { button, visible, setVisible } = useActionContext(); - return ( - { - setVisible(visible); - }} - content={props.children} - > - {button} - - ); -}); - -Action.Popover.Footer = observer((props) => { - return ( -
    - {props.children} -
    - ); -}); +Action.Popover.Footer = observer( + (props) => { + return ( +
    + {props.children} +
    + ); + }, + { displayName: 'Action.Popover.Footer' }, +); Action.Link = ActionLink; Action.Designer = ActionDesigner; diff --git a/packages/core/client/src/schema-component/antd/action/ActionBar.tsx b/packages/core/client/src/schema-component/antd/action/ActionBar.tsx index 16dd8cd6b..39c6cf12c 100644 --- a/packages/core/client/src/schema-component/antd/action/ActionBar.tsx +++ b/packages/core/client/src/schema-component/antd/action/ActionBar.tsx @@ -6,40 +6,41 @@ import { useSchemaInitializer } from '../../../schema-initializer'; import { DndContext } from '../../common'; import { useDesignable, useProps } from '../../hooks'; -export const ActionBar = observer((props: any) => { - const { layout = 'tow-columns', style, spaceProps, ...others } = useProps(props); - const fieldSchema = useFieldSchema(); - const { InitializerComponent } = useSchemaInitializer(fieldSchema['x-initializer']); - const { designable } = useDesignable(); - if (layout === 'one-column') { +export const ActionBar = observer( + (props: any) => { + const { layout = 'tow-columns', style, spaceProps, ...others } = useProps(props); + const fieldSchema = useFieldSchema(); + const { InitializerComponent } = useSchemaInitializer(fieldSchema['x-initializer']); + const { designable } = useDesignable(); + if (layout === 'one-column') { + return ( + +
    + {props.children && ( +
    + + {fieldSchema.mapProperties((schema, key) => { + return ; + })} + +
    + )} + +
    +
    + ); + } + const hasActions = Object.keys(fieldSchema.properties ?? {}).length > 0; return ( - -
    - {props.children && ( -
    - - {fieldSchema.mapProperties((schema, key) => { - return ; - })} - -
    - )} - -
    -
    - ); - } - const hasActions = Object.keys(fieldSchema.properties ?? {}).length > 0; - return ( -
    { flexShrink: 0, ...style, } - } - {...others} - className={cx(others.className, 'nb-action-bar')} - > -
    - - - {fieldSchema.mapProperties((schema, key) => { - if (schema['x-align'] !== 'left') { - return null; - } - return ; - })} - - - {fieldSchema.mapProperties((schema, key) => { - if (schema['x-align'] === 'left') { - return null; - } - return ; - })} - - +
    + + + {fieldSchema.mapProperties((schema, key) => { + if (schema['x-align'] !== 'left') { + return null; + } + return ; + })} + + + {fieldSchema.mapProperties((schema, key) => { + if (schema['x-align'] === 'left') { + return null; + } + return ; + })} + + +
    +
    - -
    - ); -}); + ); + }, + { displayName: 'ActionBar' }, +); diff --git a/packages/core/client/src/schema-component/antd/action/demos/demo3.tsx b/packages/core/client/src/schema-component/antd/action/demos/demo3.tsx index 32ceeafc9..d2d971de4 100644 --- a/packages/core/client/src/schema-component/antd/action/demos/demo3.tsx +++ b/packages/core/client/src/schema-component/antd/action/demos/demo3.tsx @@ -18,30 +18,33 @@ const useCloseAction = () => { }; }; -const Editable = observer((props) => { - const field = useField(); - const schema = useFieldSchema(); - return ( -
    -
    - 打开方式: - +const Editable = observer( + (props) => { + const field = useField(); + const schema = useFieldSchema(); + return ( +
    +
    + 打开方式: + +
    + {props.children}
    - {props.children} -
    - ); -}); + ); + }, + { displayName: 'Editable' }, +); const schema: ISchema = { type: 'object', diff --git a/packages/core/client/src/schema-component/antd/action/demos/demo5.tsx b/packages/core/client/src/schema-component/antd/action/demos/demo5.tsx index 98660d24a..9263ef84d 100644 --- a/packages/core/client/src/schema-component/antd/action/demos/demo5.tsx +++ b/packages/core/client/src/schema-component/antd/action/demos/demo5.tsx @@ -71,52 +71,55 @@ function TypeSelect(props) { ); } -const EditOptions = observer((props) => { - const record = ArrayTable.useRecord(); - const field = useField(); - console.log(record.type); - return ( - + ); + }, + { displayName: 'EditOptions' }, +); const SchemaField = createSchemaField({ components: { diff --git a/packages/core/client/src/schema-component/antd/association-field/AssociationFieldProvider.tsx b/packages/core/client/src/schema-component/antd/association-field/AssociationFieldProvider.tsx index 2c81951f3..1278e36d0 100644 --- a/packages/core/client/src/schema-component/antd/association-field/AssociationFieldProvider.tsx +++ b/packages/core/client/src/schema-component/antd/association-field/AssociationFieldProvider.tsx @@ -4,63 +4,66 @@ import React, { useEffect, useMemo, useState } from 'react'; import { useCollectionManager } from '../../../collection-manager'; import { AssociationFieldContext } from './context'; -export const AssociationFieldProvider = observer((props) => { - const field = useField(); - const { getCollectionJoinField, getCollection } = useCollectionManager(); - const fieldSchema = useFieldSchema(); - const allowMultiple = fieldSchema['x-component-props']?.multiple !== false; - const allowDissociate = fieldSchema['x-component-props']?.allowDissociate !== false; +export const AssociationFieldProvider = observer( + (props) => { + const field = useField(); + const { getCollectionJoinField, getCollection } = useCollectionManager(); + const fieldSchema = useFieldSchema(); + const allowMultiple = fieldSchema['x-component-props']?.multiple !== false; + const allowDissociate = fieldSchema['x-component-props']?.allowDissociate !== false; - const collectionField = useMemo( - () => getCollectionJoinField(fieldSchema['x-collection-field']), - [fieldSchema['x-collection-field'], fieldSchema.name], - ); - const isFileCollection = useMemo( - () => getCollection(collectionField?.target)?.template === 'file', - [fieldSchema['x-collection-field']], - ); - const currentMode = useMemo( - () => fieldSchema['x-component-props']?.mode || (isFileCollection ? 'FileManager' : 'Select'), - [fieldSchema['x-component-props']?.mode], - ); + const collectionField = useMemo( + () => getCollectionJoinField(fieldSchema['x-collection-field']), + [fieldSchema['x-collection-field'], fieldSchema.name], + ); + const isFileCollection = useMemo( + () => getCollection(collectionField?.target)?.template === 'file', + [fieldSchema['x-collection-field']], + ); + const currentMode = useMemo( + () => fieldSchema['x-component-props']?.mode || (isFileCollection ? 'FileManager' : 'Select'), + [fieldSchema['x-component-props']?.mode], + ); - const [loading, setLoading] = useState(true); + const [loading, setLoading] = useState(true); - useEffect(() => { - setLoading(true); - if (!collectionField) { - setLoading(false); - return; - } - if (field.value !== null && field.value !== undefined) { - // Nester 子表单时,如果没数据初始化一个 [null] 的占位 - if (currentMode === 'Nester' && Array.isArray(field.value)) { - if (field.value.length === 0 && ['belongsToMany', 'hasMany'].includes(collectionField.type)) { + useEffect(() => { + setLoading(true); + if (!collectionField) { + setLoading(false); + return; + } + if (field.value !== null && field.value !== undefined) { + // Nester 子表单时,如果没数据初始化一个 [null] 的占位 + if (currentMode === 'Nester' && Array.isArray(field.value)) { + if (field.value.length === 0 && ['belongsToMany', 'hasMany'].includes(collectionField.type)) { + field.value = [{}]; + } + } + setLoading(false); + return; + } + if (currentMode === 'Nester') { + if (['belongsTo', 'hasOne'].includes(collectionField.type)) { + field.value = {}; + } else if (['belongsToMany', 'hasMany'].includes(collectionField.type)) { field.value = [{}]; } } setLoading(false); - return; - } - if (currentMode === 'Nester') { - if (['belongsTo', 'hasOne'].includes(collectionField.type)) { - field.value = {}; - } else if (['belongsToMany', 'hasMany'].includes(collectionField.type)) { - field.value = [{}]; - } - } - setLoading(false); - }, [currentMode, collectionField, field.value]); + }, [currentMode, collectionField, field.value]); - if (loading) { - return null; - } + if (loading) { + return null; + } - return collectionField ? ( - - {props.children} - - ) : null; -}); + return collectionField ? ( + + {props.children} + + ) : null; + }, + { displayName: 'AssociationFieldProvider' }, +); diff --git a/packages/core/client/src/schema-component/antd/association-field/AssociationSelect.tsx b/packages/core/client/src/schema-component/antd/association-field/AssociationSelect.tsx index d039ae10e..2eadb26c9 100644 --- a/packages/core/client/src/schema-component/antd/association-field/AssociationSelect.tsx +++ b/packages/core/client/src/schema-component/antd/association-field/AssociationSelect.tsx @@ -11,41 +11,44 @@ export type AssociationSelectProps

    = RemoteSelectProps

    & { multiple?: boolean; }; -const InternalAssociationSelect = observer((props: AssociationSelectProps) => { - const { fieldNames, objectValue = true } = props; - const field: any = useField(); - const fieldSchema = useFieldSchema(); - const service = useServiceOptions(props); - const isAllowAddNew = fieldSchema['x-add-new']; - const value = Array.isArray(props.value) ? props.value.filter(Boolean) : props.value; +const InternalAssociationSelect = observer( + (props: AssociationSelectProps) => { + const { fieldNames, objectValue = true } = props; + const field: any = useField(); + const fieldSchema = useFieldSchema(); + const service = useServiceOptions(props); + const isAllowAddNew = fieldSchema['x-add-new']; + const value = Array.isArray(props.value) ? props.value.filter(Boolean) : props.value; - return ( -

    - - + return ( +
    + + - {isAllowAddNew && ( - - { - return s['x-component'] === 'Action'; - }} - /> - - )} - -
    - ); -}); + {isAllowAddNew && ( + + { + return s['x-component'] === 'Action'; + }} + /> + + )} +
    +
    + ); + }, + { displayName: 'InternalAssociationSelect' }, +); interface AssociationSelectInterface { (props: any): React.ReactElement; diff --git a/packages/core/client/src/schema-component/antd/association-field/Editable.tsx b/packages/core/client/src/schema-component/antd/association-field/Editable.tsx index 76377f6f9..319811852 100644 --- a/packages/core/client/src/schema-component/antd/association-field/Editable.tsx +++ b/packages/core/client/src/schema-component/antd/association-field/Editable.tsx @@ -12,50 +12,56 @@ import { InternalSubTable } from './InternalSubTable'; import { CreateRecordAction } from './components/CreateRecordAction'; import { useAssociationFieldContext } from './hooks'; -const EditableAssociationField = observer((props: any) => { - const { multiple } = props; - const field: Field = useField(); - const form = useForm(); - const fieldSchema = useFieldSchema(); - const { options: collectionField, currentMode } = useAssociationFieldContext(); +const EditableAssociationField = observer( + (props: any) => { + const { multiple } = props; + const field: Field = useField(); + const form = useForm(); + const fieldSchema = useFieldSchema(); + const { options: collectionField, currentMode } = useAssociationFieldContext(); - const useCreateActionProps = () => { - const { onClick } = useCAP(); - const actionField: any = useField(); - return { - async onClick() { - await onClick(); - const { data } = actionField.data?.data?.data || {}; - if (data) { - if (['m2m', 'o2m'].includes(collectionField?.interface) && multiple !== false) { - const values = form.getValuesIn(field.path) || []; - values.push(data); - form.setValuesIn(field.path, values); - field.onInput(values); - } else { - form.setValuesIn(field.path, data); - field.onInput(data); + const useCreateActionProps = () => { + const { onClick } = useCAP(); + const actionField: any = useField(); + return { + async onClick() { + await onClick(); + const { data } = actionField.data?.data?.data || {}; + if (data) { + if (['m2m', 'o2m'].includes(collectionField?.interface) && multiple !== false) { + const values = form.getValuesIn(field.path) || []; + values.push(data); + form.setValuesIn(field.path, values); + field.onInput(values); + } else { + form.setValuesIn(field.path, data); + field.onInput(data); + } } - } - }, + }, + }; }; - }; - return ( - - {currentMode === 'Picker' && } - {currentMode === 'Nester' && } - {currentMode === 'Select' && } - {currentMode === 'SubTable' && } - {currentMode === 'FileManager' && } - - ); -}); + return ( + + {currentMode === 'Picker' && } + {currentMode === 'Nester' && } + {currentMode === 'Select' && } + {currentMode === 'SubTable' && } + {currentMode === 'FileManager' && } + + ); + }, + { displayName: 'EditableAssociationField' }, +); -export const Editable = observer((props) => { - return ( - - - - ); -}); +export const Editable = observer( + (props) => { + return ( + + + + ); + }, + { displayName: 'Editable' }, +); diff --git a/packages/core/client/src/schema-component/antd/association-field/InternalPicker.tsx b/packages/core/client/src/schema-component/antd/association-field/InternalPicker.tsx index 409b4bb9f..746b06704 100644 --- a/packages/core/client/src/schema-component/antd/association-field/InternalPicker.tsx +++ b/packages/core/client/src/schema-component/antd/association-field/InternalPicker.tsx @@ -60,138 +60,145 @@ const useTableSelectorProps = () => { }; }; -export const InternalPicker = observer((props: any) => { - const { value, multiple, onChange, quickUpload, selectFile, ...others } = props; - const field: any = useField(); - const fieldNames = useFieldNames(props); - const [visibleSelector, setVisibleSelector] = useState(false); - const fieldSchema = useFieldSchema(); - const insertSelector = useInsertSchema('Selector'); - const { options: collectionField } = useAssociationFieldContext(); - const compile = useCompile(); - const labelUiSchema = useLabelUiSchema(collectionField, fieldNames?.label || 'label'); - const isAllowAddNew = fieldSchema['x-add-new']; - const [selectedRows, setSelectedRows] = useState([]); - const options = useMemo(() => { - if (value && Object.keys(value).length > 0) { - const opts = (Array.isArray(value) ? value : value ? [value] : []).filter(Boolean).map((option) => { - const label = option?.[fieldNames.label]; - return { - ...option, - [fieldNames.label]: getLabelFormatValue(compile(labelUiSchema), compile(label)), - }; - }); - return opts; - } - return []; - }, [value, fieldNames?.label]); +export const InternalPicker = observer( + (props: any) => { + const { value, multiple, onChange, quickUpload, selectFile, ...others } = props; + const field: any = useField(); + const fieldNames = useFieldNames(props); + const [visibleSelector, setVisibleSelector] = useState(false); + const fieldSchema = useFieldSchema(); + const insertSelector = useInsertSchema('Selector'); + const { options: collectionField } = useAssociationFieldContext(); + const compile = useCompile(); + const labelUiSchema = useLabelUiSchema(collectionField, fieldNames?.label || 'label'); + const isAllowAddNew = fieldSchema['x-add-new']; + const [selectedRows, setSelectedRows] = useState([]); + const options = useMemo(() => { + if (value && Object.keys(value).length > 0) { + const opts = (Array.isArray(value) ? value : value ? [value] : []).filter(Boolean).map((option) => { + const label = option?.[fieldNames.label]; + return { + ...option, + [fieldNames.label]: getLabelFormatValue(compile(labelUiSchema), compile(label)), + }; + }); + return opts; + } + return []; + }, [value, fieldNames?.label]); - const pickerProps = { - size: 'small', - fieldNames, - multiple: multiple !== false && ['o2m', 'm2m'].includes(collectionField?.interface), - association: { - target: collectionField?.target, - }, - options, - onChange: props?.onChange, - selectedRows, - setSelectedRows, - collectionField, - }; - - const getValue = () => { - if (multiple == null) return null; - return Array.isArray(value) ? value.filter(Boolean)?.map((v) => v?.[fieldNames.value]) : value?.[fieldNames.value]; - }; - const getFilter = () => { - const targetKey = collectionField?.targetKey || 'id'; - const list = options.map((option) => option[targetKey]).filter(Boolean); - const filter = list.length ? { $and: [{ [`${targetKey}.$ne`]: list }] } : {}; - return filter; - }; - const usePickActionProps = () => { - const { setVisible } = useActionContext(); - const { multiple, selectedRows, onChange, options, collectionField } = useContext(RecordPickerContext); - return { - onClick() { - if (multiple) { - onChange(unionBy(selectedRows, options, collectionField?.targetKey || 'id')); - } else { - onChange(selectedRows?.[0] || null); - } - setVisible(false); + const pickerProps = { + size: 'small', + fieldNames, + multiple: multiple !== false && ['o2m', 'm2m'].includes(collectionField?.interface), + association: { + target: collectionField?.target, }, + options, + onChange: props?.onChange, + selectedRows, + setSelectedRows, + collectionField, }; - }; - return ( - <> - -
    - { + insertSelector(schema.Selector); + setVisibleSelector(true); }} + allowClear + onChange={(changed: any) => { + if (!changed) { + const value = multiple ? [] : null; + onChange(value); + setSelectedRows(value); + } else if (Array.isArray(changed)) { + if (!changed.length) { + onChange([]); + setSelectedRows([]); + return; + } + const values = options?.filter((option) => changed.includes(option[fieldNames.value])); + onChange(values); + setSelectedRows(values); + } + }} + options={options} + value={getValue()} + open={false} /> - - )} - - - - - - - - { - return s['x-component'] === 'AssociationField.Selector'; - }} - /> - - - - - - - - ); -}); +
    + {isAllowAddNew && ( + + { + return s['x-component'] === 'Action'; + }} + /> + + )} +
    + + + + + + + { + return s['x-component'] === 'AssociationField.Selector'; + }} + /> + + + + + + + + ); + }, + { displayName: 'InternalPicker' }, +); diff --git a/packages/core/client/src/schema-component/antd/association-field/InternalViewer.tsx b/packages/core/client/src/schema-component/antd/association-field/InternalViewer.tsx index 9f70e6042..cefc8ecc2 100644 --- a/packages/core/client/src/schema-component/antd/association-field/InternalViewer.tsx +++ b/packages/core/client/src/schema-component/antd/association-field/InternalViewer.tsx @@ -22,94 +22,97 @@ const toValue = (value, placeholder) => { } return value; }; -export const ReadPrettyInternalViewer: React.FC = observer((props: any) => { - const fieldSchema = useFieldSchema(); - const recordCtx = useRecord(); - const { enableLink } = fieldSchema['x-component-props']; - // value 做了转换,但 props.value 和原来 useField().value 的值不一致 - const field = useField(); - const fieldNames = useFieldNames(props); - const [visible, setVisible] = useState(false); - const insertViewer = useInsertSchema('Viewer'); - const { options: collectionField } = useAssociationFieldContext(); - const [record, setRecord] = useState({}); - const compile = useCompile(); - const labelUiSchema = useLabelUiSchema(collectionField, fieldNames?.label || 'label'); - const { snapshot } = useActionContext(); - const ellipsisWithTooltipRef = useRef(); +export const ReadPrettyInternalViewer: React.FC = observer( + (props: any) => { + const fieldSchema = useFieldSchema(); + const recordCtx = useRecord(); + const { enableLink } = fieldSchema['x-component-props']; + // value 做了转换,但 props.value 和原来 useField().value 的值不一致 + const field = useField(); + const fieldNames = useFieldNames(props); + const [visible, setVisible] = useState(false); + const insertViewer = useInsertSchema('Viewer'); + const { options: collectionField } = useAssociationFieldContext(); + const [record, setRecord] = useState({}); + const compile = useCompile(); + const labelUiSchema = useLabelUiSchema(collectionField, fieldNames?.label || 'label'); + const { snapshot } = useActionContext(); + const ellipsisWithTooltipRef = useRef(); - const renderRecords = () => - toArr(props.value).map((record, index, arr) => { - const val = toValue(compile(record?.[fieldNames?.label || 'label']), 'N/A'); - const text = getLabelFormatValue(compile(labelUiSchema), val, true); - return ( - - - {snapshot ? ( - text - ) : enableLink !== false ? ( - { - e.stopPropagation(); - e.preventDefault(); - insertViewer(schema.Viewer); - setVisible(true); - setRecord(record); - ellipsisWithTooltipRef?.current?.setPopoverVisible(false); - }} - > - {text} - - ) : ( - text - )} - - {index < arr.length - 1 ? , : null} - - ); - }); + const renderRecords = () => + toArr(props.value).map((record, index, arr) => { + const val = toValue(compile(record?.[fieldNames?.label || 'label']), 'N/A'); + const text = getLabelFormatValue(compile(labelUiSchema), val, true); + return ( + + + {snapshot ? ( + text + ) : enableLink !== false ? ( + { + e.stopPropagation(); + e.preventDefault(); + insertViewer(schema.Viewer); + setVisible(true); + setRecord(record); + ellipsisWithTooltipRef?.current?.setPopoverVisible(false); + }} + > + {text} + + ) : ( + text + )} + + {index < arr.length - 1 ? , : null} + + ); + }); - const renderWithoutTableFieldResourceProvider = () => ( - - - { - return s['x-component'] === 'AssociationField.Viewer'; - }} - /> - - - ); - - const renderRecordProvider = () => { - const collectionFieldNames = fieldSchema?.['x-collection-field']?.split('.'); - - return collectionFieldNames && collectionFieldNames.length > 2 ? ( - - {renderWithoutTableFieldResourceProvider()} - - ) : ( - {renderWithoutTableFieldResourceProvider()} + const renderWithoutTableFieldResourceProvider = () => ( + + + { + return s['x-component'] === 'AssociationField.Viewer'; + }} + /> + + ); - }; - return ( -
    - - - - {renderRecords()} - - - {renderRecordProvider()} - - - -
    - ); -}); + const renderRecordProvider = () => { + const collectionFieldNames = fieldSchema?.['x-collection-field']?.split('.'); + + return collectionFieldNames && collectionFieldNames.length > 2 ? ( + + {renderWithoutTableFieldResourceProvider()} + + ) : ( + {renderWithoutTableFieldResourceProvider()} + ); + }; + + return ( +
    + + + + {renderRecords()} + + + {renderRecordProvider()} + + + +
    + ); + }, + { displayName: 'ReadPrettyInternalViewer' }, +); diff --git a/packages/core/client/src/schema-component/antd/association-field/Nester.tsx b/packages/core/client/src/schema-component/antd/association-field/Nester.tsx index 2c01c2f33..46e376efb 100644 --- a/packages/core/client/src/schema-component/antd/association-field/Nester.tsx +++ b/packages/core/client/src/schema-component/antd/association-field/Nester.tsx @@ -25,92 +25,95 @@ const ToOneNester = (props) => { return {props.children}; }; -const ToManyNester = observer((props) => { - const fieldSchema = useFieldSchema(); - const { options, field, allowMultiple, allowDissociate } = useAssociationFieldContext(); - const { t } = useTranslation(); - return (field.value || []).length > 0 ? ( - .ant-card-body > .ant-divider:last-child { - display: none; - } - `} - > - {(field.value || []).map((value, index) => { - let allowed = allowDissociate; - if (!allowDissociate) { - allowed = !value?.[options.targetKey]; - } - return ( - <> -
    - {field.editable && allowMultiple && ( - - { - action(() => { - if (!Array.isArray(field.value)) { - field.value = []; - } - spliceArrayState(field as any, { - startIndex: index + 1, - insertCount: 1, +const ToManyNester = observer( + (props) => { + const fieldSchema = useFieldSchema(); + const { options, field, allowMultiple, allowDissociate } = useAssociationFieldContext(); + const { t } = useTranslation(); + return (field.value || []).length > 0 ? ( + .ant-card-body > .ant-divider:last-child { + display: none; + } + `} + > + {(field.value || []).map((value, index) => { + let allowed = allowDissociate; + if (!allowDissociate) { + allowed = !value?.[options.targetKey]; + } + return ( + <> +
    + {field.editable && allowMultiple && ( + + { + action(() => { + if (!Array.isArray(field.value)) { + field.value = []; + } + spliceArrayState(field as any, { + startIndex: index + 1, + insertCount: 1, + }); + field.value.splice(index + 1, 0, {}); + return field.onInput(field.value); }); - field.value.splice(index + 1, 0, {}); - return field.onInput(field.value); - }); - }} - /> - - )} - {!field.readPretty && allowed && ( - - { - action(() => { - spliceArrayState(field as any, { - startIndex: index, - deleteCount: 1, + }} + /> + + )} + {!field.readPretty && allowed && ( + + { + action(() => { + spliceArrayState(field as any, { + startIndex: index, + deleteCount: 1, + }); + field.value.splice(index, 1); + return field.onInput(field.value); }); - field.value.splice(index, 1); - return field.onInput(field.value); - }); - }} - /> - - )} -
    - - - - ); - })} -
    - ) : ( - <> - {field.editable && allowMultiple && ( - - - - )} - - ); -}); + }} + /> +
    + )} +
    + + + + ); + })} +
    + ) : ( + <> + {field.editable && allowMultiple && ( + + + + )} + + ); + }, + { displayName: 'ToManyNester' }, +); diff --git a/packages/core/client/src/schema-component/antd/association-field/ReadPretty.tsx b/packages/core/client/src/schema-component/antd/association-field/ReadPretty.tsx index 746478ee5..9362a54f6 100644 --- a/packages/core/client/src/schema-component/antd/association-field/ReadPretty.tsx +++ b/packages/core/client/src/schema-component/antd/association-field/ReadPretty.tsx @@ -7,23 +7,29 @@ import { InternalSubTable } from './InternalSubTable'; import { FileManageReadPretty } from './FileManager'; import { useAssociationFieldContext } from './hooks'; -const ReadPrettyAssociationField = observer((props: any) => { - const { currentMode } = useAssociationFieldContext(); +const ReadPrettyAssociationField = observer( + (props: any) => { + const { currentMode } = useAssociationFieldContext(); - return ( - <> - {['Select', 'Picker'].includes(currentMode) && } - {currentMode === 'Nester' && } - {currentMode === 'SubTable' && } - {currentMode === 'FileManager' && } - - ); -}); + return ( + <> + {['Select', 'Picker'].includes(currentMode) && } + {currentMode === 'Nester' && } + {currentMode === 'SubTable' && } + {currentMode === 'FileManager' && } + + ); + }, + { displayName: 'ReadPrettyAssociationField' }, +); -export const ReadPretty = observer((props) => { - return ( - - - - ); -}); +export const ReadPretty = observer( + (props) => { + return ( + + + + ); + }, + { displayName: 'ReadPretty' }, +); diff --git a/packages/core/client/src/schema-component/antd/association-field/SubTable.tsx b/packages/core/client/src/schema-component/antd/association-field/SubTable.tsx index 8424a13af..6ecbc0e5b 100644 --- a/packages/core/client/src/schema-component/antd/association-field/SubTable.tsx +++ b/packages/core/client/src/schema-component/antd/association-field/SubTable.tsx @@ -5,24 +5,27 @@ import React from 'react'; import { Table } from '../table-v2/Table'; import { useAssociationFieldContext } from './hooks'; -export const SubTable: any = observer((props) => { - const { field } = useAssociationFieldContext(); - return ( -
    -
    - {field.editable && ( - - )} - - ); -}); +export const SubTable: any = observer( + (props) => { + const { field } = useAssociationFieldContext(); + return ( +
    +
    + {field.editable && ( + + )} + + ); + }, + { displayName: 'SubTable' }, +); diff --git a/packages/core/client/src/schema-component/antd/association-field/components/CreateRecordAction.tsx b/packages/core/client/src/schema-component/antd/association-field/components/CreateRecordAction.tsx index cd5afa7e4..1c14bc215 100644 --- a/packages/core/client/src/schema-component/antd/association-field/components/CreateRecordAction.tsx +++ b/packages/core/client/src/schema-component/antd/association-field/components/CreateRecordAction.tsx @@ -6,34 +6,37 @@ import { ActionContext, useActionContext } from '../../action'; import { useAssociationFieldContext, useInsertSchema } from '../hooks'; import schema from '../schema'; -export const CreateRecordAction = observer((props) => { - const field: any = useField(); - const fieldSchema = useFieldSchema(); - const ctx = useActionContext(); - const insertAddNewer = useInsertSchema('AddNewer'); - const { options: collectionField } = useAssociationFieldContext(); - const [visibleAddNewer, setVisibleAddNewer] = useState(false); - const [currentCollection, setCurrentCollection] = useState(collectionField?.target); - const addbuttonClick = (name) => { - insertAddNewer(schema.AddNewer); - setVisibleAddNewer(true); - setCurrentCollection(name); - }; - return ( - - addbuttonClick(arg)} /> - - - { - return s['x-component'] === 'AssociationField.AddNewer'; - }} - /> - - - - ); -}); +export const CreateRecordAction = observer( + (props) => { + const field: any = useField(); + const fieldSchema = useFieldSchema(); + const ctx = useActionContext(); + const insertAddNewer = useInsertSchema('AddNewer'); + const { options: collectionField } = useAssociationFieldContext(); + const [visibleAddNewer, setVisibleAddNewer] = useState(false); + const [currentCollection, setCurrentCollection] = useState(collectionField?.target); + const addbuttonClick = (name) => { + insertAddNewer(schema.AddNewer); + setVisibleAddNewer(true); + setCurrentCollection(name); + }; + return ( + + addbuttonClick(arg)} /> + + + { + return s['x-component'] === 'AssociationField.AddNewer'; + }} + /> + + + + ); + }, + { displayName: 'CreateRecordAction' }, +); diff --git a/packages/core/client/src/schema-component/antd/association-select/ReadPretty.tsx b/packages/core/client/src/schema-component/antd/association-select/ReadPretty.tsx index 54fa4ff12..66cbdd103 100644 --- a/packages/core/client/src/schema-component/antd/association-select/ReadPretty.tsx +++ b/packages/core/client/src/schema-component/antd/association-select/ReadPretty.tsx @@ -4,8 +4,11 @@ import { useFieldTitle } from '../../hooks'; import { RemoteSelect } from '../remote-select'; import useServiceOptions from './useServiceOptions'; -export const ReadPretty = observer((props: any) => { - const service = useServiceOptions(props); - useFieldTitle(); - return ; -}); +export const ReadPretty = observer( + (props: any) => { + const service = useServiceOptions(props); + useFieldTitle(); + return ; + }, + { displayName: 'ReadPretty' }, +); diff --git a/packages/core/client/src/schema-component/antd/block-item/demos/demo1.tsx b/packages/core/client/src/schema-component/antd/block-item/demos/demo1.tsx index b3e462243..5dde65fa2 100644 --- a/packages/core/client/src/schema-component/antd/block-item/demos/demo1.tsx +++ b/packages/core/client/src/schema-component/antd/block-item/demos/demo1.tsx @@ -3,15 +3,18 @@ import { uid } from '@formily/shared'; import { BlockItem, DndContext, DragHandler, SchemaComponent, SchemaComponentProvider } from '@nocobase/client'; import React from 'react'; -const Block = observer((props) => { - const fieldSchema = useFieldSchema(); - return ( -
    - Block {fieldSchema.name} - -
    - ); -}); +const Block = observer( + (props) => { + const fieldSchema = useFieldSchema(); + return ( +
    + Block {fieldSchema.name} + +
    + ); + }, + { displayName: 'Block' }, +); export default function App() { return ( diff --git a/packages/core/client/src/schema-component/antd/calendar/Calendar.tsx b/packages/core/client/src/schema-component/antd/calendar/Calendar.tsx index d5a772b1c..54504f800 100644 --- a/packages/core/client/src/schema-component/antd/calendar/Calendar.tsx +++ b/packages/core/client/src/schema-component/antd/calendar/Calendar.tsx @@ -190,71 +190,74 @@ const CalendarRecordViewer = (props) => { ); }; -export const Calendar: any = observer((props: any) => { - const { dataSource, fieldNames, showLunar, fixedBlock } = useProps(props); - const [date, setDate] = useState(new Date()); - const [view, setView] = useState<(typeof Weeks)[number]>('month'); - const events = useEvents(dataSource, fieldNames, date, view); - const [visible, setVisible] = useState(false); - const [record, setRecord] = useState({}); +export const Calendar: any = observer( + (props: any) => { + const { dataSource, fieldNames, showLunar, fixedBlock } = useProps(props); + const [date, setDate] = useState(new Date()); + const [view, setView] = useState<(typeof Weeks)[number]>('month'); + const events = useEvents(dataSource, fieldNames, date, view); + const [visible, setVisible] = useState(false); + const [record, setRecord] = useState({}); - const components = useMemo(() => { - return { - toolbar: (props) => , - week: { - header: (props) =>
    , - }, - month: { - dateHeader: (props) =>
    , - }, - }; - }, [showLunar]); + const components = useMemo(() => { + return { + toolbar: (props) => , + week: { + header: (props) =>
    , + }, + month: { + dateHeader: (props) =>
    , + }, + }; + }, [showLunar]); - return ( -
    - - { - console.log('onSelectSlot', slotInfo); - }} - onDoubleClickEvent={(event) => { - console.log('onDoubleClickEvent'); - }} - onSelectEvent={(event) => { - const record = dataSource?.find((item) => item[fieldNames.id] === event.id); - if (!record) { - return; - } - record.__event = { ...event, start: formatDate(moment(event.start)), end: formatDate(moment(event.end)) }; - - setRecord(record); - setVisible(true); - }} - formats={{ - monthHeaderFormat: 'Y-M', - agendaDateFormat: 'M-DD', - dayHeaderFormat: 'Y-M-DD', - dayRangeHeaderFormat: ({ start, end }, culture, local) => { - if (dates.eq(start, end, 'month')) { - return local.format(start, 'Y-M', culture); + return ( +
    + + { + console.log('onSelectSlot', slotInfo); + }} + onDoubleClickEvent={(event) => { + console.log('onDoubleClickEvent'); + }} + onSelectEvent={(event) => { + const record = dataSource?.find((item) => item[fieldNames.id] === event.id); + if (!record) { + return; } - return `${local.format(start, 'Y-M', culture)} - ${local.format(end, 'Y-M', culture)}`; - }, - }} - components={components} - localizer={localizer} - /> -
    - ); -}); + record.__event = { ...event, start: formatDate(moment(event.start)), end: formatDate(moment(event.end)) }; + + setRecord(record); + setVisible(true); + }} + formats={{ + monthHeaderFormat: 'Y-M', + agendaDateFormat: 'M-DD', + dayHeaderFormat: 'Y-M-DD', + dayRangeHeaderFormat: ({ start, end }, culture, local) => { + if (dates.eq(start, end, 'month')) { + return local.format(start, 'Y-M', culture); + } + return `${local.format(start, 'Y-M', culture)} - ${local.format(end, 'Y-M', culture)}`; + }, + }} + components={components} + localizer={localizer} + /> +
    + ); + }, + { displayName: 'Calendar' }, +); diff --git a/packages/core/client/src/schema-component/antd/calendar/DeleteEvent.tsx b/packages/core/client/src/schema-component/antd/calendar/DeleteEvent.tsx index 00cc4703e..45875df91 100644 --- a/packages/core/client/src/schema-component/antd/calendar/DeleteEvent.tsx +++ b/packages/core/client/src/schema-component/antd/calendar/DeleteEvent.tsx @@ -11,61 +11,64 @@ import { DeleteEventContext } from './Calendar'; import { formatDate } from './utils'; const { Text } = Typography; -export const DeleteEvent = observer(() => { - const { visible, setVisible } = useActionContext(); - const { exclude = [], cron, ...record } = useRecord(); - const { close } = useContext(DeleteEventContext); - const startDate = formatDate(moment(record.__parent.__event.start)); - const filterByTk = useFilterByTk(); - const { resource, service, __parent } = useBlockRequestContext(); - const [value, onChange] = useState(startDate); - const [loading, setLoading] = useState(false); - const onOk = async () => { - setLoading(true); - if (value === 'all' || !cron) { - await resource.destroy({ - filterByTk, - }); - } else { - await resource.update({ - filterByTk, - values: { - exclude: (exclude || []).concat(value), - }, - }); - } - setLoading(false); - __parent?.service?.refresh?.(); - service?.refresh?.(); - setVisible?.(false, true); - close(); - }; +export const DeleteEvent = observer( + () => { + const { visible, setVisible } = useActionContext(); + const { exclude = [], cron, ...record } = useRecord(); + const { close } = useContext(DeleteEventContext); + const startDate = formatDate(moment(record.__parent.__event.start)); + const filterByTk = useFilterByTk(); + const { resource, service, __parent } = useBlockRequestContext(); + const [value, onChange] = useState(startDate); + const [loading, setLoading] = useState(false); + const onOk = async () => { + setLoading(true); + if (value === 'all' || !cron) { + await resource.destroy({ + filterByTk, + }); + } else { + await resource.update({ + filterByTk, + values: { + exclude: (exclude || []).concat(value), + }, + }); + } + setLoading(false); + __parent?.service?.refresh?.(); + service?.refresh?.(); + setVisible?.(false, true); + close(); + }; - const { t } = useTranslation(); - return createPortal( - setVisible(false)} - onOk={() => onOk()} - confirmLoading={loading} - > - {cron ? ( - onChange(event.target.value)}> - - {t('This event')} - {t('This and following events')} - {t('All events')} - - - ) : ( - - {t('Delete this event?')} - - )} - , - document.body, - ); -}); + const { t } = useTranslation(); + return createPortal( + setVisible(false)} + onOk={() => onOk()} + confirmLoading={loading} + > + {cron ? ( + onChange(event.target.value)}> + + {t('This event')} + {t('This and following events')} + {t('All events')} + + + ) : ( + + {t('Delete this event?')} + + )} + , + document.body, + ); + }, + { displayName: 'DeleteEvent' }, +); export default DeleteEvent; diff --git a/packages/core/client/src/schema-component/antd/calendar/Event.tsx b/packages/core/client/src/schema-component/antd/calendar/Event.tsx index 73a9f26f6..4550041ba 100644 --- a/packages/core/client/src/schema-component/antd/calendar/Event.tsx +++ b/packages/core/client/src/schema-component/antd/calendar/Event.tsx @@ -1,6 +1,9 @@ import { observer } from '@formily/react'; import React from 'react'; -export const Event = observer((props) => { - return <>{props.children}; -}); +export const Event = observer( + (props) => { + return <>{props.children}; + }, + { displayName: 'Event' }, +); diff --git a/packages/core/client/src/schema-component/antd/calendar/Nav.tsx b/packages/core/client/src/schema-component/antd/calendar/Nav.tsx index 4a8bd3ca3..dd2938323 100644 --- a/packages/core/client/src/schema-component/antd/calendar/Nav.tsx +++ b/packages/core/client/src/schema-component/antd/calendar/Nav.tsx @@ -6,14 +6,17 @@ import { navigate } from 'react-big-calendar/lib/utils/constants'; import { useDesignable } from '../../hooks'; import { CalendarToolbarContext } from './context'; -export const Nav = observer((props) => { - const { DesignableBar } = useDesignable(); - const { onNavigate } = useContext(CalendarToolbarContext); - return ( -
    - - - -
    - ); -}); +export const Nav = observer( + (props) => { + const { DesignableBar } = useDesignable(); + const { onNavigate } = useContext(CalendarToolbarContext); + return ( +
    + + + +
    + ); + }, + { displayName: 'Nav' }, +); diff --git a/packages/core/client/src/schema-component/antd/calendar/Title.tsx b/packages/core/client/src/schema-component/antd/calendar/Title.tsx index 7e45128bd..a91f3e1d2 100644 --- a/packages/core/client/src/schema-component/antd/calendar/Title.tsx +++ b/packages/core/client/src/schema-component/antd/calendar/Title.tsx @@ -4,22 +4,25 @@ import { useDesignable } from '../../hooks'; import { CalendarToolbarContext } from './context'; import { getLunarDay } from './utils'; -export const Title = observer(() => { - const { DesignableBar } = useDesignable(); - const { date, view, label, showLunar } = useContext(CalendarToolbarContext); +export const Title = observer( + () => { + const { DesignableBar } = useDesignable(); + const { date, view, label, showLunar } = useContext(CalendarToolbarContext); - const lunarElement = useMemo(() => { - if (!showLunar || view !== 'day') { - return; - } - return {getLunarDay(date)}; - }, [view, date, showLunar]); + const lunarElement = useMemo(() => { + if (!showLunar || view !== 'day') { + return; + } + return {getLunarDay(date)}; + }, [view, date, showLunar]); - return ( -
    - {label} - {lunarElement} - -
    - ); -}); + return ( +
    + {label} + {lunarElement} + +
    + ); + }, + { displayName: 'Title' }, +); diff --git a/packages/core/client/src/schema-component/antd/calendar/Today.tsx b/packages/core/client/src/schema-component/antd/calendar/Today.tsx index dd8804f7b..a8fa40355 100644 --- a/packages/core/client/src/schema-component/antd/calendar/Today.tsx +++ b/packages/core/client/src/schema-component/antd/calendar/Today.tsx @@ -6,18 +6,21 @@ import { useTranslation } from 'react-i18next'; import { useDesignable } from '../../hooks'; import { CalendarToolbarContext } from './context'; -export const Today = observer((props) => { - const { DesignableBar } = useDesignable(); - const { onNavigate } = useContext(CalendarToolbarContext); - const { t } = useTranslation(); - return ( - - ); -}); +export const Today = observer( + (props) => { + const { DesignableBar } = useDesignable(); + const { onNavigate } = useContext(CalendarToolbarContext); + const { t } = useTranslation(); + return ( + + ); + }, + { displayName: 'Today' }, +); diff --git a/packages/core/client/src/schema-component/antd/calendar/ViewSelect.tsx b/packages/core/client/src/schema-component/antd/calendar/ViewSelect.tsx index 027ea36e3..afcda564e 100644 --- a/packages/core/client/src/schema-component/antd/calendar/ViewSelect.tsx +++ b/packages/core/client/src/schema-component/antd/calendar/ViewSelect.tsx @@ -4,22 +4,25 @@ import React, { useContext } from 'react'; import { useDesignable } from '../../hooks'; import { CalendarToolbarContext } from './context'; -export const ViewSelect = observer((props) => { - const { DesignableBar } = useDesignable(); - const { - views, - view, - onView, - localizer: { messages }, - } = useContext(CalendarToolbarContext); - return ( -
    - - -
    - ); -}); +export const ViewSelect = observer( + (props) => { + const { DesignableBar } = useDesignable(); + const { + views, + view, + onView, + localizer: { messages }, + } = useContext(CalendarToolbarContext); + return ( +
    + + +
    + ); + }, + { displayName: 'ViewSelect' }, +); diff --git a/packages/core/client/src/schema-component/antd/collection-select/CollectionSelect.tsx b/packages/core/client/src/schema-component/antd/collection-select/CollectionSelect.tsx index 3a3dadead..de529c445 100644 --- a/packages/core/client/src/schema-component/antd/collection-select/CollectionSelect.tsx +++ b/packages/core/client/src/schema-component/antd/collection-select/CollectionSelect.tsx @@ -58,6 +58,6 @@ export const CollectionSelect = connect( ))} ); - }), + }, { displayName: 'CollectionSelectObserver' }), ), ); diff --git a/packages/core/client/src/schema-component/antd/filter/Filter.tsx b/packages/core/client/src/schema-component/antd/filter/Filter.tsx index 245f283a5..db3af32fb 100644 --- a/packages/core/client/src/schema-component/antd/filter/Filter.tsx +++ b/packages/core/client/src/schema-component/antd/filter/Filter.tsx @@ -15,35 +15,38 @@ const useDef = (options) => { return useRequest(() => Promise.resolve({ data: field.dataSource }), options); }; -export const Filter: any = observer((props: any) => { - const { useDataSource = useDef } = props; - const { options, dynamicComponent, className } = useProps(props); - const field = useField(); - const fieldSchema = useFieldSchema(); - useDataSource({ - onSuccess(data) { - field.dataSource = data?.data || []; - }, - }); - return ( -
    - - - - {/*
    {JSON.stringify(field.value, null, 2)}
    */} -
    -
    -
    - ); -}); +export const Filter: any = observer( + (props: any) => { + const { useDataSource = useDef } = props; + const { options, dynamicComponent, className } = useProps(props); + const field = useField(); + const fieldSchema = useFieldSchema(); + useDataSource({ + onSuccess(data) { + field.dataSource = data?.data || []; + }, + }); + return ( +
    + + + + {/*
    {JSON.stringify(field.value, null, 2)}
    */} +
    +
    +
    + ); + }, + { displayName: 'Filter' }, +); Filter.SaveDefaultValue = SaveDefaultValue; diff --git a/packages/core/client/src/schema-component/antd/filter/FilterAction.tsx b/packages/core/client/src/schema-component/antd/filter/FilterAction.tsx index 27623159e..c55432f24 100644 --- a/packages/core/client/src/schema-component/antd/filter/FilterAction.tsx +++ b/packages/core/client/src/schema-component/antd/filter/FilterAction.tsx @@ -11,83 +11,86 @@ import { Action } from '../action'; export const FilterActionContext = createContext(null); -export const FilterAction = observer((props: any) => { - const { t } = useTranslation(); - const field = useField(); - const [visible, setVisible] = useState(false); - const { designable, dn } = useDesignable(); - const fieldSchema = useFieldSchema(); - const form = useMemo
    (() => props.form || createForm(), []); - const { options, onSubmit, onReset, ...others } = useProps(props); - return ( - - { - setVisible(visible); - }} - trigger={'click'} - content={ - - - { + const { t } = useTranslation(); + const field = useField(); + const [visible, setVisible] = useState(false); + const { designable, dn } = useDesignable(); + const fieldSchema = useFieldSchema(); + const form = useMemo(() => props.form || createForm(), []); + const { options, onSubmit, onReset, ...others } = useProps(props); + return ( + + { + setVisible(visible); + }} + trigger={'click'} + content={ + + + -
    - - - - - -
    -
    - - } - > - -
    -
    - ); -}); + }} + /> +
    + + + + + +
    +
    + + } + > + +
    +
    + ); + }, + { displayName: 'FilterAction' }, +); const SaveConditions = () => { const { fieldSchema, field, designable, dn } = useContext(FilterActionContext); diff --git a/packages/core/client/src/schema-component/antd/filter/FilterItem.tsx b/packages/core/client/src/schema-component/antd/filter/FilterItem.tsx index 8f10a6a95..de1ba7066 100644 --- a/packages/core/client/src/schema-component/antd/filter/FilterItem.tsx +++ b/packages/core/client/src/schema-component/antd/filter/FilterItem.tsx @@ -9,56 +9,59 @@ import { RemoveConditionContext } from './context'; import { DynamicComponent } from './DynamicComponent'; import { useValues } from './useValues'; -export const FilterItem = observer((props: any) => { - const { t } = useTranslation(); - const compile = useCompile(); - const remove = useContext(RemoveConditionContext); - const { schema, fields, operators, dataIndex, operator, setDataIndex, setOperator, value, setValue } = useValues(); - return ( -
    - - { - setDataIndex(value); - }} - placeholder={t('Select Field')} - /> - { + setOperator(value); + }} + placeholder={t('Comparision')} + /> + {!operator?.noValue && + React.createElement(DynamicComponent, { + value: value ? value : undefined, + schema, + onChange(value) { + setValue(value); + }, + })} + {!props.disabled && ( + + remove()} style={{ color: '#bfbfbf' }} /> + + )} + +
    + ); + }, + { displayName: 'FilterItem' }, +); diff --git a/packages/core/client/src/schema-component/antd/filter/FilterItems.tsx b/packages/core/client/src/schema-component/antd/filter/FilterItems.tsx index c6064b0a1..8fbd15c1f 100644 --- a/packages/core/client/src/schema-component/antd/filter/FilterItems.tsx +++ b/packages/core/client/src/schema-component/antd/filter/FilterItems.tsx @@ -5,17 +5,20 @@ import { RemoveConditionContext } from './context'; import { FilterGroup } from './FilterGroup'; import { FilterItem } from './FilterItem'; -export const FilterItems = observer((props) => { - const field = useField(); - return ( -
    - {field?.value?.map((item, index) => { - return ( - field.remove(index)}> - - - ); - })} -
    - ); -}); +export const FilterItems = observer( + (props) => { + const field = useField(); + return ( +
    + {field?.value?.map((item, index) => { + return ( + field.remove(index)}> + + + ); + })} +
    + ); + }, + { displayName: 'FilterItems' }, +); diff --git a/packages/core/client/src/schema-component/antd/form-item/FormItem.tsx b/packages/core/client/src/schema-component/antd/form-item/FormItem.tsx index e4d3380be..3de16bb96 100644 --- a/packages/core/client/src/schema-component/antd/form-item/FormItem.tsx +++ b/packages/core/client/src/schema-component/antd/form-item/FormItem.tsx @@ -53,61 +53,64 @@ const divWrap = (schema: ISchema) => { }; }; -export const FormItem: any = observer((props: any) => { - useEnsureOperatorsValid(); +export const FormItem: any = observer( + (props: any) => { + useEnsureOperatorsValid(); - const field = useField(); - const ctx = useContext(BlockRequestContext); - const schema = useFieldSchema(); - const variablesCtx = useVariablesCtx(); + const field = useField(); + const ctx = useContext(BlockRequestContext); + const schema = useFieldSchema(); + const variablesCtx = useVariablesCtx(); - useEffect(() => { - if (ctx?.block === 'form') { - ctx.field.data = ctx.field.data || {}; - ctx.field.data.activeFields = ctx.field.data.activeFields || new Set(); - ctx.field.data.activeFields.add(schema.name); - // 如果默认值是一个变量,则需要解析之后再显示出来 - if (isVariable(schema?.default)) { - field.setInitialValue?.(parseVariables(schema.default, variablesCtx)); + useEffect(() => { + if (ctx?.block === 'form') { + ctx.field.data = ctx.field.data || {}; + ctx.field.data.activeFields = ctx.field.data.activeFields || new Set(); + ctx.field.data.activeFields.add(schema.name); + // 如果默认值是一个变量,则需要解析之后再显示出来 + if (isVariable(schema?.default)) { + field.setInitialValue?.(parseVariables(schema.default, variablesCtx)); + } } - } - }, []); - const showTitle = schema['x-decorator-props']?.showTitle ?? true; - return ( - - - .ant-formily-item-label { - display: none; + }, []); + const showTitle = schema['x-decorator-props']?.showTitle ?? true; + return ( + + + '), - }} - /> - ) : ( - field.description - ) - } - /> - - - ); -}); + `, + { + [css` + > .ant-formily-item-label { + display: none; + } + `]: showTitle === false, + }, + )} + {...props} + extra={ + typeof field.description === 'string' ? ( +
    '), + }} + /> + ) : ( + field.description + ) + } + /> + + + ); + }, + { displayName: 'FormItem' }, +); FormItem.Designer = function Designer() { const { getCollectionFields, getInterface, getCollectionJoinField, getCollection } = useCollectionManager(); diff --git a/packages/core/client/src/schema-component/antd/form-v2/Form.tsx b/packages/core/client/src/schema-component/antd/form-v2/Form.tsx index 992b4bd2a..0a3023d7f 100644 --- a/packages/core/client/src/schema-component/antd/form-v2/Form.tsx +++ b/packages/core/client/src/schema-component/antd/form-v2/Form.tsx @@ -170,21 +170,24 @@ export const Form: React.FC & { FilterDesigner?: any; ReadPrettyDesigner?: any; Templates?: any; -} = observer((props) => { - const field = useField(); - const { form, disabled, ...others } = useProps(props); - const formDisabled = disabled || field.disabled; - return ( - -
    - - {form ? ( - - ) : ( - - )} - - -
    - ); -}); +} = observer( + (props) => { + const field = useField(); + const { form, disabled, ...others } = useProps(props); + const formDisabled = disabled || field.disabled; + return ( + +
    + + {form ? ( + + ) : ( + + )} + + +
    + ); + }, + { displayName: 'Form' }, +); diff --git a/packages/core/client/src/schema-component/antd/form-v2/FormField.tsx b/packages/core/client/src/schema-component/antd/form-v2/FormField.tsx index 547e39881..bc217feea 100644 --- a/packages/core/client/src/schema-component/antd/form-v2/FormField.tsx +++ b/packages/core/client/src/schema-component/antd/form-v2/FormField.tsx @@ -4,21 +4,24 @@ import { useFormBlockContext } from '../../../block-provider'; import { useCollection } from '../../../collection-manager'; import { useCompile } from '../../hooks'; -export const FormField: any = observer((props) => { - const fieldSchema = useFieldSchema(); - const { getField } = useCollection(); - const field = useField(); - const collectionField = getField(fieldSchema.name); - const compile = useCompile(); - const ctx = useFormBlockContext(); - useEffect(() => { - if (!field.title) { - field.title = compile(collectionField?.uiSchema?.title); - } - if (ctx?.field) { - ctx.field.added = ctx.field.added || new Set(); - ctx.field.added.add(fieldSchema.name); - } - }, []); - return
    {props.children}
    ; -}); +export const FormField: any = observer( + (props) => { + const fieldSchema = useFieldSchema(); + const { getField } = useCollection(); + const field = useField(); + const collectionField = getField(fieldSchema.name); + const compile = useCompile(); + const ctx = useFormBlockContext(); + useEffect(() => { + if (!field.title) { + field.title = compile(collectionField?.uiSchema?.title); + } + if (ctx?.field) { + ctx.field.added = ctx.field.added || new Set(); + ctx.field.added.add(fieldSchema.name); + } + }, []); + return
    {props.children}
    ; + }, + { displayName: 'FormField' }, +); diff --git a/packages/core/client/src/schema-component/antd/form/Form.tsx b/packages/core/client/src/schema-component/antd/form/Form.tsx index 9991f6fae..2a6133a4d 100644 --- a/packages/core/client/src/schema-component/antd/form/Form.tsx +++ b/packages/core/client/src/schema-component/antd/form/Form.tsx @@ -83,34 +83,37 @@ const useDefaultValues = (opts: any = {}, props: FormProps = {}) => { const FormBlockContext = createContext(null); -export const Form: React.FC & { Designer?: any } = observer((props) => { - const { request, effects, initialValue, useValues = useDefaultValues, ...others } = props; - const fieldSchema = useFieldSchema(); - const field = useField(); - const form = useMemo(() => createForm({ effects }), []); - const result = useValues( - { - uid: fieldSchema['x-uid'], - async onSuccess(data) { - await form.reset(); - form.setValues(data?.data); +export const Form: React.FC & { Designer?: any } = observer( + (props) => { + const { request, effects, initialValue, useValues = useDefaultValues, ...others } = props; + const fieldSchema = useFieldSchema(); + const field = useField(); + const form = useMemo(() => createForm({ effects }), []); + const result = useValues( + { + uid: fieldSchema['x-uid'], + async onSuccess(data) { + await form.reset(); + form.setValues(data?.data); + }, }, - }, - props, - ); - const parent = useContext(FormBlockContext); - return ( - - - {fieldSchema['x-decorator'] === 'Form' ? ( - - ) : ( - - )} - - - ); -}); + props, + ); + const parent = useContext(FormBlockContext); + return ( + + + {fieldSchema['x-decorator'] === 'Form' ? ( + + ) : ( + + )} + + + ); + }, + { displayName: 'Form' }, +); Form.Designer = () => { const { name, title } = useCollection(); diff --git a/packages/core/client/src/schema-component/antd/form/demos/demo1.tsx b/packages/core/client/src/schema-component/antd/form/demos/demo1.tsx index 9eab608bc..5b2778de4 100644 --- a/packages/core/client/src/schema-component/antd/form/demos/demo1.tsx +++ b/packages/core/client/src/schema-component/antd/form/demos/demo1.tsx @@ -49,10 +49,13 @@ export default observer(() => { }, }; - const Output = observer(() => { - const form = useForm(); - return
    {JSON.stringify(form.values, null, 2)}
    ; - }); + const Output = observer( + () => { + const form = useForm(); + return
    {JSON.stringify(form.values, null, 2)}
    ; + }, + { displayName: 'Output' }, + ); return ( diff --git a/packages/core/client/src/schema-component/antd/form/demos/demo2.tsx b/packages/core/client/src/schema-component/antd/form/demos/demo2.tsx index 5f1f243aa..5107888bd 100644 --- a/packages/core/client/src/schema-component/antd/form/demos/demo2.tsx +++ b/packages/core/client/src/schema-component/antd/form/demos/demo2.tsx @@ -38,10 +38,13 @@ export default observer(() => { }, }; - const Output = observer(() => { - const form = useForm(); - return
    {JSON.stringify(form.values, null, 2)}
    ; - }); + const Output = observer( + () => { + const form = useForm(); + return
    {JSON.stringify(form.values, null, 2)}
    ; + }, + { displayName: 'Output' }, + ); const useSubmit = () => { const form = useForm(); diff --git a/packages/core/client/src/schema-component/antd/form/demos/demo3.tsx b/packages/core/client/src/schema-component/antd/form/demos/demo3.tsx index 87cf4589f..935390c0d 100644 --- a/packages/core/client/src/schema-component/antd/form/demos/demo3.tsx +++ b/packages/core/client/src/schema-component/antd/form/demos/demo3.tsx @@ -38,10 +38,13 @@ export default observer(() => { }, }; - const Output = observer(() => { - const form = useForm(); - return
    {JSON.stringify(form.values, null, 2)}
    ; - }); + const Output = observer( + () => { + const form = useForm(); + return
    {JSON.stringify(form.values, null, 2)}
    ; + }, + { displayName: 'Output' }, + ); const useSubmit = () => { const form = useForm(); diff --git a/packages/core/client/src/schema-component/antd/form/demos/demo4.tsx b/packages/core/client/src/schema-component/antd/form/demos/demo4.tsx index 904fbac89..7849eb7f3 100644 --- a/packages/core/client/src/schema-component/antd/form/demos/demo4.tsx +++ b/packages/core/client/src/schema-component/antd/form/demos/demo4.tsx @@ -54,10 +54,13 @@ export default observer(() => { }, }; - const Output = observer(() => { - const form = useForm(); - return
    {JSON.stringify(form.values, null, 2)}
    ; - }); + const Output = observer( + () => { + const form = useForm(); + return
    {JSON.stringify(form.values, null, 2)}
    ; + }, + { displayName: 'Output' }, + ); return ( diff --git a/packages/core/client/src/schema-component/antd/form/demos/demo5.tsx b/packages/core/client/src/schema-component/antd/form/demos/demo5.tsx index c7494e0d4..83bc545f4 100644 --- a/packages/core/client/src/schema-component/antd/form/demos/demo5.tsx +++ b/packages/core/client/src/schema-component/antd/form/demos/demo5.tsx @@ -69,10 +69,13 @@ export default observer(() => { }, }; - const Output = observer(() => { - const form = useForm(); - return
    {JSON.stringify(form.values, null, 2)}
    ; - }); + const Output = observer( + () => { + const form = useForm(); + return
    {JSON.stringify(form.values, null, 2)}
    ; + }, + { displayName: 'Output' }, + ); const useSubmit = () => { const form = useForm(); diff --git a/packages/core/client/src/schema-component/antd/form/demos/demo6.tsx b/packages/core/client/src/schema-component/antd/form/demos/demo6.tsx index 3e44e1ae9..bd664dfaf 100644 --- a/packages/core/client/src/schema-component/antd/form/demos/demo6.tsx +++ b/packages/core/client/src/schema-component/antd/form/demos/demo6.tsx @@ -39,10 +39,13 @@ export default observer(() => { }, }; - const Output = observer(() => { - const form = useForm(); - return
    {JSON.stringify(form.values, null, 2)}
    ; - }); + const Output = observer( + () => { + const form = useForm(); + return
    {JSON.stringify(form.values, null, 2)}
    ; + }, + { displayName: 'Output' }, + ); const useSubmit = () => { const form = useForm(); diff --git a/packages/core/client/src/schema-component/antd/form/demos/demo7.tsx b/packages/core/client/src/schema-component/antd/form/demos/demo7.tsx index bba9db056..f695eccf1 100644 --- a/packages/core/client/src/schema-component/antd/form/demos/demo7.tsx +++ b/packages/core/client/src/schema-component/antd/form/demos/demo7.tsx @@ -36,10 +36,13 @@ const schema: ISchema = { }, }; -const Output = observer(() => { - const form = useForm(); - return
    {JSON.stringify(form.values, null, 2)}
    ; -}); +const Output = observer( + () => { + const form = useForm(); + return
    {JSON.stringify(form.values, null, 2)}
    ; + }, + { displayName: 'Output' }, +); const useSubmit = () => { const form = useForm(); diff --git a/packages/core/client/src/schema-component/antd/g2plot/G2Plot.tsx b/packages/core/client/src/schema-component/antd/g2plot/G2Plot.tsx index 9cd945680..6453837f0 100644 --- a/packages/core/client/src/schema-component/antd/g2plot/G2Plot.tsx +++ b/packages/core/client/src/schema-component/antd/g2plot/G2Plot.tsx @@ -127,51 +127,54 @@ export const G2PlotRenderer = forwardRef(function (props: ReactG2PlotPr return
    ; }); -export const G2Plot: any = observer((props: any) => { - const { plot, config } = props; - const field = useField(); - const { t } = useTranslation(); - const api = useAPIClient(); - useEffect(() => { - field.data = field.data || {}; - field.data.loading = true; - const fn = config?.data; - if (typeof fn === 'function') { - const result = fn.bind({ api })(); - if (result?.then) { - result.then((data) => { - if (Array.isArray(data)) { - field.componentProps.config.data = data; - } +export const G2Plot: any = observer( + (props: any) => { + const { plot, config } = props; + const field = useField(); + const { t } = useTranslation(); + const api = useAPIClient(); + useEffect(() => { + field.data = field.data || {}; + field.data.loading = true; + const fn = config?.data; + if (typeof fn === 'function') { + const result = fn.bind({ api })(); + if (result?.then) { + result.then((data) => { + if (Array.isArray(data)) { + field.componentProps.config.data = data; + } + field.data.loading = false; + }); + } else { field.data.loading = false; - }); + } } else { field.data.loading = false; } - } else { - field.data.loading = false; - } - }, []); + }, []); - if (!plot || !config) { - return
    {t('In configuration')}...
    ; - } - if (field?.data?.loading !== false) { - return ; - } - return ( -
    - {field.title &&

    {field.title}

    } - -
    - ); -}); + if (!plot || !config) { + return
    {t('In configuration')}...
    ; + } + if (field?.data?.loading !== false) { + return ; + } + return ( +
    + {field.title &&

    {field.title}

    } + +
    + ); + }, + { displayName: 'G2Plot' }, +); G2Plot.Designer = G2PlotDesigner; G2Plot.plots = plots; diff --git a/packages/core/client/src/schema-component/antd/gantt/components/gantt/Event.tsx b/packages/core/client/src/schema-component/antd/gantt/components/gantt/Event.tsx index 73a9f26f6..4550041ba 100644 --- a/packages/core/client/src/schema-component/antd/gantt/components/gantt/Event.tsx +++ b/packages/core/client/src/schema-component/antd/gantt/components/gantt/Event.tsx @@ -1,6 +1,9 @@ import { observer } from '@formily/react'; import React from 'react'; -export const Event = observer((props) => { - return <>{props.children}; -}); +export const Event = observer( + (props) => { + return <>{props.children}; + }, + { displayName: 'Event' }, +); diff --git a/packages/core/client/src/schema-component/antd/grid/Block.tsx b/packages/core/client/src/schema-component/antd/grid/Block.tsx index 210bc4905..410c77a56 100644 --- a/packages/core/client/src/schema-component/antd/grid/Block.tsx +++ b/packages/core/client/src/schema-component/antd/grid/Block.tsx @@ -2,12 +2,15 @@ import { observer, useFieldSchema } from '@formily/react'; import React from 'react'; import { DragHandler } from '../../'; -export const Block = observer((props) => { - const fieldSchema = useFieldSchema(); - return ( -
    - Block {fieldSchema.title} - -
    - ); -}); +export const Block = observer( + (props) => { + const fieldSchema = useFieldSchema(); + return ( +
    + Block {fieldSchema.title} + +
    + ); + }, + { displayName: 'Block' }, +); diff --git a/packages/core/client/src/schema-component/antd/grid/Grid.tsx b/packages/core/client/src/schema-component/antd/grid/Grid.tsx index 049b96ccc..abc4594b4 100644 --- a/packages/core/client/src/schema-component/antd/grid/Grid.tsx +++ b/packages/core/client/src/schema-component/antd/grid/Grid.tsx @@ -330,45 +330,108 @@ export const useGridRowContext = () => { return useContext(GridRowContext); }; -export const Grid: any = observer((props: any) => { - const gridRef = useRef(null); - const field = useField(); - const fieldSchema = useFieldSchema(); - const { render, InitializerComponent } = useSchemaInitializer(fieldSchema['x-initializer']); - const addr = field.address.toString(); - const rows = useRowProperties(); - const { setPrintContent } = useFormBlockContext(); +export const Grid: any = observer( + (props: any) => { + const gridRef = useRef(null); + const field = useField(); + const fieldSchema = useFieldSchema(); + const { render, InitializerComponent } = useSchemaInitializer(fieldSchema['x-initializer']); + const addr = field.address.toString(); + const rows = useRowProperties(); + const { setPrintContent } = useFormBlockContext(); - useEffect(() => { - gridRef.current && setPrintContent?.(gridRef.current); - }, [gridRef.current]); + useEffect(() => { + gridRef.current && setPrintContent?.(gridRef.current); + }, [gridRef.current]); - return ( - -
    - - +
    + + + {rows.map((schema, index) => { + return ( + + + + + ); + })} + + +
    + + ); + }, + { displayName: 'Grid' }, +); + +Grid.Row = observer( + () => { + const field = useField(); + const fieldSchema = useFieldSchema(); + const addr = field.address.toString(); + const cols = useColProperties(); + + return ( + +
    + - {rows.map((schema, index) => { + {cols.map((schema, index) => { return ( - { ); })} - - -
    - - ); -}); +
    + + ); + }, + { displayName: 'Grid.Row' }, +); -Grid.Row = observer(() => { - const field = useField(); - const fieldSchema = useFieldSchema(); - const addr = field.address.toString(); - const cols = useColProperties(); +Grid.Col = observer( + (props: any) => { + const { cols = [] } = useContext(GridRowContext); + const schema = useFieldSchema(); + const field = useField(); - return ( - -
    - - {cols.map((schema, index) => { - return ( - - - - - ); - })} -
    -
    - ); -}); + const width = useMemo(() => { + let width = ''; + if (cols?.length) { + const w = schema?.['x-component-props']?.['width'] || 100 / cols.length; + width = `calc(${w}% - var(--nb-spacing) * ${(cols.length + 1) / cols.length})`; + } + return width; + }, [cols?.length, schema?.['x-component-props']?.['width']]); -Grid.Col = observer((props: any) => { - const { cols = [] } = useContext(GridRowContext); - const schema = useFieldSchema(); - const field = useField(); - - const width = useMemo(() => { - let width = ''; - if (cols?.length) { - const w = schema?.['x-component-props']?.['width'] || 100 / cols.length; - width = `calc(${w}% - var(--nb-spacing) * ${(cols.length + 1) / cols.length})`; - } - return width; - }, [cols?.length, schema?.['x-component-props']?.['width']]); - - const { setNodeRef } = useDroppable({ - id: field.address.toString(), - data: { - insertAdjacent: 'beforeEnd', - schema, - wrapSchema: (s) => s, - }, - }); - return ( - -
    - {props.children} -
    -
    - ); -}); + const { setNodeRef } = useDroppable({ + id: field.address.toString(), + data: { + insertAdjacent: 'beforeEnd', + schema, + wrapSchema: (s) => s, + }, + }); + return ( + +
    + {props.children} +
    +
    + ); + }, + { displayName: 'Grid.Col' }, +); diff --git a/packages/core/client/src/schema-component/antd/grid/demos/demo1.tsx b/packages/core/client/src/schema-component/antd/grid/demos/demo1.tsx index 1fc91654b..9d89b1a48 100644 --- a/packages/core/client/src/schema-component/antd/grid/demos/demo1.tsx +++ b/packages/core/client/src/schema-component/antd/grid/demos/demo1.tsx @@ -2,15 +2,18 @@ import { observer, useFieldSchema } from '@formily/react'; import { BlockItem, DragHandler, Grid, SchemaComponent, SchemaComponentProvider } from '@nocobase/client'; import React from 'react'; -const Block = observer((props) => { - const fieldSchema = useFieldSchema(); - return ( -
    - Block {fieldSchema.title} - -
    - ); -}); +const Block = observer( + (props) => { + const fieldSchema = useFieldSchema(); + return ( +
    + Block {fieldSchema.title} + +
    + ); + }, + { displayName: 'Block' }, +); const schema = { _isJSONSchemaObject: true, diff --git a/packages/core/client/src/schema-component/antd/kanban/Kanban.Card.tsx b/packages/core/client/src/schema-component/antd/kanban/Kanban.Card.tsx index a82183b05..1825ee360 100644 --- a/packages/core/client/src/schema-component/antd/kanban/Kanban.Card.tsx +++ b/packages/core/client/src/schema-component/antd/kanban/Kanban.Card.tsx @@ -10,98 +10,101 @@ import { RecordProvider } from '../../../record-provider'; import { SchemaComponentOptions } from '../../core/SchemaComponentOptions'; import { KanbanCardContext } from './context'; -export const KanbanCard: any = observer((props: any) => { - const { setDisableCardDrag, cardViewerSchema, card, cardField, columnIndex, cardIndex } = - useContext(KanbanCardContext); - const fieldSchema = useFieldSchema(); - const [visible, setVisible] = useState(false); - const labelDisabled = fieldSchema['x-label-disabled']; +export const KanbanCard: any = observer( + (props: any) => { + const { setDisableCardDrag, cardViewerSchema, card, cardField, columnIndex, cardIndex } = + useContext(KanbanCardContext); + const fieldSchema = useFieldSchema(); + const [visible, setVisible] = useState(false); + const labelDisabled = fieldSchema['x-label-disabled']; - return ( - - { - setVisible(true); - }} - bordered={false} - hoverable - style={{ cursor: 'pointer', overflow: 'hidden' }} - // bodyStyle={{ paddingBottom: 0 }} - className={cls( - css` - .ant-card-body { - padding: 16px; - } - .nb-row-divider { - height: 16px; - margin-top: -16px; - &:last-child { - margin-top: 0; + return ( + + { + setVisible(true); + }} + bordered={false} + hoverable + style={{ cursor: 'pointer', overflow: 'hidden' }} + // bodyStyle={{ paddingBottom: 0 }} + className={cls( + css` + .ant-card-body { + padding: 16px; } - } - .ant-description-input { - text-overflow: ellipsis; - width: 100%; - overflow: hidden; - } - .ant-description-textarea { - text-overflow: ellipsis; - width: 100%; - overflow: hidden; - } - .ant-formily-item { - margin-bottom: 12px; - } - .nb-grid-row:last-of-type { - .nb-grid-col { - .nb-form-item:last-of-type { - .ant-formily-item { - margin-bottom: 0; + .nb-row-divider { + height: 16px; + margin-top: -16px; + &:last-child { + margin-top: 0; + } + } + .ant-description-input { + text-overflow: ellipsis; + width: 100%; + overflow: hidden; + } + .ant-description-textarea { + text-overflow: ellipsis; + width: 100%; + overflow: hidden; + } + .ant-formily-item { + margin-bottom: 12px; + } + .nb-grid-row:last-of-type { + .nb-grid-col { + .nb-form-item:last-of-type { + .ant-formily-item { + margin-bottom: 0; + } } } } - } - `, - { - 'kanban-no-label': labelDisabled, - }, + `, + { + 'kanban-no-label': labelDisabled, + }, + )} + > + { + setDisableCardDrag(true); + }} + onDragEnd={() => { + setDisableCardDrag(false); + }} + > + + + + + + {cardViewerSchema && ( + + + + + )} - > - { - setDisableCardDrag(true); - }} - onDragEnd={() => { - setDisableCardDrag(false); - }} - > - - - - - - {cardViewerSchema && ( - - - - - - )} - - ); -}); + + ); + }, + { displayName: 'KanbanCard' }, +); diff --git a/packages/core/client/src/schema-component/antd/kanban/Kanban.CardViewer.tsx b/packages/core/client/src/schema-component/antd/kanban/Kanban.CardViewer.tsx index 788523f6d..99fea76b5 100644 --- a/packages/core/client/src/schema-component/antd/kanban/Kanban.CardViewer.tsx +++ b/packages/core/client/src/schema-component/antd/kanban/Kanban.CardViewer.tsx @@ -1,5 +1,8 @@ import { observer } from '@formily/react'; -export const KanbanCardViewer: any = observer((props: any) => { - return props.children; -}); +export const KanbanCardViewer: any = observer( + (props: any) => { + return props.children; + }, + { displayName: 'KanbanCardViewer' }, +); diff --git a/packages/core/client/src/schema-component/antd/kanban/Kanban.tsx b/packages/core/client/src/schema-component/antd/kanban/Kanban.tsx index b6e128b60..d5a34f2b5 100644 --- a/packages/core/client/src/schema-component/antd/kanban/Kanban.tsx +++ b/packages/core/client/src/schema-component/antd/kanban/Kanban.tsx @@ -55,103 +55,106 @@ export const toColumns = (groupField: any, dataSource: Array = []) => { return Object.values(columns); }; -export const Kanban: any = observer((props: any) => { - const { groupField, onCardDragEnd, ...restProps } = useProps(props); - const field = useField(); - const fieldSchema = useFieldSchema(); - const [disableCardDrag, setDisableCardDrag] = useState(false); - const schemas = useMemo( - () => - fieldSchema.reduceProperties( - (buf, current) => { - if (current['x-component'].endsWith('.Card')) { - buf.card = current; - } else if (current['x-component'].endsWith('.CardAdder')) { - buf.cardAdder = current; - } else if (current['x-component'].endsWith('.CardViewer')) { - buf.cardViewer = current; - } - return buf; - }, - { card: null, cardAdder: null, cardViewer: null }, - ), - [], - ); - const handleCardRemove = (card, column) => { - const updatedBoard = Board.removeCard({ columns: field.value }, column, card); - field.value = updatedBoard.columns; - }; - const handleCardDragEnd = (card, fromColumn, toColumn) => { - onCardDragEnd?.({ columns: field.value, groupField }, fromColumn, toColumn); - const updatedBoard = Board.moveCard({ columns: field.value }, fromColumn, toColumn); - field.value = updatedBoard.columns; - }; +export const Kanban: any = observer( + (props: any) => { + const { groupField, onCardDragEnd, ...restProps } = useProps(props); + const field = useField(); + const fieldSchema = useFieldSchema(); + const [disableCardDrag, setDisableCardDrag] = useState(false); + const schemas = useMemo( + () => + fieldSchema.reduceProperties( + (buf, current) => { + if (current['x-component'].endsWith('.Card')) { + buf.card = current; + } else if (current['x-component'].endsWith('.CardAdder')) { + buf.cardAdder = current; + } else if (current['x-component'].endsWith('.CardViewer')) { + buf.cardViewer = current; + } + return buf; + }, + { card: null, cardAdder: null, cardViewer: null }, + ), + [], + ); + const handleCardRemove = (card, column) => { + const updatedBoard = Board.removeCard({ columns: field.value }, column, card); + field.value = updatedBoard.columns; + }; + const handleCardDragEnd = (card, fromColumn, toColumn) => { + onCardDragEnd?.({ columns: field.value, groupField }, fromColumn, toColumn); + const updatedBoard = Board.moveCard({ columns: field.value }, fromColumn, toColumn); + field.value = updatedBoard.columns; + }; - return ( - .ant-spin-container { + return ( + - ( -
    - {title} -
    - )} - renderCard={(card, { column, dragging }) => { - const columnIndex = field.value?.indexOf(column); - const cardIndex = column?.cards?.indexOf(card); - return ( - schemas.card && ( - - - - - - ) - ); - }} - renderCardAdder={({ column }) => { - if (!schemas.cardAdder) { - return null; + > .ant-spin-container { + height: 100%; } - return ( - - - - - - ); - }} + `} + spinning={field.loading || false} > - {{ - columns: field.value || [], - }} -
    -
    - ); -}); + ( +
    + {title} +
    + )} + renderCard={(card, { column, dragging }) => { + const columnIndex = field.value?.indexOf(column); + const cardIndex = column?.cards?.indexOf(card); + return ( + schemas.card && ( + + + + + + ) + ); + }} + renderCardAdder={({ column }) => { + if (!schemas.cardAdder) { + return null; + } + return ( + + + + + + ); + }} + > + {{ + columns: field.value || [], + }} +
    +
    + ); + }, + { displayName: 'Kanban' }, +); diff --git a/packages/core/client/src/schema-component/antd/markdown/Markdown.Void.tsx b/packages/core/client/src/schema-component/antd/markdown/Markdown.Void.tsx index 0ce24b232..04a827ba6 100644 --- a/packages/core/client/src/schema-component/antd/markdown/Markdown.Void.tsx +++ b/packages/core/client/src/schema-component/antd/markdown/Markdown.Void.tsx @@ -41,44 +41,47 @@ const MarkdownEditor = (props: any) => { ); }; -export const MarkdownVoid: any = observer((props: any) => { - const { content, className } = props; - const field = useField(); - const schema = useFieldSchema(); - const { dn } = useDesignable(); - const { onSave, onCancel } = props; - const { html, loading } = useParseMarkdown(content); - if (loading) { - return ; - } - return field?.editable ? ( - { - field.editable = false; - onCancel?.(); - }} - onSubmit={async (value) => { - field.editable = false; - schema['x-component-props'] ?? (schema['x-component-props'] = {}); - schema['x-component-props']['content'] = value; - field.componentProps.content = value; - onSave?.(schema); - dn.emit('patch', { - schema: { - 'x-uid': schema['x-uid'], - 'x-component-props': { - content: value, +export const MarkdownVoid: any = observer( + (props: any) => { + const { content, className } = props; + const field = useField(); + const schema = useFieldSchema(); + const { dn } = useDesignable(); + const { onSave, onCancel } = props; + const { html, loading } = useParseMarkdown(content); + if (loading) { + return ; + } + return field?.editable ? ( + { + field.editable = false; + onCancel?.(); + }} + onSubmit={async (value) => { + field.editable = false; + schema['x-component-props'] ?? (schema['x-component-props'] = {}); + schema['x-component-props']['content'] = value; + field.componentProps.content = value; + onSave?.(schema); + dn.emit('patch', { + schema: { + 'x-uid': schema['x-uid'], + 'x-component-props': { + content: value, + }, }, - }, - }); - }} - /> - ) : ( -
    - ); -}); + }); + }} + /> + ) : ( +
    + ); + }, + { displayName: 'MarkdownVoid' }, +); MarkdownVoid.Designer = MarkdownVoidDesigner; diff --git a/packages/core/client/src/schema-component/antd/markdown/demos/demo2.tsx b/packages/core/client/src/schema-component/antd/markdown/demos/demo2.tsx index fc7eccc78..c22c007d1 100644 --- a/packages/core/client/src/schema-component/antd/markdown/demos/demo2.tsx +++ b/packages/core/client/src/schema-component/antd/markdown/demos/demo2.tsx @@ -23,24 +23,27 @@ const schema = { }, }; -const Editable = observer((props: any) => { - const filed = useField(); - if (filed.editable) { - return props.children; - } - return ( -
    - -
    {props.children}
    -
    - ); -}); +const Editable = observer( + (props: any) => { + const filed = useField(); + if (filed.editable) { + return props.children; + } + return ( +
    + +
    {props.children}
    +
    + ); + }, + { displayName: 'Editable' }, +); export default () => { return ( diff --git a/packages/core/client/src/schema-component/antd/menu/Menu.tsx b/packages/core/client/src/schema-component/antd/menu/Menu.tsx index f0c46d3c5..a2a0a6e32 100644 --- a/packages/core/client/src/schema-component/antd/menu/Menu.tsx +++ b/packages/core/client/src/schema-component/antd/menu/Menu.tsx @@ -136,148 +136,149 @@ const useSideMenuRef = () => { const MenuItemDesignerContext = createContext(null); -export const Menu: ComposedMenu = observer((props) => { - const { - onSelect, - mode, - selectedUid, - defaultSelectedUid, - sideMenuRefScopeKey, - defaultSelectedKeys: dSelectedKeys, - defaultOpenKeys: dOpenKeys, - ...others - } = useProps(props); - const { t } = useTranslation(); - const Designer = useDesigner(); - const schema = useFieldSchema(); - const { refresh } = useDesignable(); - const api = useAPIClient(); - const { render } = useSchemaInitializer(schema['x-initializer']); - const sideMenuRef = useSideMenuRef(); - const [defaultSelectedKeys, setDefaultSelectedKeys] = useState(() => { - if (dSelectedKeys) { - return dSelectedKeys; - } - if (defaultSelectedUid) { - return findKeysByUid(schema, defaultSelectedUid); - } - return []; - }); - const [loading, setLoading] = useState(false); - const [defaultOpenKeys, setDefaultOpenKeys] = useState(() => { - if (['inline', 'mix'].includes(mode)) { - return dOpenKeys || defaultSelectedKeys; - } - return dOpenKeys; - }); - const [sideMenuSchema, setSideMenuSchema] = useState(() => { - const key = defaultSelectedKeys?.[0] || null; - if (mode === 'mix' && key) { - const s = schema.properties?.[key]; - if (s['x-component'] === 'Menu.SubMenu') { - return s; +export const Menu: ComposedMenu = observer( + (props) => { + const { + onSelect, + mode, + selectedUid, + defaultSelectedUid, + sideMenuRefScopeKey, + defaultSelectedKeys: dSelectedKeys, + defaultOpenKeys: dOpenKeys, + ...others + } = useProps(props); + const { t } = useTranslation(); + const Designer = useDesigner(); + const schema = useFieldSchema(); + const { refresh } = useDesignable(); + const api = useAPIClient(); + const { render } = useSchemaInitializer(schema['x-initializer']); + const sideMenuRef = useSideMenuRef(); + const [defaultSelectedKeys, setDefaultSelectedKeys] = useState(() => { + if (dSelectedKeys) { + return dSelectedKeys; } - } - return null; - }); - useEffect(() => { - const keys = findKeysByUid(schema, selectedUid); - setDefaultSelectedKeys(keys); - if (['inline', 'mix'].includes(mode)) { - setDefaultOpenKeys(dOpenKeys || keys); - } - const key = keys?.[0] || null; - if (mode === 'mix') { - if (key) { + if (defaultSelectedUid) { + return findKeysByUid(schema, defaultSelectedUid); + } + return []; + }); + const [loading, setLoading] = useState(false); + const [defaultOpenKeys, setDefaultOpenKeys] = useState(() => { + if (['inline', 'mix'].includes(mode)) { + return dOpenKeys || defaultSelectedKeys; + } + return dOpenKeys; + }); + const [sideMenuSchema, setSideMenuSchema] = useState(() => { + const key = defaultSelectedKeys?.[0] || null; + if (mode === 'mix' && key) { const s = schema.properties?.[key]; if (s['x-component'] === 'Menu.SubMenu') { - setSideMenuSchema(s); + return s; } - } else { - setSideMenuSchema(null); } - } - }, [selectedUid]); - useEffect(() => { - if (['inline', 'mix'].includes(mode)) { - setDefaultOpenKeys(defaultSelectedKeys); - } - }, [defaultSelectedKeys]); - useEffect(() => { - const sideMenuElement = sideMenuRef?.current as HTMLElement; - if (!sideMenuElement) { - return; - } - sideMenuElement.style.display = sideMenuSchema?.['x-component'] === 'Menu.SubMenu' ? 'block' : 'none'; - }, [sideMenuSchema?.name, sideMenuRef]); - const { designable } = useDesignable(); - return ( - - - - .ant-menu-title-content > div { - .general-schema-designer { - display: block; - } + return null; + }); + useEffect(() => { + const keys = findKeysByUid(schema, selectedUid); + setDefaultSelectedKeys(keys); + if (['inline', 'mix'].includes(mode)) { + setDefaultOpenKeys(dOpenKeys || keys); + } + const key = keys?.[0] || null; + if (mode === 'mix') { + if (key) { + const s = schema.properties?.[key]; + if (s['x-component'] === 'Menu.SubMenu') { + setSideMenuSchema(s); + } + } else { + setSideMenuSchema(null); + } + } + }, [selectedUid]); + useEffect(() => { + if (['inline', 'mix'].includes(mode)) { + setDefaultOpenKeys(defaultSelectedKeys); + } + }, [defaultSelectedKeys]); + useEffect(() => { + const sideMenuElement = sideMenuRef?.current as HTMLElement; + if (!sideMenuElement) { + return; + } + sideMenuElement.style.display = sideMenuSchema?.['x-component'] === 'Menu.SubMenu' ? 'block' : 'none'; + }, [sideMenuSchema?.name, sideMenuRef]); + const { designable } = useDesignable(); + return ( + + + + { - const s = schema.properties[info.key]; - if (mode === 'mix') { - setSideMenuSchema(s); - if (s['x-component'] !== 'Menu.SubMenu') { - onSelect && onSelect(info); - } else { - const menuItemSchema = findMenuItem(s); - if (!menuItemSchema) { - return; + className={css` + .ant-menu-item:hover { + > .ant-menu-title-content > div { + .general-schema-designer { + display: block; + } } - // TODO - setLoading(true); - const keys = findKeysByUid(schema, menuItemSchema['x-uid']); - setDefaultSelectedKeys(keys); - setTimeout(() => { - setLoading(false); - }, 100); - onSelect && - onSelect({ - key: menuItemSchema.name, - item: { - props: { - schema: menuItemSchema, + } + `} + onSelect={(info: any) => { + const s = schema.properties[info.key]; + if (mode === 'mix') { + setSideMenuSchema(s); + if (s['x-component'] !== 'Menu.SubMenu') { + onSelect && onSelect(info); + } else { + const menuItemSchema = findMenuItem(s); + if (!menuItemSchema) { + return; + } + // TODO + setLoading(true); + const keys = findKeysByUid(schema, menuItemSchema['x-uid']); + setDefaultSelectedKeys(keys); + setTimeout(() => { + setLoading(false); + }, 100); + onSelect && + onSelect({ + key: menuItemSchema.name, + item: { + props: { + schema: menuItemSchema, + }, }, - }, - }); + }); + } + } else { + onSelect && onSelect(info); } - } else { - onSelect && onSelect(info); - } - }} - mode={mode === 'mix' ? 'horizontal' : mode} - defaultOpenKeys={defaultOpenKeys} - defaultSelectedKeys={defaultSelectedKeys} - selectedKeys={defaultSelectedKeys} - > - {designable && ( - - {render({ style: { background: 'none' } })} - - )} - {props.children} - - {loading - ? null - : mode === 'mix' && + }} + mode={mode === 'mix' ? 'horizontal' : mode} + defaultOpenKeys={defaultOpenKeys} + defaultSelectedKeys={defaultSelectedKeys} + selectedKeys={defaultSelectedKeys} + > + {designable && ( + + {render({ style: { background: 'none' } })} + + )} + {props.children} + + {loading + ? null + : mode === 'mix' && sideMenuSchema?.['x-component'] === 'Menu.SubMenu' && sideMenuRef?.current?.firstChild && createPortal( @@ -290,37 +291,37 @@ export const Menu: ComposedMenu = observer((props) => { onSelect && onSelect(info); }} className={css` - height: 100%; - overflow-y: auto; - overflow-x: hidden; - .ant-menu-item { - > .ant-menu-title-content { - margin-left: -24px; - margin-right: -16px; - padding: 0 16px 0 24px; - > div { - > .general-schema-designer { - right: 6px !important; + height: 100%; + overflow-y: auto; + overflow-x: hidden; + .ant-menu-item { + > .ant-menu-title-content { + margin-left: -24px; + margin-right: -16px; + padding: 0 16px 0 24px; + > div { + > .general-schema-designer { + right: 6px !important; + } } } } - } - .ant-menu-submenu-title { - .ant-menu-title-content { - margin-left: -24px; - margin-right: -34px; - padding: 0 34px 0 24px; - > div { - > .general-schema-designer { - right: 6px !important; - } - > span.anticon { - margin-right: 10px; + .ant-menu-submenu-title { + .ant-menu-title-content { + margin-left: -24px; + margin-right: -34px; + padding: 0 34px 0 24px; + > div { + > .general-schema-designer { + right: 6px !important; + } + > span.anticon { + margin-right: 10px; + } } } } - } - `} + `} > {render({ @@ -340,117 +341,128 @@ export const Menu: ComposedMenu = observer((props) => { , sideMenuRef.current.firstChild, )} - - - - ); -}); + + + + ); + }, + { displayName: 'Menu' }, +); -Menu.Item = observer((props) => { - const { icon, ...others } = props; - const schema = useFieldSchema(); - const field = useField(); - const Designer = useContext(MenuItemDesignerContext); - return ( - - - - - {field.title} - - - - - ); -}); - -Menu.URL = observer((props) => { - const { icon, ...others } = props; - const schema = useFieldSchema(); - const field = useField(); - const Designer = useContext(MenuItemDesignerContext); - return ( - { - window.open(props.href, '_blank'); - }} - > - - - - {field.title} - - - - - ); -}); - -Menu.SubMenu = observer((props) => { - const { icon, ...others } = props; - const schema = useFieldSchema(); - const field = useField(); - const mode = useContext(MenuModeContext); - const Designer = useContext(MenuItemDesignerContext); - if (mode === 'mix') { - return ; - } - return ( - +Menu.Item = observer( + (props) => { + const { icon, ...others } = props; + const schema = useFieldSchema(); + const field = useField(); + const Designer = useContext(MenuItemDesignerContext); + return ( + + - {field.title} + + {field.title} + - } - > - - - ); -}); + + ); + }, + { displayName: 'MenuItem' }, +); + +Menu.URL = observer( + (props) => { + const { icon, ...others } = props; + const schema = useFieldSchema(); + const field = useField(); + const Designer = useContext(MenuItemDesignerContext); + return ( + { + window.open(props.href, '_blank'); + }} + > + + + + {field.title} + + + + + ); + }, + { displayName: 'MenuURL' }, +); + +Menu.SubMenu = observer( + (props) => { + const { icon, ...others } = props; + const schema = useFieldSchema(); + const field = useField(); + const mode = useContext(MenuModeContext); + const Designer = useContext(MenuItemDesignerContext); + if (mode === 'mix') { + return ; + } + return ( + + + {field.title} + + + } + > + + + ); + }, + { displayName: 'MenuSubMenu' }, +); Menu.Designer = MenuDesigner; diff --git a/packages/core/client/src/schema-component/antd/pagination/index.tsx b/packages/core/client/src/schema-component/antd/pagination/index.tsx index e0e5c6e76..c58fd8a8a 100644 --- a/packages/core/client/src/schema-component/antd/pagination/index.tsx +++ b/packages/core/client/src/schema-component/antd/pagination/index.tsx @@ -3,20 +3,23 @@ import { Pagination as AntdPagination } from 'antd'; import React, { KeyboardEventHandler } from 'react'; import { useProps } from '../../hooks/useProps'; -export const Pagination = observer((props: any) => { - const { hidden, ...others } = useProps(props); - if (hidden) { - return null; - } - const onKeypress: KeyboardEventHandler = (e) => { - if (e.key === 'Enter') { - e.preventDefault(); +export const Pagination = observer( + (props: any) => { + const { hidden, ...others } = useProps(props); + if (hidden) { + return null; } - }; + const onKeypress: KeyboardEventHandler = (e) => { + if (e.key === 'Enter') { + e.preventDefault(); + } + }; - return ( -
    - -
    - ); -}); + return ( +
    + +
    + ); + }, + { displayName: 'Pagination' }, +); diff --git a/packages/core/client/src/schema-component/antd/record-picker/ReadPrettyRecordPicker.tsx b/packages/core/client/src/schema-component/antd/record-picker/ReadPrettyRecordPicker.tsx index 7f8e69524..c7fe6ee7e 100644 --- a/packages/core/client/src/schema-component/antd/record-picker/ReadPrettyRecordPicker.tsx +++ b/packages/core/client/src/schema-component/antd/record-picker/ReadPrettyRecordPicker.tsx @@ -25,98 +25,101 @@ const toValue = (value, placeholder) => { return value; }; -export const ReadPrettyRecordPicker: React.FC = observer((props: any) => { - const { ellipsis } = props; - const fieldSchema = useFieldSchema(); - const recordCtx = useRecord(); - const { getCollectionJoinField } = useCollectionManager(); - // value 做了转换,但 props.value 和原来 useField().value 的值不一致 - // const field = useField(); - const fieldNames = useFieldNames(props); - const [visible, setVisible] = useState(false); - const { getField } = useCollection(); - const collectionField = getField(fieldSchema.name) || getCollectionJoinField(fieldSchema?.['x-collection-field']); - const [record, setRecord] = useState({}); - const compile = useCompile(); - const labelUiSchema = useLabelUiSchema(collectionField, fieldNames?.label || 'label'); - const showFilePicker = isShowFilePicker(labelUiSchema); - const { snapshot } = useActionContext(); - const isTagsMode = fieldSchema['x-component-props']?.mode === 'tags'; +export const ReadPrettyRecordPicker: React.FC = observer( + (props: any) => { + const { ellipsis } = props; + const fieldSchema = useFieldSchema(); + const recordCtx = useRecord(); + const { getCollectionJoinField } = useCollectionManager(); + // value 做了转换,但 props.value 和原来 useField().value 的值不一致 + // const field = useField(); + const fieldNames = useFieldNames(props); + const [visible, setVisible] = useState(false); + const { getField } = useCollection(); + const collectionField = getField(fieldSchema.name) || getCollectionJoinField(fieldSchema?.['x-collection-field']); + const [record, setRecord] = useState({}); + const compile = useCompile(); + const labelUiSchema = useLabelUiSchema(collectionField, fieldNames?.label || 'label'); + const showFilePicker = isShowFilePicker(labelUiSchema); + const { snapshot } = useActionContext(); + const isTagsMode = fieldSchema['x-component-props']?.mode === 'tags'; - const ellipsisWithTooltipRef = useRef(); + const ellipsisWithTooltipRef = useRef(); - if (showFilePicker) { - return collectionField ? : null; - } + if (showFilePicker) { + return collectionField ? : null; + } - const renderRecords = () => - toArr(props.value).map((record, index, arr) => { - const val = toValue(compile(record?.[fieldNames?.label || 'label']), 'N/A'); - const text = getLabelFormatValue(labelUiSchema, val, true); - return ( - - - {snapshot || isTagsMode ? ( - text - ) : ( - { - e.stopPropagation(); - e.preventDefault(); - setVisible(true); - setRecord(record); - ellipsisWithTooltipRef?.current?.setPopoverVisible(false); - }} - > - {text} - - )} - - {index < arr.length - 1 ? , : null} - - ); - }); + const renderRecords = () => + toArr(props.value).map((record, index, arr) => { + const val = toValue(compile(record?.[fieldNames?.label || 'label']), 'N/A'); + const text = getLabelFormatValue(labelUiSchema, val, true); + return ( + + + {snapshot || isTagsMode ? ( + text + ) : ( + { + e.stopPropagation(); + e.preventDefault(); + setVisible(true); + setRecord(record); + ellipsisWithTooltipRef?.current?.setPopoverVisible(false); + }} + > + {text} + + )} + + {index < arr.length - 1 ? , : null} + + ); + }); - const renderWithoutTableFieldResourceProvider = () => ( - - - { - return s['x-component'] === 'RecordPicker.Viewer'; - }} - /> - - - ); - - const renderRecordProvider = () => { - const collectionFieldNames = fieldSchema?.['x-collection-field']?.split('.'); - - return collectionFieldNames && collectionFieldNames.length > 2 ? ( - - {renderWithoutTableFieldResourceProvider()} - - ) : ( - {renderWithoutTableFieldResourceProvider()} + const renderWithoutTableFieldResourceProvider = () => ( + + + { + return s['x-component'] === 'RecordPicker.Viewer'; + }} + /> + + ); - }; - return collectionField ? ( -
    - - - - {renderRecords()} - - - {renderRecordProvider()} - - - -
    - ) : null; -}); + const renderRecordProvider = () => { + const collectionFieldNames = fieldSchema?.['x-collection-field']?.split('.'); + + return collectionFieldNames && collectionFieldNames.length > 2 ? ( + + {renderWithoutTableFieldResourceProvider()} + + ) : ( + {renderWithoutTableFieldResourceProvider()} + ); + }; + + return collectionField ? ( +
    + + + + {renderRecords()} + + + {renderRecordProvider()} + + + +
    + ) : null; + }, + { displayName: 'ReadPrettyRecordPicker' }, +); diff --git a/packages/core/client/src/schema-component/antd/remote-select/ReadPretty.tsx b/packages/core/client/src/schema-component/antd/remote-select/ReadPretty.tsx index 1452597b6..59ffeb0a7 100644 --- a/packages/core/client/src/schema-component/antd/remote-select/ReadPretty.tsx +++ b/packages/core/client/src/schema-component/antd/remote-select/ReadPretty.tsx @@ -6,19 +6,20 @@ import { useRequest } from '../../../api-client'; import { useRecord } from '../../../record-provider'; import { useActionContext } from '../action'; -export const ReadPretty = observer((props: any) => { - const fieldNames = { ...defaultFieldNames, ...props.fieldNames }; - const field = useField(); - const fieldSchema = useFieldSchema(); - const record = useRecord(); - const { snapshot } = useActionContext(); +export const ReadPretty = observer( + (props: any) => { + const fieldNames = { ...defaultFieldNames, ...props.fieldNames }; + const field = useField(); + const fieldSchema = useFieldSchema(); + const record = useRecord(); + const { snapshot } = useActionContext(); - const { data } = useRequest( - snapshot - ? async () => ({ + const { data } = useRequest( + snapshot + ? async () => ({ data: record[fieldSchema.name], }) - : { + : { action: 'list', ...props.service, params: { @@ -30,10 +31,12 @@ export const ReadPretty = observer((props: any) => { }, }, }, - { - refreshDeps: [props.service, field.value], - }, - ); + { + refreshDeps: [props.service, field.value], + }, + ); - return ; -}); + return ; + }, + { displayName: 'ReadPretty' }, +); diff --git a/packages/core/client/src/schema-component/antd/select/ReadPretty.tsx b/packages/core/client/src/schema-component/antd/select/ReadPretty.tsx index bc671620a..61a108016 100644 --- a/packages/core/client/src/schema-component/antd/select/ReadPretty.tsx +++ b/packages/core/client/src/schema-component/antd/select/ReadPretty.tsx @@ -12,29 +12,32 @@ type Composed = { Object?: React.FC; }; -export const ReadPretty = observer((props: any) => { - const fieldNames = { ...defaultFieldNames, ...props.fieldNames }; - const field = useField(); - const compile = useCompile(); +export const ReadPretty = observer( + (props: any) => { + const fieldNames = { ...defaultFieldNames, ...props.fieldNames }; + const field = useField(); + const compile = useCompile(); - if (!isValid(props.value)) { - return
    ; - } - if (isArrayField(field) && field?.value?.length === 0) { - return
    ; - } - const dataSource = field.dataSource || props.options || []; - const options = getCurrentOptions(field.value, dataSource, fieldNames); + if (!isValid(props.value)) { + return
    ; + } + if (isArrayField(field) && field?.value?.length === 0) { + return
    ; + } + const dataSource = field.dataSource || props.options || []; + const options = getCurrentOptions(field.value, dataSource, fieldNames); - return ( -
    - - {options.map((option, key) => ( - - {compile(option[fieldNames.label])} - - ))} - -
    - ); -}); + return ( +
    + + {options.map((option, key) => ( + + {compile(option[fieldNames.label])} + + ))} + +
    + ); + }, + { displayName: 'ReadPretty' }, +); diff --git a/packages/core/client/src/schema-component/antd/table-v2/Table.Column.ActionBar.tsx b/packages/core/client/src/schema-component/antd/table-v2/Table.Column.ActionBar.tsx index 4974970dd..2fd39d633 100644 --- a/packages/core/client/src/schema-component/antd/table-v2/Table.Column.ActionBar.tsx +++ b/packages/core/client/src/schema-component/antd/table-v2/Table.Column.ActionBar.tsx @@ -42,12 +42,15 @@ export const designerCss = css` } `; -export const TableColumnActionBar = observer((props) => { - const Designer = useDesigner(); - return ( - - - {props.children} - - ); -}); +export const TableColumnActionBar = observer( + (props) => { + const Designer = useDesigner(); + return ( + + + {props.children} + + ); + }, + { displayName: 'TableColumnActionBar' }, +); diff --git a/packages/core/client/src/schema-component/antd/table-v2/Table.tsx b/packages/core/client/src/schema-component/antd/table-v2/Table.tsx index 2ea360e4b..af5ab82f7 100644 --- a/packages/core/client/src/schema-component/antd/table-v2/Table.tsx +++ b/packages/core/client/src/schema-component/antd/table-v2/Table.tsx @@ -163,164 +163,165 @@ const useValidator = (validator: (value: any) => string) => { }, []); }; -export const Table: any = observer((props: any) => { - const { pagination: pagination1, useProps, onChange, ...others1 } = props; - const { pagination: pagination2, onClickRow, ...others2 } = useProps?.() || {}; - const { - dragSort = false, - showIndex = true, - onRowSelectionChange, - onChange: onTableChange, - rowSelection, - rowKey, - required, - onExpand, - ...others - } = { ...others1, ...others2 } as any; - const field = useArrayField(others); - const columns = useTableColumns(others); - const schema = useFieldSchema(); - const isTableSelector = schema?.parent?.['x-decorator'] === 'TableSelectorProvider'; - const ctx = isTableSelector ? useTableSelectorContext() : useTableBlockContext(); - const { expandFlag } = ctx; - const onRowDragEnd = useMemoizedFn(others.onRowDragEnd || (() => {})); - const paginationProps = usePaginationProps(pagination1, pagination2); - const requiredValidator = field.required || required; - const { treeTable } = schema?.parent?.['x-decorator-props'] || {}; - const [expandedKeys, setExpandesKeys] = useState([]); - const [allIncludesChildren, setAllIncludesChildren] = useState([]); - const [selectedRowKeys, setSelectedRowKeys] = useState(field?.data?.selectedRowKeys || []); - const [selectedRow, setSelectedRow] = useState([]); +export const Table: any = observer( + (props: any) => { + const { pagination: pagination1, useProps, onChange, ...others1 } = props; + const { pagination: pagination2, onClickRow, ...others2 } = useProps?.() || {}; + const { + dragSort = false, + showIndex = true, + onRowSelectionChange, + onChange: onTableChange, + rowSelection, + rowKey, + required, + onExpand, + ...others + } = { ...others1, ...others2 } as any; + const field = useArrayField(others); + const columns = useTableColumns(others); + const schema = useFieldSchema(); + const isTableSelector = schema?.parent?.['x-decorator'] === 'TableSelectorProvider'; + const ctx = isTableSelector ? useTableSelectorContext() : useTableBlockContext(); + const { expandFlag } = ctx; + const onRowDragEnd = useMemoizedFn(others.onRowDragEnd || (() => { })); + const paginationProps = usePaginationProps(pagination1, pagination2); + const requiredValidator = field.required || required; + const { treeTable } = schema?.parent?.['x-decorator-props'] || {}; + const [expandedKeys, setExpandesKeys] = useState([]); + const [allIncludesChildren, setAllIncludesChildren] = useState([]); + const [selectedRowKeys, setSelectedRowKeys] = useState(field?.data?.selectedRowKeys || []); + const [selectedRow, setSelectedRow] = useState([]); - let onRow = null, - highlightRow = ''; + let onRow = null, + highlightRow = ''; - if (onClickRow) { - onRow = (record) => { - return { - onClick: () => onClickRow(record, setSelectedRow, selectedRow), + if (onClickRow) { + onRow = (record) => { + return { + onClick: () => onClickRow(record, setSelectedRow, selectedRow), + }; }; - }; - highlightRow = css` - & > td { - background-color: #caedff !important; - } - &:hover > td { - background-color: #caedff !important; - } - `; - } - - useEffect(() => { - field.setValidator((value) => { - if (requiredValidator) { - return Array.isArray(value) && value.length > 0 ? null : 'The field value is required'; - } - return; - }); - }, [requiredValidator]); - - useEffect(() => { - if (treeTable !== false) { - const keys = getIdsWithChildren(field.value?.slice?.()); - setAllIncludesChildren(keys); + highlightRow = css` + & > td { + background-color: #caedff !important; + } + &:hover > td { + background-color: #caedff !important; + } + `; } - }, [field.value]); - useEffect(() => { - if (expandFlag) { - setExpandesKeys(allIncludesChildren); - } else { - setExpandesKeys([]); - } - }, [expandFlag, allIncludesChildren]); - const components = useMemo(() => { - return { - header: { - wrapper: (props) => { - return ( - -
    - - ); + useEffect(() => { + field.setValidator((value) => { + if (requiredValidator) { + return Array.isArray(value) && value.length > 0 ? null : 'The field value is required'; + } + return; + }); + }, [requiredValidator]); + + useEffect(() => { + if (treeTable !== false) { + const keys = getIdsWithChildren(field.value?.slice?.()); + setAllIncludesChildren(keys); + } + }, [field.value]); + useEffect(() => { + if (expandFlag) { + setExpandesKeys(allIncludesChildren); + } else { + setExpandesKeys([]); + } + }, [expandFlag, allIncludesChildren]); + + const components = useMemo(() => { + return { + header: { + wrapper: (props) => { + return ( + + + + ); + }, + cell: (props) => { + return ( + + + ); + }, + row: (props) => { + return ; + }, + cell: (props) => ( + - - ); - }, - row: (props) => { - return ; - }, - cell: (props) => ( -
    + ); + }, }, - cell: (props) => { - return ( - { + return ( + { + if (!e.active || !e.over) { + console.warn('move cancel'); + return; + } + + const fromIndex = e.active?.data.current?.sortable?.index; + const toIndex = e.over?.data.current?.sortable?.index; + const from = field.value[fromIndex]; + const to = field.value[toIndex]; + field.move(fromIndex, toIndex); + onRowDragEnd({ fromIndex, toIndex, from, to }); + }} + > +
    - ); + ), }, - }, - body: { - wrapper: (props) => { - return ( - { - if (!e.active || !e.over) { - console.warn('move cancel'); - return; - } + }; + }, [field, onRowDragEnd, dragSort]); - const fromIndex = e.active?.data.current?.sortable?.index; - const toIndex = e.over?.data.current?.sortable?.index; - const from = field.value[fromIndex]; - const to = field.value[toIndex]; - field.move(fromIndex, toIndex); - onRowDragEnd({ fromIndex, toIndex, from, to }); - }} - > -
    - ), - }, + const defaultRowKey = (record: any) => { + return field.value?.indexOf?.(record); }; - }, [field, onRowDragEnd, dragSort]); - const defaultRowKey = (record: any) => { - return field.value?.indexOf?.(record); - }; + const getRowKey = (record: any) => { + if (typeof rowKey === 'string') { + return record[rowKey]?.toString(); + } else { + return (rowKey ?? defaultRowKey)(record)?.toString(); + } + }; - const getRowKey = (record: any) => { - if (typeof rowKey === 'string') { - return record[rowKey]?.toString(); - } else { - return (rowKey ?? defaultRowKey)(record)?.toString(); - } - }; - - const restProps = { - rowSelection: rowSelection - ? { + const restProps = { + rowSelection: rowSelection + ? { type: 'checkbox', selectedRowKeys: selectedRowKeys, onChange(selectedRowKeys: any[], selectedRows: any[]) { @@ -348,40 +349,40 @@ export const Table: any = observer((props: any) => { className={classNames( checked ? 'checked' : null, css` - position: relative; - display: flex; - float: left; - align-items: center; - justify-content: space-evenly; - padding-right: 8px; - .nb-table-index { - opacity: 0; - } - &:not(.checked) { - .nb-table-index { - opacity: 1; - } - } - &:hover { + position: relative; + display: flex; + float: left; + align-items: center; + justify-content: space-evenly; + padding-right: 8px; .nb-table-index { opacity: 0; } - .nb-origin-node { - display: block; + &:not(.checked) { + .nb-table-index { + opacity: 1; + } } - } - `, + &:hover { + .nb-table-index { + opacity: 0; + } + .nb-origin-node { + display: block; + } + } + `, )} >
    {dragSort && } @@ -392,13 +393,13 @@ export const Table: any = observer((props: any) => { 'nb-origin-node', checked ? 'checked' : null, css` - position: absolute; - right: 50%; - transform: translateX(50%); - &:not(.checked) { - display: none; - } - `, + position: absolute; + right: 50%; + transform: translateX(50%); + &:not(.checked) { + display: none; + } + `, )} > {originNode} @@ -408,94 +409,96 @@ export const Table: any = observer((props: any) => { }, ...rowSelection, } - : undefined, - }; + : undefined, + }; - const SortableWrapper = useCallback( - ({ children }) => { - return dragSort - ? React.createElement(SortableContext, { + const SortableWrapper = useCallback( + ({ children }) => { + return dragSort + ? React.createElement(SortableContext, { items: field.value.map(getRowKey), children: children, }) - : React.createElement(React.Fragment, { + : React.createElement(React.Fragment, { children, }); - }, - [field, dragSort], - ); - const fieldSchema = useFieldSchema(); - const fixedBlock = fieldSchema?.parent?.['x-decorator-props']?.fixedBlock; + }, + [field, dragSort], + ); + const fieldSchema = useFieldSchema(); + const fixedBlock = fieldSchema?.parent?.['x-decorator-props']?.fixedBlock; - const { height: tableHeight, tableSizeRefCallback } = useTableSize(); + const { height: tableHeight, tableSizeRefCallback } = useTableSize(); - const scroll = useMemo(() => { - return fixedBlock - ? { + const scroll = useMemo(() => { + return fixedBlock + ? { x: 'max-content', y: tableHeight, } - : { + : { x: 'max-content', }; - }, [fixedBlock, tableHeight]); + }, [fixedBlock, tableHeight]); - return ( -
    - - { - onTableChange?.(pagination, filters, sorter, extra); - }} - onRow={onRow} - rowClassName={(record) => (selectedRow.includes(record[rowKey]) ? highlightRow : '')} - tableLayout={'auto'} - scroll={scroll} - columns={columns} - expandable={{ - onExpand: (flag, record) => { - const newKeys = flag ? [...expandedKeys, record.id] : expandedKeys.filter((i) => record.id !== i); - setExpandesKeys(newKeys); - onExpand?.(flag, record); - }, - expandedRowKeys: expandedKeys, - }} - /> - - {field.errors.length > 0 && ( -
    - {field.errors.map((error) => { - return error.messages.map((message) =>
    {message}
    ); - })} -
    - )} -
    - ); -}); + .ant-table { + overflow-x: auto; + overflow-y: hidden; + } + `} + > + + { + onTableChange?.(pagination, filters, sorter, extra); + }} + onRow={onRow} + rowClassName={(record) => (selectedRow.includes(record[rowKey]) ? highlightRow : '')} + tableLayout={'auto'} + scroll={scroll} + columns={columns} + expandable={{ + onExpand: (flag, record) => { + const newKeys = flag ? [...expandedKeys, record.id] : expandedKeys.filter((i) => record.id !== i); + setExpandesKeys(newKeys); + onExpand?.(flag, record); + }, + expandedRowKeys: expandedKeys, + }} + /> + + {field.errors.length > 0 && ( +
    + {field.errors.map((error) => { + return error.messages.map((message) =>
    {message}
    ); + })} +
    + )} +
    + ); + }, + { displayName: 'Table' }, +); diff --git a/packages/core/client/src/schema-component/antd/table-v2/TableField.tsx b/packages/core/client/src/schema-component/antd/table-v2/TableField.tsx index 89097f65c..917afe1cc 100644 --- a/packages/core/client/src/schema-component/antd/table-v2/TableField.tsx +++ b/packages/core/client/src/schema-component/antd/table-v2/TableField.tsx @@ -6,36 +6,42 @@ import { useCollection } from '../../../collection-manager'; import { useCompile } from '../../hooks'; import { ActionBar } from '../action'; -export const TableField: any = observer((props) => { - const fieldSchema = useFieldSchema(); - const { getField } = useCollection(); - const field = useField(); - const collectionField = getField(fieldSchema.name); - const compile = useCompile(); - const ctx = useFormBlockContext(); - useEffect(() => { - if (!field.title) { - field.title = compile(collectionField?.uiSchema?.title); - } - if (ctx?.field) { - ctx.field.added = ctx.field.added || new Set(); - ctx.field.added.add(fieldSchema.name); - } - }, []); - useEffect(() => { - field.decoratorProps.asterisk = fieldSchema.required; - }, [fieldSchema.required]); - return
    {props.children}
    ; -}); +export const TableField: any = observer( + (props) => { + const fieldSchema = useFieldSchema(); + const { getField } = useCollection(); + const field = useField(); + const collectionField = getField(fieldSchema.name); + const compile = useCompile(); + const ctx = useFormBlockContext(); + useEffect(() => { + if (!field.title) { + field.title = compile(collectionField?.uiSchema?.title); + } + if (ctx?.field) { + ctx.field.added = ctx.field.added || new Set(); + ctx.field.added.add(fieldSchema.name); + } + }, []); + useEffect(() => { + field.decoratorProps.asterisk = fieldSchema.required; + }, [fieldSchema.required]); + return
    {props.children}
    ; + }, + { displayName: 'TableField' }, +); -TableField.ActionBar = observer((props) => { - const form = useForm(); - if (form.readPretty) { - return null; - } - return ( -
    - -
    - ); -}); +TableField.ActionBar = observer( + (props) => { + const form = useForm(); + if (form.readPretty) { + return null; + } + return ( +
    + +
    + ); + }, + { displayName: 'TableField.ActionBar' }, +); diff --git a/packages/core/client/src/schema-component/antd/table-v2/demos/demo3.tsx b/packages/core/client/src/schema-component/antd/table-v2/demos/demo3.tsx index 05122f50b..c4ec7b365 100644 --- a/packages/core/client/src/schema-component/antd/table-v2/demos/demo3.tsx +++ b/packages/core/client/src/schema-component/antd/table-v2/demos/demo3.tsx @@ -4,27 +4,30 @@ import { SchemaComponent, SchemaComponentProvider } from '@nocobase/client'; import { Table, TableColumnType } from 'antd'; import React from 'react'; -const ArrayTable = observer((props: any) => { - const { rowKey } = props; - const field = useField(); - const schema = useFieldSchema(); - const columnSchemas = schema.reduceProperties((buf, s) => { - if (s['x-component'] === 'ArrayTable.Column') { - buf.push(s); - } - return buf; - }, []); +const ArrayTable = observer( + (props: any) => { + const { rowKey } = props; + const field = useField(); + const schema = useFieldSchema(); + const columnSchemas = schema.reduceProperties((buf, s) => { + if (s['x-component'] === 'ArrayTable.Column') { + buf.push(s); + } + return buf; + }, []); - const columns = columnSchemas.map((s) => { - return { - render: (value, record) => { - return ; - }, - } as TableColumnType; - }); + const columns = columnSchemas.map((s) => { + return { + render: (value, record) => { + return ; + }, + } as TableColumnType; + }); - return ; -}); + return
    ; + }, + { displayName: 'ArrayTable' }, +); const Value = connect((props) => { return
  • value: {props.value}
  • ; diff --git a/packages/core/client/src/schema-component/antd/table/Table.Array.tsx b/packages/core/client/src/schema-component/antd/table/Table.Array.tsx index b398cea18..daf50e3ef 100644 --- a/packages/core/client/src/schema-component/antd/table/Table.Array.tsx +++ b/packages/core/client/src/schema-component/antd/table/Table.Array.tsx @@ -151,28 +151,29 @@ const useDefAction = () => { }; }; -export const TableArray: React.FC = observer((props) => { - const field = useField(); - const columns = useTableColumns(); - const { - dragSort = false, - showIndex = true, - useSelectedRowKeys = useDef, - useDataSource = useDefDataSource, - useAction = useDefAction, - onChange, - ...others - } = props; - const [selectedRowKeys, setSelectedRowKeys] = useSelectedRowKeys(); - useDataSource({ - onSuccess(data) { - field.value = data?.data || []; - }, - }); - const { move } = useAction(); - const restProps = { - rowSelection: props.rowSelection - ? { +export const TableArray: React.FC = observer( + (props) => { + const field = useField(); + const columns = useTableColumns(); + const { + dragSort = false, + showIndex = true, + useSelectedRowKeys = useDef, + useDataSource = useDefDataSource, + useAction = useDefAction, + onChange, + ...others + } = props; + const [selectedRowKeys, setSelectedRowKeys] = useSelectedRowKeys(); + useDataSource({ + onSuccess(data) { + field.value = data?.data || []; + }, + }); + const { move } = useAction(); + const restProps = { + rowSelection: props.rowSelection + ? { type: 'checkbox', selectedRowKeys, onChange(selectedRowKeys: any[]) { @@ -189,39 +190,39 @@ export const TableArray: React.FC = observer((props) => { className={classNames( checked ? 'checked' : null, css` - position: relative; - display: flex; - align-items: center; - justify-content: space-evenly; - padding-right: 8px; - .nb-table-index { - opacity: 0; - } - &:not(.checked) { - .nb-table-index { - opacity: 1; - } - } - &:hover { + position: relative; + display: flex; + align-items: center; + justify-content: space-evenly; + padding-right: 8px; .nb-table-index { opacity: 0; } - .nb-origin-node { - display: block; + &:not(.checked) { + .nb-table-index { + opacity: 1; + } } - } - `, + &:hover { + .nb-table-index { + opacity: 0; + } + .nb-origin-node { + display: block; + } + } + `, )} >
    {dragSort && } @@ -232,13 +233,13 @@ export const TableArray: React.FC = observer((props) => { 'nb-origin-node', checked ? 'checked' : null, css` - position: absolute; - right: 50%; - transform: translateX(50%); - &:not(.checked) { - display: none; - } - `, + position: absolute; + right: 50%; + transform: translateX(50%); + &:not(.checked) { + display: none; + } + `, )} > {originNode} @@ -248,43 +249,45 @@ export const TableArray: React.FC = observer((props) => { }, ...props.rowSelection, } - : undefined, - }; + : undefined, + }; - const defaultRowKey = (record: any) => { - return field.value?.indexOf?.(record); - }; + const defaultRowKey = (record: any) => { + return field.value?.indexOf?.(record); + }; - return ( -
    - { - const from = field.value[fromIndex]; - const to = field.value[toIndex]; - field.move(fromIndex, toIndex); - await move(from, to); - }} - lineClassName={css` - border-bottom: 2px solid rgba(241, 139, 98, 0.6) !important; + return ( +
    -
    - - - ); -}); + { + const from = field.value[fromIndex]; + const to = field.value[toIndex]; + field.move(fromIndex, toIndex); + await move(from, to); + }} + lineClassName={css` + border-bottom: 2px solid rgba(241, 139, 98, 0.6) !important; + `} + > +
    + + + ); + }, + { displayName: 'TableArray' }, +); diff --git a/packages/core/client/src/schema-component/antd/table/Table.Column.ActionBar.tsx b/packages/core/client/src/schema-component/antd/table/Table.Column.ActionBar.tsx index 4974970dd..2fd39d633 100644 --- a/packages/core/client/src/schema-component/antd/table/Table.Column.ActionBar.tsx +++ b/packages/core/client/src/schema-component/antd/table/Table.Column.ActionBar.tsx @@ -42,12 +42,15 @@ export const designerCss = css` } `; -export const TableColumnActionBar = observer((props) => { - const Designer = useDesigner(); - return ( - - - {props.children} - - ); -}); +export const TableColumnActionBar = observer( + (props) => { + const Designer = useDesigner(); + return ( + + + {props.children} + + ); + }, + { displayName: 'TableColumnActionBar' }, +); diff --git a/packages/core/client/src/schema-component/antd/table/Table.RowSelection.tsx b/packages/core/client/src/schema-component/antd/table/Table.RowSelection.tsx index 1a541ab21..46cdd256a 100644 --- a/packages/core/client/src/schema-component/antd/table/Table.RowSelection.tsx +++ b/packages/core/client/src/schema-component/antd/table/Table.RowSelection.tsx @@ -9,20 +9,23 @@ type Props = TableProps & { value?: any; onChange?: any; objectValue?: bool const toArr = (value: any) => (isArr(value) ? value : isValid(value) ? [value] : []); -export const TableRowSelection = observer((props: Props) => { - const { rowKey = 'id', objectValue } = props; - const field = useField(); - const rowSelection: any = { - type: 'checkbox', - ...props.rowSelection, - selectedRowKeys: toArr(field.value).map((val) => (typeof val === 'object' ? val[rowKey as any] : val)), - onChange(selectedRowKeys: any[], selectedRows?: any) { - if (rowSelection.type === 'checkbox') { - props.onChange(objectValue ? selectedRows : selectedRowKeys); - } else { - props.onChange([...(objectValue ? selectedRows : selectedRowKeys)].shift()); - } - }, - }; - return ; -}); +export const TableRowSelection = observer( + (props: Props) => { + const { rowKey = 'id', objectValue } = props; + const field = useField(); + const rowSelection: any = { + type: 'checkbox', + ...props.rowSelection, + selectedRowKeys: toArr(field.value).map((val) => (typeof val === 'object' ? val[rowKey as any] : val)), + onChange(selectedRowKeys: any[], selectedRows?: any) { + if (rowSelection.type === 'checkbox') { + props.onChange(objectValue ? selectedRows : selectedRowKeys); + } else { + props.onChange([...(objectValue ? selectedRows : selectedRowKeys)].shift()); + } + }, + }; + return ; + }, + { displayName: 'TableRowSelection' }, +); diff --git a/packages/core/client/src/schema-component/antd/table/Table.Void.tsx b/packages/core/client/src/schema-component/antd/table/Table.Void.tsx index 6c11408df..3ea22262b 100644 --- a/packages/core/client/src/schema-component/antd/table/Table.Void.tsx +++ b/packages/core/client/src/schema-component/antd/table/Table.Void.tsx @@ -80,45 +80,48 @@ const useDefSelectedRowKeys = () => { return [result?.state?.selectedRowKeys, (selectedRowKeys) => result?.setState?.({ selectedRowKeys })]; }; -export const TableVoid: React.FC = observer((props) => { - const { rowKey = 'id', useDataSource = useDef, useSelectedRowKeys = useDefSelectedRowKeys } = props; - const field = useField(); - const fieldSchema = useFieldSchema(); - const form = useMemo(() => createForm(), []); - const f = useAttach(form.createArrayField({ ...field.props, basePath: '' })); - const result = useDataSource( - { - uid: fieldSchema['x-uid'], - onSuccess(data) { - form.setValues({ - [fieldSchema.name]: data?.data, - }); - if (field?.componentProps?.pagination === false) { - return; - } - field.componentProps.pagination = field.componentProps.pagination || {}; - if (data?.meta?.count) { - field.componentProps.pagination.total = data?.meta?.count; - } - field.componentProps.pagination.current = data?.meta?.page || 1; - field.componentProps.pagination.pageSize = data?.meta?.pageSize || 10; +export const TableVoid: React.FC = observer( + (props) => { + const { rowKey = 'id', useDataSource = useDef, useSelectedRowKeys = useDefSelectedRowKeys } = props; + const field = useField(); + const fieldSchema = useFieldSchema(); + const form = useMemo(() => createForm(), []); + const f = useAttach(form.createArrayField({ ...field.props, basePath: '' })); + const result = useDataSource( + { + uid: fieldSchema['x-uid'], + onSuccess(data) { + form.setValues({ + [fieldSchema.name]: data?.data, + }); + if (field?.componentProps?.pagination === false) { + return; + } + field.componentProps.pagination = field.componentProps.pagination || {}; + if (data?.meta?.count) { + field.componentProps.pagination.total = data?.meta?.count; + } + field.componentProps.pagination.current = data?.meta?.page || 1; + field.componentProps.pagination.pageSize = data?.meta?.pageSize || 10; + }, }, - }, - props, - ); - return ( - - - - - - - - ); -}); + props, + ); + return ( + + + + + + + + ); + }, + { displayName: 'TableVoid' }, +); diff --git a/packages/core/client/src/schema-component/antd/table/demos/demo4.tsx b/packages/core/client/src/schema-component/antd/table/demos/demo4.tsx index 401060530..5946ed766 100644 --- a/packages/core/client/src/schema-component/antd/table/demos/demo4.tsx +++ b/packages/core/client/src/schema-component/antd/table/demos/demo4.tsx @@ -184,40 +184,43 @@ const schema: ISchema = { }, }; -const DataSourceProvider = observer((props) => { - const [selectedRowKeys, setSelectedRowKeys] = useState([]); - const [dataSource, setDataSource] = useState([]); - const service = useRequest( - () => { - return Promise.resolve({ - data: [ - { id: 1, name: 'Name1' }, - { id: 2, name: 'Name2' }, - { id: 3, name: 'Name3' }, - ], - }); - }, - { - onSuccess(data) { - setDataSource(data.data); +const DataSourceProvider = observer( + (props) => { + const [selectedRowKeys, setSelectedRowKeys] = useState([]); + const [dataSource, setDataSource] = useState([]); + const service = useRequest( + () => { + return Promise.resolve({ + data: [ + { id: 1, name: 'Name1' }, + { id: 2, name: 'Name2' }, + { id: 3, name: 'Name3' }, + ], + }); }, - }, - ); - console.log('dataSource1', dataSource); - return ( - - {props.children} - - ); -}); + { + onSuccess(data) { + setDataSource(data.data); + }, + }, + ); + console.log('dataSource1', dataSource); + return ( + + {props.children} + + ); + }, + { displayName: 'DataSourceProvider' }, +); export default () => { return ( diff --git a/packages/core/client/src/schema-component/antd/tabs/Tabs.tsx b/packages/core/client/src/schema-component/antd/tabs/Tabs.tsx index 3309ac4c6..644f882de 100644 --- a/packages/core/client/src/schema-component/antd/tabs/Tabs.tsx +++ b/packages/core/client/src/schema-component/antd/tabs/Tabs.tsx @@ -9,28 +9,31 @@ import { DndContext, SortableItem } from '../../common'; import { useDesigner } from '../../hooks/useDesigner'; import { TabsDesigner } from './Tabs.Designer'; -export const Tabs: any = observer((props: TabsProps) => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializer(fieldSchema['x-initializer']); - return ( - - - {fieldSchema.mapProperties((schema, key) => { - return ( - } key={key}> - - - ); - })} - - - ); -}); +export const Tabs: any = observer( + (props: TabsProps) => { + const fieldSchema = useFieldSchema(); + const { render } = useSchemaInitializer(fieldSchema['x-initializer']); + return ( + + + {fieldSchema.mapProperties((schema, key) => { + return ( + } key={key}> + + + ); + })} + + + ); + }, + { displayName: 'Tabs' }, +); const designerCss = css` position: relative; @@ -79,15 +82,18 @@ const designerCss = css` } `; -Tabs.TabPane = observer((props: TabPaneProps & { icon?: any }) => { - const Designer = useDesigner(); - const field = useField(); - return ( - - {props.icon && } {props.tab || field.title} - - - ); -}); +Tabs.TabPane = observer( + (props: TabPaneProps & { icon?: any }) => { + const Designer = useDesigner(); + const field = useField(); + return ( + + {props.icon && } {props.tab || field.title} + + + ); + }, + { displayName: 'TabPane' }, +); Tabs.Designer = TabsDesigner; diff --git a/packages/core/client/src/schema-component/antd/tree-select/ReadPretty.tsx b/packages/core/client/src/schema-component/antd/tree-select/ReadPretty.tsx index 3ee56a384..6e2d14c56 100644 --- a/packages/core/client/src/schema-component/antd/tree-select/ReadPretty.tsx +++ b/packages/core/client/src/schema-component/antd/tree-select/ReadPretty.tsx @@ -7,50 +7,53 @@ import { TreeSelectProps } from 'antd/lib/tree-select'; import cls from 'classnames'; import React from 'react'; -export const ReadPretty: React.FC> = observer((props) => { - const field = useField(); - const { placeholder } = props; - const prefixCls = usePrefixCls('description-tree-select', props); - const dataSource = field?.dataSource?.length ? field.dataSource : props?.treeData?.length ? props.treeData : []; - const getSelected = () => { - const value = props.value; - if (props.multiple) { - if (props.labelInValue) { - return isArr(value) ? value : []; +export const ReadPretty: React.FC> = observer( + (props) => { + const field = useField(); + const { placeholder } = props; + const prefixCls = usePrefixCls('description-tree-select', props); + const dataSource = field?.dataSource?.length ? field.dataSource : props?.treeData?.length ? props.treeData : []; + const getSelected = () => { + const value = props.value; + if (props.multiple) { + if (props.labelInValue) { + return isArr(value) ? value : []; + } else { + return isArr(value) ? value.map((val) => ({ label: val, value: val })) : []; + } } else { - return isArr(value) ? value.map((val) => ({ label: val, value: val })) : []; + if (props.labelInValue) { + return value ? [value] : []; + } else { + return value ? [{ label: value, value }] : []; + } } - } else { - if (props.labelInValue) { - return value ? [value] : []; - } else { - return value ? [{ label: value, value }] : []; - } - } - }; + }; - const findLabel = (value: any, dataSource: any[]) => { - for (let i = 0; i < dataSource?.length; i++) { - const item = dataSource[i]; - if (item?.value === value) { - return item?.label; - } else { - const childLabel = findLabel(value, item?.children); - if (childLabel) return childLabel; + const findLabel = (value: any, dataSource: any[]) => { + for (let i = 0; i < dataSource?.length; i++) { + const item = dataSource[i]; + if (item?.value === value) { + return item?.label; + } else { + const childLabel = findLabel(value, item?.children); + if (childLabel) return childLabel; + } } - } - }; + }; - const getLabels = () => { - const selected = getSelected(); - if (!selected?.length) return {placeholder}; - return selected.map(({ value, label }, key) => { - return {findLabel(value, dataSource) || label || placeholder}; - }); - }; - return ( -
    - {getLabels()} -
    - ); -}); + const getLabels = () => { + const selected = getSelected(); + if (!selected?.length) return {placeholder}; + return selected.map(({ value, label }, key) => { + return {findLabel(value, dataSource) || label || placeholder}; + }); + }; + return ( +
    + {getLabels()} +
    + ); + }, + { displayName: 'ReadPretty' }, +); diff --git a/packages/core/client/src/schema-component/common/dnd-context/index.tsx b/packages/core/client/src/schema-component/common/dnd-context/index.tsx index 7ff6c772e..4d2090cad 100644 --- a/packages/core/client/src/schema-component/common/dnd-context/index.tsx +++ b/packages/core/client/src/schema-component/common/dnd-context/index.tsx @@ -59,32 +59,35 @@ const useDragEnd = (props?: any) => { }; }; -export const DndContext = observer((props: Props) => { - const { t } = useTranslation(); - const [visible, setVisible] = useState(true); - return ( - { - const { active } = event; - const activeSchema = active?.data?.current?.schema; - setVisible(!!activeSchema); - if (props?.onDragStart) { - props?.onDragStart?.(event); - } - }} - onDragEnd={useDragEnd(props)} - > - { + const { t } = useTranslation(); + const [visible, setVisible] = useState(true); + return ( + { + const { active } = event; + const activeSchema = active?.data?.current?.schema; + setVisible(!!activeSchema); + if (props?.onDragStart) { + props?.onDragStart?.(event); + } }} + onDragEnd={useDragEnd(props)} > - {visible && {t('Dragging')}} - - {props.children} - - ); -}); + + {visible && {t('Dragging')}} + + {props.children} + + ); + }, + { displayName: 'DndContext' }, +); diff --git a/packages/core/client/src/schema-component/common/sortable-item/SortableItem.tsx b/packages/core/client/src/schema-component/common/sortable-item/SortableItem.tsx index 761783c3d..d0d0263fd 100644 --- a/packages/core/client/src/schema-component/common/sortable-item/SortableItem.tsx +++ b/packages/core/client/src/schema-component/common/sortable-item/SortableItem.tsx @@ -55,21 +55,24 @@ const useSortableItemId = (props) => { return field.address.toString(); }; -export const SortableItem: React.FC = observer((props) => { - const { schema, id, removeParentsIfNoChildren, ...others } = useSortableItemProps(props); - return ( - - {props.children} - - ); -}); +export const SortableItem: React.FC = observer( + (props) => { + const { schema, id, removeParentsIfNoChildren, ...others } = useSortableItemProps(props); + return ( + + {props.children} + + ); + }, + { displayName: 'SortableItem' }, +); export const DragHandler = (props) => { const { draggable } = useContext(SortableContext); diff --git a/packages/core/client/src/schema-component/core/SchemaComponentOptions.tsx b/packages/core/client/src/schema-component/core/SchemaComponentOptions.tsx index 152be0322..8e5918644 100644 --- a/packages/core/client/src/schema-component/core/SchemaComponentOptions.tsx +++ b/packages/core/client/src/schema-component/core/SchemaComponentOptions.tsx @@ -1,16 +1,22 @@ -import { SchemaExpressionScopeContext, SchemaOptionsContext } from '@formily/react'; +import { ExpressionScope, SchemaComponentsContext, SchemaOptionsContext } from '@formily/react'; import React, { useContext } from 'react'; import { ISchemaComponentOptionsProps } from '../types'; -export const SchemaComponentOptions: React.FC = (props) => { - const { inherit } = props; +const useSchemaOptionsContext = () => { const options = useContext(SchemaOptionsContext); - const expressionScope = useContext(SchemaExpressionScopeContext); - const scope = { ...options?.scope, ...expressionScope, ...props.scope }; - const components = { ...options?.components, ...props.components }; + return options || {}; +}; + +export const SchemaComponentOptions: React.FC = (props) => { + const { children } = props; + const options = useSchemaOptionsContext(); + const components = { ...options.components, ...props.components }; + const scope = { ...options.scope, ...props.scope }; return ( - {props.children} + + {children} + ); }; diff --git a/packages/core/client/src/schema-component/core/SchemaComponentProvider.tsx b/packages/core/client/src/schema-component/core/SchemaComponentProvider.tsx index 36b470a6b..fba98a941 100644 --- a/packages/core/client/src/schema-component/core/SchemaComponentProvider.tsx +++ b/packages/core/client/src/schema-component/core/SchemaComponentProvider.tsx @@ -14,18 +14,30 @@ const randomString = (prefix = '') => { Schema.silent(true); +const results = {}; + const Registry = { silent: true, compile(expression: string, scope = {}) { - if (Registry.silent) { - try { + const fn = () => { + if (Registry.silent) { + try { + return new Function('$root', `with($root) { return (${expression}); }`)(scope); + } catch { + return `{{${expression}}}`; + } + } else { return new Function('$root', `with($root) { return (${expression}); }`)(scope); - } catch { - return `{{${expression}}}`; } - } else { - return new Function('$root', `with($root) { return (${expression}); }`)(scope); + }; + if (results[expression]) { + return results[expression]; } + if (expression.trim().startsWith('t(')) { + results[expression] = fn(); + return results[expression]; + } + return fn(); }, }; diff --git a/packages/core/client/src/schema-component/demos/demo1.tsx b/packages/core/client/src/schema-component/demos/demo1.tsx index 22c423ef3..a46f567b6 100644 --- a/packages/core/client/src/schema-component/demos/demo1.tsx +++ b/packages/core/client/src/schema-component/demos/demo1.tsx @@ -7,58 +7,64 @@ import { observer, Schema, useFieldSchema } from '@formily/react'; import { Button, Space } from 'antd'; import { uid } from '@formily/shared'; -const Hello = observer((props) => { - const { insertAdjacent } = useDesignable(); - const fieldSchema = useFieldSchema(); - return ( -
    -

    {fieldSchema.name}

    - - - - - - -
    {props.children}
    -
    - ); -}); +const Hello = observer( + (props) => { + const { insertAdjacent } = useDesignable(); + const fieldSchema = useFieldSchema(); + return ( +
    +

    {fieldSchema.name}

    + + + + + + +
    {props.children}
    +
    + ); + }, + { displayName: 'Hello' }, +); -const Page = observer((props) => { - return
    {props.children}
    ; -}); +const Page = observer( + (props) => { + return
    {props.children}
    ; + }, + { displayName: 'Page' }, +); export default function App() { return ( diff --git a/packages/core/client/src/schema-component/hooks/useCompile.ts b/packages/core/client/src/schema-component/hooks/useCompile.ts index 922ef9885..0d60c7d2a 100644 --- a/packages/core/client/src/schema-component/hooks/useCompile.ts +++ b/packages/core/client/src/schema-component/hooks/useCompile.ts @@ -1,13 +1,47 @@ import { Schema, SchemaExpressionScopeContext, SchemaOptionsContext } from '@formily/react'; -import { useContext } from 'react'; +import { useContext, isValidElement } from 'react'; + +const compileCache = {}; export const useCompile = () => { const options = useContext(SchemaOptionsContext); const scope = useContext(SchemaExpressionScopeContext); return (source: any, ext?: any) => { - if (!source) { - return source; + let shouldCompile = false; + let cacheKey: string; + + // source is i18n, for example: {{ t('Add new') }} + if (typeof source === 'string' && source.startsWith('{{')) { + shouldCompile = true; + cacheKey = source; } - return Schema.compile(source, { ...options.scope, ...scope, ...ext }); + + // source is Component Object, for example: { 'x-component': "Cascader", type: "array", title: "所属地区(行政区划)" } + if (source && typeof source === 'object' && !isValidElement(source)) { + shouldCompile = true; + cacheKey = JSON.stringify(source); + } + + // source is Array, for example: [{ 'title': "{{ ('Admin')}}", name: 'admin' }, { 'title': "{{ ('Root')}}", name: 'root' }] + if (Array.isArray(source)) { + shouldCompile = true; + } + + if (shouldCompile) { + const mergedScope = { ...options.scope, ...scope, ...ext }; + if (!cacheKey) { + return Schema.compile(source, mergedScope); + } + try { + compileCache[cacheKey] = compileCache[cacheKey] || Schema.compile(source, mergedScope); + return compileCache[cacheKey]; + } catch (e) { + console.log('useCompile error', source, e); + return Schema.compile(source, mergedScope); + } + } + + // source is: plain object、string、number、boolean、undefined、null + return source; }; }; diff --git a/packages/core/client/src/schema-initializer/SchemaInitializer.tsx b/packages/core/client/src/schema-initializer/SchemaInitializer.tsx index 8b1130ed6..2b71c8f76 100644 --- a/packages/core/client/src/schema-initializer/SchemaInitializer.tsx +++ b/packages/core/client/src/schema-initializer/SchemaInitializer.tsx @@ -22,134 +22,137 @@ export const SchemaInitializer = () => null; const menuItemGroupCss = 'nb-menu-item-group'; -SchemaInitializer.Button = observer((props: SchemaInitializerButtonProps) => { - const { - title, - insert, - wrap = defaultWrap, - items = [], - insertPosition = 'beforeEnd', - dropdown, - component, - style, - icon, - onSuccess, - ...others - } = props; - const compile = useCompile(); - const { insertAdjacent, findComponent, designable } = useDesignable(); - const [visible, setVisible] = useState(false); - const insertSchema = (schema) => { - if (props.insert) { - props.insert(wrap(schema)); - } else { - insertAdjacent(insertPosition, wrap(schema), { onSuccess }); - } - }; - const renderItems = (items: any) => { - return items - .filter((v) => { - return v && (v?.visible ? v.visible() : true); - }) - ?.map((item, indexA) => { - if (item.type === 'divider') { - return ; - } - if (item.type === 'item' && item.component) { - const Component = findComponent(item.component); - item.key = `${item.key || item.title}-${indexA}`; - return ( - Component && ( - - { + const { + title, + insert, + wrap = defaultWrap, + items = [], + insertPosition = 'beforeEnd', + dropdown, + component, + style, + icon, + onSuccess, + ...others + } = props; + const compile = useCompile(); + const { insertAdjacent, findComponent, designable } = useDesignable(); + const [visible, setVisible] = useState(false); + const insertSchema = (schema) => { + if (props.insert) { + props.insert(wrap(schema)); + } else { + insertAdjacent(insertPosition, wrap(schema), { onSuccess }); + } + }; + const renderItems = (items: any) => { + return items + .filter((v) => { + return v && (v?.visible ? v.visible() : true); + }) + ?.map((item, indexA) => { + if (item.type === 'divider') { + return ; + } + if (item.type === 'item' && item.component) { + const Component = findComponent(item.component); + item.key = `${item.key || item.title}-${indexA}`; + return ( + Component && ( + - - ) - ); - } - if (item.type === 'itemGroup') { - return ( - !!item.children?.length && ( - - {renderItems(item.children)} - - ) - ); - } - if (item.type === 'subMenu') { - return ( - !!item.children?.length && ( - - {renderItems(item.children)} - - ) - ); - } - }); - }; - const menu = {renderItems(items)}; - if (!designable && props.designable !== true) { - return null; - } - return ( - - { - setVisible(visible); - }} - {...dropdown} - overlay={menu} - > - {component ? ( - component - ) : ( - - )} - - - ); -}); + > + + + ) + ); + } + if (item.type === 'itemGroup') { + return ( + !!item.children?.length && ( + + {renderItems(item.children)} + + ) + ); + } + if (item.type === 'subMenu') { + return ( + !!item.children?.length && ( + + {renderItems(item.children)} + + ) + ); + } + }); + }; + const menu = {renderItems(items)}; + if (!designable && props.designable !== true) { + return null; + } + return ( + + { + setVisible(visible); + }} + {...dropdown} + overlay={menu} + > + {component ? ( + component + ) : ( + + )} + + + ); + }, + { displayName: 'SchemaInitializer.Button' }, +); SchemaInitializer.Item = (props: SchemaInitializerItemProps) => { const { index, info } = useContext(SchemaInitializerItemContext); diff --git a/packages/core/client/src/schema-initializer/components/CreateRecordAction.tsx b/packages/core/client/src/schema-initializer/components/CreateRecordAction.tsx index f7b534250..481ee9f61 100644 --- a/packages/core/client/src/schema-initializer/components/CreateRecordAction.tsx +++ b/packages/core/client/src/schema-initializer/components/CreateRecordAction.tsx @@ -80,146 +80,152 @@ const actionAclCheck = (actionPath) => { return true; }; -export const CreateRecordAction = observer((props: any) => { - const [visible, setVisible] = useState(false); - const collection = useCollection(); - const fieldSchema = useFieldSchema(); - const field: any = useField(); - const [currentCollection, setCurrentCollection] = useState(collection.name); - const linkageRules = fieldSchema?.['x-linkage-rules'] || []; - const values = useRecord(); - const ctx = useActionContext(); - useEffect(() => { - field.linkageProperty = {}; - linkageRules - .filter((k) => !k.disabled) - .map((v) => { - return v.actions?.map((h) => { - linkageAction(h.operator, field, v.condition, values); +export const CreateRecordAction = observer( + (props: any) => { + const [visible, setVisible] = useState(false); + const collection = useCollection(); + const fieldSchema = useFieldSchema(); + const field: any = useField(); + const [currentCollection, setCurrentCollection] = useState(collection.name); + const linkageRules = fieldSchema?.['x-linkage-rules'] || []; + const values = useRecord(); + const ctx = useActionContext(); + useEffect(() => { + field.linkageProperty = {}; + linkageRules + .filter((k) => !k.disabled) + .map((v) => { + return v.actions?.map((h) => { + linkageAction(h.operator, field, v.condition, values); + }); }); - }); - }, [linkageRules, values]); - return ( -
    - - { - setVisible(true); - setCurrentCollection(name); - }} - /> - - - - -
    - ); -}); - -export const CreateAction = observer((props: any) => { - const { onClick } = props; - const collection = useCollection(); - const fieldSchema = useFieldSchema(); - const enableChildren = fieldSchema['x-enable-children'] || []; - const allowAddToCurrent = fieldSchema?.['x-allow-add-to-current']; - const field: any = useField(); - const componentType = field.componentProps.type || 'primary'; - const { getChildrenCollections } = useCollectionManager(); - const totalChildCollections = getChildrenCollections(collection.name); - const inheritsCollections = enableChildren - .map((k) => { - if (!k) { - return; - } - const childCollection = totalChildCollections.find((j) => j.name === k.collection); - if (!childCollection) { - return; - } - return { - ...childCollection, - title: k.title || childCollection.title, - }; - }) - .filter((v) => { - return v && actionAclCheck(`${v.name}:create`); - }); - const linkageRules = fieldSchema?.['x-linkage-rules'] || []; - const values = useRecord(); - const compile = useCompile(); - const { designable } = useDesignable(); - const icon = props.icon || ; - const menu = ( - - {inheritsCollections.map((option) => { - return ( - { - onClick?.(option.name); + }, [linkageRules, values]); + return ( +
    + + { + setVisible(true); + setCurrentCollection(name); }} - > - {compile(option.title)} - - ); - })} -
    - ); - useEffect(() => { - field.linkageProperty = {}; - linkageRules - .filter((k) => !k.disabled) - .map((v) => { - return v.actions?.map((h) => { - linkageAction(h.operator, field, v.condition, values); - }); + /> + + + + + + ); + }, + { displayName: 'CreateRecordAction' }, +); + +export const CreateAction = observer( + (props: any) => { + const { onClick } = props; + const collection = useCollection(); + const fieldSchema = useFieldSchema(); + const enableChildren = fieldSchema['x-enable-children'] || []; + const allowAddToCurrent = fieldSchema?.['x-allow-add-to-current']; + const field: any = useField(); + const componentType = field.componentProps.type || 'primary'; + const { getChildrenCollections } = useCollectionManager(); + const totalChildCollections = getChildrenCollections(collection.name); + const inheritsCollections = enableChildren + .map((k) => { + if (!k) { + return; + } + const childCollection = totalChildCollections.find((j) => j.name === k.collection); + if (!childCollection) { + return; + } + return { + ...childCollection, + title: k.title || childCollection.title, + }; + }) + .filter((v) => { + return v && actionAclCheck(`${v.name}:create`); }); - }, [linkageRules, values]); - return ( -
    - {inheritsCollections?.length > 0 ? ( - allowAddToCurrent === undefined || allowAddToCurrent ? ( - ; + const menu = ( + + {inheritsCollections.map((option) => { + return ( + { + onClick?.(option.name); + }} + > + {compile(option.title)} + + ); + })} + + ); + useEffect(() => { + field.linkageProperty = {}; + linkageRules + .filter((k) => !k.disabled) + .map((v) => { + return v.actions?.map((h) => { + linkageAction(h.operator, field, v.condition, values); + }); + }); + }, [linkageRules, values]); + return ( +
    + {inheritsCollections?.length > 0 ? ( + allowAddToCurrent === undefined || allowAddToCurrent ? ( + } + buttonsRender={([leftButton, rightButton]) => [ + leftButton, + React.cloneElement(rightButton as React.ReactElement, { loading: false }), + ]} + overlay={menu} + onClick={(info) => { + onClick?.(collection.name); + }} + > + {icon} + {props.children} + + ) : ( + + { + + } + + ) + ) : ( + - } - - ) - ) : ( - - )} -
    - ); -}); + + )} +
    + ); + }, + { displayName: 'CreateAction' }, +); diff --git a/packages/core/client/src/schema-initializer/demos/demo1.tsx b/packages/core/client/src/schema-initializer/demos/demo1.tsx index 8801f7a4a..a8b5824a7 100644 --- a/packages/core/client/src/schema-initializer/demos/demo1.tsx +++ b/packages/core/client/src/schema-initializer/demos/demo1.tsx @@ -10,14 +10,17 @@ import { } from '@nocobase/client'; import React from 'react'; -const Hello = observer((props) => { - const field = useField(); - return ( -
    - {field.title} -
    - ); -}); +const Hello = observer( + (props) => { + const field = useField(); + return ( +
    + {field.title} +
    + ); + }, + { displayName: 'Hello' }, +); const TableBlockInitializer = SchemaInitializer.itemWrap((props) => { const { insert } = props; @@ -84,10 +87,13 @@ const initializers = { }, }; -const AddBlockButton = observer((props: any) => { - const { render } = useSchemaInitializer('AddBlock'); - return <>{render()}; -}); +const AddBlockButton = observer( + (props: any) => { + const { render } = useSchemaInitializer('AddBlock'); + return <>{render()}; + }, + { displayName: 'AddBlockButton' }, +); export default function App() { return ( diff --git a/packages/core/client/src/schema-items/GeneralSchemaItems.tsx b/packages/core/client/src/schema-items/GeneralSchemaItems.tsx index 996b0f0c8..c18e0bc97 100644 --- a/packages/core/client/src/schema-items/GeneralSchemaItems.tsx +++ b/packages/core/client/src/schema-items/GeneralSchemaItems.tsx @@ -8,154 +8,157 @@ import { SchemaSettings } from '../schema-settings'; export const GeneralSchemaItems: React.FC<{ required?: boolean; -}> = observer((props) => { - const { required = true } = props; - const { getCollectionJoinField } = useCollectionManager(); - const { getField } = useCollection(); - const field = useField(); - const fieldSchema = useFieldSchema(); - const { t } = useTranslation(); - const { dn, refresh } = useDesignable(); - const collectionField = getField(fieldSchema['name']) || getCollectionJoinField(fieldSchema['x-collection-field']); - return ( - <> - {collectionField && ( - = observer( + (props) => { + const { required = true } = props; + const { getCollectionJoinField } = useCollectionManager(); + const { getField } = useCollection(); + const field = useField(); + const fieldSchema = useFieldSchema(); + const { t } = useTranslation(); + const { dn, refresh } = useDesignable(); + const collectionField = getField(fieldSchema['name']) || getCollectionJoinField(fieldSchema['x-collection-field']); + return ( + <> + {collectionField && ( + { + if (title) { + field.title = title; + fieldSchema.title = title; + dn.emit('patch', { + schema: { + 'x-uid': fieldSchema['x-uid'], + title: fieldSchema.title, + }, + }); + } + dn.refresh(); + }} + /> + )} + { + fieldSchema['x-decorator-props'] = fieldSchema['x-decorator-props'] || {}; + fieldSchema['x-decorator-props']['showTitle'] = checked; + field.decoratorProps.showTitle = checked; + dn.emit('patch', { + schema: { + 'x-uid': fieldSchema['x-uid'], + 'x-decorator-props': { + ...fieldSchema['x-decorator-props'], + showTitle: checked, }, }, - } as ISchema - } - onSubmit={({ title }) => { - if (title) { - field.title = title; - fieldSchema.title = title; + }); + dn.refresh(); + }} + > + {!field.readPretty && ( + { + field.description = description; + fieldSchema.description = description; dn.emit('patch', { schema: { 'x-uid': fieldSchema['x-uid'], - title: fieldSchema.title, + description: fieldSchema.description, }, }); + dn.refresh(); + }} + /> + )} + {field.readPretty && ( + - )} - { - fieldSchema['x-decorator-props'] = fieldSchema['x-decorator-props'] || {}; - fieldSchema['x-decorator-props']['showTitle'] = checked; - field.decoratorProps.showTitle = checked; - dn.emit('patch', { - schema: { - 'x-uid': fieldSchema['x-uid'], - 'x-decorator-props': { - ...fieldSchema['x-decorator-props'], - showTitle: checked, - }, - }, - }); - dn.refresh(); - }} - > - {!field.readPretty && ( - { + field.decoratorProps.tooltip = tooltip; + fieldSchema['x-decorator-props'] = fieldSchema['x-decorator-props'] || {}; + fieldSchema['x-decorator-props']['tooltip'] = tooltip; + dn.emit('patch', { + schema: { + 'x-uid': fieldSchema['x-uid'], + 'x-decorator-props': fieldSchema['x-decorator-props'], }, - }, - } as ISchema - } - onSubmit={({ description }) => { - field.description = description; - fieldSchema.description = description; - dn.emit('patch', { - schema: { - 'x-uid': fieldSchema['x-uid'], - description: fieldSchema.description, - }, - }); - dn.refresh(); - }} - /> - )} - {field.readPretty && ( - { - field.decoratorProps.tooltip = tooltip; - fieldSchema['x-decorator-props'] = fieldSchema['x-decorator-props'] || {}; - fieldSchema['x-decorator-props']['tooltip'] = tooltip; - dn.emit('patch', { - schema: { - 'x-uid': fieldSchema['x-uid'], - 'x-decorator-props': fieldSchema['x-decorator-props'], - }, - }); - dn.refresh(); - }} - /> - )} - {!field.readPretty && fieldSchema['x-component'] !== 'FormField' && required && ( - { - const schema = { - ['x-uid']: fieldSchema['x-uid'], - }; - field.required = required; - fieldSchema['required'] = required; - schema['required'] = required; - dn.emit('patch', { - schema, - }); - refresh(); - }} - /> - )} - - ); -}); + }); + dn.refresh(); + }} + /> + )} + {!field.readPretty && fieldSchema['x-component'] !== 'FormField' && required && ( + { + const schema = { + ['x-uid']: fieldSchema['x-uid'], + }; + field.required = required; + fieldSchema['required'] = required; + schema['required'] = required; + dn.emit('patch', { + schema, + }); + refresh(); + }} + /> + )} + + ); + }, + { displayName: 'GeneralSchemaItems' }, +); diff --git a/packages/core/client/src/schema-settings/DataTemplates/FormDataTemplates.tsx b/packages/core/client/src/schema-settings/DataTemplates/FormDataTemplates.tsx index c7886670e..d448f6e58 100644 --- a/packages/core/client/src/schema-settings/DataTemplates/FormDataTemplates.tsx +++ b/packages/core/client/src/schema-settings/DataTemplates/FormDataTemplates.tsx @@ -28,215 +28,218 @@ const Tree = connect( }), ); -export const FormDataTemplates = observer((props: any) => { - const { useProps, formSchema, designerCtx } = props; - const { defaultValues, collectionName } = useProps(); - const { collectionList, getEnableFieldTree, onLoadData, onCheck } = useCollectionState(collectionName); - const { getCollection, getCollectionField } = useCollectionManager(); - const { t } = useTranslation(); +export const FormDataTemplates = observer( + (props: any) => { + const { useProps, formSchema, designerCtx } = props; + const { defaultValues, collectionName } = useProps(); + const { collectionList, getEnableFieldTree, onLoadData, onCheck } = useCollectionState(collectionName); + const { getCollection, getCollectionField } = useCollectionManager(); + const { t } = useTranslation(); - // 不要在后面的数组中依赖 defaultValues,否则会因为 defaultValues 的变化导致 activeData 响应性丢失 - const activeData = useMemo( - () => - observable( - defaultValues || { items: [], display: true, config: { [collectionName]: { titleField: '', filter: {} } } }, - ), - [], - ); - - const getTargetField = (collectionName: string) => { - const collection = getCollection(collectionName); - return getCollectionField( - `${collectionName}.${activeData?.config[collectionName]?.titleField || collection?.titleField || 'id'}`, + // 不要在后面的数组中依赖 defaultValues,否则会因为 defaultValues 的变化导致 activeData 响应性丢失 + const activeData = useMemo( + () => + observable( + defaultValues || { items: [], display: true, config: { [collectionName]: { titleField: '', filter: {} } } }, + ), + [], ); - }; - const getFieldNames = (collectionName: string) => { - const collection = getCollection(collectionName); - return { - label: getLabel(activeData.config?.[collectionName]?.titleField || collection?.titleField || 'id'), - value: 'id', + const getTargetField = (collectionName: string) => { + const collection = getCollection(collectionName); + return getCollectionField( + `${collectionName}.${activeData?.config[collectionName]?.titleField || collection?.titleField || 'id'}`, + ); }; - }; - const getFilter = (collectionName: string, value: any) => { - const filter = activeData.config?.[collectionName]?.filter; - return _.isEmpty(filter) ? {} : removeNullCondition(mergeFilter([filter, getSelectedIdFilter(value)], '$or')); - }; + const getFieldNames = (collectionName: string) => { + const collection = getCollection(collectionName); + return { + label: getLabel(activeData.config?.[collectionName]?.titleField || collection?.titleField || 'id'), + value: 'id', + }; + }; - const components = useMemo(() => ({ ArrayCollapse }), []); - const scope = useMemo( - () => ({ - getEnableFieldTree, - getTargetField, - getFieldNames, - getFilter, - getResource, - collectionName, - }), - [], - ); - const schema = useMemo( - () => ({ - type: 'object', - properties: { - items: { - type: 'array', - default: activeData?.items, - 'x-component': 'ArrayCollapse', - 'x-decorator': 'FormItem', - 'x-component-props': { - accordion: true, - }, + const getFilter = (collectionName: string, value: any) => { + const filter = activeData.config?.[collectionName]?.filter; + return _.isEmpty(filter) ? {} : removeNullCondition(mergeFilter([filter, getSelectedIdFilter(value)], '$or')); + }; + + const components = useMemo(() => ({ ArrayCollapse }), []); + const scope = useMemo( + () => ({ + getEnableFieldTree, + getTargetField, + getFieldNames, + getFilter, + getResource, + collectionName, + }), + [], + ); + const schema = useMemo( + () => ({ + type: 'object', + properties: { items: { - type: 'object', - 'x-component': 'ArrayCollapse.CollapsePanel', + type: 'array', + default: activeData?.items, + 'x-component': 'ArrayCollapse', + 'x-decorator': 'FormItem', 'x-component-props': { - extra: [], + accordion: true, }, - properties: { - layout: { - type: 'void', - 'x-component': 'FormLayout', - 'x-component-props': { - layout: 'vertical', - }, - properties: { - collection: { - type: 'string', - title: '{{ t("Collection") }}', - required: true, - description: t('If collection inherits, choose inherited collections as templates'), - default: '{{ collectionName }}', - 'x-display': collectionList.length > 1 ? 'visible' : 'hidden', - 'x-decorator': 'FormItem', - 'x-component': 'Select', - 'x-component-props': { - options: collectionList, - }, + items: { + type: 'object', + 'x-component': 'ArrayCollapse.CollapsePanel', + 'x-component-props': { + extra: [], + }, + properties: { + layout: { + type: 'void', + 'x-component': 'FormLayout', + 'x-component-props': { + layout: 'vertical', }, - dataId: { - type: 'number', - title: '{{ t("Template Data") }}', - required: true, - description: t('Select an existing piece of data as the initialization data for the form'), - 'x-designer': Designer, - 'x-designer-props': { - formSchema, - data: activeData, - }, - 'x-decorator': 'FormItem', - 'x-component': AssociationSelect, - 'x-component-props': { - service: { - resource: '{{ $record.collection || collectionName }}', - params: { - filter: '{{ getFilter($self.componentProps.service.resource, $self.value) }}', - }, + properties: { + collection: { + type: 'string', + title: '{{ t("Collection") }}', + required: true, + description: t('If collection inherits, choose inherited collections as templates'), + default: '{{ collectionName }}', + 'x-display': collectionList.length > 1 ? 'visible' : 'hidden', + 'x-decorator': 'FormItem', + 'x-component': 'Select', + 'x-component-props': { + options: collectionList, }, - action: 'list', - multiple: false, - objectValue: false, - manual: false, - targetField: '{{ getTargetField($self.componentProps.service.resource) }}', - mapOptions: getMapOptions(), - fieldNames: '{{ getFieldNames($self.componentProps.service.resource) }}', }, - 'x-reactions': [ - { - dependencies: ['.collection'], - fulfill: { - state: { - disabled: '{{ !$deps[0] }}', - componentProps: { - service: { - resource: '{{ getResource($deps[0], $self) }}', + dataId: { + type: 'number', + title: '{{ t("Template Data") }}', + required: true, + description: t('Select an existing piece of data as the initialization data for the form'), + 'x-designer': Designer, + 'x-designer-props': { + formSchema, + data: activeData, + }, + 'x-decorator': 'FormItem', + 'x-component': AssociationSelect, + 'x-component-props': { + service: { + resource: '{{ $record.collection || collectionName }}', + params: { + filter: '{{ getFilter($self.componentProps.service.resource, $self.value) }}', + }, + }, + action: 'list', + multiple: false, + objectValue: false, + manual: false, + targetField: '{{ getTargetField($self.componentProps.service.resource) }}', + mapOptions: getMapOptions(), + fieldNames: '{{ getFieldNames($self.componentProps.service.resource) }}', + }, + 'x-reactions': [ + { + dependencies: ['.collection'], + fulfill: { + state: { + disabled: '{{ !$deps[0] }}', + componentProps: { + service: { + resource: '{{ getResource($deps[0], $self) }}', + }, }, }, }, }, - }, - ], - }, - fields: { - type: 'array', - title: '{{ t("Data fields") }}', - required: true, - description: t('Only the selected fields will be used as the initialization data for the form'), - 'x-decorator': 'FormItem', - 'x-component': Tree, - 'x-component-props': { - treeData: [], - checkable: true, - checkStrictly: true, - selectable: false, - loadData: onLoadData, - onCheck, - rootStyle: { - padding: '8px 0', - border: '1px solid #d9d9d9', - borderRadius: '2px', - maxHeight: '30vh', - overflow: 'auto', - margin: '2px 0', - }, + ], }, - 'x-reactions': [ - { - dependencies: ['.collection'], - fulfill: { - state: { - disabled: '{{ !$deps[0] }}', - componentProps: { - treeData: '{{ getEnableFieldTree($deps[0], $self) }}', + fields: { + type: 'array', + title: '{{ t("Data fields") }}', + required: true, + description: t('Only the selected fields will be used as the initialization data for the form'), + 'x-decorator': 'FormItem', + 'x-component': Tree, + 'x-component-props': { + treeData: [], + checkable: true, + checkStrictly: true, + selectable: false, + loadData: onLoadData, + onCheck, + rootStyle: { + padding: '8px 0', + border: '1px solid #d9d9d9', + borderRadius: '2px', + maxHeight: '30vh', + overflow: 'auto', + margin: '2px 0', + }, + }, + 'x-reactions': [ + { + dependencies: ['.collection'], + fulfill: { + state: { + disabled: '{{ !$deps[0] }}', + componentProps: { + treeData: '{{ getEnableFieldTree($deps[0], $self) }}', + }, }, }, }, - }, - ], + ], + }, }, }, + remove: { + type: 'void', + 'x-component': 'ArrayCollapse.Remove', + }, + moveUp: { + type: 'void', + 'x-component': 'ArrayCollapse.MoveUp', + }, + moveDown: { + type: 'void', + 'x-component': 'ArrayCollapse.MoveDown', + }, }, - remove: { + }, + properties: { + add: { type: 'void', - 'x-component': 'ArrayCollapse.Remove', - }, - moveUp: { - type: 'void', - 'x-component': 'ArrayCollapse.MoveUp', - }, - moveDown: { - type: 'void', - 'x-component': 'ArrayCollapse.MoveDown', + title: '{{ t("Add template") }}', + 'x-component': 'ArrayCollapse.Addition', }, }, }, - properties: { - add: { - type: 'void', - title: '{{ t("Add template") }}', - 'x-component': 'ArrayCollapse.Addition', - }, + display: { + type: 'boolean', + 'x-content': '{{ t("Display data template selector") }}', + default: activeData?.display !== false, + 'x-decorator': 'FormItem', + 'x-component': 'Checkbox', }, }, - display: { - type: 'boolean', - 'x-content': '{{ t("Display data template selector") }}', - default: activeData?.display !== false, - 'x-decorator': 'FormItem', - 'x-component': 'Checkbox', - }, - }, - }), - [], - ); + }), + [], + ); - return ( - - - - ); -}); + return ( + + + + ); + }, + { displayName: 'FormDataTemplates' }, +); export function getLabel(titleField) { return titleField || 'label'; diff --git a/packages/core/client/src/schema-settings/DataTemplates/components/DataTemplateTitle.tsx b/packages/core/client/src/schema-settings/DataTemplates/components/DataTemplateTitle.tsx index dcae98891..8330d9892 100644 --- a/packages/core/client/src/schema-settings/DataTemplates/components/DataTemplateTitle.tsx +++ b/packages/core/client/src/schema-settings/DataTemplates/components/DataTemplateTitle.tsx @@ -100,129 +100,132 @@ const insertActiveKeys = (activeKeys: number[], index: number) => { }, []); }; -export const ArrayCollapse: ComposedArrayCollapse = observer((props: IArrayCollapseProps) => { - const field = useField(); - const dataSource = Array.isArray(field.value) ? field.value : []; - const [activeKeys, setActiveKeys] = useState( - takeDefaultActiveKeys(dataSource.length, props.defaultOpenPanelCount), - ); - const schema = useFieldSchema(); - const prefixCls = 'ant-formily-array-collapse'; - useEffect(() => { - if (!field.modified && dataSource.length) { - setActiveKeys(takeDefaultActiveKeys(dataSource.length, props.defaultOpenPanelCount)); - } - }, [dataSource.length, field]); - if (!schema) throw new Error('can not found schema object'); - - const renderAddition = () => { - return schema.reduceProperties((addition, schema, key) => { - if (isAdditionComponent(schema)) { - return ; - } - return addition; - }, null); - }; - const renderEmpty = () => { - if (dataSource.length) return; - return ( - - - +export const ArrayCollapse: ComposedArrayCollapse = observer( + (props: IArrayCollapseProps) => { + const field = useField(); + const dataSource = Array.isArray(field.value) ? field.value : []; + const [activeKeys, setActiveKeys] = useState( + takeDefaultActiveKeys(dataSource.length, props.defaultOpenPanelCount), ); - }; + const schema = useFieldSchema(); + const prefixCls = 'ant-formily-array-collapse'; + useEffect(() => { + if (!field.modified && dataSource.length) { + setActiveKeys(takeDefaultActiveKeys(dataSource.length, props.defaultOpenPanelCount)); + } + }, [dataSource.length, field]); + if (!schema) throw new Error('can not found schema object'); - const renderItems = () => { - return ( - setActiveKeys(toArr(keys).map(Number))} - className={cls(`${prefixCls}-item`, props.className)} - > - {dataSource.map((item, index) => { - const items = Array.isArray(schema.items) ? schema.items[index] || schema.items[0] : schema.items; + const renderAddition = () => { + return schema.reduceProperties((addition, schema, key) => { + if (isAdditionComponent(schema)) { + return ; + } + return addition; + }, null); + }; + const renderEmpty = () => { + if (dataSource.length) return; + return ( + + + + ); + }; - const panelProps = field.query(`${field.address}.${index}`).get('componentProps'); - const props: CollapsePanelProps = items['x-component-props']; - const header = () => { - const header = `${panelProps?.header || props.header || field.title}`; - const path = field.address.concat(index); - const errors = field.form.queryFeedbacks({ - type: 'error', - address: `${path}.**`, - }); - return ( - field.value?.[index]}> + const renderItems = () => { + return ( + setActiveKeys(toArr(keys).map(Number))} + className={cls(`${prefixCls}-item`, props.className)} + > + {dataSource.map((item, index) => { + const items = Array.isArray(schema.items) ? schema.items[index] || schema.items[0] : schema.items; + + const panelProps = field.query(`${field.address}.${index}`).get('componentProps'); + const props: CollapsePanelProps = items['x-component-props']; + const header = () => { + const header = `${panelProps?.header || props.header || field.title}`; + const path = field.address.concat(index); + const errors = field.form.queryFeedbacks({ + type: 'error', + address: `${path}.**`, + }); + return ( + field.value?.[index]}> + { + if (!isIndexComponent(schema)) return false; + return true; + }} + onlyRenderProperties + /> + {errors.length ? ( + + {header} + + ) : ( + + )} + + ); + }; + + const extra = ( + { - if (!isIndexComponent(schema)) return false; + if (!isOperationComponent(schema)) return false; return true; }} onlyRenderProperties /> - {errors.length ? ( - - {header} - - ) : ( - - )} + {panelProps?.extra} ); - }; - const extra = ( - + const content = ( { - if (!isOperationComponent(schema)) return false; + if (isIndexComponent(schema)) return false; + if (isOperationComponent(schema)) return false; return true; }} - onlyRenderProperties /> - {panelProps?.extra} - - ); - - const content = ( - { - if (isIndexComponent(schema)) return false; - if (isOperationComponent(schema)) return false; - return true; - }} - /> - ); - return ( - - - {content} - - - ); - })} - + ); + return ( + + + {content} + + + ); + })} + + ); + }; + return ( + { + setActiveKeys(insertActiveKeys(activeKeys, index)); + }} + > + {renderEmpty()} + {renderItems()} + {renderAddition()} + ); - }; - return ( - { - setActiveKeys(insertActiveKeys(activeKeys, index)); - }} - > - {renderEmpty()} - {renderItems()} - {renderAddition()} - - ); -}); + }, + { displayName: 'ArrayCollapse' }, +); const CollapsePanel: React.FC> = ({ children }) => { return {children}; diff --git a/packages/core/client/src/schema-settings/DataTemplates/components/Designer.tsx b/packages/core/client/src/schema-settings/DataTemplates/components/Designer.tsx index 8412e4542..281eca7a3 100644 --- a/packages/core/client/src/schema-settings/DataTemplates/components/Designer.tsx +++ b/packages/core/client/src/schema-settings/DataTemplates/components/Designer.tsx @@ -13,143 +13,146 @@ import { removeNullCondition, useCompile, useDesignable } from '../../../schema- import { ITemplate } from '../../../schema-component/antd/form-v2/Templates'; import { FilterDynamicComponent } from '../../../schema-component/antd/table-v2/FilterDynamicComponent'; -export const Designer = observer(() => { - const { getCollectionFields, getCollectionField, getCollection } = useCollectionManager(); - const field = useField(); - const fieldSchema = useFieldSchema(); - const { t } = useTranslation(); - const { dn } = useDesignable(); - const compile = useCompile(); - const { formSchema, data } = fieldSchema['x-designer-props'] as { - formSchema: ISchema; - data?: ITemplate; - }; +export const Designer = observer( + () => { + const { getCollectionFields, getCollectionField, getCollection } = useCollectionManager(); + const field = useField(); + const fieldSchema = useFieldSchema(); + const { t } = useTranslation(); + const { dn } = useDesignable(); + const compile = useCompile(); + const { formSchema, data } = fieldSchema['x-designer-props'] as { + formSchema: ISchema; + data?: ITemplate; + }; - // 在这里读取 resource 的值,当 resource 变化时,会触发该组件的更新 - const collectionName = field.componentProps.service.resource; + // 在这里读取 resource 的值,当 resource 变化时,会触发该组件的更新 + const collectionName = field.componentProps.service.resource; - const collection = getCollection(collectionName); - const collectionFields = getCollectionFields(collectionName); - const dataSource = useCollectionFilterOptions(collectionName); + const collection = getCollection(collectionName); + const collectionFields = getCollectionFields(collectionName); + const dataSource = useCollectionFilterOptions(collectionName); - if (!data) { - error('data is required'); - return null; - } - - const getFilter = () => data.config?.[collectionName]?.filter || {}; - const setFilter = (filter) => { - try { - _.set(data, `config.${collectionName}.filter`, removeNullCondition(filter)); - } catch (err) { - error(err); + if (!data) { + error('data is required'); + return null; } - }; - const getTitleFIeld = () => data.config?.[collectionName]?.titleField || collection?.titleField || 'id'; - const setTitleField = (titleField) => { - try { - _.set(data, `config.${collectionName}.titleField`, titleField); - } catch (err) { - error(err); - } - }; - const options = collectionFields - .filter((field) => isTitleField(field)) - .map((field) => ({ - value: field?.name, - label: compile(field?.uiSchema?.title) || field?.name, - })); + const getFilter = () => data.config?.[collectionName]?.filter || {}; + const setFilter = (filter) => { + try { + _.set(data, `config.${collectionName}.filter`, removeNullCondition(filter)); + } catch (err) { + error(err); + } + }; + const getTitleFIeld = () => data.config?.[collectionName]?.titleField || collection?.titleField || 'id'; + const setTitleField = (titleField) => { + try { + _.set(data, `config.${collectionName}.titleField`, titleField); + } catch (err) { + error(err); + } + }; - return ( - - FilterDynamicComponent({ ...props }), + const options = collectionFields + .filter((field) => isTitleField(field)) + .map((field) => ({ + value: field?.name, + label: compile(field?.uiSchema?.title) || field?.name, + })); + + return ( + + FilterDynamicComponent({ ...props }), + }, }, }, - }, - } as ISchema - } - onSubmit={({ filter }) => { - setFilter(filter); - - try { - // 不仅更新当前模板,也更新同级的其它模板 - field.query('fieldReaction.items.*.layout.dataId').forEach((item) => { - if (item.componentProps.service.resource !== collectionName) { - return; - } - - item.componentProps.service.params = { - filter: _.isEmpty(filter) - ? {} - : removeNullCondition(mergeFilter([filter, getSelectedIdFilter(field.value)], '$or')), - }; - }); - } catch (err) { - error(err); + } as ISchema } - formSchema['x-data-templates'] = data; - dn.emit('patch', { - schema: { + onSubmit={({ filter }) => { + setFilter(filter); + + try { + // 不仅更新当前模板,也更新同级的其它模板 + field.query('fieldReaction.items.*.layout.dataId').forEach((item) => { + if (item.componentProps.service.resource !== collectionName) { + return; + } + + item.componentProps.service.params = { + filter: _.isEmpty(filter) + ? {} + : removeNullCondition(mergeFilter([filter, getSelectedIdFilter(field.value)], '$or')), + }; + }); + } catch (err) { + error(err); + } + formSchema['x-data-templates'] = data; + dn.emit('patch', { + schema: { + ['x-uid']: formSchema['x-uid'], + ['x-data-templates']: data, + }, + }); + dn.refresh(); + }} + /> + { + setTitleField(label); + + try { + // 不仅更新当前模板,也更新同级的其它模板 + field.query('fieldReaction.items.*.layout.dataId').forEach((item) => { + if (item.componentProps.service.resource !== collectionName) { + return; + } + + item.componentProps.fieldNames.label = label; + item.componentProps.targetField = getCollectionField( + `${collectionName}.${label || collection?.titleField || 'id'}`, + ); + }); + } catch (err) { + console.error(err); + } + formSchema['x-data-templates'] = data; + + const schema = { ['x-uid']: formSchema['x-uid'], ['x-data-templates']: data, - }, - }); - dn.refresh(); - }} - /> - { - setTitleField(label); + }; - try { - // 不仅更新当前模板,也更新同级的其它模板 - field.query('fieldReaction.items.*.layout.dataId').forEach((item) => { - if (item.componentProps.service.resource !== collectionName) { - return; - } - - item.componentProps.fieldNames.label = label; - item.componentProps.targetField = getCollectionField( - `${collectionName}.${label || collection?.titleField || 'id'}`, - ); + dn.emit('patch', { + schema, }); - } catch (err) { - console.error(err); - } - formSchema['x-data-templates'] = data; - - const schema = { - ['x-uid']: formSchema['x-uid'], - ['x-data-templates']: data, - }; - - dn.emit('patch', { - schema, - }); - dn.refresh(); - }} - /> - - ); -}); + dn.refresh(); + }} + /> + + ); + }, + { displayName: 'Designer' }, +); export function getSelectedIdFilter(selectedId) { return selectedId diff --git a/packages/core/client/src/schema-settings/EnableChildCollections/index.tsx b/packages/core/client/src/schema-settings/EnableChildCollections/index.tsx index 45b9c7080..f7d0a7d3a 100644 --- a/packages/core/client/src/schema-settings/EnableChildCollections/index.tsx +++ b/packages/core/client/src/schema-settings/EnableChildCollections/index.tsx @@ -4,103 +4,106 @@ import { action } from '@formily/reactive'; import { SchemaComponent, useCompile } from '../../schema-component'; import { useCollectionManager } from '../../collection-manager'; -export const EnableChildCollections = observer((props: any) => { - const { useProps } = props; - const { defaultValues, collectionName } = useProps(); - const form = useForm(); - const compile = useCompile(); - const { getChildrenCollections } = useCollectionManager(); - const childrenCollections = getChildrenCollections(collectionName); +export const EnableChildCollections = observer( + (props: any) => { + const { useProps } = props; + const { defaultValues, collectionName } = useProps(); + const form = useForm(); + const compile = useCompile(); + const { getChildrenCollections } = useCollectionManager(); + const childrenCollections = getChildrenCollections(collectionName); - const useAsyncDataSource = (service: any) => { - return (field: any, options?: any) => { - field.loading = true; - service(field, options).then( - action.bound((data: any) => { - field.dataSource = data; - field.loading = false; - if (field.initialValue) { - field.disabled = true; - } - }), - ); + const useAsyncDataSource = (service: any) => { + return (field: any, options?: any) => { + field.loading = true; + service(field, options).then( + action.bound((data: any) => { + field.dataSource = data; + field.loading = false; + if (field.initialValue) { + field.disabled = true; + } + }), + ); + }; }; - }; - const loadData = async (field) => { - const { childrenCollections: childCollections } = form.values?.enableChildren; - return childrenCollections - .filter((v) => { - return !childCollections.find((k) => k.collection === v.name) || field.initialValue || v.name === field.value; - }) - ?.map((collection: any) => ({ - label: compile(collection.title), - value: collection.name, - })); - }; - return ( - childrenCollections.find((k) => k.name === v.collection)), - 'x-component': 'ArrayItems', - 'x-decorator': 'FormItem', - items: { - type: 'object', - properties: { - space: { - type: 'void', - 'x-component': 'Space', - properties: { - sort: { - type: 'void', - 'x-decorator': 'FormItem', - 'x-component': 'ArrayItems.SortHandle', - }, - collection: { - type: 'string', - 'x-decorator': 'FormItem', - required: true, - 'x-component': 'Select', - 'x-component-props': { - style: { - width: 260, + const loadData = async (field) => { + const { childrenCollections: childCollections } = form.values?.enableChildren; + return childrenCollections + .filter((v) => { + return !childCollections.find((k) => k.collection === v.name) || field.initialValue || v.name === field.value; + }) + ?.map((collection: any) => ({ + label: compile(collection.title), + value: collection.name, + })); + }; + return ( + childrenCollections.find((k) => k.name === v.collection)), + 'x-component': 'ArrayItems', + 'x-decorator': 'FormItem', + items: { + type: 'object', + properties: { + space: { + type: 'void', + 'x-component': 'Space', + properties: { + sort: { + type: 'void', + 'x-decorator': 'FormItem', + 'x-component': 'ArrayItems.SortHandle', + }, + collection: { + type: 'string', + 'x-decorator': 'FormItem', + required: true, + 'x-component': 'Select', + 'x-component-props': { + style: { + width: 260, + }, + }, + 'x-reactions': ['{{useAsyncDataSource(loadData)}}'], + }, + title: { + type: 'string', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + 'x-component-props': { + style: { + width: 235, + }, }, }, - 'x-reactions': ['{{useAsyncDataSource(loadData)}}'], - }, - title: { - type: 'string', - 'x-decorator': 'FormItem', - 'x-component': 'Input', - 'x-component-props': { - style: { - width: 235, - }, + remove: { + type: 'void', + 'x-decorator': 'FormItem', + 'x-component': 'ArrayItems.Remove', }, }, - remove: { - type: 'void', - 'x-decorator': 'FormItem', - 'x-component': 'ArrayItems.Remove', - }, }, }, }, - }, - properties: { - add: { - type: 'void', - title: '{{ t("Add collection") }}', - 'x-component': 'ArrayItems.Addition', + properties: { + add: { + type: 'void', + title: '{{ t("Add collection") }}', + 'x-component': 'ArrayItems.Addition', + }, }, }, }, - }, - }} - scope={{ useAsyncDataSource, loadData }} - /> - ); -}); + }} + scope={{ useAsyncDataSource, loadData }} + /> + ); + }, + { displayName: 'EnableChildCollections' }, +); diff --git a/packages/core/client/src/schema-settings/LinkageRules/LinkageRuleAction.tsx b/packages/core/client/src/schema-settings/LinkageRules/LinkageRuleAction.tsx index 8d7b33d45..16df557ea 100644 --- a/packages/core/client/src/schema-settings/LinkageRules/LinkageRuleAction.tsx +++ b/packages/core/client/src/schema-settings/LinkageRules/LinkageRuleAction.tsx @@ -13,82 +13,131 @@ import { useValues } from './useValues'; import { ActionType } from './type'; import { ValueDynamicComponent } from './ValueDynamicComponent'; -export const FormFieldLinkageRuleAction = observer((props: any) => { - const { value, options, collectionName } = props; - const { t } = useTranslation(); - const compile = useCompile(); - const remove = useContext(RemoveActionContext); - const { - schema, - fields, - operator, - setDataIndex, - setOperator, - setValue, - value: fieldValue, - operators, - } = useValues(options); - return ( - -
    - { + const { value, options, collectionName } = props; + const { t } = useTranslation(); + const compile = useCompile(); + const remove = useContext(RemoveActionContext); + const { + schema, + fields, + operator, + setDataIndex, + setOperator, + setValue, + value: fieldValue, + operators, + } = useValues(options); + return ( + +
    - { - setDataIndex(value); - }} - placeholder={t('Select Field')} - /> + > + { + setDataIndex(value); + }} + placeholder={t('Select Field')} + /> + { + const flag = [ActionType.Value].includes(value); + setEditFlag(flag); setOperator(value); }} placeholder={t('action')} /> - {[ActionType.Value].includes(operator) && ( - - )} + {editFalg && + React.createElement(DynamicComponent, { + value, + schema, + onChange(value) { + setValue(value); + }, + })} {!props.disabled && ( remove()} style={{ color: '#bfbfbf' }} /> @@ -96,50 +145,7 @@ export const FormFieldLinkageRuleAction = observer((props: any) => { )}
    -
    - ); -}); - -export const FormButtonLinkageRuleAction = observer((props: any) => { - const { value, options } = props; - const { t } = useTranslation(); - const compile = useCompile(); - const [editFalg, setEditFlag] = useState(false); - const remove = useContext(RemoveActionContext); - const { schema, operator, setOperator, setValue } = useValues(options); - const operators = [ - { label: t('Visible'), value: ActionType.Visible, schema: {} }, - { label: t('Hidden'), value: ActionType.Hidden, schema: {} }, - { label: t('Disabled'), value: ActionType.Disabled, schema: {} }, - { label: t('Enabled'), value: ActionType.Active, schema: {} }, - ]; - return ( -
    - - setOpen(open)} - onSelect={() => { - setOpen(false); - }} - onChange={(value) => { - field.value = value; - }} - value={field.value} - options={field.dataSource} - style={{ width: '60%' }} - size={'small'} - bordered={false} - /> -
    - - ); -}); +SettingsForm.Select = observer( + (props) => { + const field = useField(); + const [open, setOpen] = useState(false); + return ( + !open && setOpen(true)}> +
    + {field.title} + -
    - ); -}); +export const SourceCollection = observer( + () => { + const { record } = useContext(GraphCollectionContext); + const compile = useCompile(); + return ( +
    + - -
    - ); -}); + return ( +
    + + + +
    + ); + }, + { displayName: 'RedirectURLInput' }, +); diff --git a/packages/plugins/saml/src/client/RedirectURLInput.tsx b/packages/plugins/saml/src/client/RedirectURLInput.tsx index 0ebfadba5..976077f11 100644 --- a/packages/plugins/saml/src/client/RedirectURLInput.tsx +++ b/packages/plugins/saml/src/client/RedirectURLInput.tsx @@ -5,23 +5,26 @@ import { observer, useField, useForm } from '@formily/react'; import { useEffect } from 'react'; import { Input, useRecord } from '@nocobase/client'; -export const RedirectURLInput = observer(() => { - const form = useForm(); - const field = useField(); - const record = useRecord(); +export const RedirectURLInput = observer( + () => { + const form = useForm(); + const field = useField(); + const record = useRecord(); - const clientId = form.values.clientId ?? record.clientId; + const clientId = form.values.clientId ?? record.clientId; - useEffect(() => { - const { protocol, host } = window.location; - field.setValue(`${protocol}//${host}/api/saml:redirect?clientId=${clientId}`); - }, [clientId]); + useEffect(() => { + const { protocol, host } = window.location; + field.setValue(`${protocol}//${host}/api/saml:redirect?clientId=${clientId}`); + }, [clientId]); - return ( -
    - - - -
    - ); -}); + return ( +
    + + + +
    + ); + }, + { displayName: 'RedirectURLInput' }, +); diff --git a/packages/plugins/snapshot-field/src/client/index.tsx b/packages/plugins/snapshot-field/src/client/index.tsx index 859a29af8..caef94573 100644 --- a/packages/plugins/snapshot-field/src/client/index.tsx +++ b/packages/plugins/snapshot-field/src/client/index.tsx @@ -14,7 +14,7 @@ import { SnapshotBlockInitializersDetailItem } from './SnapshotBlock/SnapshotBlo import { SnapshotBlockProvider } from './SnapshotBlock/SnapshotBlockProvider'; import { SnapshotRecordPicker } from './SnapshotRecordPicker'; -export default React.memo((props) => { +const SnapshotField = React.memo((props) => { useEffect(() => { registerField(snapshot.group, snapshot.name as string, snapshot); }, []); @@ -47,3 +47,6 @@ export default React.memo((props) => { ); }); +SnapshotField.displayName = 'SnapshotField'; + +export default SnapshotField; diff --git a/packages/plugins/ui-schema-storage/package.json b/packages/plugins/ui-schema-storage/package.json index ef063d4fc..6083b49bb 100644 --- a/packages/plugins/ui-schema-storage/package.json +++ b/packages/plugins/ui-schema-storage/package.json @@ -9,7 +9,7 @@ "main": "./lib/index.js", "types": "./lib/index.d.ts", "devDependencies": { - "@formily/json-schema": "2.0.20", + "@formily/json-schema": "2.2.24", "@nocobase/test": "0.9.4-alpha.2" }, "gitHead": "ce588eefb0bfc50f7d5bbee575e0b5e843bf6644" diff --git a/packages/plugins/verification/src/client/ProviderOptions.tsx b/packages/plugins/verification/src/client/ProviderOptions.tsx index 74e6d8607..68907db6d 100644 --- a/packages/plugins/verification/src/client/ProviderOptions.tsx +++ b/packages/plugins/verification/src/client/ProviderOptions.tsx @@ -5,17 +5,27 @@ import { observer, RecursionField, Schema, useField, useForm } from '@formily/re import providerTypes from './providerTypes'; -export default observer((props) => { - const form = useForm(); - const field = useField(); - const [s, setSchema] = useState(new Schema({})); - useEffect(() => { - form.clearFormGraph('options.*'); - setSchema(new Schema(providerTypes.get(form.values.type) || {})); - }, [form.values.type]); - return ( - - - - ); -}); +const Verification = observer( + (props) => { + const form = useForm(); + const field = useField(); + const [s, setSchema] = useState(new Schema({})); + useEffect(() => { + form.clearFormGraph('options.*'); + setSchema(new Schema(providerTypes.get(form.values.type) || {})); + }, [form.values.type]); + return ( + + + + ); + }, + { displayName: 'Verification' }, +); + +export default Verification; diff --git a/packages/plugins/workflow/src/client/components/CollectionFieldset.tsx b/packages/plugins/workflow/src/client/components/CollectionFieldset.tsx index 0d2b0c499..65319bed0 100644 --- a/packages/plugins/workflow/src/client/components/CollectionFieldset.tsx +++ b/packages/plugins/workflow/src/client/components/CollectionFieldset.tsx @@ -33,118 +33,123 @@ function AssociationInput(props) { } // NOTE: observer for watching useProps -export default observer(({ value, disabled, onChange }: any) => { - const { t } = useTranslation(); - const compile = useCompile(); - const form = useForm(); - const { getCollection, getCollectionFields } = useCollectionManager(); - const { values: config } = useForm(); - const collectionName = config?.collection; - const fields = getCollectionFields(collectionName).filter( - (field) => - !field.hidden && - (field.uiSchema ? !field.uiSchema['x-read-pretty'] : false) && - // TODO: should use some field option but not type to control this - !['formula'].includes(field.type), - ); +const CollectionFieldSet = observer( + ({ value, disabled, onChange }: any) => { + const { t } = useTranslation(); + const compile = useCompile(); + const form = useForm(); + const { getCollection, getCollectionFields } = useCollectionManager(); + const { values: config } = useForm(); + const collectionName = config?.collection; + const fields = getCollectionFields(collectionName).filter( + (field) => + !field.hidden && + (field.uiSchema ? !field.uiSchema['x-read-pretty'] : false) && + // TODO: should use some field option but not type to control this + !['formula'].includes(field.type), + ); - const unassignedFields = fields.filter((field) => !value || !(field.name in value)); - const scope = useWorkflowVariableOptions(); - const mergedDisabled = disabled || form.disabled; + const unassignedFields = fields.filter((field) => !value || !(field.name in value)); + const scope = useWorkflowVariableOptions(); + const mergedDisabled = disabled || form.disabled; - return ( -
    .ant-formily-item { - flex-direction: column; + > .ant-formily-item { + flex-direction: column; - > .ant-formily-item-label { - line-height: 32px; + > .ant-formily-item-label { + line-height: 32px; + } } - } - `} - > - {fields.length ? ( - - {fields - .filter((field) => value && field.name in value) - .map((field) => { - // constant for associations to use Input, others to use CollectionField - // dynamic values only support belongsTo/hasOne association, other association type should disable - const ConstantCompoent = ['belongsTo', 'hasOne', 'hasMany', 'belongsToMany'].includes(field.type) - ? AssociationInput - : CollectionField; - // TODO: try to use to replace this map - return ( - - { - onChange({ ...value, [field.name]: next }); - }} + `} + > + {fields.length ? ( + + {fields + .filter((field) => value && field.name in value) + .map((field) => { + // constant for associations to use Input, others to use CollectionField + // dynamic values only support belongsTo/hasOne association, other association type should disable + const ConstantCompoent = ['belongsTo', 'hasOne', 'hasMany', 'belongsToMany'].includes(field.type) + ? AssociationInput + : CollectionField; + // TODO: try to use to replace this map + return ( + - { + onChange({ ...value, [field.name]: next }); + }} + > + - - {!mergedDisabled ? ( - - - ) : null} - - ) : ( -

    {lang('Please select collection first')}

    - )} -
    - ); -}); + }} + /> + + {!mergedDisabled ? ( + + + ) : null} + + ) : ( +

    {lang('Please select collection first')}

    + )} + + ); + }, + { displayName: 'CollectionFieldSet' }, +); + +export default CollectionFieldSet; diff --git a/packages/plugins/workflow/src/client/components/DynamicExpression.tsx b/packages/plugins/workflow/src/client/components/DynamicExpression.tsx index 3603385db..8eb852294 100644 --- a/packages/plugins/workflow/src/client/components/DynamicExpression.tsx +++ b/packages/plugins/workflow/src/client/components/DynamicExpression.tsx @@ -9,25 +9,28 @@ import { useRecord, Variable } from '@nocobase/client'; import { NAMESPACE } from '../locale'; import { useCollectionFieldOptions } from '../variable'; -const InternalExpression = observer((props: any) => { - const { onChange } = props; - const { values } = useForm(); - const [collection, setCollection] = useState(values?.sourceCollection); +const InternalExpression = observer( + (props: any) => { + const { onChange } = props; + const { values } = useForm(); + const [collection, setCollection] = useState(values?.sourceCollection); - useFormEffects(() => { - onFormInitialValuesChange((form) => { - setCollection(form.values.sourceCollection); + useFormEffects(() => { + onFormInitialValuesChange((form) => { + setCollection(form.values.sourceCollection); + }); + onFieldInputValueChange('sourceCollection', (f) => { + setCollection(f.value); + onChange(null); + }); }); - onFieldInputValueChange('sourceCollection', (f) => { - setCollection(f.value); - onChange(null); - }); - }); - const options = useCollectionFieldOptions({ collection: collection }); + const options = useCollectionFieldOptions({ collection: collection }); - return ; -}); + return ; + }, + { displayName: 'InternalExpression' }, +); function Result(props) { const { t } = useTranslation(); diff --git a/packages/plugins/workflow/src/client/components/FieldsSelect.tsx b/packages/plugins/workflow/src/client/components/FieldsSelect.tsx index f44442025..968e2dae5 100644 --- a/packages/plugins/workflow/src/client/components/FieldsSelect.tsx +++ b/packages/plugins/workflow/src/client/components/FieldsSelect.tsx @@ -4,22 +4,25 @@ import { observer, useForm } from '@formily/react'; import { useCollectionManager, useCompile } from '@nocobase/client'; -export const FieldsSelect = observer((props: any) => { - const { filter = () => true, ...others } = props; - const compile = useCompile(); - const { getCollectionFields } = useCollectionManager(); - const { values } = useForm(); - const fields = getCollectionFields(values?.collection); +export const FieldsSelect = observer( + (props: any) => { + const { filter = () => true, ...others } = props; + const compile = useCompile(); + const { getCollectionFields } = useCollectionManager(); + const { values } = useForm(); + const fields = getCollectionFields(values?.collection); - return ( - ({ + label: compile(field.uiSchema?.title), + value: field.name, + }))} + /> + ); + }, + { displayName: 'FieldsSelect' }, +); diff --git a/packages/plugins/workflow/src/client/nodes/manual/WorkflowTodo.tsx b/packages/plugins/workflow/src/client/nodes/manual/WorkflowTodo.tsx index 476359a4d..fa1688c02 100644 --- a/packages/plugins/workflow/src/client/nodes/manual/WorkflowTodo.tsx +++ b/packages/plugins/workflow/src/client/nodes/manual/WorkflowTodo.tsx @@ -184,20 +184,29 @@ const todoCollection = { ], }; -const NodeColumn = observer(() => { - const field = useField(); - return field?.value?.title ?? `#${field.value?.id}`; -}); +const NodeColumn = observer( + () => { + const field = useField(); + return field?.value?.title ?? `#${field.value?.id}`; + }, + { displayName: 'NodeColumn' }, +); -const WorkflowColumn = observer(() => { - const field = useField(); - return field?.value?.title ?? `#${field.value?.id}`; -}); +const WorkflowColumn = observer( + () => { + const field = useField(); + return field?.value?.title ?? `#${field.value?.id}`; + }, + { displayName: 'WorkflowColumn' }, +); -const UserColumn = observer(() => { - const field = useField(); - return field?.value?.nickname ?? field.value?.id; -}); +const UserColumn = observer( + () => { + const field = useField(); + return field?.value?.nickname ?? field.value?.id; + }, + { displayName: 'UserColumn' }, +); export const WorkflowTodo: React.FC & { Drawer: React.FC; Decorator: React.FC } = () => { return ( diff --git a/packages/plugins/workflow/src/client/triggers/schedule/DateFieldsSelect.tsx b/packages/plugins/workflow/src/client/triggers/schedule/DateFieldsSelect.tsx index 22ff18cc4..d9d24401f 100644 --- a/packages/plugins/workflow/src/client/triggers/schedule/DateFieldsSelect.tsx +++ b/packages/plugins/workflow/src/client/triggers/schedule/DateFieldsSelect.tsx @@ -5,22 +5,25 @@ import { useTranslation } from 'react-i18next'; import { useCollectionManager, useCompile } from '@nocobase/client'; -export const DateFieldsSelect: React.FC = observer((props) => { - const { t } = useTranslation(); - const compile = useCompile(); - const { getCollectionFields } = useCollectionManager(); - const { values } = useForm(); - const fields = getCollectionFields(values?.collection); +export const DateFieldsSelect: React.FC = observer( + (props) => { + const { t } = useTranslation(); + const compile = useCompile(); + const { getCollectionFields } = useCollectionManager(); + const { values } = useForm(); + const fields = getCollectionFields(values?.collection); - return ( - - ); -}); + return ( + + ); + }, + { displayName: 'DateFieldsSelect' }, +); diff --git a/packages/samples/command/src/client/index.tsx b/packages/samples/command/src/client/index.tsx index db735f78d..803e7ab47 100644 --- a/packages/samples/command/src/client/index.tsx +++ b/packages/samples/command/src/client/index.tsx @@ -1,5 +1,8 @@ import React from 'react'; -export default React.memo((props) => { +const CommandMemo = React.memo((props) => { return <>{props.children}; }); +CommandMemo.displayName = 'CommandMemo'; + +export default CommandMemo; diff --git a/packages/samples/custom-block/src/client/index.tsx b/packages/samples/custom-block/src/client/index.tsx index 776c681a8..a3e714480 100644 --- a/packages/samples/custom-block/src/client/index.tsx +++ b/packages/samples/custom-block/src/client/index.tsx @@ -30,7 +30,7 @@ export const HelloBlockInitializer = (props) => { ); }; -export default React.memo((props) => { +const CustomBlock = React.memo((props) => { const items = useContext(SchemaInitializerContext); const children = items.BlockInitializers.items[2].children; children.push({ @@ -45,3 +45,6 @@ export default React.memo((props) => { ); }); +CustomBlock.displayName = 'CustomBlock'; + +export default CustomBlock; diff --git a/packages/samples/custom-collection-template/src/client/index.tsx b/packages/samples/custom-collection-template/src/client/index.tsx index 5b8615b3a..4d2090b88 100644 --- a/packages/samples/custom-collection-template/src/client/index.tsx +++ b/packages/samples/custom-collection-template/src/client/index.tsx @@ -47,6 +47,9 @@ const myCollectionTemplate: ICollectionTemplate = { registerTemplate('myCollection', myCollectionTemplate); -export default React.memo((props) => { +const CustomCollectionTemplateMemo = React.memo((props) => { return <>{props.children}; }); +CustomCollectionTemplateMemo.displayName = 'CustomCollectionTemplateMemo'; + +export default CustomCollectionTemplateMemo; diff --git a/packages/samples/custom-page/src/client/index.tsx b/packages/samples/custom-page/src/client/index.tsx index 289a2fcbd..d5eee3808 100644 --- a/packages/samples/custom-page/src/client/index.tsx +++ b/packages/samples/custom-page/src/client/index.tsx @@ -5,7 +5,7 @@ const HelloWorld = () => { return
    Hello ui router
    ; }; -export default React.memo((props) => { +const CustomPage = React.memo((props) => { const ctx = useContext(RouteSwitchContext); ctx.routes.push({ type: 'route', @@ -14,3 +14,6 @@ export default React.memo((props) => { }); return {props.children}; }); +CustomPage.displayName = 'CustomPage'; + +export default CustomPage; diff --git a/packages/samples/custom-signup-page/src/client/index.tsx b/packages/samples/custom-signup-page/src/client/index.tsx index 349c565aa..58a6d7d72 100644 --- a/packages/samples/custom-signup-page/src/client/index.tsx +++ b/packages/samples/custom-signup-page/src/client/index.tsx @@ -23,7 +23,7 @@ const CustomSignupPage = (props) => { ); }; -export default React.memo((props) => { +const CustomSignupPageMemo = React.memo((props) => { const ctx = useContext(RouteSwitchContext); return ( @@ -31,3 +31,6 @@ export default React.memo((props) => { ); }); +CustomSignupPageMemo.displayName = 'CustomSignupPageMemo'; + +export default CustomSignupPageMemo; diff --git a/packages/samples/hello/src/client/index.tsx b/packages/samples/hello/src/client/index.tsx index 38ef3b388..20acb70b5 100644 --- a/packages/samples/hello/src/client/index.tsx +++ b/packages/samples/hello/src/client/index.tsx @@ -36,7 +36,7 @@ export const HelloBlockInitializer = (props) => { ); }; -export default React.memo((props) => { +const Hello = React.memo((props) => { const items = useContext(SchemaInitializerContext); const children = items.BlockInitializers.items[1].children; children.push({ @@ -66,3 +66,6 @@ export default React.memo((props) => { ); }); +Hello.displayName = 'Hello'; + +export default Hello; diff --git a/packages/samples/ratelimit/src/client/index.tsx b/packages/samples/ratelimit/src/client/index.tsx index db735f78d..9e38157ed 100644 --- a/packages/samples/ratelimit/src/client/index.tsx +++ b/packages/samples/ratelimit/src/client/index.tsx @@ -1,5 +1,8 @@ import React from 'react'; -export default React.memo((props) => { +const RateLimit = React.memo((props) => { return <>{props.children}; }); +RateLimit.displayName = 'RateLimit'; + +export default RateLimit; diff --git a/packages/samples/shop-actions/src/client/index.tsx b/packages/samples/shop-actions/src/client/index.tsx index db735f78d..8379cd12b 100644 --- a/packages/samples/shop-actions/src/client/index.tsx +++ b/packages/samples/shop-actions/src/client/index.tsx @@ -1,5 +1,8 @@ import React from 'react'; -export default React.memo((props) => { +const ShopActions = React.memo((props) => { return <>{props.children}; }); +ShopActions.displayName = 'ShopActions'; + +export default ShopActions; diff --git a/packages/samples/shop-events/src/client/index.tsx b/packages/samples/shop-events/src/client/index.tsx index db735f78d..c054f9d35 100644 --- a/packages/samples/shop-events/src/client/index.tsx +++ b/packages/samples/shop-events/src/client/index.tsx @@ -1,5 +1,8 @@ import React from 'react'; -export default React.memo((props) => { +const ShopEvents = React.memo((props) => { return <>{props.children}; }); +ShopEvents.displayName = 'ShopEvents'; + +export default ShopEvents; diff --git a/packages/samples/shop-i18n/src/client/index.tsx b/packages/samples/shop-i18n/src/client/index.tsx index 82afa0a1f..d72911be4 100644 --- a/packages/samples/shop-i18n/src/client/index.tsx +++ b/packages/samples/shop-i18n/src/client/index.tsx @@ -59,7 +59,7 @@ export const ShopShortcut = () => { ); }; -export default React.memo((props) => { +const ShopI18n = React.memo((props) => { const ctx = useContext(PluginManagerContext); const { routes, components, ...others } = useContext(RouteSwitchContext); @@ -93,3 +93,5 @@ export default React.memo((props) => { ); }); + +export default ShopI18n; diff --git a/packages/samples/shop-modeling/src/client/index.tsx b/packages/samples/shop-modeling/src/client/index.tsx index db735f78d..81f5550c4 100644 --- a/packages/samples/shop-modeling/src/client/index.tsx +++ b/packages/samples/shop-modeling/src/client/index.tsx @@ -1,5 +1,8 @@ import React from 'react'; -export default React.memo((props) => { +const ShopModeling = React.memo((props) => { return <>{props.children}; }); +ShopModeling.displayName = 'ShopModeling'; + +export default ShopModeling; diff --git a/yarn.lock b/yarn.lock index c723dd95b..1e6104778 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3107,100 +3107,85 @@ version "8.39.0" resolved "https://registry.npmjs.org/@eslint/js/-/js-8.39.0.tgz#58b536bcc843f4cd1e02a7e6171da5c040f4d44b" -"@formily/antd@2.0.20": - version "2.0.20" - resolved "https://registry.yarnpkg.com/@formily/antd/-/antd-2.0.20.tgz#8a60ce0473ffa55df63c911a4e11330dd0ddfe2b" +"@formily/antd@2.2.24": + version "2.2.24" + resolved "https://registry.yarnpkg.com/@formily/antd/-/antd-2.2.24.tgz#d536cba6d4691b9c2089efd818cb85681a6d4c9b" + integrity sha512-jMrbg63FMQvkwT+y4mum2DE2mRlSuqwd1cuvWiUsH2RkaQM/SQhVdwigIsKFwzj69ujN75IeQCmAhZJIBFoLvQ== dependencies: - "@formily/core" "2.0.20" - "@formily/grid" "2.0.20" - "@formily/json-schema" "2.0.20" - "@formily/react" "2.0.20" - "@formily/reactive" "2.0.20" - "@formily/reactive-react" "2.0.20" - "@formily/shared" "2.0.20" + "@formily/core" "2.2.24" + "@formily/grid" "2.2.24" + "@formily/json-schema" "2.2.24" + "@formily/react" "2.2.24" + "@formily/reactive" "2.2.24" + "@formily/reactive-react" "2.2.24" + "@formily/shared" "2.2.24" classnames "^2.2.6" react-sortable-hoc "^1.11.0" react-sticky-box "^0.9.3" -"@formily/core@2.0.20": - version "2.0.20" - resolved "https://registry.yarnpkg.com/@formily/core/-/core-2.0.20.tgz#a8e8ea74e60d55c4ac61afb467084dcae4948049" +"@formily/core@2.2.24": + version "2.2.24" + resolved "https://registry.yarnpkg.com/@formily/core/-/core-2.2.24.tgz#b96b72def806ee4c71c0a0279b678ffcc23828bf" + integrity sha512-FjyhtSwSxSK18C5L+D2U2uqkVh5J0BnWmk/OyvOGNoQ3gdCHJFyH8gr6NNt11B8xL2oXKIEpaC0nw8iOcGf8eA== dependencies: - "@formily/reactive" "2.0.20" - "@formily/shared" "2.0.20" - "@formily/validator" "2.0.20" + "@formily/reactive" "2.2.24" + "@formily/shared" "2.2.24" + "@formily/validator" "2.2.24" -"@formily/core@2.2.21": - version "2.2.21" - resolved "https://registry.yarnpkg.com/@formily/core/-/core-2.2.21.tgz#fc2a34284f59dce34b985e96ef3092a0648c1f3c" +"@formily/grid@2.2.24": + version "2.2.24" + resolved "https://registry.yarnpkg.com/@formily/grid/-/grid-2.2.24.tgz#e5e1163ef9597a4417fc2f2f4e438d48c0d3dd59" + integrity sha512-w0IWWYDG8NwzdrLRsbUkX/L5OuFATTwyJc+tswtxVi2nrF9hZeHSYwvMh4dBI9rF2l0LKORvnVnk1O/kufnWug== dependencies: - "@formily/reactive" "2.2.21" - "@formily/shared" "2.2.21" - "@formily/validator" "2.2.21" - -"@formily/grid@2.0.20": - version "2.0.20" - resolved "https://registry.yarnpkg.com/@formily/grid/-/grid-2.0.20.tgz#76a0cabebf9d98f5169f60864cfa29c0204c0088" - dependencies: - "@formily/reactive" "2.0.20" + "@formily/reactive" "2.2.24" "@juggle/resize-observer" "^3.3.1" -"@formily/json-schema@2.0.20": - version "2.0.20" - resolved "https://registry.yarnpkg.com/@formily/json-schema/-/json-schema-2.0.20.tgz#1432fba50277e431074eaf96551e162a3528c560" +"@formily/json-schema@2.2.24": + version "2.2.24" + resolved "https://registry.yarnpkg.com/@formily/json-schema/-/json-schema-2.2.24.tgz#b23b9ae18a24fbcb716cd0e23677c8597abc5689" + integrity sha512-3aEMEO5D0B1p5rM/lzWmhx3rYqid4OKzCXAdxBsyicacFK9dVqxlOBt8d6auOsppMZ675q52jSVDxNSgh4xKqg== dependencies: - "@formily/core" "2.0.20" - "@formily/reactive" "2.0.20" - "@formily/shared" "2.0.20" + "@formily/core" "2.2.24" + "@formily/reactive" "2.2.24" + "@formily/shared" "2.2.24" -"@formily/json-schema@^2.0.15": - version "2.2.21" - resolved "https://registry.yarnpkg.com/@formily/json-schema/-/json-schema-2.2.21.tgz#6765dbafd391ac6d642c824ed9c7548ee7e9421f" +"@formily/path@2.2.24": + version "2.2.24" + resolved "https://registry.yarnpkg.com/@formily/path/-/path-2.2.24.tgz#1c15352dc72f78ef3e8924633a9d8a8182364d6b" + integrity sha512-DrRBIPvlqGr7+xQ/74MY/j7WSbUzvWeHOsjfXTIllbijKAdUm+DovpQuHMXR16I3gnuQ8CvyMzCizP9RKVnhzw== + +"@formily/react@2.2.24": + version "2.2.24" + resolved "https://registry.yarnpkg.com/@formily/react/-/react-2.2.24.tgz#415ca8df2c445ba43fe596d0a6e8bd4236abe8d6" + integrity sha512-Bq5LQzK9u0E8BBwHqWY1jXtbdVAJV/gMkZAssAHVXu01YvDUVugHXcbxuzKZKY5MrZFIyM7Jod0TbhjEPr2bhA== dependencies: - "@formily/core" "2.2.21" - "@formily/reactive" "2.2.21" - "@formily/shared" "2.2.21" - -"@formily/path@2.0.20": - version "2.0.20" - resolved "https://registry.yarnpkg.com/@formily/path/-/path-2.0.20.tgz#1047cb1737d1878182427bdbebf69a86be8b414f" - -"@formily/path@2.2.21": - version "2.2.21" - resolved "https://registry.yarnpkg.com/@formily/path/-/path-2.2.21.tgz#55b0844dbfb65b1beee1a34525042b575cc7b7f6" - -"@formily/react@2.0.20": - version "2.0.20" - resolved "https://registry.yarnpkg.com/@formily/react/-/react-2.0.20.tgz#57d9be728a2a297e11ba1def0da28915707c8d0d" - dependencies: - "@formily/core" "2.0.20" - "@formily/json-schema" "2.0.20" - "@formily/reactive" "2.0.20" - "@formily/reactive-react" "2.0.20" - "@formily/shared" "2.0.20" - "@formily/validator" "2.0.20" + "@formily/core" "2.2.24" + "@formily/json-schema" "2.2.24" + "@formily/reactive" "2.2.24" + "@formily/reactive-react" "2.2.24" + "@formily/shared" "2.2.24" + "@formily/validator" "2.2.24" hoist-non-react-statics "^3.3.2" -"@formily/reactive-react@2.0.20": - version "2.0.20" - resolved "https://registry.yarnpkg.com/@formily/reactive-react/-/reactive-react-2.0.20.tgz#63ec73aca01f3a8de5ef6e18f07e80b7b72551f8" +"@formily/reactive-react@2.2.24": + version "2.2.24" + resolved "https://registry.yarnpkg.com/@formily/reactive-react/-/reactive-react-2.2.24.tgz#187e6f07b1aab09f41134c4335200b38afdcc67c" + integrity sha512-MSS2ug+19+GzVJFhWjwOp6QWe/Bc3xC9YXYB7lfriJBQCC5lGlX0xaOZNkOH4yFz9OvSR59wwManOpOh329/EQ== dependencies: - "@formily/reactive" "2.0.20" + "@formily/reactive" "2.2.24" hoist-non-react-statics "^3.3.2" -"@formily/reactive@2.0.20": - version "2.0.20" - resolved "https://registry.yarnpkg.com/@formily/reactive/-/reactive-2.0.20.tgz#e8701a49e94bb53c362da945170c6eeffe931540" +"@formily/reactive@2.2.24": + version "2.2.24" + resolved "https://registry.yarnpkg.com/@formily/reactive/-/reactive-2.2.24.tgz#758b0fb26568970cbd326e1abb86f0264713f0c1" + integrity sha512-b3+43v7pmUCC8C57XO27M0x+2aE8k6lNndaOuo15Du+tLQyr+g+JBpEZsbIJfy9ScgdK6mIttxIhJiU+xUAmvg== -"@formily/reactive@2.2.21": - version "2.2.21" - resolved "https://registry.yarnpkg.com/@formily/reactive/-/reactive-2.2.21.tgz#f39eeb13bee086d2a85feab73f5b8eb4bb01e462" - -"@formily/shared@2.0.20": - version "2.0.20" - resolved "https://registry.yarnpkg.com/@formily/shared/-/shared-2.0.20.tgz#8d638598ade03a07e67fb66ebb7de2ba0bb57248" +"@formily/shared@2.2.24": + version "2.2.24" + resolved "https://registry.yarnpkg.com/@formily/shared/-/shared-2.2.24.tgz#f7939d8a36796db7fce580c2e6c52d04fed1b13b" + integrity sha512-PU3gBgbybSU6yv/Act2fn5sYnYTuiVJtpiYEMQGyn7wuWguOQfOpIkuaVim4h64PARO8WmnjENeDl5R5evgIYQ== dependencies: - "@formily/path" "2.0.20" + "@formily/path" "2.2.24" camel-case "^4.1.1" lower-case "^2.0.1" no-case "^3.0.4" @@ -3208,29 +3193,12 @@ pascal-case "^3.1.1" upper-case "^2.0.1" -"@formily/shared@2.2.21": - version "2.2.21" - resolved "https://registry.yarnpkg.com/@formily/shared/-/shared-2.2.21.tgz#01fbdb9fcf92516a17d4afec204cb10936aaf533" +"@formily/validator@2.2.24": + version "2.2.24" + resolved "https://registry.yarnpkg.com/@formily/validator/-/validator-2.2.24.tgz#03fc909fe93694e895d73e6d9e445a9f89bc1d51" + integrity sha512-EDZiArnLdDbp2k7/PHknjkX5FgsJXoqWbBrrhXCyzwC2ebBG4VTxWZUB+MWGT17A77Tl7xPsY7JPpJohcuQ+4Q== dependencies: - "@formily/path" "2.2.21" - camel-case "^4.1.1" - lower-case "^2.0.1" - no-case "^3.0.4" - param-case "^3.0.4" - pascal-case "^3.1.1" - upper-case "^2.0.1" - -"@formily/validator@2.0.20": - version "2.0.20" - resolved "https://registry.yarnpkg.com/@formily/validator/-/validator-2.0.20.tgz#956c612603fe87430efd6193fe683803f0b22b30" - dependencies: - "@formily/shared" "2.0.20" - -"@formily/validator@2.2.21": - version "2.2.21" - resolved "https://registry.yarnpkg.com/@formily/validator/-/validator-2.2.21.tgz#661d45c9cf1eeac44cb23e5ed03009cfa8548e4a" - dependencies: - "@formily/shared" "2.2.21" + "@formily/shared" "2.2.24" "@formulajs/formulajs@4.2.0", "@formulajs/formulajs@^4.2.0": version "4.2.0"