From 80f4635bb6d3c1e262d76ef5f60a26b4fc281800 Mon Sep 17 00:00:00 2001 From: chenos Date: Sat, 21 Aug 2021 18:33:56 +0800 Subject: [PATCH] feat: improve code --- .../client/src/components/Sortable/index.tsx | 5 +- .../src/components/schema-renderer/index.tsx | 32 +++++++- .../client/src/schemas/grid/DesignableBar.tsx | 81 +++++++++++++++++++ packages/client/src/schemas/grid/index.tsx | 77 ++++++++++++------ 4 files changed, 167 insertions(+), 28 deletions(-) create mode 100644 packages/client/src/schemas/grid/DesignableBar.tsx diff --git a/packages/client/src/components/Sortable/index.tsx b/packages/client/src/components/Sortable/index.tsx index d38a1a085c..4499c0e41d 100644 --- a/packages/client/src/components/Sortable/index.tsx +++ b/packages/client/src/components/Sortable/index.tsx @@ -48,7 +48,7 @@ export function DragHandle(props) { ) @@ -104,6 +104,7 @@ export function SortableItem(props: SortableItemProps) { className, component, children, + disabled, ...others } = props; const previewRef = useRef(); @@ -113,6 +114,7 @@ export function SortableItem(props: SortableItemProps) { ...data, previewRef, }, + disabled, }); const { isDragging, @@ -122,6 +124,7 @@ export function SortableItem(props: SortableItemProps) { transform, } = useDraggable({ id: `draggable-${id}`, + disabled, data: { ...data, previewRef, diff --git a/packages/client/src/components/schema-renderer/index.tsx b/packages/client/src/components/schema-renderer/index.tsx index e2df53cfa0..41143940cb 100644 --- a/packages/client/src/components/schema-renderer/index.tsx +++ b/packages/client/src/components/schema-renderer/index.tsx @@ -272,7 +272,7 @@ function setKeys(schema: ISchema | FormilyISchema, parentKey = null) { if (!schema['key']) { schema['key'] = uid(); } - if (parentKey && !schema['parentKey']) { + if (parentKey) { schema['parentKey'] = parentKey; } Object.keys(schema.properties || {}).forEach((name) => { @@ -429,6 +429,36 @@ export function useDesignable(path?: any) { refresh(); return target.parent.properties[property.name]; }, + deepRemoveIfEmpty(targetPath) { + let target = currentSchema; + if (targetPath) { + target = findPropertyByPath(schema, targetPath); + } + if (!target) { + console.error('target schema does not exist.'); + return; + } + const removed = []; + const remove = (s: Schema) => { + if (!s.parent) { + return; + } + s.parent.removeProperty(s.name); + removed.push(s); + if (s['x-component'] === 'Grid.Row') { + return; + } + if (Object.keys(s.parent.properties || {}).length === 0) { + remove(s.parent); + } + }; + console.log({ removed }); + if (Object.keys(target.properties || {}).length === 0) { + remove(target); + } + refresh(); + return removed; + }, deepRemove(targetPath?: any) { let target = currentSchema; if (targetPath) { diff --git a/packages/client/src/schemas/grid/DesignableBar.tsx b/packages/client/src/schemas/grid/DesignableBar.tsx new file mode 100644 index 0000000000..b09b7d7724 --- /dev/null +++ b/packages/client/src/schemas/grid/DesignableBar.tsx @@ -0,0 +1,81 @@ +import React, { useContext, useMemo, useRef, useState } from 'react'; +import { createForm } from '@formily/core'; +import { + SchemaOptionsContext, + Schema, + useFieldSchema, + observer, + SchemaExpressionScopeContext, + FormProvider, + ISchema, + useField, + useForm, + RecursionField, +} from '@formily/react'; +import { useSchemaPath, SchemaField, useDesignable, removeSchema } from '../'; +import get from 'lodash/get'; +import { Button, Dropdown, Menu, Space } from 'antd'; +import { MenuOutlined, DragOutlined } from '@ant-design/icons'; +import cls from 'classnames'; +import { FormLayout } from '@formily/antd'; +import './style.less'; +import AddNew from '../add-new'; +import { DraggableBlockContext } from '../../components/drag-and-drop'; +import { isGridRowOrCol } from '../grid'; +import constate from 'constate'; +import { useEffect } from 'react'; +import { uid } from '@formily/shared'; +import { getSchemaPath } from '../../components/schema-renderer'; +import { useCollection, useCollectionContext } from '../../constate'; +import { useTable } from '../table'; +import { DragHandle } from '../../components/Sortable'; + +export const DesignableBar = observer((props) => { + const field = useField(); + const { designable, schema, refresh, deepRemove } = useDesignable(); + const [visible, setVisible] = useState(false); + const { dragRef } = useContext(DraggableBlockContext); + const { props: tableProps } = useTable(); + const collectionName = field.componentProps?.collectionName || tableProps?.collectionName; + const { collection } = useCollection({ collectionName }); + return ( +
+
{collection?.title || collection?.name}
+ { + e.stopPropagation(); + }} + className={cls('designable-bar-actions', { active: visible })} + > + + + {/* */} + { + setVisible(visible); + }} + overlay={ + + { + const removed = deepRemove(); + // console.log({ removed }) + const last = removed.pop(); + await removeSchema(last); + }} + > + 移除 + + + } + > + + + + +
+ ); +}); diff --git a/packages/client/src/schemas/grid/index.tsx b/packages/client/src/schemas/grid/index.tsx index a010f4b49c..495e26800c 100644 --- a/packages/client/src/schemas/grid/index.tsx +++ b/packages/client/src/schemas/grid/index.tsx @@ -31,17 +31,29 @@ import { removeSchema, updateSchema, } from '..'; -import { createPortal } from 'react-dom'; +import { DesignableBar } from './DesignableBar'; const GridRowContext = createContext(null); const GridColContext = createContext(null); export function isGridRowOrCol(schema: ISchema | FormilyISchema) { - return ['Grid.Row', 'Grid.Col'].includes(schema['x-component']); + if (!schema) { + return; + } + return ['Grid.Row', 'Grid.Col'].includes(schema?.['x-component']); } export const Grid: any = observer((props: any) => { - const { designable, root, schema, deepRemove, ...methods } = useDesignable(); + const { + designable, + root, + schema, + refresh, + deepRemove, + deepRemoveIfEmpty, + remove, + ...methods + } = useDesignable(); const [dragOverlayContent, setDragOverlayContent] = useState(''); const [style, setStyle] = useState({}); const [active, setActive] = useState(false); @@ -157,15 +169,15 @@ export const Grid: any = observer((props: any) => { } let data; if (['col-divider', 'col-resize'].includes(type)) { - if (sourceSchema?.parent?.['x-component'] === 'Grid.Col') { - // console.log('datadata', sourcePath, targetPath); - if ( - sourcePath.join('.').startsWith(targetPath.join('.')) && - Object.keys(sourceSchema?.parent?.properties).length < 2 - ) { - return; - } - } + // if (sourceSchema?.parent?.['x-component'] === 'Grid.Col') { + // // console.log('datadata', sourcePath, targetPath); + // if ( + // sourcePath.join('.').startsWith(targetPath.join('.')) && + // Object.keys(sourceSchema?.parent?.properties).length < 2 + // ) { + // return; + // } + // } data = { type: 'void', 'x-component': 'Grid.Col', @@ -192,17 +204,20 @@ export const Grid: any = observer((props: any) => { } if (data) { console.log('datadata', data, type, method); - const removed = deepRemove(sourcePath); - const last = removed.pop(); + remove(sourcePath); + const ppath = [...sourcePath]; + ppath.pop(); const s = fn(data, targetPath); - if (isGridRowOrCol(last)) { - await removeSchema(last); - } + const removed = deepRemoveIfEmpty(ppath); + const last = removed.pop(); if (['block', 'col'].includes(type)) { await updateSchema(s); } else { await createSchema(s); } + if (isGridRowOrCol(last)) { + await removeSchema(last); + } } }} > @@ -211,18 +226,22 @@ export const Grid: any = observer((props: any) => { duration: 20, easing: 'cubic-bezier(0.18, 0.67, 0.6, 1.22)', }} - style={{ whiteSpace: 'nowrap' }} - // style={{ ...style, pointerEvents: 'none' }} + // dropAnimation={null} + // style={{ whiteSpace: 'nowrap' }} + style={{ + width: 40, + whiteSpace: 'nowrap', + // ...style, + // pointerEvents: 'none', + }} > - {dragOverlayContent} - {/*
*/} + /> { }); Grid.Row = observer((props: any) => { - const { schema } = useDesignable(); + const { designable, schema } = useDesignable(); const columns = Object.values(schema.properties || {}).filter((item) => { return !item['x-hidden']; }); @@ -310,7 +329,10 @@ Grid.Row = observer((props: any) => { parentPath: [...path], path: [...path, property.name], }} - className={cls('nb-grid-col-divider', 'resizable')} + disabled={!designable} + className={cls('nb-grid-col-divider', { + resizable: designable, + })} /> )} @@ -334,7 +356,7 @@ Grid.Row = observer((props: any) => { }); Grid.Col = observer((props: any) => { - const { schema } = useDesignable(); + const { schema, designable, DesignableBar } = useDesignable(); // const { width } = props; const { columnCount } = useContext(GridRowContext); const { width } = useContext(GridColContext); @@ -358,6 +380,9 @@ Grid.Col = observer((props: any) => { className={'nb-grid-row-divider'} /> */} {props.children} + {/* */} ); }); + +Grid.Col.DesignableBar = DesignableBar;