@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
@@ -1,57 +1,42 @@
1
1
  <template>
2
- <TMagicTree
3
- ref="tree"
4
- class="magic-editor-layer-tree"
5
- node-key="id"
6
- empty-text="暂无代码块"
7
- :default-expanded-keys="expandedKeys"
8
- :expand-on-click-node="false"
9
- :data="codeList"
10
- :props="{
11
- children: 'children',
12
- label: 'name',
13
- value: 'id',
14
- }"
15
- :highlight-current="true"
16
- :filter-node-method="filterNode"
17
- @node-click="clickHandler"
18
- >
19
- <template #default="{ data }">
20
- <div :id="data.id" class="list-container">
21
- <div class="list-item">
22
- <CodeIcon v-if="data.type === 'code'" class="codeIcon"></CodeIcon>
23
- <AppManageIcon v-if="data.type === 'node'" class="compIcon"></AppManageIcon>
24
- <span class="name" :class="{ code: data.type === 'code', hook: data.type === 'key' }"
25
- >{{ data.name }} ({{ data.id }})</span
26
- >
27
- <!-- 右侧工具栏 -->
28
- <div class="right-tool" v-if="data.type === 'code'">
29
- <TMagicTooltip effect="dark" :content="editable ? '编辑' : '查看'" placement="bottom">
30
- <Icon :icon="editable ? Edit : View" class="edit-icon" @click.stop="editCode(data.id)"></Icon>
31
- </TMagicTooltip>
32
- <TMagicTooltip v-if="editable" effect="dark" content="删除" placement="bottom">
33
- <Icon :icon="Close" class="edit-icon" @click.stop="deleteCode(`${data.id}`)"></Icon>
34
- </TMagicTooltip>
35
- <slot name="code-block-panel-tool" :id="data.id" :data="data.codeBlockContent"></slot>
36
- </div>
37
- </div>
2
+ <Tree :data="codeList" :node-status-map="nodeStatusMap" @node-click="clickHandler">
3
+ <template #tree-node-label="{ data }">
4
+ <div
5
+ :class="{
6
+ code: data.type === 'code',
7
+ hook: data.type === 'key',
8
+ disabled: data.type === 'key' || data.type === 'code',
9
+ }"
10
+ >
11
+ {{ data.name }} {{ data.key ? `(${data.key})` : '' }}
38
12
  </div>
39
13
  </template>
40
- </TMagicTree>
14
+
15
+ <template #tree-node-tool="{ data }">
16
+ <TMagicTooltip v-if="data.type === 'code'" effect="dark" :content="editable ? '编辑' : '查看'" placement="bottom">
17
+ <Icon :icon="editable ? Edit : View" class="edit-icon" @click.stop="editCode(`${data.key}`)"></Icon>
18
+ </TMagicTooltip>
19
+ <TMagicTooltip v-if="data.type === 'code' && editable" effect="dark" content="删除" placement="bottom">
20
+ <Icon :icon="Close" class="edit-icon" @click.stop="deleteCode(`${data.key}`)"></Icon>
21
+ </TMagicTooltip>
22
+ <slot name="code-block-panel-tool" :id="data.key" :data="data"></slot>
23
+ </template>
24
+ </Tree>
41
25
  </template>
42
26
 
43
27
  <script lang="ts" setup>
44
- import { computed, inject, ref } from 'vue';
28
+ import { computed, inject } from 'vue';
45
29
  import { Close, Edit, View } from '@element-plus/icons-vue';
46
30
 
47
31
  import { DepTargetType } from '@tmagic/dep';
48
- import { tMagicMessage, tMagicMessageBox, TMagicTooltip, TMagicTree } from '@tmagic/design';
49
- import type { Id } from '@tmagic/schema';
32
+ import { tMagicMessage, tMagicMessageBox, TMagicTooltip } from '@tmagic/design';
33
+ import type { Id, MNode } from '@tmagic/schema';
50
34
 
51
35
  import Icon from '@editor/components/Icon.vue';
52
- import AppManageIcon from '@editor/icons/AppManageIcon.vue';
53
- import CodeIcon from '@editor/icons/CodeIcon.vue';
54
- import { type CodeBlockListSlots, CodeDeleteErrorType, type CodeDslItem, type Services } from '@editor/type';
36
+ import Tree from '@editor/components/Tree.vue';
37
+ import { useFilter } from '@editor/hooks/use-filter';
38
+ import { useNodeStatus } from '@editor/hooks/use-node-status';
39
+ import { type CodeBlockListSlots, CodeDeleteErrorType, type Services, type TreeNodeData } from '@editor/type';
55
40
 
