@tmagic/editor 1.3.4 → 1.3.6

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 (103) hide show
  1. package/dist/style.css +73 -51
  2. package/dist/tmagic-editor.js +1171 -1102
  3. package/dist/tmagic-editor.js.map +1 -1
  4. package/dist/tmagic-editor.umd.cjs +1188 -1119
  5. package/dist/tmagic-editor.umd.cjs.map +1 -1
  6. package/package.json +17 -17
  7. package/src/Editor.vue +5 -0
  8. package/src/components/FloatingBox.vue +117 -0
  9. package/src/components/Tree.vue +5 -0
  10. package/src/components/TreeNode.vue +8 -2
  11. package/src/editorProps.ts +7 -0
  12. package/src/hooks/use-filter.ts +55 -0
  13. package/src/hooks/use-node-status.ts +48 -0
  14. package/src/hooks/use-stage.ts +1 -0
  15. package/src/initService.ts +28 -12
  16. package/src/layouts/sidebar/Sidebar.vue +7 -2
  17. package/src/layouts/sidebar/code-block/CodeBlockList.vue +55 -65
  18. package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +2 -1
  19. package/src/layouts/sidebar/data-source/DataSourceList.vue +63 -59
  20. package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +1 -1
  21. package/src/layouts/sidebar/layer/LayerPanel.vue +24 -7
  22. package/src/layouts/sidebar/layer/use-node-status.ts +8 -11
  23. package/src/layouts/workspace/viewer/NodeListMenu.vue +67 -128
  24. package/src/layouts/workspace/viewer/Stage.vue +2 -1
  25. package/src/layouts/workspace/viewer/ViewerMenu.vue +1 -6
  26. package/src/services/BaseService.ts +63 -26
  27. package/src/services/codeBlock.ts +7 -1
  28. package/src/services/dep.ts +12 -8
  29. package/src/services/editor.ts +66 -30
  30. package/src/services/props.ts +70 -12
  31. package/src/services/storage.ts +23 -13
  32. package/src/services/ui.ts +4 -1
  33. package/src/theme/floating-box.scss +30 -0
  34. package/src/theme/layer-panel.scss +19 -0
  35. package/src/theme/stage.scss +24 -0
  36. package/src/theme/theme.scss +1 -1
  37. package/src/theme/tree.scss +12 -1
  38. package/src/type.ts +6 -3
  39. package/src/utils/compose.ts +25 -6
  40. package/src/utils/content-menu.ts +4 -5
  41. package/src/utils/editor.ts +12 -3
  42. package/src/utils/operator.ts +1 -2
  43. package/types/components/CodeBlockEditor.vue.d.ts +6 -2
  44. package/types/components/CodeParams.vue.d.ts +3 -1
  45. package/types/components/ContentMenu.vue.d.ts +13 -5
  46. package/types/components/FloatingBox.vue.d.ts +78 -0
  47. package/types/components/Resizer.vue.d.ts +6 -1
  48. package/types/components/ScrollBar.vue.d.ts +3 -1
  49. package/types/components/ScrollViewer.vue.d.ts +3 -3
  50. package/types/components/SearchInput.vue.d.ts +3 -1
  51. package/types/components/SplitView.vue.d.ts +8 -4
  52. package/types/components/ToolButton.vue.d.ts +1 -1
  53. package/types/components/Tree.vue.d.ts +27 -8
  54. package/types/components/TreeNode.vue.d.ts +24 -7
  55. package/types/editorProps.d.ts +7 -1
  56. package/types/fields/Code.vue.d.ts +6 -2
  57. package/types/fields/CodeLink.vue.d.ts +5 -3
  58. package/types/fields/CodeSelect.vue.d.ts +3 -1
  59. package/types/fields/CodeSelectCol.vue.d.ts +3 -1
  60. package/types/fields/DataSourceFieldSelect.vue.d.ts +3 -1
  61. package/types/fields/DataSourceFields.vue.d.ts +5 -3
  62. package/types/fields/DataSourceInput.vue.d.ts +8 -4
  63. package/types/fields/DataSourceMethodSelect.vue.d.ts +3 -1
  64. package/types/fields/DataSourceMethods.vue.d.ts +5 -3
  65. package/types/fields/DataSourceMocks.vue.d.ts +5 -3
  66. package/types/fields/DataSourceSelect.vue.d.ts +5 -3
  67. package/types/fields/EventSelect.vue.d.ts +3 -1
  68. package/types/fields/KeyValue.vue.d.ts +2 -2
  69. package/types/fields/UISelect.vue.d.ts +3 -1
  70. package/types/hooks/use-code-block-edit.d.ts +14 -5
  71. package/types/hooks/use-data-source-method.d.ts +14 -5
  72. package/types/hooks/use-filter.d.ts +7 -0
  73. package/types/hooks/use-node-status.d.ts +6 -0
  74. package/types/layouts/CodeEditor.vue.d.ts +4 -1
  75. package/types/layouts/Framework.vue.d.ts +1 -1
  76. package/types/layouts/PropsPanel.vue.d.ts +10 -4
  77. package/types/layouts/sidebar/ComponentListPanel.vue.d.ts +1 -1
  78. package/types/layouts/sidebar/Sidebar.vue.d.ts +5 -5
  79. package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +9 -3
  80. package/types/layouts/sidebar/code-block/CodeBlockListPanel.vue.d.ts +1 -1
  81. package/types/layouts/sidebar/data-source/DataSourceConfigPanel.vue.d.ts +3 -1
  82. package/types/layouts/sidebar/data-source/DataSourceList.vue.d.ts +8 -2
  83. package/types/layouts/sidebar/data-source/DataSourceListPanel.vue.d.ts +1 -1
  84. package/types/layouts/sidebar/layer/LayerMenu.vue.d.ts +6 -2
  85. package/types/layouts/sidebar/layer/LayerPanel.vue.d.ts +1 -1
  86. package/types/layouts/sidebar/layer/use-click.d.ts +14 -5
  87. package/types/layouts/sidebar/layer/use-node-status.d.ts +3 -4
  88. package/types/layouts/workspace/Workspace.vue.d.ts +1 -1
  89. package/types/layouts/workspace/viewer/NodeListMenu.vue.d.ts +1 -14
  90. package/types/layouts/workspace/viewer/ViewerMenu.vue.d.ts +1 -1
  91. package/types/services/BaseService.d.ts +4 -1
  92. package/types/services/dep.d.ts +6 -5
  93. package/types/services/editor.d.ts +9 -3
  94. package/types/services/props.d.ts +25 -1
  95. package/types/services/storage.d.ts +7 -7
  96. package/types/type.d.ts +8 -6
  97. package/types/utils/compose.d.ts +1 -1
  98. package/types/utils/editor.d.ts +5 -1
  99. package/src/layouts/sidebar/layer/use-filter.ts +0 -59
  100. package/src/layouts/workspace/viewer/NodeListMenuTitle.vue +0 -68
  101. package/src/theme/dep-list.scss +0 -59
  102. package/types/layouts/sidebar/layer/use-filter.d.ts +0 -7
  103. package/types/layouts/workspace/viewer/NodeListMenuTitle.vue.d.ts +0 -15
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.3.4",
2
+ "version": "1.3.6",
3
3
  "name": "@tmagic/editor",
