mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-09 23:49:27 +08:00
feat: improve code
This commit is contained in:
parent
1012cb6401
commit
80f4635bb6
@ -48,7 +48,7 @@ export function DragHandle(props) {
|
|||||||
<Icon
|
<Icon
|
||||||
ref={setDraggableNodeRef}
|
ref={setDraggableNodeRef}
|
||||||
{...others}
|
{...others}
|
||||||
{...attributes}
|
// {...attributes}
|
||||||
{...listeners}
|
{...listeners}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
@ -104,6 +104,7 @@ export function SortableItem(props: SortableItemProps) {
|
|||||||
className,
|
className,
|
||||||
component,
|
component,
|
||||||
children,
|
children,
|
||||||
|
disabled,
|
||||||
...others
|
...others
|
||||||
} = props;
|
} = props;
|
||||||
const previewRef = useRef<HTMLElement>();
|
const previewRef = useRef<HTMLElement>();
|
||||||
@ -113,6 +114,7 @@ export function SortableItem(props: SortableItemProps) {
|
|||||||
...data,
|
...data,
|
||||||
previewRef,
|
previewRef,
|
||||||
},
|
},
|
||||||
|
disabled,
|
||||||
});
|
});
|
||||||
const {
|
const {
|
||||||
isDragging,
|
isDragging,
|
||||||
@ -122,6 +124,7 @@ export function SortableItem(props: SortableItemProps) {
|
|||||||
transform,
|
transform,
|
||||||
} = useDraggable({
|
} = useDraggable({
|
||||||
id: `draggable-${id}`,
|
id: `draggable-${id}`,
|
||||||
|
disabled,
|
||||||
data: {
|
data: {
|
||||||
...data,
|
...data,
|
||||||
previewRef,
|
previewRef,
|
||||||
|
@ -272,7 +272,7 @@ function setKeys(schema: ISchema | FormilyISchema, parentKey = null) {
|
|||||||
if (!schema['key']) {
|
if (!schema['key']) {
|
||||||
schema['key'] = uid();
|
schema['key'] = uid();
|
||||||
}
|
}
|
||||||
if (parentKey && !schema['parentKey']) {
|
if (parentKey) {
|
||||||
schema['parentKey'] = parentKey;
|
schema['parentKey'] = parentKey;
|
||||||
}
|
}
|
||||||
Object.keys(schema.properties || {}).forEach((name) => {
|
Object.keys(schema.properties || {}).forEach((name) => {
|
||||||
@ -429,6 +429,36 @@ export function useDesignable(path?: any) {
|
|||||||
refresh();
|
refresh();
|
||||||
return target.parent.properties[property.name];
|
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) {
|
deepRemove(targetPath?: any) {
|
||||||
let target = currentSchema;
|
let target = currentSchema;
|
||||||
if (targetPath) {
|
if (targetPath) {
|
||||||
|
81
packages/client/src/schemas/grid/DesignableBar.tsx
Normal file
81
packages/client/src/schemas/grid/DesignableBar.tsx
Normal file
@ -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 (
|
||||||
|
<div className={cls('designable-bar', { active: visible })}>
|
||||||
|
<div className={'designable-info'}>{collection?.title || collection?.name}</div>
|
||||||
|
<span
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
}}
|
||||||
|
className={cls('designable-bar-actions', { active: visible })}
|
||||||
|
>
|
||||||
|
<Space size={2}>
|
||||||
|
<AddNew.CardItem defaultAction={'appendChild'} ghost />
|
||||||
|
{/* <DragHandle /> */}
|
||||||
|
<Dropdown
|
||||||
|
trigger={['click']}
|
||||||
|
visible={visible}
|
||||||
|
onVisibleChange={(visible) => {
|
||||||
|
setVisible(visible);
|
||||||
|
}}
|
||||||
|
overlay={
|
||||||
|
<Menu>
|
||||||
|
<Menu.Item
|
||||||
|
key={'delete'}
|
||||||
|
onClick={async () => {
|
||||||
|
const removed = deepRemove();
|
||||||
|
// console.log({ removed })
|
||||||
|
const last = removed.pop();
|
||||||
|
await removeSchema(last);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
移除
|
||||||
|
</Menu.Item>
|
||||||
|
</Menu>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<MenuOutlined />
|
||||||
|
</Dropdown>
|
||||||
|
</Space>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
@ -31,17 +31,29 @@ import {
|
|||||||
removeSchema,
|
removeSchema,
|
||||||
updateSchema,
|
updateSchema,
|
||||||
} from '..';
|
} from '..';
|
||||||
import { createPortal } from 'react-dom';
|
import { DesignableBar } from './DesignableBar';
|
||||||
|
|
||||||
const GridRowContext = createContext<any>(null);
|
const GridRowContext = createContext<any>(null);
|
||||||
const GridColContext = createContext<any>(null);
|
const GridColContext = createContext<any>(null);
|
||||||
|
|
||||||
export function isGridRowOrCol(schema: ISchema | FormilyISchema) {
|
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) => {
|
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 [dragOverlayContent, setDragOverlayContent] = useState('');
|
||||||
const [style, setStyle] = useState({});
|
const [style, setStyle] = useState({});
|
||||||
const [active, setActive] = useState(false);
|
const [active, setActive] = useState(false);
|
||||||
@ -157,15 +169,15 @@ export const Grid: any = observer((props: any) => {
|
|||||||
}
|
}
|
||||||
let data;
|
let data;
|
||||||
if (['col-divider', 'col-resize'].includes(type)) {
|
if (['col-divider', 'col-resize'].includes(type)) {
|
||||||
if (sourceSchema?.parent?.['x-component'] === 'Grid.Col') {
|
// if (sourceSchema?.parent?.['x-component'] === 'Grid.Col') {
|
||||||
// console.log('datadata', sourcePath, targetPath);
|
// // console.log('datadata', sourcePath, targetPath);
|
||||||
if (
|
// if (
|
||||||
sourcePath.join('.').startsWith(targetPath.join('.')) &&
|
// sourcePath.join('.').startsWith(targetPath.join('.')) &&
|
||||||
Object.keys(sourceSchema?.parent?.properties).length < 2
|
// Object.keys(sourceSchema?.parent?.properties).length < 2
|
||||||
) {
|
// ) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
data = {
|
data = {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
'x-component': 'Grid.Col',
|
'x-component': 'Grid.Col',
|
||||||
@ -192,17 +204,20 @@ export const Grid: any = observer((props: any) => {
|
|||||||
}
|
}
|
||||||
if (data) {
|
if (data) {
|
||||||
console.log('datadata', data, type, method);
|
console.log('datadata', data, type, method);
|
||||||
const removed = deepRemove(sourcePath);
|
remove(sourcePath);
|
||||||
const last = removed.pop();
|
const ppath = [...sourcePath];
|
||||||
|
ppath.pop();
|
||||||
const s = fn(data, targetPath);
|
const s = fn(data, targetPath);
|
||||||
if (isGridRowOrCol(last)) {
|
const removed = deepRemoveIfEmpty(ppath);
|
||||||
await removeSchema(last);
|
const last = removed.pop();
|
||||||
}
|
|
||||||
if (['block', 'col'].includes(type)) {
|
if (['block', 'col'].includes(type)) {
|
||||||
await updateSchema(s);
|
await updateSchema(s);
|
||||||
} else {
|
} else {
|
||||||
await createSchema(s);
|
await createSchema(s);
|
||||||
}
|
}
|
||||||
|
if (isGridRowOrCol(last)) {
|
||||||
|
await removeSchema(last);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -211,18 +226,22 @@ export const Grid: any = observer((props: any) => {
|
|||||||
duration: 20,
|
duration: 20,
|
||||||
easing: 'cubic-bezier(0.18, 0.67, 0.6, 1.22)',
|
easing: 'cubic-bezier(0.18, 0.67, 0.6, 1.22)',
|
||||||
}}
|
}}
|
||||||
style={{ whiteSpace: 'nowrap' }}
|
// dropAnimation={null}
|
||||||
// style={{ ...style, pointerEvents: 'none' }}
|
// style={{ whiteSpace: 'nowrap' }}
|
||||||
|
style={{
|
||||||
|
width: 40,
|
||||||
|
whiteSpace: 'nowrap',
|
||||||
|
// ...style,
|
||||||
|
// pointerEvents: 'none',
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{dragOverlayContent}
|
<div
|
||||||
{/* <div
|
|
||||||
className={'nb-grid-drag-overlay'}
|
className={'nb-grid-drag-overlay'}
|
||||||
style={{
|
style={{
|
||||||
...style,
|
...style,
|
||||||
transform: 'translate(calc(-100% + 30px), 2px)',
|
|
||||||
}}
|
}}
|
||||||
dangerouslySetInnerHTML={{ __html: dragOverlayContent }}
|
dangerouslySetInnerHTML={{ __html: dragOverlayContent }}
|
||||||
/> */}
|
/>
|
||||||
</DragOverlay>
|
</DragOverlay>
|
||||||
<Droppable
|
<Droppable
|
||||||
id={`${schema.name}-row-divider`}
|
id={`${schema.name}-row-divider`}
|
||||||
@ -267,7 +286,7 @@ export const Grid: any = observer((props: any) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Grid.Row = observer((props: any) => {
|
Grid.Row = observer((props: any) => {
|
||||||
const { schema } = useDesignable();
|
const { designable, schema } = useDesignable();
|
||||||
const columns = Object.values(schema.properties || {}).filter((item) => {
|
const columns = Object.values(schema.properties || {}).filter((item) => {
|
||||||
return !item['x-hidden'];
|
return !item['x-hidden'];
|
||||||
});
|
});
|
||||||
@ -310,7 +329,10 @@ Grid.Row = observer((props: any) => {
|
|||||||
parentPath: [...path],
|
parentPath: [...path],
|
||||||
path: [...path, property.name],
|
path: [...path, property.name],
|
||||||
}}
|
}}
|
||||||
className={cls('nb-grid-col-divider', 'resizable')}
|
disabled={!designable}
|
||||||
|
className={cls('nb-grid-col-divider', {
|
||||||
|
resizable: designable,
|
||||||
|
})}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<GridColContext.Provider value={{ index, width: size[index] }}>
|
<GridColContext.Provider value={{ index, width: size[index] }}>
|
||||||
@ -334,7 +356,7 @@ Grid.Row = observer((props: any) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Grid.Col = observer((props: any) => {
|
Grid.Col = observer((props: any) => {
|
||||||
const { schema } = useDesignable();
|
const { schema, designable, DesignableBar } = useDesignable();
|
||||||
// const { width } = props;
|
// const { width } = props;
|
||||||
const { columnCount } = useContext(GridRowContext);
|
const { columnCount } = useContext(GridRowContext);
|
||||||
const { width } = useContext(GridColContext);
|
const { width } = useContext(GridColContext);
|
||||||
@ -358,6 +380,9 @@ Grid.Col = observer((props: any) => {
|
|||||||
className={'nb-grid-row-divider'}
|
className={'nb-grid-row-divider'}
|
||||||
/> */}
|
/> */}
|
||||||
{props.children}
|
{props.children}
|
||||||
|
{/* <Grid.Col.DesignableBar /> */}
|
||||||
</Droppable>
|
</Droppable>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Grid.Col.DesignableBar = DesignableBar;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user