@tmagic/editor 1.2.3 → 1.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.2.3",
2
+ "version": "1.2.5",
3
3
  "name": "@tmagic/editor",
4
4
  "type": "module",
5
5
  "sideEffects": [
@@ -46,12 +46,12 @@
46
46
  "dependencies": {
47
47
  "@babel/core": "^7.18.0",
48
48
  "@element-plus/icons-vue": "^2.0.9",
49
- "@tmagic/core": "1.2.3",
50
- "@tmagic/design": "1.2.3",
51
- "@tmagic/form": "1.2.3",
52
- "@tmagic/schema": "1.2.3",
53
- "@tmagic/stage": "1.2.3",
54
- "@tmagic/utils": "1.2.3",
49
+ "@tmagic/core": "1.2.5",
50
+ "@tmagic/design": "1.2.5",
51
+ "@tmagic/form": "1.2.5",
52
+ "@tmagic/schema": "1.2.5",
53
+ "@tmagic/stage": "1.2.5",
54
+ "@tmagic/utils": "1.2.5",
55
55
  "buffer": "^6.0.3",
56
56
  "color": "^3.1.3",
57
57
  "events": "^3.3.0",
@@ -63,8 +63,8 @@
63
63
  "vue": "^3.2.37"
64
64
  },
65
65
  "peerDependencies": {
66
- "@tmagic/design": "1.2.3",
67
- "@tmagic/form": "1.2.3",
66
+ "@tmagic/design": "1.2.5",
67
+ "@tmagic/form": "1.2.5",
68
68
  "monaco-editor": "^0.34.0",
69
69
  "vue": "^3.2.37"
70
70
  },
package/src/Editor.vue CHANGED
@@ -362,6 +362,8 @@ export default defineComponent({
362
362
  disabledDragStart: props.disabledDragStart,
363
363
  }),
364
364
  );
365
+ // 监听组件update
366
+ codeBlockService.addCodeRelationListener();
365
367
 
366
368
  return services;
367
369
  },
@@ -6,7 +6,12 @@
6
6
  type="card"
7
7
  tab-position="left"
8
8
  >
9
- <component :is="uiComponent.component" v-for="(config, index) in sideBarItems" :key="index" :name="config.text">
9
+ <component
10
+ :is="uiComponent.component"
11
+ v-for="(config, index) in sideBarItems"
12
+ :key="config.$key || index"
13
+ :name="config.text"
14
+ >
10
15
  <template #label>
11
16
  <div :key="config.text">
12
17
  <MIcon v-if="config.icon" :icon="config.icon"></MIcon>
@@ -96,7 +96,7 @@ import { ColumnConfig } from '@tmagic/form';
96
96
  import { CodeBlockContent, Id } from '@tmagic/schema';
97
97
 
98
98
  import Icon from '../../../components/Icon.vue';
99
- import type { CodeRelation, Services } from '../../../type';
99
+ import type { CodeRelation, CombineInfo, Services } from '../../../type';
100
100
  import { CodeDeleteErrorType, CodeDslItem, ListState } from '../../../type';
101
101
 
102
102
  import codeBlockEditor from './CodeBlockEditor.vue';