4
4
  "type": "module",
5
5
  "sideEffects": [
@@ -29,7 +29,7 @@
29
29
  "clear:type": "rimraf ./types"
30
30
  },
31
31
  "engines": {
32
- "node": ">=14"
32
+ "node": ">=18"
33
33
  },
34
34
  "repository": {
35
35
  "type": "git",
@@ -46,15 +46,15 @@
46
46
  ],
47
47
  "dependencies": {
48
48
  "@babel/core": "^7.18.0",
49
- "@element-plus/icons-vue": "^2.0.9",
50
- "@tmagic/core": "1.3.4",
51
- "@tmagic/dep": "1.3.4",
52
- "@tmagic/design": "1.3.4",
53
- "@tmagic/form": "1.3.4",
54
- "@tmagic/schema": "1.3.4",
55
- "@tmagic/stage": "1.3.4",
56
- "@tmagic/table": "1.3.4",
57
- "@tmagic/utils": "1.3.4",
49
+ "@element-plus/icons-vue": "^2.3.1",
50
+ "@tmagic/core": "1.3.6",
51
+ "@tmagic/dep": "1.3.6",
52
+ "@tmagic/design": "1.3.6",
53
+ "@tmagic/form": "1.3.6",
54
+ "@tmagic/schema": "1.3.6",
55
+ "@tmagic/stage": "1.3.6",
56
+ "@tmagic/table": "1.3.6",
57
+ "@tmagic/utils": "1.3.6",
58
58
  "buffer": "^6.0.3",
59
59
  "color": "^3.1.3",
60
60
  "events": "^3.3.0",
@@ -67,24 +67,24 @@
67
67
  "vue": "^3.3.8"
68
68
  },
