@tmagic/editor 1.8.0-beta.2 → 1.8.0-beta.4

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.
Files changed (84) hide show
  1. package/dist/es/Editor.vue_vue_type_script_setup_true_lang.js +9 -0
  2. package/dist/es/components/CompareForm.vue_vue_type_script_setup_true_lang.js +46 -28
  3. package/dist/es/editorProps.js +2 -0
  4. package/dist/es/fields/CodeLink.vue_vue_type_script_setup_true_lang.js +2 -5
  5. package/dist/es/hooks/use-code-block-edit.js +6 -3
  6. package/dist/es/hooks/use-data-source-edit.js +5 -2
  7. package/dist/es/hooks/use-stage.js +8 -4
  8. package/dist/es/index.js +3 -1
  9. package/dist/es/layouts/CodeEditor.vue_vue_type_script_setup_true_lang.js +2 -5
  10. package/dist/es/layouts/NavMenu.vue_vue_type_script_setup_true_lang.js +1 -1
  11. package/dist/es/layouts/history-list/Bucket.vue_vue_type_script_setup_true_lang.js +37 -14
  12. package/dist/es/layouts/history-list/BucketTab.js +5 -0
  13. package/dist/es/layouts/history-list/{CodeBlockTab.vue_vue_type_script_setup_true_lang.js → BucketTab.vue_vue_type_script_setup_true_lang.js} +30 -16
  14. package/dist/es/layouts/history-list/GroupRow.vue_vue_type_script_setup_true_lang.js +91 -60
  15. package/dist/es/layouts/history-list/HistoryDiffDialog.vue_vue_type_script_setup_true_lang.js +82 -30
  16. package/dist/es/layouts/history-list/HistoryListPanel.vue_vue_type_script_setup_true_lang.js +140 -66
  17. package/dist/es/layouts/history-list/InitialRow.vue_vue_type_script_setup_true_lang.js +15 -9
  18. package/dist/es/layouts/history-list/PageTab.vue_vue_type_script_setup_true_lang.js +15 -6
  19. package/dist/es/layouts/history-list/composables.js +72 -2
  20. package/dist/es/layouts/props-panel/PropsPanel.vue_vue_type_script_setup_true_lang.js +5 -1
  21. package/dist/es/layouts/sidebar/ComponentListPanel.vue_vue_type_script_setup_true_lang.js +1 -1
  22. package/dist/es/layouts/sidebar/code-block/CodeBlockList.vue_vue_type_script_setup_true_lang.js +3 -3
  23. package/dist/es/layouts/sidebar/code-block/CodeBlockListPanel.vue_vue_type_script_setup_true_lang.js +1 -1
  24. package/dist/es/layouts/sidebar/code-block/useContentMenu.js +1 -1
  25. package/dist/es/layouts/sidebar/data-source/DataSourceListPanel.vue_vue_type_script_setup_true_lang.js +1 -1
  26. package/dist/es/layouts/sidebar/data-source/useContentMenu.js +1 -1
  27. package/dist/es/layouts/sidebar/layer/LayerMenu.vue_vue_type_script_setup_true_lang.js +5 -5
  28. package/dist/es/layouts/sidebar/layer/LayerNodeTool.vue_vue_type_script_setup_true_lang.js +1 -1
  29. package/dist/es/layouts/workspace/viewer/Stage.vue_vue_type_script_setup_true_lang.js +1 -1
  30. package/dist/es/layouts/workspace/viewer/ViewerMenu.vue_vue_type_script_setup_true_lang.js +8 -8
  31. package/dist/es/services/codeBlock.js +25 -10
  32. package/dist/es/services/dataSource.js +24 -10
  33. package/dist/es/services/editor.js +98 -46
  34. package/dist/es/services/history.js +7 -2
  35. package/dist/es/services/keybinding.js +3 -3
  36. package/dist/es/style.css +60 -16
  37. package/dist/es/utils/content-menu.js +17 -9
  38. package/dist/style.css +60 -16
  39. package/dist/tmagic-editor.umd.cjs +795 -443
  40. package/package.json +7 -7
  41. package/src/Editor.vue +8 -0
  42. package/src/components/CompareForm.vue +50 -19
  43. package/src/editorProps.ts +7 -0
  44. package/src/fields/CodeLink.vue +2 -5
  45. package/src/hooks/use-code-block-edit.ts +4 -3
  46. package/src/hooks/use-data-source-edit.ts +2 -2
  47. package/src/hooks/use-stage.ts +4 -3
  48. package/src/index.ts +2 -0
  49. package/src/layouts/CodeEditor.vue +2 -5
  50. package/src/layouts/NavMenu.vue +1 -1
  51. package/src/layouts/history-list/Bucket.vue +58 -29
  52. package/src/layouts/history-list/BucketTab.vue +80 -0
  53. package/src/layouts/history-list/GroupRow.vue +110 -58
  54. package/src/layouts/history-list/HistoryDiffDialog.vue +53 -33
  55. package/src/layouts/history-list/HistoryListPanel.vue +165 -52
  56. package/src/layouts/history-list/InitialRow.vue +17 -6
  57. package/src/layouts/history-list/PageTab.vue +25 -7
  58. package/src/layouts/history-list/composables.ts +92 -1
  59. package/src/layouts/props-panel/PropsPanel.vue +5 -1
  60. package/src/layouts/sidebar/ComponentListPanel.vue +9 -5
  61. package/src/layouts/sidebar/code-block/CodeBlockList.vue +5 -5
  62. package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +1 -1
  63. package/src/layouts/sidebar/code-block/useContentMenu.ts +1 -1
  64. package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +1 -1
  65. package/src/layouts/sidebar/data-source/useContentMenu.ts +1 -1
  66. package/src/layouts/sidebar/layer/LayerMenu.vue +19 -11
  67. package/src/layouts/sidebar/layer/LayerNodeTool.vue +7 -4
  68. package/src/layouts/workspace/viewer/Stage.vue +1 -1
  69. package/src/layouts/workspace/viewer/ViewerMenu.vue +8 -8
  70. package/src/services/codeBlock.ts +33 -9
  71. package/src/services/dataSource.ts +30 -8
  72. package/src/services/editor.ts +111 -34
  73. package/src/services/history.ts +10 -0
  74. package/src/services/keybinding.ts +3 -3
  75. package/src/theme/history-list-panel.scss +67 -14
  76. package/src/theme/props-panel.scss +3 -3
  77. package/src/type.ts +146 -0
  78. package/src/utils/content-menu.ts +18 -9
  79. package/types/index.d.ts +387 -156
  80. package/dist/es/layouts/history-list/CodeBlockTab.js +0 -5
  81. package/dist/es/layouts/history-list/DataSourceTab.js +0 -5
  82. package/dist/es/layouts/history-list/DataSourceTab.vue_vue_type_script_setup_true_lang.js +0 -62
  83. package/src/layouts/history-list/CodeBlockTab.vue +0 -61
  84. package/src/layouts/history-list/DataSourceTab.vue +0 -61
