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 (
-
- );
- },
- { 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 (
-
- );
- },
- { 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 (
-
- );
- },
- { 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 (
-
- );
- },
- { 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 (
-
- );
- },
- { 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 (
-
- );
- },
- { 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 (
-
- );
- },
- { 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 (
-
- );
- },
- { 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 (
-
- );
- },
- { 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 (
-
- );
- },
- { 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 (
-
- );
- },
- { 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 (
-
- );
- },
- { 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 (
-
- );
- },
- { 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 (
-
- );
- },
- { 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 (
-
- );
- },
- { 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 (
-
- );
- },
- { 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 (
-
- );
- },
- { 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 (
-
- );
- },
- { 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 (
-
- );
- },
- { 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 (
-
- );
- },
- { 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 (
-
- );
- },
- { 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 (
-
- );
- },
- { 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 (