69
69
  "peerDependencies": {
70
- "@tmagic/design": "1.3.4",
71
- "@tmagic/form": "1.3.4",
70
+ "@tmagic/design": "1.3.6",
71
+ "@tmagic/form": "1.3.6",
72
72
  "monaco-editor": "^0.41.0",
73
73
  "vue": "^3.3.8"
74
74
  },
75
75
  "devDependencies": {
76
76
  "@types/events": "^3.0.0",
77
77
  "@types/lodash-es": "^4.17.4",
78
- "@types/node": "^15.12.4",
78
+ "@types/node": "^18.19.0",
79
79
  "@types/serialize-javascript": "^5.0.1",
80
- "@vitejs/plugin-vue": "^4.2.3",
80
+ "@vitejs/plugin-vue": "^4.5.2",
81
81
  "@vue/compiler-sfc": "^3.3.8",
82
82
  "@vue/test-utils": "^2.3.2",
83
83
  "rimraf": "^3.0.2",
84
84
  "sass": "^1.35.1",
85
85
  "tsc-alias": "^1.8.5",
86
86
  "typescript": "^5.0.4",
87
- "vite": "^4.4.4",
88
- "vue-tsc": "^1.6.5"
87
+ "vite": "^5.0.7",
88
+ "vue-tsc": "^1.8.25"
89
89
  }
90
90
  }
package/src/Editor.vue CHANGED
@@ -25,6 +25,10 @@
25
25
  <slot name="layer-node-content" :data="data"></slot>
26
26
  </template>
27
27
 
28
+ <template #layer-node-label="{ data }">
29
+ <slot name="layer-node-label" :data="data"></slot>
30
+ </template>
31
+
28
32
  <template #layer-node-tool="{ data }">
29
33
  <slot name="layer-node-tool" :data="data"></slot>
30
34
  </template>
@@ -171,6 +175,7 @@ provide(
171
175
  containerHighlightDuration: props.containerHighlightDuration,
172
176
  containerHighlightType: props.containerHighlightType,
173
177
  disabledDragStart: props.disabledDragStart,
178
+ renderType: props.renderType,
174
179
  }),
175
180
  );
176
181
 
