diff --git a/packages/client/src/schema-component/antd/action/Action.Link.tsx b/packages/client/src/schema-component/antd/action/Action.Link.tsx index da4285cab..abea6b89d 100644 --- a/packages/client/src/schema-component/antd/action/Action.Link.tsx +++ b/packages/client/src/schema-component/antd/action/Action.Link.tsx @@ -1,31 +1,11 @@ -import { observer, useField, useFieldSchema } from '@formily/react'; -import React, { useState } from 'react'; +import { observer } from '@formily/react'; +import React from 'react'; import { Link } from 'react-router-dom'; -import { ActionContext } from './context'; -import { useA } from './hooks'; +import Action from './Action'; import { ComposedAction } from './types'; export const ActionLink: ComposedAction = observer((props: any) => { - const { openMode, containerRefKey, useAction = useA, onClick, ...others } = props; - const [visible, setVisible] = useState(false); - const schema = useFieldSchema(); - const field = useField(); - const { run } = useAction(); - return ( - - { - onClick && onClick(e); - setVisible(true); - run(); - }} - > - {field.title} - - {props.children} - - ); + return ; }); export default ActionLink; diff --git a/packages/client/src/schema-component/antd/action/Action.tsx b/packages/client/src/schema-component/antd/action/Action.tsx index 158256489..929cb28a4 100644 --- a/packages/client/src/schema-component/antd/action/Action.tsx +++ b/packages/client/src/schema-component/antd/action/Action.tsx @@ -1,39 +1,110 @@ -import { observer, useField, useFieldSchema } from '@formily/react'; +import { css } from '@emotion/css'; +import { observer, useField } from '@formily/react'; import { Button } from 'antd'; +import classnames from 'classnames'; import React, { useState } from 'react'; +import { Link } from 'react-router-dom'; +import { GeneralSchemaDesigner, SchemaSettings } from '../../../schema-settings'; +import { SortableItem } from '../../common'; +import { useDesigner } from '../../hooks'; import ActionContainer from './Action.Container'; import { ActionDrawer } from './Action.Drawer'; -import { ActionLink } from './Action.Link'; import { ActionModal } from './Action.Modal'; import { ActionPage } from './Action.Page'; import { ActionContext } from './context'; import { useA } from './hooks'; import { ComposedAction } from './types'; +export const actionDesignerCss = css` + position: relative; + &:hover { + > .general-schema-designer { + display: block; + } + } + &.nb-action-link { + > .general-schema-designer { + top: -10px; + bottom: -10px; + left: -10px; + right: -10px; + } + } + > .general-schema-designer { + position: absolute; + z-index: 999; + top: 0; + bottom: 0; + left: 0; + right: 0; + display: none; + background: rgba(241, 139, 98, 0.06); + border: 0; + top: 0; + bottom: 0; + left: 0; + right: 0; + pointer-events: none; + > .general-schema-designer-icons { + position: absolute; + right: 2px; + top: 2px; + line-height: 16px; + pointer-events: all; + .ant-space-item { + background-color: #f18b62; + color: #fff; + line-height: 16px; + width: 16px; + padding-left: 1px; + } + } + } +`; + export const Action: ComposedAction = observer((props: any) => { - const { openMode, containerRefKey, useAction = useA, onClick, ...others } = props; + const { openMode, containerRefKey, component, useAction = useA, onClick, className, ...others } = props; const [visible, setVisible] = useState(false); - const schema = useFieldSchema(); + const Designer = useDesigner(); const field = useField(); const { run } = useAction(); return ( - + {props.children} ); }); -Action.Link = ActionLink; +Action.Designer = () => { + return ( + + { + return s['x-component'] === 'Space' || s['x-component'] === 'ActionBar'; + }} + /> + + ); +}; + +Action.Link = observer((props) => { + return ; +}); + Action.Drawer = ActionDrawer; Action.Modal = ActionModal; Action.Container = ActionContainer; diff --git a/packages/client/src/schema-component/antd/action/types.ts b/packages/client/src/schema-component/antd/action/types.ts index d40c68c25..67aeab70f 100644 --- a/packages/client/src/schema-component/antd/action/types.ts +++ b/packages/client/src/schema-component/antd/action/types.ts @@ -1,6 +1,7 @@ import { ButtonProps, DrawerProps } from 'antd'; export type ActionProps = ButtonProps & { + component?: any; useAction?: () => { run(): Promise; }; diff --git a/packages/client/src/schema-component/antd/array-table/ArrayTable.tsx b/packages/client/src/schema-component/antd/array-table/ArrayTable.tsx index 18966da5e..0d4d41037 100644 --- a/packages/client/src/schema-component/antd/array-table/ArrayTable.tsx +++ b/packages/client/src/schema-component/antd/array-table/ArrayTable.tsx @@ -62,6 +62,7 @@ export const ArrayTable: ArrayTableType = observer((props) => { ArrayTable.Column = (props) => { const field = useField(); + console.log('field.title', field.title); return
{field.title}
; }; diff --git a/packages/client/src/schema-component/antd/array-table/TableActionDesignable.tsx b/packages/client/src/schema-component/antd/array-table/TableActionDesignable.tsx deleted file mode 100644 index 8554ccba1..000000000 --- a/packages/client/src/schema-component/antd/array-table/TableActionDesignable.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { observer, useFieldSchema } from '@formily/react'; -import React from 'react'; -import { createDesignable, useDesignable } from '../..'; -import { useAPIClient } from '../../../api-client'; - -export const TableActionDesignable = observer((props) => { - const fieldSchema = useFieldSchema(); - const api = useAPIClient(); - const { refresh } = useDesignable(); - return ( -
- { - const spaceSchema = fieldSchema.reduceProperties((buf, schema) => { - if (schema['x-component'] === 'Space') { - return schema; - } - return buf; - }, null); - const dn = createDesignable({ - current: spaceSchema, - refresh, - api, - }); - dn.loadAPIClientEvents(); - dn.insertBeforeEnd({ - type: 'void', - title: '{{ t("Delete") }}', - 'x-component': 'Action.Link', - 'x-component-props': { - useAction: '{{ useDestroyAction }}', - }, - }); - }} - > - Edit - - {props.children} -
- ); -}); diff --git a/packages/client/src/schema-component/antd/array-table/TableActionDesignableBar.tsx b/packages/client/src/schema-component/antd/array-table/TableActionDesignableBar.tsx deleted file mode 100644 index b15e90d0f..000000000 --- a/packages/client/src/schema-component/antd/array-table/TableActionDesignableBar.tsx +++ /dev/null @@ -1,4 +0,0 @@ -import React from 'react'; -export const TableActionDesignableBar = () => { - return
Edit
; -}; diff --git a/packages/client/src/schema-component/antd/array-table/TableColumnActionBar.tsx b/packages/client/src/schema-component/antd/array-table/TableColumnActionBar.tsx index 7e5a80b29..4974970dd 100644 --- a/packages/client/src/schema-component/antd/array-table/TableColumnActionBar.tsx +++ b/packages/client/src/schema-component/antd/array-table/TableColumnActionBar.tsx @@ -1,14 +1,53 @@ -import { observer, useFieldSchema } from '@formily/react'; +import { css } from '@emotion/css'; +import { observer } from '@formily/react'; import React from 'react'; -import { useComponent } from '../..'; +import { SortableItem, useDesigner } from '../..'; + +export const designerCss = css` + position: relative; + &:hover { + > .general-schema-designer { + display: block; + } + } + > .general-schema-designer { + position: absolute; + z-index: 999; + top: 0; + bottom: 0; + left: 0; + right: 0; + display: none; + background: rgba(241, 139, 98, 0.06) !important; + border: 0 !important; + top: -16px !important; + bottom: -16px !important; + left: -16px !important; + right: -16px !important; + pointer-events: none; + > .general-schema-designer-icons { + position: absolute; + right: 2px; + top: 2px; + line-height: 16px; + pointer-events: all; + .ant-space-item { + background-color: #f18b62; + color: #fff; + line-height: 16px; + width: 16px; + padding-left: 1px; + } + } + } +`; export const TableColumnActionBar = observer((props) => { - const fieldSchema = useFieldSchema(); - const ActionInitializer = useComponent(fieldSchema['x-action-initializer']); + const Designer = useDesigner(); return ( -
- {ActionInitializer && } + + {props.children} -
+ ); }); diff --git a/packages/client/src/schema-component/antd/array-table/TableColumnDecorator.tsx b/packages/client/src/schema-component/antd/array-table/TableColumnDecorator.tsx index ec5e9a285..60015433e 100644 --- a/packages/client/src/schema-component/antd/array-table/TableColumnDecorator.tsx +++ b/packages/client/src/schema-component/antd/array-table/TableColumnDecorator.tsx @@ -1,7 +1,6 @@ import { useField, useFieldSchema } from '@formily/react'; -import { uid } from '@formily/shared'; -import React, { useEffect } from 'react'; -import { useCollection, useDesignable } from '../../../'; +import React, { useLayoutEffect } from 'react'; +import { designerCss, SortableItem, useCollection, useDesignable, useDesigner } from '../../../'; export const useColumnSchema = () => { const { getField } = useCollection(); @@ -20,10 +19,11 @@ export const useColumnSchema = () => { }; export const TableColumnDecorator = (props) => { + const Designer = useDesigner(); const field = useField(); const { columnSchema, fieldSchema, collectionField } = useColumnSchema(); const { refresh } = useDesignable(); - useEffect(() => { + useLayoutEffect(() => { if (field.title) { return; } @@ -33,22 +33,25 @@ export const TableColumnDecorator = (props) => { if (collectionField?.uiSchema?.title) { field.title = collectionField?.uiSchema?.title; } - }, []); + }, [collectionField?.uiSchema?.title]); + console.log('field.title', collectionField?.uiSchema?.title, field.title); return ( - <> - {props.children} -
+ + {/* */} + {field.title || collectionField?.uiSchema?.title} + {/*
{ field.title = uid(); - columnSchema.title = field.title = field.title; - refresh(); - field.query(`.*.${fieldSchema.name}`).take((f) => { - f.componentProps.dateFormat = 'YYYY-MM-DD'; - }); + // columnSchema.title = field.title = field.title; + // refresh(); + // field.query(`.*.${fieldSchema.name}`).take((f) => { + // f.componentProps.dateFormat = 'YYYY-MM-DD'; + // }); }} > Edit -
- +
*/} + ); }; diff --git a/packages/client/src/schema-component/antd/array-table/TableColumnDeigner.tsx b/packages/client/src/schema-component/antd/array-table/TableColumnDeigner.tsx new file mode 100644 index 000000000..657a18772 --- /dev/null +++ b/packages/client/src/schema-component/antd/array-table/TableColumnDeigner.tsx @@ -0,0 +1,35 @@ +import { useField, useFieldSchema } from '@formily/react'; +import { uid } from '@formily/shared'; +import React from 'react'; +import { GeneralSchemaDesigner, SchemaSettings } from '../../../schema-settings'; +import { useDesignable } from '../../hooks'; + +export const TableColumnDeigner = () => { + const field = useField(); + const fieldSchema = useFieldSchema(); + const { dn } = useDesignable(); + return ( + + { + field.title = uid(); + fieldSchema.title = uid(); + dn.emit('patch', { + schema: { + 'x-uid': fieldSchema['x-uid'], + title: fieldSchema.title, + }, + }); + }} + /> + + + + ); +}; diff --git a/packages/client/src/schema-component/antd/array-table/TableRecordActionDesigner.tsx b/packages/client/src/schema-component/antd/array-table/TableRecordActionDesigner.tsx new file mode 100644 index 000000000..040a05738 --- /dev/null +++ b/packages/client/src/schema-component/antd/array-table/TableRecordActionDesigner.tsx @@ -0,0 +1,22 @@ +import { DragOutlined } from '@ant-design/icons'; +import { useFieldSchema } from '@formily/react'; +import { Space } from 'antd'; +import React from 'react'; +import { DragHandler, useComponent } from '../../../schema-component'; + +export const TableRecordActionDesigner = (props: any) => { + const fieldSchema = useFieldSchema(); + const ActionInitializer = useComponent(fieldSchema['x-action-initializer']); + return ( +
+
+ + + + + + +
+
+ ); +}; diff --git a/packages/client/src/schema-component/antd/array-table/index.ts b/packages/client/src/schema-component/antd/array-table/index.ts index 8bde0aaf1..76cf14f72 100644 --- a/packages/client/src/schema-component/antd/array-table/index.ts +++ b/packages/client/src/schema-component/antd/array-table/index.ts @@ -1,5 +1,6 @@ export * from './ArrayTable'; export * from './TableColumnActionBar'; export * from './TableColumnDecorator'; - +export * from './TableColumnDeigner'; +export * from './TableRecordActionDesigner'; diff --git a/packages/client/src/schema-component/antd/block-item/BlockItem.tsx b/packages/client/src/schema-component/antd/block-item/BlockItem.tsx index 9e1e985d5..413d02fb0 100644 --- a/packages/client/src/schema-component/antd/block-item/BlockItem.tsx +++ b/packages/client/src/schema-component/antd/block-item/BlockItem.tsx @@ -19,7 +19,7 @@ export const BlockItem: React.FC = (props) => { } } &.nb-form-item:hover { - .general-schema-designer { + > .general-schema-designer { background: rgba(241, 139, 98, 0.06) !important; border: 0 !important; top: -5px !important; @@ -28,7 +28,7 @@ export const BlockItem: React.FC = (props) => { right: -5px !important; } } - .general-schema-designer { + > .general-schema-designer { position: absolute; z-index: 999; top: 0; @@ -38,7 +38,7 @@ export const BlockItem: React.FC = (props) => { display: none; border: 2px solid rgba(241, 139, 98, 0.3); pointer-events: none; - .general-schema-designer-icons { + > .general-schema-designer-icons { position: absolute; right: 2px; top: 2px; diff --git a/packages/client/src/schema-component/common/sortable-item/SortableItem.tsx b/packages/client/src/schema-component/common/sortable-item/SortableItem.tsx index 54c8e6736..a04979b80 100644 --- a/packages/client/src/schema-component/common/sortable-item/SortableItem.tsx +++ b/packages/client/src/schema-component/common/sortable-item/SortableItem.tsx @@ -3,46 +3,51 @@ import { observer, useField, useFieldSchema } from '@formily/react'; import React, { createContext, useContext } from 'react'; export const DraggableContext = createContext(null); +export const SortableContext = createContext(null); -export const Sortable = (props: any) => { - const { id, data, style, children, ...others } = props; +export const SortableProvider = (props) => { + const { id, data, children } = props; const draggable = useDraggable({ id, data, }); - - const { isOver, setNodeRef } = useDroppable({ + const droppable = useDroppable({ id, data, }); + return {children}; +}; +export const Sortable = (props: any) => { + const { component, style, children, ...others } = props; + const { droppable } = useContext(SortableContext); + const { isOver, setNodeRef } = droppable; const droppableStyle = { ...style }; if (isOver) { droppableStyle['color'] = 'rgba(241, 139, 98, .1)'; } - return ( - -
- {children} -
-
- ); + return React.createElement(component || 'div', { + ...others, + ref: setNodeRef, + style: droppableStyle, + }, children); }; export const SortableItem: React.FC = observer((props) => { const field = useField(); const fieldSchema = useFieldSchema(); return ( - - {props.children} - + + {props.children} + ); }); export const DragHandler = (props) => { - const { isDragging, attributes, listeners, setNodeRef, transform } = useContext(DraggableContext); + const { draggable } = useContext(SortableContext); + const { isDragging, attributes, listeners, setNodeRef, transform } = draggable; const style = transform ? { transform: `translate3d(${transform.x}px, ${transform.y}px, 0)`, diff --git a/packages/client/src/schema-initializer/Initializers/BlockInitializer/TableBlock.tsx b/packages/client/src/schema-initializer/Initializers/BlockInitializer/TableBlock.tsx index 705ca00af..1b8acffc4 100644 --- a/packages/client/src/schema-initializer/Initializers/BlockInitializer/TableBlock.tsx +++ b/packages/client/src/schema-initializer/Initializers/BlockInitializer/TableBlock.tsx @@ -51,10 +51,10 @@ const createSchema = (collectionName) => { properties: { actions: { type: 'void', - title: 'Actions', - 'x-designer': 'TestDesigner', + title: '{{ t("Actions") }}', 'x-decorator': 'TableColumnActionBar', 'x-component': 'VoidTable.Column', + 'x-designer': 'TableRecordActionDesigner', 'x-action-initializer': 'TableRecordActionInitializer', properties: { actions: { diff --git a/packages/client/src/schema-initializer/Initializers/TableActionInitializer/index.tsx b/packages/client/src/schema-initializer/Initializers/TableActionInitializer/index.tsx index e3a5048dc..586eb2b8d 100644 --- a/packages/client/src/schema-initializer/Initializers/TableActionInitializer/index.tsx +++ b/packages/client/src/schema-initializer/Initializers/TableActionInitializer/index.tsx @@ -34,7 +34,7 @@ const InitializeAction = SchemaInitializer.itemWrap((props) => { } insert({ type: 'void', - 'x-designer': 'TestDesigner', + 'x-designer': 'Action.Designer', 'x-component': 'Action', ...item.schema, }); diff --git a/packages/client/src/schema-initializer/Initializers/TableColumnInitializer/index.tsx b/packages/client/src/schema-initializer/Initializers/TableColumnInitializer/index.tsx index 928fbe6e8..0027c25f5 100644 --- a/packages/client/src/schema-initializer/Initializers/TableColumnInitializer/index.tsx +++ b/packages/client/src/schema-initializer/Initializers/TableColumnInitializer/index.tsx @@ -16,7 +16,6 @@ const useTableColumnInitializerFields = () => { title: field?.uiSchema?.title || field.name, schema: { name: field.name, - 'x-designer': 'TestDesigner', 'x-collection-field': `${name}.${field.name}`, 'x-component': 'CollectionField', }, @@ -63,6 +62,7 @@ const ColumnInitializerItem = SchemaInitializer.itemWrap((props) => { insert({ type: 'void', 'x-decorator': 'TableColumnDecorator', + 'x-designer': 'TableColumnDeigner', 'x-component': 'VoidTable.Column', properties: { [item.schema.name]: { diff --git a/packages/client/src/schema-initializer/Initializers/TableRecordActionInitializer/index.tsx b/packages/client/src/schema-initializer/Initializers/TableRecordActionInitializer/index.tsx index 2b8cf183e..082eefcc1 100644 --- a/packages/client/src/schema-initializer/Initializers/TableRecordActionInitializer/index.tsx +++ b/packages/client/src/schema-initializer/Initializers/TableRecordActionInitializer/index.tsx @@ -1,3 +1,5 @@ +import { MenuOutlined } from '@ant-design/icons'; +import { css } from '@emotion/css'; import { observer, Schema, useFieldSchema } from '@formily/react'; import { Switch } from 'antd'; import React from 'react'; @@ -67,7 +69,7 @@ const InitializeAction = SchemaInitializer.itemWrap((props) => { } insert({ type: 'void', - 'x-designer': 'TestDesigner', + 'x-designer': 'Action.Designer', 'x-component': 'Action.Link', ...item.schema, }); @@ -87,6 +89,16 @@ export const TableRecordActionInitializer = observer((props: any) => { const { t } = useTranslation(); return ( { const spaceSchema = fieldSchema.reduceProperties((buf, schema) => { @@ -119,6 +131,7 @@ export const TableRecordActionInitializer = observer((props: any) => { title: '{{ t("View") }}', type: 'void', 'x-action': 'view', + 'x-designer': 'Action.Designer', 'x-component': 'Action.Link', 'x-component-props': {}, properties: { @@ -231,7 +244,7 @@ export const TableRecordActionInitializer = observer((props: any) => { }, ]} > - Configure + ); }); diff --git a/packages/client/src/schema-initializer/SchemaInitializer.tsx b/packages/client/src/schema-initializer/SchemaInitializer.tsx index 02fe6722a..e0ef46b31 100644 --- a/packages/client/src/schema-initializer/SchemaInitializer.tsx +++ b/packages/client/src/schema-initializer/SchemaInitializer.tsx @@ -16,7 +16,7 @@ export const SchemaInitializerItemContext = createContext(null); export const SchemaInitializer = () => null; SchemaInitializer.Button = observer((props: SchemaInitializerButtonProps) => { - const { insert, wrap = defaultWrap, items = [], insertPosition, dropdown, ...others } = props; + const { insert, wrap = defaultWrap, items = [], insertPosition, dropdown, style, ...others } = props; let { insertAdjacent, findComponent } = useDesignable(); const [visible, setVisible] = useState(false); const insertSchema = (schema) => { @@ -96,6 +96,7 @@ SchemaInitializer.Button = observer((props: SchemaInitializerButtonProps) => { {...others} type={'dashed'} style={{ + ...style, borderColor: '#f18b62', color: '#f18b62', }} diff --git a/packages/client/src/schema-settings/SchemaSettings.tsx b/packages/client/src/schema-settings/SchemaSettings.tsx index 3b09f5951..fd625d49e 100644 --- a/packages/client/src/schema-settings/SchemaSettings.tsx +++ b/packages/client/src/schema-settings/SchemaSettings.tsx @@ -65,7 +65,15 @@ export const SchemaSettings: React.FC & SchemaSettingsNeste SchemaSettings.Item = (props) => { return ( - + { + info.domEvent.preventDefault(); + info.domEvent.stopPropagation(); + props?.onClick?.(info); + }} + style={{ minWidth: 120 }} + > {props.children || props.title} ); @@ -87,8 +95,7 @@ SchemaSettings.Remove = (props: any) => { const { removeParentsIfNoChildren, breakRemoveOn } = props; const { dn } = useSchemaSettings(); return ( - { dn.remove(null, { removeParentsIfNoChildren, @@ -97,7 +104,7 @@ SchemaSettings.Remove = (props: any) => { }} > 移除 - + ); };