From 0ca3fef9d30137686bcc1c0dc47605b04cbb47b9 Mon Sep 17 00:00:00 2001 From: chenos Date: Mon, 2 Aug 2021 16:17:27 +0800 Subject: [PATCH] `moveTo` for menu & table & tabs --- packages/client/src/schemas/menu/index.tsx | 38 +++++++++++++++--- .../client/src/schemas/table/Sortable.tsx | 40 +++++++++++++++++++ packages/client/src/schemas/tabs/index.tsx | 25 ++++++++++-- 3 files changed, 94 insertions(+), 9 deletions(-) diff --git a/packages/client/src/schemas/menu/index.tsx b/packages/client/src/schemas/menu/index.tsx index fd6d5f537..27b65fe3a 100644 --- a/packages/client/src/schemas/menu/index.tsx +++ b/packages/client/src/schemas/menu/index.tsx @@ -107,7 +107,18 @@ export const Menu: any = observer((props: any) => { defaultSelectedKeys = [], ...others } = props; - const { designable, schema } = useDesignable(); + const { root, schema, insertAfter, remove } = useDesignable(); + const moveToAfter = (path1, path2) => { + if (!path1 || !path2) { + return; + } + const data = findPropertyByPath(root, path1); + if (!data) { + return; + } + remove(path1); + return insertAfter(data.toJSON(), path2); + } const fieldSchema = useFieldSchema(); console.log('Menu.schema', schema, fieldSchema); const [selectedKey, setSelectedKey] = useState( @@ -140,9 +151,18 @@ export const Menu: any = observer((props: any) => { const [dragOverlayContent, setDragOverlayContent] = useState(''); return ( - { - setDragOverlayContent(event.active.data?.current?.title || ''); - }}> + { + console.log({ event }); + setDragOverlayContent(event.active.data?.current?.title || ''); + }} + onDragEnd={async (event) => { + const path1 = event.active?.data?.current?.path; + const path2 = event.over?.data?.current?.path; + const data = moveToAfter(path1, path2); + await updateSchema(data); + }} + > {createPortal( { id={schema.name} data={{ title: schema.title, + path: getSchemaPath(schema), }} > {icon && ( - + + + )} {schema.title} @@ -247,10 +270,13 @@ Menu.Link = observer((props: any) => { id={schema.name} data={{ title: schema.title, + path: getSchemaPath(schema), }} > {icon && ( - + + + )} {schema.title} diff --git a/packages/client/src/schemas/table/Sortable.tsx b/packages/client/src/schemas/table/Sortable.tsx index 78bfa09f7..fda1c1289 100644 --- a/packages/client/src/schemas/table/Sortable.tsx +++ b/packages/client/src/schemas/table/Sortable.tsx @@ -29,6 +29,13 @@ import { import { createPortal } from 'react-dom'; import { useRef } from 'react'; import { SortableItem } from '../../components/Sortable'; +import { + findPropertyByPath, + getSchemaPath, + useDesignable, +} from '../../components/schema-renderer'; +import { updateSchema } from '..'; +import { Schema } from '@formily/react'; export const RowDraggableContext = createContext({}); export const ColDraggableContext = createContext(null); @@ -131,6 +138,18 @@ export function SortableBodyRow(props: any) { } export function SortableHeaderRow(props) { + const { root, remove, insertAfter } = useDesignable(); + const moveToAfter = (path1, path2) => { + if (!path1 || !path2) { + return; + } + const data = findPropertyByPath(root, path1); + if (!data) { + return; + } + remove(path1); + return insertAfter(data.toJSON(), path2); + }; const [dragOverlayContent, setDragOverlayContent] = useState(''); return ( @@ -143,6 +162,12 @@ export function SortableHeaderRow(props) { setDragOverlayContent(previewRef.current.textContent || ''); } }} + onDragEnd={async (event) => { + const path1 = event.active?.data?.current?.path; + const path2 = event.over?.data?.current?.path; + const data = moveToAfter(path1, path2); + await updateSchema(data); + }} > {createPortal( @@ -163,10 +188,25 @@ export function SortableHeaderCell(props) { if (['RC_TABLE_KEY', 'addnew'].includes(id)) { return ; } + const { schema } = useDesignable(); + const columns: Schema[] = schema.reduceProperties((columns, current) => { + if (current['x-component'] === 'Table.Column' && current.name === id) { + return [...columns, current]; + } + return [...columns]; + }, []); + const column = columns.shift(); + if (!column) { + return ; + } return ( ((props, ref) => ( ))} diff --git a/packages/client/src/schemas/tabs/index.tsx b/packages/client/src/schemas/tabs/index.tsx index 10840d295..cb35c1892 100644 --- a/packages/client/src/schemas/tabs/index.tsx +++ b/packages/client/src/schemas/tabs/index.tsx @@ -1,12 +1,12 @@ import { observer, connect, useField, RecursionField } from '@formily/react'; import React from 'react'; import { Button, Tabs as AntdTabs, Dropdown, Menu, Switch } from 'antd'; -import { useDesignable } from '../../components/schema-renderer'; +import { findPropertyByPath, getSchemaPath, useDesignable } from '../../components/schema-renderer'; import { Schema, SchemaKey } from '@formily/react'; import { PlusOutlined, MenuOutlined } from '@ant-design/icons'; import { useState } from 'react'; import cls from 'classnames'; -import { createSchema, removeSchema } from '..'; +import { createSchema, removeSchema, updateSchema } from '..'; import './style.less'; import { uid } from '@formily/shared'; import { DragHandle, SortableItem } from '../../components/Sortable'; @@ -35,10 +35,22 @@ const useTabs = () => { export const Tabs: any = observer((props: any) => { const { singleton, ...others } = props; - const { schema, DesignableBar, appendChild } = useDesignable(); + const { schema, DesignableBar, appendChild, root, remove, insertAfter } = useDesignable(); const tabs = useTabs(); const [dragOverlayContent, setDragOverlayContent] = useState(''); + const moveToAfter = (path1, path2) => { + if (!path1 || !path2) { + return; + } + const data = findPropertyByPath(root, path1); + if (!data) { + return; + } + remove(path1); + return insertAfter(data.toJSON(), path2); + }; + if (singleton) { return (
@@ -57,6 +69,12 @@ export const Tabs: any = observer((props: any) => { onDragStart={(event) => { setDragOverlayContent(event.active.data?.current?.title || ''); }} + onDragEnd={async (event) => { + const path1 = event.active?.data?.current?.path; + const path2 = event.over?.data?.current?.path; + const data = moveToAfter(path1, path2); + await updateSchema(data); + }} > {dragOverlayContent} @@ -123,6 +141,7 @@ Tabs.TabPane = observer((props: any) => { id={schema.name} data={{ title: schema.title, + path: getSchemaPath(schema), }} >