@@ -0,0 +1,117 @@
1
+ <template>
2
+ <Teleport to="body" v-if="visible">
3
+ <div ref="target" class="m-editor-float-box" :style="style">
4
+ <div ref="dragTarget" class="m-editor-float-box-title">
5
+ <slot name="title">
6
+ <span>{{ title }}</span>
7
+ </slot>
8
+ <div>
9
+ <TMagicButton text size="small" :icon="Close" @click="closeHandler"></TMagicButton>
10
+ </div>
11
+ </div>
12
+ <div class="m-editor-float-box-body">
13
+ <slot name="body"></slot>
14
+ </div>
15
+ </div>
16
+ </Teleport>
17
+ </template>
18
+
19
+ <script setup lang="ts">
20
+ import { computed, nextTick, onBeforeUnmount, ref, watch } from 'vue';
21
+ import { Close } from '@element-plus/icons-vue';
22
+ import VanillaMoveable from 'moveable';
23
+
24
+ import { TMagicButton } from '@tmagic/design';
25
+
26
+ interface Position {
27
+ left: number;
28
+ top: number;
29
+ }
30
+
31
+ interface Rect {
32
+ width: number | string;
33
+ height: number | string;
34
+ }
35
+
36
+ const props = withDefaults(defineProps<{ visible: boolean; position?: Position; rect?: Rect; title?: string }>(), {
37
+ visible: false,
38
+ title: '',
39
+ position: () => ({ left: 0, top: 0 }),
40
+ rect: () => ({ width: 'auto', height: 'auto' }),
41
+ });
42
+
43
+ const emit = defineEmits<{
44
+ 'update:visible': [boolean];
45
+ }>();
46
+
47
+ const target = ref<HTMLDivElement>();
48
+ const dragTarget = ref<HTMLDivElement>();
49
+
50
+ const style = computed(() => ({
51
+ left: `${props.position.left}px`,
52
+ top: `${props.position.top}px`,
53
+ width: typeof props.rect.width === 'string' ? props.rect.width : `${props.rect.width}px`,
54
+ height: typeof props.rect.height === 'string' ? props.rect.height : `${props.rect.height}px`,
55
+ }));
56
+
57
+ let moveable: VanillaMoveable | null = null;
58
+
59
+ const initMoveable = () => {
60
+ moveable = new VanillaMoveable(globalThis.document.body, {
61
+ className: 'm-editor-floating-box-moveable',
62
+ target: target.value,
63
+ draggable: true,
64
+ resizable: true,
65
+ edge: true,
66
+ keepRatio: false,
67
+ origin: false,
68
+ snappable: true,
69
+ dragTarget: dragTarget.value,
70
+ dragTargetSelf: false,
71
+ linePadding: 10,
72
+ controlPadding: 10,
73
+ });
74
+
75
+ moveable.on('drag', (e) => {
76
+ e.target.style.transform = e.transform;
77
+ });
78
+
79
+ moveable.on('resize', (e) => {
80
+ e.target.style.width = `${e.width}px`;
81
+ e.target.style.height = `${e.height}px`;
82
+ e.target.style.transform = e.drag.transform;
83
+ });
84
+ };
85
+
86
+ const destroyMoveable = () => {
87
+ moveable?.destroy();
88
+ moveable = null;
89
+ };
90
+
91
+ watch(
92
+ () => props.visible,
93
+ async (visible) => {
94
+ if (visible) {
95
+ await nextTick();
96
+ initMoveable();
97
+ } else {
98
+ destroyMoveable();
99
+ }
100
+ },
101
+ {
102
+ immediate: true,
103
+ },
104
+ );
105
+
106
+ onBeforeUnmount(() => {
107
+ destroyMoveable();
108
+ });
109
+
110
+ const closeHandler = () => {
111
+ emit('update:visible', false);
112
+ };
113
+
114
+ defineExpose({
115
+ target,
116
+ });
117
+ </script>
@@ -6,6 +6,10 @@
6
6
  <slot name="tree-node-content" :data="nodeData"> </slot>
7
7
  </template>
8
8
 
9
+ <template #tree-node-label="{ data: nodeData }">
10
+ <slot name="tree-node-label" :data="nodeData"> </slot>
11
+ </template>
12
+
9
13
  <template #tree-node-tool="{ data: nodeData }">
10
14
  <slot name="tree-node-tool" :data="nodeData"> </slot>
11
15
  </template>
@@ -28,6 +32,7 @@ import TreeNode from './TreeNode.vue';
28
32
 
29
33
  defineSlots<{
30
34
  'tree-node-content'(props: { data: TreeNodeData }): any;
35
+ 'tree-node-label'(props: { data: TreeNodeData }): any;
31
36
  'tree-node-tool'(props: { data: TreeNodeData }): any;
32
37
  }>();
33
38
 
@@ -25,7 +25,9 @@
25
25
 
26
26
  <div class="tree-node-content" @click="nodeClickHandler">
27
27
  <slot name="tree-node-content" :data="data">