@@ -121,17 +121,22 @@ const isShowCodeBlockEditor = computed(() => services?.codeBlockService.getCodeE
121
121
  const codeCombineInfo = ref<CodeRelation | null>(null);
122
122
 
123
123
  // 根据代码块ID获取其绑定的组件信息
124
- const getBindCompsByCodeId = (codeId: Id) => {
125
- if (!codeCombineInfo.value || !codeCombineInfo.value[codeId]) return [];
126
- const bindCompsId = Object.keys(codeCombineInfo.value[codeId]);
127
- return bindCompsId.map((compId) => ({
128
- compId,
129
- compName: getCompName(compId),
130
- }));
124
+ const getBindCompsByCodeId = (codeId: Id): CombineInfo[] => {
125
+ if (!codeCombineInfo.value) return [];
126
+ const bindsComp = [] as CombineInfo[];
127
+ forIn(codeCombineInfo.value, (codeIds, compId) => {
128
+ if (codeIds.includes(codeId)) {
129
+ bindsComp.push({
130
+ compId,
131
+ compName: getCompName(compId),
132
+ });
133
+ }
134
+ });
135
+ return bindsComp as CombineInfo[];
131
136
  };
132
137
 
133
- // 初始化代码块列表
134
- const initList = async () => {
138
+ // 更新代码块列表
139
+ const refreshCodeList = async () => {
135
140
  const codeDsl = cloneDeep(await services?.codeBlockService.getCodeDsl()) || null;
136
141
  codeCombineInfo.value = cloneDeep(services?.codeBlockService.getCombineInfo()) || null;
137
142
  if (!codeDsl || !codeCombineInfo.value) return;
@@ -148,12 +153,19 @@ const initList = async () => {
148
153
  };
149
154
 
150
155
  watch(
151
- [() => services?.codeBlockService.getCodeDslSync(), () => services?.codeBlockService.refreshCombineInfo()],
156
+ () => services?.editorService.get('root'),
157
+ () => {
158
+ services?.codeBlockService.refreshAllRelations();
159
+ refreshCodeList();
160
+ },
161
+ );
162
+
163
+ watch(
164
+ [() => services?.codeBlockService.getCodeDslSync(), () => services?.codeBlockService.getCombineInfo()],
152
165
  () => {
153
- initList();
166
+ refreshCodeList();
154
167
  },
155
168
  {
156
- immediate: true,
157
169
  deep: true,
158
170
  },
159
171
  );
@@ -17,9 +17,9 @@
17
17
  */
18
18
 
19
19
  import { reactive } from 'vue';
20
- import { cloneDeep, forIn, isEmpty, keys, omit, pick } from 'lodash-es';
20
+ import { cloneDeep, forIn, isEmpty, keys, omit, pick, union } from 'lodash-es';
21
21
 
22
- import { CodeBlockContent, CodeBlockDSL, HookType, Id, MNode } from '@tmagic/schema';
22
+ import { CodeBlockContent, CodeBlockDSL, HookType, Id, MNode, MPage } from '@tmagic/schema';
23
23
 
24
24
  import editorService from '../services/editor';
25
25
  import type { CodeRelation, CodeState, HookData } from '../type';
@@ -230,16 +230,45 @@ class CodeBlock extends BaseService {
230
230
  }
231
231
 
232
232
  /**
233
- * 刷新绑定关系
234
- * @returns {CodeRelation | null}
233
+ * 监听组件更新来更新代码块绑定关系
234
+ * @returns {void}
235
235
  */
236
- public refreshCombineInfo(): CodeRelation | null {
236
+ public addCodeRelationListener(): void {
237
+ // 监听组件更新
238
+ editorService.on('update', (nodes: MNode[]) => {
239
+ const relations: CodeRelation = cloneDeep(this.state.relations);
240
+ nodes.forEach((node: MNode) => {
241
+ if (node?.id) {
242
+ relations[node.id] = [];
243
+ this.getNodeRelation(node, relations);
244
+ }
245
+ });
246
+ this.state.relations = { ...relations };
247
+ });
248
+ // 监听组件删除
249
+ editorService.on('remove', (nodes: MNode[]) => {
250
+ nodes.forEach((node: MNode) => {
251
+ this.state.relations = this.deleteNodeRelation(node, this.state.relations);
252
+ });
253
+ });
254
+ // 监听历史记录,历史快照为页面整体,需要深层遍历更新
255
+ editorService.on('history-change', (page: MPage) => {
256
+ const relations: CodeRelation = {};
257
+ this.getNodeRelation(page, relations, true);
258
+ this.state.relations = relations;
259
+ });
260
+ }
261
+
262
+ /**
263
+ * 更新全部绑定关系
264
+ * @returns {void}
265
+ */
266
+ public refreshAllRelations(): void {
237
267
  const root = editorService.get('root');
238
- if (!root) return null;
239
- const relations = {};
240
- this.recurseMNode(root, relations);
268
+ if (!root) return;
269
+ const relations: CodeRelation = {};
270
+ this.getNodeRelation(root, relations, true);
241
271
  this.state.relations = relations;
242
- return this.state.relations;
243
272
  }
244
273
 
245
274
  /**
@@ -313,18 +342,6 @@ class CodeBlock extends BaseService {
313
342
  return await this.getUniqueId();
314
343
  }
315
344
 
316
- /**
317
- * 通过组件id解除绑定关系(删除组件)
318
- * @param {MNode} compId 组件节点
319
- * @returns void
320
- */
321
- public async deleteCompsInRelation(node: MNode): Promise<void> {
322
- const codeDsl = cloneDeep(await this.getCodeDsl());
323
- if (!codeDsl) return;
324
- this.refreshRelationDeep(node, codeDsl);
325
- this.setCodeDsl(codeDsl);
326
- }
327
-
328
345
  public resetState() {
329
346
  this.state.isShowCodeEditor = false;
330
347
  this.state.codeDsl = null;
@@ -340,63 +357,63 @@ class CodeBlock extends BaseService {
340
357
  this.removeAllPlugins();
341
358
  }
342
359
 
343
- /**
344
- * 删除组件时 如果是容器 需要遍历删除其包含节点的绑定信息
345
- * @param {MNode} node 节点信息
346
- * @param {CodeBlockDSL} codeDsl 代码块
347
- * @returns void
348
- */
349
- private refreshRelationDeep(node: MNode, codeDsl: CodeBlockDSL): void {
350
- if (!node.id) return;
351
- forIn(codeDsl, (codeBlockContent) => {
352
- const compsContent = codeBlockContent.comps || {};
353
- codeBlockContent.comps = omit(compsContent, node.id);
354
- });
355
- if (!isEmpty(node.items)) {
356
- node.items.forEach((item: MNode) => {
357
- this.refreshRelationDeep(item, codeDsl);
358
- });
359
- }
360
- }
361
-
362
360
  /**
363
361
  * 递归遍历dsl中挂载了代码块的节点,并更新绑定关系数据
364
- * @param {MContainer} node 节点信息
362
+ * @param {MNode} node 节点信息
363
+ * @param {CodeRelation} relation 关系数据
364
+ * @param {boolean} deep 是否深层遍历
365
365
  * @returns void
366
366
  */
367
- private recurseMNode(node: MNode, relations: CodeRelation): void {
367
+ private getNodeRelation(node: MNode, relation: CodeRelation, deep = false): void {
368
368
  forIn(node, (value, key) => {
369
- let unConfirmedValue: MNode = { id: node.id };
370
369
  if (value?.hookType === HookType.CODE && !isEmpty(value.hookData)) {
371
370
  value.hookData.forEach((relationItem: HookData) => {
372
- // continue
373
- if (!relationItem.codeId) return;
374
- if (!relations[relationItem.codeId]) {
375
- relations[relationItem.codeId] = {};
371
+ if (relationItem.codeId) {
372
+ relation[node.id] = union(relation[node.id], [relationItem.codeId]);
376
373
  }
377
- const codeItem = relations[relationItem.codeId];
378
- if (isEmpty(codeItem[node.id])) {
379
- codeItem[node.id] = [];
380
- }
381
- codeItem[node.id].push(key);
382
374
  });
383
375
  // continue
384
376
  return;
385
377
  }
386
- if (typeof value === 'object') {
378
+ let isContinue = false;
379
+ try {
380
+ // 只遍历更新当前组件的关系,不再深层遍历容器包含的组件
381
+ isContinue = key !== 'items' && typeof value === 'object' && JSON.stringify(value).includes('hookType');
382
+ } catch (error) {
383
+ console.error(error);
384
+ }
385
+ if (isContinue) {
387
386
  // 检查value内部是否有嵌套
388
- unConfirmedValue = {
389
- ...unConfirmedValue,
387
+ const unConfirmedValue = {
388
+ id: node.id,
390
389
  ...value,
391
390
  };
392
- this.recurseMNode(unConfirmedValue, relations);
391
+ this.getNodeRelation(unConfirmedValue, relation);
392
+ }
393
+ // 深层遍历用于代码列表初始化
394
+ if (key === 'items' && !isEmpty(value) && deep) {
395
+ value.forEach((item: MNode) => {
396
+ this.getNodeRelation(item, relation, deep);
397
+ });
393
398
  }
394
399
  });
400
+ }
401
+
402
+ /**
403
+ * 删除组件关系
404
+ * @param {MNode} node 节点信息
405
+ * @param {CodeRelation} relations 关系数据
406
+ * @returns CodeRelation
407
+ */
408
+ private deleteNodeRelation(node: MNode, relations: CodeRelation): CodeRelation {
409
+ if (!node.id) return {};
410
+ let newRelations = omit(relations, [node.id]);
395
411
  if (!isEmpty(node.items)) {
396
412
  node.items.forEach((item: MNode) => {
397
- this.recurseMNode(item, relations);
413
+ newRelations = this.deleteNodeRelation(item, newRelations);
398
414
  });
399
415
  }
416
+ return newRelations;
400
417
  }
401
418
  }
402
419
 
@@ -24,7 +24,6 @@ import { NodeType } from '@tmagic/schema';
24
24
  import StageCore from '@tmagic/stage';
25
25
  import { getNodePath, isNumber, isPage, isPop } from '@tmagic/utils';
26
26
 
27
- import codeBlockService from '../services/codeBlock';
28
27
  import historyService from '../services/history';
29
28
  import storageService, { Protocol } from '../services/storage';
30
29
  import type { AddMNode, EditorNodeInfo, PastePosition, StepValue, StoreState, StoreStateKey } from '../type';
@@ -452,9 +451,6 @@ class Editor extends BaseService {
452
451
  }
453
452
 
454
453
  this.addModifiedNodeId(parent.id);
455
-
456
- // 通知codeBlockService解除绑定关系
457
- codeBlockService.deleteCompsInRelation(node);
458
454
  }
459
455
 
460
456
  /**
@@ -555,7 +551,6 @@ class Editor extends BaseService {
555
551
  this.pushHistoryState();
556
552
 
557
553
  this.emit('update', newNodes);
558
- codeBlockService.refreshCombineInfo();
559
554
  return Array.isArray(config) ? newNodes : newNodes[0];
560
555
  }
561
556
 
@@ -891,6 +886,7 @@ class Editor extends BaseService {
891
886
  await this.select(value.nodeId);
892
887
  this.get('stage')?.select(value.nodeId);
893
888
  }, 0);
889
+ this.emit('history-change', value.data);
894
890
  }
895
891
 
896
892
  private async toggleFixedPosition(dist: MNode, src: MNode, root: MApp) {
package/src/type.ts CHANGED
@@ -351,10 +351,8 @@ export type HookData = {
351
351
  };
352
352
 
353
353
  export type CodeRelation = {
354
- [codeId: Id]: {
355
- /** 组件id:['created'] */
356
- [compId: Id]: string[];
357
- };
354
+ /** 组件id:[代码id1,代码id2] */
355
+ [compId: Id]: Id[];
358
356
  };
359
357
 
360
358
  export interface CodeDslItem {
@@ -1,4 +1,4 @@
1
- import { CodeBlockContent, CodeBlockDSL, Id, MNode } from '@tmagic/schema';
1
+ import { CodeBlockContent, CodeBlockDSL, Id } from '@tmagic/schema';
2
2
  import type { CodeRelation } from '../type';
3
3
  import BaseService from './BaseService';
4
4
  declare class CodeBlock extends BaseService {
@@ -94,10 +94,15 @@ declare class CodeBlock extends BaseService {
94
94
  */
95
95
  getCombineIds(): string[];
96
96
  /**
97
- * 刷新绑定关系
98
- * @returns {CodeRelation | null}
97
+ * 监听组件更新来更新代码块绑定关系
98
+ * @returns {void}
99
+ */
100
+ addCodeRelationListener(): void;
101
+ /**
102
+ * 更新全部绑定关系
103
+ * @returns {void}
99
104
  */
100
- refreshCombineInfo(): CodeRelation | null;
105
+ refreshAllRelations(): void;
101
106
  /**
102
107
  * 获取绑定关系
103
108
  * @returns {CodeRelation}
@@ -137,27 +142,23 @@ declare class CodeBlock extends BaseService {
137
142
  * @returns {Id} 代码块唯一id
138
143
  */
139
144
  getUniqueId(): Promise<Id>;
140
- /**
141
- * 通过组件id解除绑定关系(删除组件)
142
- * @param {MNode} compId 组件节点
143
- * @returns void
144
- */
145
- deleteCompsInRelation(node: MNode): Promise<void>;
146
145
  resetState(): void;
147
146
  destroy(): void;
148
147
  /**
149
- * 删除组件时 如果是容器 需要遍历删除其包含节点的绑定信息
148
+ * 递归遍历dsl中挂载了代码块的节点,并更新绑定关系数据
150
149
  * @param {MNode} node 节点信息
151
- * @param {CodeBlockDSL} codeDsl 代码块
150
+ * @param {CodeRelation} relation 关系数据
151
+ * @param {boolean} deep 是否深层遍历
152
152
  * @returns void
153
153
  */
154
- private refreshRelationDeep;
154
+ private getNodeRelation;
155
155
  /**
156
- * 递归遍历dsl中挂载了代码块的节点,并更新绑定关系数据
157
- * @param {MContainer} node 节点信息
158
- * @returns void
156
+ * 删除组件关系
157
+ * @param {MNode} node 节点信息
158
+ * @param {CodeRelation} relations 关系数据
159
+ * @returns CodeRelation
159
160
  */
160
- private recurseMNode;
161
+ private deleteNodeRelation;
161
162
  }
162
163
  export declare type CodeBlockService = CodeBlock;
163
164
  declare const _default: CodeBlock;
package/types/type.d.ts CHANGED
@@ -278,10 +278,8 @@ export declare type HookData = {
278
278
  params?: object;
279
279
  };
280
280
  export declare type CodeRelation = {
281
- [codeId: Id]: {
282
- /** 组件id:['created'] */
283
- [compId: Id]: string[];
284
- };
281
+ /** 组件id:[代码id1,代码id2] */
282
+ [compId: Id]: Id[];
285
283
  };
286
284
  export interface CodeDslItem {
287
285
  /** 代码块id */