56
41
  defineSlots<CodeBlockListSlots>();
57
42
 
@@ -68,38 +53,49 @@ const emit = defineEmits<{
68
53
  remove: [id: string];
69
54
  }>();
70
55
 
71
- const { codeBlockService, depService, editorService } = inject<Services>('services') || {};
56
+ const services = inject<Services>('services');
57
+ const { codeBlockService, depService, editorService } = services || {};
72
58
 
73
59
  // 代码块列表
74
- const codeList = computed(() =>
60
+ const codeList = computed<TreeNodeData[]>(() =>
75
61
  Object.values(depService?.getTargets(DepTargetType.CODE_BLOCK) || {}).map((target) => {
76
62
  // 组件节点
77
- const compNodes = Object.entries(target.deps).map(([id, dep]) => ({
63
+ const compNodes: TreeNodeData[] = Object.entries(target.deps).map(([id, dep]) => ({
78
64
  name: dep.name,
79
65
  type: 'node',
80
- id,
81
- children: dep.keys.map((key) => ({ name: key, id: key, type: 'key' })),
66
+ id: `${target.id}_${id}`,
67
+ key: id,
68
+ items: dep.keys.map((key) => {
69
+ const data: TreeNodeData = { name: `${key}`, id: `${target.id}_${id}_${key}`, type: 'key' };
70
+ return data;
71
+ }),
82
72
  }));
83
- return {
73
+
74
+ const data: TreeNodeData = {
84
75
  id: target.id,
76
+ key: target.id,
85
77
  name: target.name,
86
78
  type: 'code',
87
79
  codeBlockContent: codeBlockService?.getCodeContentById(target.id),
88
- children: compNodes,
80
+ items: compNodes,
89
81
  };
82
+
83
+ return data;
90
84
  }),
91
85
  );
92
- // 默认展开组件层级的节点
93
- const expandedKeys = computed(() => codeList.value.map((item) => item.id));
94
- const editable = computed(() => codeBlockService?.getEditStatus());
95
86
 
96
- const filterNode = (value: string, data: CodeDslItem): boolean => {
87
+ const filterNode = (value: string, data: MNode): boolean => {
97
88
  if (!value) {
98
89
  return true;
99
90
  }
100
- return `${data.name}${data.id}`.toLocaleLowerCase().indexOf(value.toLocaleLowerCase()) !== -1;
91
+ return `${data.name}${data.id}`.toLocaleLowerCase().includes(value.toLocaleLowerCase());
101
92
  };
102
93
 
94
+ const { nodeStatusMap } = useNodeStatus(codeList);
95
+ const { filterTextChangeHandler } = useFilter(codeList, nodeStatusMap, filterNode);
96
+
97
+ const editable = computed(() => codeBlockService?.getEditStatus());
98
+
103
99
  // 选中组件
104
100
  const selectComp = (compId: Id) => {
105
101
  const stage = editorService?.get('stage');
@@ -107,11 +103,9 @@ const selectComp = (compId: Id) => {
107
103
  stage?.select(compId);
108
104
  };
109
105
 
110
- const clickHandler = (data: any, node: any) => {
106
+ const clickHandler = (event: MouseEvent, data: any) => {
111
107
  if (data.type === 'node') {
112
- selectComp(data.id);
113
- } else if (data.type === 'key') {
114
- selectComp(node.parent.data.id);
108
+ selectComp(data.key);
115
109
  }
116
110
  };
117
111
 
@@ -122,7 +116,7 @@ const editCode = (id: string) => {
122
116
 
123
117
  const deleteCode = async (id: string) => {
124
118
  const currentCode = codeList.value.find((codeItem) => codeItem.id === id);
125
- const existBinds = Boolean(currentCode?.children.length);
119
+ const existBinds = Boolean(currentCode?.items?.length);
126
120
  const undeleteableList = codeBlockService?.getUndeletableList() || [];
127
121
  if (!existBinds && !undeleteableList.includes(id)) {
128
122
  await tMagicMessageBox.confirm('确定删除该代码块吗?', '提示', {
@@ -142,11 +136,7 @@ const deleteCode = async (id: string) => {
142
136
  }
143
137
  };
144
138
 
145
- const tree = ref<InstanceType<typeof TMagicTree>>();
146
-
147
139
  defineExpose({
148
- filter(val: string) {
149
- tree.value?.filter(val);
150
- },
140
+ filter: filterTextChangeHandler,
151
141
  });
152
142
  </script>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <TMagicScrollbar class="m-editor-code-block-list m-editor-dep-list-panel">
2
+ <TMagicScrollbar class="m-editor-code-block-list m-editor-layer-panel">
3
3
  <slot name="code-block-panel-header">
4
4
  <div class="search-wrapper">
5
5
  <SearchInput @search="filterTextChangeHandler"></SearchInput>
@@ -17,6 +17,7 @@
17
17
  </template>
18
18
  </CodeBlockList>
19
19
  </TMagicScrollbar>
20
+
20
21
  <!-- 代码块编辑区 -->
21
22
  <CodeBlockEditor
22
23
  v-if="codeConfig"
@@ -1,48 +1,40 @@
1
1
  <template>
2
- <TMagicTree
3
- ref="tree"
4
- class="magic-editor-layer-tree"
5
- node-key="id"
6
- empty-text="暂无代码块"
7
- default-expand-all
8
- :expand-on-click-node="false"
9
- :data="list"
10
- :highlight-current="true"
11
- @node-click="clickHandler"
12
- >
13
- <template #default="{ data }">
14
- <div :id="data.id" class="list-container">
15
- <div class="list-item">
16
- <Icon v-if="data.type === 'code'" class="codeIcon" :icon="Coin"></Icon>
17
- <Icon v-if="data.type === 'node'" class="compIcon" :icon="Aim"></Icon>
18
- <span class="name" :class="{ code: data.type === 'ds', hook: data.type === 'key' }">{{
19
- data.type === 'key' ? data.name : `${data.name}(${data.id})`
20
- }}</span>
21
- <!-- 右侧工具栏 -->
22
- <div class="right-tool" v-if="data.type === 'ds'">
23
- <TMagicTooltip effect="dark" :content="editable ? '编辑' : '查看'" placement="bottom">
24
- <Icon :icon="editable ? Edit : View" class="edit-icon" @click.stop="editHandler(`${data.id}`)"></Icon>
25
- </TMagicTooltip>
26
- <TMagicTooltip v-if="editable" effect="dark" content="删除" placement="bottom">
27
- <Icon :icon="Close" class="edit-icon" @click.stop="removeHandler(`${data.id}`)"></Icon>
28
- </TMagicTooltip>
29
- <slot name="data-source-panel-tool" :data="data"></slot>
30
- </div>
31
- </div>
2
+ <Tree :data="list" :node-status-map="nodeStatusMap" @node-click="clickHandler">
3
+ <template #tree-node-label="{ data }">
4
+ <div
5
+ :class="{
6
+ ds: data.type === 'ds',
7
+ hook: data.type === 'key',
8
+ disabled: data.type === 'key' || data.type === 'ds',
9
+ }"
10
+ >
11
+ {{ data.name }} {{ data.key ? `(${data.key})` : '' }}
32
12
  </div>
33
13
  </template>
34
- </TMagicTree>
14
+ <template #tree-node-tool="{ data }">
15
+ <TMagicTooltip v-if="data.type === 'ds'" effect="dark" :content="editable ? '编辑' : '查看'" placement="bottom">
16
+ <Icon :icon="editable ? Edit : View" class="edit-icon" @click.stop="editHandler(`${data.key}`)"></Icon>
17
+ </TMagicTooltip>
18
+ <TMagicTooltip v-if="data.type === 'ds' && editable" effect="dark" content="删除" placement="bottom">
19
+ <Icon :icon="Close" class="edit-icon" @click.stop="removeHandler(`${data.key}`)"></Icon>
20
+ </TMagicTooltip>
21
+ <slot name="data-source-panel-tool" :data="data"></slot>
22
+ </template>
23
+ </Tree>
35
24
  </template>
36
25
 
37
26
  <script lang="ts" setup>
38
- import { computed, inject, ref } from 'vue';
39
- import { Aim, Close, Coin, Edit, View } from '@element-plus/icons-vue';
27
+ import { computed, inject } from 'vue';
28
+ import { Close, Edit, View } from '@element-plus/icons-vue';
40
29
 
41
30
  import { DepTargetType } from '@tmagic/dep';
42
- import { tMagicMessageBox, TMagicTooltip, TMagicTree } from '@tmagic/design';
43
- import { DepData, Id } from '@tmagic/schema';
31
+ import { tMagicMessageBox, TMagicTooltip } from '@tmagic/design';
32
+ import { DepData, Id, MNode } from '@tmagic/schema';
44
33
 
45
34
  import Icon from '@editor/components/Icon.vue';
35
+ import Tree from '@editor/components/Tree.vue';
36
+ import { useFilter } from '@editor/hooks/use-filter';
37
+ import { useNodeStatus } from '@editor/hooks/use-node-status';
46
38
  import type { DataSourceListSlots, Services } from '@editor/type';
47
39
 
48
40
  defineSlots<DataSourceListSlots>();
@@ -66,32 +58,39 @@ const dsDep = computed(() => depService?.getTargets(DepTargetType.DATA_SOURCE) |
66
58
  const dsMethodDep = computed(() => depService?.getTargets(DepTargetType.DATA_SOURCE_METHOD) || {});
67
59
  const dsCondDep = computed(() => depService?.getTargets(DepTargetType.DATA_SOURCE_COND) || {});
68
60
 
69
- const getKeyTreeConfig = (dep: DepData[string], type?: string) =>
70
- dep.keys.map((key) => ({ name: key, id: key, type: 'key', isMethod: type === 'method', isCond: type === 'cond' }));
61
+ const getKeyTreeConfig = (dep: DepData[string], type?: string, parentKey?: Id) =>
62
+ dep.keys.map((key) => ({
63
+ name: key,
64
+ id: `${parentKey}_${key}`,
65
+ type: 'key',
66
+ isMethod: type === 'method',
67
+ isCond: type === 'cond',
68
+ }));
71
69
 
72
- const getNodeTreeConfig = (id: string, dep: DepData[string], type?: string) => ({
70
+ const getNodeTreeConfig = (id: string, dep: DepData[string], type?: string, parentKey?: Id) => ({
73
71
  name: dep.name,
74
72
  type: 'node',
75
- id,
76
- children: getKeyTreeConfig(dep, type),
73
+ id: `${parentKey}_${id}`,
74
+ key: id,
75
+ items: getKeyTreeConfig(dep, type, `${parentKey}_${id}`),
77
76
  });
78
77
 
79
78
  /**
80
79
  * 生成tree中依赖节点的数据
81
- * @param children 节点
80
+ * @param items 节点
82
81
  * @param deps 依赖
83
82
  * @param type 依赖类型
84
83
  */
85
- const mergeChildren = (children: any[], deps: DepData, type?: string) => {
84
+ const mergeChildren = (dsId: Id, items: any[], deps: DepData, type?: string) => {
86
85
  Object.entries(deps).forEach(([id, dep]) => {
87
86
  // 已经生成过的节点
88
- const nodeItem = children.find((item) => item.id === id);
87
+ const nodeItem = items.find((item) => item.key === id);
89
88
  // 节点存在,则追加依赖的key
90
89
  if (nodeItem) {
91
- nodeItem.children = nodeItem.children.concat(getKeyTreeConfig(dep, type));
90
+ nodeItem.items = nodeItem.items.concat(getKeyTreeConfig(dep, type, nodeItem.key));
92
91
  } else {
93
92
  // 节点不存在,则生成
94
- children.push(getNodeTreeConfig(id, dep, type));
93
+ items.push(getNodeTreeConfig(id, dep, type, dsId));
95
94
  }
96
95
  });
97
96
  };
@@ -102,21 +101,32 @@ const list = computed(() =>
102
101
  const dsMethodDeps = dsMethodDep.value[ds.id]?.deps || {};
103
102
  const dsCondDeps = dsCondDep.value[ds.id]?.deps || {};
104
103
 
105
- const children: any[] = [];
104
+ const items: any[] = [];
106
105
  // 数据源依赖分为三种类型:key/node、method、cond,是分开存储,这里将其合并展示
107
- mergeChildren(children, dsDeps);
108
- mergeChildren(children, dsMethodDeps, 'method');
109
- mergeChildren(children, dsCondDeps, 'cond');
106
+ mergeChildren(ds.id, items, dsDeps);
107
+ mergeChildren(ds.id, items, dsMethodDeps, 'method');
108
+ mergeChildren(ds.id, items, dsCondDeps, 'cond');
110
109
 
111
110
  return {
112
111
  id: ds.id,
112
+ key: ds.id,
113
113
  name: ds.title,
114
114
  type: 'ds',
115
- children,
115
+ items,
116
116
  };
117
117
  }),
118
118
  );
119
119
 
120
+ const filterNode = (value: string, data: MNode): boolean => {
121
+ if (!value) {
122
+ return true;
123
+ }
124
+ return `${data.name}${data.id}`.toLocaleLowerCase().includes(value.toLocaleLowerCase());
125
+ };
126
+
127
+ const { nodeStatusMap } = useNodeStatus(list);
128
+ const { filterTextChangeHandler } = useFilter(list, nodeStatusMap, filterNode);
129
+
120
130
  const editHandler = (id: string) => {
121
131
  emit('edit', id);
122
132
  };
@@ -138,19 +148,13 @@ const selectComp = (compId: Id) => {
138
148
  stage?.select(compId);
139
149
  };
140
150
 
141
- const clickHandler = (data: any, node: any) => {
151
+ const clickHandler = (event: MouseEvent, data: any) => {
142
152
  if (data.type === 'node') {
143
- selectComp(data.id);
144
- } else if (data.type === 'key') {
145
- selectComp(node.parent.data.id);
153
+ selectComp(data.key);
146
154
  }
147
155
  };
148
156
 
149
- const tree = ref<InstanceType<typeof TMagicTree>>();
150
-
151
157
  defineExpose({
152
- filter(val: string) {
153
- tree.value?.filter(val);
154
- },
158
+ filter: filterTextChangeHandler,
155
159
  });
156
160
  </script>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <TMagicScrollbar class="data-source-list-panel m-editor-dep-list-panel">
2
+ <TMagicScrollbar class="data-source-list-panel m-editor-layer-panel">
3
3
  <div class="search-wrapper">
4
4
  <SearchInput @search="filterTextChangeHandler"></SearchInput>
5
5
  <TMagicPopover v-if="editable" placement="right">
@@ -8,7 +8,7 @@
8
8
  v-if="page && nodeStatusMap"
9
9
  tabindex="-1"
10
10
  ref="tree"
11
- :data="[page]"
11
+ :data="nodeData"
12
12
  :node-status-map="nodeStatusMap"
13
13
  @node-dragover="handleDragOver"
14
14
  @node-dragstart="handleDragStart"
@@ -18,14 +18,18 @@
18
18
  @node-mouseenter="mouseenterHandler"
19
19
  @node-click="nodeClickHandler"
20
20
  >
21
+ <template #tree-node-content="{ data: nodeData }">
22
+ <slot name="layer-node-content" :data="nodeData"> </slot>
23
+ </template>
24
+
21
25
  <template #tree-node-tool="{ data: nodeData }">
22
26
  <slot name="layer-node-tool" :data="nodeData">
23
27
  <LayerNodeTool :data="nodeData"></LayerNodeTool>
24
28
  </slot>
25
29
  </template>
26
30
 
27
- <template #tree-node-content="{ data: nodeData }">
28
- <slot name="layer-node-content" :data="nodeData"> </slot>
31
+ <template #tree-node-label="{ data: nodeData }">
32
+ <slot name="layer-node-label" :data="nodeData"></slot>
29
33
  </template>
30
34
  </Tree>
31
35
 
@@ -39,16 +43,17 @@
39
43
  import { computed, inject, ref } from 'vue';
40
44
 
41
45
  import { TMagicScrollbar } from '@tmagic/design';
46
+ import type { MNode } from '@tmagic/schema';
42
47
 
43
48
  import SearchInput from '@editor/components/SearchInput.vue';
44
49
  import Tree from '@editor/components/Tree.vue';
45
- import { LayerPanelSlots, MenuButton, MenuComponent, Services } from '@editor/type';
50
+ import { useFilter } from '@editor/hooks/use-filter';
51
+ import { LayerPanelSlots, MenuButton, MenuComponent, Services, TreeNodeData } from '@editor/type';
46
52
 
47
53
  import LayerMenu from './LayerMenu.vue';
48
54
  import LayerNodeTool from './LayerNodeTool.vue';
49
55
  import { useClick } from './use-click';
50
56
  import { useDrag } from './use-drag';
51
- import { useFilter } from './use-filter';
52
57
  import { useKeybinding } from './use-keybinding';
53
58
  import { useNodeStatus } from './use-node-status';
54
59
 
@@ -68,11 +73,23 @@ const editorService = services?.editorService;
68
73
  const tree = ref<InstanceType<typeof Tree>>();
69
74
 
70
75
  const page = computed(() => editorService?.get('page'));
76
+ const nodeData = computed<TreeNodeData[]>(() => (!page.value ? [] : [page.value]));
71
77
 
72
- const { nodeStatusMap } = useNodeStatus(services, page);
78
+ const { nodeStatusMap } = useNodeStatus(services);
73
79
  const { isCtrlKeyDown } = useKeybinding(services, tree);
74
80
 
75
- const { filterTextChangeHandler } = useFilter(nodeStatusMap, page);
81
+ const filterNodeMethod = (v: string, data: MNode): boolean => {
82
+ let name = '';
83
+ if (data.name) {
84
+ name = data.name;
85
+ } else if (data.items) {
86
+ name = 'container';
87
+ }
88
+
89
+ return `${data.id}${name}${data.type}`.includes(v);
90
+ };
91
+
92
+ const { filterTextChangeHandler } = useFilter(nodeData, nodeStatusMap, filterNodeMethod);
76
93
 
77
94
  const collapseAllHandler = () => {
78
95
  if (!page.value || !nodeStatusMap.value) return;
@@ -1,4 +1,4 @@
1
- import { computed, type ComputedRef, ref, watch } from 'vue';
1
+ import { computed, ref, watch } from 'vue';
2
2
 
3
3
  import type { Id, MNode, MPage } from '@tmagic/schema';
4
4
  import { getNodePath } from '@tmagic/utils';
@@ -7,22 +7,18 @@ import { LayerNodeStatus, Services } from '@editor/type';
7
7
  import { traverseNode } from '@editor/utils';
8
8
  import { updateStatus } from '@editor/utils/tree';
9
9
 
10
- const createPageNodeStatus = (
11
- services: Services | undefined,
12
- pageId: Id,
13
- initalLayerNodeStatus?: Map<Id, LayerNodeStatus>,
14
- ) => {
10
+ const createPageNodeStatus = (page: MPage, initalLayerNodeStatus?: Map<Id, LayerNodeStatus>) => {
15
11
  const map = new Map<Id, LayerNodeStatus>();
16
12
 
17
- map.set(pageId, {
13
+ map.set(page.id, {
18
14
  visible: true,
19
15
  expand: true,
20
16
  selected: true,
21
17
  draggable: false,
22
18
  });
23
19
 
24
- services?.editorService.getNodeById(pageId)?.items.forEach((node: MNode) =>
25
- traverseNode(node, (node) => {
20
+ page.items.forEach((node: MNode) =>
21
+ traverseNode<MNode>(node, (node) => {
26
22
  map.set(
27
23
  node.id,
28
24
  initalLayerNodeStatus?.get(node.id) || {
@@ -38,7 +34,8 @@ const createPageNodeStatus = (
38
34
  return map;
39
35
  };
40
36
 
41
- export const useNodeStatus = (services: Services | undefined, page: ComputedRef<MPage | null | undefined>) => {
37
+ export const useNodeStatus = (services: Services | undefined) => {
38
+ const page = computed(() => services?.editorService.get('page'));
42
39
  const nodes = computed(() => services?.editorService.get('nodes') || []);
43
40
 
44
41
  /** 所有页面的节点状态 */
@@ -57,7 +54,7 @@ export const useNodeStatus = (services: Services | undefined, page: ComputedRef<
57
54
  return;
58
55
  }
59
56
  // 生成节点状态
60
- nodeStatusMaps.value.set(page.id, createPageNodeStatus(services, page.id, nodeStatusMaps.value.get(page.id)));
57
+ nodeStatusMaps.value.set(page.id, createPageNodeStatus(page, nodeStatusMaps.value.get(page.id)));
61
58
  },
62
59
  {
63
60
  immediate: true,