@tmagic/editor 1.4.16 → 1.5.0-beta.1

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 (140) hide show
  1. package/dist/style.css +11 -7
  2. package/dist/tmagic-editor.js +434 -411
  3. package/dist/tmagic-editor.umd.cjs +441 -408
  4. package/package.json +11 -15
  5. package/src/components/CodeParams.vue +1 -1
  6. package/src/editorProps.ts +2 -1
  7. package/src/fields/DataSourceInput.vue +2 -2
  8. package/src/fields/UISelect.vue +20 -15
  9. package/src/hooks/index.ts +7 -0
  10. package/src/hooks/use-stage.ts +13 -7
  11. package/src/index.ts +2 -0
  12. package/src/initService.ts +50 -53
  13. package/src/layouts/sidebar/Sidebar.vue +18 -2
  14. package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +12 -14
  15. package/src/layouts/workspace/viewer/NodeListMenu.vue +2 -1
  16. package/src/layouts/workspace/viewer/Stage.vue +4 -3
  17. package/src/services/editor.ts +2 -2
  18. package/src/services/stageOverlay.ts +3 -1
  19. package/src/theme/data-source.scss +8 -5
  20. package/src/theme/page-bar.scss +2 -2
  21. package/src/utils/data-source/index.ts +25 -23
  22. package/src/utils/editor.ts +4 -3
  23. package/src/utils/index.ts +4 -0
  24. package/src/utils/operator.ts +3 -2
  25. package/src/utils/props.ts +2 -1
  26. package/types/index.d.ts +6685 -49
  27. package/src/shims-vue.d.ts +0 -6
  28. package/types/Editor.vue.d.ts +0 -2313
  29. package/types/components/CodeBlockEditor.vue.d.ts +0 -33
  30. package/types/components/CodeParams.vue.d.ts +0 -28
  31. package/types/components/ContentMenu.vue.d.ts +0 -81
  32. package/types/components/FloatingBox.vue.d.ts +0 -70
  33. package/types/components/Icon.vue.d.ts +0 -15
  34. package/types/components/Resizer.vue.d.ts +0 -16
  35. package/types/components/ScrollBar.vue.d.ts +0 -25
  36. package/types/components/ScrollViewer.vue.d.ts +0 -81
  37. package/types/components/SearchInput.vue.d.ts +0 -6
  38. package/types/components/SplitView.vue.d.ts +0 -72
  39. package/types/components/ToolButton.vue.d.ts +0 -41
  40. package/types/components/Tree.vue.d.ts +0 -83
  41. package/types/components/TreeNode.vue.d.ts +0 -83
  42. package/types/editorProps.d.ts +0 -111
  43. package/types/fields/Code.vue.d.ts +0 -44
  44. package/types/fields/CodeLink.vue.d.ts +0 -24
  45. package/types/fields/CodeSelect.vue.d.ts +0 -28
  46. package/types/fields/CodeSelectCol.vue.d.ts +0 -31
  47. package/types/fields/CondOpSelect.vue.d.ts +0 -17
  48. package/types/fields/DataSourceFieldSelect/FieldSelect.vue.d.ts +0 -36
  49. package/types/fields/DataSourceFieldSelect/Index.vue.d.ts +0 -31
  50. package/types/fields/DataSourceFields.vue.d.ts +0 -44
  51. package/types/fields/DataSourceInput.vue.d.ts +0 -34
  52. package/types/fields/DataSourceMethodSelect.vue.d.ts +0 -31
  53. package/types/fields/DataSourceMethods.vue.d.ts +0 -34
  54. package/types/fields/DataSourceMocks.vue.d.ts +0 -41
  55. package/types/fields/DataSourceSelect.vue.d.ts +0 -31
  56. package/types/fields/DisplayConds.vue.d.ts +0 -37
  57. package/types/fields/EventSelect.vue.d.ts +0 -17
  58. package/types/fields/KeyValue.vue.d.ts +0 -36
  59. package/types/fields/PageFragmentSelect.vue.d.ts +0 -31
  60. package/types/fields/UISelect.vue.d.ts +0 -20
  61. package/types/hooks/index.d.ts +0 -6
  62. package/types/hooks/use-code-block-edit.d.ts +0 -189
  63. package/types/hooks/use-data-source-edit.d.ts +0 -176
  64. package/types/hooks/use-data-source-method.d.ts +0 -187
  65. package/types/hooks/use-editor-content-height.d.ts +0 -3
  66. package/types/hooks/use-filter.d.ts +0 -7
  67. package/types/hooks/use-float-box.d.ts +0 -17
  68. package/types/hooks/use-getso.d.ts +0 -5
  69. package/types/hooks/use-next-float-box-position.d.ts +0 -15
  70. package/types/hooks/use-node-status.d.ts +0 -16
  71. package/types/hooks/use-stage.d.ts +0 -3
  72. package/types/hooks/use-window-rect.d.ts +0 -6
  73. package/types/icons/AppManageIcon.vue.d.ts +0 -2
  74. package/types/icons/CenterIcon.vue.d.ts +0 -2
  75. package/types/icons/CodeIcon.vue.d.ts +0 -2
  76. package/types/icons/FolderMinusIcon.vue.d.ts +0 -2
  77. package/types/icons/PinIcon.vue.d.ts +0 -2
  78. package/types/icons/PinnedIcon.vue.d.ts +0 -2
  79. package/types/initService.d.ts +0 -9
  80. package/types/layouts/AddPageBox.vue.d.ts +0 -15
  81. package/types/layouts/CodeEditor.vue.d.ts +0 -80
  82. package/types/layouts/Framework.vue.d.ts +0 -25
  83. package/types/layouts/NavMenu.vue.d.ts +0 -35
  84. package/types/layouts/PropsPanel.vue.d.ts +0 -535
  85. package/types/layouts/page-bar/AddButton.vue.d.ts +0 -16
  86. package/types/layouts/page-bar/PageBar.vue.d.ts +0 -36
  87. package/types/layouts/page-bar/PageBarScrollContainer.vue.d.ts +0 -29
  88. package/types/layouts/page-bar/PageList.vue.d.ts +0 -27
  89. package/types/layouts/page-bar/SwitchTypeButton.vue.d.ts +0 -20
  90. package/types/layouts/sidebar/ComponentListPanel.vue.d.ts +0 -10
  91. package/types/layouts/sidebar/Sidebar.vue.d.ts +0 -51
  92. package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +0 -32
  93. package/types/layouts/sidebar/code-block/CodeBlockListPanel.vue.d.ts +0 -24
  94. package/types/layouts/sidebar/data-source/DataSourceConfigPanel.vue.d.ts +0 -31
  95. package/types/layouts/sidebar/data-source/DataSourceList.vue.d.ts +0 -18
  96. package/types/layouts/sidebar/data-source/DataSourceListPanel.vue.d.ts +0 -10
  97. package/types/layouts/sidebar/layer/LayerMenu.vue.d.ts +0 -41
  98. package/types/layouts/sidebar/layer/LayerNodeTool.vue.d.ts +0 -16
  99. package/types/layouts/sidebar/layer/LayerPanel.vue.d.ts +0 -25
  100. package/types/layouts/sidebar/layer/use-click.d.ts +0 -119
  101. package/types/layouts/sidebar/layer/use-drag.d.ts +0 -14
  102. package/types/layouts/sidebar/layer/use-keybinding.d.ts +0 -6
  103. package/types/layouts/sidebar/layer/use-node-status.d.ts +0 -16
  104. package/types/layouts/workspace/Breadcrumb.vue.d.ts +0 -2
  105. package/types/layouts/workspace/Workspace.vue.d.ts +0 -41
  106. package/types/layouts/workspace/viewer/NodeListMenu.vue.d.ts +0 -2
  107. package/types/layouts/workspace/viewer/Stage.vue.d.ts +0 -34
  108. package/types/layouts/workspace/viewer/StageOverlay.vue.d.ts +0 -2
  109. package/types/layouts/workspace/viewer/ViewerMenu.vue.d.ts +0 -42
  110. package/types/services/BaseService.d.ts +0 -65
  111. package/types/services/codeBlock.d.ts +0 -130
  112. package/types/services/componentList.d.ts +0 -16
  113. package/types/services/dataSource.d.ts +0 -68
  114. package/types/services/dep.d.ts +0 -33
  115. package/types/services/editor.d.ts +0 -180
  116. package/types/services/events.d.ts +0 -18
  117. package/types/services/history.d.ts +0 -26
  118. package/types/services/keybinding.d.ts +0 -40
  119. package/types/services/props.d.ts +0 -92
  120. package/types/services/stageOverlay.d.ts +0 -30
  121. package/types/services/storage.d.ts +0 -65
  122. package/types/services/ui.d.ts +0 -77
  123. package/types/type.d.ts +0 -657
  124. package/types/utils/compose.d.ts +0 -5
  125. package/types/utils/config.d.ts +0 -4
  126. package/types/utils/content-menu.d.ts +0 -7
  127. package/types/utils/data-source/formConfigs/base.d.ts +0 -2
  128. package/types/utils/data-source/formConfigs/http.d.ts +0 -3
  129. package/types/utils/data-source/index.d.ts +0 -10
  130. package/types/utils/editor.d.ts +0 -59
  131. package/types/utils/idle-task.d.ts +0 -13
  132. package/types/utils/index.d.ts +0 -6
  133. package/types/utils/keybinding-config.d.ts +0 -7
  134. package/types/utils/logger.d.ts +0 -5
  135. package/types/utils/monaco-editor.d.ts +0 -2
  136. package/types/utils/operator.d.ts +0 -21
  137. package/types/utils/props.d.ts +0 -23
  138. package/types/utils/scroll-viewer.d.ts +0 -37
  139. package/types/utils/tree.d.ts +0 -3
  140. package/types/utils/undo-redo.d.ts +0 -12
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.4.16",
2
+ "version": "1.5.0-beta.1",
3
3
  "name": "@tmagic/editor",
