feat: resize grid columns with drag and drop (#748)
* feat: resize grid columns with drag and drop * fix: column resizing only in designable * fix: batch patch * fix: does not scroll when dragging to a blank block * fix: overflow-x auto
This commit is contained in:
parent
56bd996bd4
commit
259393f626
@ -1,3 +1,4 @@
|
|||||||
|
import { css } from '@emotion/css';
|
||||||
import { observer, RecursionField, useFieldSchema } from '@formily/react';
|
import { observer, RecursionField, useFieldSchema } from '@formily/react';
|
||||||
import { Space } from 'antd';
|
import { Space } from 'antd';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
@ -25,8 +26,15 @@ export const ActionBar = observer((props: any) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', ...style }} {...others}>
|
<div
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', width: '100%' }}>
|
style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', overflowX: 'auto', ...style }}
|
||||||
|
{...others}
|
||||||
|
>
|
||||||
|
<div className={css`
|
||||||
|
.ant-space:last-child {
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
`} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', width: '100%' }}>
|
||||||
<DndContext>
|
<DndContext>
|
||||||
<Space>
|
<Space>
|
||||||
{fieldSchema.mapProperties((schema, key) => {
|
{fieldSchema.mapProperties((schema, key) => {
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
import { useDndContext, useDndMonitor, useDroppable } from '@dnd-kit/core';
|
import { useDndContext, useDndMonitor, useDraggable, useDroppable } from '@dnd-kit/core';
|
||||||
import { css } from '@emotion/css';
|
import { css } from '@emotion/css';
|
||||||
import { observer, RecursionField, Schema, useField, useFieldSchema } from '@formily/react';
|
import { observer, RecursionField, Schema, useField, useFieldSchema } from '@formily/react';
|
||||||
import { uid } from '@formily/shared';
|
import { uid } from '@formily/shared';
|
||||||
import cls from 'classnames';
|
import cls from 'classnames';
|
||||||
import React, { createContext, useContext, useEffect, useRef, useState } from 'react';
|
import React, { createContext, useContext, useEffect, useRef, useState } from 'react';
|
||||||
import { useFormBlockContext, useSchemaInitializer } from '../../../';
|
import { useDesignable, useFormBlockContext, useSchemaInitializer } from '../../../';
|
||||||
import { DndContext } from '../../common/dnd-context';
|
import { DndContext } from '../../common/dnd-context';
|
||||||
|
|
||||||
const GridRowContext = createContext(null);
|
const GridRowContext = createContext<any>({});
|
||||||
const GridColContext = createContext(null);
|
const GridColContext = createContext<any>({});
|
||||||
const GridContext = createContext<any>({});
|
const GridContext = createContext<any>({});
|
||||||
|
|
||||||
const breakRemoveOnGrid = (s: Schema) => s['x-component'] === 'Grid';
|
const breakRemoveOnGrid = (s: Schema) => s['x-component'] === 'Grid';
|
||||||
@ -19,6 +19,8 @@ const ColDivider = (props) => {
|
|||||||
id: props.id,
|
id: props.id,
|
||||||
data: props.data,
|
data: props.data,
|
||||||
});
|
});
|
||||||
|
const { dn, designable } = useDesignable();
|
||||||
|
const dividerRef = useRef<HTMLElement>();
|
||||||
|
|
||||||
const droppableStyle = {
|
const droppableStyle = {
|
||||||
backgroundColor: isOver ? 'rgba(241, 139, 98, .1)' : undefined,
|
backgroundColor: isOver ? 'rgba(241, 139, 98, .1)' : undefined,
|
||||||
@ -38,10 +40,89 @@ const ColDivider = (props) => {
|
|||||||
visible = activeSchema !== currentSchema && downSchema !== activeSchema;
|
visible = activeSchema !== currentSchema && downSchema !== activeSchema;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const prevSchema = props.cols[props.index];
|
||||||
|
const nextSchema = props.cols[props.index + 1];
|
||||||
|
const {
|
||||||
|
attributes,
|
||||||
|
listeners,
|
||||||
|
setNodeRef: setDraggableNodeRef,
|
||||||
|
isDragging,
|
||||||
|
} = useDraggable({
|
||||||
|
disabled: props.first || props.last || !designable,
|
||||||
|
id: props.id,
|
||||||
|
data: {
|
||||||
|
dividerRef,
|
||||||
|
prevSchema,
|
||||||
|
nextSchema,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const [clientWidths, setClientWidths] = useState([0, 0]);
|
||||||
|
|
||||||
|
useDndMonitor({
|
||||||
|
onDragStart(event) {
|
||||||
|
if (!isDragging) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const el = dividerRef.current;
|
||||||
|
const prev = el.previousElementSibling as HTMLDivElement;
|
||||||
|
const next = el.nextElementSibling as HTMLDivElement;
|
||||||
|
setClientWidths([prev.clientWidth, next.clientWidth]);
|
||||||
|
},
|
||||||
|
onDragMove(event) {
|
||||||
|
if (!isDragging) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const el = dividerRef.current;
|
||||||
|
const prev = el.previousElementSibling as HTMLDivElement;
|
||||||
|
const next = el.nextElementSibling as HTMLDivElement;
|
||||||
|
prev.style.width = `calc(${clientWidths[0]}px + ${event.delta.x}px)`;
|
||||||
|
next.style.width = `calc(${clientWidths[1]}px - ${event.delta.x}px)`;
|
||||||
|
},
|
||||||
|
onDragEnd(event) {
|
||||||
|
if (clientWidths[0] <= 0 || clientWidths[1] <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setClientWidths([0, 0]);
|
||||||
|
if (!prevSchema || !nextSchema) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const el = dividerRef.current;
|
||||||
|
const prev = el.previousElementSibling as HTMLDivElement;
|
||||||
|
const next = el.nextElementSibling as HTMLDivElement;
|
||||||
|
prevSchema['x-component-props'] = prevSchema['x-component-props'] || {};
|
||||||
|
nextSchema['x-component-props'] = nextSchema['x-component-props'] || {};
|
||||||
|
prevSchema['x-component-props']['width'] =
|
||||||
|
(100 * (prev?.clientWidth + 24 + 24 / props.cols.length)) / el.parentElement.clientWidth;
|
||||||
|
nextSchema['x-component-props']['width'] =
|
||||||
|
(100 * (next?.clientWidth + 24 + 24 / props.cols.length)) / el.parentElement.clientWidth;
|
||||||
|
dn.emit('batchPatch', {
|
||||||
|
schemas: [
|
||||||
|
{
|
||||||
|
['x-uid']: prevSchema['x-uid'],
|
||||||
|
'x-component-props': {
|
||||||
|
...prevSchema['x-component-props'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
['x-uid']: nextSchema['x-uid'],
|
||||||
|
'x-component-props': {
|
||||||
|
...nextSchema['x-component-props'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={visible ? setNodeRef : null}
|
ref={(el) => {
|
||||||
|
if (visible) {
|
||||||
|
setNodeRef(el);
|
||||||
|
dividerRef.current = el;
|
||||||
|
}
|
||||||
|
}}
|
||||||
className={cls(
|
className={cls(
|
||||||
'nb-col-divider',
|
'nb-col-divider',
|
||||||
css`
|
css`
|
||||||
@ -49,7 +130,36 @@ const ColDivider = (props) => {
|
|||||||
`,
|
`,
|
||||||
)}
|
)}
|
||||||
style={{ ...droppableStyle }}
|
style={{ ...droppableStyle }}
|
||||||
></div>
|
>
|
||||||
|
<div
|
||||||
|
ref={setDraggableNodeRef}
|
||||||
|
{...listeners}
|
||||||
|
{...attributes}
|
||||||
|
className={
|
||||||
|
props.first || props.last || !designable
|
||||||
|
? null
|
||||||
|
: css`
|
||||||
|
&::before {
|
||||||
|
content: ' ';
|
||||||
|
width: 12px;
|
||||||
|
height: 100%;
|
||||||
|
left: 6px;
|
||||||
|
position: absolute;
|
||||||
|
cursor: col-resize;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
&::before {
|
||||||
|
background: rgba(241, 139, 98, 0.06) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
width: 24px;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
cursor: col-resize;
|
||||||
|
`
|
||||||
|
}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -255,7 +365,7 @@ Grid.Row = observer((props) => {
|
|||||||
const cols = useColProperties();
|
const cols = useColProperties();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GridRowContext.Provider value={{ cols }}>
|
<GridRowContext.Provider value={{ schema: fieldSchema, cols }}>
|
||||||
<div
|
<div
|
||||||
className={cls(
|
className={cls(
|
||||||
'nb-grid-row',
|
'nb-grid-row',
|
||||||
@ -285,6 +395,7 @@ Grid.Row = observer((props) => {
|
|||||||
<ColDivider
|
<ColDivider
|
||||||
cols={cols}
|
cols={cols}
|
||||||
index={index}
|
index={index}
|
||||||
|
last={index === cols.length - 1}
|
||||||
id={`${addr}_${index + 1}`}
|
id={`${addr}_${index + 1}`}
|
||||||
data={{
|
data={{
|
||||||
breakRemoveOn: breakRemoveOnRow,
|
breakRemoveOn: breakRemoveOnRow,
|
||||||
@ -303,20 +414,33 @@ Grid.Row = observer((props) => {
|
|||||||
|
|
||||||
Grid.Col = observer((props: any) => {
|
Grid.Col = observer((props: any) => {
|
||||||
const { cols } = useContext(GridRowContext);
|
const { cols } = useContext(GridRowContext);
|
||||||
const w = props.width || 100 / cols.length;
|
const schema = useFieldSchema();
|
||||||
|
const field = useField();
|
||||||
|
const w = schema?.['x-component-props']?.['width'] || 100 / cols.length;
|
||||||
const width = `calc(${w}% - 24px - 24px / ${cols.length})`;
|
const width = `calc(${w}% - 24px - 24px / ${cols.length})`;
|
||||||
|
const { isOver, setNodeRef } = useDroppable({
|
||||||
|
id: field.address.toString(),
|
||||||
|
data: {
|
||||||
|
insertAdjacent: 'beforeEnd',
|
||||||
|
schema,
|
||||||
|
wrapSchema: (s) => s,
|
||||||
|
},
|
||||||
|
});
|
||||||
return (
|
return (
|
||||||
<div
|
<GridColContext.Provider value={{ cols, schema }}>
|
||||||
style={{ width }}
|
<div
|
||||||
className={cls(
|
ref={setNodeRef}
|
||||||
'nb-grid-col',
|
style={{ width }}
|
||||||
css`
|
className={cls(
|
||||||
position: relative;
|
'nb-grid-col',
|
||||||
/* z-index: 0; */
|
css`
|
||||||
`,
|
position: relative;
|
||||||
)}
|
/* z-index: 0; */
|
||||||
>
|
`,
|
||||||
{props.children}
|
)}
|
||||||
</div>
|
>
|
||||||
|
{props.children}
|
||||||
|
</div>
|
||||||
|
</GridColContext.Provider>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { DndContext as DndKitContext, DragEndEvent, DragOverlay, rectIntersection } from '@dnd-kit/core';
|
import { DndContext as DndKitContext, DragEndEvent, DragOverlay, rectIntersection } from '@dnd-kit/core';
|
||||||
import { Props } from '@dnd-kit/core/dist/components/DndContext/DndContext';
|
import { Props } from '@dnd-kit/core/dist/components/DndContext/DndContext';
|
||||||
import { observer } from '@formily/react';
|
import { observer } from '@formily/react';
|
||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useAPIClient } from '../../../';
|
import { useAPIClient } from '../../../';
|
||||||
import { createDesignable, useDesignable } from '../../hooks';
|
import { createDesignable, useDesignable } from '../../hooks';
|
||||||
@ -18,6 +18,7 @@ const useDragEnd = (props?: any) => {
|
|||||||
const insertAdjacent = over?.data?.current?.insertAdjacent;
|
const insertAdjacent = over?.data?.current?.insertAdjacent;
|
||||||
const breakRemoveOn = over?.data?.current?.breakRemoveOn;
|
const breakRemoveOn = over?.data?.current?.breakRemoveOn;
|
||||||
const wrapSchema = over?.data?.current?.wrapSchema;
|
const wrapSchema = over?.data?.current?.wrapSchema;
|
||||||
|
const onSuccess = over?.data?.current?.onSuccess;
|
||||||
|
|
||||||
if (!activeSchema || !overSchema) {
|
if (!activeSchema || !overSchema) {
|
||||||
props?.onDragEnd?.(event);
|
props?.onDragEnd?.(event);
|
||||||
@ -49,6 +50,7 @@ const useDragEnd = (props?: any) => {
|
|||||||
wrap: wrapSchema,
|
wrap: wrapSchema,
|
||||||
breakRemoveOn,
|
breakRemoveOn,
|
||||||
removeParentsIfNoChildren: true,
|
removeParentsIfNoChildren: true,
|
||||||
|
onSuccess,
|
||||||
});
|
});
|
||||||
props?.onDragEnd?.(event);
|
props?.onDragEnd?.(event);
|
||||||
return;
|
return;
|
||||||
@ -58,15 +60,25 @@ const useDragEnd = (props?: any) => {
|
|||||||
|
|
||||||
export const DndContext = observer((props: Props) => {
|
export const DndContext = observer((props: Props) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const [visible, setVisible] = useState(true);
|
||||||
return (
|
return (
|
||||||
<DndKitContext collisionDetection={rectIntersection} {...props} onDragEnd={useDragEnd(props)}>
|
<DndKitContext
|
||||||
|
collisionDetection={rectIntersection}
|
||||||
|
{...props}
|
||||||
|
onDragStart={(event) => {
|
||||||
|
const { active } = event;
|
||||||
|
const activeSchema = active?.data?.current?.schema;
|
||||||
|
setVisible(!!activeSchema);
|
||||||
|
}}
|
||||||
|
onDragEnd={useDragEnd(props)}
|
||||||
|
>
|
||||||
<DragOverlay
|
<DragOverlay
|
||||||
dropAnimation={{
|
dropAnimation={{
|
||||||
duration: 10,
|
duration: 10,
|
||||||
easing: 'cubic-bezier(0.18, 0.67, 0.6, 1.22)',
|
easing: 'cubic-bezier(0.18, 0.67, 0.6, 1.22)',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span style={{ whiteSpace: 'nowrap' }}>{t('Dragging')}</span>
|
{visible && <span style={{ whiteSpace: 'nowrap' }}>{t('Dragging')}</span>}
|
||||||
</DragOverlay>
|
</DragOverlay>
|
||||||
{props.children}
|
{props.children}
|
||||||
</DndKitContext>
|
</DndKitContext>
|
||||||
|
@ -111,7 +111,35 @@ export class Designable {
|
|||||||
if (!api) {
|
if (!api) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.on('insertAdjacent', async ({ onSuccess, current, position, schema, wrap, removed }) => {
|
const updateColumnSize = (parent: Schema) => {
|
||||||
|
if (!parent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const len = Object.values(parent.properties).length;
|
||||||
|
const schemas = [];
|
||||||
|
parent.mapProperties((s) => {
|
||||||
|
s['x-component-props'] = s['x-component-props'] || {};
|
||||||
|
s['x-component-props']['width'] = 100 / len;
|
||||||
|
if (s['x-uid']) {
|
||||||
|
schemas.push({
|
||||||
|
'x-uid': s['x-uid'],
|
||||||
|
'x-component-props': s['x-component-props'],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (parent['x-uid'] && schemas.length) {
|
||||||
|
return schemas;
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
};
|
||||||
|
this.on('insertAdjacent', async ({ onSuccess, current, position, schema, wrap, wrapped, removed }) => {
|
||||||
|
let schemas = [];
|
||||||
|
if (wrapped?.['x-component'] === 'Grid.Col') {
|
||||||
|
schemas = updateColumnSize(wrapped.parent);
|
||||||
|
}
|
||||||
|
if (removed?.['x-component'] === 'Grid.Col') {
|
||||||
|
schemas = updateColumnSize(removed.parent);
|
||||||
|
}
|
||||||
refresh();
|
refresh();
|
||||||
if (!current['x-uid']) {
|
if (!current['x-uid']) {
|
||||||
return;
|
return;
|
||||||
@ -124,6 +152,13 @@ export class Designable {
|
|||||||
wrap,
|
wrap,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
if (schemas.length) {
|
||||||
|
await api.request({
|
||||||
|
url: `/uiSchemas:batchPatch`,
|
||||||
|
method: 'post',
|
||||||
|
data: schemas,
|
||||||
|
});
|
||||||
|
}
|
||||||
if (removed?.['x-uid']) {
|
if (removed?.['x-uid']) {
|
||||||
await api.request({
|
await api.request({
|
||||||
url: `/uiSchemas:remove/${removed['x-uid']}`,
|
url: `/uiSchemas:remove/${removed['x-uid']}`,
|
||||||
@ -147,7 +182,20 @@ export class Designable {
|
|||||||
});
|
});
|
||||||
message.success(t('Saved successfully'), 0.2);
|
message.success(t('Saved successfully'), 0.2);
|
||||||
});
|
});
|
||||||
|
this.on('batchPatch', async ({ schemas }) => {
|
||||||
|
refresh();
|
||||||
|
await api.request({
|
||||||
|
url: `/uiSchemas:batchPatch`,
|
||||||
|
method: 'post',
|
||||||
|
data: schemas,
|
||||||
|
});
|
||||||
|
message.success(t('Saved successfully'), 0.2);
|
||||||
|
});
|
||||||
this.on('remove', async ({ removed }) => {
|
this.on('remove', async ({ removed }) => {
|
||||||
|
let schemas = [];
|
||||||
|
if (removed?.['x-component'] === 'Grid.Col') {
|
||||||
|
schemas = updateColumnSize(removed.parent);
|
||||||
|
}
|
||||||
refresh();
|
refresh();
|
||||||
if (!removed?.['x-uid']) {
|
if (!removed?.['x-uid']) {
|
||||||
return;
|
return;
|
||||||
@ -156,6 +204,13 @@ export class Designable {
|
|||||||
url: `/uiSchemas:remove/${removed['x-uid']}`,
|
url: `/uiSchemas:remove/${removed['x-uid']}`,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
});
|
});
|
||||||
|
if (schemas.length) {
|
||||||
|
await api.request({
|
||||||
|
url: `/uiSchemas:batchPatch`,
|
||||||
|
method: 'post',
|
||||||
|
data: schemas,
|
||||||
|
});
|
||||||
|
}
|
||||||
message.success(t('Saved successfully'), 0.2);
|
message.success(t('Saved successfully'), 0.2);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -177,14 +232,14 @@ export class Designable {
|
|||||||
generateUid(schema);
|
generateUid(schema);
|
||||||
}
|
}
|
||||||
|
|
||||||
on(name: 'insertAdjacent' | 'remove' | 'error' | 'patch', listener: any) {
|
on(name: 'insertAdjacent' | 'remove' | 'error' | 'patch' | 'batchPatch', listener: any) {
|
||||||
if (!this.events[name]) {
|
if (!this.events[name]) {
|
||||||
this.events[name] = [];
|
this.events[name] = [];
|
||||||
}
|
}
|
||||||
this.events[name].push(listener);
|
this.events[name].push(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
emit(name: 'insertAdjacent' | 'remove' | 'error' | 'patch', ...args) {
|
emit(name: 'insertAdjacent' | 'remove' | 'error' | 'patch' | 'batchPatch', ...args) {
|
||||||
if (!this.events[name]) {
|
if (!this.events[name]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -356,6 +411,7 @@ export class Designable {
|
|||||||
this.emit('insertAdjacent', {
|
this.emit('insertAdjacent', {
|
||||||
position: 'beforeBegin',
|
position: 'beforeBegin',
|
||||||
schema: schema2,
|
schema: schema2,
|
||||||
|
wrapped,
|
||||||
wrap: schema1,
|
wrap: schema1,
|
||||||
...opts,
|
...opts,
|
||||||
});
|
});
|
||||||
@ -407,6 +463,7 @@ export class Designable {
|
|||||||
position: 'afterBegin',
|
position: 'afterBegin',
|
||||||
schema: schema2,
|
schema: schema2,
|
||||||
wrap: schema1,
|
wrap: schema1,
|
||||||
|
wrapped,
|
||||||
...opts,
|
...opts,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -421,6 +478,7 @@ export class Designable {
|
|||||||
if (!Schema.isSchemaInstance(this.current)) {
|
if (!Schema.isSchemaInstance(this.current)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
delete schema['x-index'];
|
||||||
const opts = { onSuccess: options.onSuccess };
|
const opts = { onSuccess: options.onSuccess };
|
||||||
const { wrap = defaultWrap, breakRemoveOn, removeParentsIfNoChildren } = options;
|
const { wrap = defaultWrap, breakRemoveOn, removeParentsIfNoChildren } = options;
|
||||||
if (Schema.isSchemaInstance(schema)) {
|
if (Schema.isSchemaInstance(schema)) {
|
||||||
@ -447,6 +505,7 @@ export class Designable {
|
|||||||
position: 'beforeEnd',
|
position: 'beforeEnd',
|
||||||
schema: schema2,
|
schema: schema2,
|
||||||
wrap: schema1,
|
wrap: schema1,
|
||||||
|
wrapped,
|
||||||
...opts,
|
...opts,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -508,6 +567,7 @@ export class Designable {
|
|||||||
position: 'afterEnd',
|
position: 'afterEnd',
|
||||||
schema: schema2,
|
schema: schema2,
|
||||||
wrap: schema1,
|
wrap: schema1,
|
||||||
|
wrapped,
|
||||||
...opts,
|
...opts,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@ export const uiSchemaActions = {
|
|||||||
insertNewSchema: callRepositoryMethod('insertNewSchema', 'values'),
|
insertNewSchema: callRepositoryMethod('insertNewSchema', 'values'),
|
||||||
remove: callRepositoryMethod('remove', 'resourceIndex'),
|
remove: callRepositoryMethod('remove', 'resourceIndex'),
|
||||||
patch: callRepositoryMethod('patch', 'values'),
|
patch: callRepositoryMethod('patch', 'values'),
|
||||||
|
batchPatch: callRepositoryMethod('batchPatch', 'values'),
|
||||||
clearAncestor: callRepositoryMethod('clearAncestor', 'resourceIndex'),
|
clearAncestor: callRepositoryMethod('clearAncestor', 'resourceIndex'),
|
||||||
|
|
||||||
async insertAdjacent(ctx: Context, next) {
|
async insertAdjacent(ctx: Context, next) {
|
||||||
|
@ -303,6 +303,14 @@ export class UiSchemaRepository extends Repository {
|
|||||||
await traverSchemaTree(newSchema);
|
await traverSchemaTree(newSchema);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@transaction()
|
||||||
|
async batchPatch(schemas: any[], options?) {
|
||||||
|
const { transaction } = options;
|
||||||
|
for (const schema of schemas) {
|
||||||
|
await this.patch(schema, { ...options, transaction });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async updateNode(uid: string, schema: any, transaction?: Transaction) {
|
async updateNode(uid: string, schema: any, transaction?: Transaction) {
|
||||||
const nodeModel = await this.findOne({
|
const nodeModel = await this.findOne({
|
||||||
filter: {
|
filter: {
|
||||||
|
Loading…
Reference in New Issue
Block a user