@@ -129,7 +129,7 @@ const removeHandler = async (id: string) => {
129
129
  type: 'warning',
130
130
  });
131
131
 
132
- dataSourceService.remove(id);
132
+ dataSourceService.remove(id, { historySource: 'tree-contextmenu' });
133
133
  };
134
134
 
135
135
  const dataSourceListRef = useTemplateRef<InstanceType<typeof DataSourceList>>('dataSourceList');
@@ -39,7 +39,7 @@ export const useContentMenu = () => {
39
39
  return;
40
40
  }
41
41
 
42
- dataSourceService.add(cloneDeep(ds));
42
+ dataSourceService.add(cloneDeep(ds), { historySource: 'tree-contextmenu' });
43
43
  },
44
44
  },
45
45
  {
@@ -41,11 +41,15 @@ const createMenuItems = (group: ComponentGroup): MenuButton[] =>
41
41
  type: 'button',
42
42
  icon: component.icon,
43
43
  handler: () => {
44
- editorService.add({
45
- name: component.text,
46
- type: component.type,
47
- ...(component.data || {}),
48
- });
44
+ editorService.add(
45
+ {
46
+ name: component.text,
47
+ type: component.type,
48
+ ...(component.data || {}),
49
+ },
50
+ undefined,
51
+ { historySource: 'tree-contextmenu' },
52
+ );
49
53
  },
50
54
  }));
