lots of updates
This commit is contained in:
		
							parent
							
								
									ed4397e112
								
							
						
					
					
						commit
						e53a1edf7d
					
				| @ -1,283 +0,0 @@ | ||||
| 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: [
 | ||||
|   //   { key: uid(), field1: uid(), field2: uid() },
 | ||||
|   //   { key: uid(), field1: uid(), field2: uid() },
 | ||||
|   //   { key: uid(), field1: uid(), field2: uid() },
 | ||||
|   //   { key: uid(), field1: uid(), field2: uid() },
 | ||||
|   //   { key: uid(), field1: uid(), field2: uid() },
 | ||||
|   //   { key: uid(), field1: uid(), field2: uid() },
 | ||||
|   //   { key: uid(), field1: uid(), field2: uid() },
 | ||||
|   //   { key: uid(), field1: uid(), field2: uid() },
 | ||||
|   //   { key: uid(), field1: uid(), field2: uid() },
 | ||||
|   //   { key: uid(), field1: uid(), field2: uid() },
 | ||||
|   //   { key: uid(), field1: uid(), field2: uid() },
 | ||||
|   //   { key: uid(), field1: uid(), field2: uid() },
 | ||||
|   // ],
 | ||||
|   'x-component-props': { | ||||
|     rowKey: 'key', | ||||
|     // isRemoteDataSource: true,
 | ||||
|   }, | ||||
|   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: { | ||||
|                 [uid()]: { | ||||
|                   name: 'form', | ||||
|                   type: 'object', | ||||
|                   'x-component': 'Form', | ||||
|                   properties: { | ||||
|                     filter: { | ||||
|                       type: 'string', | ||||
|                       title: '字段1', | ||||
|                       'x-decorator': 'FormItem', | ||||
|                       'x-component': 'Input', | ||||
|                     }, | ||||
|                     action: { | ||||
|                       type: 'void', | ||||
|                       title: '提交', | ||||
|                       'x-component': 'Action', | ||||
|                       'x-component-props': { | ||||
|                         'useAction': '{{ useTableFilterAction }}' | ||||
|                       }, | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|               }, | ||||
|             }, | ||||
|           }, | ||||
|         }, | ||||
|         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: { | ||||
|                 [uid()]: { | ||||
|                   name: 'form', | ||||
|                   type: 'object', | ||||
|                   'x-component': 'Form', | ||||
|                   properties: { | ||||
|                     field1: { | ||||
|                       type: 'string', | ||||
|                       title: '字段1', | ||||
|                       'x-decorator': 'FormItem', | ||||
|                       'x-component': 'Input', | ||||
|                     }, | ||||
|                     field2: { | ||||
|                       type: 'string', | ||||
|                       title: '字段2', | ||||
|                       'x-decorator': 'FormItem', | ||||
|                       'x-component': 'Input', | ||||
|                     }, | ||||
|                     action: { | ||||
|                       type: 'void', | ||||
|                       title: '提交', | ||||
|                       'x-component': 'Action', | ||||
|                       'x-component-props': { | ||||
|                         'useAction': '{{ useTableCreateAction }}' | ||||
|                       }, | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|               }, | ||||
|             }, | ||||
|           }, | ||||
|         }, | ||||
|         action3: { | ||||
|           type: 'void', | ||||
|           name: 'action1', | ||||
|           title: '删除', | ||||
|           'x-component': 'Action', | ||||
|           'x-component-props': { | ||||
|             'useAction': '{{ useTableDestroyAction }}' | ||||
|           }, | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|     [`a_${uid()}`]: { | ||||
|       type: 'void', | ||||
|       'x-component': 'Table.ActionBar', | ||||
|       'x-component-props': { | ||||
|         align: 'bottom', | ||||
|       }, | ||||
|       properties: { | ||||
|         pagination: { | ||||
|           type: 'void', | ||||
|           'x-component': 'Table.Pagination', | ||||
|           'x-component-props': { | ||||
|             defaultPageSize: 5, | ||||
|           }, | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|     [`c_${uid()}`]: { | ||||
|       type: 'void', | ||||
|       title: '排序', | ||||
|       'x-component': 'Table.Column', | ||||
|       properties: { | ||||
|         sort: { | ||||
|           type: 'void', | ||||
|           'x-component': 'Table.SortHandle', | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|     [`c_${uid()}`]: { | ||||
|       type: 'void', | ||||
|       title: '序号', | ||||
|       'x-component': 'Table.Column', | ||||
|       properties: { | ||||
|         index: { | ||||
|           type: 'void', | ||||
|           'x-component': 'Table.Index', | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|     [`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-read-pretty': 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-read-pretty': true, | ||||
|           'x-decorator-props': { | ||||
|             feedbackLayout: 'popover', | ||||
|           }, | ||||
|           'x-decorator': 'FormItem', | ||||
|           'x-component': 'Input', | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|     [`col_${uid()}`]: { | ||||
|       type: 'void', | ||||
|       title: '操作', | ||||
|       'x-component': 'Table.Column', | ||||
|       properties: { | ||||
|         action3: { | ||||
|           type: 'void', | ||||
|           title: '删除', | ||||
|           'x-component': 'Action', | ||||
|           'x-component-props': { | ||||
|             'useAction': '{{ useTableDestroyAction }}' | ||||
|           }, | ||||
|         }, | ||||
|         action2: { | ||||
|           type: 'void', | ||||
|           name: 'action1', | ||||
|           title: '修改', | ||||
|           'x-component': 'Action', | ||||
|           'x-default-action': true, | ||||
|           'x-designable-bar': 'Action.DesignableBar', | ||||
|           properties: { | ||||
|             drawer1: { | ||||
|               type: 'void', | ||||
|               title: '编辑表单', | ||||
|               'x-component': 'Action.Drawer', | ||||
|               'x-component-props': {}, | ||||
|               properties: { | ||||
|                 [uid()]: { | ||||
|                   name: 'form', | ||||
|                   type: 'void', | ||||
|                   'x-component': 'Form', | ||||
|                   'x-component-props': { | ||||
|                     'useValues': '{{ useTableRow }}', | ||||
|                   }, | ||||
|                   properties: { | ||||
|                     field1: { | ||||
|                       type: 'string', | ||||
|                       title: '字段1', | ||||
|                       'x-decorator': 'FormItem', | ||||
|                       'x-component': 'Input', | ||||
|                     }, | ||||
|                     field2: { | ||||
|                       type: 'string', | ||||
|                       title: '字段2', | ||||
|                       'x-decorator': 'FormItem', | ||||
|                       'x-component': 'Input', | ||||
|                     }, | ||||
|                     action: { | ||||
|                       type: 'void', | ||||
|                       title: '提交', | ||||
|                       'x-component': 'Action', | ||||
|                       'x-component-props': { | ||||
|                         'useAction': '{{ useTableUpdateAction }}' | ||||
|                       }, | ||||
|                     } | ||||
|                   } | ||||
|                 }, | ||||
|               }, | ||||
|             }, | ||||
|           }, | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| const form = createForm(); | ||||
| 
 | ||||
| export default observer(() => { | ||||
|   return ( | ||||
|     <div> | ||||
|       <SchemaRenderer form={form} schema={schema} /> | ||||
|       <Editor | ||||
|         height="200px" | ||||
|         defaultLanguage="json" | ||||
|         value={JSON.stringify(form.values, null, 2)} | ||||
|       /> | ||||
|     </div> | ||||
|   ) | ||||
| }); | ||||
| @ -4,7 +4,7 @@ import { useMouseEvents, useWillUnmount } from 'beautiful-react-hooks'; | ||||
| import { useField, useFieldSchema } from '@formily/react'; | ||||
| import { useMount } from 'ahooks'; | ||||
| import constate from 'constate'; | ||||
| import { useSchemaPath } from '../../blocks'; | ||||
| import { useSchemaPath } from '../../schemas'; | ||||
| 
 | ||||
| export const DraggableBlockContext = createContext({ | ||||
|   dragRef: null, | ||||
|  | ||||
| @ -5,8 +5,8 @@ nav: | ||||
|   path: /client | ||||
| group: | ||||
|   order: 1 | ||||
|   title: Components - 组件 | ||||
|   path: /client/components | ||||
|   title: Schemas | ||||
|   path: /client/schemas | ||||
| --- | ||||
| 
 | ||||
| # Action - 操作 | ||||
| @ -94,6 +94,107 @@ export default () => { | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| ## Action.Dropdown - 下拉操作 | ||||
| 
 | ||||
| ```tsx | ||||
| import React from 'react'; | ||||
| import { SchemaRenderer } from '../'; | ||||
| 
 | ||||
| function useAction() { | ||||
|   return { | ||||
|     run() { | ||||
|       alert('这是自定义的操作逻辑'); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| const popoverSchema = { | ||||
|   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', | ||||
|         } | ||||
|       }, | ||||
|     }, | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| const drawerSchema = { | ||||
|   type: 'void', | ||||
|   title: '按钮', | ||||
|   'x-component': 'Action', | ||||
|   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', | ||||
|           title: '打开二级抽屉', | ||||
|           // 'x-decorator': 'FormItem', | ||||
|           'x-component': 'Action', | ||||
|           properties: { | ||||
|             drawer1: { | ||||
|               type: 'void', | ||||
|               title: '二级抽屉标题', | ||||
|               'x-component': 'Action.Drawer', | ||||
|               'x-component-props': {}, | ||||
|               properties: { | ||||
|                 input: { | ||||
|                   type: 'string', | ||||
|                   'x-component': 'Input', | ||||
|                 }, | ||||
|               }, | ||||
|             }, | ||||
|           }, | ||||
|         } | ||||
|       }, | ||||
|     }, | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| const schema = { | ||||
|   type: 'void', | ||||
|   name: 'action1', | ||||
|   title: '下拉菜单', | ||||
|   'x-component': 'Action.Dropdown', | ||||
|   properties: { | ||||
|     action1: { | ||||
|       type: 'void', | ||||
|       name: 'action1', | ||||
|       title: '按钮', | ||||
|       'x-component': 'Action', | ||||
|       'x-component-props': { | ||||
|         useAction, | ||||
|       }, | ||||
|     }, | ||||
|     action2: drawerSchema, | ||||
|     action3: popoverSchema, | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| export default () => { | ||||
|   return <SchemaRenderer schema={schema} /> | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| ## Action.Popover - 打开气泡 | ||||
| 
 | ||||
| ```tsx | ||||
| @ -12,10 +12,10 @@ import { | ||||
| } from '@formily/react'; | ||||
| import { Button, Dropdown, Menu, Popover, Space, Drawer, Modal } from 'antd'; | ||||
| import { Link, useHistory, LinkProps } from 'react-router-dom'; | ||||
| import { SchemaRenderer, useDesignable } from '../'; | ||||
| import { SchemaRenderer, useDesignable } from '..'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import get from 'lodash/get'; | ||||
| import { MenuOutlined } from '@ant-design/icons'; | ||||
| import { MenuOutlined, DownOutlined } from '@ant-design/icons'; | ||||
| import classNames from 'classnames'; | ||||
| import { useMount } from 'ahooks'; | ||||
| import { uid } from '@formily/shared'; | ||||
| @ -78,6 +78,7 @@ export type ActionType = React.FC<ActionProps> & { | ||||
|   Drawer?: React.FC<any>; | ||||
|   Modal?: React.FC<any>; | ||||
|   Dropdown?: React.FC<any>; | ||||
|   Group?: React.FC<any>; | ||||
|   DesignableBar?: React.FC<any>; | ||||
| }; | ||||
| 
 | ||||
| @ -115,7 +116,7 @@ const BaseAction = observer((props: any) => { | ||||
|     field.componentProps.setVisible = setVisible; | ||||
|   }, []); | ||||
| 
 | ||||
|   console.log('BaseAction', { field, schema }, field.title) | ||||
|   console.log('BaseAction', { field, schema }, field.title); | ||||
| 
 | ||||
|   const renderButton = () => ( | ||||
|     <Button | ||||
| @ -168,7 +169,10 @@ export const Action: ActionType = observer((props: any) => { | ||||
|   const schema = useFieldSchema(); | ||||
|   if (schema.properties) { | ||||
|     return ( | ||||
|       <VisibleProvider initialVisible={props.initialVisible} containerRef={props.containerRef}> | ||||
|       <VisibleProvider | ||||
|         initialVisible={props.initialVisible} | ||||
|         containerRef={props.containerRef} | ||||
|       > | ||||
|         <BaseAction {...props} /> | ||||
|       </VisibleProvider> | ||||
|     ); | ||||
| @ -218,7 +222,7 @@ Action.Drawer = observer((props) => { | ||||
|   const { visible, setVisible } = useVisibleContext(); | ||||
|   return ( | ||||
|     <Drawer | ||||
|       onClick={e => { | ||||
|       onClick={(e) => { | ||||
|         e.stopPropagation(); | ||||
|       }} | ||||
|       title={field.title} | ||||
| @ -227,7 +231,7 @@ Action.Drawer = observer((props) => { | ||||
|       visible={visible} | ||||
|       onClose={(e) => { | ||||
|         e.stopPropagation(); | ||||
|         setVisible(false) | ||||
|         setVisible(false); | ||||
|       }} | ||||
|     > | ||||
|       {props.children} | ||||
| @ -240,17 +244,46 @@ Action.Modal = observer((props) => { | ||||
|   const { visible, setVisible } = useVisibleContext(); | ||||
|   return ( | ||||
|     <Modal | ||||
|       // onClick={e => {
 | ||||
|       //   e.stopPropagation();
 | ||||
|       // }}
 | ||||
|       title={field.title} | ||||
|       width={'50%'} | ||||
|       {...props} | ||||
|       visible={visible} | ||||
|       onCancel={() => setVisible(false)} | ||||
|       closable | ||||
|       maskClosable | ||||
|       onCancel={(e) => { | ||||
|         e.stopPropagation(); | ||||
|         setVisible(false); | ||||
|       }} | ||||
|       footer={null} | ||||
|     > | ||||
|       {props.children} | ||||
|       <div onClick={(e) => e.stopPropagation()}>{props.children}</div> | ||||
|     </Modal> | ||||
|   ); | ||||
| }); | ||||
| 
 | ||||
| Action.Dropdown = observer((props) => { | ||||
|   // const { visible, setVisible } = useVisibleContext();
 | ||||
|   const schema = useFieldSchema(); | ||||
|   return ( | ||||
|     <Popover | ||||
|       // visible={visible}
 | ||||
|       // onVisibleChange={(visible) => {
 | ||||
|       //   setVisible(visible);
 | ||||
|       // }}
 | ||||
|       {...props} | ||||
|       overlayClassName={'nb-action-group'} | ||||
|       // trigger={'click'}
 | ||||
|       content={props.children} | ||||
|       placement={'bottomLeft'} | ||||
|     > | ||||
|       <Button>{schema.title}</Button> | ||||
|     </Popover> | ||||
|   ); | ||||
| }); | ||||
| 
 | ||||
| Action.DesignableBar = () => { | ||||
|   const field = useField(); | ||||
|   const schema = useFieldSchema(); | ||||
| @ -51,3 +51,32 @@ | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .ant-popover.nb-action-group { | ||||
|   z-index: 1000; | ||||
|   padding-top: 0; | ||||
|   .ant-popover-arrow { | ||||
|     display: none; | ||||
|   } | ||||
|   .ant-popover-inner-content { | ||||
|     padding: 4px 0; | ||||
|     .ant-btn { | ||||
|       display: block; | ||||
|       min-width: 100px; | ||||
|       width: 100%; | ||||
|       border: 0; | ||||
|       border-radius: 0; | ||||
|       text-align: left; | ||||
|       padding: 5px 12px; | ||||
|       color: #000; | ||||
|       &:hover { | ||||
|         background-color: #f5f5f5; | ||||
|       } | ||||
|       &[disabled] { | ||||
|         color: #00000040; | ||||
|         background-color:#fff; | ||||
|         cursor:not-allowed; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -5,8 +5,8 @@ nav: | ||||
|   path: /client | ||||
| group: | ||||
|   order: 1 | ||||
|   title: Components - 组件 | ||||
|   path: /client/components | ||||
|   title: Schemas | ||||
|   path: /client/schemas | ||||
| --- | ||||
| 
 | ||||
| # AddNew - 新增 | ||||
| @ -5,8 +5,8 @@ nav: | ||||
|   path: /client | ||||
| group: | ||||
|   order: 1 | ||||
|   title: Components - 组件 | ||||
|   path: /client/components | ||||
|   title: Schemas | ||||
|   path: /client/schemas | ||||
| --- | ||||
| 
 | ||||
| # Cascader - 级联选择 | ||||
| @ -5,8 +5,8 @@ nav: | ||||
|   path: /client | ||||
| group: | ||||
|   order: 1 | ||||
|   title: Components - 组件 | ||||
|   path: /client/components | ||||
|   title: Schemas | ||||
|   path: /client/schemas | ||||
| --- | ||||
| 
 | ||||
| # Checkbox - 多选框 | ||||
| @ -5,8 +5,8 @@ nav: | ||||
|   path: /client | ||||
| group: | ||||
|   order: 1 | ||||
|   title: Components - 组件 | ||||
|   path: /client/components | ||||
|   title: Schemas | ||||
|   path: /client/schemas | ||||
| --- | ||||
| 
 | ||||
| # ColorSelect - 颜色选择器 | ||||
| @ -5,8 +5,8 @@ nav: | ||||
|   path: /client | ||||
| group: | ||||
|   order: 1 | ||||
|   title: Components - 组件 | ||||
|   path: /client/components | ||||
|   title: Schemas | ||||
|   path: /client/schemas | ||||
| --- | ||||
| 
 | ||||
| # DatabaseField - 数据表字段 | ||||
| @ -5,8 +5,8 @@ nav: | ||||
|   path: /client | ||||
| group: | ||||
|   order: 1 | ||||
|   title: Components - 组件 | ||||
|   path: /client/components | ||||
|   title: Schemas | ||||
|   path: /client/schemas | ||||
| --- | ||||
| 
 | ||||
| # DatePicker - 日期选择器 | ||||
| @ -5,8 +5,8 @@ nav: | ||||
|   path: /client | ||||
| group: | ||||
|   order: 1 | ||||
|   title: Components - 组件 | ||||
|   path: /client/components | ||||
|   title: Schemas | ||||
|   path: /client/schemas | ||||
| --- | ||||
| 
 | ||||
| # DrawerSelect - 抽屉选择器 | ||||
| @ -1,5 +1,5 @@ | ||||
| import React, { useMemo, useState } from 'react'; | ||||
| import { SchemaField } from '../'; | ||||
| import { SchemaField } from '..'; | ||||
| import { createForm, onFieldChange, onFieldReact } from '@formily/core' | ||||
| import { FormProvider, FormConsumer } from '@formily/react' | ||||
| import { Field } from '@formily/core/esm/models/Field'; | ||||
| @ -5,6 +5,6 @@ nav: | ||||
|   path: /client | ||||
| group: | ||||
|   order: 1 | ||||
|   title: Components - 组件 | ||||
|   path: /client/components | ||||
|   title: Schemas | ||||
|   path: /client/schemas | ||||
| --- | ||||
| @ -5,8 +5,8 @@ nav: | ||||
|   path: /client | ||||
| group: | ||||
|   order: 1 | ||||
|   title: Components - 组件 | ||||
|   path: /client/components | ||||
|   title: Schemas | ||||
|   path: /client/schemas | ||||
| --- | ||||
| 
 | ||||
| # Form - 表单 | ||||
| @ -8,7 +8,7 @@ import { | ||||
|   RecursionField, | ||||
|   useField, | ||||
| } from '@formily/react'; | ||||
| import { SchemaRenderer } from '../../'; | ||||
| import { SchemaRenderer } from '../..'; | ||||
| 
 | ||||
| const schema: ISchema = { | ||||
|   type: 'void', | ||||
| @ -6,7 +6,7 @@ nav: | ||||
| group: | ||||
|   order: 2 | ||||
|   title: Blocks  | ||||
|   path: /client/components | ||||
|   path: /client/schemas | ||||
| --- | ||||
| 
 | ||||
| # Grid - 栅格 | ||||
| @ -29,7 +29,7 @@ import { | ||||
|   useColResizer, | ||||
|   useDragDropUID, | ||||
|   DragDropManagerProvider, | ||||
| } from './../../components/drag-and-drop'; | ||||
| } from '../../components/drag-and-drop'; | ||||
| 
 | ||||
| const ColumnSizeContext = createContext(null); | ||||
| 
 | ||||
| @ -5,8 +5,8 @@ nav: | ||||
|   path: /client | ||||
| group: | ||||
|   order: 1 | ||||
|   title: Components - 组件 | ||||
|   path: /client/components | ||||
|   title: Schemas | ||||
|   path: /client/schemas | ||||
| --- | ||||
| 
 | ||||
| # IconPicker - 图标选择器 | ||||
| @ -5,8 +5,8 @@ nav: | ||||
|   path: /client | ||||
| group: | ||||
|   order: 1 | ||||
|   title: Components - 组件 | ||||
|   path: /client/components | ||||
|   title: Schemas | ||||
|   path: /client/schemas | ||||
| --- | ||||
| 
 | ||||
| # InputNumber - 数字框 | ||||
| @ -5,8 +5,8 @@ nav: | ||||
|   path: /client | ||||
| group: | ||||
|   order: 1 | ||||
|   title: Components - 组件 | ||||
|   path: /client/components | ||||
|   title: Schemas | ||||
|   path: /client/schemas | ||||
| --- | ||||
| 
 | ||||
| # Input - 输入框 | ||||
| @ -5,8 +5,8 @@ nav: | ||||
|   path: /client | ||||
| group: | ||||
|   order: 1 | ||||
|   title: Components - 组件 | ||||
|   path: /client/components | ||||
|   title: Schemas | ||||
|   path: /client/schemas | ||||
| --- | ||||
| 
 | ||||
| # Markdown 编辑器 | ||||
| @ -5,8 +5,8 @@ nav: | ||||
|   path: /client | ||||
| group: | ||||
|   order: 1 | ||||
|   title: Components - 组件 | ||||
|   path: /client/components | ||||
|   title: Schemas | ||||
|   path: /client/schemas | ||||
| --- | ||||
| 
 | ||||
| # Menu - 菜单 | ||||
| @ -50,10 +50,11 @@ import { useHistory } from 'react-router-dom'; | ||||
| import cls from 'classnames'; | ||||
| import ReactDOM from 'react-dom'; | ||||
| import { useMount } from 'ahooks'; | ||||
| import { useDesignable, SchemaRenderer } from '../'; | ||||
| import { useDesignable, SchemaRenderer } from '..'; | ||||
| import { Router } from "react-router"; | ||||
| 
 | ||||
| import { useLifecycle } from 'beautiful-react-hooks'; | ||||
| import { useDefaultAction } from '../action'; | ||||
| 
 | ||||
| export type MenuType = React.FC<MenuProps & { hideSubMenu?: boolean }> & { | ||||
|   Item?: React.FC<MenuItemProps>; | ||||
| @ -273,13 +274,18 @@ Menu.Link = observer((props) => { | ||||
|   ); | ||||
| }); | ||||
| 
 | ||||
| Menu.Item = observer((props) => { | ||||
| Menu.Item = observer((props: any) => { | ||||
|   const { useAction = useDefaultAction, ...others } = props; | ||||
|   const { run } = useAction(); | ||||
|   const field = useField(); | ||||
|   const schema = useFieldSchema(); | ||||
|   const { DesignableBar } = useDesignableBar(); | ||||
|   return ( | ||||
|     <AntdMenu.Item | ||||
|       {...props} | ||||
|       {...others} | ||||
|       onClick={async () => { | ||||
|         await run(); | ||||
|       }} | ||||
|       schema={schema} | ||||
|       // @ts-ignore
 | ||||
|       eventKey={schema.name} | ||||
| @ -5,8 +5,8 @@ nav: | ||||
|   path: /client | ||||
| group: | ||||
|   order: 1 | ||||
|   title: Components - 组件 | ||||
|   path: /client/components | ||||
|   title: Schemas | ||||
|   path: /client/schemas | ||||
| --- | ||||
| 
 | ||||
| # Password - 密码 | ||||
| @ -5,8 +5,8 @@ nav: | ||||
|   path: /client | ||||
| group: | ||||
|   order: 1 | ||||
|   title: Components - 组件 | ||||
|   path: /client/components | ||||
|   title: Schemas | ||||
|   path: /client/schemas | ||||
| --- | ||||
| 
 | ||||
| # Radio - 单选框 | ||||
| @ -5,8 +5,8 @@ nav: | ||||
|   path: /client | ||||
| group: | ||||
|   order: 1 | ||||
|   title: Components - 组件 | ||||
|   path: /client/components | ||||
|   title: Schemas | ||||
|   path: /client/schemas | ||||
| --- | ||||
| 
 | ||||
| # Select - 选择器 | ||||
							
								
								
									
										498
									
								
								packages/client/src/schemas/table/demos/demo1.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										498
									
								
								packages/client/src/schemas/table/demos/demo1.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,498 @@ | ||||
| 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'; | ||||
| 
 | ||||
| function useAction() { | ||||
|   return { | ||||
|     async run() { | ||||
|       alert('自定义') | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| const schema = { | ||||
|   name: `t_${uid()}`, | ||||
|   type: 'array', | ||||
|   'x-component': 'Table', | ||||
|   // default: [
 | ||||
|   //   { key: uid(), field1: uid(), field2: uid() },
 | ||||
|   //   { key: uid(), field1: uid(), field2: uid() },
 | ||||
|   //   { key: uid(), field1: uid(), field2: uid() },
 | ||||
|   //   { key: uid(), field1: uid(), field2: uid() },
 | ||||
|   //   { key: uid(), field1: uid(), field2: uid() },
 | ||||
|   //   { key: uid(), field1: uid(), field2: uid() },
 | ||||
|   //   { key: uid(), field1: uid(), field2: uid() },
 | ||||
|   //   { key: uid(), field1: uid(), field2: uid() },
 | ||||
|   //   { key: uid(), field1: uid(), field2: uid() },
 | ||||
|   //   { key: uid(), field1: uid(), field2: uid() },
 | ||||
|   //   { key: uid(), field1: uid(), field2: uid() },
 | ||||
|   //   { key: uid(), field1: uid(), field2: uid() },
 | ||||
|   // ],
 | ||||
|   'x-component-props': { | ||||
|     rowKey: 'key', | ||||
|     // isRemoteDataSource: true,
 | ||||
|   }, | ||||
|   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: { | ||||
|                 [uid()]: { | ||||
|                   name: 'form', | ||||
|                   type: 'object', | ||||
|                   'x-component': 'Form', | ||||
|                   properties: { | ||||
|                     filter: { | ||||
|                       type: 'string', | ||||
|                       title: '字段1', | ||||
|                       'x-decorator': 'FormItem', | ||||
|                       'x-component': 'Input', | ||||
|                     }, | ||||
|                     action: { | ||||
|                       type: 'void', | ||||
|                       title: '提交', | ||||
|                       'x-component': 'Action', | ||||
|                       'x-component-props': { | ||||
|                         useAction: '{{ useTableFilterAction }}', | ||||
|                       }, | ||||
|                     }, | ||||
|                   }, | ||||
|                 }, | ||||
|               }, | ||||
|             }, | ||||
|           }, | ||||
|         }, | ||||
|         action2: { | ||||
|           type: 'void', | ||||
|           name: 'action1', | ||||
|           title: '新增', | ||||
|           'x-component': 'Action', | ||||
|           'x-designable-bar': 'Action.DesignableBar', | ||||
|           properties: { | ||||
|             drawer1: { | ||||
|               type: 'void', | ||||
|               title: '抽屉标题', | ||||
|               'x-component': 'Action.Modal', | ||||
|               'x-component-props': {}, | ||||
|               properties: { | ||||
|                 [uid()]: { | ||||
|                   name: 'form', | ||||
|                   type: 'object', | ||||
|                   'x-component': 'Form', | ||||
|                   properties: { | ||||
|                     field1: { | ||||
|                       type: 'string', | ||||
|                       title: '字段1', | ||||
|                       'x-decorator': 'FormItem', | ||||
|                       'x-component': 'Input', | ||||
|                     }, | ||||
|                     field2: { | ||||
|                       type: 'string', | ||||
|                       title: '字段2', | ||||
|                       'x-decorator': 'FormItem', | ||||
|                       'x-component': 'Input', | ||||
|                     }, | ||||
|                     action: { | ||||
|                       type: 'void', | ||||
|                       title: '提交', | ||||
|                       'x-component': 'Action', | ||||
|                       'x-component-props': { | ||||
|                         useAction: '{{ useTableCreateAction }}', | ||||
|                       }, | ||||
|                     }, | ||||
|                   }, | ||||
|                 }, | ||||
|               }, | ||||
|             }, | ||||
|           }, | ||||
|         }, | ||||
|         action3: { | ||||
|           type: 'void', | ||||
|           name: 'action1', | ||||
|           title: '删除', | ||||
|           'x-component': 'Action', | ||||
|           'x-component-props': { | ||||
|             useAction: '{{ useTableDestroyAction }}', | ||||
|           }, | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|     [`a_${uid()}`]: { | ||||
|       type: 'void', | ||||
|       'x-component': 'Table.ActionBar', | ||||
|       'x-component-props': { | ||||
|         align: 'bottom', | ||||
|       }, | ||||
|       properties: { | ||||
|         pagination: { | ||||
|           type: 'void', | ||||
|           'x-component': 'Table.Pagination', | ||||
|           'x-component-props': { | ||||
|             defaultPageSize: 5, | ||||
|           }, | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|     [`a_${uid()}`]: { | ||||
|       type: 'void', | ||||
|       'x-component': 'Table.ActionBar', | ||||
|       'x-component-props': { | ||||
|         align: 'bottom', | ||||
|       }, | ||||
|       properties: { | ||||
|         pagination: { | ||||
|           type: 'void', | ||||
|           title: '新增', | ||||
|           'x-component': 'Table.Addition', | ||||
|           'x-component-props': {}, | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|     [`c_${uid()}`]: { | ||||
|       type: 'void', | ||||
|       title: '排序', | ||||
|       'x-component': 'Table.Column', | ||||
|       properties: { | ||||
|         sort: { | ||||
|           type: 'void', | ||||
|           'x-component': 'Table.SortHandle', | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|     [`c_${uid()}`]: { | ||||
|       type: 'void', | ||||
|       title: '序号', | ||||
|       'x-component': 'Table.Column', | ||||
|       properties: { | ||||
|         index: { | ||||
|           type: 'void', | ||||
|           'x-component': 'Table.Index', | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|     [`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-read-pretty': 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-read-pretty': true,
 | ||||
|           'x-decorator-props': { | ||||
|             feedbackLayout: 'popover', | ||||
|           }, | ||||
|           'x-decorator': 'FormItem', | ||||
|           'x-component': 'Input', | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|     [`col_${uid()}`]: { | ||||
|       type: 'void', | ||||
|       title: '操作', | ||||
|       'x-component': 'Table.Column', | ||||
|       properties: { | ||||
|         action1: { | ||||
|           type: 'void', | ||||
|           name: 'action1', | ||||
|           title: '查看', | ||||
|           'x-component': 'Action', | ||||
|           'x-default-action': true, | ||||
|           'x-designable-bar': 'Action.DesignableBar', | ||||
|           properties: { | ||||
|             drawer1: { | ||||
|               type: 'void', | ||||
|               title: '查看', | ||||
|               'x-component': 'Action.Modal', | ||||
|               'x-component-props': {}, | ||||
|               properties: { | ||||
|                 [uid()]: { | ||||
|                   type: 'void', | ||||
|                   'x-component': 'Tabs', | ||||
|                   properties: { | ||||
|                     tab1: { | ||||
|                       type: 'void', | ||||
|                       'x-component': 'Tabs.TabPane', | ||||
|                       'x-component-props': { | ||||
|                         tab: 'Tab1', | ||||
|                       }, | ||||
|                       properties: { | ||||
|                         aaa: { | ||||
|                           type: 'string', | ||||
|                           title: 'AAA', | ||||
|                           'x-decorator': 'FormItem', | ||||
|                           required: true, | ||||
|                           'x-component': 'Input', | ||||
|                         }, | ||||
|                       }, | ||||
|                     }, | ||||
|                     tab2: { | ||||
|                       type: 'void', | ||||
|                       'x-component': 'Tabs.TabPane', | ||||
|                       'x-component-props': { | ||||
|                         tab: 'Tab2', | ||||
|                       }, | ||||
|                       properties: { | ||||
|                         bbb: { | ||||
|                           type: 'string', | ||||
|                           title: 'BBB', | ||||
|                           'x-decorator': 'FormItem', | ||||
|                           required: true, | ||||
|                           'x-component': 'Input', | ||||
|                         }, | ||||
|                       }, | ||||
|                     }, | ||||
|                   }, | ||||
|                 }, | ||||
|               }, | ||||
|             }, | ||||
|           }, | ||||
|         }, | ||||
|         action2: { | ||||
|           type: 'void', | ||||
|           name: 'action1', | ||||
|           title: '修改', | ||||
|           'x-component': 'Action', | ||||
|           'x-default-action': true, | ||||
|           'x-designable-bar': 'Action.DesignableBar', | ||||
|           properties: { | ||||
|             drawer1: { | ||||
|               type: 'void', | ||||
|               title: '编辑表单', | ||||
|               'x-component': 'Action.Modal', | ||||
|               'x-component-props': {}, | ||||
|               properties: { | ||||
|                 [uid()]: { | ||||
|                   name: 'form', | ||||
|                   type: 'void', | ||||
|                   'x-component': 'Form', | ||||
|                   'x-component-props': { | ||||
|                     useValues: '{{ useTableRow }}', | ||||
|                   }, | ||||
|                   properties: { | ||||
|                     field1: { | ||||
|                       type: 'string', | ||||
|                       title: '字段1', | ||||
|                       'x-decorator': 'FormItem', | ||||
|                       'x-component': 'Input', | ||||
|                     }, | ||||
|                     field2: { | ||||
|                       type: 'string', | ||||
|                       title: '字段2', | ||||
|                       'x-decorator': 'FormItem', | ||||
|                       'x-component': 'Input', | ||||
|                     }, | ||||
|                     action: { | ||||
|                       type: 'void', | ||||
|                       title: '提交', | ||||
|                       'x-component': 'Action', | ||||
|                       'x-component-props': { | ||||
|                         useAction: '{{ useTableUpdateAction }}', | ||||
|                       }, | ||||
|                     }, | ||||
|                   }, | ||||
|                 }, | ||||
|               }, | ||||
|             }, | ||||
|           }, | ||||
|         }, | ||||
|         action3: { | ||||
|           type: 'void', | ||||
|           title: '删除', | ||||
|           'x-component': 'Action', | ||||
|           'x-component-props': { | ||||
|             useAction: '{{ useTableDestroyAction }}', | ||||
|           }, | ||||
|         }, | ||||
|         action4: { | ||||
|           type: 'void', | ||||
|           title: '...', | ||||
|           'x-component': 'Action.Dropdown', | ||||
|           properties: { | ||||
|             action5: { | ||||
|               type: 'void', | ||||
|               title: '操作 1', | ||||
|               'x-component': 'Action', | ||||
|               'x-component-props': { | ||||
|                 useAction, | ||||
|                 disabled: true, | ||||
|               }, | ||||
|             }, | ||||
|             action4: { | ||||
|               type: 'void', | ||||
|               title: '操作 2', | ||||
|               'x-component': 'Action', | ||||
|               'x-component-props': { | ||||
|                 useAction, | ||||
|               }, | ||||
|             }, | ||||
|             action1: { | ||||
|               type: 'void', | ||||
|               name: 'action1', | ||||
|               title: '查看', | ||||
|               'x-component': 'Action', | ||||
|               // 'x-default-action': true,
 | ||||
|               'x-designable-bar': 'Action.DesignableBar', | ||||
|               properties: { | ||||
|                 drawer1: { | ||||
|                   type: 'void', | ||||
|                   title: '查看', | ||||
|                   'x-component': 'Action.Modal', | ||||
|                   'x-component-props': {}, | ||||
|                   properties: { | ||||
|                     [uid()]: { | ||||
|                       type: 'void', | ||||
|                       'x-component': 'Tabs', | ||||
|                       properties: { | ||||
|                         tab1: { | ||||
|                           type: 'void', | ||||
|                           'x-component': 'Tabs.TabPane', | ||||
|                           'x-component-props': { | ||||
|                             tab: 'Tab1', | ||||
|                           }, | ||||
|                           properties: { | ||||
|                             aaa: { | ||||
|                               type: 'string', | ||||
|                               title: 'AAA', | ||||
|                               'x-decorator': 'FormItem', | ||||
|                               required: true, | ||||
|                               'x-component': 'Input', | ||||
|                             }, | ||||
|                           }, | ||||
|                         }, | ||||
|                         tab2: { | ||||
|                           type: 'void', | ||||
|                           'x-component': 'Tabs.TabPane', | ||||
|                           'x-component-props': { | ||||
|                             tab: 'Tab2', | ||||
|                           }, | ||||
|                           properties: { | ||||
|                             bbb: { | ||||
|                               type: 'string', | ||||
|                               title: 'BBB', | ||||
|                               'x-decorator': 'FormItem', | ||||
|                               required: true, | ||||
|                               'x-component': 'Input', | ||||
|                             }, | ||||
|                           }, | ||||
|                         }, | ||||
|                       }, | ||||
|                     }, | ||||
|                   }, | ||||
|                 }, | ||||
|               }, | ||||
|             }, | ||||
|             action2: { | ||||
|               type: 'void', | ||||
|               name: 'action1', | ||||
|               title: '修改', | ||||
|               'x-component': 'Action', | ||||
|               'x-default-action': true, | ||||
|               'x-designable-bar': 'Action.DesignableBar', | ||||
|               properties: { | ||||
|                 drawer1: { | ||||
|                   type: 'void', | ||||
|                   title: '编辑表单', | ||||
|                   'x-component': 'Action.Modal', | ||||
|                   'x-component-props': {}, | ||||
|                   properties: { | ||||
|                     [uid()]: { | ||||
|                       name: 'form', | ||||
|                       type: 'void', | ||||
|                       'x-component': 'Form', | ||||
|                       'x-component-props': { | ||||
|                         useValues: '{{ useTableRow }}', | ||||
|                       }, | ||||
|                       properties: { | ||||
|                         field1: { | ||||
|                           type: 'string', | ||||
|                           title: '字段1', | ||||
|                           'x-decorator': 'FormItem', | ||||
|                           'x-component': 'Input', | ||||
|                         }, | ||||
|                         field2: { | ||||
|                           type: 'string', | ||||
|                           title: '字段2', | ||||
|                           'x-decorator': 'FormItem', | ||||
|                           'x-component': 'Input', | ||||
|                         }, | ||||
|                         action: { | ||||
|                           type: 'void', | ||||
|                           title: '提交', | ||||
|                           'x-component': 'Action', | ||||
|                           'x-component-props': { | ||||
|                             useAction: '{{ useTableUpdateAction }}', | ||||
|                           }, | ||||
|                         }, | ||||
|                       }, | ||||
|                     }, | ||||
|                   }, | ||||
|                 }, | ||||
|               }, | ||||
|             }, | ||||
|             action3: { | ||||
|               type: 'void', | ||||
|               title: '删除', | ||||
|               'x-component': 'Action', | ||||
|               'x-component-props': { | ||||
|                 useAction: '{{ useTableDestroyAction }}', | ||||
|               }, | ||||
|             }, | ||||
|           }, | ||||
|         }, | ||||
|       }, | ||||
|     }, | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| const form = createForm(); | ||||
| 
 | ||||
| export default observer(() => { | ||||
|   return ( | ||||
|     <div> | ||||
|       <SchemaRenderer form={form} schema={schema} /> | ||||
|       {/* <Editor | ||||
|         height="200px" | ||||
|         defaultLanguage="json" | ||||
|         value={JSON.stringify(form.values, null, 2)} | ||||
|       /> */} | ||||
|     </div> | ||||
|   ); | ||||
| }); | ||||
| @ -5,8 +5,8 @@ nav: | ||||
|   path: /client | ||||
| group: | ||||
|   order: 1 | ||||
|   title: Components - 组件 | ||||
|   path: /client/components | ||||
|   title: Schemas | ||||
|   path: /client/schemas | ||||
| --- | ||||
| 
 | ||||
| # Table - 表格 | ||||
| @ -1,4 +1,4 @@ | ||||
| import React, { createContext, useContext, useState } from 'react'; | ||||
| import React, { createContext, useContext, useRef, useState } from 'react'; | ||||
| import { | ||||
|   useFieldSchema, | ||||
|   Schema, | ||||
| @ -24,12 +24,17 @@ import { BaseResult } from '@ahooksjs/use-request/lib/types'; | ||||
| import { uid, clone } from '@formily/shared'; | ||||
| import { MenuOutlined } from '@ant-design/icons'; | ||||
| import { useVisibleContext } from '../action'; | ||||
| import { SortableHandle, SortableContainer, SortableElement } from 'react-sortable-hoc' | ||||
| import cls from 'classnames'; | ||||
| 
 | ||||
| interface TableRowProps { | ||||
|   index: number; | ||||
|   data: any; | ||||
| } | ||||
| 
 | ||||
| const SortableRow = SortableElement((props: any) => <tr {...props} />) | ||||
| const SortableBody = SortableContainer((props: any) => <tbody {...props} />) | ||||
| 
 | ||||
| const TableRowContext = createContext<TableRowProps>(null); | ||||
| 
 | ||||
| function usePaginationProps() { | ||||
| @ -55,6 +60,21 @@ function usePaginationProps() { | ||||
|   return false; | ||||
| } | ||||
| 
 | ||||
| function useDefaultAction() { | ||||
|   const schema = useFieldSchema(); | ||||
| 
 | ||||
|   function findDefaultAction(schema: Schema): Schema[] { | ||||
|     return schema.reduceProperties((columns, current) => { | ||||
|       if (current['x-default-action']) { | ||||
|         return [...columns, current]; | ||||
|       } | ||||
|       return [...columns, ...findDefaultAction(current)]; | ||||
|     }, []); | ||||
|   } | ||||
| 
 | ||||
|   return findDefaultAction(schema).shift(); | ||||
| } | ||||
| 
 | ||||
| function useTableActionBars() { | ||||
|   const schema = useFieldSchema(); | ||||
| 
 | ||||
| @ -127,7 +147,9 @@ export function useTableRow() { | ||||
| } | ||||
| 
 | ||||
| export function useTableIndex() { | ||||
|   const { params: { page, pageSize } } = useTableContext(); | ||||
|   const { | ||||
|     params: { page, pageSize }, | ||||
|   } = useTableContext(); | ||||
|   const ctx = useContext(TableRowContext); | ||||
|   const field = useField(); | ||||
|   if (!field.componentProps.isRemoteDataSource) { | ||||
| @ -138,7 +160,8 @@ export function useTableIndex() { | ||||
| 
 | ||||
| export function useTableDestroyAction() { | ||||
|   const ctx = useContext(TableRowContext); | ||||
|   const { field, selectedRowKeys, setSelectedRowKeys, refresh } = useTableContext(); | ||||
|   const { field, selectedRowKeys, setSelectedRowKeys, refresh } = | ||||
|     useTableContext(); | ||||
|   const rowKey = field.componentProps.rowKey || 'id'; | ||||
| 
 | ||||
|   return { | ||||
| @ -148,23 +171,19 @@ export function useTableDestroyAction() { | ||||
|         refresh(); | ||||
|         return; | ||||
|       } | ||||
|      | ||||
| 
 | ||||
|       if (!selectedRowKeys.length) { | ||||
|         return; | ||||
|       } | ||||
|       while (selectedRowKeys.length) { | ||||
|         const key = selectedRowKeys.shift(); | ||||
|         const index = findIndex( | ||||
|           field.value, | ||||
|           (item) => item[rowKey] === key, | ||||
|         ); | ||||
|         const index = findIndex(field.value, (item) => item[rowKey] === key); | ||||
|         field.remove(index); | ||||
|       } | ||||
|       refresh(); | ||||
|       setSelectedRowKeys([]); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|     }, | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| export function useTableFilterAction() { | ||||
| @ -175,8 +194,8 @@ export function useTableFilterAction() { | ||||
|     async run() { | ||||
|       setVisible && setVisible(false); | ||||
|       refresh(); | ||||
|     } | ||||
|   } | ||||
|     }, | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| export function useTableCreateAction() { | ||||
| @ -186,11 +205,14 @@ export function useTableCreateAction() { | ||||
|   return { | ||||
|     async run() { | ||||
|       setVisible && setVisible(false); | ||||
|       field.unshift(clone(form.values)); | ||||
|       field.push({ | ||||
|         key: uid(), | ||||
|         ...clone(form.values), | ||||
|       }); | ||||
|       form.reset(); | ||||
|       exec({...params, page: 1}); | ||||
|     } | ||||
|   } | ||||
|       exec({ ...params, page: 1 }); | ||||
|     }, | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| export function useTableUpdateAction() { | ||||
| @ -201,12 +223,13 @@ export function useTableUpdateAction() { | ||||
|     async run() { | ||||
|       setVisible && setVisible(false); | ||||
|       refresh(); | ||||
|     } | ||||
|   } | ||||
|     }, | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| const [TableContextProvider, useTableContext] = constate(() => { | ||||
|   const field = useField<Formily.Core.Models.ArrayField>(); | ||||
|   const schema = useFieldSchema(); | ||||
|   const [selectedRowKeys, setSelectedRowKeys] = useState([]); | ||||
|   const pagination = usePaginationProps(); | ||||
|   const response = useRequest<{ | ||||
| @ -239,7 +262,14 @@ const [TableContextProvider, useTableContext] = constate(() => { | ||||
|     pageSize: pagination.defaultPageSize, | ||||
|     ...(response.params[0] || {}), | ||||
|   }; | ||||
|   return { ...response, params, field, selectedRowKeys, setSelectedRowKeys }; | ||||
|   return { | ||||
|     ...response, | ||||
|     params, | ||||
|     field, | ||||
|     schema, | ||||
|     selectedRowKeys, | ||||
|     setSelectedRowKeys, | ||||
|   }; | ||||
| }); | ||||
| 
 | ||||
| export { TableContextProvider, useTableContext }; | ||||
| @ -251,12 +281,26 @@ const TableContainer = observer((props) => { | ||||
|   const { loading, data, refresh, selectedRowKeys, setSelectedRowKeys } = | ||||
|     useTableContext(); | ||||
|   const rowKey = field.componentProps.rowKey || 'id'; | ||||
|   console.log({ actionBars }); | ||||
|   const dataSource = Array.isArray(field.value) ? field.value.slice() : [] | ||||
|   const defaultAction = useDefaultAction(); | ||||
|   console.log({ defaultAction }); | ||||
|   const dataSource = Array.isArray(field.value) ? field.value.slice() : []; | ||||
|   const columns = useTableColumns({ dataSource }); | ||||
| 
 | ||||
|   const ref = useRef<HTMLDivElement>() | ||||
|   const addTdStyles = (node: HTMLElement) => { | ||||
|     const helper = document.body.querySelector(`.nb-table-sort-helper`) | ||||
|     if (helper) { | ||||
|       const tds = node.querySelectorAll('td') | ||||
|       requestAnimationFrame(() => { | ||||
|         helper.querySelectorAll('td').forEach((td, index) => { | ||||
|           if (tds[index]) { | ||||
|             td.style.width = getComputedStyle(tds[index]).width | ||||
|           } | ||||
|         }) | ||||
|       }) | ||||
|     } | ||||
|   } | ||||
|   return ( | ||||
|     <div> | ||||
|     <div ref={ref} className={'nb-table'}> | ||||
|       {actionBars.top.map((actionBarSchema) => { | ||||
|         return ( | ||||
|           <RecursionField | ||||
| @ -286,14 +330,56 @@ const TableContainer = observer((props) => { | ||||
|         }} | ||||
|         dataSource={data?.list} | ||||
|         columns={columns} | ||||
|         components={{ | ||||
|           body: { | ||||
|             wrapper: (props: any) => ( | ||||
|               <SortableBody | ||||
|                 useDragHandle | ||||
|                 lockAxis="y" | ||||
|                 // disableAutoscroll
 | ||||
|                 helperClass={`nb-table-sort-helper`} | ||||
|                 helperContainer={() => { | ||||
|                   return ref.current?.querySelector('tbody') | ||||
|                 }} | ||||
|                 onSortStart={({ node }) => { | ||||
|                   addTdStyles(node) | ||||
|                 }} | ||||
|                 onSortEnd={({ oldIndex, newIndex }) => { | ||||
|                   field.move(oldIndex, newIndex); | ||||
|                   refresh(); | ||||
|                 }} | ||||
|                 {...props} | ||||
|               /> | ||||
|             ), | ||||
|             row: (props: any) => { | ||||
|               const index = findIndex(field.value, item => item[rowKey] === props['data-row-key']); | ||||
|               return ( | ||||
|                 <SortableRow | ||||
|                   index={index} | ||||
|                   {...props} | ||||
|                 /> | ||||
|               ) | ||||
|             }, | ||||
|           }, | ||||
|         }} | ||||
|         onRow={(data) => { | ||||
|           const index = dataSource.indexOf(data); | ||||
|           return { | ||||
|             onClick(e) { | ||||
|               field.query(`.${schema.name}.${index}.action2`).take((f) => { | ||||
|                 const setVisible = f.componentProps.setVisible; | ||||
|                 setVisible && setVisible(true); | ||||
|               }); | ||||
|               console.log('onRow', (e.target as HTMLElement), (e.target as HTMLElement).classList.contains('ant-table-cell')); | ||||
|               if (!(e.target as HTMLElement).classList.contains('ant-table-cell')) { | ||||
|                 return; | ||||
|               } | ||||
|               if (!defaultAction) { | ||||
|                 return; | ||||
|               } | ||||
|               // console.log('defaultAction');
 | ||||
|               field | ||||
|                 .query(`.${schema.name}.${index}.${defaultAction.name}`) | ||||
|                 .take((f) => { | ||||
|                   const setVisible = f.componentProps.setVisible; | ||||
|                   setVisible && setVisible(true); | ||||
|                 }); | ||||
|             }, | ||||
|           }; | ||||
|         }} | ||||
| @ -337,28 +423,64 @@ Table.ActionBar = observer((props) => { | ||||
| 
 | ||||
| Table.Pagination = observer((props) => { | ||||
|   const { data, params, run } = useTableContext(); | ||||
|   return data?.total > params?.pageSize && ( | ||||
|     <Pagination | ||||
|       {...props} | ||||
|       defaultCurrent={1} | ||||
|       defaultPageSize={5} | ||||
|       current={params?.page} | ||||
|       pageSize={params?.pageSize} | ||||
|       total={data?.total} | ||||
|       onChange={(page, pageSize) => { | ||||
|         run({ page, pageSize }); | ||||
|       }} | ||||
|     /> | ||||
|   return ( | ||||
|     data?.total > params?.pageSize && ( | ||||
|       <Pagination | ||||
|         {...props} | ||||
|         defaultCurrent={1} | ||||
|         defaultPageSize={5} | ||||
|         current={params?.page} | ||||
|         pageSize={params?.pageSize} | ||||
|         total={data?.total} | ||||
|         onChange={(page, pageSize) => { | ||||
|           run({ page, pageSize }); | ||||
|         }} | ||||
|       /> | ||||
|     ) | ||||
|   ); | ||||
| }); | ||||
| 
 | ||||
| const SortHandle = SortableHandle((props: any) => { | ||||
|   return ( | ||||
|     <MenuOutlined | ||||
|       {...props} | ||||
|       className={cls(`nb-table-sort-handle`, props.className)} | ||||
|       style={{ ...props.style }} | ||||
|     /> | ||||
|   ) | ||||
| }) as any | ||||
| 
 | ||||
| Table.SortHandle = observer((props) => { | ||||
|   const field = useField<Formily.Core.Models.Field>(); | ||||
|   console.log('SortHandle', field.value); | ||||
|   return <MenuOutlined />; | ||||
|   return <SortHandle {...props}/>; | ||||
| }); | ||||
| 
 | ||||
| Table.Index = observer((props) => { | ||||
|   const index = useTableIndex(); | ||||
|   return <div>#{index + 1}</div>; | ||||
| }); | ||||
| 
 | ||||
| Table.Addition = observer((props: any) => { | ||||
|   const { field, refresh } = useTableContext(); | ||||
|   const current = useField(); | ||||
|   return ( | ||||
|     <Button | ||||
|       block | ||||
|       onClick={() => { | ||||
|         if (props.method === 'unshift') { | ||||
|           field.unshift({ | ||||
|             key: uid(), | ||||
|           }); | ||||
|         } else { | ||||
|           field.push({ | ||||
|             key: uid(), | ||||
|           }); | ||||
|         } | ||||
|         refresh(); | ||||
|       }} | ||||
|     > | ||||
|       {current.title} | ||||
|     </Button> | ||||
|   ); | ||||
| }); | ||||
| @ -5,8 +5,8 @@ nav: | ||||
|   path: /client | ||||
| group: | ||||
|   order: 1 | ||||
|   title: Components - 组件 | ||||
|   path: /client/components | ||||
|   title: Schemas | ||||
|   path: /client/schemas | ||||
| --- | ||||
| 
 | ||||
| # Tabs - 标签页 | ||||
| @ -5,8 +5,8 @@ nav: | ||||
|   path: /client | ||||
| group: | ||||
|   order: 1 | ||||
|   title: Components - 组件 | ||||
|   path: /client/components | ||||
|   title: Schemas | ||||
|   path: /client/schemas | ||||
| --- | ||||
| 
 | ||||
| # TimePicker - 时间选择器 | ||||
| @ -5,8 +5,8 @@ nav: | ||||
|   path: /client | ||||
| group: | ||||
|   order: 1 | ||||
|   title: Components - 组件 | ||||
|   path: /client/components | ||||
|   title: Schemas | ||||
|   path: /client/schemas | ||||
| --- | ||||
| 
 | ||||
| # Upload - 上传 | ||||
| @ -22,7 +22,7 @@ import { | ||||
|   refreshGlobalAction, | ||||
|   RouteComponentContext, | ||||
| } from '../../'; | ||||
| import { SchemaRenderer } from '../../blocks'; | ||||
| import { SchemaRenderer } from '../../schemas'; | ||||
| import { useRequest } from 'ahooks'; | ||||
| import { | ||||
|   DatabaseOutlined, | ||||
| @ -32,7 +32,7 @@ import { | ||||
| import { Tabs } from 'antd'; | ||||
| import '@formily/antd/esm/array-collapse/style'; | ||||
| import './style.less'; | ||||
| import { MenuContainerContext } from '../../blocks/menu'; | ||||
| import { MenuContainerContext } from '../../schemas/menu'; | ||||
| 
 | ||||
| function LogoutButton() { | ||||
|   const history = useHistory(); | ||||
|  | ||||
| @ -2,7 +2,7 @@ import React, { useContext, useEffect, useState } from 'react'; | ||||
| import { Spin } from 'antd'; | ||||
| import { Helmet } from 'react-helmet'; | ||||
| import { useRequest } from 'ahooks'; | ||||
| import { SchemaRenderer } from '../../blocks'; | ||||
| import { SchemaRenderer } from '../../schemas'; | ||||
| 
 | ||||
| export function DefaultPage({ route }) { | ||||
|   const { data = {}, loading } = useRequest( | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user