28
- <div class="tree-node-label">{{ `${data.name} (${data.id})` }}</div>
28
+ <div class="tree-node-label">
29
+ <slot name="tree-node-label" :data="data">{{ `${data.name} (${data.id})` }}</slot>
30
+ </div>
29
31
  <div class="tree-node-tool">
30
32
  <slot name="tree-node-tool" :data="data"></slot>
31
33
  </div>
@@ -44,6 +46,9 @@
44
46
  <template #tree-node-content="{ data: nodeData }">
45
47
  <slot name="tree-node-content" :data="nodeData"> </slot>
46
48
  </template>
49
+ <template #tree-node-label="{ data: nodeData }">
50
+ <slot name="tree-node-label" :data="nodeData"> </slot>
51
+ </template>
47
52
  <template #tree-node-tool="{ data: nodeData }">
48
53
  <slot name="tree-node-tool" :data="nodeData"> </slot>
49
54
  </template>
@@ -63,6 +68,7 @@ import type { LayerNodeStatus, TreeNodeData } from '@editor/type';
63
68
  import { updateStatus } from '@editor/utils/tree';
64
69
 
65
70
  defineSlots<{
71
+ 'tree-node-label'(props: { data: TreeNodeData }): any;
66
72
  'tree-node-tool'(props: { data: TreeNodeData }): any;
67
73
  'tree-node-content'(props: { data: TreeNodeData }): any;
68
74
  }>();
@@ -108,7 +114,7 @@ const selected = computed(() => nodeStatus.value.selected);
108
114
  const visible = computed(() => nodeStatus.value.visible);
109
115
  const draggable = computed(() => nodeStatus.value.draggable);
110
116
 
111
- const hasChilren = computed(() => props.data.items && props.data.items.length > 0);
117
+ const hasChilren = computed(() => props.data.items?.some((item) => props.nodeStatusMap.get(item.id)?.visible));
112
118
 
