diff --git a/packages/client/src/components/Sortable/index.tsx b/packages/client/src/components/Sortable/index.tsx index ac9c84038..3248bf6de 100644 --- a/packages/client/src/components/Sortable/index.tsx +++ b/packages/client/src/components/Sortable/index.tsx @@ -54,6 +54,30 @@ export function DragHandle() { ); } +export function Droppable(props) { + const { id, data = {}, className, component, children, ...others } = props; + const { isOver, setNodeRef: setDroppableNodeRef } = useDroppable({ + id: `droppable-${id}`, + data: { + ...data, + }, + }); + const Component = component || Div; + return ( + { + setDroppableNodeRef(el); + }} + > + {children} + + ); +} + export function SortableItem(props) { const { id, data = {}, className, component, children, ...others } = props; const previewRef = useRef(); diff --git a/packages/client/src/schemas/index.tsx b/packages/client/src/schemas/index.tsx index 78f0fed40..4feec70e6 100644 --- a/packages/client/src/schemas/index.tsx +++ b/packages/client/src/schemas/index.tsx @@ -61,6 +61,9 @@ export async function createSchema(schema: ISchema) { } export async function updateSchema(schema: ISchema) { + if (!schema) { + return; + } if (!schema['key']) { return; } diff --git a/packages/client/src/schemas/menu/index.tsx b/packages/client/src/schemas/menu/index.tsx index 27b65fe3a..c318e9883 100644 --- a/packages/client/src/schemas/menu/index.tsx +++ b/packages/client/src/schemas/menu/index.tsx @@ -112,6 +112,9 @@ export const Menu: any = observer((props: any) => { if (!path1 || !path2) { return; } + if (path1.join('.') === path2.join('.')) { + return; + } const data = findPropertyByPath(root, path1); if (!data) { return; diff --git a/packages/client/src/schemas/table/Sortable.tsx b/packages/client/src/schemas/table/Sortable.tsx index fda1c1289..ef3dc589c 100644 --- a/packages/client/src/schemas/table/Sortable.tsx +++ b/packages/client/src/schemas/table/Sortable.tsx @@ -143,6 +143,9 @@ export function SortableHeaderRow(props) { if (!path1 || !path2) { return; } + if (path1.join('.') === path2.join('.')) { + return; + } const data = findPropertyByPath(root, path1); if (!data) { return; diff --git a/packages/client/src/schemas/table/index.tsx b/packages/client/src/schemas/table/index.tsx index 978350550..cc18c32e2 100644 --- a/packages/client/src/schemas/table/index.tsx +++ b/packages/client/src/schemas/table/index.tsx @@ -29,6 +29,7 @@ import { Select, Dropdown, Menu, Switch, Button, Space } from 'antd'; import { PlusOutlined } from '@ant-design/icons'; import './style.less'; import { + findPropertyByPath, getSchemaPath, SchemaField, SchemaRenderer, @@ -57,7 +58,7 @@ import { SortableHeaderRow, SortableRowHandle, } from './Sortable'; -import { DragHandle, SortableItem } from '../../components/Sortable'; +import { DragHandle, Droppable, SortableItem } from '../../components/Sortable'; const SyntheticListenerMapContext = createContext(null); @@ -784,36 +785,107 @@ function Actions(props: any) { const { align = 'left' } = props; const { schema, designable } = useDesignable(); return ( - - {schema.mapProperties((s) => { - const currentAlign = s['x-align'] || 'left'; - if (currentAlign !== align) { - return null; - } - return ( - - - - ); - })} - + + + {schema.mapProperties((s) => { + const currentAlign = s['x-align'] || 'left'; + if (currentAlign !== align) { + return null; + } + return ( + + + + ); + })} + + ); } Table.ActionBar = observer((props: any) => { const { align = 'top' } = props; - const { schema, designable } = useDesignable(); + // const { schema, designable } = useDesignable(); + const { root, schema, insertAfter, remove, appendChild } = useDesignable(); + const moveToAfter = (path1, path2, extra = {}) => { + if (!path1 || !path2) { + return; + } + if (path1.join('.') === path2.join('.')) { + return; + } + const data = findPropertyByPath(root, path1); + if (!data) { + return; + } + remove(path1); + return insertAfter( + { + ...data.toJSON(), + ...extra, + }, + path2, + ); + }; + const [dragOverlayContent, setDragOverlayContent] = useState(''); return ( - { - setDragOverlayContent(event.active.data?.current?.title || ''); - // const previewRef = event.active.data?.current?.previewRef; - // if (previewRef) { - // setDragOverlayContent(previewRef?.current?.innerHTML); - // } else { - // setDragOverlayContent(''); - // } - }}> + { + setDragOverlayContent(event.active.data?.current?.title || ''); + // const previewRef = event.active.data?.current?.previewRef; + // if (previewRef) { + // setDragOverlayContent(previewRef?.current?.innerHTML); + // } else { + // setDragOverlayContent(''); + // } + }} + onDragEnd={async (event) => { + const path1 = event.active?.data?.current?.path; + const path2 = event.over?.data?.current?.path; + const align = event.over?.data?.current?.align; + const draggable = event.over?.data?.current?.draggable; + if (!path1 || !path2) { + return; + } + if (path1.join('.') === path2.join('.')) { + return; + } + if (!draggable) { + console.log('alignalignalignalign', align); + const p = findPropertyByPath(root, path1); + if (!p) { + return; + } + remove(path1); + const data = appendChild( + { + ...p.toJSON(), + 'x-align': align, + }, + path2, + ); + await updateSchema(data); + } else { + const data = moveToAfter(path1, path2, { + 'x-align': align, + }); + await updateSchema(data); + } + }} + > {dragOverlayContent} {/*
*/} @@ -910,6 +982,7 @@ Table.Filter.DesignableBar = () => { }} className={cls('designable-bar-actions', { active: visible })} > +