51
55
 
@@ -57,9 +61,13 @@ const getSubMenuData = computed<MenuButton[]>(() => {
57
61
  type: 'button',
58
62
  icon: Files,
59
63
  handler: () => {
60
- editorService.add({
61
- type: 'tab-pane',
62
- });
64
+ editorService.add(
65
+ {
66
+ type: 'tab-pane',
67
+ },
68
+ undefined,
69
+ { historySource: 'tree-contextmenu' },
70
+ );
63
71
  },
64
72
  },
65
73
  ];
@@ -106,9 +114,9 @@ const menuData = computed<(MenuButton | MenuComponent)[]>(() =>
106
114
  items: getSubMenuData.value,
107
115
  },
108
116
  useCopyMenu(),
109
- usePasteMenu(),
110
- useDeleteMenu(),
111
- useMoveToMenu(services),
117
+ usePasteMenu('tree-contextmenu'),
118
+ useDeleteMenu('tree-contextmenu'),
119
+ useMoveToMenu(services, 'tree-contextmenu'),
112
120
  ...props.layerContentMenu,
113
121
  ],
114
122
  'layer',
@@ -25,9 +25,12 @@ const props = defineProps<{
25
25
  const { editorService } = useServices();
26
26
 
27
27
  const setNodeVisible = (visible: boolean) => {
28
- editorService.update({
29
- id: props.data.id,
30
- visible,
31
- });
28
+ editorService.update(
29
+ {
30
+ id: props.data.id,
31
+ visible,
32
+ },
33
+ { historySource: 'tree' },
34
+ );
32
35
  };
33
36
  </script>
@@ -380,7 +380,7 @@ const dropHandler = async (e: DragEvent) => {
380
380
 
381
381
  config.data.inputEvent = e;
382
382
 
383
- editorService.add(config.data, parent);
383
+ editorService.add(config.data, parent, { historySource: 'component-panel' });
384
384
  }
385
385
  };
386
386
  </script>
@@ -49,11 +49,11 @@ const menuData = computed<(MenuButton | MenuComponent)[]>(() =>
49
49
  display: () => canCenter.value,
50
50
  handler: () => {
51
51
  if (!nodes.value) return;
52
- editorService.alignCenter(nodes.value);
52
+ editorService.alignCenter(nodes.value, { historySource: 'stage-contextmenu' });
53
53
  },
54
54
  },
55
55
  useCopyMenu(),
