diff --git a/packages/client/src/blocks/DesignableSchemaField/index.tsx b/packages/client/src/blocks/DesignableSchemaField/index.tsx index e5f7ff5bc..336c0cea4 100644 --- a/packages/client/src/blocks/DesignableSchemaField/index.tsx +++ b/packages/client/src/blocks/DesignableSchemaField/index.tsx @@ -40,7 +40,7 @@ import { Menu } from '../menu'; import { Password } from '../password'; import { Radio } from '../radio'; import { Select } from '../select'; -import { Table } from '../table'; +import { Table, useTableCreateAction, useTableDestroyAction } from '../table'; import { Tabs } from '../tabs'; import { TimePicker } from '../time-picker'; import { Upload } from '../upload'; @@ -59,6 +59,8 @@ export const scope = { useLogin, useRegister, useSubmit, + useTableCreateAction, + useTableDestroyAction, }; export const components = { diff --git a/packages/client/src/blocks/action/index.md b/packages/client/src/blocks/action/index.md index d5da98ebc..c3a29588c 100644 --- a/packages/client/src/blocks/action/index.md +++ b/packages/client/src/blocks/action/index.md @@ -29,7 +29,7 @@ group: import React from 'react'; import { SchemaRenderer, registerScope } from '../'; -function useCustomAction() { +function useAction() { return { run() { alert('这是自定义的操作逻辑'); @@ -37,17 +37,13 @@ function useCustomAction() { } } -registerScope({ - useCustomAction, -}); - const schema = { type: 'void', name: 'action1', title: '按钮', 'x-component': 'Action', 'x-component-props': { - useAction: '{{ useCustomAction }}' + useAction, }, }; @@ -188,6 +184,17 @@ export default () => { ```tsx import React from 'react'; import { SchemaRenderer } from '../'; +import { useVisibleContext } from './'; + +function useAction() { + const { visible, setVisible } = useVisibleContext(); + return { + async run() { + console.log({ visible }) + setVisible(false); + } + } +} const schema = { type: 'void', @@ -200,88 +207,21 @@ const schema = { title: '弹窗标题', 'x-component': 'Action.Modal', 'x-component-props': {}, - properties: { - }, - }, - }, -}; - -export default () => { - return -} -``` - -## Action.Container - 指定容器内打开 - -```tsx -import React, { useRef } from 'react'; -import { SchemaRenderer } from '../'; -import { ActionContext } from './'; - -const schema = { - type: 'void', - name: 'action1', - title: '按钮', - 'x-component': 'Action', - properties: { - container1: { - type: 'void', - title: '页面标题', - 'x-component': 'Action.Container', - properties: { - input: { - type: 'string', - title: '字段', - 'x-designable-bar': 'FormItem.DesignableBar', - 'x-decorator': 'FormItem', - 'x-component': 'Input', - } - }, - }, - }, -}; - -export default () => { - const ref = useRef(); - console.log('containerRef2222', ref) - return ( -
- - - -
目标容器:
-
-
- ) -} -``` - -## Action.DesignableBar - 按钮配置操作栏 - -```tsx -import React from 'react'; -import { SchemaRenderer } from '../'; - -const schema = { - type: 'void', - name: 'action1', - title: '按钮', - 'x-component': 'Action', - 'x-designable-bar': 'Action.DesignableBar', - properties: { - drawer1: { - type: 'void', - title: '抽屉标题', - 'x-component': 'Action.Drawer', - 'x-component-props': {}, properties: { input: { type: 'string', 'x-decorator': 'FormItem', 'x-component': 'Input', }, + close: { + type: 'void', + name: 'action1', + title: '关闭', + 'x-component': 'Action', + 'x-component-props': { + useAction, + }, + }, action2: { type: 'void', title: '打开二级抽屉', @@ -291,7 +231,7 @@ const schema = { drawer1: { type: 'void', title: '二级抽屉标题', - 'x-component': 'Action.Drawer', + 'x-component': 'Action.Modal', 'x-component-props': {}, properties: { input: { @@ -311,3 +251,45 @@ export default () => { return } ``` + +## Action.Container - 指定容器内打开 + +```tsx +import React, { useRef } from 'react'; +import { SchemaRenderer } from '../'; +import { ActionContext } from './'; + +export default () => { + const containerRef = useRef(); + const schema = { + type: 'void', + name: 'action1', + title: '按钮', + 'x-component': 'Action', + 'x-component-props': { + containerRef + }, + properties: { + container1: { + type: 'void', + title: '页面标题', + 'x-component': 'Action.Container', + properties: { + input: { + type: 'string', + title: '字段', + 'x-designable-bar': 'FormItem.DesignableBar', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + } + }, + }, + }, + }; + return ( +
+ +
+ ) +} +``` diff --git a/packages/client/src/blocks/action/index.tsx b/packages/client/src/blocks/action/index.tsx index 5e18ff0de..0f71d58d7 100644 --- a/packages/client/src/blocks/action/index.tsx +++ b/packages/client/src/blocks/action/index.tsx @@ -10,9 +10,8 @@ import { Schema, useField, } from '@formily/react'; -import { Button, Dropdown, Menu, Popover, Space } from 'antd'; +import { Button, Dropdown, Menu, Popover, Space, Drawer, Modal } from 'antd'; import { Link, useHistory, LinkProps } from 'react-router-dom'; -import Drawer from '../../components/Drawer'; import { SchemaRenderer, useDesignable } from '../'; import ReactDOM from 'react-dom'; import get from 'lodash/get'; @@ -22,6 +21,7 @@ import { useMount } from 'ahooks'; import { uid } from '@formily/shared'; import './style.less'; +import constate from 'constate'; export function useDefaultAction() { return { @@ -95,92 +95,81 @@ function useDesignableBar() { }; } -export const ActionContext = createContext({ containerRef: null }); +const [VisibleProvider, useVisibleContext] = constate( + (props: any = {}) => { + const { initialVisible = false, containerRef = null } = props; + const [visible, setVisible] = useState(initialVisible); -export const Action: ActionType = observer((props) => { + return { containerRef, visible, setVisible }; + }, +); + +export { VisibleProvider, useVisibleContext }; + +const BaseAction = observer((props: any) => { const { useAction = useDefaultAction, ...others } = props; - const { containerRef } = useContext(ActionContext); const field = useField(); - const schema = useFieldSchema(); const { run } = useAction(); const { DesignableBar } = useDesignableBar(); + const { setVisible } = useVisibleContext(); + const schema = useFieldSchema(); - const renderContainer = () => { - let childSchema = null; - if (schema.properties) { - const key = Object.keys(schema.properties).shift(); - const current = schema.properties[key]; - childSchema = current; - } - if (childSchema && childSchema['x-component'] === 'Action.Container') { - containerRef && - ReactDOM.render( -
- -
, - containerRef.current, - ); - } - }; - - useMount(() => { - renderContainer(); - }); - - let childSchema = null; - - if (schema.properties) { - const key = Object.keys(schema.properties).shift(); - const current = schema.properties[key]; - childSchema = current; - } - console.log({ schema }); - if (childSchema && childSchema['x-component'] === 'Action.Popover') { - return ( - - -
- } - > - - - ); - } - - return ( + const renderButton = () => ( ); + + const popover = schema.reduceProperties((items, current) => { + if (current['x-component'] === 'Action.Popover') { + return current; + } + return null; + }, null); + + if (popover) { + return ( + + ); + } + + return ( + <> + {renderButton()} + {props.children} + + ); +}); + +export const Action: ActionType = observer((props: any) => { + const schema = useFieldSchema(); + if (schema.properties) { + return ( + + + + ); + } + return ; }); Action.Link = observer((props) => { @@ -198,21 +187,51 @@ Action.URL = observer((props) => { ); }); -Action.Container = ({ children }) => { - return children; -}; +Action.Container = observer((props) => { + const { visible, setVisible } = useVisibleContext(); + return visible &&
{props.children}
; +}); -Action.Popover = ({ children }) => { - return children; -}; +Action.Popover = observer((props) => { + const schema = useFieldSchema(); + return ( + + {schema['x-button']} + + ); +}); -Action.Drawer = ({ children }) => { - return children; -}; +Action.Drawer = observer((props) => { + const field = useField(); + const { visible, setVisible } = useVisibleContext(); + return ( + setVisible(false)} + > + {props.children} + + ); +}); -Action.Modal = ({ children }) => { - return children; -}; +Action.Modal = observer((props) => { + const field = useField(); + const { visible, setVisible } = useVisibleContext(); + return ( + setVisible(false)} + > + {props.children} + + ); +}); Action.DesignableBar = () => { const field = useField(); diff --git a/packages/client/src/blocks/database-field/index.md b/packages/client/src/blocks/database-field/index.md index 94da656ca..211c487dd 100644 --- a/packages/client/src/blocks/database-field/index.md +++ b/packages/client/src/blocks/database-field/index.md @@ -16,6 +16,7 @@ import React from 'react'; import { createForm } from '@formily/core'; import { SchemaRenderer } from '../'; import { observer, connect, useField } from '@formily/react'; +import Editor from '@monaco-editor/react'; const schema = { type: 'object', @@ -50,73 +51,13 @@ const form = createForm(); export default observer(() => { return (
- {JSON.stringify(form.values, null, 2)} +
) }) ``` - -```tsx -import React from 'react'; -import { SchemaRenderer } from '../'; - -const schema = { - type: 'object', - properties: { - array: { - type: 'array', - // title: '数据表字段', - 'x-component': 'ArrayCollapse', - 'x-component-props': { - accordion: true, - }, - // maxItems: 3, - 'x-decorator': 'FormItem', - items: { - type: 'object', - 'x-component': 'ArrayCollapse.CollapsePanel', - 'x-component-props': { - header: '字段', - }, - properties: { - index: { - type: 'void', - 'x-component': 'ArrayCollapse.Index', - }, - input: { - type: 'string', - 'x-decorator': 'FormItem', - title: 'Input', - required: true, - 'x-component': 'Input', - }, - remove: { - type: 'void', - 'x-component': 'ArrayCollapse.Remove', - }, - moveUp: { - type: 'void', - 'x-component': 'ArrayCollapse.MoveUp', - }, - moveDown: { - type: 'void', - 'x-component': 'ArrayCollapse.MoveDown', - }, - }, - }, - properties: { - addition: { - type: 'void', - title: '添加字段', - 'x-component': 'ArrayCollapse.Addition', - }, - }, - }, - } -}; - -export default () => { - return -} -``` diff --git a/packages/client/src/blocks/database-field/index.tsx b/packages/client/src/blocks/database-field/index.tsx index 4ed82d9dd..906cb29d3 100644 --- a/packages/client/src/blocks/database-field/index.tsx +++ b/packages/client/src/blocks/database-field/index.tsx @@ -11,13 +11,7 @@ import { import { ArrayCollapse } from '@formily/antd'; import { uid } from '@formily/shared'; import '@formily/antd/lib/form-tab/style'; -import { Collapse, Button } from 'antd'; - -const text = ` - A dog is a type of domesticated animal. - Known for its loyalty and faithfulness, - it can be found as a welcome guest in many households across the world. -`; +import { Collapse, Button, Dropdown, Menu } from 'antd'; const interfaces = new Map(); @@ -33,6 +27,21 @@ interfaces.set('string', { } as ISchema, }, properties: { + 'ui.title': { + type: 'string', + title: '字段名称', + required: true, + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + name: { + type: 'string', + title: '字段标识', + required: true, + 'x-disabled': true, + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, type: { type: 'string', title: '数据类型', @@ -44,20 +53,6 @@ interfaces.set('string', { { label: 'Text', value: 'text' }, ], }, - name: { - type: 'string', - title: '字段标识', - required: true, - 'x-decorator': 'FormItem', - 'x-component': 'Input', - }, - 'ui.title': { - type: 'string', - title: '字段名称', - required: true, - 'x-decorator': 'FormItem', - 'x-component': 'Input', - }, 'ui.required': { type: 'string', title: '必填', @@ -79,6 +74,21 @@ interfaces.set('textarea', { } as ISchema, }, properties: { + 'ui.title': { + type: 'string', + required: true, + title: '字段名称', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + name: { + type: 'string', + required: true, + title: '字段标识', + 'x-disabled': true, + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, type: { type: 'string', title: '数据类型', @@ -90,13 +100,28 @@ interfaces.set('textarea', { { label: 'Text', value: 'text' }, ], }, - name: { + 'ui.required': { type: 'string', - required: true, - title: '字段标识', + title: '必填', 'x-decorator': 'FormItem', - 'x-component': 'Input.TextArea', + 'x-component': 'Checkbox', }, + }, +}); + +interfaces.set('subTable', { + type: 'object', + default: { + type: 'string', + // name, + ui: { + type: 'string', + // title, + 'x-component': 'Select', + enum: [], + } as ISchema, + }, + properties: { 'ui.title': { type: 'string', required: true, @@ -104,6 +129,170 @@ interfaces.set('textarea', { 'x-decorator': 'FormItem', 'x-component': 'Input', }, + name: { + type: 'string', + required: true, + title: '字段标识', + 'x-disabled': true, + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + type: { + type: 'string', + title: '数据类型', + required: true, + 'x-decorator': 'FormItem', + 'x-component': 'Select', + enum: [ + { label: 'String', value: 'string' }, + { label: 'Text', value: 'text' }, + { label: 'HasMany', value: 'hasMany' }, + ], + }, + 'children': { + type: 'array', + title: '子表格字段', + 'x-decorator': 'FormItem', + 'x-component': 'DatabaseField', + }, + // 'ui.required': { + // type: 'string', + // title: '必填', + // 'x-decorator': 'FormItem', + // 'x-component': 'Checkbox', + // }, + }, +}); + +interfaces.set('select', { + type: 'object', + default: { + type: 'string', + // name, + ui: { + type: 'string', + // title, + 'x-component': 'Select', + enum: [], + } as ISchema, + }, + properties: { + 'ui.title': { + type: 'string', + required: true, + title: '字段名称', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + name: { + type: 'string', + required: true, + title: '字段标识', + 'x-disabled': true, + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + type: { + type: 'string', + title: '数据类型', + required: true, + 'x-decorator': 'FormItem', + 'x-component': 'Select', + enum: [ + { label: 'String', value: 'string' }, + { label: 'Text', value: 'text' }, + ], + }, + 'ui.enum': { + type: 'array', + title: '可选项', + 'x-decorator': 'FormItem', + 'x-component': 'ArrayTable', + 'x-component-props': { + pagination: false, + // scroll: { x: '100%' }, + }, + items: { + type: 'object', + properties: { + column1: { + type: 'void', + 'x-component': 'ArrayTable.Column', + 'x-component-props': { width: 50, title: '', align: 'center' }, + properties: { + sort: { + type: 'void', + 'x-component': 'ArrayTable.SortHandle', + }, + }, + }, + column2: { + type: 'void', + 'x-component': 'ArrayTable.Column', + 'x-component-props': { title: '选项值' }, + properties: { + value: { + type: 'string', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + }, + }, + column3: { + type: 'void', + 'x-component': 'ArrayTable.Column', + 'x-component-props': { title: '选项' }, + properties: { + label: { + type: 'string', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + }, + }, + column4: { + type: 'void', + 'x-component': 'ArrayTable.Column', + 'x-component-props': { title: '颜色' }, + properties: { + color: { + type: 'string', + 'x-decorator': 'FormItem', + 'x-component': 'ColorSelect', + }, + }, + }, + column5: { + type: 'void', + 'x-component': 'ArrayTable.Column', + 'x-component-props': { + title: '', + dataIndex: 'operations', + fixed: 'right', + }, + properties: { + item: { + type: 'void', + 'x-component': 'FormItem', + properties: { + remove: { + type: 'void', + 'x-component': 'ArrayTable.Remove', + }, + }, + }, + }, + }, + }, + }, + properties: { + add: { + type: 'void', + 'x-component': 'ArrayTable.Addition', + title: '添加可选项', + }, + }, + }, 'ui.required': { type: 'string', title: '必填', @@ -116,65 +305,101 @@ interfaces.set('textarea', { export const DatabaseField: any = observer((props) => { const field = useField(); console.log('DatabaseField', field.componentProps); + const [activeKey, setActiveKey] = useState(null); return (
- { - field.setComponentProps({ - activeKey: key, - }); - }} - accordion - > + { + setActiveKey(key); + }} accordion> {field.value?.map((item, index) => { const schema = interfaces.get(item.interface); console.log({ schema }); return ( field.moveUp(index)}>Up, - , - ]} - header={item.name} + // extra={[ + // , + // , + // ]} + header={ + <> + {item.ui && item.ui.title} + {' '} + {item.name} + + } key={item.id} > ); })} - + +
); }); diff --git a/packages/client/src/blocks/table/index.md b/packages/client/src/blocks/table/index.md index d211c08aa..27f8b9a53 100644 --- a/packages/client/src/blocks/table/index.md +++ b/packages/client/src/blocks/table/index.md @@ -9,18 +9,26 @@ group: path: /client/components --- -# Table - 表格 +### Table.View + +只做数据展示,不能用作表单字段 ```tsx import React from 'react'; import { SchemaRenderer } from '../'; import { uid } from '@formily/shared'; +import Editor from '@monaco-editor/react'; +import { createForm } from '@formily/core'; +import { observer } from '@formily/react'; const schema = { name: `t_${uid()}`, - type: 'array', - 'x-component': 'Table', - default: [{ field1: 'a1', field2: 'b1' }, { field1: 'a2', field2: 'b2' }], + type: 'void', + 'x-component': 'Table.View', + // default: [ + // { key: uid(), field1: 'a1', field2: 'b1' }, + // { key: uid(), field1: 'a2', field2: 'b2' }, + // ], 'x-component-props': {}, properties: { [`a_${uid()}`]: { @@ -28,17 +36,64 @@ const schema = { 'x-component': 'Table.ActionBar', properties: { action1: { - type: 'object', - title: '按钮1', - 'x-component': 'Table.BulkAction.Popover', - 'x-component-props': {}, - properties: {}, + type: 'void', + name: 'action1', + title: '筛选', + 'x-component': 'Action', + properties: { + popover1: { + type: 'void', + title: '弹窗标题', + 'x-component': 'Action.Popover', + 'x-component-props': {}, + properties: { + input: { + type: 'string', + 'x-component': 'Input', + } + }, + }, + }, }, action2: { type: 'void', - title: '按钮2', - 'x-component': 'Table.BulkAction', - 'x-component-props': {}, + name: 'action1', + title: '新增', + 'x-component': 'Action', + 'x-designable-bar': 'Action.DesignableBar', + properties: { + drawer1: { + type: 'void', + title: '抽屉标题', + 'x-component': 'Action.Drawer', + 'x-component-props': {}, + properties: { + input: { + type: 'string', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + action2: { + type: 'void', + name: 'action1', + title: '提交', + 'x-component': 'Action', + 'x-component-props': { + 'useAction': '{{ useTableCreateAction }}' + }, + } + }, + }, + }, + }, + action3: { + type: 'void', + name: 'action1', + title: '删除', + 'x-component': 'Action', + 'x-component-props': { + 'useAction': '{{ useTableDestroyAction }}' + }, }, }, }, @@ -65,8 +120,6 @@ const schema = { 'x-component': 'Table.Column', 'x-component-props': { title: 'z1', - width: 100, - // DesignableBar: 'Table.Column.DesignableBar', }, 'x-designable-bar': 'Table.Column.DesignableBar', properties: { @@ -101,9 +154,172 @@ const schema = { }, }; -export default () => { +const form = createForm(); + +export default observer(() => { return ( - - ); +
+ + +
+ ) +}); +``` + +### Table.Field + +可用作表单字段 + +```tsx +import React from 'react'; +import { SchemaRenderer } from '../'; +import { uid } from '@formily/shared'; +import Editor from '@monaco-editor/react'; +import { createForm } from '@formily/core'; +import { observer } from '@formily/react'; + +const schema = { + name: `t_${uid()}`, + type: 'array', + 'x-component': 'Table.Field', + // default: [ + // { key: uid(), field1: 'a1', field2: 'b1' }, + // { key: uid(), field1: 'a2', field2: 'b2' }, + // ], + 'x-component-props': {}, + properties: { + [`a_${uid()}`]: { + type: 'void', + 'x-component': 'Table.ActionBar', + properties: { + action1: { + type: 'void', + name: 'action1', + title: '筛选', + 'x-component': 'Action', + properties: { + popover1: { + type: 'void', + title: '弹窗标题', + 'x-component': 'Action.Popover', + 'x-component-props': {}, + properties: { + input: { + type: 'string', + 'x-component': 'Input', + } + }, + }, + }, + }, + action2: { + type: 'void', + name: 'action1', + title: '新增', + 'x-component': 'Action', + 'x-designable-bar': 'Action.DesignableBar', + properties: { + drawer1: { + type: 'void', + title: '抽屉标题', + 'x-component': 'Action.Drawer', + 'x-component-props': {}, + properties: { + action2: { + type: 'void', + name: 'action1', + title: '提交', + 'x-component': 'Action', + 'x-component-props': { + }, + } + }, + }, + }, + }, + action3: { + type: 'void', + name: 'action1', + title: '删除', + 'x-component': 'Action', + 'x-component-props': { + }, + }, + }, + }, + [`a_${uid()}`]: { + type: 'void', + 'x-component': 'Table.ActionBar', + 'x-component-props': { + align: 'bottom', + }, + properties: { + pagination: { + type: 'void', + 'x-component': 'Table.Pagination', + 'x-component-props': { + defaultCurrent: 1, + total: 50, + }, + }, + }, + }, + [`c_${uid()}`]: { + type: 'void', + title: '字段1', + 'x-component': 'Table.Column', + 'x-component-props': { + title: 'z1', + }, + 'x-designable-bar': 'Table.Column.DesignableBar', + properties: { + field1: { + type: 'string', + required: true, + 'x-decorator-props': { + feedbackLayout: 'popover', + }, + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + }, + }, + [`c_${uid()}`]: { + type: 'void', + title: '字段2', + 'x-component': 'Table.Column', + properties: { + field2: { + type: 'string', + title: '字段2', + required: true, + 'x-decorator-props': { + feedbackLayout: 'popover', + }, + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + }, + }, + }, }; + +const form = createForm(); + +export default observer(() => { + return ( +
+ + +
+ ) +}); ``` \ No newline at end of file diff --git a/packages/client/src/blocks/table/index.tsx b/packages/client/src/blocks/table/index.tsx index c70822ffd..2173c804b 100644 --- a/packages/client/src/blocks/table/index.tsx +++ b/packages/client/src/blocks/table/index.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { createContext, useContext, useState } from 'react'; import { useFieldSchema, Schema, @@ -6,13 +6,18 @@ import { RecursionField, useField, } from '@formily/react'; -import { Table as AntdTable } from 'antd'; +import { Button, Pagination, Space, Table as AntdTable } from 'antd'; import { DesignableBar } from './DesignableBar'; import { ColumnDesignableBar } from './ColumnDesignableBar'; +import { uid } from '@formily/shared'; +import useRequest from '@ahooksjs/use-request'; +import constate from 'constate'; +import { SchemaRenderer } from '../'; +import { useVisibleContext } from '../action'; -function useTableColumns(props) { +function useTableColumns(props?: any) { const schema = useFieldSchema(); - const { dataSource } = props; + const { dataSource } = props || {}; function findColumns(schema: Schema): Schema[] { return schema.reduceProperties((columns, current) => { @@ -29,14 +34,14 @@ function useTableColumns(props) { title: item.title, dataIndex: item.name, ...columnProps, - render(value, record) { - console.log({ item }); - const index = dataSource.indexOf(record); + render(value, record, index) { + // console.log({ item }); + // const index = dataSource.indexOf(record); item.mapProperties((s) => { s['title'] = undefined; s['x-read-pretty'] = true; return s; - }) + }); return ( ); @@ -74,35 +79,200 @@ function useTableActionBars() { return findActionBars(schema); } -function useTableDetails() { - const schema = useFieldSchema(); - - function findDetails(schema: Schema) { - return schema.reduceProperties((items, current) => { - if (current['x-component'] === 'Table.Details') { - return [...items, current]; - } - return [...items, ...findDetails(current)]; - }, []); - } - - return findDetails(schema); +function useTable() { + const field = useField(); + const [selectedRowKeys, setSelectedRowKeys] = useState([]); + const response = useRequest( + () => { + return new Promise((resolve) => { + console.log('useRequest'); + setTimeout(() => { + resolve([ + { key: uid(), field1: uid(), field2: uid() }, + { key: uid(), field1: uid(), field2: uid() }, + ]); + }, 500); + }); + }, + { + onSuccess(data) { + field.setValue(data); + }, + }, + ); + return { + selectedRowKeys, + setSelectedRowKeys, + mutate: response.mutate, + response, + async create() { + response.refresh() + }, + async update() { + response.refresh() + }, + async destroy() { + response.refresh() + }, + } as any; } -export const Table: any = observer((props) => { +const [TableContextProvider, useTableContext] = constate(useTable); + +export function useTableCreateAction() { + const { visible, setVisible } = useVisibleContext() + const { create } = useTableContext(); + return { + run: async () => { + setVisible(false); + await create(); + console.log({ visible }) + }, + } +} + +export function useTableDestroyAction() { + // const { setVisible } = useVisibleContext() + const { destroy } = useTableContext(); + return { + run: async () => { + // setVisible(false); + await destroy(); + }, + } +} + +const ArrayTable = (props) => { const field = useField(); - const dataSource = field.value; - const columns = useTableColumns({ dataSource }); + // const dataSource = Array.isArray(field.value) ? field.value.slice() : []; + const columns = useTableColumns(); const actionBars = useTableActionBars(); - const details = useTableDetails(); - console.log({ columns, actionBars, details }); + const { + selectedRowKeys, + setSelectedRowKeys, + response = {}, + create, + } = useTableContext(); + console.log({ response }); + const { data = [], loading, mutate } = response as any; return ( - <> - - +
+ {actionBars.top.map((actionBarSchema) => { + return ( + + ); + })} + + { + setSelectedRowKeys(keys); + }, + }} + /> + {actionBars.bottom.map((actionBarSchema) => { + return ( + + ); + })} +
+ ); +}; + +export const Table: any = observer((props) => { + return ( + + + ); }); Table.Column = () => null; -Table.Column.DesignableBar = ColumnDesignableBar; -Table.DesignableBar = DesignableBar; + +Table.ActionBar = observer((props) => { + return ( +
+ {props.children} +
+ ); +}); + +Table.Pagination = observer((props) => { + const { response } = useTableContext(); + return ( + { + response.refresh(); + // console.log('useRequest', { page, pageSize }); + }} + /> + ); +}); + +Table.View = observer(() => { + const schema = useFieldSchema(); + console.log('Table.View', schema); + return ( + + ); +}); + +Table.Field = observer((props) => { + return ( + + + + ); +});