4
4
  "type": "module",
5
5
  "sideEffects": [
@@ -55,8 +55,8 @@
55
55
  "moveable": "^0.53.0",
56
56
  "serialize-javascript": "^6.0.0",
57
57
  "sortablejs": "^1.15.2",
58
- "@tmagic/dep": "1.4.16",
59
- "@tmagic/table": "1.4.16"
58
+ "@tmagic/table": "1.5.0-beta.1",
59
+ "@tmagic/dep": "1.5.0-beta.1"
60
60
  },
61
61
  "devDependencies": {
62
62
  "@types/events": "^3.0.0",
@@ -71,19 +71,18 @@
71
71
  "sass": "^1.77.0",
72
72
  "tsc-alias": "^1.8.5",
73
73
  "type-fest": "^4.10.3",
74
- "vite": "^5.3.5",
75
- "vue-tsc": "^2.0.19"
74
+ "vite": "^5.3.5"
76
75
  },
77
76
  "peerDependencies": {
78
77
  "monaco-editor": "^0.48.0",
79
78
  "typescript": "*",
80
79
  "vue": "^3.4.35",
81
- "@tmagic/core": "1.4.16",
82
- "@tmagic/design": "1.4.16",
83
- "@tmagic/schema": "1.4.16",
84
- "@tmagic/stage": "1.4.16",
85
- "@tmagic/utils": "1.4.16",
86
- "@tmagic/form": "1.4.16"
80
+ "@tmagic/core": "1.5.0-beta.1",
81
+ "@tmagic/design": "1.5.0-beta.1",
82
+ "@tmagic/form": "1.5.0-beta.1",
83
+ "@tmagic/schema": "1.5.0-beta.1",
84
+ "@tmagic/stage": "1.5.0-beta.1",
85
+ "@tmagic/utils": "1.5.0-beta.1"
87
86
  },
