import { DndContext, DragOverlay } from '@dnd-kit/core'; import { observer, RecursionField, Schema } from '@formily/react'; import React, { useState } from 'react'; import { createSchema, ISchema, removeSchema, updateSchema } from '..'; import { findPropertyByPath, getSchemaPath, useDesignable, } from '../../components/schema-renderer'; import { DisplayedMapProvider, useDisplayedMapContext } from '../../constate'; import cls from 'classnames'; import { Button, Dropdown, Menu, Space } from 'antd'; import SwitchMenuItem from '../../components/SwitchMenuItem'; import { uid } from '@formily/shared'; import { PlusOutlined } from '@ant-design/icons'; import { Droppable, SortableItem } from '../../components/Sortable'; export const ActionBar = observer((props: any) => { const { align = 'top' } = props; // 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(''); // } }} 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} {/*
*/}
); }); function generateActionSchema(type) { const actions: { [key: string]: ISchema } = { update: { type: 'void', title: '编辑', 'x-align': 'right', 'x-decorator': 'AddNew.Displayed', 'x-decorator-props': { displayName: 'update', }, 'x-component': 'Action', 'x-component-props': { type: 'primary', }, 'x-action-type': 'update', 'x-designable-bar': 'Action.DesignableBar', properties: { modal: { type: 'void', title: '编辑数据', 'x-decorator': 'Form', 'x-decorator-props': { useResource: '{{ Table.useResource }}', useValues: '{{ Table.useTableRowRecord }}', }, 'x-component': 'Action.Modal', 'x-component-props': { useOkAction: '{{ Table.useTableUpdateAction }}', }, properties: { [uid()]: { type: 'void', 'x-component': 'Grid', 'x-component-props': { addNewComponent: 'AddNew.FormItem', }, }, }, }, }, }, destroy: { type: 'void', title: '删除', 'x-align': 'right', 'x-decorator': 'AddNew.Displayed', 'x-decorator-props': { displayName: 'destroy', }, 'x-action-type': 'destroy', 'x-component': 'Action', 'x-designable-bar': 'Action.DesignableBar', 'x-component-props': { useAction: '{{ Table.useTableDestroyAction }}', }, }, }; return actions[type]; } function AddActionButton() { const [visible, setVisible] = useState(false); const displayed = useDisplayedMapContext(); const { appendChild, remove } = useDesignable(); const { schema, designable } = useDesignable(); if (!designable) { return null; } return ( {[ { title: '编辑', name: 'update' }, { title: '删除', name: 'destroy' }, ].map((item) => ( { if (!checked) { const s = displayed.get(item.name) as Schema; const path = getSchemaPath(s); displayed.remove(item.name); const removed = remove(path); await removeSchema(removed); } else { const s = generateActionSchema(item.name); const data = appendChild(s); await createSchema(data); } }} /> ))} 函数操作 弹窗表单 复杂弹窗 } > ); } 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 ( ); })} ); }