113
119
  const handleDragStart = (event: DragEvent) => {
114
120
  treeEmit?.('node-dragstart', event, props.data);
@@ -1,4 +1,5 @@
1
1
  import type { EventOption } from '@tmagic/core';
2
+ import { CustomTargetOptions } from '@tmagic/dep';
2
3
  import type { FormConfig, FormState } from '@tmagic/form';
3
4
  import type { DataSourceSchema, Id, MApp, MNode } from '@tmagic/schema';
4
5
  import StageCore, {
@@ -6,6 +7,7 @@ import StageCore, {
6
7
  ContainerHighlightType,
7
8
  CustomizeMoveableOptionsCallbackConfig,
8
9
  MoveableOptions,
10
+ RenderType,
9
11
  UpdateDragEl,
10
12
  } from '@tmagic/stage';
11
13
 
@@ -38,6 +40,8 @@ export interface EditorProps {
38
40
  render?: (stage: StageCore) => HTMLDivElement | Promise<HTMLDivElement>;
39
41
  /** 中间工作区域中画布通过iframe渲染时的页面url */
40
42
  runtimeUrl?: string;
43
+ /** 是用iframe渲染还是直接渲染 */
44
+ renderType?: RenderType;
41
45
  /** 选中时是否自动滚动到可视区域 */
42
46
  autoScrollIntoView?: boolean;
43
47
  /** 组件的属性配置表单的dsl */
@@ -65,6 +69,8 @@ export interface EditorProps {
65
69
  updateDragEl?: UpdateDragEl;
66
70
  disabledDragStart?: boolean;
67
71
  extendFormState?: (state: FormState) => Record<string, any> | Promise<Record<string, any>>;
72
+ /** 自定义依赖收集器,复制组件时会将关联依赖一并复制 */
73
+ collectorOptions?: CustomTargetOptions;
68
74
  }
69
75
 
70
76
  export const defaultEditorProps = {
@@ -84,4 +90,5 @@ export const defaultEditorProps = {
84
90
  containerHighlightDuration: 800,
85
91
  containerHighlightType: ContainerHighlightType.DEFAULT,
86
92
  codeOptions: () => ({}),
93
+ renderType: RenderType.IFRAME,
87
94
  };
@@ -0,0 +1,55 @@
1
+ import { type Ref, ref } from 'vue';
2
+
3
+ import type { Id, MNode } from '@tmagic/schema';
4
+
5
+ import type { LayerNodeStatus, TreeNodeData } from '@editor/type';
6
+ import { traverseNode } from '@editor/utils';
7
+ import { updateStatus } from '@editor/utils/tree';
8
+
9
+ export const useFilter = (
10
+ nodeData: Ref<TreeNodeData[]>,
11
+ nodeStatusMap: Ref<Map<Id, LayerNodeStatus> | undefined>,
12
+ filterNodeMethod: (value: string, data: MNode) => boolean,
13
+ ) => {
14
+ // tree方法:对树节点进行筛选时执行的方法
15
+ const filterIsMatch = (value: string | string[], data: MNode): boolean => {
16
+ const string = !Array.isArray(value) ? [value] : value;
17
+
18
+ if (!string.length) {
19
+ return true;
20
+ }
21
+
22
+ return string.some((v) => filterNodeMethod(v, data));
23
+ };
24
+
25
+ const filter = (text: string | string[]) => {
26
+ if (!nodeData.value.length) return;
27
+
28
+ nodeData.value.forEach((node) => {
29
+ traverseNode(node, (node: MNode, parents: MNode[]) => {
30
+ if (!nodeStatusMap.value) return;
31
+
32
+ const visible = filterIsMatch(text, node);
33
+ if (visible && parents.length) {
34
+ parents.forEach((parent) => {
35
+ updateStatus(nodeStatusMap.value!, parent.id, {
36
+ visible,
37
+ expand: true,
38
+ });
39
+ });
40
+ }
41
+
42
+ updateStatus(nodeStatusMap.value, node.id, {
43
+ visible,
44
+ });
45
+ });
46
+ });
47
+ };
48
+
49
+ return {
50
+ filterText: ref(''),
51
+ filterTextChangeHandler(text: string | string[]) {
52
+ filter(text);
53
+ },
54
+ };
55
+ };
@@ -0,0 +1,48 @@
1
+ import { ComputedRef, ref, watch } from 'vue';
2
+
3
+ import type { Id, MNode } from '@tmagic/schema';
4
+
5
+ import { LayerNodeStatus, TreeNodeData } from '@editor/type';
6
+ import { traverseNode } from '@editor/utils';
7
+
8
+ const createPageNodeStatus = (nodeData: TreeNodeData[], initalLayerNodeStatus?: Map<Id, LayerNodeStatus>) => {
9
+ const map = new Map<Id, LayerNodeStatus>();
10
+
11
+ nodeData.forEach((node: MNode) =>
12
+ traverseNode(node, (node) => {
13
+ map.set(
14
+ node.id,
15
+ initalLayerNodeStatus?.get(node.id) || {
16
+ visible: true,
17
+ expand: false,
18
+ selected: false,
19
+ draggable: false,
20
+ },
21
+ );
22
+ }),
23
+ );
24
+
25
+ return map;
26
+ };
27
+
28
+ export const useNodeStatus = (nodeData: ComputedRef<TreeNodeData[]>) => {
29
+ /** 所有页面的节点状态 */
30
+ const nodeStatusMap = ref(new Map<Id, LayerNodeStatus>());
31
+
32
+ // 切换页面或者新增页面,重新生成节点状态
33
+ watch(
34
+ nodeData,
35
+ (nodeData) => {
36
+ // 生成节点状态
37
+ nodeStatusMap.value = createPageNodeStatus(nodeData, nodeStatusMap.value);
38
+ },
39
+ {
40
+ immediate: true,
41
+ deep: true,
42
+ },
43
+ );
44
+
45
+ return {
46
+ nodeStatusMap,
47
+ };
48
+ };
@@ -31,6 +31,7 @@ export const useStage = (stageOptions: StageOptions) => {
31
31
  containerHighlightDuration: stageOptions.containerHighlightDuration,
32
32
  containerHighlightType: stageOptions.containerHighlightType,
33
33
  disabledDragStart: stageOptions.disabledDragStart,
34
+ renderType: stageOptions.renderType,
34
35
  canSelect: (el, event, stop) => {
35
36
  const elCanSelect = stageOptions.canSelect(el);
36
37
  // 在组件联动过程中不能再往下选择,返回并触发 ui-select
@@ -2,13 +2,14 @@ import { onUnmounted, reactive, toRaw, watch } from 'vue';
2
2
  import { cloneDeep } from 'lodash-es';
3
3
 
4
4
  import type { EventOption } from '@tmagic/core';
5
- import type { Target } from '@tmagic/dep';
6
5
  import {
7
6
  createCodeBlockTarget,
8
7
  createDataSourceCondTarget,
9
8
  createDataSourceMethodTarget,
10
9
  createDataSourceTarget,
10
+ createRelatedCompTarget,
11
11
  DepTargetType,
12
+ Target,
12
13
  } from '@tmagic/dep';
13
14
  import type { CodeBlockContent, DataSourceSchema, Id, MApp, MNode, MPage } from '@tmagic/schema';
14
15
  import { getNodes } from '@tmagic/utils';
@@ -186,7 +187,7 @@ export const initServiceEvents = (
186
187
  return stage?.renderer.runtime?.getApp?.();
187
188
  };
188
189
 
189
- const updateDataSoucreSchema = () => {
190
+ const updateDataSourceSchema = () => {
190
191
  const root = editorService.get('root');
191
192
 
192
193
  if (root?.dataSources) {
@@ -194,7 +195,7 @@ export const initServiceEvents = (
194
195
  }
195
196
  };
196
197
 
197
- const upateNodeWhenDataSourceChange = (nodes: MNode[]) => {
198
+ const updateNodeWhenDataSourceChange = (nodes: MNode[]) => {
198
199
  const root = editorService.get('root');
199
200
  const stage = editorService.get('stage');
200
201
 
@@ -210,7 +211,7 @@ export const initServiceEvents = (
210
211
  app.dsl.dataSources = root.dataSources;
211
212
  }
212
213
 
213
- updateDataSoucreSchema();
214
+ updateDataSourceSchema();
214
215
 
215
216
  nodes.forEach((node) => {
216
217
  const deps = Object.values(root.dataSourceDeps || {});
@@ -258,11 +259,11 @@ export const initServiceEvents = (
258
259
  };
259
260
 
260
261
  const depUpdateHandler = (node: MNode) => {
261
- upateNodeWhenDataSourceChange([node]);
262
+ updateNodeWhenDataSourceChange([node]);
262
263
  };
263
264
 
264
265
  const collectedHandler = (nodes: MNode[]) => {
265
- upateNodeWhenDataSourceChange(nodes);
266
+ updateNodeWhenDataSourceChange(nodes);
266
267
  };
267
268
 
268
269
  depService.on('add-target', targetAddHandler);
@@ -291,7 +292,7 @@ export const initServiceEvents = (
291
292
  depService.addTarget(createCodeBlockTarget(id, code));
292
293
  });
293
294
 
294
- value.dataSources.forEach((ds) => {
295
+ dataSourceService.get('dataSources').forEach((ds) => {
295
296
  initDataSourceDepTarget(ds);
296
297
  });
297
298
 
@@ -350,8 +351,8 @@ export const initServiceEvents = (
350
351
  editorService.on('update', nodeUpdateHandler);
351
352
 
352
353
  const codeBlockAddOrUpdateHandler = (id: Id, codeBlock: CodeBlockContent) => {
353
- if (depService.hasTarget(id)) {
354
- depService.getTarget(id)!.name = codeBlock.name;
354
+ if (depService.hasTarget(id, DepTargetType.CODE_BLOCK)) {
355
+ depService.getTarget(id, DepTargetType.CODE_BLOCK)!.name = codeBlock.name;
355
356
  return;
356
357
  }
357
358
 
@@ -359,7 +360,7 @@ export const initServiceEvents = (
359
360
  };
360
361
 
361
362
  const codeBlockRemoveHandler = (id: Id) => {
362
- depService.removeTarget(id);
363
+ depService.removeTarget(id, DepTargetType.CODE_BLOCK);
363
364
  };
364
365
 
365
366
  codeBlockService.on('addOrUpdate', codeBlockAddOrUpdateHandler);
@@ -372,16 +373,26 @@ export const initServiceEvents = (
372
373
 
373
374
  const dataSourceUpdateHandler = (config: DataSourceSchema) => {
374
375
  const root = editorService.get('root');
376
+ removeDataSourceTarget(config.id);
377
+ initDataSourceDepTarget(config);
378
+
379
+ depService.collect(root?.items || [], true);
375
380
 
376
381
  const targets = depService.getTargets(DepTargetType.DATA_SOURCE);
377
382
 
378
383
  const nodes = getNodes(Object.keys(targets[config.id].deps), root?.items);
379
384
 
380
- upateNodeWhenDataSourceChange(nodes);
385
+ updateNodeWhenDataSourceChange(nodes);
386
+ };
387
+
388
+ const removeDataSourceTarget = (id: string) => {
389
+ depService.removeTarget(id, DepTargetType.DATA_SOURCE);
390
+ depService.removeTarget(id, DepTargetType.DATA_SOURCE_COND);
391
+ depService.removeTarget(id, DepTargetType.DATA_SOURCE_METHOD);
381
392
  };
382
393
 
383
394
  const dataSourceRemoveHandler = (id: string) => {
384
- depService.removeTarget(id);
395
+ removeDataSourceTarget(id);
385
396
  getApp()?.dataSourceManager?.removeDataSource(id);
386
397
  };
387
398
 
@@ -389,6 +400,11 @@ export const initServiceEvents = (
389
400
  dataSourceService.on('update', dataSourceUpdateHandler);
390
401
  dataSourceService.on('remove', dataSourceRemoveHandler);
391
402
 
403
+ // 初始化复制组件相关的依赖收集器
404
+ if (props.collectorOptions && !depService.hasTarget(DepTargetType.RELATED_COMP_WHEN_COPY)) {
405
+ depService.addTarget(createRelatedCompTarget(props.collectorOptions));
406
+ }
407
+
392
408
  onUnmounted(() => {
393
409
  depService.off('add-target', targetAddHandler);
394
410
  depService.off('remove-target', targetRemoveHandler);
@@ -4,13 +4,13 @@
4
4
  <div
5
5
  class="m-editor-sidebar-header-item"
6
6
  v-for="(config, index) in sideBarItems"
7
+ v-show="!floatBoxStates?.get(config.$key)?.status"
8
+ draggable="true"
7
9
  :key="config.$key ?? index"
8
10
  :class="{ 'is-active': activeTabName === config.text }"
9
11
  @click="activeTabName = config.text || `${index}`"
10
- draggable="true"
11
12
  @dragstart="dragstartHandler"
12
13
  @dragend="dragendHandler(config.$key, $event)"
13
- v-show="!floatBoxStates?.get(config.$key)?.status"
14
14
  >
15
15
  <MIcon v-if="config.icon" :icon="config.icon"></MIcon>
16
16
  <div v-if="config.text" class="magic-editor-tab-panel-title">{{ config.text }}</div>
@@ -74,6 +74,11 @@
74
74
  <component v-else-if="config.slots?.layerNodeContent" :is="config.slots.layerNodeContent" :data="nodeData" />
75
75
  </template>
76
76
 
77
+ <template #layer-node-label="{ data: nodeData }" v-if="config.$key === 'layer' || config.slots?.layerNodeLabel">
78
+ <slot v-if="config.$key === 'layer'" name="layer-node-label" :data="nodeData"></slot>
79
+ <component v-else-if="config.slots?.layerNodeLabel" :is="config.slots.layerNodeTool" :data="nodeData" />
80
+ </template>
81
+
77
82
  <template #layer-node-tool="{ data: nodeData }" v-if="config.$key === 'layer' || config.slots?.layerNodeTool">
78
83
  <slot v-if="config.$key === 'layer'" name="layer-node-tool" :data="nodeData"></slot>
79
84
  <component v-else-if="config.slots?.layerNodeTool" :is="config.slots.layerNodeTool" :data="nodeData" />