Skip to content

Commit

Permalink
feat: 添加组件支持添加组合
Browse files Browse the repository at this point in the history
  • Loading branch information
roymondchen authored and jia000 committed Jun 13, 2022
1 parent c8c692b commit 5e31257
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 120 deletions.
3 changes: 1 addition & 2 deletions packages/editor/src/services/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ import {
initPosition,
isFixed,
setLayout,
setNewItemId,
} from '@editor/utils/editor';
import { log } from '@editor/utils/logger';

Expand Down Expand Up @@ -495,7 +494,7 @@ class Editor extends BaseService {
return;
}

setNewItemId(config, this.get('root'));
await propsService.setNewItemId(config, this.get('root'));
if (config.style) {
config.style = {
...config.style,
Expand Down
69 changes: 62 additions & 7 deletions packages/editor/src/services/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@
*/

import { reactive } from 'vue';
import { cloneDeep, mergeWith } from 'lodash-es';
import { cloneDeep, mergeWith, random } from 'lodash-es';

import type { FormConfig } from '@tmagic/form';
import type { MComponent, MNode } from '@tmagic/schema';
import { toLine } from '@tmagic/utils';
import type { Id, MComponent, MNode, MPage } from '@tmagic/schema';
import { NodeType } from '@tmagic/schema';
import { isPop, toLine } from '@tmagic/utils';

import type { PropsState } from '@editor/type';
import { DEFAULT_CONFIG, fillConfig, getDefaultPropsValue } from '@editor/utils/props';
Expand All @@ -35,7 +36,7 @@ class Props extends BaseService {
});

constructor() {
super(['setPropsConfig', 'getPropsConfig', 'setPropsValue', 'getPropsValue']);
super(['setPropsConfig', 'getPropsConfig', 'setPropsValue', 'getPropsValue', 'createId', 'setNewItemId']);
}

public setPropsConfigs(configs: Record<string, FormConfig>) {
Expand Down Expand Up @@ -87,7 +88,7 @@ class Props extends BaseService {
* @param type 组件类型
* @returns 组件初始值
*/
public async getPropsValue(type: string, defaultValue = {}) {
public async getPropsValue(type: string, defaultValue: Record<string, any> = {}) {
if (type === 'area') {
const value = (await this.getPropsValue('button')) as MComponent;
value.className = 'action-area';
Expand All @@ -98,13 +99,67 @@ class Props extends BaseService {
return value;
}

const data = cloneDeep(defaultValue as any);

await this.setNewItemId(data);

return {
...getDefaultPropsValue(type),
...mergeWith(cloneDeep(this.state.propsValueMap[type] || {}), cloneDeep(defaultValue)),
...getDefaultPropsValue(type, await this.createId(type)),
...mergeWith(cloneDeep(this.state.propsValueMap[type] || {}), data),
};
}

public async createId(type: string | number): Promise<string> {
return `${type}_${random(10000, false)}`;
}

/**
* 将组件与组件的子元素配置中的id都设置成一个新的ID
* @param {Object} config 组件配置
*/
/* eslint no-param-reassign: ["error", { "props": false }] */
public async setNewItemId(config: MNode, parent?: MPage) {
const oldId = config.id;

config.id = await this.createId(config.type || 'component');

// 只有弹窗在页面下的一级子元素才有效
if (isPop(config) && parent?.type === NodeType.PAGE) {
updatePopId(oldId, config.id, parent);
}

if (config.items && Array.isArray(config.items)) {
for (const item of config.items) {
await this.setNewItemId(item, config as MPage);
}
}
}
}

/**
* 复制页面时,需要把组件下关联的弹窗id换测复制出来的弹窗的id
* @param {number} oldId 复制的源弹窗id
* @param {number} popId 新的弹窗id
* @param {Object} pageConfig 页面配置
*/
const updatePopId = (oldId: Id, popId: Id, pageConfig: MPage) => {
pageConfig.items?.forEach((config) => {
if (config.pop === oldId) {
config.pop = popId;
return;
}

if (config.popId === oldId) {
config.popId = popId;
return;
}

if (Array.isArray(config.items)) {
updatePopId(oldId, popId, config as MPage);
}
});
};

export type PropsService = Props;

export default new Props();
51 changes: 1 addition & 50 deletions packages/editor/src/utils/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@
* limitations under the License.
*/

import { random } from 'lodash-es';

import type { Id, MApp, MContainer, MNode, MPage } from '@tmagic/schema';
import type { MApp, MContainer, MNode, MPage } from '@tmagic/schema';
import { NodeType } from '@tmagic/schema';
import type StageCore from '@tmagic/stage';
import { getNodePath, isNumber, isPage, isPop } from '@tmagic/utils';
Expand All @@ -27,8 +25,6 @@ import { Layout } from '@editor/type';

export const COPY_STORAGE_KEY = '$MagicEditorCopyData';

export const generateId = (type: string | number): string => `${type}_${random(10000, false)}`;

/**
* 获取所有页面配置
* @param app DSL跟节点
Expand Down Expand Up @@ -74,51 +70,6 @@ export const generatePageName = (pageNameList: string[]): string => {
*/
export const generatePageNameByApp = (app: MApp): string => generatePageName(getPageNameList(getPageList(app)));

/**
* 复制页面时,需要把组件下关联的弹窗id换测复制出来的弹窗的id
* @param {number} oldId 复制的源弹窗id
* @param {number} popId 新的弹窗id
* @param {Object} pageConfig 页面配置
*/
const updatePopId = (oldId: Id, popId: Id, pageConfig: MPage) => {
pageConfig.items?.forEach((config) => {
if (config.pop === oldId) {
config.pop = popId;
return;
}

if (config.popId === oldId) {
config.popId = popId;
return;
}

if (Array.isArray(config.items)) {
updatePopId(oldId, popId, config as MPage);
}
});
};

/**
* 将组件与组件的子元素配置中的id都设置成一个新的ID
* @param {Object} config 组件配置
*/
/* eslint no-param-reassign: ["error", { "props": false }] */
export const setNewItemId = (config: MNode, parent?: MPage) => {
const oldId = config.id;

config.id = generateId(config.type || 'component');
config.name = `${config.name?.replace(/_(\d+)$/, '')}_${config.id}`;

// 只有弹窗在页面下的一级子元素才有效
if (isPop(config) && parent?.type === NodeType.PAGE) {
updatePopId(oldId, config.id, parent);
}

if (config.items && Array.isArray(config.items)) {
config.items.forEach((item) => setNewItemId(item, config as MPage));
}
};

/**
* @param {Object} node
* @returns {boolean}
Expand Down
5 changes: 2 additions & 3 deletions packages/editor/src/utils/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import { FormConfig, FormState } from '@tmagic/form';

import editorService from '@editor/services/editor';
import eventsService from '@editor/services/events';
import { generateId } from '@editor/utils/editor';

/**
* 统一为组件属性表单加上事件、高级、样式配置
Expand Down Expand Up @@ -244,9 +243,9 @@ export const DEFAULT_CONFIG: FormConfig = fillConfig([]);
* @param type 组件类型
* @returns Object
*/
export const getDefaultPropsValue = (type: string) => ({
export const getDefaultPropsValue = (type: string, id: string) => ({
type,
id: generateId(type),
id,
style: {},
name: type,
});
63 changes: 63 additions & 0 deletions packages/editor/tests/unit/services/props.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { describe, expect, test } from 'vitest';

import { NodeType } from '@tmagic/schema';

import props from '@editor/services/props';

test('createId', async () => {
const id = await props.createId('text');

console.log(id);

expect(id.startsWith('text')).toBeTruthy();
});

describe('setNewItemId', () => {
test('普通', async () => {
const config = {
id: 1,
type: 'text',
};
// 将组件与组件的子元素配置中的id都设置成一个新的ID
await props.setNewItemId(config);
expect(config.id === 1).toBeFalsy();
});

test('items', async () => {
const config = {
id: 1,
type: NodeType.PAGE,
items: [
{
type: 'text',
id: 2,
},
],
};
await props.setNewItemId(config);
expect(config.id === 1).toBeFalsy();
expect(config.items[0].id === 2).toBeFalsy();
});

test('pop', async () => {
const config = {
id: 1,
type: NodeType.PAGE,
items: [
{
type: 'button',
id: 2,
pop: 3,
},
{
type: 'pop',
id: 3,
},
],
};
await props.setNewItemId(config);
expect(config.items[0].pop === 3).toBeFalsy();
expect(config.items[1].id === 3).toBeFalsy();
expect(config.items[1].id === config.items[0].pop).toBeTruthy();
});
});
56 changes: 0 additions & 56 deletions packages/editor/tests/unit/utils/editor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,6 @@ import { NodeType } from '@tmagic/schema';
import * as editor from '@editor/utils/editor';

describe('util form', () => {
test('generateId', () => {
const id = editor.generateId('text');

expect(id.startsWith('text')).toBeTruthy();
});

test('getPageList', () => {
const pageList = editor.getPageList({
id: 'app_1',
Expand Down Expand Up @@ -67,56 +61,6 @@ describe('util form', () => {
});
});

describe('setNewItemId', () => {
test('普通', () => {
const config = {
id: 1,
type: 'text',
};
// 将组件与组件的子元素配置中的id都设置成一个新的ID
editor.setNewItemId(config);
expect(config.id === 1).toBeFalsy();
});

test('items', () => {
const config = {
id: 1,
type: NodeType.PAGE,
items: [
{
type: 'text',
id: 2,
},
],
};
editor.setNewItemId(config);
expect(config.id === 1).toBeFalsy();
expect(config.items[0].id === 2).toBeFalsy();
});

test('pop', () => {
const config = {
id: 1,
type: NodeType.PAGE,
items: [
{
type: 'button',
id: 2,
pop: 3,
},
{
type: 'pop',
id: 3,
},
],
};
editor.setNewItemId(config);
expect(config.items[0].pop === 3).toBeFalsy();
expect(config.items[1].id === 3).toBeFalsy();
expect(config.items[1].id === config.items[0].pop).toBeTruthy();
});
});

describe('isFixed', () => {
test('true', () => {
expect(
Expand Down
5 changes: 3 additions & 2 deletions packages/editor/tests/unit/utils/form.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ describe('util form', () => {
});

test('getDefaultValue', () => {
const value = props.getDefaultPropsValue('text');
expect(value.id.startsWith('text')).toBeTruthy();
const value = props.getDefaultPropsValue('text', '1');
expect(value.id).toBe('1');
expect(value.type).toBe('text');
});
});

0 comments on commit 5e31257

Please sign in to comment.