diff --git a/packages/core/client/.dumirc.ts b/packages/core/client/.dumirc.ts index ae514893b..dd0c2198e 100644 --- a/packages/core/client/.dumirc.ts +++ b/packages/core/client/.dumirc.ts @@ -179,12 +179,8 @@ export default defineConfig({ title: 'DataBlock', type: 'group', children: [ - // { - // title: '临时', - // link: '/core/data-block/tmp', - // }, { - title: 'Record', + title: 'CollectionRecord', link: '/core/data-block/collection-record', }, { diff --git a/packages/core/client/docs/en-US/core/data-block/tmp-demos/collections.ts b/packages/core/client/docs/en-US/core/data-block/tmp-demos/collections.ts deleted file mode 100644 index 82ba795b8..000000000 --- a/packages/core/client/docs/en-US/core/data-block/tmp-demos/collections.ts +++ /dev/null @@ -1,128 +0,0 @@ -export const mainCollections = [ - { - name: 'users', - title: 'Users', - fields: [ - { - key: 'id', - name: 'id', - interface: 'id', - primaryKey: true, - uiSchema: { - type: 'number', - title: 'ID', - 'x-component': 'InputNumber', - 'x-read-pretty': true, - rawTitle: 'ID', - }, - }, - { - uiSchema: { - type: 'string', - title: 'Nickname', - 'x-component': 'Input', - }, - name: 'nickname', - type: 'string', - interface: 'input', - }, - { - uiSchema: { - type: 'string', - title: 'Email', - 'x-component': 'Input', - required: true, - }, - key: 'rrskwjl5wt1', - name: 'email', - type: 'string', - interface: 'email', - unique: true, - }, - { - name: 'favoriteColor', - type: 'string', - interface: 'color', - uiSchema: { - type: 'string', - 'x-component': 'ColorPicker', - default: '#1677FF', - title: 'Favorite Color', - }, - }, - ], - }, - { - name: 'roles', - title: 'Roles', - fields: [ - { - uiSchema: { - type: 'string', - title: 'Role UID', - 'x-component': 'Input', - }, - name: 'name', - type: 'uid', - interface: 'input', - primaryKey: true, - }, - { - uiSchema: { - type: 'string', - title: 'Role name', - 'x-component': 'Input', - }, - name: 'title', - type: 'string', - interface: 'input', - }, - { - name: 'description', - type: 'string', - }, - ], - }, -]; - -export const TestDBCollections = [ - { - name: 'test1', - title: 'Test1', - fields: [ - { - name: 'id', - interface: 'id', - primaryKey: true, - uiSchema: { - type: 'number', - title: 'ID', - 'x-component': 'InputNumber', - 'x-read-pretty': true, - }, - }, - { - name: 'field1', - interface: 'input', - uiSchema: { - type: 'string', - 'x-component': 'Input', - title: 'Field1', - }, - }, - { - name: 'field2', - interface: 'number', - uiSchema: { - 'x-component-props': { - step: '1', - stringMode: true, - }, - 'x-component': 'InputNumber', - title: 'Field2', - }, - defaultValue: 1, - }, - ], - }, -]; diff --git a/packages/core/client/docs/en-US/core/data-block/tmp-demos/createApp.tsx b/packages/core/client/docs/en-US/core/data-block/tmp-demos/createApp.tsx deleted file mode 100644 index ebbc8ec12..000000000 --- a/packages/core/client/docs/en-US/core/data-block/tmp-demos/createApp.tsx +++ /dev/null @@ -1 +0,0 @@ -import { Application } from '@nocobase/client'; diff --git a/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo1.tsx b/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo1.tsx deleted file mode 100644 index 8c3f6a54f..000000000 --- a/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo1.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { Table } from 'antd'; -import React from 'react'; - -const MyTable = () => { - const dataSource = [ - { - key: '1', - name: 'Mike', - age: 32, - address: '10 Downing Street', - }, - { - key: '2', - name: 'John', - age: 42, - address: '10 Downing Street', - }, - ]; - - const columns = [ - { - title: 'Name', - dataIndex: 'name', - key: 'name', - }, - { - title: 'Age', - dataIndex: 'age', - key: 'age', - }, - { - title: 'Address', - dataIndex: 'address', - key: 'address', - }, - ]; - - return ; -}; - -export default MyTable; diff --git a/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo10.tsx b/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo10.tsx deleted file mode 100644 index 844315f33..000000000 --- a/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo10.tsx +++ /dev/null @@ -1,412 +0,0 @@ -import { Button, Drawer, Space, Table, TableProps } from 'antd'; -import React, { useEffect, useMemo, useState } from 'react'; -import { - CardItem, - CollectionField, - ColorFieldInterface, - ColorPicker, - DataBlockProvider, - EmailFieldInterface, - FormItem, - IdFieldInterface, - Input, - InputFieldInterface, - InputNumber, - NumberFieldInterface, - Plugin, - SchemaComponent, - SchemaInitializer, - SchemaInitializerItem, - SchemaSettings, - SchemaToolbar, - useCollection, - useCompile, - useDataBlock, - useDataBlockProps, - useDataBlockRequest, - useDataSourceManager, - useSchemaInitializer, - useSchemaInitializerRender, - useSchemaToolbar, - useSchemaToolbarRender, - withDynamicSchemaProps, -} from '@nocobase/client'; -import { Application } from '@nocobase/client'; -import { uid } from '@formily/shared'; -import { ISchema, RecursionField, Schema, observer, useField, useFieldSchema } from '@formily/react'; -import { mainCollections, TestDBCollections } from './collections'; -import { mock } from './mockData'; - -const MyTable = withDynamicSchemaProps(Table, { displayName: 'MyTable' }); - -const TableColumn = observer(() => { - const field = useField(); - return
{field.title}
; -}); - -function useTableProps(): TableProps { - const { tableProps } = useDataBlockProps(); - const { data, loading } = useDataBlockRequest(); - const dataSource = useMemo(() => data?.data || [], [data]); - const collection = useCollection(); - const field = useField(); - - useEffect(() => { - field.value = dataSource; - }, [dataSource]); - - const columns = useMemo(() => { - return collection.getFields().map((collectionField) => { - const tableFieldSchema = { - name: collectionField.name, - type: 'void', - title: collectionField.uiSchema?.title || collectionField.name, - 'x-component': 'TableColumn', - properties: { - [collectionField.name]: { - 'x-component': 'CollectionField', - 'x-read-pretty': true, - 'x-decorator-props': { - labelStyle: { - display: 'none', - }, - }, - }, - }, - }; - - return { - title: , - dataIndex: collectionField.name, - render(value, record, index) { - return ( - - ); - }, - }; - }); - }, [collection]); - - return { - ...tableProps, - loading, - dataSource, - columns, - }; -} - -const myTableSettings = new SchemaSettings({ - name: 'myTableSettings', - items: [ - { - name: 'bordered', - type: 'switch', - useComponentProps() { - const { props: blockSettingsProps, dn } = useDataBlock(); - - return { - title: 'Bordered', - checked: !!blockSettingsProps.tableProps?.bordered, - onChange: (checked) => { - // 修改 schema - dn.deepMerge({ 'x-decorator-props': { tableProps: { bordered: checked } } }); - }, - }; - }, - }, - { - type: 'remove', - name: 'remove', - }, - ], -}); - -const AddBlockButton = observer( - () => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - return render(); - }, - { displayName: 'AddBlockButton' }, -); - -const Page = observer( - (props) => { - return ( -
- {props.children} - -
- ); - }, - { displayName: 'Page' }, -); - -function useCollectionMenuItems() { - const dataSourceManager = useDataSourceManager(); - const allCollections = dataSourceManager.getAllCollections(); - const menus = useMemo( - () => - allCollections.map((item) => { - const { key, displayName, collections } = item; - return { - name: key, - label: displayName, - type: 'subMenu', - children: collections.map((collection) => { - return { - name: collection.name, - label: collection.title, - collection: collection.name, - dataSource: key, - }; - }), - }; - }), - [allCollections], - ); - - return menus; -} - -const CreateAction = () => { - const [open, setOpen] = useState(false); - - const showDrawer = () => { - setOpen(true); - }; - - const onClose = () => { - setOpen(false); - }; - - const compile = useCompile(); - const collection = useCollection(); - const title = compile(collection.title); - const fieldSchema = useFieldSchema(); - - const { render } = useSchemaToolbarRender(fieldSchema); - return ( - <> -
- {render()} - -
- -

Some contents...

-
- - ); -}; - -const createActionSettings = new SchemaSettings({ - name: 'createActionSettings', - items: [ - { - type: 'remove', - name: 'remove', - }, - ], -}); - -const RefreshAction = () => { - const { refresh } = useDataBlockRequest(); - return ; -}; - -const ActionBar = ({ children }) => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - - return ( -
- - {children} - {render()} - -
- ); -}; - -const CreateActionInitializer = () => { - const { insert } = useSchemaInitializer(); - const handleClick = () => { - insert({ - type: 'void', - 'x-component': 'CreateAction', - 'x-settings': 'createActionSettings', - }); - }; - return ; -}; - -const RefreshActionInitializer = () => { - const { insert } = useSchemaInitializer(); - const handleClick = () => { - insert({ - type: 'void', - 'x-component': 'RefreshAction', - }); - }; - return ; -}; - -const tableActionInitializers = new SchemaInitializer({ - name: 'tableActionInitializers', - title: 'Configure actions', - icon: 'SettingOutlined', - style: { - marginLeft: 8, - }, - items: [ - { - type: 'item', - name: 'addNew', - Component: CreateActionInitializer, - }, - { - type: 'item', - name: 'refresh', - Component: RefreshActionInitializer, - }, - ], -}); - -const TableDataBlockInitializer = () => { - const { insert, setVisible } = useSchemaInitializer(); - - const handleClick = ({ item }) => { - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - 'x-settings': 'myTableSettings', - 'x-decorator': 'DataBlockProvider', - 'x-toolbar': 'MyToolbar', - 'x-decorator-props': { - collection: item.collection, - dataSource: item.dataSource, - action: 'list', - tableProps: { - bordered: true, - }, - }, - properties: { - actions: { - type: 'void', - 'x-component': 'ActionBar', - 'x-initializer': 'tableActionInitializers', - }, - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - 'x-use-component-props': 'useTableProps', - }, - }, - }; - insert(tableSchema); - setVisible(false); - }; - - const menuItems = useCollectionMenuItems(); - - return ; -}; - -const MyToolbar = (props) => { - const collection = useCollection(); - const compile = useCompile(); - return ; -}; - -const myInitializer = new SchemaInitializer({ - name: 'myInitializer', - title: 'Add Block', - insertPosition: 'beforeEnd', - items: [ - { - name: 'table', - Component: TableDataBlockInitializer, - }, - ], -}); - -const rootSchema: ISchema = { - type: 'void', - name: 'root', - 'x-component': 'Page', - 'x-initializer': 'myInitializer', -}; - -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ MyTable, TableColumn, MyToolbar, ActionBar, CreateAction, RefreshAction }); - this.app.schemaInitializerManager.add(myInitializer); - this.app.schemaSettingsManager.add(myTableSettings); - this.app.schemaSettingsManager.add(createActionSettings); - this.app.addScopes({ useTableProps }); - this.app.schemaInitializerManager.add(tableActionInitializers); - } -} - -const Root = () => { - return ; -}; - -const app = new Application({ - plugins: [MyPlugin], - components: { - Page, - AddBlockButton, - CardItem, - DataBlockProvider, - InputNumber, - Input, - CollectionField, - ColorPicker, - FormItem, - }, - router: { - type: 'memory', - initialEntries: ['/'], - }, - designable: true, - dataSourceManager: { - collections: mainCollections, - dataSources: [ - { - key: 'test-db', - displayName: 'TestDB', - collections: TestDBCollections, - }, - ], - fieldInterfaces: [ - IdFieldInterface, - InputFieldInterface, - EmailFieldInterface, - ColorFieldInterface, - NumberFieldInterface, - ], - }, - apiClient: { - baseURL: 'http://localhost:8000', - }, -}); - -app.router.add('home', { - path: '/', - Component: Root, -}); - -mock(app); - -export default app.getRootComponent(); diff --git a/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo11.tsx b/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo11.tsx deleted file mode 100644 index e362ddf03..000000000 --- a/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo11.tsx +++ /dev/null @@ -1,492 +0,0 @@ -import { Button, Drawer, Space, Table, TableProps } from 'antd'; -import React, { useEffect, useMemo, useState } from 'react'; -import { - CardItem, - CollectionField, - ColorFieldInterface, - ColorPicker, - DataBlockProvider, - EmailFieldInterface, - FormItem, - IdFieldInterface, - Input, - InputFieldInterface, - InputNumber, - NumberFieldInterface, - Plugin, - SchemaComponent, - SchemaInitializer, - SchemaInitializerItem, - SchemaInitializerSwitch, - SchemaSettings, - SchemaToolbar, - useCollection, - useCompile, - useCurrentSchema, - useDataBlock, - useDataBlockProps, - useDataBlockRequest, - useDataSourceManager, - useDesignable, - useSchemaInitializer, - useSchemaInitializerItem, - useSchemaInitializerRender, - useSchemaToolbarRender, - withDynamicSchemaProps, -} from '@nocobase/client'; -import { Application } from '@nocobase/client'; -import { uid } from '@formily/shared'; -import { ISchema, RecursionField, observer, useField, useFieldSchema } from '@formily/react'; -import { mainCollections, TestDBCollections } from './collections'; -import { mock } from './mockData'; - -const MyTable = withDynamicSchemaProps(Table, { displayName: 'MyTable' }); - -const TableColumn = observer(() => { - const field = useField(); - return
{field.title}
; -}); - -function useTableColumns() { - const schema = useFieldSchema(); - const filed = useField(); - const { designable } = useDesignable(); - const { render } = useSchemaInitializerRender(schema['x-initializer'], schema['x-initializer-props']); - const columns = schema.mapProperties((tableField: any, name) => { - return { - title: , - dataIndex: name, - key: name, - width: 200, - render(value, record, index) { - return ; - }, - }; - }); - - const tableColumns = useMemo(() => { - return [ - ...columns, - { - title: render(), - dataIndex: 'TABLE_COLUMN_INITIALIZER', - key: 'TABLE_COLUMN_INITIALIZER', - width: 200, - render: designable ? () =>
: null, - }, - ]; - }, [columns, render, designable]); - - return tableColumns; -} - -function useTableProps(): TableProps { - const { tableProps } = useDataBlockProps(); - const { data, loading } = useDataBlockRequest(); - const dataSource = useMemo(() => data?.data || [], [data]); - const field = useField(); - - useEffect(() => { - field.value = dataSource; - }, [dataSource]); - - const columns = useTableColumns(); - - return { - ...tableProps, - loading, - dataSource, - columns, - }; -} - -const myTableSettings = new SchemaSettings({ - name: 'myTableSettings', - items: [ - { - name: 'bordered', - type: 'switch', - useComponentProps() { - const { props: blockSettingsProps, dn } = useDataBlock(); - - return { - title: 'Bordered', - checked: !!blockSettingsProps.tableProps?.bordered, - onChange: (checked) => { - // 修改 schema - dn.deepMerge({ 'x-decorator-props': { tableProps: { bordered: checked } } }); - }, - }; - }, - }, - { - type: 'remove', - name: 'remove', - }, - ], -}); - -const AddBlockButton = observer( - () => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - return render(); - }, - { displayName: 'AddBlockButton' }, -); - -const Page = observer( - (props) => { - return ( -
- {props.children} - -
- ); - }, - { displayName: 'Page' }, -); - -function useCollectionMenuItems() { - const dataSourceManager = useDataSourceManager(); - const allCollections = dataSourceManager.getAllCollections(); - const menus = useMemo( - () => - allCollections.map((item) => { - const { key, displayName, collections } = item; - return { - name: key, - label: displayName, - type: 'subMenu', - children: collections.map((collection) => { - return { - name: collection.name, - label: collection.title, - collection: collection.name, - dataSource: key, - }; - }), - }; - }), - [allCollections], - ); - - return menus; -} - -const CreateAction = () => { - const [open, setOpen] = useState(false); - - const showDrawer = () => { - setOpen(true); - }; - - const onClose = () => { - setOpen(false); - }; - - const compile = useCompile(); - const collection = useCollection(); - const title = compile(collection.title); - const fieldSchema = useFieldSchema(); - - const { render } = useSchemaToolbarRender(fieldSchema); - return ( - <> -
- {render()} - -
- -

Some contents...

-
- - ); -}; - -const createActionSettings = new SchemaSettings({ - name: 'createActionSettings', - items: [ - { - type: 'remove', - name: 'remove', - }, - ], -}); - -const RefreshAction = () => { - const { refresh } = useDataBlockRequest(); - return ; -}; - -const ActionBar = ({ children }) => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - - return ( -
- - {children} - {render()} - -
- ); -}; - -const CreateActionInitializer = () => { - const { insert } = useSchemaInitializer(); - const handleClick = () => { - insert({ - type: 'void', - 'x-component': 'CreateAction', - 'x-settings': 'createActionSettings', - }); - }; - return ; -}; - -const RefreshActionInitializer = () => { - const { insert } = useSchemaInitializer(); - const handleClick = () => { - insert({ - type: 'void', - 'x-component': 'RefreshAction', - }); - }; - return ; -}; - -const tableActionInitializers = new SchemaInitializer({ - name: 'tableActionInitializers', - title: 'Configure actions', - icon: 'SettingOutlined', - style: { - marginLeft: 8, - }, - items: [ - { - type: 'item', - name: 'addNew', - Component: CreateActionInitializer, - }, - { - type: 'item', - name: 'refresh', - Component: RefreshActionInitializer, - }, - ], -}); - -const TableDataBlockInitializer = () => { - const { insert, setVisible } = useSchemaInitializer(); - - const handleClick = ({ item }) => { - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - 'x-settings': 'myTableSettings', - 'x-decorator': 'DataBlockProvider', - 'x-toolbar': 'MyToolbar', - 'x-decorator-props': { - collection: item.collection, - dataSource: item.dataSource, - action: 'list', - tableProps: { - bordered: true, - }, - }, - properties: { - actions: { - type: 'void', - 'x-component': 'ActionBar', - 'x-initializer': 'tableActionInitializers', - }, - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - 'x-use-component-props': 'useTableProps', - 'x-initializer': 'tableColumnInitializers', - }, - }, - }; - insert(tableSchema); - setVisible(false); - }; - - const menuItems = useCollectionMenuItems(); - - return ; -}; - -const useTableColumnInitializerFields = () => { - const collection = useCollection(); - return collection.fields.map((collectionField) => { - const tableFieldSchema = { - name: collectionField.name, - type: 'void', - title: collectionField.uiSchema?.title || collectionField.name, - 'x-component': 'TableColumn', - properties: { - [collectionField.name]: { - 'x-component': 'CollectionField', - 'x-read-pretty': true, - 'x-decorator-props': { - labelStyle: { - display: 'none', - }, - }, - }, - }, - }; - return { - type: 'item', - name: collectionField.name, - title: collectionField?.uiSchema?.title || collectionField.name, - Component: 'TableCollectionFieldInitializer', - schema: tableFieldSchema, - }; - }); -}; - -export const TableCollectionFieldInitializer = () => { - const itemConfig = useSchemaInitializerItem(); - const { insert } = useSchemaInitializer(); - const { remove } = useDesignable(); - const schema = useFieldSchema(); - const exists = !!schema.properties?.[itemConfig.name]; - return ( - { - if (exists) { - return remove(schema.properties?.[itemConfig.name]); - } - insert(itemConfig.schema); - }} - /> - ); -}; - -const tableColumnInitializers = new SchemaInitializer({ - name: 'tableColumnInitializers', - insertPosition: 'beforeEnd', - icon: 'SettingOutlined', - title: 'Configure columns', - items: [ - { - name: 'displayFields', - type: 'itemGroup', - title: 'Display fields', - useChildren: useTableColumnInitializerFields, - }, - ], -}); - -const MyToolbar = (props) => { - const collection = useCollection(); - const compile = useCompile(); - return ; -}; - -const myInitializer = new SchemaInitializer({ - name: 'myInitializer', - title: 'Add Block', - insertPosition: 'beforeEnd', - items: [ - { - name: 'table', - Component: TableDataBlockInitializer, - }, - ], -}); - -const rootSchema: ISchema = { - type: 'void', - name: 'root', - 'x-component': 'Page', - 'x-initializer': 'myInitializer', -}; - -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ - MyTable, - TableColumn, - MyToolbar, - ActionBar, - CreateAction, - RefreshAction, - TableCollectionFieldInitializer, - }); - this.app.schemaInitializerManager.add(myInitializer); - this.app.schemaSettingsManager.add(myTableSettings); - this.app.addScopes({ useTableProps }); - this.app.schemaInitializerManager.add(tableActionInitializers); - this.app.schemaInitializerManager.add(tableColumnInitializers); - this.app.schemaSettingsManager.add(createActionSettings); - } -} - -const Root = () => { - return ; -}; - -const app = new Application({ - plugins: [MyPlugin], - components: { - Page, - AddBlockButton, - CardItem, - DataBlockProvider, - InputNumber, - Input, - CollectionField, - ColorPicker, - FormItem, - }, - router: { - type: 'memory', - initialEntries: ['/'], - }, - designable: true, - dataSourceManager: { - collections: mainCollections, - dataSources: [ - { - key: 'test-db', - displayName: 'TestDB', - collections: TestDBCollections, - }, - ], - fieldInterfaces: [ - IdFieldInterface, - InputFieldInterface, - EmailFieldInterface, - ColorFieldInterface, - NumberFieldInterface, - ], - }, - apiClient: { - baseURL: 'http://localhost:8000', - }, -}); - -app.router.add('home', { - path: '/', - Component: Root, -}); - -mock(app); - -export default app.getRootComponent(); diff --git a/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo12.tsx b/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo12.tsx deleted file mode 100644 index 1fd5d9a67..000000000 --- a/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo12.tsx +++ /dev/null @@ -1,532 +0,0 @@ -import { Button, Drawer, Space, Table, TableProps } from 'antd'; -import React, { useEffect, useMemo, useState } from 'react'; -import { - CardItem, - CollectionField, - ColorFieldInterface, - ColorPicker, - DataBlockProvider, - EmailFieldInterface, - FormItem, - IdFieldInterface, - Input, - InputFieldInterface, - InputNumber, - NumberFieldInterface, - Plugin, - CollectionRecordProvider, - SchemaComponent, - SchemaInitializer, - SchemaInitializerItem, - SchemaInitializerSwitch, - SchemaSettings, - SchemaToolbar, - useCollection, - useCompile, - useCurrentSchema, - useDataBlock, - useDataBlockProps, - useDataBlockRequest, - useDataSource, - useDataSourceManager, - useDesignable, - useCollectionRecord, - useSchemaInitializer, - useSchemaInitializerItem, - useSchemaInitializerRender, - useSchemaToolbarRender, - withDynamicSchemaProps, -} from '@nocobase/client'; -import { Application } from '@nocobase/client'; -import { uid } from '@formily/shared'; -import { ISchema, RecursionField, observer, useField, useFieldSchema } from '@formily/react'; -import { mainCollections, TestDBCollections } from './collections'; -import { mock } from './mockData'; - -const MyTable = withDynamicSchemaProps(Table, { displayName: 'MyTable' }); - -const TableColumn = observer(() => { - const field = useField(); - return
{field.title}
; -}); - -const ColumnView = observer( - () => { - const record = useCollectionRecord(); - const [open, setOpen] = useState(false); - - const showDrawer = () => { - setOpen(true); - }; - - const onClose = () => { - setOpen(false); - }; - return ( - <> - - -
{JSON.stringify(record, null, 2)}
-
- - ); - }, - { displayName: 'ColumnView' }, -); - -function useTableColumns() { - const schema = useFieldSchema(); - const filed = useField(); - const { designable } = useDesignable(); - const { render } = useSchemaInitializerRender(schema['x-initializer'], schema['x-initializer-props']); - const columns = schema.mapProperties((tableField: any, name) => { - return { - title: , - dataIndex: name, - key: name, - render(value, record, index) { - return ; - }, - }; - }); - const tableColumns = useMemo(() => { - return [ - ...columns, - { - title: 'Actions', - dataIndex: 'actions', - key: 'actions', - render: (value, record) => { - return ( - - - - - - ); - }, - }, - { - title: render(), - dataIndex: 'TABLE_COLUMN_INITIALIZER', - key: 'TABLE_COLUMN_INITIALIZER', - render: designable ? () =>
: null, - }, - ]; - }, [columns, render, designable]); - - return tableColumns; -} - -function useTableProps(): TableProps { - const { tableProps } = useDataBlockProps(); - const { data, loading } = useDataBlockRequest(); - const dataSource = useMemo(() => data?.data || [], [data]); - const field = useField(); - - useEffect(() => { - field.value = dataSource; - }, [dataSource]); - - const columns = useTableColumns(); - - return { - ...tableProps, - loading, - dataSource, - columns, - }; -} - -const myTableSettings = new SchemaSettings({ - name: 'myTableSettings', - items: [ - { - name: 'bordered', - type: 'switch', - useComponentProps() { - const { props: blockSettingsProps, dn } = useDataBlock(); - - return { - title: 'Bordered', - checked: !!blockSettingsProps.tableProps?.bordered, - onChange: (checked) => { - // 修改 schema - dn.deepMerge({ 'x-decorator-props': { tableProps: { bordered: checked } } }); - }, - }; - }, - }, - { - type: 'remove', - name: 'remove', - }, - ], -}); - -const AddBlockButton = observer( - () => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - return render(); - }, - { displayName: 'AddBlockButton' }, -); - -const Page = observer( - (props) => { - return ( -
- {props.children} - -
- ); - }, - { displayName: 'Page' }, -); - -function useCollectionMenuItems() { - const dataSourceManager = useDataSourceManager(); - const allCollections = dataSourceManager.getAllCollections(); - const menus = useMemo( - () => - allCollections.map((item) => { - const { key, displayName, collections } = item; - return { - name: key, - label: displayName, - type: 'subMenu', - children: collections.map((collection) => { - return { - name: collection.name, - label: collection.title, - collection: collection.name, - dataSource: key, - }; - }), - }; - }), - [allCollections], - ); - - return menus; -} - -const CreateAction = () => { - const [open, setOpen] = useState(false); - - const showDrawer = () => { - setOpen(true); - }; - - const onClose = () => { - setOpen(false); - }; - - const compile = useCompile(); - const collection = useCollection(); - const title = compile(collection.title); - const fieldSchema = useFieldSchema(); - - const { render } = useSchemaToolbarRender(fieldSchema); - return ( - <> -
- {render()} - -
- -

Some contents...

-
- - ); -}; - -const createActionSettings = new SchemaSettings({ - name: 'createActionSettings', - items: [ - { - type: 'remove', - name: 'remove', - }, - ], -}); - -const RefreshAction = () => { - const { refresh } = useDataBlockRequest(); - return ; -}; - -const ActionBar = ({ children }) => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - - return ( -
- - {children} - {render()} - -
- ); -}; - -const CreateActionInitializer = () => { - const { insert } = useSchemaInitializer(); - const handleClick = () => { - insert({ - type: 'void', - 'x-component': 'CreateAction', - 'x-settings': 'createActionSettings', - }); - }; - return ; -}; - -const RefreshActionInitializer = () => { - const { insert } = useSchemaInitializer(); - const handleClick = () => { - insert({ - type: 'void', - 'x-component': 'RefreshAction', - }); - }; - return ; -}; - -const tableActionInitializers = new SchemaInitializer({ - name: 'tableActionInitializers', - title: 'Configure actions', - icon: 'SettingOutlined', - style: { - marginLeft: 8, - }, - items: [ - { - type: 'item', - name: 'addNew', - Component: CreateActionInitializer, - }, - { - type: 'item', - name: 'refresh', - Component: RefreshActionInitializer, - }, - ], -}); - -const TableDataBlockInitializer = () => { - const { insert, setVisible } = useSchemaInitializer(); - - const handleClick = ({ item }) => { - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - 'x-settings': 'myTableSettings', - 'x-decorator': 'DataBlockProvider', - 'x-toolbar': 'MyToolbar', - 'x-decorator-props': { - collection: item.collection, - dataSource: item.dataSource, - action: 'list', - tableProps: { - bordered: true, - }, - }, - properties: { - actions: { - type: 'void', - 'x-component': 'ActionBar', - 'x-initializer': 'tableActionInitializers', - }, - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - 'x-use-component-props': 'useTableProps', - 'x-initializer': 'tableColumnInitializers', - }, - }, - }; - insert(tableSchema); - setVisible(false); - }; - - const menuItems = useCollectionMenuItems(); - - return ; -}; - -const useTableColumnInitializerFields = () => { - const collection = useCollection(); - return collection.fields.map((collectionField) => { - const tableFieldSchema = { - name: collectionField.name, - type: 'void', - title: collectionField.uiSchema?.title || collectionField.name, - 'x-component': 'TableColumn', - properties: { - [collectionField.name]: { - 'x-component': 'CollectionField', - 'x-read-pretty': true, - 'x-decorator-props': { - labelStyle: { - display: 'none', - }, - }, - }, - }, - }; - return { - type: 'item', - name: collectionField.name, - title: collectionField?.uiSchema?.title || collectionField.name, - Component: 'TableCollectionFieldInitializer', - schema: tableFieldSchema, - }; - }); -}; - -export const TableCollectionFieldInitializer = () => { - const itemConfig = useSchemaInitializerItem(); - const { insert } = useSchemaInitializer(); - const { remove } = useDesignable(); - const schema = useFieldSchema(); - const exists = !!schema.properties?.[itemConfig.name]; - return ( - { - if (exists) { - return remove(schema.properties?.[itemConfig.name]); - } - insert(itemConfig.schema); - }} - /> - ); -}; - -const tableColumnInitializers = new SchemaInitializer({ - name: 'tableColumnInitializers', - insertPosition: 'beforeEnd', - icon: 'SettingOutlined', - title: 'Configure columns', - items: [ - { - name: 'displayFields', - type: 'itemGroup', - title: 'Display fields', - useChildren: useTableColumnInitializerFields, - }, - ], -}); - -const MyToolbar = (props) => { - const collection = useCollection(); - const compile = useCompile(); - return ; -}; - -const myInitializer = new SchemaInitializer({ - name: 'myInitializer', - title: 'Add Block', - insertPosition: 'beforeEnd', - items: [ - { - name: 'table', - Component: TableDataBlockInitializer, - }, - ], -}); - -const rootSchema: ISchema = { - type: 'void', - name: 'root', - 'x-component': 'Page', - 'x-initializer': 'myInitializer', -}; - -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ - MyTable, - TableColumn, - MyToolbar, - ActionBar, - CreateAction, - RefreshAction, - TableCollectionFieldInitializer, - }); - this.app.schemaInitializerManager.add(myInitializer); - this.app.schemaSettingsManager.add(myTableSettings); - this.app.addScopes({ useTableProps }); - this.app.schemaInitializerManager.add(tableActionInitializers); - this.app.schemaInitializerManager.add(tableColumnInitializers); - this.app.schemaSettingsManager.add(createActionSettings); - } -} - -const Root = () => { - return ; -}; - -const app = new Application({ - plugins: [MyPlugin], - components: { - Page, - AddBlockButton, - CardItem, - DataBlockProvider, - InputNumber, - Input, - CollectionField, - ColorPicker, - FormItem, - }, - router: { - type: 'memory', - initialEntries: ['/'], - }, - designable: true, - dataSourceManager: { - collections: mainCollections, - dataSources: [ - { - key: 'test-db', - displayName: 'TestDB', - collections: TestDBCollections, - }, - ], - fieldInterfaces: [ - IdFieldInterface, - InputFieldInterface, - EmailFieldInterface, - ColorFieldInterface, - NumberFieldInterface, - ], - }, - apiClient: { - baseURL: 'http://localhost:8000', - }, -}); - -app.router.add('home', { - path: '/', - Component: Root, -}); - -mock(app); - -export default app.getRootComponent(); diff --git a/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo2.tsx b/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo2.tsx deleted file mode 100644 index f487115da..000000000 --- a/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo2.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import { Table } from 'antd'; -import React from 'react'; -import { CardItem, Plugin, SchemaComponent } from '@nocobase/client'; -import { Application } from '@nocobase/client'; -import { uid } from '@formily/shared'; - -const MyTable = () => { - const dataSource = [ - { - key: '1', - name: 'Mike', - age: 32, - address: '10 Downing Street', - }, - { - key: '2', - name: 'John', - age: 42, - address: '10 Downing Street', - }, - ]; - - const columns = [ - { - title: 'Name', - dataIndex: 'name', - key: 'name', - }, - { - title: 'Age', - dataIndex: 'age', - key: 'age', - }, - { - title: 'Address', - dataIndex: 'address', - key: 'address', - }, - ]; - - return
; -}; - -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ MyTable }); - } -} - -const tableSchema = { - name: 'demo', - type: 'void', - 'x-component': 'CardItem', - properties: { - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - }, - }, -}; - -const Root = () => { - return ; -}; - -const app = new Application({ - plugins: [MyPlugin], - components: { - CardItem, - }, - router: { - type: 'memory', - initialEntries: ['/'], - }, -}); - -app.router.add('root', { - path: '/', - Component: Root, -}); - -export default app.getRootComponent(); diff --git a/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo3.tsx b/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo3.tsx deleted file mode 100644 index 1d899d6fb..000000000 --- a/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo3.tsx +++ /dev/null @@ -1,147 +0,0 @@ -import { Table } from 'antd'; -import React, { useCallback } from 'react'; -import { - CardItem, - Plugin, - SchemaComponent, - SchemaInitializer, - SchemaInitializerItem, - useSchemaInitializer, - useSchemaInitializerRender, -} from '@nocobase/client'; -import { Application } from '@nocobase/client'; -import { uid } from '@formily/shared'; -import { ISchema, observer, useFieldSchema } from '@formily/react'; - -const MyTable = () => { - const dataSource = [ - { - key: '1', - name: 'Mike', - age: 32, - address: '10 Downing Street', - }, - { - key: '2', - name: 'John', - age: 42, - address: '10 Downing Street', - }, - ]; - - const columns = [ - { - title: 'Name', - dataIndex: 'name', - key: 'name', - }, - { - title: 'Age', - dataIndex: 'age', - key: 'age', - }, - { - title: 'Address', - dataIndex: 'address', - key: 'address', - }, - ]; - - return
; -}; - -const AddBlockButton = observer( - () => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - return render(); - }, - { displayName: 'AddBlockButton' }, -); - -const Page = observer( - (props) => { - return ( -
- {props.children} - -
- ); - }, - { displayName: 'Page' }, -); - -const TableDataBlockInitializer = () => { - const { insert, setVisible } = useSchemaInitializer(); - - const handleClick = useCallback( - ({ item }) => { - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - properties: { - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - }, - }, - }; - insert(tableSchema); - setVisible(false); - }, - [insert, setVisible], - ); - - return ; -}; - -const myInitializer = new SchemaInitializer({ - name: 'myInitializer', - title: 'Add Block', - insertPosition: 'beforeEnd', - items: [ - { - name: 'table', - Component: TableDataBlockInitializer, - }, - ], -}); - -const rootSchema: ISchema = { - type: 'void', - name: 'root', - 'x-component': 'Page', - 'x-initializer': 'myInitializer', -}; - -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ MyTable }); - this.app.schemaInitializerManager.add(myInitializer); - } -} - -const Root = () => { - return ; -}; - -const app = new Application({ - plugins: [MyPlugin], - components: { - Page, - AddBlockButton, - CardItem, - }, - router: { - type: 'memory', - initialEntries: ['/'], - }, - designable: true, -}); - -app.router.add('home', { - path: '/', - Component: Root, -}); - -export default app.getRootComponent(); diff --git a/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo4.tsx b/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo4.tsx deleted file mode 100644 index 7c327227b..000000000 --- a/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo4.tsx +++ /dev/null @@ -1,180 +0,0 @@ -import { Table } from 'antd'; -import React, { useMemo } from 'react'; -import { - CardItem, - DataBlockProvider, - Plugin, - SchemaComponent, - SchemaInitializer, - SchemaInitializerItem, - useCollection, - useDataBlockRequest, - useDataSourceManager, - useSchemaInitializer, - useSchemaInitializerRender, -} from '@nocobase/client'; -import { Application } from '@nocobase/client'; -import { uid } from '@formily/shared'; -import { ISchema, observer, useFieldSchema } from '@formily/react'; -import { mainCollections, TestDBCollections } from './collections'; -import { mock } from './mockData'; - -const MyTable = () => { - const { data, loading } = useDataBlockRequest(); - const dataSource = useMemo(() => data?.data || [], [data]); - const collection = useCollection(); - const columns = useMemo(() => { - return collection.getFields().map((collectionField) => { - return { - title: collectionField.uiSchema?.title || collectionField.name, - dataIndex: collectionField.name, - }; - }); - }, [collection]); - - return
; -}; - -const AddBlockButton = observer( - () => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - return render(); - }, - { displayName: 'AddBlockButton' }, -); - -const Page = observer( - (props) => { - return ( -
- {props.children} - -
- ); - }, - { displayName: 'Page' }, -); - -function useCollectionMenuItems() { - const dataSourceManager = useDataSourceManager(); - const allCollections = dataSourceManager.getAllCollections(); - const menus = useMemo( - () => - allCollections.map((item) => { - const { key, displayName, collections } = item; - return { - name: key, - label: displayName, - type: 'subMenu', - children: collections.map((collection) => { - return { - name: collection.name, - label: collection.title, - collection: collection.name, - dataSource: key, - }; - }), - }; - }), - [allCollections], - ); - - return menus; -} - -const TableDataBlockInitializer = () => { - const { insert, setVisible } = useSchemaInitializer(); - - const handleClick = ({ item }) => { - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - 'x-decorator': 'DataBlockProvider', - 'x-decorator-props': { - collection: item.collection, - dataSource: item.dataSource, - action: 'list', - }, - properties: { - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - }, - }, - }; - insert(tableSchema); - setVisible(false); - }; - - const menuItems = useCollectionMenuItems(); - - return ; -}; - -const myInitializer = new SchemaInitializer({ - name: 'myInitializer', - title: 'Add Block', - insertPosition: 'beforeEnd', - items: [ - { - name: 'table', - Component: TableDataBlockInitializer, - }, - ], -}); - -const rootSchema: ISchema = { - type: 'void', - name: 'root', - 'x-component': 'Page', - 'x-initializer': 'myInitializer', -}; - -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ MyTable }); - this.app.schemaInitializerManager.add(myInitializer); - } -} - -const Root = () => { - return ; -}; - -const app = new Application({ - plugins: [MyPlugin], - components: { - Page, - AddBlockButton, - CardItem, - DataBlockProvider, - }, - router: { - type: 'memory', - initialEntries: ['/'], - }, - designable: true, - dataSourceManager: { - collections: mainCollections, - dataSources: [ - { - key: 'test-db', - displayName: 'TestDB', - collections: TestDBCollections, - }, - ], - }, - apiClient: { - baseURL: 'http://localhost:8000', - }, -}); - -app.router.add('home', { - path: '/', - Component: Root, -}); - -mock(app); - -export default app.getRootComponent(); diff --git a/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo5.tsx b/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo5.tsx deleted file mode 100644 index 51b09f7bc..000000000 --- a/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo5.tsx +++ /dev/null @@ -1,236 +0,0 @@ -import { Table } from 'antd'; -import React, { useEffect, useMemo } from 'react'; -import { - CardItem, - CollectionField, - ColorFieldInterface, - ColorPicker, - DataBlockProvider, - EmailFieldInterface, - FormItem, - IdFieldInterface, - Input, - InputFieldInterface, - InputNumber, - NumberFieldInterface, - Plugin, - SchemaComponent, - SchemaInitializer, - SchemaInitializerItem, - useCollection, - useDataBlockRequest, - useDataSourceManager, - useSchemaInitializer, - useSchemaInitializerRender, -} from '@nocobase/client'; -import { Application } from '@nocobase/client'; -import { uid } from '@formily/shared'; -import { ISchema, RecursionField, observer, useField, useFieldSchema } from '@formily/react'; -import { mainCollections, TestDBCollections } from './collections'; -import { mock } from './mockData'; - -const TableColumn = observer(() => { - const field = useField(); - return
{field.title}
; -}); - -const MyTable = () => { - const { data, loading } = useDataBlockRequest(); - const dataSource = useMemo(() => data?.data || [], [data]); - const collection = useCollection(); - const field = useField(); - - useEffect(() => { - field.value = dataSource; - }, [dataSource]); - - const columns = useMemo(() => { - return collection.getFields().map((collectionField) => { - const tableFieldSchema = { - name: collectionField.name, - type: 'void', - title: collectionField.uiSchema?.title || collectionField.name, - 'x-component': 'TableColumn', - properties: { - [collectionField.name]: { - 'x-component': 'CollectionField', - 'x-read-pretty': true, - 'x-decorator-props': { - labelStyle: { - display: 'none', - }, - }, - }, - }, - }; - - return { - title: , - dataIndex: collectionField.name, - render(value, record, index) { - return ( - - ); - }, - }; - }); - }, [collection]); - - return
; -}; - -const AddBlockButton = observer( - () => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - return render(); - }, - { displayName: 'AddBlockButton' }, -); - -const Page = observer( - (props) => { - return ( -
- {props.children} - -
- ); - }, - { displayName: 'Page' }, -); - -function useCollectionMenuItems() { - const dataSourceManager = useDataSourceManager(); - const allCollections = dataSourceManager.getAllCollections(); - const menus = useMemo( - () => - allCollections.map((item) => { - const { key, displayName, collections } = item; - return { - name: key, - label: displayName, - type: 'subMenu', - children: collections.map((collection) => { - return { - name: collection.name, - label: collection.title, - collection: collection.name, - dataSource: key, - }; - }), - }; - }), - [allCollections], - ); - - return menus; -} - -const TableDataBlockInitializer = () => { - const { insert, setVisible } = useSchemaInitializer(); - - const handleClick = ({ item }) => { - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - 'x-decorator': 'DataBlockProvider', - 'x-decorator-props': { - collection: item.collection, - dataSource: item.dataSource, - action: 'list', - }, - properties: { - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - }, - }, - }; - insert(tableSchema); - setVisible(false); - }; - - const menuItems = useCollectionMenuItems(); - - return ; -}; - -const myInitializer = new SchemaInitializer({ - name: 'myInitializer', - title: 'Add Block', - insertPosition: 'beforeEnd', - items: [ - { - name: 'table', - Component: TableDataBlockInitializer, - }, - ], -}); - -const rootSchema: ISchema = { - type: 'void', - name: 'root', - 'x-component': 'Page', - 'x-initializer': 'myInitializer', -}; - -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ MyTable, TableColumn }); - this.app.schemaInitializerManager.add(myInitializer); - } -} - -const Root = () => { - return ; -}; - -const app = new Application({ - plugins: [MyPlugin], - components: { - Page, - AddBlockButton, - CardItem, - DataBlockProvider, - InputNumber, - Input, - CollectionField, - ColorPicker, - FormItem, - }, - router: { - type: 'memory', - initialEntries: ['/'], - }, - designable: true, - dataSourceManager: { - collections: mainCollections, - dataSources: [ - { - key: 'test-db', - displayName: 'TestDB', - collections: TestDBCollections, - }, - ], - fieldInterfaces: [ - IdFieldInterface, - InputFieldInterface, - EmailFieldInterface, - ColorFieldInterface, - NumberFieldInterface, - ], - }, - apiClient: { - baseURL: 'http://localhost:8000', - }, -}); - -app.router.add('home', { - path: '/', - Component: Root, -}); - -mock(app); - -export default app.getRootComponent(); diff --git a/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo6.tsx b/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo6.tsx deleted file mode 100644 index a07197d3f..000000000 --- a/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo6.tsx +++ /dev/null @@ -1,280 +0,0 @@ -import { Table, TableProps } from 'antd'; -import React, { useEffect, useMemo } from 'react'; -import { - CardItem, - CollectionField, - ColorFieldInterface, - ColorPicker, - DataBlockProvider, - EmailFieldInterface, - FormItem, - IdFieldInterface, - Input, - InputFieldInterface, - InputNumber, - NumberFieldInterface, - Plugin, - SchemaComponent, - SchemaInitializer, - SchemaInitializerItem, - SchemaSettings, - useCollection, - useDataBlock, - useDataBlockProps, - useDataBlockRequest, - useDataSourceManager, - useSchemaInitializer, - useSchemaInitializerRender, - withDynamicSchemaProps, -} from '@nocobase/client'; -import { Application } from '@nocobase/client'; -import { uid } from '@formily/shared'; -import { ISchema, RecursionField, observer, useField, useFieldSchema } from '@formily/react'; -import { mainCollections, TestDBCollections } from './collections'; -import { mock } from './mockData'; - -const MyTable = withDynamicSchemaProps(Table, { displayName: 'MyTable' }); - -const TableColumn = observer(() => { - const field = useField(); - return
{field.title}
; -}); - -function useTableProps(): TableProps { - const { tableProps } = useDataBlockProps(); - const { data, loading } = useDataBlockRequest(); - const dataSource = useMemo(() => data?.data || [], [data]); - const collection = useCollection(); - const field = useField(); - - useEffect(() => { - field.value = dataSource; - }, [dataSource]); - - const columns = useMemo(() => { - return collection.getFields().map((collectionField) => { - const tableFieldSchema = { - name: collectionField.name, - type: 'void', - title: collectionField.uiSchema?.title || collectionField.name, - 'x-component': 'TableColumn', - properties: { - [collectionField.name]: { - 'x-component': 'CollectionField', - 'x-read-pretty': true, - 'x-decorator-props': { - labelStyle: { - display: 'none', - }, - }, - }, - }, - }; - - return { - title: , - dataIndex: collectionField.name, - render(value, record, index) { - return ( - - ); - }, - }; - }); - }, [collection]); - - return { - ...tableProps, - loading, - dataSource, - columns, - rowKey: 'id', - }; -} - -const myTableSettings = new SchemaSettings({ - name: 'myTableSettings', - items: [ - { - name: 'bordered', - type: 'switch', - useComponentProps() { - const { props: blockSettingsProps, dn } = useDataBlock(); - return { - title: 'Bordered', - checked: !!blockSettingsProps.tableProps?.bordered, - onChange: (checked) => { - // 修改 schema - dn.deepMerge({ 'x-decorator-props': { tableProps: { bordered: checked } } }); - }, - }; - }, - }, - { - type: 'remove', - name: 'remove', - }, - ], -}); - -const AddBlockButton = observer( - () => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - return render(); - }, - { displayName: 'AddBlockButton' }, -); - -const Page = observer( - (props) => { - return ( -
- {props.children} - -
- ); - }, - { displayName: 'Page' }, -); - -function useCollectionMenuItems() { - const dataSourceManager = useDataSourceManager(); - const allCollections = dataSourceManager.getAllCollections(); - const menus = useMemo( - () => - allCollections.map((item) => { - const { key, displayName, collections } = item; - return { - name: key, - label: displayName, - type: 'subMenu', - children: collections.map((collection) => { - return { - name: collection.name, - label: collection.title, - collection: collection.name, - dataSource: key, - }; - }), - }; - }), - [allCollections], - ); - - return menus; -} - -const TableDataBlockInitializer = () => { - const { insert, setVisible } = useSchemaInitializer(); - - const handleClick = ({ item }) => { - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - 'x-settings': 'myTableSettings', - 'x-decorator': 'DataBlockProvider', - 'x-decorator-props': { - collection: item.collection, - dataSource: item.dataSource, - action: 'list', - tableProps: { - bordered: true, - }, - }, - properties: { - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - 'x-use-component-props': 'useTableProps', - }, - }, - }; - insert(tableSchema); - setVisible(false); - }; - - const menuItems = useCollectionMenuItems(); - return ; -}; - -const myInitializer = new SchemaInitializer({ - name: 'myInitializer', - title: 'Add Block', - insertPosition: 'beforeEnd', - items: [ - { - name: 'table', - Component: TableDataBlockInitializer, - }, - ], -}); - -const rootSchema: ISchema = { - type: 'void', - name: 'root', - 'x-component': 'Page', - 'x-initializer': 'myInitializer', -}; - -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ MyTable, TableColumn }); - this.app.schemaInitializerManager.add(myInitializer); - this.app.schemaSettingsManager.add(myTableSettings); - this.app.addScopes({ useTableProps }); - } -} - -const Root = () => { - return ; -}; - -const app = new Application({ - plugins: [MyPlugin], - components: { - Page, - AddBlockButton, - CardItem, - DataBlockProvider, - InputNumber, - Input, - CollectionField, - ColorPicker, - FormItem, - }, - router: { - type: 'memory', - initialEntries: ['/'], - }, - designable: true, - dataSourceManager: { - collections: mainCollections, - dataSources: [ - { - key: 'test-db', - displayName: 'TestDB', - collections: TestDBCollections, - }, - ], - fieldInterfaces: [ - IdFieldInterface, - InputFieldInterface, - EmailFieldInterface, - ColorFieldInterface, - NumberFieldInterface, - ], - }, - apiClient: { - baseURL: 'http://localhost:8000', - }, -}); - -app.router.add('home', { - path: '/', - Component: Root, -}); - -mock(app); - -export default app.getRootComponent(); diff --git a/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo7.tsx b/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo7.tsx deleted file mode 100644 index 6acb8e01c..000000000 --- a/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo7.tsx +++ /dev/null @@ -1,291 +0,0 @@ -import { Table, TableProps } from 'antd'; -import React, { useEffect, useMemo } from 'react'; -import { - CardItem, - CollectionField, - ColorFieldInterface, - ColorPicker, - DataBlockProvider, - EmailFieldInterface, - FormItem, - IdFieldInterface, - Input, - InputFieldInterface, - InputNumber, - NumberFieldInterface, - Plugin, - SchemaComponent, - SchemaInitializer, - SchemaInitializerItem, - SchemaSettings, - SchemaToolbar, - useCollection, - useCompile, - useDataBlock, - useDataBlockProps, - useDataBlockRequest, - useDataSource, - useDataSourceManager, - useSchemaInitializer, - useSchemaInitializerRender, - withDynamicSchemaProps, -} from '@nocobase/client'; -import { Application } from '@nocobase/client'; -import { uid } from '@formily/shared'; -import { ISchema, RecursionField, observer, useField, useFieldSchema } from '@formily/react'; -import { mainCollections, TestDBCollections } from './collections'; -import { mock } from './mockData'; - -const MyTable = withDynamicSchemaProps(Table, { displayName: 'MyTable' }); - -const TableColumn = observer(() => { - const field = useField(); - return
{field.title}
; -}); - -function useTableProps(): TableProps { - const { tableProps } = useDataBlockProps(); - const { data, loading } = useDataBlockRequest(); - const dataSource = useMemo(() => data?.data || [], [data]); - const collection = useCollection(); - const field = useField(); - - useEffect(() => { - field.value = dataSource; - }, [dataSource]); - - const columns = useMemo(() => { - return collection.getFields().map((collectionField) => { - const tableFieldSchema = { - name: collectionField.name, - type: 'void', - title: collectionField.uiSchema?.title || collectionField.name, - 'x-component': 'TableColumn', - properties: { - [collectionField.name]: { - 'x-component': 'CollectionField', - 'x-read-pretty': true, - 'x-decorator-props': { - labelStyle: { - display: 'none', - }, - }, - }, - }, - }; - - return { - title: , - dataIndex: collectionField.name, - render(value, record, index) { - return ( - - ); - }, - }; - }); - }, [collection]); - - return { - ...tableProps, - loading, - dataSource, - columns, - }; -} - -const myTableSettings = new SchemaSettings({ - name: 'myTableSettings', - items: [ - { - name: 'bordered', - type: 'switch', - useComponentProps() { - const { props: blockSettingsProps, dn } = useDataBlock(); - - return { - title: 'Bordered', - checked: !!blockSettingsProps.tableProps?.bordered, - onChange: (checked) => { - // 修改 schema - dn.deepMerge({ 'x-decorator-props': { tableProps: { bordered: checked } } }); - }, - }; - }, - }, - { - type: 'remove', - name: 'remove', - }, - ], -}); - -const AddBlockButton = observer( - () => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - return render(); - }, - { displayName: 'AddBlockButton' }, -); - -const Page = observer( - (props) => { - return ( -
- {props.children} - -
- ); - }, - { displayName: 'Page' }, -); - -function useCollectionMenuItems() { - const dataSourceManager = useDataSourceManager(); - const allCollections = dataSourceManager.getAllCollections(); - const menus = useMemo( - () => - allCollections.map((item) => { - const { key, displayName, collections } = item; - return { - name: key, - label: displayName, - type: 'subMenu', - children: collections.map((collection) => { - return { - name: collection.name, - label: collection.title, - collection: collection.name, - dataSource: key, - }; - }), - }; - }), - [allCollections], - ); - - return menus; -} - -const TableDataBlockInitializer = () => { - const { insert, setVisible } = useSchemaInitializer(); - - const handleClick = ({ item }) => { - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - 'x-settings': 'myTableSettings', - 'x-decorator': 'DataBlockProvider', - 'x-toolbar': 'MyToolbar', - 'x-decorator-props': { - collection: item.collection, - dataSource: item.dataSource, - action: 'list', - tableProps: { - bordered: true, - }, - }, - properties: { - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - 'x-use-component-props': 'useTableProps', - }, - }, - }; - insert(tableSchema); - setVisible(false); - }; - - const menuItems = useCollectionMenuItems(); - - return ; -}; - -const MyToolbar = (props) => { - const collection = useCollection(); - const compile = useCompile(); - return ; -}; - -const myInitializer = new SchemaInitializer({ - name: 'myInitializer', - title: 'Add Block', - insertPosition: 'beforeEnd', - items: [ - { - name: 'table', - Component: TableDataBlockInitializer, - }, - ], -}); - -const rootSchema: ISchema = { - type: 'void', - name: 'root', - 'x-component': 'Page', - 'x-initializer': 'myInitializer', -}; - -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ MyTable, TableColumn, MyToolbar }); - this.app.schemaInitializerManager.add(myInitializer); - this.app.schemaSettingsManager.add(myTableSettings); - this.app.addScopes({ useTableProps }); - } -} - -const Root = () => { - return ; -}; - -const app = new Application({ - plugins: [MyPlugin], - components: { - Page, - AddBlockButton, - CardItem, - DataBlockProvider, - InputNumber, - Input, - CollectionField, - ColorPicker, - FormItem, - }, - router: { - type: 'memory', - initialEntries: ['/'], - }, - designable: true, - dataSourceManager: { - collections: mainCollections, - dataSources: [ - { - key: 'test-db', - displayName: 'TestDB', - collections: TestDBCollections, - }, - ], - fieldInterfaces: [ - IdFieldInterface, - InputFieldInterface, - EmailFieldInterface, - ColorFieldInterface, - NumberFieldInterface, - ], - }, - apiClient: { - baseURL: 'http://localhost:8000', - }, -}); - -app.router.add('home', { - path: '/', - Component: Root, -}); - -mock(app); - -export default app.getRootComponent(); diff --git a/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo8.tsx b/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo8.tsx deleted file mode 100644 index edb6b3310..000000000 --- a/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo8.tsx +++ /dev/null @@ -1,351 +0,0 @@ -import { Button, Drawer, Space, Table, TableProps } from 'antd'; -import React, { useEffect, useMemo, useState } from 'react'; -import { - CardItem, - CollectionField, - ColorFieldInterface, - ColorPicker, - DataBlockProvider, - EmailFieldInterface, - FormItem, - IdFieldInterface, - Input, - InputFieldInterface, - InputNumber, - NumberFieldInterface, - Plugin, - SchemaComponent, - SchemaInitializer, - SchemaInitializerItem, - SchemaSettings, - SchemaToolbar, - useCollection, - useCompile, - useDataBlock, - useDataBlockProps, - useDataBlockRequest, - useDataSource, - useDataSourceManager, - useSchemaInitializer, - useSchemaInitializerRender, - withDynamicSchemaProps, -} from '@nocobase/client'; -import { Application } from '@nocobase/client'; -import { uid } from '@formily/shared'; -import { ISchema, RecursionField, observer, useField, useFieldSchema } from '@formily/react'; -import { mainCollections, TestDBCollections } from './collections'; -import { mock } from './mockData'; - -const MyTable = withDynamicSchemaProps(Table, { displayName: 'MyTable' }); - -const TableColumn = observer(() => { - const field = useField(); - return
{field.title}
; -}); - -function useTableProps(): TableProps { - const { tableProps } = useDataBlockProps(); - const { data, loading } = useDataBlockRequest(); - const dataSource = useMemo(() => data?.data || [], [data]); - const collection = useCollection(); - const field = useField(); - - useEffect(() => { - field.value = dataSource; - }, [dataSource]); - - const columns = useMemo(() => { - return collection.getFields().map((collectionField) => { - const tableFieldSchema = { - name: collectionField.name, - type: 'void', - title: collectionField.uiSchema?.title || collectionField.name, - 'x-component': 'TableColumn', - properties: { - [collectionField.name]: { - 'x-component': 'CollectionField', - 'x-read-pretty': true, - 'x-decorator-props': { - labelStyle: { - display: 'none', - }, - }, - }, - }, - }; - - return { - title: , - dataIndex: collectionField.name, - render(value, record, index) { - return ( - - ); - }, - }; - }); - }, [collection]); - - return { - ...tableProps, - loading, - dataSource, - columns, - }; -} - -const myTableSettings = new SchemaSettings({ - name: 'myTableSettings', - items: [ - { - name: 'bordered', - type: 'switch', - useComponentProps() { - const { props: blockSettingsProps, dn } = useDataBlock(); - - return { - title: 'Bordered', - checked: !!blockSettingsProps.tableProps?.bordered, - onChange: (checked) => { - // 修改 schema - dn.deepMerge({ 'x-decorator-props': { tableProps: { bordered: checked } } }); - }, - }; - }, - }, - { - type: 'remove', - name: 'remove', - }, - ], -}); - -const AddBlockButton = observer( - () => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - return render(); - }, - { displayName: 'AddBlockButton' }, -); - -const Page = observer( - (props) => { - return ( -
- {props.children} - -
- ); - }, - { displayName: 'Page' }, -); - -function useCollectionMenuItems() { - const dataSourceManager = useDataSourceManager(); - const allCollections = dataSourceManager.getAllCollections(); - const menus = useMemo( - () => - allCollections.map((item) => { - const { key, displayName, collections } = item; - return { - name: key, - label: displayName, - type: 'subMenu', - children: collections.map((collection) => { - return { - name: collection.name, - label: collection.title, - collection: collection.name, - dataSource: key, - }; - }), - }; - }), - [allCollections], - ); - - return menus; -} - -const CreateAction = () => { - const [open, setOpen] = useState(false); - - const showDrawer = () => { - setOpen(true); - }; - - const onClose = () => { - setOpen(false); - }; - - const compile = useCompile(); - const collection = useCollection(); - const title = compile(collection.title); - - return ( - <> - - -

Some contents...

-
- - ); -}; - -const RefreshAction = () => { - const { refresh } = useDataBlockRequest(); - return ; -}; - -const ActionBar = () => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - - return ( -
- - - - {render()} - -
- ); -}; - -const TableDataBlockInitializer = () => { - const { insert, setVisible } = useSchemaInitializer(); - - const handleClick = ({ item }) => { - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - 'x-settings': 'myTableSettings', - 'x-decorator': 'DataBlockProvider', - 'x-toolbar': 'MyToolbar', - 'x-decorator-props': { - collection: item.collection, - dataSource: item.dataSource, - action: 'list', - tableProps: { - bordered: true, - }, - }, - properties: { - actions: { - type: 'void', - 'x-component': 'ActionBar', - 'x-initializer': 'tableActionInitializers', - }, - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - 'x-use-component-props': 'useTableProps', - }, - }, - }; - insert(tableSchema); - setVisible(false); - }; - - const menuItems = useCollectionMenuItems(); - - return ; -}; - -const MyToolbar = (props) => { - const collection = useCollection(); - const compile = useCompile(); - return ; -}; - -const myInitializer = new SchemaInitializer({ - name: 'myInitializer', - title: 'Add Block', - insertPosition: 'beforeEnd', - items: [ - { - name: 'table', - Component: TableDataBlockInitializer, - }, - ], -}); - -const rootSchema: ISchema = { - type: 'void', - name: 'root', - 'x-component': 'Page', - 'x-initializer': 'myInitializer', -}; - -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ MyTable, TableColumn, MyToolbar, ActionBar }); - this.app.schemaInitializerManager.add(myInitializer); - this.app.schemaSettingsManager.add(myTableSettings); - this.app.addScopes({ useTableProps }); - } -} - -const Root = () => { - return ; -}; - -const app = new Application({ - plugins: [MyPlugin], - components: { - Page, - AddBlockButton, - CardItem, - DataBlockProvider, - InputNumber, - Input, - CollectionField, - ColorPicker, - FormItem, - }, - router: { - type: 'memory', - initialEntries: ['/'], - }, - designable: true, - dataSourceManager: { - collections: mainCollections, - dataSources: [ - { - key: 'test-db', - displayName: 'TestDB', - collections: TestDBCollections, - }, - ], - fieldInterfaces: [ - IdFieldInterface, - InputFieldInterface, - EmailFieldInterface, - ColorFieldInterface, - NumberFieldInterface, - ], - }, - apiClient: { - baseURL: 'http://localhost:8000', - }, -}); - -app.router.add('home', { - path: '/', - Component: Root, -}); - -mock(app); - -export default app.getRootComponent(); diff --git a/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo9.tsx b/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo9.tsx deleted file mode 100644 index f5cf4261b..000000000 --- a/packages/core/client/docs/en-US/core/data-block/tmp-demos/demo9.tsx +++ /dev/null @@ -1,394 +0,0 @@ -import { Button, Drawer, Space, Table, TableProps } from 'antd'; -import React, { useEffect, useMemo, useState } from 'react'; -import { - CardItem, - CollectionField, - ColorFieldInterface, - ColorPicker, - DataBlockProvider, - EmailFieldInterface, - FormItem, - IdFieldInterface, - Input, - InputFieldInterface, - InputNumber, - NumberFieldInterface, - Plugin, - SchemaComponent, - SchemaInitializer, - SchemaInitializerItem, - SchemaSettings, - SchemaToolbar, - useCollection, - useCompile, - useDataBlock, - useDataBlockProps, - useDataBlockRequest, - useDataSource, - useDataSourceManager, - useSchemaInitializer, - useSchemaInitializerRender, - withDynamicSchemaProps, -} from '@nocobase/client'; -import { Application } from '@nocobase/client'; -import { uid } from '@formily/shared'; -import { ISchema, RecursionField, observer, useField, useFieldSchema } from '@formily/react'; -import { mainCollections, TestDBCollections } from './collections'; -import { mock } from './mockData'; - -const MyTable = withDynamicSchemaProps(Table, { displayName: 'MyTable' }); - -const TableColumn = observer(() => { - const field = useField(); - return
{field.title}
; -}); - -function useTableProps(): TableProps { - const { tableProps } = useDataBlockProps(); - const { data, loading } = useDataBlockRequest(); - const dataSource = useMemo(() => data?.data || [], [data]); - const collection = useCollection(); - const field = useField(); - - useEffect(() => { - field.value = dataSource; - }, [dataSource]); - - const columns = useMemo(() => { - return collection.getFields().map((collectionField) => { - const tableFieldSchema = { - name: collectionField.name, - type: 'void', - title: collectionField.uiSchema?.title || collectionField.name, - 'x-component': 'TableColumn', - properties: { - [collectionField.name]: { - 'x-component': 'CollectionField', - 'x-read-pretty': true, - 'x-decorator-props': { - labelStyle: { - display: 'none', - }, - }, - }, - }, - }; - - return { - title: , - dataIndex: collectionField.name, - render(value, record, index) { - return ( - - ); - }, - }; - }); - }, [collection]); - - return { - ...tableProps, - loading, - dataSource, - columns, - }; -} - -const myTableSettings = new SchemaSettings({ - name: 'myTableSettings', - items: [ - { - name: 'bordered', - type: 'switch', - useComponentProps() { - const { props: blockSettingsProps, dn } = useDataBlock(); - - return { - title: 'Bordered', - checked: !!blockSettingsProps.tableProps?.bordered, - onChange: (checked) => { - // 修改 schema - dn.deepMerge({ 'x-decorator-props': { tableProps: { bordered: checked } } }); - }, - }; - }, - }, - { - type: 'remove', - name: 'remove', - }, - ], -}); - -const AddBlockButton = observer( - () => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - return render(); - }, - { displayName: 'AddBlockButton' }, -); - -const Page = observer( - (props) => { - return ( -
- {props.children} - -
- ); - }, - { displayName: 'Page' }, -); - -function useCollectionMenuItems() { - const dataSourceManager = useDataSourceManager(); - const allCollections = dataSourceManager.getAllCollections(); - const menus = useMemo( - () => - allCollections.map((item) => { - const { key, displayName, collections } = item; - return { - name: key, - label: displayName, - type: 'subMenu', - children: collections.map((collection) => { - return { - name: collection.name, - label: collection.title, - collection: collection.name, - dataSource: key, - }; - }), - }; - }), - [allCollections], - ); - - return menus; -} - -const CreateAction = () => { - const [open, setOpen] = useState(false); - - const showDrawer = () => { - setOpen(true); - }; - - const onClose = () => { - setOpen(false); - }; - - const compile = useCompile(); - const collection = useCollection(); - const title = compile(collection.title); - - return ( - <> - - -

Some contents...

-
- - ); -}; - -const RefreshAction = () => { - const { refresh } = useDataBlockRequest(); - return ; -}; - -const ActionBar = ({ children }) => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - - return ( -
- - {children} - {render()} - -
- ); -}; - -const CreateActionInitializer = () => { - const { insert } = useSchemaInitializer(); - const handleClick = () => { - insert({ - type: 'void', - 'x-component': 'CreateAction', - }); - }; - return ; -}; - -const RefreshActionInitializer = () => { - const { insert } = useSchemaInitializer(); - const handleClick = () => { - insert({ - type: 'void', - 'x-component': 'RefreshAction', - }); - }; - return ; -}; - -const tableActionInitializers = new SchemaInitializer({ - name: 'tableActionInitializers', - title: 'Configure actions', - icon: 'SettingOutlined', - style: { - marginLeft: 8, - }, - items: [ - { - type: 'item', - name: 'addNew', - Component: CreateActionInitializer, - }, - { - type: 'item', - name: 'refresh', - Component: RefreshActionInitializer, - }, - ], -}); - -const TableDataBlockInitializer = () => { - const { insert, setVisible } = useSchemaInitializer(); - - const handleClick = ({ item }) => { - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - 'x-settings': 'myTableSettings', - 'x-decorator': 'DataBlockProvider', - 'x-toolbar': 'MyToolbar', - 'x-decorator-props': { - collection: item.collection, - dataSource: item.dataSource, - action: 'list', - tableProps: { - bordered: true, - }, - }, - properties: { - actions: { - type: 'void', - 'x-component': 'ActionBar', - 'x-initializer': 'tableActionInitializers', - }, - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - 'x-use-component-props': 'useTableProps', - }, - }, - }; - insert(tableSchema); - setVisible(false); - }; - - const menuItems = useCollectionMenuItems(); - - return ; -}; - -const MyToolbar = (props) => { - const collection = useCollection(); - const compile = useCompile(); - return ; -}; - -const myInitializer = new SchemaInitializer({ - name: 'myInitializer', - title: 'Add Block', - insertPosition: 'beforeEnd', - items: [ - { - name: 'table', - Component: TableDataBlockInitializer, - }, - ], -}); - -const rootSchema: ISchema = { - type: 'void', - name: 'root', - 'x-component': 'Page', - 'x-initializer': 'myInitializer', -}; - -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ MyTable, TableColumn, MyToolbar, ActionBar, CreateAction, RefreshAction }); - this.app.schemaInitializerManager.add(myInitializer); - this.app.schemaSettingsManager.add(myTableSettings); - this.app.addScopes({ useTableProps }); - this.app.schemaInitializerManager.add(tableActionInitializers); - } -} - -const Root = () => { - return ; -}; - -const app = new Application({ - plugins: [MyPlugin], - components: { - Page, - AddBlockButton, - CardItem, - DataBlockProvider, - InputNumber, - Input, - CollectionField, - ColorPicker, - FormItem, - }, - router: { - type: 'memory', - initialEntries: ['/'], - }, - designable: true, - dataSourceManager: { - collections: mainCollections, - dataSources: [ - { - key: 'test-db', - displayName: 'TestDB', - collections: TestDBCollections, - }, - ], - fieldInterfaces: [ - IdFieldInterface, - InputFieldInterface, - EmailFieldInterface, - ColorFieldInterface, - NumberFieldInterface, - ], - }, - apiClient: { - baseURL: 'http://localhost:8000', - }, -}); - -app.router.add('home', { - path: '/', - Component: Root, -}); - -mock(app); - -export default app.getRootComponent(); diff --git a/packages/core/client/docs/en-US/core/data-block/tmp-demos/mockData.ts b/packages/core/client/docs/en-US/core/data-block/tmp-demos/mockData.ts deleted file mode 100644 index 59bff781e..000000000 --- a/packages/core/client/docs/en-US/core/data-block/tmp-demos/mockData.ts +++ /dev/null @@ -1,79 +0,0 @@ -import type { Application } from '@nocobase/client'; -import MockAdapter from 'axios-mock-adapter'; - -const mockData = { - 'users:list': { - data: [ - { - id: '1', - nickname: 'Jack Ma', - email: 'test@gmail.com', - favoriteColor: '#1677FF', - }, - { - id: '2', - email: 'jim@gmail.com', - nickname: 'Jim Green', - favoriteColor: '#36C', - }, - { - id: '3', - nickname: 'Tom Cat', - email: 'tom@gmail.com', - favoriteColor: '#F0F', - }, - ], - }, - 'users:destroy': { - result: 'ok', - }, - 'roles:list': { - data: [ - { - name: 'root', - title: 'Root', - description: 'Root', - }, - { - name: 'admin', - title: 'Admin', - description: 'Admin description', - }, - ], - }, - 'test1:list': { - data: [ - { - id: '1', - field1: 'aaa', - field2: 1, - }, - { - id: '2', - field1: 'bbb', - field2: 2, - }, - { - id: '3', - field1: 'ccc', - field2: 3, - }, - ], - }, -}; - -export function mock(app: Application) { - const mock = new MockAdapter(app.apiClient.axios); - - Object.entries(mockData).forEach(([url, data]) => { - mock.onGet(url).reply(async (config) => { - return [200, data]; - }); - mock.onPost(url).reply(async (config) => { - return [200, data]; - }); - mock.onDelete(url).reply(async (config) => { - return [200, data]; - }); - }); -} diff --git a/packages/core/client/docs/en-US/core/data-block/tmp.md b/packages/core/client/docs/en-US/core/data-block/tmp.md deleted file mode 100644 index 49807329c..000000000 --- a/packages/core/client/docs/en-US/core/data-block/tmp.md +++ /dev/null @@ -1,1149 +0,0 @@ -# 临时 - - -## 区块介绍 - - -## 区块扩展 - -### 1. 先简单定义一个 Table 组件 - -```tsx | pure -const MyTable = () => { - const dataSource = [ - { - key: '1', - name: 'Mike', - age: 32, - address: '10 Downing Street', - }, - { - key: '2', - name: 'John', - age: 42, - address: '10 Downing Street', - }, - ]; - - const columns = [ - { - title: 'Name', - dataIndex: 'name', - key: 'name', - }, - { - title: 'Age', - dataIndex: 'age', - key: 'age', - }, - { - title: 'Address', - dataIndex: 'address', - key: 'address', - }, - ]; - - return
; -} -``` - - - -### 2. 使用 UI Schema 的方式将组件渲染到页面上 - -先将组件注册到 NocoBase 应用中 - -```tsx | pure -import { Plugin } from '@nocobase/client'; - -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ MyTable }) - } -} -``` - -然后定义 UI Schema,并通过 `SchemaComponent` 渲染到页面上。 - -```tsx | pure -const tableSchema = { - name: 'demo', - type: 'void', - 'x-component': 'CardItem', - properties: { - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - }, - }, -} - -const Root = () => { - return -} - -app.router.add('root', { - path: '/', - Component: Root, -}) -``` - - - -关于 UI Schema 的更多信息请参考 [UI Schema](/core/ui-schema/schema-component) 和 [UI Schema Quick Start](https://docs-cn.nocobase.com/development/client/ui-schema/quick-start) - -其中 `CardItem` 是 NocoBase 的内置组件,相当于外层的容器。 - -### 3. 使用 `SchemaInitializer` 将组件动态添加到页面上 - -首先我们将 `Root` 组件更换 Schema 为 `rootSchema`。 - -```tsx | pure -const rootSchema: ISchema = { - type: 'void', - name: 'root', - 'x-component': 'Page', - 'x-initializer': 'myInitializer', -}; - -const Root = () => { - return ; -}; -``` - -其中 `Page` 的定义如下: - -```tsx | pure -import { observer } from "@formily/react"; - -const AddBlockButton = observer(() => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - return render(); -}, { displayName: 'AddBlockButton' }); - -const Page = observer( - (props) => { - return ( -
- {props.children} - -
- ); - }, - { displayName: 'Page' }, -); -``` - -其中: - -- `useSchemaInitializerRender()`:用于获取 `SchemaInitializer` 的渲染函数,具体用法请参考 [useSchemaInitializerRender](/core/ui-schema/schema-initializer#useschemainitializer)。 -- `useFieldSchema()`:用于获取当前字段的 schema,具体用法请参考 [useFieldSchema](/core/ui-schema/designable#usefieldschema)。 -- `observer`:用于将函数组件转换为响应式组件,具体用法请参考 [observer](https://react.formilyjs.org/api/shared/observer)。 - -`myInitializer` 的定义如下: - -```tsx | pure -const TableDataBlockInitializer = () => { - const { insert, setVisible } = useSchemaInitializer(); - - const handleClick = useCallback(({ item }) => { - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - properties: { - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - }, - }, - }; - insert(tableSchema); - setVisible(false); - }, [insert, setVisible]); - - return ; -}; - -const myInitializer = new SchemaInitializer({ - name: 'myInitializer', - title: 'Add Block', - insertPosition: 'beforeEnd', - items: [ - { - name: 'table', - Component: TableDataBlockInitializer, - }, - ], -}); -``` - -我们将 `tableSchema` 放到了 `TableDataBlockInitializer` 中,当点击 `Add Block` 时,会将 `tableSchema` 插入到页面上。 - -关于 SchemaInitializer 的更多信息请参考 [SchemaInitializer](/core/ui-schema/schema-initializer) 和 [SchemaInitializer Quick Start](https://docs-cn.nocobase.com/development/client/ui-schema/quick-start#schemainitializer)。 - -最后将 `myInitializer` 注册到 NocoBase 应用中。 - -```diff -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ MyTable }) -+ this.app.schemaInitializerManager.add(myInitializer); - } -} -``` - - - -在真正的插件开发过程中只需要定义和添加 `myInitializer` 和 `MyTable` 即可,`Page` 和 `Root` 是 NocoBase 内置的组件,无需重复定义。 - - -### 4. 从数据表中读取数据 - -上述 Table 中的数据是固定数据,我们需要动态的获取数据并渲染。 - -```diff -+ function useCollectionMenuItems() { -+ const dataSourceManager = useDataSourceManager(); -+ const allCollections = dataSourceManager.getAllCollections(); -+ const menus = useMemo( -+ () => allCollections.map((item) => { -+ const { key, displayName, collections } = item; -+ return { -+ name: key, -+ label: displayName, -+ type: 'subMenu', -+ children: collections.map((collection) => { -+ return { -+ name: collection.name, -+ label: collection.title, -+ collection: collection.name, -+ dataSource: key, -+ } -+ }) -+ }; -+ }), -+ [allCollections], -+ ); -+ -+ return menus; -+ } - -const TableDataBlockInitializer = () => { - const { insert, setVisible } = useSchemaInitializer(); - - const handleClick = ({ item }) => { - const tableSchema = { - type: 'void', -+ 'x-decorator': 'DataBlockProvider', -+ 'x-decorator-props': { -+ collection: item.collection, -+ dataSource: item.dataSource, -+ action: 'list', -+ }, - 'x-component': 'CardItem', - properties: { - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - }, - }, - } - insert(tableSchema); - setVisible(false); - }; - -+ const collectionMenuItems = useCollectionMenuItems(); - return ; -}; -``` - -其中: - -- [DataBlockProvider](/core/data-block/data-block-provider) 是 NocoBase 的内置组件,主要作用有4个: - - 提供 Collection 表结构信息 - - 提供 Collection 表的数据 - - 提供对数据增删改查的 [Resource](https://docs.nocobase.com/api/sdk#action-api) 对象 - - 提供区块的配置信息 - -- item:是当前点击的菜单对象,包括 `collection` 和 `dataSource`。 -- `useCollectionMenuItems`:是一个自定义的 hook,用于获取所有的 Collection 表信息,返回一个菜单数组。 - - `dataSourceManager`:用于获取数据源管理器,具体用法请参考 [useDataSourceManager](/core/data-source/data-source-manager-provider#usedatasourcemanager)。 - - -然后我们修改 `MyTable` 组件 - -```diff -const MyTable = () => { -- const dataSource = [ -- { -- key: '1', -- name: 'Mike', -- age: 32, -- address: '10 Downing Street', -- }, -- { -- key: '2', -- name: 'John', -- age: 42, -- address: '10 Downing Street', -- }, -- ]; -- -- const columns = [ -- { -- title: 'Name', -- dataIndex: 'name', -- key: 'name', -- }, -- { -- title: 'Age', -- dataIndex: 'age', -- key: 'age', -- }, -- { -- title: 'Address', -- dataIndex: 'address', -- key: 'address', -- }, -- ]; - - -+ const { data, loading } = useDataBlockRequest(); -+ const dataSource = useMemo(() => data?.data || [], [data]); - -+ const collection = useCollection(); -+ const columns = useMemo(() => { -+ return collection.getFields().map((collectionField) => { -+ return { -+ title: compile(collectionField.uiSchema?.title || collectionField.name), -+ dataIndex: collectionField.name, -+ }; -+ }); -+ }, [collection, compile]); - - return
; -} -``` - -其中: - -- `useDataBlockRequest()`:由 [DataBlockProvider](/core/data-block/data-block-provider) 组件里面的 [DataBlockRequestProvider](/core/data-block/data-block-request-provider) 提供,用于获取对应的数据表结构。 -- `useCollection()`:由 [DataBlockProvider](/core/data-block/data-block-provider) 组件里面的 [DataBlockRequestProvider](/core/data-source/collection-provider) 提供,用于获取当前 Collection 的信息。 - - - -### 5. 将字段渲染为自定义组件 - -上面一步仅是把数据渲染成普通的字符串,还需要进一步把字段渲染成不同的组件。 - -我们以 `favoriteColor` 字段为例,其数据结构如下: - -```json -{ - "name": "favoriteColor", - "type": "string", - "interface": "color", - "uiSchema": { - "type": "string", - "x-component": "ColorPicker", - "default": "#1677FF", - "title": "Favorite Color" - } -} -``` - -其和渲染相关的是 `uiSchema` 字段和 `interface` 字段,`interface` 相当于一些公共的配置,`uiSchema` 相当于一些私有的配置,更多信息请参考 [CollectionField](/core/data-source/collection-field)。 - -```diff -+ useEffect(() => { -+ field.value = dataSource; -+ }, [dataSource]); - - const columns = useMemo(() => { - return collection.getFields().map((collectionField) => { -+ const tableFieldSchema = { - name: collectionField.name, -+ type: 'void', -+ title: collectionField.uiSchema?.title || collectionField.name, -+ 'x-component': 'TableColumn', -+ properties: { -+ [collectionField.name]: { -+ 'x-component': 'CollectionField', -+ 'x-read-pretty': true, -+ 'x-decorator-props': { -+ labelStyle: { -+ display: 'none', -+ }, -+ }, -+ }, -+ }, -+ }; -+ -+ return { -- title: collectionField.uiSchema?.title || collectionField.name, -+ title: , - dataIndex: collectionField.name, -+ render(value, record, index) { -+ return ; -+ }, -+ }; - }); - }, [collection]); -``` - -```diff -+ const TableColumn = observer(() => { -+ const field = useField(); -+ return
{field.title}
; -+ }); - -class MyPlugin extends Plugin { - async load() { - // ... -+ this.app.addComponents({ TableColumn }); - } -} -``` - -其中: - -`field.value = dataSource` 用于将数据赋值给 `MyTable` 这一层的 `field`,相当于: - -```diff -const tableSchema = { - // ... - properties: { - [uid()]: { - type: 'array', -+ value: dataSource, - 'x-component': 'MyTable', - }, - }, -}; -``` - -然后使用 `RecursionField` 组件将字段渲染成自定义组件,因为是数组,所以需要加上 `index`,这样子组件才能正确的读取到数据。 - -关于 `RecursionField` 的更多信息请参考 [RecursionField](https://react.formilyjs.org/api/components/recursion-fieldeld)。 - - - -### 6. 区块属性配置 - -首先我们先修改 `tableSchema`。 - -```diff - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', -+ 'x-settings': 'myTableSettings', - 'x-decorator': 'DataBlockProvider', - 'x-decorator-props': { - collection: item.collection, - dataSource: item.dataSource, - action: 'list', -+ tableProps: { -+ bordered: true, -+ }, - }, - properties: { - [uid()]: { - type: 'array', - 'x-component': 'MyTable', -+ 'x-use-component-props': 'useTableProps', - }, - }, -} -``` - -其中: - -- `x-settings`:用于指定区块的配置信息,具体用法请参考 [SchemaSettings](/core/ui-schema/schema-settings)。 -- `tableProps`:Table 的属性 -- `x-use-component-props`:用于动态读取的 UI Schema 属性 - -关于 `useTableProps` 的定义,我们先将 `MyTable` 的属性单独抽离为一个 Hook。 - -```tsx | pure -function useTableProps(): TableProps { - const { data, loading } = useDataBlockRequest(); - const dataSource = useMemo(() => data?.data || [], [data]); - const collection = useCollection(); - - const field = useField(); - - useEffect(() => { - field.value = dataSource; - }, [dataSource]); - - const columns = useMemo(() => { - return collection.getFields().map((collectionField) => { - const tableFieldSchema = { - name: collectionField.name, - type: 'void', - title: collectionField.uiSchema?.title || collectionField.name, - 'x-component': 'TableColumn', - properties: { - [collectionField.name]: { - 'x-component': 'CollectionField', - 'x-read-pretty': true, - 'x-decorator-props': { - labelStyle: { - display: 'none', - }, - }, - }, - }, - }; - - return { - title: , - dataIndex: collectionField.name, - render(value, record, index) { - return ; - }, - }; - }); - }, [collection]); - - return { - loading, - dataSource, - columns, - }; -} -``` - -然后增加如下内容: - -```diff -function useTableProps(): TableProps { -+ const { tableProps } = useDataBlockProps(); - // ... - - return { -+ ...tableProps, - loading, - dataSource, - columns, - }; -} -``` - -其中: - -- `useDataBlockProps()`:用于获取区块的配置信息,具体用法请参考 [useDataBlockProps](/core/data-block/data-block-provider#usedatablockprops)。 - - -再将 `MyTable` 组件使用 `withDynamicSchemaProps` 包裹。 - -```tsx | pure -const MyTable = withDynamicSchemaProps(Table, { displayName: 'MyTable' }); -``` - -`withDynamicSchemaProps` 的作用是能读取 Schema 中的 `x-use-component-props` 属性,将其解析并执行,然后将结果传递给组件。 - -然后我们实现 `myTableSettings`: - -```tsx | pure -const myTableSettings = new SchemaSettings({ - name: 'myTableSettings', - items: [ - { - name: 'bordered', - type: 'switch', - useComponentProps() { - const { props: blockSettingsProps, dn } = useDataBlock(); - - return { - title: 'Bordered', - checked: !!blockSettingsProps.tableProps?.bordered, - onChange: (checked) => { - // 修改 schema - dn.deepMerge({ 'x-decorator-props': { tableProps: { bordered: checked } } }); - }, - }; - }, - }, - { - type: 'remove', - name: 'remove', - } - ], -}); -``` - -然后我们将 `myTableSettings` 和 `useTableProps` 注册到 NocoBase 应用中。 - -```diff -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ MyTable }) - this.app.schemaInitializerManager.add(myInitializer); -+ this.app.schemaSettingsManager.add(myTableSettings); -+ this.app.addScopes({ useTableProps }); - } -} -``` - -以上各个部分的关系如下: - -- `tableSchema`:`tableProps` 存储属性配置信息 -- `DataBlockProvider`:读取 `tableSchema` 的配置,并通过 `useDataBlockProps` 传递子组件 -- `useTableProps`:通过 `useDataBlockProps` 获取 `DataBlockProvider` 提供的配置 -- `MyTable`:通过 `withDynamicSchemaProps` 自动读取到 `'x-use-component-props': 'useTableProps'` 进行编译,执行 `useTableProps()` 获取到配置传递给 `Table` -- `myTableSettings`:通过 `useDataBlock()` 并修改配置 `DataBlockProvider` 提供的配置 - -然后在右上角的 `Settings` 中可以看到 `Bordered` 选项,可以动态修改 `Table` 的 `bordered` 属性。 - - - - -### 7. 区块 Toolbar 配置 - -我们还可以给区块增加 Toolbar 配置,让其在左上角显示所属的 Collection 表信息。 - -我们先修改 `tableSchema`。 - -```diff - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', -+ 'x-toolbar': 'MyToolbar', - // ... -} -``` - -然后我们实现 `MyToolbar`。 - -```tsx | pure -const MyToolbar = (props) => { - const collection = useCollection(); - const compile = useCompile(); - return -} -``` - -然后我们将 `MyToolbar` 注册到 NocoBase 应用中。 - -```diff -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ MyTable }) - this.app.schemaInitializerManager.add(myInitializer); - this.app.schemaSettingsManager.add(myTableSettings); - this.app.addScopes({ useTableProps }); -+ this.app.addComponents({ MyToolbar }); - } -} -``` - -这样左上角 Toolbar 就会显示所属的 Collection 表信息。 - -关于 `SchemaToolbar` 的更多信息请参考 [SchemaToolbar](/core/ui-schema/schema-toolbar)。 - - - -### 8. 增加顶部操作按钮 - -我们可以给区块增加顶部操作按钮,比如增加 `Add New` 和 `Refresh` 新增列表数据按钮。 - -我们先修改 `tableSchema`。 - -```diff - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - // ... - properties: { -+ actions: { -+ type: 'void', -+ 'x-component': 'ActionBar', -+ }, - // ... - } -} -``` - -然后我们实现 `ActionBar`。 - -```tsx | pure -const CreateAction = () => { - const [open, setOpen] = useState(false); - - const showDrawer = () => { - setOpen(true); - }; - - const onClose = () => { - setOpen(false); - }; - - const compile = useCompile(); - const collection = useCollection(); - const title = compile(collection.title); - - return <> - - -

Some contents...

-
- -} - -const RefreshAction = () => { - const { refresh } = useDataBlockRequest(); - return -} - -const ActionBar = () => { - return ( -
- - - - -
- ) -}; -``` - -其中: - -- `useDataBlockRequest()`: 用于获取区块的请求对象,具体用法请参考 [useDataBlockRequest](/core/data-block/data-block-request-provider#usedatablockrequest)。 - -然后我们将 `ActionBar` 注册到 NocoBase 应用中。 - -```diff -class MyPlugin extends Plugin { - async load() { - // ... -+ this.app.addComponents({ ActionBar }); - } -} -``` - - - -### 9. 动态配置顶部操作按钮 - -上面的 `ActionBar` 里面的 `CreateAction` 和 `RefreshAction` 是固定的,我们可以将其配置动态化。 - -首先修改 `tableSchema`。 - -```diff - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - // ... - properties: { - actions: { - type: 'void', - 'x-component': 'ActionBar', -+ 'x-initializer': 'tableActionInitializers', - }, - // ... - } -} -``` - -然后我们实现 `tableActionInitializers`。 - -```tsx | pure -const CreateActionInitializer = () => { - const { insert } = useSchemaInitializer(); - const handleClick = () => { - insert({ - type: 'void', - 'x-component': 'CreateAction', - }); - }; - return ; -} - - -const RefreshActionInitializer = () => { - const { insert } = useSchemaInitializer(); - const handleClick = () => { - insert({ - type: 'void', - 'x-component': 'RefreshAction', - }); - }; - return ; -} - -const tableActionInitializers = new SchemaInitializer({ - name: 'tableActionInitializers', - title: "Configure actions", - icon: 'SettingOutlined', - style: { - marginLeft: 8, - }, - items: [ - { - type: 'item', - name: 'addNew', - title: "Add New", - Component: CreateActionInitializer, - }, - { - type: 'item', - name: 'refresh', - title: "Refresh", - Component: RefreshActionInitializer, - }, - ] -}) -``` - -然后修改 `ActionBar`: - -```diff -const ActionBar = ({ children }) => { -+ const fieldSchema = useFieldSchema(); -+ const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - - return ( -
- -+ {children} -+ {render()} - -
- ) -}; -``` - -然后我们将 `tableActionInitializers` 和 `CreateAction`、`RefreshAction` 注册到 NocoBase 应用中。 - -```diff -class MyPlugin extends Plugin { - async load() { - // ... -+ this.app.addComponents({ CreateAction, RefreshAction }); -+ this.app.schemaInitializerManager.add(tableActionInitializers); - } -} -``` - - - -### 10. 操作按钮的配置 - -目前的操作按钮只能添加,不能删除或者配置 ,我们可以通过 `SchemaSettings` 来配置。 - -这里以 `Add New` 按钮为例。首先我们修改 `CreateActionInitializer`。 - -```diff -const CreateActionInitializer = () => { - const { insert } = useSchemaInitializer(); - const handleClick = () => { - insert({ - type: 'void', - 'x-component': 'CreateAction', -+ 'x-settings': 'createActionSettings', - }); - }; - return ; -}; -``` - -然后我们实现 `createActionSettings`。 - -```tsx | pure -const createActionSettings = new SchemaSettings({ - name: 'createActionSettings', - items: [ - { - type: 'remove', - name: 'remove', - }, - ], -}) -``` - -然后我们将 `createActionSettings` 注册到 NocoBase 应用中。 - -```diff -class MyPlugin extends Plugin { - async load() { - // ... -+ this.app.schemaSettingsManager.add(createActionSettings); - } -} -``` - -最后将 `createActionSettings` 渲染出来。 - -```diff -const CreateAction = () => { - const [open, setOpen] = useState(false); - - const showDrawer = () => { - setOpen(true); - }; - - const onClose = () => { - setOpen(false); - }; - - const compile = useCompile(); - const collection = useCollection(); - const title = compile(collection.title); - -+ const fieldSchema = useFieldSchema(); -+ const { render } = useSchemaToolbarRender(fieldSchema); - - return ( - <> -- -+
-+ {render()} -+ -+
- -

Some contents...

-
- - ); -}; -``` - -需要注意的是,要将 `render()` 和 `Add New` 包裹在一个 `div` 中,这样 `render()` 才能正确的渲染。 - - - -### 11. 动态配置 table 列 - -首先修改 `tableSchema`。 - -```diff -const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - // ... - properties: { - action: { - // ... - }, - [uid()]: { - type: 'array', - 'x-component': 'MyTable', -+ 'x-initializer': 'tableColumnInitializers', - 'x-use-component-props': 'useTableProps', - }, - } -} -``` - -然后我们实现 `tableColumnInitializers`。 - -```tsx | pure -const tableColumnInitializers = new SchemaInitializer({ - name: 'tableColumnInitializers', - insertPosition: 'beforeEnd', - icon: 'SettingOutlined', - title: 'Configure columns', - items: [ - { - name: 'displayFields', - type: 'itemGroup', - title: 'Display fields', - useChildren: useTableColumnInitializerFields, - } - ], -}) - -const useTableColumnInitializerFields = () => { - const collection = useCollection(); - return collection.fields.map((collectionField) => { - const tableFieldSchema = { - name: collectionField.name, - type: 'void', - title: collectionField.uiSchema?.title || collectionField.name, - 'x-component': 'TableColumn', - properties: { - [collectionField.name]: { - 'x-component': 'CollectionField', - 'x-read-pretty': true, - 'x-decorator-props': { - labelStyle: { - display: 'none', - }, - }, - }, - }, - }; - return { - type: 'item', - name: collectionField.name, - title: collectionField?.uiSchema?.title || collectionField.name, - Component: 'TableCollectionFieldInitializer', - schema: tableFieldSchema, - }; - }); -}; - -export const TableCollectionFieldInitializer = () => { - const itemConfig = useSchemaInitializerItem(); - const { insert } = useSchemaInitializer(); - const { remove } = useDesignable(); - const schema = useFieldSchema(); - const exists = !!schema.properties?.[itemConfig.name]; - return ( - { - if (exists) { - return remove(schema.properties?.[itemConfig.name]); - } - insert(itemConfig.schema); - }} - /> - ); -}; -``` - -然后我们修改 `useTableProps`,增加 `useTableColumns`: - -```diff -function useTableProps(): TableProps { - const { tableProps } = useDataBlockProps(); - const { data, loading } = useDataBlockRequest(); - const dataSource = useMemo(() => data?.data || [], [data]); -+ const columns = useTableColumns(); - - return { - ...tableProps, - loading, - dataSource, - columns, - }; -} -``` - -```tsx | pure -function useTableColumns() { - const schema = useFieldSchema(); - const filed = useField(); - const { designable } = useDesignable(); - const { render } = useSchemaInitializerRender(schema['x-initializer'], schema['x-initializer-props']); - const columns = schema.mapProperties((tableField: any, name) => { - return { - title: , - dataIndex: name, - key: name, - width: 200, - render(value, record, index) { - return ; - }, - }; - }); - - const tableColumns = useMemo(() => { - return [ - ...columns, - { - title: render(), - dataIndex: 'TABLE_COLUMN_INITIALIZER', - key: 'TABLE_COLUMN_INITIALIZER', - width: 200, - render: designable ? () =>
: null, - }, - ]; - }, [columns, render, designable]); - - return tableColumns; -} -``` - -然后我们将 `tableColumnInitializers` 和 `TableCollectionFieldInitializer` 注册到 NocoBase 应用中。 - -```diff -class MyPlugin extends Plugin { - async load() { - // ... -+ this.app.schemaInitializerManager.add(tableColumnInitializers); -+ this.app.addComponents({ TableCollectionFieldInitializer }); - } -} -``` - - - -### 12. 增加操作列 - -修改 `useTableColumns`: - -```diff -function useTableColumns() { - // ... - const tableColumns = useMemo(() => { - return [ - ...columns, -+ { -+ title: 'Actions', -+ dataIndex: 'actions', -+ key: 'actions', -+ render: (value, record) => { -+ return ( -+ -+ -+ -+ -+ -+ ); -+ }, -+ }, - { - title: render(), - dataIndex: 'TABLE_COLUMN_INITIALIZER', - key: 'TABLE_COLUMN_INITIALIZER', - render: designable ? () =>
: null, - }, - ]; - }, [columns, render, designable]); - - return tableColumns; -} -``` - -然后我们实现 `ColumnView`。 - -```tsx | pure - -const ColumnView = observer( - () => { - const record = useCollectionRecord(); - const [open, setOpen] = useState(false); - - const showDrawer = () => { - setOpen(true); - }; - - const onClose = () => { - setOpen(false); - }; - return ( - <> - - -
{JSON.stringify(record, null, 2)}
-
- - ); - }, - { displayName: 'ColumnView' }, -); -``` - - diff --git a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/collections.ts b/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/collections.ts deleted file mode 100644 index 82ba795b8..000000000 --- a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/collections.ts +++ /dev/null @@ -1,128 +0,0 @@ -export const mainCollections = [ - { - name: 'users', - title: 'Users', - fields: [ - { - key: 'id', - name: 'id', - interface: 'id', - primaryKey: true, - uiSchema: { - type: 'number', - title: 'ID', - 'x-component': 'InputNumber', - 'x-read-pretty': true, - rawTitle: 'ID', - }, - }, - { - uiSchema: { - type: 'string', - title: 'Nickname', - 'x-component': 'Input', - }, - name: 'nickname', - type: 'string', - interface: 'input', - }, - { - uiSchema: { - type: 'string', - title: 'Email', - 'x-component': 'Input', - required: true, - }, - key: 'rrskwjl5wt1', - name: 'email', - type: 'string', - interface: 'email', - unique: true, - }, - { - name: 'favoriteColor', - type: 'string', - interface: 'color', - uiSchema: { - type: 'string', - 'x-component': 'ColorPicker', - default: '#1677FF', - title: 'Favorite Color', - }, - }, - ], - }, - { - name: 'roles', - title: 'Roles', - fields: [ - { - uiSchema: { - type: 'string', - title: 'Role UID', - 'x-component': 'Input', - }, - name: 'name', - type: 'uid', - interface: 'input', - primaryKey: true, - }, - { - uiSchema: { - type: 'string', - title: 'Role name', - 'x-component': 'Input', - }, - name: 'title', - type: 'string', - interface: 'input', - }, - { - name: 'description', - type: 'string', - }, - ], - }, -]; - -export const TestDBCollections = [ - { - name: 'test1', - title: 'Test1', - fields: [ - { - name: 'id', - interface: 'id', - primaryKey: true, - uiSchema: { - type: 'number', - title: 'ID', - 'x-component': 'InputNumber', - 'x-read-pretty': true, - }, - }, - { - name: 'field1', - interface: 'input', - uiSchema: { - type: 'string', - 'x-component': 'Input', - title: 'Field1', - }, - }, - { - name: 'field2', - interface: 'number', - uiSchema: { - 'x-component-props': { - step: '1', - stringMode: true, - }, - 'x-component': 'InputNumber', - title: 'Field2', - }, - defaultValue: 1, - }, - ], - }, -]; diff --git a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/createApp.tsx b/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/createApp.tsx deleted file mode 100644 index ebbc8ec12..000000000 --- a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/createApp.tsx +++ /dev/null @@ -1 +0,0 @@ -import { Application } from '@nocobase/client'; diff --git a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo1.tsx b/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo1.tsx deleted file mode 100644 index 8c3f6a54f..000000000 --- a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo1.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { Table } from 'antd'; -import React from 'react'; - -const MyTable = () => { - const dataSource = [ - { - key: '1', - name: 'Mike', - age: 32, - address: '10 Downing Street', - }, - { - key: '2', - name: 'John', - age: 42, - address: '10 Downing Street', - }, - ]; - - const columns = [ - { - title: 'Name', - dataIndex: 'name', - key: 'name', - }, - { - title: 'Age', - dataIndex: 'age', - key: 'age', - }, - { - title: 'Address', - dataIndex: 'address', - key: 'address', - }, - ]; - - return
; -}; - -export default MyTable; diff --git a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo10.tsx b/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo10.tsx deleted file mode 100644 index 844315f33..000000000 --- a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo10.tsx +++ /dev/null @@ -1,412 +0,0 @@ -import { Button, Drawer, Space, Table, TableProps } from 'antd'; -import React, { useEffect, useMemo, useState } from 'react'; -import { - CardItem, - CollectionField, - ColorFieldInterface, - ColorPicker, - DataBlockProvider, - EmailFieldInterface, - FormItem, - IdFieldInterface, - Input, - InputFieldInterface, - InputNumber, - NumberFieldInterface, - Plugin, - SchemaComponent, - SchemaInitializer, - SchemaInitializerItem, - SchemaSettings, - SchemaToolbar, - useCollection, - useCompile, - useDataBlock, - useDataBlockProps, - useDataBlockRequest, - useDataSourceManager, - useSchemaInitializer, - useSchemaInitializerRender, - useSchemaToolbar, - useSchemaToolbarRender, - withDynamicSchemaProps, -} from '@nocobase/client'; -import { Application } from '@nocobase/client'; -import { uid } from '@formily/shared'; -import { ISchema, RecursionField, Schema, observer, useField, useFieldSchema } from '@formily/react'; -import { mainCollections, TestDBCollections } from './collections'; -import { mock } from './mockData'; - -const MyTable = withDynamicSchemaProps(Table, { displayName: 'MyTable' }); - -const TableColumn = observer(() => { - const field = useField(); - return
{field.title}
; -}); - -function useTableProps(): TableProps { - const { tableProps } = useDataBlockProps(); - const { data, loading } = useDataBlockRequest(); - const dataSource = useMemo(() => data?.data || [], [data]); - const collection = useCollection(); - const field = useField(); - - useEffect(() => { - field.value = dataSource; - }, [dataSource]); - - const columns = useMemo(() => { - return collection.getFields().map((collectionField) => { - const tableFieldSchema = { - name: collectionField.name, - type: 'void', - title: collectionField.uiSchema?.title || collectionField.name, - 'x-component': 'TableColumn', - properties: { - [collectionField.name]: { - 'x-component': 'CollectionField', - 'x-read-pretty': true, - 'x-decorator-props': { - labelStyle: { - display: 'none', - }, - }, - }, - }, - }; - - return { - title: , - dataIndex: collectionField.name, - render(value, record, index) { - return ( - - ); - }, - }; - }); - }, [collection]); - - return { - ...tableProps, - loading, - dataSource, - columns, - }; -} - -const myTableSettings = new SchemaSettings({ - name: 'myTableSettings', - items: [ - { - name: 'bordered', - type: 'switch', - useComponentProps() { - const { props: blockSettingsProps, dn } = useDataBlock(); - - return { - title: 'Bordered', - checked: !!blockSettingsProps.tableProps?.bordered, - onChange: (checked) => { - // 修改 schema - dn.deepMerge({ 'x-decorator-props': { tableProps: { bordered: checked } } }); - }, - }; - }, - }, - { - type: 'remove', - name: 'remove', - }, - ], -}); - -const AddBlockButton = observer( - () => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - return render(); - }, - { displayName: 'AddBlockButton' }, -); - -const Page = observer( - (props) => { - return ( -
- {props.children} - -
- ); - }, - { displayName: 'Page' }, -); - -function useCollectionMenuItems() { - const dataSourceManager = useDataSourceManager(); - const allCollections = dataSourceManager.getAllCollections(); - const menus = useMemo( - () => - allCollections.map((item) => { - const { key, displayName, collections } = item; - return { - name: key, - label: displayName, - type: 'subMenu', - children: collections.map((collection) => { - return { - name: collection.name, - label: collection.title, - collection: collection.name, - dataSource: key, - }; - }), - }; - }), - [allCollections], - ); - - return menus; -} - -const CreateAction = () => { - const [open, setOpen] = useState(false); - - const showDrawer = () => { - setOpen(true); - }; - - const onClose = () => { - setOpen(false); - }; - - const compile = useCompile(); - const collection = useCollection(); - const title = compile(collection.title); - const fieldSchema = useFieldSchema(); - - const { render } = useSchemaToolbarRender(fieldSchema); - return ( - <> -
- {render()} - -
- -

Some contents...

-
- - ); -}; - -const createActionSettings = new SchemaSettings({ - name: 'createActionSettings', - items: [ - { - type: 'remove', - name: 'remove', - }, - ], -}); - -const RefreshAction = () => { - const { refresh } = useDataBlockRequest(); - return ; -}; - -const ActionBar = ({ children }) => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - - return ( -
- - {children} - {render()} - -
- ); -}; - -const CreateActionInitializer = () => { - const { insert } = useSchemaInitializer(); - const handleClick = () => { - insert({ - type: 'void', - 'x-component': 'CreateAction', - 'x-settings': 'createActionSettings', - }); - }; - return ; -}; - -const RefreshActionInitializer = () => { - const { insert } = useSchemaInitializer(); - const handleClick = () => { - insert({ - type: 'void', - 'x-component': 'RefreshAction', - }); - }; - return ; -}; - -const tableActionInitializers = new SchemaInitializer({ - name: 'tableActionInitializers', - title: 'Configure actions', - icon: 'SettingOutlined', - style: { - marginLeft: 8, - }, - items: [ - { - type: 'item', - name: 'addNew', - Component: CreateActionInitializer, - }, - { - type: 'item', - name: 'refresh', - Component: RefreshActionInitializer, - }, - ], -}); - -const TableDataBlockInitializer = () => { - const { insert, setVisible } = useSchemaInitializer(); - - const handleClick = ({ item }) => { - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - 'x-settings': 'myTableSettings', - 'x-decorator': 'DataBlockProvider', - 'x-toolbar': 'MyToolbar', - 'x-decorator-props': { - collection: item.collection, - dataSource: item.dataSource, - action: 'list', - tableProps: { - bordered: true, - }, - }, - properties: { - actions: { - type: 'void', - 'x-component': 'ActionBar', - 'x-initializer': 'tableActionInitializers', - }, - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - 'x-use-component-props': 'useTableProps', - }, - }, - }; - insert(tableSchema); - setVisible(false); - }; - - const menuItems = useCollectionMenuItems(); - - return ; -}; - -const MyToolbar = (props) => { - const collection = useCollection(); - const compile = useCompile(); - return ; -}; - -const myInitializer = new SchemaInitializer({ - name: 'myInitializer', - title: 'Add Block', - insertPosition: 'beforeEnd', - items: [ - { - name: 'table', - Component: TableDataBlockInitializer, - }, - ], -}); - -const rootSchema: ISchema = { - type: 'void', - name: 'root', - 'x-component': 'Page', - 'x-initializer': 'myInitializer', -}; - -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ MyTable, TableColumn, MyToolbar, ActionBar, CreateAction, RefreshAction }); - this.app.schemaInitializerManager.add(myInitializer); - this.app.schemaSettingsManager.add(myTableSettings); - this.app.schemaSettingsManager.add(createActionSettings); - this.app.addScopes({ useTableProps }); - this.app.schemaInitializerManager.add(tableActionInitializers); - } -} - -const Root = () => { - return ; -}; - -const app = new Application({ - plugins: [MyPlugin], - components: { - Page, - AddBlockButton, - CardItem, - DataBlockProvider, - InputNumber, - Input, - CollectionField, - ColorPicker, - FormItem, - }, - router: { - type: 'memory', - initialEntries: ['/'], - }, - designable: true, - dataSourceManager: { - collections: mainCollections, - dataSources: [ - { - key: 'test-db', - displayName: 'TestDB', - collections: TestDBCollections, - }, - ], - fieldInterfaces: [ - IdFieldInterface, - InputFieldInterface, - EmailFieldInterface, - ColorFieldInterface, - NumberFieldInterface, - ], - }, - apiClient: { - baseURL: 'http://localhost:8000', - }, -}); - -app.router.add('home', { - path: '/', - Component: Root, -}); - -mock(app); - -export default app.getRootComponent(); diff --git a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo11.tsx b/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo11.tsx deleted file mode 100644 index e362ddf03..000000000 --- a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo11.tsx +++ /dev/null @@ -1,492 +0,0 @@ -import { Button, Drawer, Space, Table, TableProps } from 'antd'; -import React, { useEffect, useMemo, useState } from 'react'; -import { - CardItem, - CollectionField, - ColorFieldInterface, - ColorPicker, - DataBlockProvider, - EmailFieldInterface, - FormItem, - IdFieldInterface, - Input, - InputFieldInterface, - InputNumber, - NumberFieldInterface, - Plugin, - SchemaComponent, - SchemaInitializer, - SchemaInitializerItem, - SchemaInitializerSwitch, - SchemaSettings, - SchemaToolbar, - useCollection, - useCompile, - useCurrentSchema, - useDataBlock, - useDataBlockProps, - useDataBlockRequest, - useDataSourceManager, - useDesignable, - useSchemaInitializer, - useSchemaInitializerItem, - useSchemaInitializerRender, - useSchemaToolbarRender, - withDynamicSchemaProps, -} from '@nocobase/client'; -import { Application } from '@nocobase/client'; -import { uid } from '@formily/shared'; -import { ISchema, RecursionField, observer, useField, useFieldSchema } from '@formily/react'; -import { mainCollections, TestDBCollections } from './collections'; -import { mock } from './mockData'; - -const MyTable = withDynamicSchemaProps(Table, { displayName: 'MyTable' }); - -const TableColumn = observer(() => { - const field = useField(); - return
{field.title}
; -}); - -function useTableColumns() { - const schema = useFieldSchema(); - const filed = useField(); - const { designable } = useDesignable(); - const { render } = useSchemaInitializerRender(schema['x-initializer'], schema['x-initializer-props']); - const columns = schema.mapProperties((tableField: any, name) => { - return { - title: , - dataIndex: name, - key: name, - width: 200, - render(value, record, index) { - return ; - }, - }; - }); - - const tableColumns = useMemo(() => { - return [ - ...columns, - { - title: render(), - dataIndex: 'TABLE_COLUMN_INITIALIZER', - key: 'TABLE_COLUMN_INITIALIZER', - width: 200, - render: designable ? () =>
: null, - }, - ]; - }, [columns, render, designable]); - - return tableColumns; -} - -function useTableProps(): TableProps { - const { tableProps } = useDataBlockProps(); - const { data, loading } = useDataBlockRequest(); - const dataSource = useMemo(() => data?.data || [], [data]); - const field = useField(); - - useEffect(() => { - field.value = dataSource; - }, [dataSource]); - - const columns = useTableColumns(); - - return { - ...tableProps, - loading, - dataSource, - columns, - }; -} - -const myTableSettings = new SchemaSettings({ - name: 'myTableSettings', - items: [ - { - name: 'bordered', - type: 'switch', - useComponentProps() { - const { props: blockSettingsProps, dn } = useDataBlock(); - - return { - title: 'Bordered', - checked: !!blockSettingsProps.tableProps?.bordered, - onChange: (checked) => { - // 修改 schema - dn.deepMerge({ 'x-decorator-props': { tableProps: { bordered: checked } } }); - }, - }; - }, - }, - { - type: 'remove', - name: 'remove', - }, - ], -}); - -const AddBlockButton = observer( - () => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - return render(); - }, - { displayName: 'AddBlockButton' }, -); - -const Page = observer( - (props) => { - return ( -
- {props.children} - -
- ); - }, - { displayName: 'Page' }, -); - -function useCollectionMenuItems() { - const dataSourceManager = useDataSourceManager(); - const allCollections = dataSourceManager.getAllCollections(); - const menus = useMemo( - () => - allCollections.map((item) => { - const { key, displayName, collections } = item; - return { - name: key, - label: displayName, - type: 'subMenu', - children: collections.map((collection) => { - return { - name: collection.name, - label: collection.title, - collection: collection.name, - dataSource: key, - }; - }), - }; - }), - [allCollections], - ); - - return menus; -} - -const CreateAction = () => { - const [open, setOpen] = useState(false); - - const showDrawer = () => { - setOpen(true); - }; - - const onClose = () => { - setOpen(false); - }; - - const compile = useCompile(); - const collection = useCollection(); - const title = compile(collection.title); - const fieldSchema = useFieldSchema(); - - const { render } = useSchemaToolbarRender(fieldSchema); - return ( - <> -
- {render()} - -
- -

Some contents...

-
- - ); -}; - -const createActionSettings = new SchemaSettings({ - name: 'createActionSettings', - items: [ - { - type: 'remove', - name: 'remove', - }, - ], -}); - -const RefreshAction = () => { - const { refresh } = useDataBlockRequest(); - return ; -}; - -const ActionBar = ({ children }) => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - - return ( -
- - {children} - {render()} - -
- ); -}; - -const CreateActionInitializer = () => { - const { insert } = useSchemaInitializer(); - const handleClick = () => { - insert({ - type: 'void', - 'x-component': 'CreateAction', - 'x-settings': 'createActionSettings', - }); - }; - return ; -}; - -const RefreshActionInitializer = () => { - const { insert } = useSchemaInitializer(); - const handleClick = () => { - insert({ - type: 'void', - 'x-component': 'RefreshAction', - }); - }; - return ; -}; - -const tableActionInitializers = new SchemaInitializer({ - name: 'tableActionInitializers', - title: 'Configure actions', - icon: 'SettingOutlined', - style: { - marginLeft: 8, - }, - items: [ - { - type: 'item', - name: 'addNew', - Component: CreateActionInitializer, - }, - { - type: 'item', - name: 'refresh', - Component: RefreshActionInitializer, - }, - ], -}); - -const TableDataBlockInitializer = () => { - const { insert, setVisible } = useSchemaInitializer(); - - const handleClick = ({ item }) => { - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - 'x-settings': 'myTableSettings', - 'x-decorator': 'DataBlockProvider', - 'x-toolbar': 'MyToolbar', - 'x-decorator-props': { - collection: item.collection, - dataSource: item.dataSource, - action: 'list', - tableProps: { - bordered: true, - }, - }, - properties: { - actions: { - type: 'void', - 'x-component': 'ActionBar', - 'x-initializer': 'tableActionInitializers', - }, - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - 'x-use-component-props': 'useTableProps', - 'x-initializer': 'tableColumnInitializers', - }, - }, - }; - insert(tableSchema); - setVisible(false); - }; - - const menuItems = useCollectionMenuItems(); - - return ; -}; - -const useTableColumnInitializerFields = () => { - const collection = useCollection(); - return collection.fields.map((collectionField) => { - const tableFieldSchema = { - name: collectionField.name, - type: 'void', - title: collectionField.uiSchema?.title || collectionField.name, - 'x-component': 'TableColumn', - properties: { - [collectionField.name]: { - 'x-component': 'CollectionField', - 'x-read-pretty': true, - 'x-decorator-props': { - labelStyle: { - display: 'none', - }, - }, - }, - }, - }; - return { - type: 'item', - name: collectionField.name, - title: collectionField?.uiSchema?.title || collectionField.name, - Component: 'TableCollectionFieldInitializer', - schema: tableFieldSchema, - }; - }); -}; - -export const TableCollectionFieldInitializer = () => { - const itemConfig = useSchemaInitializerItem(); - const { insert } = useSchemaInitializer(); - const { remove } = useDesignable(); - const schema = useFieldSchema(); - const exists = !!schema.properties?.[itemConfig.name]; - return ( - { - if (exists) { - return remove(schema.properties?.[itemConfig.name]); - } - insert(itemConfig.schema); - }} - /> - ); -}; - -const tableColumnInitializers = new SchemaInitializer({ - name: 'tableColumnInitializers', - insertPosition: 'beforeEnd', - icon: 'SettingOutlined', - title: 'Configure columns', - items: [ - { - name: 'displayFields', - type: 'itemGroup', - title: 'Display fields', - useChildren: useTableColumnInitializerFields, - }, - ], -}); - -const MyToolbar = (props) => { - const collection = useCollection(); - const compile = useCompile(); - return ; -}; - -const myInitializer = new SchemaInitializer({ - name: 'myInitializer', - title: 'Add Block', - insertPosition: 'beforeEnd', - items: [ - { - name: 'table', - Component: TableDataBlockInitializer, - }, - ], -}); - -const rootSchema: ISchema = { - type: 'void', - name: 'root', - 'x-component': 'Page', - 'x-initializer': 'myInitializer', -}; - -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ - MyTable, - TableColumn, - MyToolbar, - ActionBar, - CreateAction, - RefreshAction, - TableCollectionFieldInitializer, - }); - this.app.schemaInitializerManager.add(myInitializer); - this.app.schemaSettingsManager.add(myTableSettings); - this.app.addScopes({ useTableProps }); - this.app.schemaInitializerManager.add(tableActionInitializers); - this.app.schemaInitializerManager.add(tableColumnInitializers); - this.app.schemaSettingsManager.add(createActionSettings); - } -} - -const Root = () => { - return ; -}; - -const app = new Application({ - plugins: [MyPlugin], - components: { - Page, - AddBlockButton, - CardItem, - DataBlockProvider, - InputNumber, - Input, - CollectionField, - ColorPicker, - FormItem, - }, - router: { - type: 'memory', - initialEntries: ['/'], - }, - designable: true, - dataSourceManager: { - collections: mainCollections, - dataSources: [ - { - key: 'test-db', - displayName: 'TestDB', - collections: TestDBCollections, - }, - ], - fieldInterfaces: [ - IdFieldInterface, - InputFieldInterface, - EmailFieldInterface, - ColorFieldInterface, - NumberFieldInterface, - ], - }, - apiClient: { - baseURL: 'http://localhost:8000', - }, -}); - -app.router.add('home', { - path: '/', - Component: Root, -}); - -mock(app); - -export default app.getRootComponent(); diff --git a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo12.tsx b/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo12.tsx deleted file mode 100644 index 1fd5d9a67..000000000 --- a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo12.tsx +++ /dev/null @@ -1,532 +0,0 @@ -import { Button, Drawer, Space, Table, TableProps } from 'antd'; -import React, { useEffect, useMemo, useState } from 'react'; -import { - CardItem, - CollectionField, - ColorFieldInterface, - ColorPicker, - DataBlockProvider, - EmailFieldInterface, - FormItem, - IdFieldInterface, - Input, - InputFieldInterface, - InputNumber, - NumberFieldInterface, - Plugin, - CollectionRecordProvider, - SchemaComponent, - SchemaInitializer, - SchemaInitializerItem, - SchemaInitializerSwitch, - SchemaSettings, - SchemaToolbar, - useCollection, - useCompile, - useCurrentSchema, - useDataBlock, - useDataBlockProps, - useDataBlockRequest, - useDataSource, - useDataSourceManager, - useDesignable, - useCollectionRecord, - useSchemaInitializer, - useSchemaInitializerItem, - useSchemaInitializerRender, - useSchemaToolbarRender, - withDynamicSchemaProps, -} from '@nocobase/client'; -import { Application } from '@nocobase/client'; -import { uid } from '@formily/shared'; -import { ISchema, RecursionField, observer, useField, useFieldSchema } from '@formily/react'; -import { mainCollections, TestDBCollections } from './collections'; -import { mock } from './mockData'; - -const MyTable = withDynamicSchemaProps(Table, { displayName: 'MyTable' }); - -const TableColumn = observer(() => { - const field = useField(); - return
{field.title}
; -}); - -const ColumnView = observer( - () => { - const record = useCollectionRecord(); - const [open, setOpen] = useState(false); - - const showDrawer = () => { - setOpen(true); - }; - - const onClose = () => { - setOpen(false); - }; - return ( - <> - - -
{JSON.stringify(record, null, 2)}
-
- - ); - }, - { displayName: 'ColumnView' }, -); - -function useTableColumns() { - const schema = useFieldSchema(); - const filed = useField(); - const { designable } = useDesignable(); - const { render } = useSchemaInitializerRender(schema['x-initializer'], schema['x-initializer-props']); - const columns = schema.mapProperties((tableField: any, name) => { - return { - title: , - dataIndex: name, - key: name, - render(value, record, index) { - return ; - }, - }; - }); - const tableColumns = useMemo(() => { - return [ - ...columns, - { - title: 'Actions', - dataIndex: 'actions', - key: 'actions', - render: (value, record) => { - return ( - - - - - - ); - }, - }, - { - title: render(), - dataIndex: 'TABLE_COLUMN_INITIALIZER', - key: 'TABLE_COLUMN_INITIALIZER', - render: designable ? () =>
: null, - }, - ]; - }, [columns, render, designable]); - - return tableColumns; -} - -function useTableProps(): TableProps { - const { tableProps } = useDataBlockProps(); - const { data, loading } = useDataBlockRequest(); - const dataSource = useMemo(() => data?.data || [], [data]); - const field = useField(); - - useEffect(() => { - field.value = dataSource; - }, [dataSource]); - - const columns = useTableColumns(); - - return { - ...tableProps, - loading, - dataSource, - columns, - }; -} - -const myTableSettings = new SchemaSettings({ - name: 'myTableSettings', - items: [ - { - name: 'bordered', - type: 'switch', - useComponentProps() { - const { props: blockSettingsProps, dn } = useDataBlock(); - - return { - title: 'Bordered', - checked: !!blockSettingsProps.tableProps?.bordered, - onChange: (checked) => { - // 修改 schema - dn.deepMerge({ 'x-decorator-props': { tableProps: { bordered: checked } } }); - }, - }; - }, - }, - { - type: 'remove', - name: 'remove', - }, - ], -}); - -const AddBlockButton = observer( - () => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - return render(); - }, - { displayName: 'AddBlockButton' }, -); - -const Page = observer( - (props) => { - return ( -
- {props.children} - -
- ); - }, - { displayName: 'Page' }, -); - -function useCollectionMenuItems() { - const dataSourceManager = useDataSourceManager(); - const allCollections = dataSourceManager.getAllCollections(); - const menus = useMemo( - () => - allCollections.map((item) => { - const { key, displayName, collections } = item; - return { - name: key, - label: displayName, - type: 'subMenu', - children: collections.map((collection) => { - return { - name: collection.name, - label: collection.title, - collection: collection.name, - dataSource: key, - }; - }), - }; - }), - [allCollections], - ); - - return menus; -} - -const CreateAction = () => { - const [open, setOpen] = useState(false); - - const showDrawer = () => { - setOpen(true); - }; - - const onClose = () => { - setOpen(false); - }; - - const compile = useCompile(); - const collection = useCollection(); - const title = compile(collection.title); - const fieldSchema = useFieldSchema(); - - const { render } = useSchemaToolbarRender(fieldSchema); - return ( - <> -
- {render()} - -
- -

Some contents...

-
- - ); -}; - -const createActionSettings = new SchemaSettings({ - name: 'createActionSettings', - items: [ - { - type: 'remove', - name: 'remove', - }, - ], -}); - -const RefreshAction = () => { - const { refresh } = useDataBlockRequest(); - return ; -}; - -const ActionBar = ({ children }) => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - - return ( -
- - {children} - {render()} - -
- ); -}; - -const CreateActionInitializer = () => { - const { insert } = useSchemaInitializer(); - const handleClick = () => { - insert({ - type: 'void', - 'x-component': 'CreateAction', - 'x-settings': 'createActionSettings', - }); - }; - return ; -}; - -const RefreshActionInitializer = () => { - const { insert } = useSchemaInitializer(); - const handleClick = () => { - insert({ - type: 'void', - 'x-component': 'RefreshAction', - }); - }; - return ; -}; - -const tableActionInitializers = new SchemaInitializer({ - name: 'tableActionInitializers', - title: 'Configure actions', - icon: 'SettingOutlined', - style: { - marginLeft: 8, - }, - items: [ - { - type: 'item', - name: 'addNew', - Component: CreateActionInitializer, - }, - { - type: 'item', - name: 'refresh', - Component: RefreshActionInitializer, - }, - ], -}); - -const TableDataBlockInitializer = () => { - const { insert, setVisible } = useSchemaInitializer(); - - const handleClick = ({ item }) => { - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - 'x-settings': 'myTableSettings', - 'x-decorator': 'DataBlockProvider', - 'x-toolbar': 'MyToolbar', - 'x-decorator-props': { - collection: item.collection, - dataSource: item.dataSource, - action: 'list', - tableProps: { - bordered: true, - }, - }, - properties: { - actions: { - type: 'void', - 'x-component': 'ActionBar', - 'x-initializer': 'tableActionInitializers', - }, - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - 'x-use-component-props': 'useTableProps', - 'x-initializer': 'tableColumnInitializers', - }, - }, - }; - insert(tableSchema); - setVisible(false); - }; - - const menuItems = useCollectionMenuItems(); - - return ; -}; - -const useTableColumnInitializerFields = () => { - const collection = useCollection(); - return collection.fields.map((collectionField) => { - const tableFieldSchema = { - name: collectionField.name, - type: 'void', - title: collectionField.uiSchema?.title || collectionField.name, - 'x-component': 'TableColumn', - properties: { - [collectionField.name]: { - 'x-component': 'CollectionField', - 'x-read-pretty': true, - 'x-decorator-props': { - labelStyle: { - display: 'none', - }, - }, - }, - }, - }; - return { - type: 'item', - name: collectionField.name, - title: collectionField?.uiSchema?.title || collectionField.name, - Component: 'TableCollectionFieldInitializer', - schema: tableFieldSchema, - }; - }); -}; - -export const TableCollectionFieldInitializer = () => { - const itemConfig = useSchemaInitializerItem(); - const { insert } = useSchemaInitializer(); - const { remove } = useDesignable(); - const schema = useFieldSchema(); - const exists = !!schema.properties?.[itemConfig.name]; - return ( - { - if (exists) { - return remove(schema.properties?.[itemConfig.name]); - } - insert(itemConfig.schema); - }} - /> - ); -}; - -const tableColumnInitializers = new SchemaInitializer({ - name: 'tableColumnInitializers', - insertPosition: 'beforeEnd', - icon: 'SettingOutlined', - title: 'Configure columns', - items: [ - { - name: 'displayFields', - type: 'itemGroup', - title: 'Display fields', - useChildren: useTableColumnInitializerFields, - }, - ], -}); - -const MyToolbar = (props) => { - const collection = useCollection(); - const compile = useCompile(); - return ; -}; - -const myInitializer = new SchemaInitializer({ - name: 'myInitializer', - title: 'Add Block', - insertPosition: 'beforeEnd', - items: [ - { - name: 'table', - Component: TableDataBlockInitializer, - }, - ], -}); - -const rootSchema: ISchema = { - type: 'void', - name: 'root', - 'x-component': 'Page', - 'x-initializer': 'myInitializer', -}; - -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ - MyTable, - TableColumn, - MyToolbar, - ActionBar, - CreateAction, - RefreshAction, - TableCollectionFieldInitializer, - }); - this.app.schemaInitializerManager.add(myInitializer); - this.app.schemaSettingsManager.add(myTableSettings); - this.app.addScopes({ useTableProps }); - this.app.schemaInitializerManager.add(tableActionInitializers); - this.app.schemaInitializerManager.add(tableColumnInitializers); - this.app.schemaSettingsManager.add(createActionSettings); - } -} - -const Root = () => { - return ; -}; - -const app = new Application({ - plugins: [MyPlugin], - components: { - Page, - AddBlockButton, - CardItem, - DataBlockProvider, - InputNumber, - Input, - CollectionField, - ColorPicker, - FormItem, - }, - router: { - type: 'memory', - initialEntries: ['/'], - }, - designable: true, - dataSourceManager: { - collections: mainCollections, - dataSources: [ - { - key: 'test-db', - displayName: 'TestDB', - collections: TestDBCollections, - }, - ], - fieldInterfaces: [ - IdFieldInterface, - InputFieldInterface, - EmailFieldInterface, - ColorFieldInterface, - NumberFieldInterface, - ], - }, - apiClient: { - baseURL: 'http://localhost:8000', - }, -}); - -app.router.add('home', { - path: '/', - Component: Root, -}); - -mock(app); - -export default app.getRootComponent(); diff --git a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo2.tsx b/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo2.tsx deleted file mode 100644 index f487115da..000000000 --- a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo2.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import { Table } from 'antd'; -import React from 'react'; -import { CardItem, Plugin, SchemaComponent } from '@nocobase/client'; -import { Application } from '@nocobase/client'; -import { uid } from '@formily/shared'; - -const MyTable = () => { - const dataSource = [ - { - key: '1', - name: 'Mike', - age: 32, - address: '10 Downing Street', - }, - { - key: '2', - name: 'John', - age: 42, - address: '10 Downing Street', - }, - ]; - - const columns = [ - { - title: 'Name', - dataIndex: 'name', - key: 'name', - }, - { - title: 'Age', - dataIndex: 'age', - key: 'age', - }, - { - title: 'Address', - dataIndex: 'address', - key: 'address', - }, - ]; - - return
; -}; - -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ MyTable }); - } -} - -const tableSchema = { - name: 'demo', - type: 'void', - 'x-component': 'CardItem', - properties: { - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - }, - }, -}; - -const Root = () => { - return ; -}; - -const app = new Application({ - plugins: [MyPlugin], - components: { - CardItem, - }, - router: { - type: 'memory', - initialEntries: ['/'], - }, -}); - -app.router.add('root', { - path: '/', - Component: Root, -}); - -export default app.getRootComponent(); diff --git a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo3.tsx b/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo3.tsx deleted file mode 100644 index 1d899d6fb..000000000 --- a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo3.tsx +++ /dev/null @@ -1,147 +0,0 @@ -import { Table } from 'antd'; -import React, { useCallback } from 'react'; -import { - CardItem, - Plugin, - SchemaComponent, - SchemaInitializer, - SchemaInitializerItem, - useSchemaInitializer, - useSchemaInitializerRender, -} from '@nocobase/client'; -import { Application } from '@nocobase/client'; -import { uid } from '@formily/shared'; -import { ISchema, observer, useFieldSchema } from '@formily/react'; - -const MyTable = () => { - const dataSource = [ - { - key: '1', - name: 'Mike', - age: 32, - address: '10 Downing Street', - }, - { - key: '2', - name: 'John', - age: 42, - address: '10 Downing Street', - }, - ]; - - const columns = [ - { - title: 'Name', - dataIndex: 'name', - key: 'name', - }, - { - title: 'Age', - dataIndex: 'age', - key: 'age', - }, - { - title: 'Address', - dataIndex: 'address', - key: 'address', - }, - ]; - - return
; -}; - -const AddBlockButton = observer( - () => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - return render(); - }, - { displayName: 'AddBlockButton' }, -); - -const Page = observer( - (props) => { - return ( -
- {props.children} - -
- ); - }, - { displayName: 'Page' }, -); - -const TableDataBlockInitializer = () => { - const { insert, setVisible } = useSchemaInitializer(); - - const handleClick = useCallback( - ({ item }) => { - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - properties: { - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - }, - }, - }; - insert(tableSchema); - setVisible(false); - }, - [insert, setVisible], - ); - - return ; -}; - -const myInitializer = new SchemaInitializer({ - name: 'myInitializer', - title: 'Add Block', - insertPosition: 'beforeEnd', - items: [ - { - name: 'table', - Component: TableDataBlockInitializer, - }, - ], -}); - -const rootSchema: ISchema = { - type: 'void', - name: 'root', - 'x-component': 'Page', - 'x-initializer': 'myInitializer', -}; - -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ MyTable }); - this.app.schemaInitializerManager.add(myInitializer); - } -} - -const Root = () => { - return ; -}; - -const app = new Application({ - plugins: [MyPlugin], - components: { - Page, - AddBlockButton, - CardItem, - }, - router: { - type: 'memory', - initialEntries: ['/'], - }, - designable: true, -}); - -app.router.add('home', { - path: '/', - Component: Root, -}); - -export default app.getRootComponent(); diff --git a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo4.tsx b/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo4.tsx deleted file mode 100644 index 7c327227b..000000000 --- a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo4.tsx +++ /dev/null @@ -1,180 +0,0 @@ -import { Table } from 'antd'; -import React, { useMemo } from 'react'; -import { - CardItem, - DataBlockProvider, - Plugin, - SchemaComponent, - SchemaInitializer, - SchemaInitializerItem, - useCollection, - useDataBlockRequest, - useDataSourceManager, - useSchemaInitializer, - useSchemaInitializerRender, -} from '@nocobase/client'; -import { Application } from '@nocobase/client'; -import { uid } from '@formily/shared'; -import { ISchema, observer, useFieldSchema } from '@formily/react'; -import { mainCollections, TestDBCollections } from './collections'; -import { mock } from './mockData'; - -const MyTable = () => { - const { data, loading } = useDataBlockRequest(); - const dataSource = useMemo(() => data?.data || [], [data]); - const collection = useCollection(); - const columns = useMemo(() => { - return collection.getFields().map((collectionField) => { - return { - title: collectionField.uiSchema?.title || collectionField.name, - dataIndex: collectionField.name, - }; - }); - }, [collection]); - - return
; -}; - -const AddBlockButton = observer( - () => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - return render(); - }, - { displayName: 'AddBlockButton' }, -); - -const Page = observer( - (props) => { - return ( -
- {props.children} - -
- ); - }, - { displayName: 'Page' }, -); - -function useCollectionMenuItems() { - const dataSourceManager = useDataSourceManager(); - const allCollections = dataSourceManager.getAllCollections(); - const menus = useMemo( - () => - allCollections.map((item) => { - const { key, displayName, collections } = item; - return { - name: key, - label: displayName, - type: 'subMenu', - children: collections.map((collection) => { - return { - name: collection.name, - label: collection.title, - collection: collection.name, - dataSource: key, - }; - }), - }; - }), - [allCollections], - ); - - return menus; -} - -const TableDataBlockInitializer = () => { - const { insert, setVisible } = useSchemaInitializer(); - - const handleClick = ({ item }) => { - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - 'x-decorator': 'DataBlockProvider', - 'x-decorator-props': { - collection: item.collection, - dataSource: item.dataSource, - action: 'list', - }, - properties: { - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - }, - }, - }; - insert(tableSchema); - setVisible(false); - }; - - const menuItems = useCollectionMenuItems(); - - return ; -}; - -const myInitializer = new SchemaInitializer({ - name: 'myInitializer', - title: 'Add Block', - insertPosition: 'beforeEnd', - items: [ - { - name: 'table', - Component: TableDataBlockInitializer, - }, - ], -}); - -const rootSchema: ISchema = { - type: 'void', - name: 'root', - 'x-component': 'Page', - 'x-initializer': 'myInitializer', -}; - -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ MyTable }); - this.app.schemaInitializerManager.add(myInitializer); - } -} - -const Root = () => { - return ; -}; - -const app = new Application({ - plugins: [MyPlugin], - components: { - Page, - AddBlockButton, - CardItem, - DataBlockProvider, - }, - router: { - type: 'memory', - initialEntries: ['/'], - }, - designable: true, - dataSourceManager: { - collections: mainCollections, - dataSources: [ - { - key: 'test-db', - displayName: 'TestDB', - collections: TestDBCollections, - }, - ], - }, - apiClient: { - baseURL: 'http://localhost:8000', - }, -}); - -app.router.add('home', { - path: '/', - Component: Root, -}); - -mock(app); - -export default app.getRootComponent(); diff --git a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo5.tsx b/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo5.tsx deleted file mode 100644 index 51b09f7bc..000000000 --- a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo5.tsx +++ /dev/null @@ -1,236 +0,0 @@ -import { Table } from 'antd'; -import React, { useEffect, useMemo } from 'react'; -import { - CardItem, - CollectionField, - ColorFieldInterface, - ColorPicker, - DataBlockProvider, - EmailFieldInterface, - FormItem, - IdFieldInterface, - Input, - InputFieldInterface, - InputNumber, - NumberFieldInterface, - Plugin, - SchemaComponent, - SchemaInitializer, - SchemaInitializerItem, - useCollection, - useDataBlockRequest, - useDataSourceManager, - useSchemaInitializer, - useSchemaInitializerRender, -} from '@nocobase/client'; -import { Application } from '@nocobase/client'; -import { uid } from '@formily/shared'; -import { ISchema, RecursionField, observer, useField, useFieldSchema } from '@formily/react'; -import { mainCollections, TestDBCollections } from './collections'; -import { mock } from './mockData'; - -const TableColumn = observer(() => { - const field = useField(); - return
{field.title}
; -}); - -const MyTable = () => { - const { data, loading } = useDataBlockRequest(); - const dataSource = useMemo(() => data?.data || [], [data]); - const collection = useCollection(); - const field = useField(); - - useEffect(() => { - field.value = dataSource; - }, [dataSource]); - - const columns = useMemo(() => { - return collection.getFields().map((collectionField) => { - const tableFieldSchema = { - name: collectionField.name, - type: 'void', - title: collectionField.uiSchema?.title || collectionField.name, - 'x-component': 'TableColumn', - properties: { - [collectionField.name]: { - 'x-component': 'CollectionField', - 'x-read-pretty': true, - 'x-decorator-props': { - labelStyle: { - display: 'none', - }, - }, - }, - }, - }; - - return { - title: , - dataIndex: collectionField.name, - render(value, record, index) { - return ( - - ); - }, - }; - }); - }, [collection]); - - return
; -}; - -const AddBlockButton = observer( - () => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - return render(); - }, - { displayName: 'AddBlockButton' }, -); - -const Page = observer( - (props) => { - return ( -
- {props.children} - -
- ); - }, - { displayName: 'Page' }, -); - -function useCollectionMenuItems() { - const dataSourceManager = useDataSourceManager(); - const allCollections = dataSourceManager.getAllCollections(); - const menus = useMemo( - () => - allCollections.map((item) => { - const { key, displayName, collections } = item; - return { - name: key, - label: displayName, - type: 'subMenu', - children: collections.map((collection) => { - return { - name: collection.name, - label: collection.title, - collection: collection.name, - dataSource: key, - }; - }), - }; - }), - [allCollections], - ); - - return menus; -} - -const TableDataBlockInitializer = () => { - const { insert, setVisible } = useSchemaInitializer(); - - const handleClick = ({ item }) => { - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - 'x-decorator': 'DataBlockProvider', - 'x-decorator-props': { - collection: item.collection, - dataSource: item.dataSource, - action: 'list', - }, - properties: { - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - }, - }, - }; - insert(tableSchema); - setVisible(false); - }; - - const menuItems = useCollectionMenuItems(); - - return ; -}; - -const myInitializer = new SchemaInitializer({ - name: 'myInitializer', - title: 'Add Block', - insertPosition: 'beforeEnd', - items: [ - { - name: 'table', - Component: TableDataBlockInitializer, - }, - ], -}); - -const rootSchema: ISchema = { - type: 'void', - name: 'root', - 'x-component': 'Page', - 'x-initializer': 'myInitializer', -}; - -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ MyTable, TableColumn }); - this.app.schemaInitializerManager.add(myInitializer); - } -} - -const Root = () => { - return ; -}; - -const app = new Application({ - plugins: [MyPlugin], - components: { - Page, - AddBlockButton, - CardItem, - DataBlockProvider, - InputNumber, - Input, - CollectionField, - ColorPicker, - FormItem, - }, - router: { - type: 'memory', - initialEntries: ['/'], - }, - designable: true, - dataSourceManager: { - collections: mainCollections, - dataSources: [ - { - key: 'test-db', - displayName: 'TestDB', - collections: TestDBCollections, - }, - ], - fieldInterfaces: [ - IdFieldInterface, - InputFieldInterface, - EmailFieldInterface, - ColorFieldInterface, - NumberFieldInterface, - ], - }, - apiClient: { - baseURL: 'http://localhost:8000', - }, -}); - -app.router.add('home', { - path: '/', - Component: Root, -}); - -mock(app); - -export default app.getRootComponent(); diff --git a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo6.tsx b/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo6.tsx deleted file mode 100644 index a07197d3f..000000000 --- a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo6.tsx +++ /dev/null @@ -1,280 +0,0 @@ -import { Table, TableProps } from 'antd'; -import React, { useEffect, useMemo } from 'react'; -import { - CardItem, - CollectionField, - ColorFieldInterface, - ColorPicker, - DataBlockProvider, - EmailFieldInterface, - FormItem, - IdFieldInterface, - Input, - InputFieldInterface, - InputNumber, - NumberFieldInterface, - Plugin, - SchemaComponent, - SchemaInitializer, - SchemaInitializerItem, - SchemaSettings, - useCollection, - useDataBlock, - useDataBlockProps, - useDataBlockRequest, - useDataSourceManager, - useSchemaInitializer, - useSchemaInitializerRender, - withDynamicSchemaProps, -} from '@nocobase/client'; -import { Application } from '@nocobase/client'; -import { uid } from '@formily/shared'; -import { ISchema, RecursionField, observer, useField, useFieldSchema } from '@formily/react'; -import { mainCollections, TestDBCollections } from './collections'; -import { mock } from './mockData'; - -const MyTable = withDynamicSchemaProps(Table, { displayName: 'MyTable' }); - -const TableColumn = observer(() => { - const field = useField(); - return
{field.title}
; -}); - -function useTableProps(): TableProps { - const { tableProps } = useDataBlockProps(); - const { data, loading } = useDataBlockRequest(); - const dataSource = useMemo(() => data?.data || [], [data]); - const collection = useCollection(); - const field = useField(); - - useEffect(() => { - field.value = dataSource; - }, [dataSource]); - - const columns = useMemo(() => { - return collection.getFields().map((collectionField) => { - const tableFieldSchema = { - name: collectionField.name, - type: 'void', - title: collectionField.uiSchema?.title || collectionField.name, - 'x-component': 'TableColumn', - properties: { - [collectionField.name]: { - 'x-component': 'CollectionField', - 'x-read-pretty': true, - 'x-decorator-props': { - labelStyle: { - display: 'none', - }, - }, - }, - }, - }; - - return { - title: , - dataIndex: collectionField.name, - render(value, record, index) { - return ( - - ); - }, - }; - }); - }, [collection]); - - return { - ...tableProps, - loading, - dataSource, - columns, - rowKey: 'id', - }; -} - -const myTableSettings = new SchemaSettings({ - name: 'myTableSettings', - items: [ - { - name: 'bordered', - type: 'switch', - useComponentProps() { - const { props: blockSettingsProps, dn } = useDataBlock(); - return { - title: 'Bordered', - checked: !!blockSettingsProps.tableProps?.bordered, - onChange: (checked) => { - // 修改 schema - dn.deepMerge({ 'x-decorator-props': { tableProps: { bordered: checked } } }); - }, - }; - }, - }, - { - type: 'remove', - name: 'remove', - }, - ], -}); - -const AddBlockButton = observer( - () => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - return render(); - }, - { displayName: 'AddBlockButton' }, -); - -const Page = observer( - (props) => { - return ( -
- {props.children} - -
- ); - }, - { displayName: 'Page' }, -); - -function useCollectionMenuItems() { - const dataSourceManager = useDataSourceManager(); - const allCollections = dataSourceManager.getAllCollections(); - const menus = useMemo( - () => - allCollections.map((item) => { - const { key, displayName, collections } = item; - return { - name: key, - label: displayName, - type: 'subMenu', - children: collections.map((collection) => { - return { - name: collection.name, - label: collection.title, - collection: collection.name, - dataSource: key, - }; - }), - }; - }), - [allCollections], - ); - - return menus; -} - -const TableDataBlockInitializer = () => { - const { insert, setVisible } = useSchemaInitializer(); - - const handleClick = ({ item }) => { - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - 'x-settings': 'myTableSettings', - 'x-decorator': 'DataBlockProvider', - 'x-decorator-props': { - collection: item.collection, - dataSource: item.dataSource, - action: 'list', - tableProps: { - bordered: true, - }, - }, - properties: { - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - 'x-use-component-props': 'useTableProps', - }, - }, - }; - insert(tableSchema); - setVisible(false); - }; - - const menuItems = useCollectionMenuItems(); - return ; -}; - -const myInitializer = new SchemaInitializer({ - name: 'myInitializer', - title: 'Add Block', - insertPosition: 'beforeEnd', - items: [ - { - name: 'table', - Component: TableDataBlockInitializer, - }, - ], -}); - -const rootSchema: ISchema = { - type: 'void', - name: 'root', - 'x-component': 'Page', - 'x-initializer': 'myInitializer', -}; - -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ MyTable, TableColumn }); - this.app.schemaInitializerManager.add(myInitializer); - this.app.schemaSettingsManager.add(myTableSettings); - this.app.addScopes({ useTableProps }); - } -} - -const Root = () => { - return ; -}; - -const app = new Application({ - plugins: [MyPlugin], - components: { - Page, - AddBlockButton, - CardItem, - DataBlockProvider, - InputNumber, - Input, - CollectionField, - ColorPicker, - FormItem, - }, - router: { - type: 'memory', - initialEntries: ['/'], - }, - designable: true, - dataSourceManager: { - collections: mainCollections, - dataSources: [ - { - key: 'test-db', - displayName: 'TestDB', - collections: TestDBCollections, - }, - ], - fieldInterfaces: [ - IdFieldInterface, - InputFieldInterface, - EmailFieldInterface, - ColorFieldInterface, - NumberFieldInterface, - ], - }, - apiClient: { - baseURL: 'http://localhost:8000', - }, -}); - -app.router.add('home', { - path: '/', - Component: Root, -}); - -mock(app); - -export default app.getRootComponent(); diff --git a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo7.tsx b/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo7.tsx deleted file mode 100644 index 6acb8e01c..000000000 --- a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo7.tsx +++ /dev/null @@ -1,291 +0,0 @@ -import { Table, TableProps } from 'antd'; -import React, { useEffect, useMemo } from 'react'; -import { - CardItem, - CollectionField, - ColorFieldInterface, - ColorPicker, - DataBlockProvider, - EmailFieldInterface, - FormItem, - IdFieldInterface, - Input, - InputFieldInterface, - InputNumber, - NumberFieldInterface, - Plugin, - SchemaComponent, - SchemaInitializer, - SchemaInitializerItem, - SchemaSettings, - SchemaToolbar, - useCollection, - useCompile, - useDataBlock, - useDataBlockProps, - useDataBlockRequest, - useDataSource, - useDataSourceManager, - useSchemaInitializer, - useSchemaInitializerRender, - withDynamicSchemaProps, -} from '@nocobase/client'; -import { Application } from '@nocobase/client'; -import { uid } from '@formily/shared'; -import { ISchema, RecursionField, observer, useField, useFieldSchema } from '@formily/react'; -import { mainCollections, TestDBCollections } from './collections'; -import { mock } from './mockData'; - -const MyTable = withDynamicSchemaProps(Table, { displayName: 'MyTable' }); - -const TableColumn = observer(() => { - const field = useField(); - return
{field.title}
; -}); - -function useTableProps(): TableProps { - const { tableProps } = useDataBlockProps(); - const { data, loading } = useDataBlockRequest(); - const dataSource = useMemo(() => data?.data || [], [data]); - const collection = useCollection(); - const field = useField(); - - useEffect(() => { - field.value = dataSource; - }, [dataSource]); - - const columns = useMemo(() => { - return collection.getFields().map((collectionField) => { - const tableFieldSchema = { - name: collectionField.name, - type: 'void', - title: collectionField.uiSchema?.title || collectionField.name, - 'x-component': 'TableColumn', - properties: { - [collectionField.name]: { - 'x-component': 'CollectionField', - 'x-read-pretty': true, - 'x-decorator-props': { - labelStyle: { - display: 'none', - }, - }, - }, - }, - }; - - return { - title: , - dataIndex: collectionField.name, - render(value, record, index) { - return ( - - ); - }, - }; - }); - }, [collection]); - - return { - ...tableProps, - loading, - dataSource, - columns, - }; -} - -const myTableSettings = new SchemaSettings({ - name: 'myTableSettings', - items: [ - { - name: 'bordered', - type: 'switch', - useComponentProps() { - const { props: blockSettingsProps, dn } = useDataBlock(); - - return { - title: 'Bordered', - checked: !!blockSettingsProps.tableProps?.bordered, - onChange: (checked) => { - // 修改 schema - dn.deepMerge({ 'x-decorator-props': { tableProps: { bordered: checked } } }); - }, - }; - }, - }, - { - type: 'remove', - name: 'remove', - }, - ], -}); - -const AddBlockButton = observer( - () => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - return render(); - }, - { displayName: 'AddBlockButton' }, -); - -const Page = observer( - (props) => { - return ( -
- {props.children} - -
- ); - }, - { displayName: 'Page' }, -); - -function useCollectionMenuItems() { - const dataSourceManager = useDataSourceManager(); - const allCollections = dataSourceManager.getAllCollections(); - const menus = useMemo( - () => - allCollections.map((item) => { - const { key, displayName, collections } = item; - return { - name: key, - label: displayName, - type: 'subMenu', - children: collections.map((collection) => { - return { - name: collection.name, - label: collection.title, - collection: collection.name, - dataSource: key, - }; - }), - }; - }), - [allCollections], - ); - - return menus; -} - -const TableDataBlockInitializer = () => { - const { insert, setVisible } = useSchemaInitializer(); - - const handleClick = ({ item }) => { - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - 'x-settings': 'myTableSettings', - 'x-decorator': 'DataBlockProvider', - 'x-toolbar': 'MyToolbar', - 'x-decorator-props': { - collection: item.collection, - dataSource: item.dataSource, - action: 'list', - tableProps: { - bordered: true, - }, - }, - properties: { - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - 'x-use-component-props': 'useTableProps', - }, - }, - }; - insert(tableSchema); - setVisible(false); - }; - - const menuItems = useCollectionMenuItems(); - - return ; -}; - -const MyToolbar = (props) => { - const collection = useCollection(); - const compile = useCompile(); - return ; -}; - -const myInitializer = new SchemaInitializer({ - name: 'myInitializer', - title: 'Add Block', - insertPosition: 'beforeEnd', - items: [ - { - name: 'table', - Component: TableDataBlockInitializer, - }, - ], -}); - -const rootSchema: ISchema = { - type: 'void', - name: 'root', - 'x-component': 'Page', - 'x-initializer': 'myInitializer', -}; - -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ MyTable, TableColumn, MyToolbar }); - this.app.schemaInitializerManager.add(myInitializer); - this.app.schemaSettingsManager.add(myTableSettings); - this.app.addScopes({ useTableProps }); - } -} - -const Root = () => { - return ; -}; - -const app = new Application({ - plugins: [MyPlugin], - components: { - Page, - AddBlockButton, - CardItem, - DataBlockProvider, - InputNumber, - Input, - CollectionField, - ColorPicker, - FormItem, - }, - router: { - type: 'memory', - initialEntries: ['/'], - }, - designable: true, - dataSourceManager: { - collections: mainCollections, - dataSources: [ - { - key: 'test-db', - displayName: 'TestDB', - collections: TestDBCollections, - }, - ], - fieldInterfaces: [ - IdFieldInterface, - InputFieldInterface, - EmailFieldInterface, - ColorFieldInterface, - NumberFieldInterface, - ], - }, - apiClient: { - baseURL: 'http://localhost:8000', - }, -}); - -app.router.add('home', { - path: '/', - Component: Root, -}); - -mock(app); - -export default app.getRootComponent(); diff --git a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo8.tsx b/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo8.tsx deleted file mode 100644 index edb6b3310..000000000 --- a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo8.tsx +++ /dev/null @@ -1,351 +0,0 @@ -import { Button, Drawer, Space, Table, TableProps } from 'antd'; -import React, { useEffect, useMemo, useState } from 'react'; -import { - CardItem, - CollectionField, - ColorFieldInterface, - ColorPicker, - DataBlockProvider, - EmailFieldInterface, - FormItem, - IdFieldInterface, - Input, - InputFieldInterface, - InputNumber, - NumberFieldInterface, - Plugin, - SchemaComponent, - SchemaInitializer, - SchemaInitializerItem, - SchemaSettings, - SchemaToolbar, - useCollection, - useCompile, - useDataBlock, - useDataBlockProps, - useDataBlockRequest, - useDataSource, - useDataSourceManager, - useSchemaInitializer, - useSchemaInitializerRender, - withDynamicSchemaProps, -} from '@nocobase/client'; -import { Application } from '@nocobase/client'; -import { uid } from '@formily/shared'; -import { ISchema, RecursionField, observer, useField, useFieldSchema } from '@formily/react'; -import { mainCollections, TestDBCollections } from './collections'; -import { mock } from './mockData'; - -const MyTable = withDynamicSchemaProps(Table, { displayName: 'MyTable' }); - -const TableColumn = observer(() => { - const field = useField(); - return
{field.title}
; -}); - -function useTableProps(): TableProps { - const { tableProps } = useDataBlockProps(); - const { data, loading } = useDataBlockRequest(); - const dataSource = useMemo(() => data?.data || [], [data]); - const collection = useCollection(); - const field = useField(); - - useEffect(() => { - field.value = dataSource; - }, [dataSource]); - - const columns = useMemo(() => { - return collection.getFields().map((collectionField) => { - const tableFieldSchema = { - name: collectionField.name, - type: 'void', - title: collectionField.uiSchema?.title || collectionField.name, - 'x-component': 'TableColumn', - properties: { - [collectionField.name]: { - 'x-component': 'CollectionField', - 'x-read-pretty': true, - 'x-decorator-props': { - labelStyle: { - display: 'none', - }, - }, - }, - }, - }; - - return { - title: , - dataIndex: collectionField.name, - render(value, record, index) { - return ( - - ); - }, - }; - }); - }, [collection]); - - return { - ...tableProps, - loading, - dataSource, - columns, - }; -} - -const myTableSettings = new SchemaSettings({ - name: 'myTableSettings', - items: [ - { - name: 'bordered', - type: 'switch', - useComponentProps() { - const { props: blockSettingsProps, dn } = useDataBlock(); - - return { - title: 'Bordered', - checked: !!blockSettingsProps.tableProps?.bordered, - onChange: (checked) => { - // 修改 schema - dn.deepMerge({ 'x-decorator-props': { tableProps: { bordered: checked } } }); - }, - }; - }, - }, - { - type: 'remove', - name: 'remove', - }, - ], -}); - -const AddBlockButton = observer( - () => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - return render(); - }, - { displayName: 'AddBlockButton' }, -); - -const Page = observer( - (props) => { - return ( -
- {props.children} - -
- ); - }, - { displayName: 'Page' }, -); - -function useCollectionMenuItems() { - const dataSourceManager = useDataSourceManager(); - const allCollections = dataSourceManager.getAllCollections(); - const menus = useMemo( - () => - allCollections.map((item) => { - const { key, displayName, collections } = item; - return { - name: key, - label: displayName, - type: 'subMenu', - children: collections.map((collection) => { - return { - name: collection.name, - label: collection.title, - collection: collection.name, - dataSource: key, - }; - }), - }; - }), - [allCollections], - ); - - return menus; -} - -const CreateAction = () => { - const [open, setOpen] = useState(false); - - const showDrawer = () => { - setOpen(true); - }; - - const onClose = () => { - setOpen(false); - }; - - const compile = useCompile(); - const collection = useCollection(); - const title = compile(collection.title); - - return ( - <> - - -

Some contents...

-
- - ); -}; - -const RefreshAction = () => { - const { refresh } = useDataBlockRequest(); - return ; -}; - -const ActionBar = () => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - - return ( -
- - - - {render()} - -
- ); -}; - -const TableDataBlockInitializer = () => { - const { insert, setVisible } = useSchemaInitializer(); - - const handleClick = ({ item }) => { - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - 'x-settings': 'myTableSettings', - 'x-decorator': 'DataBlockProvider', - 'x-toolbar': 'MyToolbar', - 'x-decorator-props': { - collection: item.collection, - dataSource: item.dataSource, - action: 'list', - tableProps: { - bordered: true, - }, - }, - properties: { - actions: { - type: 'void', - 'x-component': 'ActionBar', - 'x-initializer': 'tableActionInitializers', - }, - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - 'x-use-component-props': 'useTableProps', - }, - }, - }; - insert(tableSchema); - setVisible(false); - }; - - const menuItems = useCollectionMenuItems(); - - return ; -}; - -const MyToolbar = (props) => { - const collection = useCollection(); - const compile = useCompile(); - return ; -}; - -const myInitializer = new SchemaInitializer({ - name: 'myInitializer', - title: 'Add Block', - insertPosition: 'beforeEnd', - items: [ - { - name: 'table', - Component: TableDataBlockInitializer, - }, - ], -}); - -const rootSchema: ISchema = { - type: 'void', - name: 'root', - 'x-component': 'Page', - 'x-initializer': 'myInitializer', -}; - -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ MyTable, TableColumn, MyToolbar, ActionBar }); - this.app.schemaInitializerManager.add(myInitializer); - this.app.schemaSettingsManager.add(myTableSettings); - this.app.addScopes({ useTableProps }); - } -} - -const Root = () => { - return ; -}; - -const app = new Application({ - plugins: [MyPlugin], - components: { - Page, - AddBlockButton, - CardItem, - DataBlockProvider, - InputNumber, - Input, - CollectionField, - ColorPicker, - FormItem, - }, - router: { - type: 'memory', - initialEntries: ['/'], - }, - designable: true, - dataSourceManager: { - collections: mainCollections, - dataSources: [ - { - key: 'test-db', - displayName: 'TestDB', - collections: TestDBCollections, - }, - ], - fieldInterfaces: [ - IdFieldInterface, - InputFieldInterface, - EmailFieldInterface, - ColorFieldInterface, - NumberFieldInterface, - ], - }, - apiClient: { - baseURL: 'http://localhost:8000', - }, -}); - -app.router.add('home', { - path: '/', - Component: Root, -}); - -mock(app); - -export default app.getRootComponent(); diff --git a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo9.tsx b/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo9.tsx deleted file mode 100644 index f5cf4261b..000000000 --- a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/demo9.tsx +++ /dev/null @@ -1,394 +0,0 @@ -import { Button, Drawer, Space, Table, TableProps } from 'antd'; -import React, { useEffect, useMemo, useState } from 'react'; -import { - CardItem, - CollectionField, - ColorFieldInterface, - ColorPicker, - DataBlockProvider, - EmailFieldInterface, - FormItem, - IdFieldInterface, - Input, - InputFieldInterface, - InputNumber, - NumberFieldInterface, - Plugin, - SchemaComponent, - SchemaInitializer, - SchemaInitializerItem, - SchemaSettings, - SchemaToolbar, - useCollection, - useCompile, - useDataBlock, - useDataBlockProps, - useDataBlockRequest, - useDataSource, - useDataSourceManager, - useSchemaInitializer, - useSchemaInitializerRender, - withDynamicSchemaProps, -} from '@nocobase/client'; -import { Application } from '@nocobase/client'; -import { uid } from '@formily/shared'; -import { ISchema, RecursionField, observer, useField, useFieldSchema } from '@formily/react'; -import { mainCollections, TestDBCollections } from './collections'; -import { mock } from './mockData'; - -const MyTable = withDynamicSchemaProps(Table, { displayName: 'MyTable' }); - -const TableColumn = observer(() => { - const field = useField(); - return
{field.title}
; -}); - -function useTableProps(): TableProps { - const { tableProps } = useDataBlockProps(); - const { data, loading } = useDataBlockRequest(); - const dataSource = useMemo(() => data?.data || [], [data]); - const collection = useCollection(); - const field = useField(); - - useEffect(() => { - field.value = dataSource; - }, [dataSource]); - - const columns = useMemo(() => { - return collection.getFields().map((collectionField) => { - const tableFieldSchema = { - name: collectionField.name, - type: 'void', - title: collectionField.uiSchema?.title || collectionField.name, - 'x-component': 'TableColumn', - properties: { - [collectionField.name]: { - 'x-component': 'CollectionField', - 'x-read-pretty': true, - 'x-decorator-props': { - labelStyle: { - display: 'none', - }, - }, - }, - }, - }; - - return { - title: , - dataIndex: collectionField.name, - render(value, record, index) { - return ( - - ); - }, - }; - }); - }, [collection]); - - return { - ...tableProps, - loading, - dataSource, - columns, - }; -} - -const myTableSettings = new SchemaSettings({ - name: 'myTableSettings', - items: [ - { - name: 'bordered', - type: 'switch', - useComponentProps() { - const { props: blockSettingsProps, dn } = useDataBlock(); - - return { - title: 'Bordered', - checked: !!blockSettingsProps.tableProps?.bordered, - onChange: (checked) => { - // 修改 schema - dn.deepMerge({ 'x-decorator-props': { tableProps: { bordered: checked } } }); - }, - }; - }, - }, - { - type: 'remove', - name: 'remove', - }, - ], -}); - -const AddBlockButton = observer( - () => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - return render(); - }, - { displayName: 'AddBlockButton' }, -); - -const Page = observer( - (props) => { - return ( -
- {props.children} - -
- ); - }, - { displayName: 'Page' }, -); - -function useCollectionMenuItems() { - const dataSourceManager = useDataSourceManager(); - const allCollections = dataSourceManager.getAllCollections(); - const menus = useMemo( - () => - allCollections.map((item) => { - const { key, displayName, collections } = item; - return { - name: key, - label: displayName, - type: 'subMenu', - children: collections.map((collection) => { - return { - name: collection.name, - label: collection.title, - collection: collection.name, - dataSource: key, - }; - }), - }; - }), - [allCollections], - ); - - return menus; -} - -const CreateAction = () => { - const [open, setOpen] = useState(false); - - const showDrawer = () => { - setOpen(true); - }; - - const onClose = () => { - setOpen(false); - }; - - const compile = useCompile(); - const collection = useCollection(); - const title = compile(collection.title); - - return ( - <> - - -

Some contents...

-
- - ); -}; - -const RefreshAction = () => { - const { refresh } = useDataBlockRequest(); - return ; -}; - -const ActionBar = ({ children }) => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - - return ( -
- - {children} - {render()} - -
- ); -}; - -const CreateActionInitializer = () => { - const { insert } = useSchemaInitializer(); - const handleClick = () => { - insert({ - type: 'void', - 'x-component': 'CreateAction', - }); - }; - return ; -}; - -const RefreshActionInitializer = () => { - const { insert } = useSchemaInitializer(); - const handleClick = () => { - insert({ - type: 'void', - 'x-component': 'RefreshAction', - }); - }; - return ; -}; - -const tableActionInitializers = new SchemaInitializer({ - name: 'tableActionInitializers', - title: 'Configure actions', - icon: 'SettingOutlined', - style: { - marginLeft: 8, - }, - items: [ - { - type: 'item', - name: 'addNew', - Component: CreateActionInitializer, - }, - { - type: 'item', - name: 'refresh', - Component: RefreshActionInitializer, - }, - ], -}); - -const TableDataBlockInitializer = () => { - const { insert, setVisible } = useSchemaInitializer(); - - const handleClick = ({ item }) => { - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - 'x-settings': 'myTableSettings', - 'x-decorator': 'DataBlockProvider', - 'x-toolbar': 'MyToolbar', - 'x-decorator-props': { - collection: item.collection, - dataSource: item.dataSource, - action: 'list', - tableProps: { - bordered: true, - }, - }, - properties: { - actions: { - type: 'void', - 'x-component': 'ActionBar', - 'x-initializer': 'tableActionInitializers', - }, - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - 'x-use-component-props': 'useTableProps', - }, - }, - }; - insert(tableSchema); - setVisible(false); - }; - - const menuItems = useCollectionMenuItems(); - - return ; -}; - -const MyToolbar = (props) => { - const collection = useCollection(); - const compile = useCompile(); - return ; -}; - -const myInitializer = new SchemaInitializer({ - name: 'myInitializer', - title: 'Add Block', - insertPosition: 'beforeEnd', - items: [ - { - name: 'table', - Component: TableDataBlockInitializer, - }, - ], -}); - -const rootSchema: ISchema = { - type: 'void', - name: 'root', - 'x-component': 'Page', - 'x-initializer': 'myInitializer', -}; - -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ MyTable, TableColumn, MyToolbar, ActionBar, CreateAction, RefreshAction }); - this.app.schemaInitializerManager.add(myInitializer); - this.app.schemaSettingsManager.add(myTableSettings); - this.app.addScopes({ useTableProps }); - this.app.schemaInitializerManager.add(tableActionInitializers); - } -} - -const Root = () => { - return ; -}; - -const app = new Application({ - plugins: [MyPlugin], - components: { - Page, - AddBlockButton, - CardItem, - DataBlockProvider, - InputNumber, - Input, - CollectionField, - ColorPicker, - FormItem, - }, - router: { - type: 'memory', - initialEntries: ['/'], - }, - designable: true, - dataSourceManager: { - collections: mainCollections, - dataSources: [ - { - key: 'test-db', - displayName: 'TestDB', - collections: TestDBCollections, - }, - ], - fieldInterfaces: [ - IdFieldInterface, - InputFieldInterface, - EmailFieldInterface, - ColorFieldInterface, - NumberFieldInterface, - ], - }, - apiClient: { - baseURL: 'http://localhost:8000', - }, -}); - -app.router.add('home', { - path: '/', - Component: Root, -}); - -mock(app); - -export default app.getRootComponent(); diff --git a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/mockData.ts b/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/mockData.ts deleted file mode 100644 index 59bff781e..000000000 --- a/packages/core/client/docs/zh-CN/core/data-block/tmp-demos/mockData.ts +++ /dev/null @@ -1,79 +0,0 @@ -import type { Application } from '@nocobase/client'; -import MockAdapter from 'axios-mock-adapter'; - -const mockData = { - 'users:list': { - data: [ - { - id: '1', - nickname: 'Jack Ma', - email: 'test@gmail.com', - favoriteColor: '#1677FF', - }, - { - id: '2', - email: 'jim@gmail.com', - nickname: 'Jim Green', - favoriteColor: '#36C', - }, - { - id: '3', - nickname: 'Tom Cat', - email: 'tom@gmail.com', - favoriteColor: '#F0F', - }, - ], - }, - 'users:destroy': { - result: 'ok', - }, - 'roles:list': { - data: [ - { - name: 'root', - title: 'Root', - description: 'Root', - }, - { - name: 'admin', - title: 'Admin', - description: 'Admin description', - }, - ], - }, - 'test1:list': { - data: [ - { - id: '1', - field1: 'aaa', - field2: 1, - }, - { - id: '2', - field1: 'bbb', - field2: 2, - }, - { - id: '3', - field1: 'ccc', - field2: 3, - }, - ], - }, -}; - -export function mock(app: Application) { - const mock = new MockAdapter(app.apiClient.axios); - - Object.entries(mockData).forEach(([url, data]) => { - mock.onGet(url).reply(async (config) => { - return [200, data]; - }); - mock.onPost(url).reply(async (config) => { - return [200, data]; - }); - mock.onDelete(url).reply(async (config) => { - return [200, data]; - }); - }); -} diff --git a/packages/core/client/docs/zh-CN/core/data-block/tmp.md b/packages/core/client/docs/zh-CN/core/data-block/tmp.md deleted file mode 100644 index 49807329c..000000000 --- a/packages/core/client/docs/zh-CN/core/data-block/tmp.md +++ /dev/null @@ -1,1149 +0,0 @@ -# 临时 - - -## 区块介绍 - - -## 区块扩展 - -### 1. 先简单定义一个 Table 组件 - -```tsx | pure -const MyTable = () => { - const dataSource = [ - { - key: '1', - name: 'Mike', - age: 32, - address: '10 Downing Street', - }, - { - key: '2', - name: 'John', - age: 42, - address: '10 Downing Street', - }, - ]; - - const columns = [ - { - title: 'Name', - dataIndex: 'name', - key: 'name', - }, - { - title: 'Age', - dataIndex: 'age', - key: 'age', - }, - { - title: 'Address', - dataIndex: 'address', - key: 'address', - }, - ]; - - return
; -} -``` - - - -### 2. 使用 UI Schema 的方式将组件渲染到页面上 - -先将组件注册到 NocoBase 应用中 - -```tsx | pure -import { Plugin } from '@nocobase/client'; - -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ MyTable }) - } -} -``` - -然后定义 UI Schema,并通过 `SchemaComponent` 渲染到页面上。 - -```tsx | pure -const tableSchema = { - name: 'demo', - type: 'void', - 'x-component': 'CardItem', - properties: { - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - }, - }, -} - -const Root = () => { - return -} - -app.router.add('root', { - path: '/', - Component: Root, -}) -``` - - - -关于 UI Schema 的更多信息请参考 [UI Schema](/core/ui-schema/schema-component) 和 [UI Schema Quick Start](https://docs-cn.nocobase.com/development/client/ui-schema/quick-start) - -其中 `CardItem` 是 NocoBase 的内置组件,相当于外层的容器。 - -### 3. 使用 `SchemaInitializer` 将组件动态添加到页面上 - -首先我们将 `Root` 组件更换 Schema 为 `rootSchema`。 - -```tsx | pure -const rootSchema: ISchema = { - type: 'void', - name: 'root', - 'x-component': 'Page', - 'x-initializer': 'myInitializer', -}; - -const Root = () => { - return ; -}; -``` - -其中 `Page` 的定义如下: - -```tsx | pure -import { observer } from "@formily/react"; - -const AddBlockButton = observer(() => { - const fieldSchema = useFieldSchema(); - const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - return render(); -}, { displayName: 'AddBlockButton' }); - -const Page = observer( - (props) => { - return ( -
- {props.children} - -
- ); - }, - { displayName: 'Page' }, -); -``` - -其中: - -- `useSchemaInitializerRender()`:用于获取 `SchemaInitializer` 的渲染函数,具体用法请参考 [useSchemaInitializerRender](/core/ui-schema/schema-initializer#useschemainitializer)。 -- `useFieldSchema()`:用于获取当前字段的 schema,具体用法请参考 [useFieldSchema](/core/ui-schema/designable#usefieldschema)。 -- `observer`:用于将函数组件转换为响应式组件,具体用法请参考 [observer](https://react.formilyjs.org/api/shared/observer)。 - -`myInitializer` 的定义如下: - -```tsx | pure -const TableDataBlockInitializer = () => { - const { insert, setVisible } = useSchemaInitializer(); - - const handleClick = useCallback(({ item }) => { - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - properties: { - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - }, - }, - }; - insert(tableSchema); - setVisible(false); - }, [insert, setVisible]); - - return ; -}; - -const myInitializer = new SchemaInitializer({ - name: 'myInitializer', - title: 'Add Block', - insertPosition: 'beforeEnd', - items: [ - { - name: 'table', - Component: TableDataBlockInitializer, - }, - ], -}); -``` - -我们将 `tableSchema` 放到了 `TableDataBlockInitializer` 中,当点击 `Add Block` 时,会将 `tableSchema` 插入到页面上。 - -关于 SchemaInitializer 的更多信息请参考 [SchemaInitializer](/core/ui-schema/schema-initializer) 和 [SchemaInitializer Quick Start](https://docs-cn.nocobase.com/development/client/ui-schema/quick-start#schemainitializer)。 - -最后将 `myInitializer` 注册到 NocoBase 应用中。 - -```diff -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ MyTable }) -+ this.app.schemaInitializerManager.add(myInitializer); - } -} -``` - - - -在真正的插件开发过程中只需要定义和添加 `myInitializer` 和 `MyTable` 即可,`Page` 和 `Root` 是 NocoBase 内置的组件,无需重复定义。 - - -### 4. 从数据表中读取数据 - -上述 Table 中的数据是固定数据,我们需要动态的获取数据并渲染。 - -```diff -+ function useCollectionMenuItems() { -+ const dataSourceManager = useDataSourceManager(); -+ const allCollections = dataSourceManager.getAllCollections(); -+ const menus = useMemo( -+ () => allCollections.map((item) => { -+ const { key, displayName, collections } = item; -+ return { -+ name: key, -+ label: displayName, -+ type: 'subMenu', -+ children: collections.map((collection) => { -+ return { -+ name: collection.name, -+ label: collection.title, -+ collection: collection.name, -+ dataSource: key, -+ } -+ }) -+ }; -+ }), -+ [allCollections], -+ ); -+ -+ return menus; -+ } - -const TableDataBlockInitializer = () => { - const { insert, setVisible } = useSchemaInitializer(); - - const handleClick = ({ item }) => { - const tableSchema = { - type: 'void', -+ 'x-decorator': 'DataBlockProvider', -+ 'x-decorator-props': { -+ collection: item.collection, -+ dataSource: item.dataSource, -+ action: 'list', -+ }, - 'x-component': 'CardItem', - properties: { - [uid()]: { - type: 'array', - 'x-component': 'MyTable', - }, - }, - } - insert(tableSchema); - setVisible(false); - }; - -+ const collectionMenuItems = useCollectionMenuItems(); - return ; -}; -``` - -其中: - -- [DataBlockProvider](/core/data-block/data-block-provider) 是 NocoBase 的内置组件,主要作用有4个: - - 提供 Collection 表结构信息 - - 提供 Collection 表的数据 - - 提供对数据增删改查的 [Resource](https://docs.nocobase.com/api/sdk#action-api) 对象 - - 提供区块的配置信息 - -- item:是当前点击的菜单对象,包括 `collection` 和 `dataSource`。 -- `useCollectionMenuItems`:是一个自定义的 hook,用于获取所有的 Collection 表信息,返回一个菜单数组。 - - `dataSourceManager`:用于获取数据源管理器,具体用法请参考 [useDataSourceManager](/core/data-source/data-source-manager-provider#usedatasourcemanager)。 - - -然后我们修改 `MyTable` 组件 - -```diff -const MyTable = () => { -- const dataSource = [ -- { -- key: '1', -- name: 'Mike', -- age: 32, -- address: '10 Downing Street', -- }, -- { -- key: '2', -- name: 'John', -- age: 42, -- address: '10 Downing Street', -- }, -- ]; -- -- const columns = [ -- { -- title: 'Name', -- dataIndex: 'name', -- key: 'name', -- }, -- { -- title: 'Age', -- dataIndex: 'age', -- key: 'age', -- }, -- { -- title: 'Address', -- dataIndex: 'address', -- key: 'address', -- }, -- ]; - - -+ const { data, loading } = useDataBlockRequest(); -+ const dataSource = useMemo(() => data?.data || [], [data]); - -+ const collection = useCollection(); -+ const columns = useMemo(() => { -+ return collection.getFields().map((collectionField) => { -+ return { -+ title: compile(collectionField.uiSchema?.title || collectionField.name), -+ dataIndex: collectionField.name, -+ }; -+ }); -+ }, [collection, compile]); - - return
; -} -``` - -其中: - -- `useDataBlockRequest()`:由 [DataBlockProvider](/core/data-block/data-block-provider) 组件里面的 [DataBlockRequestProvider](/core/data-block/data-block-request-provider) 提供,用于获取对应的数据表结构。 -- `useCollection()`:由 [DataBlockProvider](/core/data-block/data-block-provider) 组件里面的 [DataBlockRequestProvider](/core/data-source/collection-provider) 提供,用于获取当前 Collection 的信息。 - - - -### 5. 将字段渲染为自定义组件 - -上面一步仅是把数据渲染成普通的字符串,还需要进一步把字段渲染成不同的组件。 - -我们以 `favoriteColor` 字段为例,其数据结构如下: - -```json -{ - "name": "favoriteColor", - "type": "string", - "interface": "color", - "uiSchema": { - "type": "string", - "x-component": "ColorPicker", - "default": "#1677FF", - "title": "Favorite Color" - } -} -``` - -其和渲染相关的是 `uiSchema` 字段和 `interface` 字段,`interface` 相当于一些公共的配置,`uiSchema` 相当于一些私有的配置,更多信息请参考 [CollectionField](/core/data-source/collection-field)。 - -```diff -+ useEffect(() => { -+ field.value = dataSource; -+ }, [dataSource]); - - const columns = useMemo(() => { - return collection.getFields().map((collectionField) => { -+ const tableFieldSchema = { - name: collectionField.name, -+ type: 'void', -+ title: collectionField.uiSchema?.title || collectionField.name, -+ 'x-component': 'TableColumn', -+ properties: { -+ [collectionField.name]: { -+ 'x-component': 'CollectionField', -+ 'x-read-pretty': true, -+ 'x-decorator-props': { -+ labelStyle: { -+ display: 'none', -+ }, -+ }, -+ }, -+ }, -+ }; -+ -+ return { -- title: collectionField.uiSchema?.title || collectionField.name, -+ title: , - dataIndex: collectionField.name, -+ render(value, record, index) { -+ return ; -+ }, -+ }; - }); - }, [collection]); -``` - -```diff -+ const TableColumn = observer(() => { -+ const field = useField(); -+ return
{field.title}
; -+ }); - -class MyPlugin extends Plugin { - async load() { - // ... -+ this.app.addComponents({ TableColumn }); - } -} -``` - -其中: - -`field.value = dataSource` 用于将数据赋值给 `MyTable` 这一层的 `field`,相当于: - -```diff -const tableSchema = { - // ... - properties: { - [uid()]: { - type: 'array', -+ value: dataSource, - 'x-component': 'MyTable', - }, - }, -}; -``` - -然后使用 `RecursionField` 组件将字段渲染成自定义组件,因为是数组,所以需要加上 `index`,这样子组件才能正确的读取到数据。 - -关于 `RecursionField` 的更多信息请参考 [RecursionField](https://react.formilyjs.org/api/components/recursion-fieldeld)。 - - - -### 6. 区块属性配置 - -首先我们先修改 `tableSchema`。 - -```diff - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', -+ 'x-settings': 'myTableSettings', - 'x-decorator': 'DataBlockProvider', - 'x-decorator-props': { - collection: item.collection, - dataSource: item.dataSource, - action: 'list', -+ tableProps: { -+ bordered: true, -+ }, - }, - properties: { - [uid()]: { - type: 'array', - 'x-component': 'MyTable', -+ 'x-use-component-props': 'useTableProps', - }, - }, -} -``` - -其中: - -- `x-settings`:用于指定区块的配置信息,具体用法请参考 [SchemaSettings](/core/ui-schema/schema-settings)。 -- `tableProps`:Table 的属性 -- `x-use-component-props`:用于动态读取的 UI Schema 属性 - -关于 `useTableProps` 的定义,我们先将 `MyTable` 的属性单独抽离为一个 Hook。 - -```tsx | pure -function useTableProps(): TableProps { - const { data, loading } = useDataBlockRequest(); - const dataSource = useMemo(() => data?.data || [], [data]); - const collection = useCollection(); - - const field = useField(); - - useEffect(() => { - field.value = dataSource; - }, [dataSource]); - - const columns = useMemo(() => { - return collection.getFields().map((collectionField) => { - const tableFieldSchema = { - name: collectionField.name, - type: 'void', - title: collectionField.uiSchema?.title || collectionField.name, - 'x-component': 'TableColumn', - properties: { - [collectionField.name]: { - 'x-component': 'CollectionField', - 'x-read-pretty': true, - 'x-decorator-props': { - labelStyle: { - display: 'none', - }, - }, - }, - }, - }; - - return { - title: , - dataIndex: collectionField.name, - render(value, record, index) { - return ; - }, - }; - }); - }, [collection]); - - return { - loading, - dataSource, - columns, - }; -} -``` - -然后增加如下内容: - -```diff -function useTableProps(): TableProps { -+ const { tableProps } = useDataBlockProps(); - // ... - - return { -+ ...tableProps, - loading, - dataSource, - columns, - }; -} -``` - -其中: - -- `useDataBlockProps()`:用于获取区块的配置信息,具体用法请参考 [useDataBlockProps](/core/data-block/data-block-provider#usedatablockprops)。 - - -再将 `MyTable` 组件使用 `withDynamicSchemaProps` 包裹。 - -```tsx | pure -const MyTable = withDynamicSchemaProps(Table, { displayName: 'MyTable' }); -``` - -`withDynamicSchemaProps` 的作用是能读取 Schema 中的 `x-use-component-props` 属性,将其解析并执行,然后将结果传递给组件。 - -然后我们实现 `myTableSettings`: - -```tsx | pure -const myTableSettings = new SchemaSettings({ - name: 'myTableSettings', - items: [ - { - name: 'bordered', - type: 'switch', - useComponentProps() { - const { props: blockSettingsProps, dn } = useDataBlock(); - - return { - title: 'Bordered', - checked: !!blockSettingsProps.tableProps?.bordered, - onChange: (checked) => { - // 修改 schema - dn.deepMerge({ 'x-decorator-props': { tableProps: { bordered: checked } } }); - }, - }; - }, - }, - { - type: 'remove', - name: 'remove', - } - ], -}); -``` - -然后我们将 `myTableSettings` 和 `useTableProps` 注册到 NocoBase 应用中。 - -```diff -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ MyTable }) - this.app.schemaInitializerManager.add(myInitializer); -+ this.app.schemaSettingsManager.add(myTableSettings); -+ this.app.addScopes({ useTableProps }); - } -} -``` - -以上各个部分的关系如下: - -- `tableSchema`:`tableProps` 存储属性配置信息 -- `DataBlockProvider`:读取 `tableSchema` 的配置,并通过 `useDataBlockProps` 传递子组件 -- `useTableProps`:通过 `useDataBlockProps` 获取 `DataBlockProvider` 提供的配置 -- `MyTable`:通过 `withDynamicSchemaProps` 自动读取到 `'x-use-component-props': 'useTableProps'` 进行编译,执行 `useTableProps()` 获取到配置传递给 `Table` -- `myTableSettings`:通过 `useDataBlock()` 并修改配置 `DataBlockProvider` 提供的配置 - -然后在右上角的 `Settings` 中可以看到 `Bordered` 选项,可以动态修改 `Table` 的 `bordered` 属性。 - - - - -### 7. 区块 Toolbar 配置 - -我们还可以给区块增加 Toolbar 配置,让其在左上角显示所属的 Collection 表信息。 - -我们先修改 `tableSchema`。 - -```diff - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', -+ 'x-toolbar': 'MyToolbar', - // ... -} -``` - -然后我们实现 `MyToolbar`。 - -```tsx | pure -const MyToolbar = (props) => { - const collection = useCollection(); - const compile = useCompile(); - return -} -``` - -然后我们将 `MyToolbar` 注册到 NocoBase 应用中。 - -```diff -class MyPlugin extends Plugin { - async load() { - this.app.addComponents({ MyTable }) - this.app.schemaInitializerManager.add(myInitializer); - this.app.schemaSettingsManager.add(myTableSettings); - this.app.addScopes({ useTableProps }); -+ this.app.addComponents({ MyToolbar }); - } -} -``` - -这样左上角 Toolbar 就会显示所属的 Collection 表信息。 - -关于 `SchemaToolbar` 的更多信息请参考 [SchemaToolbar](/core/ui-schema/schema-toolbar)。 - - - -### 8. 增加顶部操作按钮 - -我们可以给区块增加顶部操作按钮,比如增加 `Add New` 和 `Refresh` 新增列表数据按钮。 - -我们先修改 `tableSchema`。 - -```diff - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - // ... - properties: { -+ actions: { -+ type: 'void', -+ 'x-component': 'ActionBar', -+ }, - // ... - } -} -``` - -然后我们实现 `ActionBar`。 - -```tsx | pure -const CreateAction = () => { - const [open, setOpen] = useState(false); - - const showDrawer = () => { - setOpen(true); - }; - - const onClose = () => { - setOpen(false); - }; - - const compile = useCompile(); - const collection = useCollection(); - const title = compile(collection.title); - - return <> - - -

Some contents...

-
- -} - -const RefreshAction = () => { - const { refresh } = useDataBlockRequest(); - return -} - -const ActionBar = () => { - return ( -
- - - - -
- ) -}; -``` - -其中: - -- `useDataBlockRequest()`: 用于获取区块的请求对象,具体用法请参考 [useDataBlockRequest](/core/data-block/data-block-request-provider#usedatablockrequest)。 - -然后我们将 `ActionBar` 注册到 NocoBase 应用中。 - -```diff -class MyPlugin extends Plugin { - async load() { - // ... -+ this.app.addComponents({ ActionBar }); - } -} -``` - - - -### 9. 动态配置顶部操作按钮 - -上面的 `ActionBar` 里面的 `CreateAction` 和 `RefreshAction` 是固定的,我们可以将其配置动态化。 - -首先修改 `tableSchema`。 - -```diff - const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - // ... - properties: { - actions: { - type: 'void', - 'x-component': 'ActionBar', -+ 'x-initializer': 'tableActionInitializers', - }, - // ... - } -} -``` - -然后我们实现 `tableActionInitializers`。 - -```tsx | pure -const CreateActionInitializer = () => { - const { insert } = useSchemaInitializer(); - const handleClick = () => { - insert({ - type: 'void', - 'x-component': 'CreateAction', - }); - }; - return ; -} - - -const RefreshActionInitializer = () => { - const { insert } = useSchemaInitializer(); - const handleClick = () => { - insert({ - type: 'void', - 'x-component': 'RefreshAction', - }); - }; - return ; -} - -const tableActionInitializers = new SchemaInitializer({ - name: 'tableActionInitializers', - title: "Configure actions", - icon: 'SettingOutlined', - style: { - marginLeft: 8, - }, - items: [ - { - type: 'item', - name: 'addNew', - title: "Add New", - Component: CreateActionInitializer, - }, - { - type: 'item', - name: 'refresh', - title: "Refresh", - Component: RefreshActionInitializer, - }, - ] -}) -``` - -然后修改 `ActionBar`: - -```diff -const ActionBar = ({ children }) => { -+ const fieldSchema = useFieldSchema(); -+ const { render } = useSchemaInitializerRender(fieldSchema['x-initializer']); - - return ( -
- -+ {children} -+ {render()} - -
- ) -}; -``` - -然后我们将 `tableActionInitializers` 和 `CreateAction`、`RefreshAction` 注册到 NocoBase 应用中。 - -```diff -class MyPlugin extends Plugin { - async load() { - // ... -+ this.app.addComponents({ CreateAction, RefreshAction }); -+ this.app.schemaInitializerManager.add(tableActionInitializers); - } -} -``` - - - -### 10. 操作按钮的配置 - -目前的操作按钮只能添加,不能删除或者配置 ,我们可以通过 `SchemaSettings` 来配置。 - -这里以 `Add New` 按钮为例。首先我们修改 `CreateActionInitializer`。 - -```diff -const CreateActionInitializer = () => { - const { insert } = useSchemaInitializer(); - const handleClick = () => { - insert({ - type: 'void', - 'x-component': 'CreateAction', -+ 'x-settings': 'createActionSettings', - }); - }; - return ; -}; -``` - -然后我们实现 `createActionSettings`。 - -```tsx | pure -const createActionSettings = new SchemaSettings({ - name: 'createActionSettings', - items: [ - { - type: 'remove', - name: 'remove', - }, - ], -}) -``` - -然后我们将 `createActionSettings` 注册到 NocoBase 应用中。 - -```diff -class MyPlugin extends Plugin { - async load() { - // ... -+ this.app.schemaSettingsManager.add(createActionSettings); - } -} -``` - -最后将 `createActionSettings` 渲染出来。 - -```diff -const CreateAction = () => { - const [open, setOpen] = useState(false); - - const showDrawer = () => { - setOpen(true); - }; - - const onClose = () => { - setOpen(false); - }; - - const compile = useCompile(); - const collection = useCollection(); - const title = compile(collection.title); - -+ const fieldSchema = useFieldSchema(); -+ const { render } = useSchemaToolbarRender(fieldSchema); - - return ( - <> -- -+
-+ {render()} -+ -+
- -

Some contents...

-
- - ); -}; -``` - -需要注意的是,要将 `render()` 和 `Add New` 包裹在一个 `div` 中,这样 `render()` 才能正确的渲染。 - - - -### 11. 动态配置 table 列 - -首先修改 `tableSchema`。 - -```diff -const tableSchema = { - type: 'void', - 'x-component': 'CardItem', - // ... - properties: { - action: { - // ... - }, - [uid()]: { - type: 'array', - 'x-component': 'MyTable', -+ 'x-initializer': 'tableColumnInitializers', - 'x-use-component-props': 'useTableProps', - }, - } -} -``` - -然后我们实现 `tableColumnInitializers`。 - -```tsx | pure -const tableColumnInitializers = new SchemaInitializer({ - name: 'tableColumnInitializers', - insertPosition: 'beforeEnd', - icon: 'SettingOutlined', - title: 'Configure columns', - items: [ - { - name: 'displayFields', - type: 'itemGroup', - title: 'Display fields', - useChildren: useTableColumnInitializerFields, - } - ], -}) - -const useTableColumnInitializerFields = () => { - const collection = useCollection(); - return collection.fields.map((collectionField) => { - const tableFieldSchema = { - name: collectionField.name, - type: 'void', - title: collectionField.uiSchema?.title || collectionField.name, - 'x-component': 'TableColumn', - properties: { - [collectionField.name]: { - 'x-component': 'CollectionField', - 'x-read-pretty': true, - 'x-decorator-props': { - labelStyle: { - display: 'none', - }, - }, - }, - }, - }; - return { - type: 'item', - name: collectionField.name, - title: collectionField?.uiSchema?.title || collectionField.name, - Component: 'TableCollectionFieldInitializer', - schema: tableFieldSchema, - }; - }); -}; - -export const TableCollectionFieldInitializer = () => { - const itemConfig = useSchemaInitializerItem(); - const { insert } = useSchemaInitializer(); - const { remove } = useDesignable(); - const schema = useFieldSchema(); - const exists = !!schema.properties?.[itemConfig.name]; - return ( - { - if (exists) { - return remove(schema.properties?.[itemConfig.name]); - } - insert(itemConfig.schema); - }} - /> - ); -}; -``` - -然后我们修改 `useTableProps`,增加 `useTableColumns`: - -```diff -function useTableProps(): TableProps { - const { tableProps } = useDataBlockProps(); - const { data, loading } = useDataBlockRequest(); - const dataSource = useMemo(() => data?.data || [], [data]); -+ const columns = useTableColumns(); - - return { - ...tableProps, - loading, - dataSource, - columns, - }; -} -``` - -```tsx | pure -function useTableColumns() { - const schema = useFieldSchema(); - const filed = useField(); - const { designable } = useDesignable(); - const { render } = useSchemaInitializerRender(schema['x-initializer'], schema['x-initializer-props']); - const columns = schema.mapProperties((tableField: any, name) => { - return { - title: , - dataIndex: name, - key: name, - width: 200, - render(value, record, index) { - return ; - }, - }; - }); - - const tableColumns = useMemo(() => { - return [ - ...columns, - { - title: render(), - dataIndex: 'TABLE_COLUMN_INITIALIZER', - key: 'TABLE_COLUMN_INITIALIZER', - width: 200, - render: designable ? () =>
: null, - }, - ]; - }, [columns, render, designable]); - - return tableColumns; -} -``` - -然后我们将 `tableColumnInitializers` 和 `TableCollectionFieldInitializer` 注册到 NocoBase 应用中。 - -```diff -class MyPlugin extends Plugin { - async load() { - // ... -+ this.app.schemaInitializerManager.add(tableColumnInitializers); -+ this.app.addComponents({ TableCollectionFieldInitializer }); - } -} -``` - - - -### 12. 增加操作列 - -修改 `useTableColumns`: - -```diff -function useTableColumns() { - // ... - const tableColumns = useMemo(() => { - return [ - ...columns, -+ { -+ title: 'Actions', -+ dataIndex: 'actions', -+ key: 'actions', -+ render: (value, record) => { -+ return ( -+ -+ -+ -+ -+ -+ ); -+ }, -+ }, - { - title: render(), - dataIndex: 'TABLE_COLUMN_INITIALIZER', - key: 'TABLE_COLUMN_INITIALIZER', - render: designable ? () =>
: null, - }, - ]; - }, [columns, render, designable]); - - return tableColumns; -} -``` - -然后我们实现 `ColumnView`。 - -```tsx | pure - -const ColumnView = observer( - () => { - const record = useCollectionRecord(); - const [open, setOpen] = useState(false); - - const showDrawer = () => { - setOpen(true); - }; - - const onClose = () => { - setOpen(false); - }; - return ( - <> - - -
{JSON.stringify(record, null, 2)}
-
- - ); - }, - { displayName: 'ColumnView' }, -); -``` - - diff --git a/packages/core/client/src/schema-settings/DateFormat/ExpiresRadio.tsx b/packages/core/client/src/schema-settings/DateFormat/ExpiresRadio.tsx index cfd367620..2823db613 100644 --- a/packages/core/client/src/schema-settings/DateFormat/ExpiresRadio.tsx +++ b/packages/core/client/src/schema-settings/DateFormat/ExpiresRadio.tsx @@ -1,5 +1,5 @@ import { css } from '@emotion/css'; -import moment from 'moment'; +import dayjs from 'dayjs'; import { connect, mapProps } from '@formily/react'; import { useBoolean } from 'ahooks'; @@ -7,7 +7,7 @@ import { Input, Radio, Space } from 'antd'; import React, { useState } from 'react'; import { useToken } from '../../'; -const date = moment(); +const date = dayjs(); const spaceCSS = css` width: 100%; @@ -16,7 +16,7 @@ const spaceCSS = css` } `; export const DateFormatCom = (props?) => { - const date = moment(); + const date = dayjs(); return (
{props.format} @@ -57,7 +57,6 @@ const InternalExpiresRadio = (props) => { onChange(v.target.value); } }; - return (