improve moveTo function

This commit is contained in:
chenos 2021-08-02 17:31:41 +08:00
parent 0ca3fef9d3
commit f997b4bebb
6 changed files with 136 additions and 24 deletions

View File

@ -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 (
<Component
{...others}
className={cls(className, `droppable-${id}`, {
isOver,
})}
ref={(el: HTMLElement) => {
setDroppableNodeRef(el);
}}
>
{children}
</Component>
);
}
export function SortableItem(props) { export function SortableItem(props) {
const { id, data = {}, className, component, children, ...others } = props; const { id, data = {}, className, component, children, ...others } = props;
const previewRef = useRef<HTMLElement>(); const previewRef = useRef<HTMLElement>();

View File

@ -61,6 +61,9 @@ export async function createSchema(schema: ISchema) {
} }
export async function updateSchema(schema: ISchema) { export async function updateSchema(schema: ISchema) {
if (!schema) {
return;
}
if (!schema['key']) { if (!schema['key']) {
return; return;
} }

View File

@ -112,6 +112,9 @@ export const Menu: any = observer((props: any) => {
if (!path1 || !path2) { if (!path1 || !path2) {
return; return;
} }
if (path1.join('.') === path2.join('.')) {
return;
}
const data = findPropertyByPath(root, path1); const data = findPropertyByPath(root, path1);
if (!data) { if (!data) {
return; return;

View File

@ -143,6 +143,9 @@ export function SortableHeaderRow(props) {
if (!path1 || !path2) { if (!path1 || !path2) {
return; return;
} }
if (path1.join('.') === path2.join('.')) {
return;
}
const data = findPropertyByPath(root, path1); const data = findPropertyByPath(root, path1);
if (!data) { if (!data) {
return; return;

View File

@ -29,6 +29,7 @@ import { Select, Dropdown, Menu, Switch, Button, Space } from 'antd';
import { PlusOutlined } from '@ant-design/icons'; import { PlusOutlined } from '@ant-design/icons';
import './style.less'; import './style.less';
import { import {
findPropertyByPath,
getSchemaPath, getSchemaPath,
SchemaField, SchemaField,
SchemaRenderer, SchemaRenderer,
@ -57,7 +58,7 @@ import {
SortableHeaderRow, SortableHeaderRow,
SortableRowHandle, SortableRowHandle,
} from './Sortable'; } from './Sortable';
import { DragHandle, SortableItem } from '../../components/Sortable'; import { DragHandle, Droppable, SortableItem } from '../../components/Sortable';
const SyntheticListenerMapContext = createContext(null); const SyntheticListenerMapContext = createContext(null);
@ -784,36 +785,107 @@ function Actions(props: any) {
const { align = 'left' } = props; const { align = 'left' } = props;
const { schema, designable } = useDesignable(); const { schema, designable } = useDesignable();
return ( return (
<Space> <Droppable
{schema.mapProperties((s) => { id={`${schema.name}-${align}`}
const currentAlign = s['x-align'] || 'left'; className={`action-bar-align-${align}`}
if (currentAlign !== align) { data={{ align, path: getSchemaPath(schema) }}
return null; >
} <Space>
return ( {schema.mapProperties((s) => {
<SortableItem id={s.name} data={{ title: s.title }}> const currentAlign = s['x-align'] || 'left';
<RecursionField name={s.name} schema={s} /> if (currentAlign !== align) {
</SortableItem> return null;
); }
})} return (
</Space> <SortableItem
id={s.name}
data={{
align,
draggable: true,
title: s.title,
path: getSchemaPath(s),
}}
>
<RecursionField name={s.name} schema={s} />
</SortableItem>
);
})}
</Space>
</Droppable>
); );
} }
Table.ActionBar = observer((props: any) => { Table.ActionBar = observer((props: any) => {
const { align = 'top' } = props; 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(''); const [dragOverlayContent, setDragOverlayContent] = useState('');
return ( return (
<DndContext onDragStart={(event) => { <DndContext
setDragOverlayContent(event.active.data?.current?.title || ''); onDragStart={(event) => {
// const previewRef = event.active.data?.current?.previewRef; setDragOverlayContent(event.active.data?.current?.title || '');
// if (previewRef) { // const previewRef = event.active.data?.current?.previewRef;
// setDragOverlayContent(previewRef?.current?.innerHTML); // if (previewRef) {
// } else { // setDragOverlayContent(previewRef?.current?.innerHTML);
// setDragOverlayContent(''); // } 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);
}
}}
>
<DragOverlay style={{ pointerEvents: 'none', whiteSpace: 'nowrap' }}> <DragOverlay style={{ pointerEvents: 'none', whiteSpace: 'nowrap' }}>
{dragOverlayContent} {dragOverlayContent}
{/* <div style={{ transform: 'translateX(-100%)' }} dangerouslySetInnerHTML={{__html: dragOverlayContent}}></div> */} {/* <div style={{ transform: 'translateX(-100%)' }} dangerouslySetInnerHTML={{__html: dragOverlayContent}}></div> */}
@ -910,6 +982,7 @@ Table.Filter.DesignableBar = () => {
}} }}
className={cls('designable-bar-actions', { active: visible })} className={cls('designable-bar-actions', { active: visible })}
> >
<DragHandle />
<Dropdown <Dropdown
trigger={['click']} trigger={['click']}
visible={visible} visible={visible}

View File

@ -218,4 +218,10 @@ td.nb-table-operation {
} }
} }
} }
}
.action-bar-align-right.isOver,
.action-bar-align-left.isOver {
min-height: 32px;
background-color: #e6f7ff;
} }