88
87
  "peerDependenciesMeta": {
89
88
  "typescript": {
@@ -91,9 +90,6 @@
91
90
  }
92
91
  },
93
92
  "scripts": {
94
- "build": "npm run build:type && vite build",
95
- "build:type": "npm run clear:type && vue-tsc --declaration --emitDeclarationOnly --project tsconfig.build.json && tsc-alias -p tsconfig.build.json",
96
- "clear:type": "rimraf ./types",
97
- "check:type": "vue-tsc --noEmit --project tsconfig.build.json"
93
+ "build": "vite build"
98
94
  }
99
95
  }
@@ -39,7 +39,7 @@ const getFormConfig = (items: FormConfig = []) => [
39
39
  type: 'fieldset',
40
40
  items,
41
41
  legend: '参数',
42
- labelWidth: '70px',
42
+ labelWidth: '120px',
43
43
  name: props.name,
44
44
  },
45
45
  ];
@@ -10,6 +10,7 @@ import StageCore, {
10
10
  RenderType,
11
11
  type UpdateDragEl,
12
12
  } from '@tmagic/stage';
13
+ import { getIdFromEl } from '@tmagic/utils';
13
14
 
14
15
  import type {
15
16
  ComponentGroup,
@@ -114,7 +115,7 @@ export const defaultEditorProps = {
114
115
  eventMethodList: () => ({}),
115
116
  datasourceValues: () => ({}),
116
117
  datasourceConfigs: () => ({}),
117
- canSelect: (el: HTMLElement) => Boolean(el.id),
118
+ canSelect: (el: HTMLElement) => Boolean(getIdFromEl()(el)),
118
119
  isContainer: (el: HTMLElement) => el.classList.contains('magic-ui-container'),
119
120
  codeOptions: () => ({}),
120
121
  };
@@ -54,7 +54,7 @@ import { Coin } from '@element-plus/icons-vue';
54
54
  import { getConfig, TMagicAutocomplete, TMagicTag } from '@tmagic/design';
55
55
  import type { FieldProps, FormItem } from '@tmagic/form';
56
56
  import type { DataSchema, DataSourceSchema } from '@tmagic/schema';
57
- import { isNumber } from '@tmagic/utils';
57
+ import { getKeysArray, isNumber } from '@tmagic/utils';
58
58
 
59
59
  import Icon from '@editor/components/Icon.vue';
60
60
  import type { Services } from '@editor/type';
@@ -218,7 +218,7 @@ const fieldQuerySearch = (
218
218
  const dsKey = queryString.substring(leftAngleIndex + 1, dotIndex);
219
219
 
220
220
  // 可能是xx.xx.xx,存在链式调用
221
- const keys = dsKey.replaceAll(/\[(\d+)\]/g, '.$1').split('.');
221
+ const keys = getKeysArray(dsKey);
222
222
 
223
223
  // 最前的是数据源id
224
224
  const dsId = keys.shift();
@@ -48,8 +48,9 @@ import { throttle } from 'lodash-es';
48
48
  import { TMagicButton, TMagicTooltip } from '@tmagic/design';
49
49
  import type { FieldProps, FormItem, FormState } from '@tmagic/form';
50
50
  import type { Id } from '@tmagic/schema';
51
+ import { getIdFromEl } from '@tmagic/utils';
51
52
 
52
- import { Services, UI_SELECT_MODE_EVENT_NAME } from '@editor/type';
53
+ import { type Services, UI_SELECT_MODE_EVENT_NAME } from '@editor/type';
53
54
 
54
55
  defineOptions({
55
56
  name: 'MFieldsUISelect',
@@ -71,11 +72,12 @@ const cancelHandler = () => {
71
72
  globalThis.document.removeEventListener(UI_SELECT_MODE_EVENT_NAME, clickHandler as EventListener);
72
73
  };
73
74
 
74
- const clickHandler = ({ detail }: Event & { detail: any }) => {
75
- if (detail.id) {
76
- props.model[props.name] = detail.id;
77
- emit('change', detail.id);
78
- mForm?.$emit('field-change', props.prop, detail.id);
75
+ const clickHandler = ({ detail }: Event & { detail: HTMLElement }) => {
76
+ const id = getIdFromEl()(detail);
77
+ if (id) {
78
+ props.model[props.name] = id;
79
+ emit('change', id);
80
+ mForm?.$emit('field-change', props.prop, id);
79
81
  }
80
82
 
81
83
  if (cancelHandler) {
@@ -104,21 +106,24 @@ const deleteHandler = () => {
104
106
  };
105
107
 
106
108
  const selectNode = async (id: Id) => {
107
- await services?.editorService.select(id);
108
- services?.editorService.get('stage')?.select(id);
109
- services?.stageOverlayService.get('stage')?.select(id);
109
+ if (!services) return;
110
+ await services.editorService.select(id);
111
+ services.editorService.get('stage')?.select(id);
112
+ services.stageOverlayService.get('stage')?.select(id);
110
113
  };
111
114
 
112
115
  const highlight = throttle((id: Id) => {
113
- services?.editorService.highlight(id);
114
- services?.editorService.get('stage')?.highlight(id);
115
- services?.stageOverlayService.get('stage')?.highlight(id);
116
+ if (!services) return;
117
+ services.editorService.highlight(id);
118
+ services.editorService.get('stage')?.highlight(id);
119
+ services.stageOverlayService.get('stage')?.highlight(id);
116
120
  }, 150);
117
121
 
118
122
  const unhighlight = () => {
119
- services?.editorService.set('highlightNode', null);
120
- services?.editorService.get('stage')?.clearHighlight();
121
- services?.stageOverlayService.get('stage')?.clearHighlight();
123
+ if (!services) return;
124
+ services.editorService.set('highlightNode', null);
125
+ services.editorService.get('stage')?.clearHighlight();
126
+ services.stageOverlayService.get('stage')?.clearHighlight();
122
127
  };
123
128
  </script>
124
129
 
@@ -22,3 +22,10 @@ export * from './use-stage';
22
22
  export * from './use-float-box';
23
23
  export * from './use-window-rect';
24
24
  export * from './use-editor-content-height';
25
+ export * from './use-filter';
26
+ export * from './use-float-box';
27
+ export * from './use-getso';
28
+ export * from './use-next-float-box-position';
29
+ export * from './use-node-status';
30
+ export * from './use-stage';
31
+ export * from './use-window-rect';
@@ -2,6 +2,7 @@ import { computed, watch } from 'vue';
2
2
 
3
3
  import type { MNode } from '@tmagic/schema';
4
4
  import StageCore, { GuidesType, RemoveEventData, SortEventData, UpdateEventData } from '@tmagic/stage';
5
+ import { getIdFromEl } from '@tmagic/utils';
5
6
 
6
7
  import editorService from '@editor/services/editor';
7
8
  import uiService from '@editor/services/ui';
@@ -71,27 +72,32 @@ export const useStage = (stageOptions: StageOptions) => {
71
72
  });
72
73
 
73
74
  stage.on('select', (el: HTMLElement) => {
74
- if (`${editorService.get('node')?.id}` === el.id && editorService.get('nodes').length === 1) return;
75
- editorService.select(el.id);
75
+ const id = getIdFromEl()(el);
76
+ if (`${editorService.get('node')?.id}` === id && editorService.get('nodes').length === 1) return;
77
+ id && editorService.select(id);
76
78
  });
77
79
 
78
80
  stage.on('highlight', (el: HTMLElement) => {
79
- editorService.highlight(el.id);
81
+ const id = getIdFromEl()(el);
82
+ id && editorService.highlight(id);
80
83
  });
81
84
 
82
85
  stage.on('multi-select', (els: HTMLElement[]) => {
83
- editorService.multiSelect(els.map((el) => el.id));
86
+ const ids = els.map((el) => getIdFromEl()(el)).filter((id) => Boolean(id)) as string[];
87
+ editorService.multiSelect(ids);
84
88
  });
85
89
 
86
90
  stage.on('update', (ev: UpdateEventData) => {
87
91
  if (ev.parentEl) {
88
92
  for (const data of ev.data) {
89
- editorService.moveToContainer({ id: data.el.id, style: data.style }, ev.parentEl.id);
93
+ const id = getIdFromEl()(data.el);
94
+ const pId = getIdFromEl()(ev.parentEl);
95
+ id && pId && editorService.moveToContainer({ id, style: data.style }, pId);
90
96
  }
91
97
  return;
92
98
  }
93
99
 
94
- editorService.update(ev.data.map((data) => ({ id: data.el.id, style: data.style })));
100
+ editorService.update(ev.data.map((data) => ({ id: getIdFromEl()(data.el) || '', style: data.style })));
95
101
  });
96
102
 
97
103
  stage.on('sort', (ev: SortEventData) => {
@@ -99,7 +105,7 @@ export const useStage = (stageOptions: StageOptions) => {
99
105
  });
100
106
 
101
107
  stage.on('remove', (ev: RemoveEventData) => {
102
- const nodes = ev.data.map(({ el }) => editorService.getNodeById(el.id));
108
+ const nodes = ev.data.map(({ el }) => editorService.getNodeById(getIdFromEl()(el) || ''));
103
109
  editorService.remove(nodes.filter((node) => Boolean(node)) as MNode[]);
104
110
  });
105
111
 
package/src/index.ts CHANGED
@@ -85,6 +85,8 @@ export { default as SplitView } from './components/SplitView.vue';
85
85
  export { default as Resizer } from './components/Resizer.vue';
86
86
  export { default as CodeBlockEditor } from './components/CodeBlockEditor.vue';
87
87
  export { default as FloatingBox } from './components/FloatingBox.vue';
88
+ export { default as Tree } from './components/Tree.vue';
89
+ export { default as TreeNode } from './components/TreeNode.vue';
88
90
  export { default as PageFragmentSelect } from './fields/PageFragmentSelect.vue';
89
91
  export { default as DisplayConds } from './fields/DisplayConds.vue';
90
92
  export { default as CondOpSelect } from './fields/CondOpSelect.vue';
@@ -192,6 +192,54 @@ export const initServiceEvents = (
192
192
  ((event: 'update:modelValue', value: MApp | null) => void),
193
193
  { editorService, codeBlockService, dataSourceService, depService }: Services,
194
194
  ) => {
195
+ const rootChangeHandler = async (value: MApp | null, preValue?: MApp | null) => {
196
+ if (!value) return;
197
+
198
+ value.codeBlocks = value.codeBlocks || {};
199
+ value.dataSources = value.dataSources || [];
200
+
201
+ codeBlockService.setCodeDsl(value.codeBlocks);
202
+ dataSourceService.set('dataSources', value.dataSources);
203
+
204
+ depService.removeTargets(DepTargetType.CODE_BLOCK);
205
+
206
+ Object.entries(value.codeBlocks).forEach(([id, code]) => {
207
+ depService.addTarget(createCodeBlockTarget(id, code));
208
+ });
209
+
210
+ dataSourceService.get('dataSources').forEach((ds) => {
211
+ initDataSourceDepTarget(ds);
212
+ });
213
+
214
+ if (Array.isArray(value.items)) {
215
+ collectIdle(value.items, true);
216
+ } else {
217
+ depService.clear();
218
+ delete value.dataSourceDeps;
219
+ delete value.dataSourceCondDeps;
220
+ }
221
+
222
+ const nodeId = editorService.get('node')?.id || props.defaultSelected;
223
+ let node;
224
+ if (nodeId) {
225
+ node = editorService.getNodeById(nodeId);
226
+ }
227
+
228
+ if (node && node !== value) {
229
+ await editorService.select(node.id);
230
+ } else if (value.items?.length) {
231
+ await editorService.select(value.items[0]);
232
+ } else if (value.id) {
233
+ editorService.set('nodes', [value]);
234
+ editorService.set('parent', null);
235
+ editorService.set('page', null);
236
+ }
237
+
238
+ if (toRaw(value) !== toRaw(preValue)) {
239
+ emit('update:modelValue', value);
240
+ }
241
+ };
242
+
195
243
  const getApp = () => {
196
244
  const stage = editorService.get('stage');
197
245
  return stage?.renderer.runtime?.getApp?.();
@@ -292,55 +340,6 @@ export const initServiceEvents = (
292
340
  depService.addTarget(createDataSourceCondTarget(ds, reactive({})));
293
341
  };
294
342
 
295
- const rootChangeHandler = async (value: MApp | null, preValue?: MApp | null) => {
296
- if (!value) return;
297
-
298
- value.codeBlocks = value.codeBlocks || {};
299
- value.dataSources = value.dataSources || [];
300
-
301
- codeBlockService.setCodeDsl(value.codeBlocks);
302
- dataSourceService.set('dataSources', value.dataSources);
303
-
304
- depService.removeTargets(DepTargetType.CODE_BLOCK);
305
-
306
- Object.entries(value.codeBlocks).forEach(([id, code]) => {
307
- depService.addTarget(createCodeBlockTarget(id, code));
308
- });
309
-
310
- dataSourceService.get('dataSources').forEach((ds) => {
311
- initDataSourceDepTarget(ds);
312
- });
313
-
314
- if (Array.isArray(value.items)) {
315
- value.items.forEach((page) => {
316
- depService.collectIdle([page], { pageId: page.id }, true);
317
- });
318
- } else {
319
- depService.clear();
320
- delete value.dataSourceDeps;
321
- }
322
-
323
- const nodeId = editorService.get('node')?.id || props.defaultSelected;
324
- let node;
325
- if (nodeId) {
326
- node = editorService.getNodeById(nodeId);
327
- }
328
-
329
- if (node && node !== value) {
330
- await editorService.select(node.id);
331
- } else if (value.items?.length) {
332
- await editorService.select(value.items[0]);
333
- } else if (value.id) {
334
- editorService.set('nodes', [value]);
335
- editorService.set('parent', null);
336
- editorService.set('page', null);
337
- }
338
-
339
- if (toRaw(value) !== toRaw(preValue)) {
340
- emit('update:modelValue', value);
341
- }
342
- };
343
-
344
343
  const collectIdle = (nodes: MNode[], deep: boolean) => {
345
344
  nodes.forEach((node) => {
346
345
  let pageId: Id | undefined;
@@ -372,7 +371,7 @@ export const initServiceEvents = (
372
371
 
373
372
  // 由于历史记录变化是更新整个page,所以历史记录变化时,需要重新收集依赖
374
373
  const historyChangeHandler = (page: MPage | MPageFragment) => {
375
- depService.collectIdle([page], { pageId: page.id }, true);
374
+ collectIdle([page], true);
376
375
  };
377
376
 
378
377
  editorService.on('history-change', historyChangeHandler);
@@ -407,9 +406,7 @@ export const initServiceEvents = (
407
406
  removeDataSourceTarget(config.id);
408
407
  initDataSourceDepTarget(config);
409
408
 
410
- (root?.items || []).forEach((page) => {
411
- depService.collectIdle([page], { pageId: page.id }, true);
412
- });
409
+ collectIdle(root?.items || [], true);
413
410
  };
414
411
 
415
412
  const removeDataSourceTarget = (id: string) => {
@@ -148,7 +148,7 @@
148
148
  </template>
149
149
 
150
150
  <script setup lang="ts">
151
- import { computed, inject, ref, watch } from 'vue';
151
+ import { computed, inject, nextTick, ref, watch } from 'vue';
152
152
  import { Coin, EditPen, Goods, List } from '@element-plus/icons-vue';
153
153
 
154
154
  import FloatingBox from '@editor/components/FloatingBox.vue';
@@ -196,7 +196,23 @@ const props = withDefaults(
196
196
  const services = inject<Services>('services');
197
197
 
198
198
  const columnLeftWidth = computed(() => services?.uiService.get('columnWidth')[ColumnLayout.LEFT] || 0);
199
- const { height: columnLeftHeight } = useEditorContentHeight();
199
+ const { height: editorContentHeight } = useEditorContentHeight();
200
+ const columnLeftHeight = ref(0);
201
+
202
+ const unWatchEditorContentHeight = watch(
203
+ editorContentHeight,
204
+ (height) => {
205
+ if (height) {
206
+ columnLeftHeight.value = height * 0.5;
207
+ nextTick().then(() => {
208
+ unWatchEditorContentHeight();
209
+ });
210
+ }
211
+ },
212
+ {
213
+ immediate: true,
214
+ },
215
+ );
200
216
 
201
217
  const activeTabName = ref(props.data?.status);
202
218
 
@@ -2,23 +2,21 @@
2
2
  <TMagicScrollbar class="data-source-list-panel m-editor-layer-panel">
3
3
  <div class="search-wrapper">
4
4
  <SearchInput @search="filterTextChangeHandler"></SearchInput>
5
- <TMagicPopover v-if="editable" placement="right">
5
+ <TMagicPopover v-if="editable" placement="right" trigger="hover" popper-class="data-source-list-panel-add-menu">
6
6
  <template #reference>
7
7
  <TMagicButton type="primary" size="small">新增</TMagicButton>
8
8
  </template>
9
- <div class="data-source-list-panel-add-menu">
10
- <ToolButton
11
- v-for="(item, index) in datasourceTypeList"
12
- :data="{
13
- type: 'button',
14
- text: item.text,
15
- handler: () => {
16
- addHandler(item.type);
17
- },
18
- }"
19
- :key="index"
20
- ></ToolButton>
21
- </div>
9
+ <ToolButton
10
+ v-for="(item, index) in datasourceTypeList"
11
+ :data="{
12
+ type: 'button',
13
+ text: item.text,
14
+ handler: () => {
15
+ addHandler(item.type);
16
+ },
17
+ }"
18
+ :key="index"
19
+ ></ToolButton>
22
20
  </TMagicPopover>
23
21
 
24
22
  <slot name="data-source-panel-search"></slot>
@@ -26,6 +26,7 @@ import { computed, inject, nextTick, ref, watch } from 'vue';
26
26
 
27
27
  import { TMagicTooltip } from '@tmagic/design';
28
28
  import type { MNode } from '@tmagic/schema';
29
+ import { getIdFromEl } from '@tmagic/utils';
29
30
 
30
31
  import FloatingBox from '@editor/components/FloatingBox.vue';
31
32
  import Tree from '@editor/components/Tree.vue';
@@ -61,7 +62,7 @@ const unWatch = watch(
61
62
 
62
63
  stage.on('select', (el: HTMLElement, event: MouseEvent) => {
63
64
  const els = stage.renderer.getElementsFromPoint(event) || [];
64
- const ids = els.map((el) => el.id).filter((id) => Boolean(id));
65
+ const ids = els.map((el) => getIdFromEl()(el)).filter((id) => Boolean(id)) as string[];
65
66
 
66
67
  buttonVisible.value = ids.length > 3;
67
68
 
@@ -46,7 +46,7 @@ import { cloneDeep } from 'lodash-es';
46
46
 
47
47
  import type { MApp, MContainer } from '@tmagic/schema';
48
48
  import StageCore, { getOffset, Runtime } from '@tmagic/stage';
49
- import { calcValueByFontsize } from '@tmagic/utils';
49
+ import { calcValueByFontsize, getIdFromEl } from '@tmagic/utils';
50
50
 
51
51
  import ScrollViewer from '@editor/components/ScrollViewer.vue';
52
52
  import { useStage } from '@editor/hooks/use-stage';
@@ -200,8 +200,9 @@ const dropHandler = async (e: DragEvent) => {
200
200
  const parentEl: HTMLElement | null | undefined = doc?.querySelector(`.${stageOptions?.containerHighlightClassName}`);
201
201
 
202
202
  let parent: MContainer | undefined | null = page.value;
203
- if (parentEl) {
204
- parent = services?.editorService.getNodeById(parentEl.id, false) as MContainer;
203
+ const parentId = getIdFromEl()(parentEl);
204
+ if (parentId) {
205
+ parent = services?.editorService.getNodeById(parentId, false) as MContainer;
205
206
  }
206
207
 
207
208
  if (parent && stageContainer.value && stage) {
@@ -23,7 +23,7 @@ import { Writable } from 'type-fest';
23
23
  import { Target, type TargetOptions, Watcher } from '@tmagic/dep';
24
24
  import type { Id, MApp, MComponent, MContainer, MNode, MPage, MPageFragment } from '@tmagic/schema';
25
25
  import { NodeType } from '@tmagic/schema';
26
- import { calcValueByFontsize, getNodePath, isNumber, isPage, isPageFragment, isPop } from '@tmagic/utils';
26
+ import { calcValueByFontsize, getElById, getNodePath, isNumber, isPage, isPageFragment, isPop } from '@tmagic/utils';
27
27
 
28
28
  import BaseService from '@editor/services//BaseService';
29
29
  import propsService from '@editor/services//props';
@@ -759,7 +759,7 @@ class Editor extends BaseService {
759
759
  const doc = stage?.renderer.contentWindow?.document;
760
760
 
761
761
  if (doc) {
762
- const el = doc.getElementById(`${node.id}`);
762
+ const el = getElById()(doc, node.id);
763
763
  const parentEl = layout === Layout.FIXED ? doc.body : el?.offsetParent;
764
764
  if (parentEl && el) {
765
765
  node.style.left = calcValueByFontsize(doc, (parentEl.clientWidth - el.clientWidth) / 2);
@@ -2,6 +2,7 @@ import { reactive } from 'vue';
2
2
  import type { Writable } from 'type-fest';
3
3
 
4
4
  import StageCore from '@tmagic/stage';
5
+ import { getIdFromEl } from '@tmagic/utils';
5
6
 
6
7
  import { useStage } from '@editor/hooks/use-stage';
7
8
  import BaseService from '@editor/services//BaseService';
@@ -169,7 +170,8 @@ class StageOverlay extends BaseService {
169
170
  });
170
171
 
171
172
  if (await stageOptions?.canSelect?.(contentEl)) {
172
- subStage?.select(contentEl.id);
173
+ const id = getIdFromEl()(contentEl);
174
+ id && subStage?.select(id);
173
175
  }
174
176
  }
175
177
 
@@ -17,12 +17,15 @@
17
17
  }
18
18
 
19
19
  .data-source-list-panel-add-menu {
20
- .tmagic-design-button {
21
- width: 100%;
22
- text-align: left;
20
+ padding: 4px 0;
23
21
 
24
- span {
25
- width: 100%;
22
+ .menu-item {
23
+ cursor: pointer;
24
+ transition: all 0.2s ease 0s;
25
+ padding: 5px 14px;
26
+
27
+ &:hover {
28
+ background-color: $--hover-color;
26
29
  }
27
30
  }
28
31
  }
@@ -81,8 +81,8 @@
81
81
  }
82
82
 
83
83
  .page-bar-popover {
84
- &.el-popper.el-popover {
85
- padding: 10px 0;
84
+ &.tmagic-design-popper {
85
+ padding: 4px 0;
86
86
  }
87
87
 
88
88
  .menu-item {
@@ -1,6 +1,11 @@
1
1
  import { CascaderOption, FormConfig, FormState } from '@tmagic/form';
2
2
  import { DataSchema, DataSourceFieldType, DataSourceSchema } from '@tmagic/schema';
3
- import { DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX, isNumber } from '@tmagic/utils';
3
+ import {
4
+ DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX,
5
+ dataSourceTemplateRegExp,
6
+ getKeysArray,
7
+ isNumber,
8
+ } from '@tmagic/utils';
4
9
 
5
10
  import BaseFormConfig from './formConfigs/base';
6
11
  import HttpFormConfig from './formConfigs/http';
@@ -118,7 +123,7 @@ export const getFormValue = (type: string, values: Partial<DataSourceSchema>): P
118
123
  * context:上下文对象
119
124
  *
120
125
  * interface Content {
121
- * app: AppCore;
126
+ * app: TMagicApp;
122
127
  * dataSource: HttpDataSource;
123
128
  * }
124
129
  *
@@ -135,7 +140,7 @@ export const getFormValue = (type: string, values: Partial<DataSourceSchema>): P
135
140
  * context:上下文对象
136
141
  *
137
142
  * interface Content {
138
- * app: AppCore;
143
+ * app: TMagicApp;
139
144
  * dataSource: HttpDataSource;
140
145
  * }
141
146
  *
@@ -152,7 +157,7 @@ export const getDisplayField = (dataSources: DataSourceSchema[], key: string) =>
152
157
  const displayState: { value: string; type: 'var' | 'text' }[] = [];
153
158
 
154
159
  // 匹配es6字符串模块
155
- const matches = key.matchAll(/\$\{([\s\S]+?)\}/g);
160
+ const matches = key.matchAll(dataSourceTemplateRegExp);
156
161
  let index = 0;
157
162
  for (const match of matches) {
158
163
  if (typeof match.index === 'undefined') break;
@@ -167,25 +172,22 @@ export const getDisplayField = (dataSources: DataSourceSchema[], key: string) =>
167
172
  let ds: DataSourceSchema | undefined;
168
173
  let fields: DataSchema[] | undefined;
169
174
  // 将模块解析成数据源对应的值
170
- match[1]
171
- .replaceAll(/\[(\d+)\]/g, '.$1')
172
- .split('.')
173
- .forEach((item, index) => {
174
- if (index === 0) {
175
- ds = dataSources.find((ds) => ds.id === item);
176
- dsText += ds?.title || item;
177
- fields = ds?.fields;
178
- return;
179
- }
180
-
181
- if (isNumber(item)) {
182
- dsText += `[${item}]`;
183
- } else {
184
- const field = fields?.find((field) => field.name === item);
185
- fields = field?.fields;
186
- dsText += `.${field?.title || item}`;
187
- }
188
- });
175
+ getKeysArray(match[1]).forEach((item, index) => {
176
+ if (index === 0) {
177
+ ds = dataSources.find((ds) => ds.id === item);
178
+ dsText += ds?.title || item;
179
+ fields = ds?.fields;
180
+ return;
181
+ }
182
+
183
+ if (isNumber(item)) {
184
+ dsText += `[${item}]`;
185
+ } else {
186
+ const field = fields?.find((field) => field.name === item);
187
+ fields = field?.fields;
188
+ dsText += `.${field?.title || item}`;
189
+ }
190
+ });
189
191
 
190
192
  displayState.push({
191
193
  type: 'var',
@@ -21,9 +21,10 @@ import serialize from 'serialize-javascript';
21
21
  import type { Id, MApp, MContainer, MNode, MPage, MPageFragment } from '@tmagic/schema';
22
22
  import { NodeType } from '@tmagic/schema';
23
23
  import type StageCore from '@tmagic/stage';
24
- import { calcValueByFontsize, getNodePath, isNumber, isPage, isPageFragment, isPop } from '@tmagic/utils';
24
+ import { calcValueByFontsize, getElById, getNodePath, isNumber, isPage, isPageFragment, isPop } from '@tmagic/utils';
25
25
 
26
26
  import { Layout } from '@editor/type';
27
+
27
28
  export const COPY_STORAGE_KEY = '$MagicEditorCopyData';
28
29
  export const COPY_CODE_STORAGE_KEY = '$MagicEditorCopyCode';
29
30
  export const COPY_DS_STORAGE_KEY = '$MagicEditorCopyDataSource';
@@ -239,8 +240,8 @@ export const getGuideLineFromCache = (key: string): number[] => {
239
240
  export const fixNodeLeft = (config: MNode, parent: MContainer, doc?: Document) => {
240
241
  if (!doc || !config.style || !isNumber(config.style.left)) return config.style?.left;
241
242
 
242
- const el = doc.getElementById(`${config.id}`);
243
- const parentEl = doc.getElementById(`${parent.id}`);
243
+ const el = getElById()(doc, `${config.id}`);
244
+ const parentEl = getElById()(doc, `${parent.id}`);
244
245
 
245
246
  const left = Number(config.style?.left) || 0;
246
247
  if (el && parentEl) {