56
- usePasteMenu(menuRef),
56
+ usePasteMenu('stage-contextmenu', menuRef),
57
57
  {
58
58
  type: 'divider',
59
59
  direction: 'horizontal',
@@ -68,7 +68,7 @@ const menuData = computed<(MenuButton | MenuComponent)[]>(() =>
68
68
  icon: markRaw(Top),
69
69
  display: () => !isPage(node.value) && !isPageFragment(node.value) && !props.isMultiSelect,
70
70
  handler: () => {
71
- editorService.moveLayer(1);
71
+ editorService.moveLayer(1, { historySource: 'stage-contextmenu' });
72
72
  },
73
73
  },
74
74
  {
@@ -77,7 +77,7 @@ const menuData = computed<(MenuButton | MenuComponent)[]>(() =>
77
77
  icon: markRaw(Bottom),
78
78
  display: () => !isPage(node.value) && !isPageFragment(node.value) && !props.isMultiSelect,
79
79
  handler: () => {
80
- editorService.moveLayer(-1);
80
+ editorService.moveLayer(-1, { historySource: 'stage-contextmenu' });
81
81
  },
82
82
  },
83
83
  {
@@ -86,7 +86,7 @@ const menuData = computed<(MenuButton | MenuComponent)[]>(() =>
86
86
  icon: markRaw(Top),
87
87
  display: () => !isPage(node.value) && !isPageFragment(node.value) && !props.isMultiSelect,
88
88
  handler: () => {
89
- editorService.moveLayer(LayerOffset.TOP);
89
+ editorService.moveLayer(LayerOffset.TOP, { historySource: 'stage-contextmenu' });
90
90
  },
91
91
  },
92
92
  {
@@ -95,16 +95,16 @@ const menuData = computed<(MenuButton | MenuComponent)[]>(() =>
95
95
  icon: markRaw(Bottom),
96
96
  display: () => !isPage(node.value) && !isPageFragment(node.value) && !props.isMultiSelect,
97
97
  handler: () => {
98
- editorService.moveLayer(LayerOffset.BOTTOM);
98
+ editorService.moveLayer(LayerOffset.BOTTOM, { historySource: 'stage-contextmenu' });
99
99
  },
100
100
  },
101
- useMoveToMenu(services),
101
+ useMoveToMenu(services, 'stage-contextmenu'),
102
102
  {
103
103
  type: 'divider',
104
104
  direction: 'horizontal',
105
105
  display: () => !isPage(node.value) && !isPageFragment(node.value) && !props.isMultiSelect,
106
106
  },
107
- useDeleteMenu(),
107
+ useDeleteMenu('stage-contextmenu'),
108
108
  {
109
109
  type: 'divider',
110
110
  direction: 'horizontal',
@@ -120,9 +120,19 @@ class CodeBlock extends BaseService {
120
120
  public async setCodeDslById(
121
121
  id: Id,
122
122
  codeConfig: Partial<CodeBlockContent>,
123
- { changeRecords, doNotPushHistory = false }: HistoryOpOptionsWithChangeRecords = {},
123
+ {
124
+ changeRecords,
125
+ doNotPushHistory = false,
126
+ historyDescription,
127
+ historySource,
128
+ }: HistoryOpOptionsWithChangeRecords = {},
124
129
  ): Promise<void> {
125
- this.setCodeDslByIdSync(id, codeConfig, true, { changeRecords, doNotPushHistory });
130
+ this.setCodeDslByIdSync(id, codeConfig, true, {
131
+ changeRecords,
132
+ doNotPushHistory,
133
+ historyDescription,
134
+ historySource,
135
+ });
126
136
  }
127
137
 
128
138
  /**
@@ -141,7 +151,12 @@ class CodeBlock extends BaseService {
141
151
  id: Id,
142
152
  codeConfig: Partial<CodeBlockContent>,
143
153
  force = true,
144
- { changeRecords, doNotPushHistory = false, historyDescription }: HistoryOpOptionsWithChangeRecords = {},
154
+ {
155
+ changeRecords,
156
+ doNotPushHistory = false,
157
+ historyDescription,
158
+ historySource,
159
+ }: HistoryOpOptionsWithChangeRecords = {},
145
160
  ): void {
146
161
  const codeDsl = this.getCodeDsl();
147
162
 
@@ -172,7 +187,13 @@ class CodeBlock extends BaseService {
172
187
  const newContent = cloneDeep(codeDsl[id]);
173
188
 
174
189
  if (!doNotPushHistory) {
175
- historyService.pushCodeBlock(id, { oldContent, newContent, changeRecords, historyDescription });
190
+ historyService.pushCodeBlock(id, {
191
+ oldContent,
192
+ newContent,
193
+ changeRecords,
194
+ historyDescription,
195
+ source: historySource,
196
+ });
176
197
  }
177
198
 
178
199
  this.emit('addOrUpdate', id, codeDsl[id]);
@@ -268,7 +289,7 @@ class CodeBlock extends BaseService {
268
289
  */
269
290
  public async deleteCodeDslByIds(
270
291
  codeIds: Id[],
271
- { doNotPushHistory = false, historyDescription }: HistoryOpOptions = {},
292
+ { doNotPushHistory = false, historyDescription, historySource }: HistoryOpOptions = {},
272
293
  ): Promise<void> {
273
294
  const currentDsl = await this.getCodeDsl();
274
295
 
@@ -281,7 +302,7 @@ class CodeBlock extends BaseService {
281
302
  delete currentDsl[id];
282
303
 
283
304
  if (oldContent && !doNotPushHistory) {
284
- historyService.pushCodeBlock(id, { oldContent, newContent: null, historyDescription });
305
+ historyService.pushCodeBlock(id, { oldContent, newContent: null, historyDescription, source: historySource });
285
306
  }
286
307
 
287
308
  this.emit('remove', id);
@@ -373,6 +394,8 @@ class CodeBlock extends BaseService {
373
394
  const list = historyService.getCodeBlockStepList(id);
374
395
  const entry = list[index];
375
396
  if (!entry?.applied) return null;
397
+ // 更新类步骤(前后 content 都存在)必须带 changeRecords 才支持回滚,否则只能整内容替换,会冲掉后续无关变更。
398
+ if (entry.step.oldContent && entry.step.newContent && !entry.step.changeRecords?.length) return null;
376
399
  const description = `回滚 #${index + 1}: ${describeRevertCodeBlockStep(entry.step)}`;
377
400
  return await this.applyRevertStep(entry.step, description);
378
401
  }
@@ -471,13 +494,13 @@ class CodeBlock extends BaseService {
471
494
 
472
495
  // 原本是新增 → revert 即删除
473
496
  if (oldContent === null && newContent) {
474
- await this.deleteCodeDslByIds([id], { historyDescription });
497
+ await this.deleteCodeDslByIds([id], { historyDescription, historySource: 'rollback' });
475
498
  return historyService.getCodeBlockStepList(id).slice(-1)[0]?.step ?? null;
476
499
  }
477
500
 
478
501
  // 原本是删除 → revert 即写回
479
502
  if (oldContent && newContent === null) {
480
- this.setCodeDslByIdSync(id, cloneDeep(oldContent), true, { historyDescription });
503
+ this.setCodeDslByIdSync(id, cloneDeep(oldContent), true, { historyDescription, historySource: 'rollback' });
481
504
  return historyService.getCodeBlockStepList(id).slice(-1)[0]?.step ?? null;
482
505
  }
483
506
 
@@ -500,11 +523,12 @@ class CodeBlock extends BaseService {
500
523
  this.setCodeDslByIdSync(id, fallbackToFullReplace ? cloneDeep(oldContent) : patched, true, {
501
524
  changeRecords,
502
525
  historyDescription,
526
+ historySource: 'rollback',
503
527
  });
504
528
  return historyService.getCodeBlockStepList(id).slice(-1)[0]?.step ?? null;
505
529
  }
506
530
 
507
- this.setCodeDslByIdSync(id, cloneDeep(oldContent), true, { historyDescription });
531
+ this.setCodeDslByIdSync(id, cloneDeep(oldContent), true, { historyDescription, historySource: 'rollback' });
508
532
  return historyService.getCodeBlockStepList(id).slice(-1)[0]?.step ?? null;
509
533
  }
510
534
 
@@ -129,7 +129,10 @@ class DataSource extends BaseService {
129
129
  * @param options.doNotPushHistory 是否不写入历史记录(默认 false)
130
130
  * @param options.historyDescription 入栈时附带的人类可读描述,用于历史面板展示
131
131
  */
132
- public add(config: DataSourceSchema, { doNotPushHistory = false, historyDescription }: HistoryOpOptions = {}) {
132
+ public add(
133
+ config: DataSourceSchema,
134
+ { doNotPushHistory = false, historyDescription, historySource }: HistoryOpOptions = {},
135
+ ) {
133
136
  const newConfig = {
134
137
  ...config,
135
138
  id: config.id && !this.getDataSourceById(config.id) ? config.id : this.createId(),
@@ -138,7 +141,12 @@ class DataSource extends BaseService {
138
141
  this.get('dataSources').push(newConfig);
139
142
 
140
143
  if (!doNotPushHistory) {
141
- historyService.pushDataSource(newConfig.id, { oldSchema: null, newSchema: newConfig, historyDescription });
144
+ historyService.pushDataSource(newConfig.id, {
145
+ oldSchema: null,
146
+ newSchema: newConfig,
147
+ historyDescription,
148
+ source: historySource,
149
+ });
142
150
  }
143
151
 
144
152
  this.emit('add', newConfig);
@@ -156,7 +164,12 @@ class DataSource extends BaseService {
156
164
  */
157
165
  public update(
158
166
  config: DataSourceSchema,
159
- { changeRecords = [], doNotPushHistory = false, historyDescription }: HistoryOpOptionsWithChangeRecords = {},
167
+ {
168
+ changeRecords = [],
169
+ doNotPushHistory = false,
170
+ historyDescription,
171
+ historySource,
172
+ }: HistoryOpOptionsWithChangeRecords = {},
160
173
  ) {
161
174
  const dataSources = this.get('dataSources');
162
175
 
@@ -173,6 +186,7 @@ class DataSource extends BaseService {
173
186
  newSchema: newConfig,
174
187
  changeRecords,
175
188
  historyDescription,
189
+ source: historySource,
176
190
  });
177
191
  }
178
192
 
@@ -191,14 +205,19 @@ class DataSource extends BaseService {
191
205
  * @param options.doNotPushHistory 是否不写入历史记录(默认 false)
192
206
  * @param options.historyDescription 入栈时附带的人类可读描述,用于历史面板展示
193
207
  */
194
- public remove(id: string, { doNotPushHistory = false, historyDescription }: HistoryOpOptions = {}) {
208
+ public remove(id: string, { doNotPushHistory = false, historyDescription, historySource }: HistoryOpOptions = {}) {
195
209
  const dataSources = this.get('dataSources');
196
210
  const index = dataSources.findIndex((ds) => ds.id === id);
197
211
  const oldConfig = index !== -1 ? dataSources[index] : null;
198
212
  dataSources.splice(index, 1);
199
213
 
200
214
  if (oldConfig && !doNotPushHistory) {
201
- historyService.pushDataSource(id, { oldSchema: cloneDeep(oldConfig), newSchema: null, historyDescription });
215
+ historyService.pushDataSource(id, {
216
+ oldSchema: cloneDeep(oldConfig),
217
+ newSchema: null,
218
+ historyDescription,
219
+ source: historySource,
220
+ });
202
221
  }
203
222
 
204
223
  this.emit('remove', id);
@@ -278,6 +297,8 @@ class DataSource extends BaseService {
278
297
  const list = historyService.getDataSourceStepList(id);
279
298
  const entry = list[index];
280
299
  if (!entry?.applied) return null;
300
+ // 更新类步骤(前后 schema 都存在)必须带 changeRecords 才支持回滚,否则只能整 schema 替换,会冲掉后续无关变更。
301
+ if (entry.step.oldSchema && entry.step.newSchema && !entry.step.changeRecords?.length) return null;
281
302
  const description = `回滚 #${index + 1}: ${describeRevertDataSourceStep(entry.step)}`;
282
303
  return this.applyRevertStep(entry.step, description);
283
304
  }
@@ -366,13 +387,13 @@ class DataSource extends BaseService {
366
387
 
367
388
  // 原本是新增 → revert 即删除
368
389
  if (oldSchema === null && newSchema) {
369
- this.remove(`${id}`, { historyDescription });
390
+ this.remove(`${id}`, { historyDescription, historySource: 'rollback' });
370
391
  return historyService.getDataSourceStepList(id).slice(-1)[0]?.step ?? null;
371
392
  }
372
393
 
373
394
  // 原本是删除 → revert 即重新加回
374
395
  if (oldSchema && newSchema === null) {
375
- this.add(cloneDeep(oldSchema), { historyDescription });
396
+ this.add(cloneDeep(oldSchema), { historyDescription, historySource: 'rollback' });
376
397
  return historyService.getDataSourceStepList(id).slice(-1)[0]?.step ?? null;
377
398
  }
378
399
 
@@ -395,11 +416,12 @@ class DataSource extends BaseService {
395
416
  this.update(fallbackToFullReplace ? cloneDeep(oldSchema) : patched, {
396
417
  changeRecords,
397
418
  historyDescription,
419
+ historySource: 'rollback',
398
420
  });
399
421
  return historyService.getDataSourceStepList(id).slice(-1)[0]?.step ?? null;
400
422
  }
401
423
 
402
- this.update(cloneDeep(oldSchema), { historyDescription });
424
+ this.update(cloneDeep(oldSchema), { historyDescription, historySource: 'rollback' });
403
425
  return historyService.getDataSourceStepList(id).slice(-1)[0]?.step ?? null;
404
426
  }
405
427