feat(client): add designable test cases
This commit is contained in:
parent
be489996c3
commit
1a7f638f85
@ -19,6 +19,7 @@ export interface IResource {
|
|||||||
create?: (params?: ActionParams) => Promise<any>;
|
create?: (params?: ActionParams) => Promise<any>;
|
||||||
update?: (params?: ActionParams) => Promise<any>;
|
update?: (params?: ActionParams) => Promise<any>;
|
||||||
destroy?: (params?: ActionParams) => Promise<any>;
|
destroy?: (params?: ActionParams) => Promise<any>;
|
||||||
|
[key: string]: (params?: ActionParams) => Promise<any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class APIClient {
|
export class APIClient {
|
||||||
|
@ -103,6 +103,96 @@ const FormBlockInitializerItem = itemWrap((props) => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const TestInitializerItem = itemWrap((props) => {
|
||||||
|
const { insert } = props;
|
||||||
|
return (
|
||||||
|
<SchemaInitializer.Item
|
||||||
|
icon={<FormOutlined />}
|
||||||
|
onClick={() => {
|
||||||
|
insert({
|
||||||
|
type: 'void',
|
||||||
|
name: uid(),
|
||||||
|
'x-decorator': 'CardItem',
|
||||||
|
'x-component': 'Grid',
|
||||||
|
'x-uid': uid(),
|
||||||
|
properties: {
|
||||||
|
row1: {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Row',
|
||||||
|
'x-uid': uid(),
|
||||||
|
properties: {
|
||||||
|
col11: {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
properties: {
|
||||||
|
block1: {
|
||||||
|
type: 'void',
|
||||||
|
title: '1',
|
||||||
|
'x-decorator': 'BlockItem',
|
||||||
|
'x-component': 'Block',
|
||||||
|
},
|
||||||
|
block2: {
|
||||||
|
type: 'void',
|
||||||
|
title: '2',
|
||||||
|
'x-decorator': 'BlockItem',
|
||||||
|
'x-component': 'Block',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
col12: {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
properties: {
|
||||||
|
block3: {
|
||||||
|
type: 'void',
|
||||||
|
title: '3',
|
||||||
|
'x-decorator': 'BlockItem',
|
||||||
|
'x-component': 'Block',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
row2: {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Row',
|
||||||
|
'x-uid': uid(),
|
||||||
|
properties: {
|
||||||
|
col21: {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
properties: {
|
||||||
|
block4: {
|
||||||
|
type: 'void',
|
||||||
|
title: '4',
|
||||||
|
'x-decorator': 'BlockItem',
|
||||||
|
'x-component': 'Block',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
col22: {
|
||||||
|
type: 'void',
|
||||||
|
'x-component': 'Grid.Col',
|
||||||
|
properties: {
|
||||||
|
block5: {
|
||||||
|
type: 'void',
|
||||||
|
title: '5',
|
||||||
|
'x-decorator': 'BlockItem',
|
||||||
|
'x-component': 'Block',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Test
|
||||||
|
</SchemaInitializer.Item>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
export const AddGridBlockItem = observer((props: any) => {
|
export const AddGridBlockItem = observer((props: any) => {
|
||||||
return (
|
return (
|
||||||
<SchemaInitializer.Button
|
<SchemaInitializer.Button
|
||||||
@ -123,6 +213,11 @@ export const AddGridBlockItem = observer((props: any) => {
|
|||||||
title: 'Form',
|
title: 'Form',
|
||||||
component: FormBlockInitializerItem,
|
component: FormBlockInitializerItem,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: 'item',
|
||||||
|
title: 'Test',
|
||||||
|
component: TestInitializerItem,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
|
@ -74,8 +74,10 @@ const useCurrentFieldSchema = (path: string) => {
|
|||||||
remove() {
|
remove() {
|
||||||
schema &&
|
schema &&
|
||||||
remove(schema, {
|
remove(schema, {
|
||||||
breakComponent: 'Grid',
|
removeParentsIfNoChildren: true,
|
||||||
removeEmptyParents: true,
|
breakSchema: (s) => {
|
||||||
|
return s['x-component'] === 'Grid';
|
||||||
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
13
packages/client/src/schema-component/antd/grid/Block.tsx
Normal file
13
packages/client/src/schema-component/antd/grid/Block.tsx
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { observer, useFieldSchema } from '@formily/react';
|
||||||
|
import React from 'react';
|
||||||
|
import { DragHandler } from '../../';
|
||||||
|
|
||||||
|
export const Block = observer((props) => {
|
||||||
|
const fieldSchema = useFieldSchema();
|
||||||
|
return (
|
||||||
|
<div style={{ marginBottom: 20, padding: '0 20px', height: 50, lineHeight: '50px', background: '#f1f1f1' }}>
|
||||||
|
Block {fieldSchema.title}
|
||||||
|
<DragHandler />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
@ -1,5 +1,4 @@
|
|||||||
import { observer, useFieldSchema } from '@formily/react';
|
import { observer, useFieldSchema } from '@formily/react';
|
||||||
import { uid } from '@formily/shared';
|
|
||||||
import { BlockItem, DragHandler, Grid, SchemaComponent, SchemaComponentProvider } from '@nocobase/client';
|
import { BlockItem, DragHandler, Grid, SchemaComponent, SchemaComponentProvider } from '@nocobase/client';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
@ -13,87 +12,151 @@ const Block = observer((props) => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
export default function App() {
|
const schema = {
|
||||||
return (
|
_isJSONSchemaObject: true,
|
||||||
<SchemaComponentProvider components={{ Grid, Block, BlockItem }}>
|
version: '2.0',
|
||||||
<SchemaComponent
|
|
||||||
schema={{
|
|
||||||
type: 'void',
|
type: 'void',
|
||||||
name: 'grid1',
|
name: 'grid1',
|
||||||
|
'x-decorator': 'CardItem',
|
||||||
'x-component': 'Grid',
|
'x-component': 'Grid',
|
||||||
'x-uid': uid(),
|
|
||||||
properties: {
|
properties: {
|
||||||
row1: {
|
row1: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
'x-component': 'Grid.Row',
|
'x-component': 'Grid.Row',
|
||||||
'x-uid': uid(),
|
|
||||||
properties: {
|
properties: {
|
||||||
col11: {
|
col11: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
type: 'void',
|
type: 'void',
|
||||||
'x-component': 'Grid.Col',
|
'x-component': 'Grid.Col',
|
||||||
properties: {
|
properties: {
|
||||||
block1: {
|
block1: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: '1',
|
title: '1',
|
||||||
'x-decorator': 'BlockItem',
|
'x-decorator': 'BlockItem',
|
||||||
'x-component': 'Block',
|
'x-component': 'Block',
|
||||||
|
'x-uid': 'a9m97uffyku',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
},
|
},
|
||||||
block2: {
|
block2: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: '2',
|
title: '2.1',
|
||||||
'x-decorator': 'BlockItem',
|
'x-decorator': 'BlockItem',
|
||||||
'x-component': 'Block',
|
'x-component': 'Block',
|
||||||
|
'x-uid': 'lensw462z8w',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 2,
|
||||||
|
},
|
||||||
|
block234: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
|
type: 'void',
|
||||||
|
title: '2.2',
|
||||||
|
'x-decorator': 'BlockItem',
|
||||||
|
'x-component': 'Block',
|
||||||
|
'x-uid': 'lensw462z81',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 3,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
'x-uid': '4shevom50rl',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
},
|
},
|
||||||
col12: {
|
col12: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
type: 'void',
|
type: 'void',
|
||||||
'x-component': 'Grid.Col',
|
'x-component': 'Grid.Col',
|
||||||
properties: {
|
properties: {
|
||||||
block3: {
|
block3: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: '3',
|
title: '3',
|
||||||
'x-decorator': 'BlockItem',
|
'x-decorator': 'BlockItem',
|
||||||
'x-component': 'Block',
|
'x-component': 'Block',
|
||||||
|
'x-uid': 'kp4kjknbs2l',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
'x-uid': 'u7n3beze0gr',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 2,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
'x-uid': 'qfl04eq71tt',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
},
|
},
|
||||||
row2: {
|
row2: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
type: 'void',
|
type: 'void',
|
||||||
'x-component': 'Grid.Row',
|
'x-component': 'Grid.Row',
|
||||||
'x-uid': uid(),
|
|
||||||
properties: {
|
properties: {
|
||||||
col21: {
|
col21: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
type: 'void',
|
type: 'void',
|
||||||
'x-component': 'Grid.Col',
|
'x-component': 'Grid.Col',
|
||||||
properties: {
|
properties: {
|
||||||
block4: {
|
block4: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: '4',
|
title: '4',
|
||||||
'x-decorator': 'BlockItem',
|
'x-decorator': 'BlockItem',
|
||||||
'x-component': 'Block',
|
'x-component': 'Block',
|
||||||
|
'x-uid': 'v5bd5kcyhat',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
'x-uid': 'bwg0mv89atk',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
},
|
},
|
||||||
col22: {
|
col22: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
type: 'void',
|
type: 'void',
|
||||||
'x-component': 'Grid.Col',
|
'x-component': 'Grid.Col',
|
||||||
properties: {
|
properties: {
|
||||||
block5: {
|
block5: {
|
||||||
|
_isJSONSchemaObject: true,
|
||||||
|
version: '2.0',
|
||||||
type: 'void',
|
type: 'void',
|
||||||
title: '5',
|
title: '5',
|
||||||
'x-decorator': 'BlockItem',
|
'x-decorator': 'BlockItem',
|
||||||
'x-component': 'Block',
|
'x-component': 'Block',
|
||||||
|
'x-uid': 'noh1flz5oqg',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
'x-uid': 'oz0rypr2rlj',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 2,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
'x-uid': '5igqpmvilz1',
|
||||||
|
'x-async': false,
|
||||||
|
'x-index': 2,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}}
|
};
|
||||||
/>
|
|
||||||
|
export default function App() {
|
||||||
|
return (
|
||||||
|
<SchemaComponentProvider components={{ Grid, Block, BlockItem }}>
|
||||||
|
<SchemaComponent schema={schema} />
|
||||||
</SchemaComponentProvider>
|
</SchemaComponentProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,44 @@
|
|||||||
import { ISchema } from '@formily/react';
|
import { ISchema, observer, useFieldSchema } from '@formily/react';
|
||||||
import { uid } from '@formily/shared';
|
import { uid } from '@formily/shared';
|
||||||
import { CardItem, Form, Grid, Markdown, SchemaComponent, SchemaComponentProvider, VoidTable } from '@nocobase/client';
|
import {
|
||||||
|
BlockItem,
|
||||||
|
CardItem,
|
||||||
|
DragHandler,
|
||||||
|
Form,
|
||||||
|
Grid,
|
||||||
|
Markdown,
|
||||||
|
SchemaComponent,
|
||||||
|
SchemaComponentProvider,
|
||||||
|
VoidTable
|
||||||
|
} from '@nocobase/client';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
const Block = observer((props) => {
|
||||||
|
const fieldSchema = useFieldSchema();
|
||||||
|
return (
|
||||||
|
<div style={{ marginBottom: 20, padding: '0 20px', height: 50, lineHeight: '50px', background: '#f1f1f1' }}>
|
||||||
|
Block {fieldSchema.title}
|
||||||
|
<DragHandler />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
const schema: ISchema = {
|
const schema: ISchema = {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
grid: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
name: 'grid1',
|
|
||||||
'x-component': 'Grid',
|
'x-component': 'Grid',
|
||||||
'x-item-initializer': 'Grid.AddBlockItem',
|
'x-item-initializer': 'Grid.AddBlockItem',
|
||||||
'x-uid': uid(),
|
'x-uid': uid(),
|
||||||
properties: {},
|
properties: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
return (
|
return (
|
||||||
<SchemaComponentProvider components={{ Grid, CardItem, Markdown, Form, VoidTable }}>
|
<SchemaComponentProvider components={{ BlockItem, Block, Grid, CardItem, Markdown, Form, VoidTable }}>
|
||||||
<SchemaComponent schema={schema} />
|
<SchemaComponent schema={schema} />
|
||||||
</SchemaComponentProvider>
|
</SchemaComponentProvider>
|
||||||
);
|
);
|
||||||
|
@ -1 +1,3 @@
|
|||||||
|
export * from './Block';
|
||||||
export * from './Grid';
|
export * from './Grid';
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@ const useDragEnd = () => {
|
|||||||
const { refresh } = useDesignable();
|
const { refresh } = useDesignable();
|
||||||
|
|
||||||
return ({ active, over }: DragEndEvent) => {
|
return ({ active, over }: DragEndEvent) => {
|
||||||
console.log({ active, over });
|
|
||||||
const activeSchema = active?.data?.current?.schema;
|
const activeSchema = active?.data?.current?.schema;
|
||||||
const overSchema = over?.data?.current?.schema;
|
const overSchema = over?.data?.current?.schema;
|
||||||
const insertAdjacent = over?.data?.current?.insertAdjacent;
|
const insertAdjacent = over?.data?.current?.insertAdjacent;
|
||||||
@ -35,7 +34,7 @@ const useDragEnd = () => {
|
|||||||
if (insertAdjacent) {
|
if (insertAdjacent) {
|
||||||
dn.insertAdjacent(insertAdjacent, activeSchema, {
|
dn.insertAdjacent(insertAdjacent, activeSchema, {
|
||||||
wrap: wrapSchema,
|
wrap: wrapSchema,
|
||||||
removeEmptyParents: true,
|
removeParentsIfNoChildren: true,
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -34,16 +34,11 @@ export const Sortable = (props: any) => {
|
|||||||
export const SortableItem: React.FC<any> = observer((props) => {
|
export const SortableItem: React.FC<any> = observer((props) => {
|
||||||
const field = useField();
|
const field = useField();
|
||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
const onInsertAdjacent = ({ dn, orginDraggedParentSchema }) => {
|
|
||||||
dn.removeIfChildrenEmpty(orginDraggedParentSchema, {
|
|
||||||
removeEmptyParents: true,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
return (
|
return (
|
||||||
<Sortable
|
<Sortable
|
||||||
{...props}
|
{...props}
|
||||||
id={field.address.toString()}
|
id={field.address.toString()}
|
||||||
data={{ insertAdjacent: 'afterEnd', onInsertAdjacent, schema: fieldSchema }}
|
data={{ insertAdjacent: 'afterEnd', schema: fieldSchema }}
|
||||||
>
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
</Sortable>
|
</Sortable>
|
||||||
|
@ -0,0 +1,453 @@
|
|||||||
|
import { Schema } from '@formily/react';
|
||||||
|
import { createDesignable, Designable } from '../useDesignable';
|
||||||
|
|
||||||
|
describe('createDesignable', () => {
|
||||||
|
let dn: Designable;
|
||||||
|
let schema: Schema;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
schema = new Schema({
|
||||||
|
type: 'void',
|
||||||
|
name: 'global',
|
||||||
|
'x-uid': 'global',
|
||||||
|
properties: {
|
||||||
|
current: {
|
||||||
|
type: 'void',
|
||||||
|
'x-uid': 'current',
|
||||||
|
properties: {
|
||||||
|
child: {
|
||||||
|
type: 'void',
|
||||||
|
'x-uid': 'child',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
dn = createDesignable({
|
||||||
|
current: schema.properties.current,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('insert a new node', () => {
|
||||||
|
test('insertBeforeBegin', () => {
|
||||||
|
dn.insertBeforeBegin({
|
||||||
|
name: 'abc',
|
||||||
|
});
|
||||||
|
expect(schema.toJSON()).toMatchObject({
|
||||||
|
type: 'void',
|
||||||
|
name: 'global',
|
||||||
|
'x-uid': 'global',
|
||||||
|
properties: {
|
||||||
|
abc: {
|
||||||
|
name: 'abc',
|
||||||
|
type: 'void',
|
||||||
|
},
|
||||||
|
current: {
|
||||||
|
type: 'void',
|
||||||
|
name: 'current',
|
||||||
|
'x-uid': 'current',
|
||||||
|
properties: {
|
||||||
|
child: {
|
||||||
|
type: 'void',
|
||||||
|
'x-uid': 'child',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(schema.properties.abc['x-uid']).toBeDefined();
|
||||||
|
expect(Object.keys(schema.properties)).toEqual(['abc', 'current']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('insertAfterBegin', () => {
|
||||||
|
dn.insertAfterBegin({
|
||||||
|
name: 'abc',
|
||||||
|
});
|
||||||
|
expect(Object.keys(schema.properties.current.properties)).toEqual(['abc', 'child']);
|
||||||
|
expect(schema.toJSON()).toMatchObject({
|
||||||
|
type: 'void',
|
||||||
|
name: 'global',
|
||||||
|
'x-uid': 'global',
|
||||||
|
properties: {
|
||||||
|
current: {
|
||||||
|
type: 'void',
|
||||||
|
name: 'current',
|
||||||
|
'x-uid': 'current',
|
||||||
|
properties: {
|
||||||
|
abc: {
|
||||||
|
name: 'abc',
|
||||||
|
type: 'void',
|
||||||
|
},
|
||||||
|
child: {
|
||||||
|
type: 'void',
|
||||||
|
'x-uid': 'child',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(schema.properties.current.properties.abc['x-uid']).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('insertBeforeEnd', () => {
|
||||||
|
dn.insertBeforeEnd({
|
||||||
|
name: 'abc',
|
||||||
|
});
|
||||||
|
expect(schema.toJSON()).toMatchObject({
|
||||||
|
type: 'void',
|
||||||
|
name: 'global',
|
||||||
|
'x-uid': 'global',
|
||||||
|
properties: {
|
||||||
|
current: {
|
||||||
|
type: 'void',
|
||||||
|
name: 'current',
|
||||||
|
'x-uid': 'current',
|
||||||
|
properties: {
|
||||||
|
child: {
|
||||||
|
type: 'void',
|
||||||
|
'x-uid': 'child',
|
||||||
|
},
|
||||||
|
abc: {
|
||||||
|
name: 'abc',
|
||||||
|
type: 'void',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(schema.properties.current.properties.abc['x-uid']).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('insertAfterEnd', () => {
|
||||||
|
dn.insertAfterEnd({
|
||||||
|
name: 'abc',
|
||||||
|
});
|
||||||
|
expect(schema.toJSON()).toMatchObject({
|
||||||
|
type: 'void',
|
||||||
|
name: 'global',
|
||||||
|
'x-uid': 'global',
|
||||||
|
properties: {
|
||||||
|
current: {
|
||||||
|
type: 'void',
|
||||||
|
name: 'current',
|
||||||
|
'x-uid': 'current',
|
||||||
|
properties: {
|
||||||
|
child: {
|
||||||
|
type: 'void',
|
||||||
|
'x-uid': 'child',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
abc: {
|
||||||
|
name: 'abc',
|
||||||
|
type: 'void',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(schema.properties.abc['x-uid']).toBeDefined();
|
||||||
|
expect(Object.keys(schema.properties)).toEqual(['current', 'abc']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('move an existing node', () => {
|
||||||
|
test('insertBeforeBegin', () => {
|
||||||
|
dn.insertBeforeBegin(schema.properties.current.properties.child);
|
||||||
|
expect(Object.keys(schema.properties)).toEqual(['child', 'current']);
|
||||||
|
expect(schema.properties.current?.properties?.child).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('insertBeforeBegin', () => {
|
||||||
|
dn.insertBeforeBegin({
|
||||||
|
type: 'void',
|
||||||
|
name: 'a1',
|
||||||
|
});
|
||||||
|
dn.insertBeforeBegin({
|
||||||
|
type: 'void',
|
||||||
|
name: 'a2',
|
||||||
|
});
|
||||||
|
dn.insertBeforeBegin({
|
||||||
|
type: 'void',
|
||||||
|
name: 'a3',
|
||||||
|
});
|
||||||
|
expect(Object.keys(schema.properties)).toEqual(['a1', 'a2', 'a3', 'current']);
|
||||||
|
dn.insertBeforeBegin(schema.properties.a2);
|
||||||
|
expect(Object.keys(schema.properties)).toEqual(['a1', 'a3', 'a2', 'current']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('insertAfterBegin', () => {
|
||||||
|
dn.insertBeforeBegin({
|
||||||
|
name: 'a1',
|
||||||
|
});
|
||||||
|
dn.insertAfterBegin(schema.properties.a1);
|
||||||
|
expect(Object.keys(schema.properties.current.properties)).toEqual(['a1', 'child']);
|
||||||
|
expect(schema.properties.a1).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('insertBeforeEnd', () => {
|
||||||
|
dn.insertBeforeBegin({
|
||||||
|
name: 'a1',
|
||||||
|
});
|
||||||
|
dn.insertBeforeEnd(schema.properties.a1);
|
||||||
|
expect(Object.keys(schema.properties.current.properties)).toEqual(['child', 'a1']);
|
||||||
|
expect(schema.properties.a1).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('insertAfterEnd', () => {
|
||||||
|
dn.insertAfterEnd(schema.properties.current.properties.child);
|
||||||
|
expect(Object.keys(schema.properties)).toEqual(['current', 'child']);
|
||||||
|
expect(schema.properties.current?.properties?.child).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('insertAfterEnd', () => {
|
||||||
|
dn.insertAfterEnd({
|
||||||
|
type: 'void',
|
||||||
|
name: 'a1',
|
||||||
|
});
|
||||||
|
dn.insertAfterEnd({
|
||||||
|
type: 'void',
|
||||||
|
name: 'a2',
|
||||||
|
});
|
||||||
|
dn.insertAfterEnd({
|
||||||
|
type: 'void',
|
||||||
|
name: 'a3',
|
||||||
|
});
|
||||||
|
expect(Object.keys(schema.properties)).toEqual(['current', 'a3', 'a2', 'a1']);
|
||||||
|
dn.insertAfterEnd(schema.properties.a2);
|
||||||
|
expect(Object.keys(schema.properties)).toEqual(['current', 'a2', 'a3', 'a1']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('removeIfNoChildren', () => {
|
||||||
|
test('has child nodes', () => {
|
||||||
|
dn.removeIfNoChildren(schema.properties.current);
|
||||||
|
expect(schema.properties.current).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('no child nodes', () => {
|
||||||
|
dn.removeIfNoChildren(schema.properties.current.properties.child);
|
||||||
|
expect(schema.properties.current?.properties?.child).toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('remove', () => {
|
||||||
|
test('without schema', () => {
|
||||||
|
dn.remove();
|
||||||
|
expect(schema?.properties?.current).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('without options', () => {
|
||||||
|
dn.remove(schema.properties.current.properties.child);
|
||||||
|
expect(schema.properties.current).toBeDefined();
|
||||||
|
expect(schema.properties.current?.properties?.child).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('removeParentsIfNoChildren + breakSchema json', () => {
|
||||||
|
dn.remove(schema.properties.current.properties.child, {
|
||||||
|
removeParentsIfNoChildren: true,
|
||||||
|
breakSchema: {
|
||||||
|
'x-uid': 'global',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(schema?.properties?.current).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('removeParentsIfNoChildren + breakSchema function', () => {
|
||||||
|
dn.remove(schema.properties.current.properties.child, {
|
||||||
|
removeParentsIfNoChildren: true,
|
||||||
|
breakSchema: (s) => s['x-uid'] === 'global',
|
||||||
|
});
|
||||||
|
expect(schema?.properties?.current).toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('x-index', () => {
|
||||||
|
let dn: Designable;
|
||||||
|
let schema: Schema;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
schema = new Schema({
|
||||||
|
type: 'void',
|
||||||
|
name: 'col1',
|
||||||
|
'x-uid': 'col1',
|
||||||
|
properties: {
|
||||||
|
block1: {
|
||||||
|
type: 'void',
|
||||||
|
'x-index': 1,
|
||||||
|
},
|
||||||
|
block2: {
|
||||||
|
type: 'void',
|
||||||
|
'x-index': 2,
|
||||||
|
},
|
||||||
|
block3: {
|
||||||
|
type: 'void',
|
||||||
|
'x-index': 3,
|
||||||
|
},
|
||||||
|
block4: {
|
||||||
|
type: 'void',
|
||||||
|
'x-index': 4,
|
||||||
|
},
|
||||||
|
block5: {
|
||||||
|
type: 'void',
|
||||||
|
'x-index': 5,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('insertBeforeBeginOrAfterEnd', () => {
|
||||||
|
dn = createDesignable({
|
||||||
|
current: schema.properties.block2,
|
||||||
|
});
|
||||||
|
dn.insertBeforeBeginOrAfterEnd(schema.properties.block5);
|
||||||
|
expect(Object.keys(schema.properties)).toEqual(['block1', 'block5', 'block2', 'block3', 'block4']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('insertBeforeBegin', () => {
|
||||||
|
dn = createDesignable({
|
||||||
|
current: schema.properties.block2,
|
||||||
|
});
|
||||||
|
dn.insertBeforeBegin({
|
||||||
|
name: 'block0',
|
||||||
|
});
|
||||||
|
expect(Object.keys(schema.properties)).toEqual(['block1', 'block0', 'block2', 'block3', 'block4', 'block5']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('insertAfterEnd', () => {
|
||||||
|
dn = createDesignable({
|
||||||
|
current: schema.properties.block2,
|
||||||
|
});
|
||||||
|
dn.insertAfterEnd({
|
||||||
|
name: 'block0',
|
||||||
|
});
|
||||||
|
expect(Object.keys(schema.properties)).toEqual(['block1', 'block2', 'block0', 'block3', 'block4', 'block5']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('insertAfterBegin', () => {
|
||||||
|
dn = createDesignable({
|
||||||
|
current: schema,
|
||||||
|
});
|
||||||
|
dn.insertAfterBegin({
|
||||||
|
name: 'block0',
|
||||||
|
});
|
||||||
|
expect(Object.keys(schema.properties)).toEqual(['block0', 'block1', 'block2', 'block3', 'block4', 'block5']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('insertBeforeEnd', () => {
|
||||||
|
dn = createDesignable({
|
||||||
|
current: schema,
|
||||||
|
});
|
||||||
|
dn.insertBeforeEnd({
|
||||||
|
name: 'block0',
|
||||||
|
});
|
||||||
|
expect(Object.keys(schema.properties)).toEqual(['block1', 'block2', 'block3', 'block4', 'block5', 'block0']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('wrap', () => {
|
||||||
|
let dn: Designable;
|
||||||
|
let schema: Schema;
|
||||||
|
const colWrap = (s) => {
|
||||||
|
return {
|
||||||
|
name: 'col12',
|
||||||
|
type: 'void',
|
||||||
|
'x-uid': 'col12',
|
||||||
|
properties: {
|
||||||
|
[s.name]: s,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const rowWrap = (s) => {
|
||||||
|
return {
|
||||||
|
name: 'row2',
|
||||||
|
type: 'void',
|
||||||
|
'x-uid': 'row2',
|
||||||
|
properties: {
|
||||||
|
col21: {
|
||||||
|
type: 'void',
|
||||||
|
'x-uid': 'col21',
|
||||||
|
properties: {
|
||||||
|
[s.name]: s,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
schema = new Schema({
|
||||||
|
type: 'void',
|
||||||
|
name: 'grid1',
|
||||||
|
'x-uid': 'grid1',
|
||||||
|
properties: {
|
||||||
|
row1: {
|
||||||
|
type: 'void',
|
||||||
|
'x-uid': 'row1',
|
||||||
|
properties: {
|
||||||
|
col11: {
|
||||||
|
type: 'void',
|
||||||
|
'x-uid': 'col11',
|
||||||
|
properties: {
|
||||||
|
block1: {
|
||||||
|
type: 'void',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('insertBeforeBegin', () => {
|
||||||
|
dn = createDesignable({
|
||||||
|
current: schema.properties.row1.properties.col11,
|
||||||
|
});
|
||||||
|
const s = {
|
||||||
|
type: 'void',
|
||||||
|
name: 'block2',
|
||||||
|
};
|
||||||
|
dn.insertBeforeBegin(s, {
|
||||||
|
wrap: colWrap,
|
||||||
|
});
|
||||||
|
expect(Object.keys(schema.properties.row1.properties)).toEqual(['col12', 'col11']);
|
||||||
|
expect(schema.properties.row1.properties.col12.properties.block2).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('insertAfterEnd', () => {
|
||||||
|
dn = createDesignable({
|
||||||
|
current: schema.properties.row1.properties.col11,
|
||||||
|
});
|
||||||
|
const s = {
|
||||||
|
type: 'void',
|
||||||
|
name: 'block2',
|
||||||
|
};
|
||||||
|
dn.insertAfterEnd(s, {
|
||||||
|
wrap: colWrap,
|
||||||
|
});
|
||||||
|
expect(Object.keys(schema.properties.row1.properties)).toEqual(['col11', 'col12']);
|
||||||
|
expect(schema.properties.row1.properties.col12.properties.block2).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('removeParentsIfNoChildren', () => {
|
||||||
|
const coldn = createDesignable({
|
||||||
|
current: schema.properties.row1.properties.col11,
|
||||||
|
});
|
||||||
|
const s = {
|
||||||
|
type: 'void',
|
||||||
|
name: 'block2',
|
||||||
|
};
|
||||||
|
coldn.insertAfterEnd(s, { wrap: colWrap });
|
||||||
|
const griddn = createDesignable({
|
||||||
|
current: schema,
|
||||||
|
});
|
||||||
|
griddn.insertBeforeEnd(schema.properties.row1.properties.col12.properties.block2, {
|
||||||
|
wrap: rowWrap,
|
||||||
|
removeParentsIfNoChildren: true,
|
||||||
|
});
|
||||||
|
expect(Object.keys(schema.properties.row1.properties)).toEqual(['col11']);
|
||||||
|
expect(Object.keys(schema.properties.row2.properties)).toEqual(['col21']);
|
||||||
|
expect(schema.properties.row2.properties.col21.properties.block2).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
@ -3,6 +3,7 @@ import { uid } from '@formily/shared';
|
|||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
import set from 'lodash/set';
|
import set from 'lodash/set';
|
||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
|
import { useAPIClient } from '../../api-client';
|
||||||
import { SchemaComponentContext } from '../context';
|
import { SchemaComponentContext } from '../context';
|
||||||
|
|
||||||
interface CreateDesignableProps {
|
interface CreateDesignableProps {
|
||||||
@ -20,12 +21,14 @@ type Position = 'beforeBegin' | 'afterBegin' | 'beforeEnd' | 'afterEnd';
|
|||||||
|
|
||||||
interface InsertAdjacentOptions {
|
interface InsertAdjacentOptions {
|
||||||
wrap?: (s: ISchema) => ISchema;
|
wrap?: (s: ISchema) => ISchema;
|
||||||
removeEmptyParents?: boolean;
|
removeParentsIfNoChildren?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type BreakFn = (s: ISchema) => boolean;
|
||||||
|
|
||||||
interface RemoveOptions {
|
interface RemoveOptions {
|
||||||
removeEmptyParents?: boolean;
|
removeParentsIfNoChildren?: boolean;
|
||||||
breakComponent?: string;
|
breakSchema?: ISchema | BreakFn;
|
||||||
}
|
}
|
||||||
|
|
||||||
const generateUid = (s: ISchema) => {
|
const generateUid = (s: ISchema) => {
|
||||||
@ -76,7 +79,7 @@ export class Designable {
|
|||||||
if (!this.events[name]) {
|
if (!this.events[name]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.events[name].forEach((fn) => fn.bind(this)(...args));
|
this.events[name].forEach((fn) => fn.bind(this)(this.current, ...args));
|
||||||
}
|
}
|
||||||
|
|
||||||
insertAdjacent(position: Position, schema: ISchema, options: InsertAdjacentOptions = {}) {
|
insertAdjacent(position: Position, schema: ISchema, options: InsertAdjacentOptions = {}) {
|
||||||
@ -92,17 +95,16 @@ export class Designable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
removeIfChildrenEmpty(schema?: Schema) {
|
removeIfNoChildren(schema?: Schema) {
|
||||||
if (!schema) {
|
if (!schema) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let s = schema;
|
let s = schema;
|
||||||
const count = Object.keys(s.properties || {}).length;
|
const count = Object.keys(s.properties || {}).length;
|
||||||
console.log('removeIfChildrenEmpty', count, s.properties);
|
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let removed;
|
let removed: Schema;
|
||||||
while (s.parent) {
|
while (s.parent) {
|
||||||
removed = s.parent.removeProperty(s.name);
|
removed = s.parent.removeProperty(s.name);
|
||||||
const count = Object.keys(s.parent.properties || {}).length;
|
const count = Object.keys(s.parent.properties || {}).length;
|
||||||
@ -111,18 +113,42 @@ export class Designable {
|
|||||||
}
|
}
|
||||||
s = s.parent;
|
s = s.parent;
|
||||||
}
|
}
|
||||||
|
return removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
remove(schema?: Schema, options: RemoveOptions = {}) {
|
remove(schema?: Schema, options: RemoveOptions = {}) {
|
||||||
const { removeEmptyParents, breakComponent } = options;
|
const { removeParentsIfNoChildren, breakSchema } = options;
|
||||||
let s = schema || this.current;
|
let s = schema || this.current;
|
||||||
let removed;
|
let removed;
|
||||||
|
const matchSchema = (source: ISchema, target: ISchema) => {
|
||||||
|
if (!source || !target) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (const key in target) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(target, key)) {
|
||||||
|
const value = target[key];
|
||||||
|
if (value !== source?.[key]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
while (s.parent) {
|
while (s.parent) {
|
||||||
removed = s.parent.removeProperty(s.name);
|
removed = s.parent.removeProperty(s.name);
|
||||||
if (!removeEmptyParents) {
|
if (!removeParentsIfNoChildren) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (s?.parent?.['x-component'] === breakComponent) {
|
if (typeof breakSchema === 'function') {
|
||||||
|
if (breakSchema(s?.parent)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (matchSchema(s?.parent, breakSchema)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (s?.parent?.['x-component'] === breakSchema) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const count = Object.keys(s.parent.properties || {}).length;
|
const count = Object.keys(s.parent.properties || {}).length;
|
||||||
@ -131,7 +157,7 @@ export class Designable {
|
|||||||
}
|
}
|
||||||
s = s.parent;
|
s = s.parent;
|
||||||
}
|
}
|
||||||
this.emit('afterRemove', removed);
|
this.emit('afterRemove', removed, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
insertBeforeBeginOrAfterEnd(schema: ISchema, options: InsertAdjacentOptions = {}) {
|
insertBeforeBeginOrAfterEnd(schema: ISchema, options: InsertAdjacentOptions = {}) {
|
||||||
@ -164,33 +190,38 @@ export class Designable {
|
|||||||
if (!Schema.isSchemaInstance(this.current)) {
|
if (!Schema.isSchemaInstance(this.current)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { wrap = defaultWrap, removeEmptyParents } = options;
|
const opts = {};
|
||||||
const properties = {};
|
const { wrap = defaultWrap, removeParentsIfNoChildren } = options;
|
||||||
let start = false;
|
|
||||||
|
|
||||||
if (Schema.isSchemaInstance(schema)) {
|
if (Schema.isSchemaInstance(schema)) {
|
||||||
schema.parent.removeProperty(schema.name);
|
schema.parent.removeProperty(schema.name);
|
||||||
if (removeEmptyParents) {
|
if (removeParentsIfNoChildren) {
|
||||||
this.removeIfChildrenEmpty(schema.parent);
|
opts['removed'] = this.removeIfNoChildren(schema.parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const properties = {};
|
||||||
|
let start = false;
|
||||||
|
let order = 0;
|
||||||
|
let newOrder = 0;
|
||||||
this.current.parent.mapProperties((property, key) => {
|
this.current.parent.mapProperties((property, key) => {
|
||||||
if (key === this.current.name) {
|
if (key === this.current.name) {
|
||||||
|
newOrder = order;
|
||||||
start = true;
|
start = true;
|
||||||
|
++order;
|
||||||
}
|
}
|
||||||
|
property['x-index'] = order;
|
||||||
|
++order;
|
||||||
if (start) {
|
if (start) {
|
||||||
properties[key] = property;
|
properties[key] = property;
|
||||||
this.current.parent.removeProperty(key);
|
this.current.parent.removeProperty(key);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.prepareProperty(schema);
|
this.prepareProperty(schema);
|
||||||
const wrapped = wrap(schema);
|
const wrapped = wrap(schema);
|
||||||
const s = this.current.parent.addProperty(wrapped.name, wrapped);
|
const s = this.current.parent.addProperty(wrapped.name || uid(), wrapped);
|
||||||
|
s['x-index'] = newOrder;
|
||||||
s.parent = this.current.parent;
|
s.parent = this.current.parent;
|
||||||
this.current.parent.setProperties(properties);
|
this.current.parent.setProperties(properties);
|
||||||
this.emit('afterInsertAdjacent', 'beforeBegin', s);
|
this.emit('afterInsertAdjacent', 'beforeBegin', s, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -203,24 +234,29 @@ export class Designable {
|
|||||||
if (!Schema.isSchemaInstance(this.current)) {
|
if (!Schema.isSchemaInstance(this.current)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { wrap = defaultWrap, removeEmptyParents } = options;
|
const opts = {};
|
||||||
|
const { wrap = defaultWrap, removeParentsIfNoChildren } = options;
|
||||||
if (Schema.isSchemaInstance(schema)) {
|
if (Schema.isSchemaInstance(schema)) {
|
||||||
schema.parent.removeProperty(schema.name);
|
schema.parent.removeProperty(schema.name);
|
||||||
if (removeEmptyParents) {
|
if (removeParentsIfNoChildren) {
|
||||||
this.removeIfChildrenEmpty(schema.parent);
|
opts['removed'] = this.removeIfNoChildren(schema.parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const properties = {};
|
const properties = {};
|
||||||
this.current.mapProperties((schema, key) => {
|
let order = 1;
|
||||||
properties[key] = schema;
|
this.current.mapProperties((s, key) => {
|
||||||
|
s['x-index'] = order;
|
||||||
|
++order;
|
||||||
|
properties[key] = s;
|
||||||
});
|
});
|
||||||
this.current.properties = {};
|
this.current.properties = {};
|
||||||
this.prepareProperty(schema);
|
this.prepareProperty(schema);
|
||||||
const wrapped = wrap(schema);
|
const wrapped = wrap(schema);
|
||||||
const s = this.current.addProperty(wrapped.name, wrapped);
|
const s = this.current.addProperty(wrapped.name || uid(), wrapped);
|
||||||
|
s['x-index'] = 0;
|
||||||
s.parent = this.current;
|
s.parent = this.current;
|
||||||
this.current.setProperties(properties);
|
this.current.setProperties(properties);
|
||||||
this.emit('afterInsertAdjacent', 'afterBegin', s);
|
this.emit('afterInsertAdjacent', 'afterBegin', s, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -233,18 +269,19 @@ export class Designable {
|
|||||||
if (!Schema.isSchemaInstance(this.current)) {
|
if (!Schema.isSchemaInstance(this.current)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { wrap = defaultWrap, removeEmptyParents } = options;
|
const opts = {};
|
||||||
|
const { wrap = defaultWrap, removeParentsIfNoChildren } = options;
|
||||||
if (Schema.isSchemaInstance(schema)) {
|
if (Schema.isSchemaInstance(schema)) {
|
||||||
schema.parent.removeProperty(schema.name);
|
schema.parent.removeProperty(schema.name);
|
||||||
if (removeEmptyParents) {
|
if (removeParentsIfNoChildren) {
|
||||||
this.removeIfChildrenEmpty(schema.parent);
|
opts['removed'] = this.removeIfNoChildren(schema.parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.prepareProperty(schema);
|
this.prepareProperty(schema);
|
||||||
const wrapped = wrap(schema);
|
const wrapped = wrap(schema);
|
||||||
const s = this.current.addProperty(wrapped.name || uid(), wrapped);
|
const s = this.current.addProperty(wrapped.name || uid(), wrapped);
|
||||||
s.parent = this.current;
|
s.parent = this.current;
|
||||||
this.emit('afterInsertAdjacent', 'beforeEnd', s);
|
this.emit('afterInsertAdjacent', 'beforeEnd', s, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -254,22 +291,29 @@ export class Designable {
|
|||||||
if (!Schema.isSchemaInstance(this.current)) {
|
if (!Schema.isSchemaInstance(this.current)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const properties = {};
|
const opts = {};
|
||||||
let start = false;
|
const { wrap = defaultWrap, removeParentsIfNoChildren } = options;
|
||||||
const { wrap = defaultWrap, removeEmptyParents } = options;
|
|
||||||
if (Schema.isSchemaInstance(schema)) {
|
if (Schema.isSchemaInstance(schema)) {
|
||||||
schema.parent.removeProperty(schema.name);
|
schema.parent.removeProperty(schema.name);
|
||||||
console.log('insertAfterEnd', removeEmptyParents);
|
if (removeParentsIfNoChildren) {
|
||||||
if (removeEmptyParents) {
|
opts['removed'] = this.removeIfNoChildren(schema.parent);
|
||||||
this.removeIfChildrenEmpty(schema.parent);
|
|
||||||
}
|
}
|
||||||
schema.parent = null;
|
schema.parent = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let order = 0;
|
||||||
|
let newOrder = 0;
|
||||||
|
let start = false;
|
||||||
|
const properties = {};
|
||||||
|
|
||||||
this.current.parent.mapProperties((property, key) => {
|
this.current.parent.mapProperties((property, key) => {
|
||||||
|
property['x-index'] = order;
|
||||||
if (key === this.current.name) {
|
if (key === this.current.name) {
|
||||||
|
++order;
|
||||||
|
newOrder = order;
|
||||||
start = true;
|
start = true;
|
||||||
}
|
}
|
||||||
|
++order;
|
||||||
if (start && key !== this.current.name) {
|
if (start && key !== this.current.name) {
|
||||||
properties[key] = property;
|
properties[key] = property;
|
||||||
this.current.parent.removeProperty(key);
|
this.current.parent.removeProperty(key);
|
||||||
@ -277,13 +321,12 @@ export class Designable {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.prepareProperty(schema);
|
this.prepareProperty(schema);
|
||||||
|
|
||||||
const wrapped = wrap(schema);
|
const wrapped = wrap(schema);
|
||||||
|
|
||||||
const s = this.current.parent.addProperty(wrapped.name || uid(), wrapped);
|
const s = this.current.parent.addProperty(wrapped.name || uid(), wrapped);
|
||||||
s.parent = this.current.parent;
|
s.parent = this.current.parent;
|
||||||
|
s['x-index'] = newOrder;
|
||||||
this.current.parent.setProperties(properties);
|
this.current.parent.setProperties(properties);
|
||||||
this.emit('afterInsertAdjacent', 'afterEnd', s);
|
this.emit('afterInsertAdjacent', 'afterEnd', s, opts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,7 +340,16 @@ export function useDesignable() {
|
|||||||
const field = useField();
|
const field = useField();
|
||||||
const fieldSchema = useFieldSchema();
|
const fieldSchema = useFieldSchema();
|
||||||
const dn = createDesignable({ current: fieldSchema });
|
const dn = createDesignable({ current: fieldSchema });
|
||||||
dn.on('afterInsertAdjacent', refresh);
|
const api = useAPIClient();
|
||||||
|
dn.on('afterInsertAdjacent', async (current, position, schema) => {
|
||||||
|
refresh();
|
||||||
|
// await api.request({
|
||||||
|
// url: `/ui_schemas:insertAdjacent/${current['x-uid']}?position=${position}`,
|
||||||
|
// method: 'post',
|
||||||
|
// data: schema.toJSON(),
|
||||||
|
// });
|
||||||
|
// console.log(current, position, schema);
|
||||||
|
});
|
||||||
dn.on('afterRemove', refresh);
|
dn.on('afterRemove', refresh);
|
||||||
return {
|
return {
|
||||||
designable,
|
designable,
|
||||||
|
Loading…
Reference in New Issue
Block a user