@tmagic/editor 1.4.6 → 1.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/tmagic-editor.js +324 -139
- package/dist/tmagic-editor.umd.cjs +323 -138
- package/package.json +9 -9
- package/src/components/TreeNode.vue +3 -1
- package/src/editorProps.ts +0 -7
- package/src/fields/DataSourceInput.vue +7 -1
- package/src/fields/EventSelect.vue +90 -16
- package/src/initService.ts +24 -28
- package/src/layouts/sidebar/code-block/CodeBlockList.vue +34 -16
- package/src/layouts/sidebar/data-source/DataSourceList.vue +17 -5
- package/src/services/codeBlock.ts +14 -11
- package/src/services/dataSource.ts +14 -7
- package/src/services/dep.ts +77 -5
- package/src/services/editor.ts +23 -14
- package/src/services/props.ts +14 -8
- package/src/utils/data-source/index.ts +20 -13
- package/src/utils/idle-task.ts +72 -0
- package/src/utils/operator.ts +6 -6
- package/types/editorProps.d.ts +0 -7
- package/types/layouts/PropsPanel.vue.d.ts +9 -9
- package/types/services/codeBlock.d.ts +2 -1
- package/types/services/dataSource.d.ts +2 -1
- package/types/services/dep.d.ts +12 -2
- package/types/services/editor.d.ts +3 -2
- package/types/services/props.d.ts +2 -1
- package/types/utils/idle-task.d.ts +14 -0
- package/types/utils/operator.d.ts +2 -2
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.4.
|
|
2
|
+
"version": "1.4.7",
|
|
3
3
|
"name": "@tmagic/editor",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": [
|
|
@@ -50,8 +50,8 @@
|
|
|
50
50
|
"lodash-es": "^4.17.21",
|
|
51
51
|
"moveable": "^0.53.0",
|
|
52
52
|
"serialize-javascript": "^6.0.0",
|
|
53
|
-
"@tmagic/dep": "1.4.
|
|
54
|
-
"@tmagic/table": "1.4.
|
|
53
|
+
"@tmagic/dep": "1.4.7",
|
|
54
|
+
"@tmagic/table": "1.4.7"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@types/events": "^3.0.0",
|
|
@@ -72,12 +72,12 @@
|
|
|
72
72
|
"monaco-editor": "^0.48.0",
|
|
73
73
|
"vue": "^3.4.27",
|
|
74
74
|
"typescript": "*",
|
|
75
|
-
"@tmagic/
|
|
76
|
-
"@tmagic/
|
|
77
|
-
"@tmagic/
|
|
78
|
-
"@tmagic/
|
|
79
|
-
"@tmagic/
|
|
80
|
-
"@tmagic/
|
|
75
|
+
"@tmagic/core": "1.4.7",
|
|
76
|
+
"@tmagic/design": "1.4.7",
|
|
77
|
+
"@tmagic/form": "1.4.7",
|
|
78
|
+
"@tmagic/schema": "1.4.7",
|
|
79
|
+
"@tmagic/stage": "1.4.7",
|
|
80
|
+
"@tmagic/utils": "1.4.7"
|
|
81
81
|
},
|
|
82
82
|
"peerDependenciesMeta": {
|
|
83
83
|
"typescript": {
|
|
@@ -114,7 +114,9 @@ const selected = computed(() => nodeStatus.value.selected);
|
|
|
114
114
|
const visible = computed(() => nodeStatus.value.visible);
|
|
115
115
|
const draggable = computed(() => nodeStatus.value.draggable);
|
|
116
116
|
|
|
117
|
-
const hasChildren = computed(
|
|
117
|
+
const hasChildren = computed(
|
|
118
|
+
() => Array.isArray(props.data.items) && props.data.items.some((item) => props.nodeStatusMap.get(item.id)?.visible),
|
|
119
|
+
);
|
|
118
120
|
|
|
119
121
|
const handleDragStart = (event: DragEvent) => {
|
|
120
122
|
treeEmit?.('node-dragstart', event, props.data);
|
package/src/editorProps.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { EventOption } from '@tmagic/core';
|
|
2
|
-
import type { CustomTargetOptions } from '@tmagic/dep';
|
|
3
2
|
import type { FormConfig, FormState } from '@tmagic/form';
|
|
4
3
|
import type { DataSourceSchema, Id, MApp, MNode } from '@tmagic/schema';
|
|
5
4
|
import StageCore, {
|
|
@@ -70,12 +69,6 @@ export interface EditorProps {
|
|
|
70
69
|
codeOptions?: { [key: string]: any };
|
|
71
70
|
/** 禁用鼠标左键按下时就开始拖拽,需要先选中再可以拖拽 */
|
|
72
71
|
disabledDragStart?: boolean;
|
|
73
|
-
/** 自定义依赖收集器,复制组件时会将关联组件一并复制 */
|
|
74
|
-
collectorOptions?: CustomTargetOptions;
|
|
75
|
-
/** 自定义依赖收集器,复制组件时会将关联代码块一并复制 */
|
|
76
|
-
collectorOptionsForCode?: CustomTargetOptions;
|
|
77
|
-
/** 自定义依赖收集器,复制组件时会将关联数据源一并复制 */
|
|
78
|
-
collectorOptionsForDataSource?: CustomTargetOptions;
|
|
79
72
|
/** 标尺配置 */
|
|
80
73
|
guidesOptions?: Partial<GuidesOptions>;
|
|
81
74
|
/** 禁止多选 */
|
|
@@ -54,6 +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
58
|
|
|
58
59
|
import Icon from '@editor/components/Icon.vue';
|
|
59
60
|
import type { Services } from '@editor/type';
|
|
@@ -209,7 +210,7 @@ const fieldQuerySearch = (
|
|
|
209
210
|
const dsKey = queryString.substring(leftAngleIndex + 1, dotIndex);
|
|
210
211
|
|
|
211
212
|
// 可能是xx.xx.xx,存在链式调用
|
|
212
|
-
const keys = dsKey.split('.');
|
|
213
|
+
const keys = dsKey.replaceAll(/\[(\d+)\]/g, '.$1').split('.');
|
|
213
214
|
|
|
214
215
|
// 最前的是数据源id
|
|
215
216
|
const dsId = keys.shift();
|
|
@@ -224,6 +225,11 @@ const fieldQuerySearch = (
|
|
|
224
225
|
// 后面这些是字段
|
|
225
226
|
let key = keys.shift();
|
|
226
227
|
while (key) {
|
|
228
|
+
if (isNumber(key)) {
|
|
229
|
+
key = keys.shift();
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
|
|
227
233
|
for (const field of fields) {
|
|
228
234
|
if (field.name === key) {
|
|
229
235
|
fields = field.fields || [];
|
|
@@ -26,14 +26,14 @@
|
|
|
26
26
|
@change="onChangeHandler"
|
|
27
27
|
>
|
|
28
28
|
<template #header>
|
|
29
|
-
<
|
|
29
|
+
<MFormContainer
|
|
30
30
|
class="fullWidth"
|
|
31
31
|
:config="eventNameConfig"
|
|
32
32
|
:model="cardItem"
|
|
33
33
|
:disabled="disabled"
|
|
34
34
|
:size="size"
|
|
35
35
|
@change="onChangeHandler"
|
|
36
|
-
></
|
|
36
|
+
></MFormContainer>
|
|
37
37
|
<TMagicButton
|
|
38
38
|
style="color: #f56c6c"
|
|
39
39
|
link
|
|
@@ -55,13 +55,13 @@ import { has } from 'lodash-es';
|
|
|
55
55
|
|
|
56
56
|
import type { EventOption } from '@tmagic/core';
|
|
57
57
|
import { TMagicButton } from '@tmagic/design';
|
|
58
|
-
import type { CascaderOption, FieldProps, FormState, PanelConfig } from '@tmagic/form';
|
|
59
|
-
import { MContainer, MPanel } from '@tmagic/form';
|
|
60
|
-
import { ActionType } from '@tmagic/schema';
|
|
58
|
+
import type { CascaderOption, ChildConfig, FieldProps, FormState, PanelConfig } from '@tmagic/form';
|
|
59
|
+
import { MContainer as MFormContainer, MPanel } from '@tmagic/form';
|
|
60
|
+
import { ActionType, type MComponent, type MContainer } from '@tmagic/schema';
|
|
61
61
|
import { DATA_SOURCE_FIELDS_CHANGE_EVENT_PREFIX } from '@tmagic/utils';
|
|
62
62
|
|
|
63
63
|
import type { CodeSelectColConfig, DataSourceMethodSelectConfig, EventSelectConfig, Services } from '@editor/type';
|
|
64
|
-
import { getCascaderOptionsFromFields } from '@editor/utils';
|
|
64
|
+
import { getCascaderOptionsFromFields, traverseNode } from '@editor/utils';
|
|
65
65
|
|
|
66
66
|
defineOptions({
|
|
67
67
|
name: 'MFieldsEventSelect',
|
|
@@ -80,13 +80,20 @@ const codeBlockService = services?.codeBlockService;
|
|
|
80
80
|
|
|
81
81
|
// 事件名称下拉框表单配置
|
|
82
82
|
const eventNameConfig = computed(() => {
|
|
83
|
-
const
|
|
84
|
-
const defaultEventNameConfig = {
|
|
83
|
+
const defaultEventNameConfig: ChildConfig = {
|
|
85
84
|
name: 'name',
|
|
86
85
|
text: '事件',
|
|
87
|
-
type:
|
|
86
|
+
type: (mForm, { formValue }: any) => {
|
|
87
|
+
if (
|
|
88
|
+
props.config.src !== 'component' ||
|
|
89
|
+
(formValue.type === 'page-fragment-container' && formValue.pageFragmentId)
|
|
90
|
+
) {
|
|
91
|
+
return 'cascader';
|
|
92
|
+
}
|
|
93
|
+
return 'select';
|
|
94
|
+
},
|
|
88
95
|
labelWidth: '40px',
|
|
89
|
-
checkStrictly:
|
|
96
|
+
checkStrictly: () => props.config.src !== 'component',
|
|
90
97
|
valueSeparator: '.',
|
|
91
98
|
options: (mForm: FormState, { formValue }: any) => {
|
|
92
99
|
let events: EventOption[] | CascaderOption[] = [];
|
|
@@ -95,11 +102,39 @@ const eventNameConfig = computed(() => {
|
|
|
95
102
|
|
|
96
103
|
if (props.config.src === 'component') {
|
|
97
104
|
events = eventsService.getEvent(formValue.type);
|
|
105
|
+
|
|
106
|
+
if (formValue.type === 'page-fragment-container' && formValue.pageFragmentId) {
|
|
107
|
+
const pageFragment = editorService?.get('root')?.items?.find((page) => page.id === formValue.pageFragmentId);
|
|
108
|
+
if (pageFragment) {
|
|
109
|
+
events = [
|
|
110
|
+
{
|
|
111
|
+
label: pageFragment.name || '迭代器容器',
|
|
112
|
+
value: pageFragment.id,
|
|
113
|
+
children: events,
|
|
114
|
+
},
|
|
115
|
+
];
|
|
116
|
+
pageFragment.items.forEach((node) => {
|
|
117
|
+
traverseNode<MComponent | MContainer>(node, (node) => {
|
|
118
|
+
const nodeEvents = (node.type && eventsService.getEvent(node.type)) || [];
|
|
119
|
+
|
|
120
|
+
events.push({
|
|
121
|
+
label: `${node.name}_${node.id}`,
|
|
122
|
+
value: `${node.id}`,
|
|
123
|
+
children: nodeEvents,
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
return events;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
98
132
|
return events.map((option) => ({
|
|
99
133
|
text: option.label,
|
|
100
134
|
value: option.value,
|
|
101
135
|
}));
|
|
102
136
|
}
|
|
137
|
+
|
|
103
138
|
if (props.config.src === 'datasource') {
|
|
104
139
|
// 从数据源类型中获取到相关事件
|
|
105
140
|
events = dataSourceService.getFormEvent(formValue.type);
|
|
@@ -163,24 +198,63 @@ const targetCompConfig = computed(() => {
|
|
|
163
198
|
text: '联动组件',
|
|
164
199
|
type: 'ui-select',
|
|
165
200
|
display: (mForm: FormState, { model }: { model: Record<any, any> }) => model.actionType === ActionType.COMP,
|
|
201
|
+
onChange: (MForm: FormState, v: string, { model }: any) => {
|
|
202
|
+
model.method = '';
|
|
203
|
+
return v;
|
|
204
|
+
},
|
|
166
205
|
};
|
|
167
206
|
return { ...defaultTargetCompConfig, ...props.config.targetCompConfig };
|
|
168
207
|
});
|
|
169
208
|
|
|
170
209
|
// 联动组件动作配置
|
|
171
210
|
const compActionConfig = computed(() => {
|
|
172
|
-
const defaultCompActionConfig = {
|
|
211
|
+
const defaultCompActionConfig: ChildConfig = {
|
|
173
212
|
name: 'method',
|
|
174
213
|
text: '动作',
|
|
175
|
-
type:
|
|
176
|
-
|
|
214
|
+
type: (mForm, { model }: any) => {
|
|
215
|
+
const to = editorService?.getNodeById(model.to);
|
|
216
|
+
|
|
217
|
+
if (to && to.type === 'page-fragment-container' && to.pageFragmentId) {
|
|
218
|
+
return 'cascader';
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return 'select';
|
|
222
|
+
},
|
|
223
|
+
checkStrictly: () => props.config.src !== 'component',
|
|
224
|
+
display: (mForm, { model }: any) => model.actionType === ActionType.COMP,
|
|
177
225
|
options: (mForm: FormState, { model }: any) => {
|
|
178
226
|
const node = editorService?.getNodeById(model.to);
|
|
179
227
|
if (!node?.type) return [];
|
|
180
228
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
229
|
+
let methods: EventOption[] | CascaderOption[] = [];
|
|
230
|
+
|
|
231
|
+
methods = eventsService?.getMethod(node.type) || [];
|
|
232
|
+
|
|
233
|
+
if (node.type === 'page-fragment-container' && node.pageFragmentId) {
|
|
234
|
+
const pageFragment = editorService?.get('root')?.items?.find((page) => page.id === node.pageFragmentId);
|
|
235
|
+
if (pageFragment) {
|
|
236
|
+
methods = [];
|
|
237
|
+
pageFragment.items.forEach((node: MComponent | MContainer) => {
|
|
238
|
+
traverseNode<MComponent | MContainer>(node, (node) => {
|
|
239
|
+
const nodeMethods = (node.type && eventsService?.getMethod(node.type)) || [];
|
|
240
|
+
|
|
241
|
+
if (nodeMethods.length) {
|
|
242
|
+
methods.push({
|
|
243
|
+
label: `${node.name}_${node.id}`,
|
|
244
|
+
value: `${node.id}`,
|
|
245
|
+
children: nodeMethods,
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
return methods;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return methods.map((method) => ({
|
|
256
|
+
text: method.label,
|
|
257
|
+
value: method.value,
|
|
184
258
|
}));
|
|
185
259
|
},
|
|
186
260
|
};
|
package/src/initService.ts
CHANGED
|
@@ -7,12 +7,11 @@ import {
|
|
|
7
7
|
createDataSourceCondTarget,
|
|
8
8
|
createDataSourceMethodTarget,
|
|
9
9
|
createDataSourceTarget,
|
|
10
|
-
createRelatedTargetForCopy,
|
|
11
10
|
DepTargetType,
|
|
12
11
|
Target,
|
|
13
12
|
} from '@tmagic/dep';
|
|
14
13
|
import type { CodeBlockContent, DataSourceSchema, Id, MApp, MNode, MPage, MPageFragment } from '@tmagic/schema';
|
|
15
|
-
import { getNodes } from '@tmagic/utils';
|
|
14
|
+
import { getNodes, isPage } from '@tmagic/utils';
|
|
16
15
|
|
|
17
16
|
import PropsPanel from './layouts/PropsPanel.vue';
|
|
18
17
|
import { EditorProps } from './editorProps';
|
|
@@ -268,17 +267,12 @@ export const initServiceEvents = (
|
|
|
268
267
|
}
|
|
269
268
|
};
|
|
270
269
|
|
|
271
|
-
const depUpdateHandler = (node: MNode) => {
|
|
272
|
-
updateNodeWhenDataSourceChange([node]);
|
|
273
|
-
};
|
|
274
|
-
|
|
275
270
|
const collectedHandler = (nodes: MNode[]) => {
|
|
276
271
|
updateNodeWhenDataSourceChange(nodes);
|
|
277
272
|
};
|
|
278
273
|
|
|
279
274
|
depService.on('add-target', targetAddHandler);
|
|
280
275
|
depService.on('remove-target', targetRemoveHandler);
|
|
281
|
-
depService.on('dep-update', depUpdateHandler);
|
|
282
276
|
depService.on('collected', collectedHandler);
|
|
283
277
|
|
|
284
278
|
const initDataSourceDepTarget = (ds: DataSourceSchema) => {
|
|
@@ -307,7 +301,9 @@ export const initServiceEvents = (
|
|
|
307
301
|
});
|
|
308
302
|
|
|
309
303
|
if (Array.isArray(value.items)) {
|
|
310
|
-
|
|
304
|
+
value.items.forEach((page) => {
|
|
305
|
+
depService.collectIdle([page], { pageId: page.id }, true);
|
|
306
|
+
});
|
|
311
307
|
} else {
|
|
312
308
|
depService.clear();
|
|
313
309
|
delete value.dataSourceDeps;
|
|
@@ -334,14 +330,28 @@ export const initServiceEvents = (
|
|
|
334
330
|
}
|
|
335
331
|
};
|
|
336
332
|
|
|
333
|
+
const collectIdle = (nodes: MNode[], deep: boolean) => {
|
|
334
|
+
nodes.forEach((node) => {
|
|
335
|
+
let pageId: Id | undefined;
|
|
336
|
+
|
|
337
|
+
if (isPage(node)) {
|
|
338
|
+
pageId = node.id;
|
|
339
|
+
} else {
|
|
340
|
+
const info = editorService.getNodeInfo(node.id);
|
|
341
|
+
pageId = info.page?.id;
|
|
342
|
+
}
|
|
343
|
+
depService.collectIdle([node], { pageId }, deep);
|
|
344
|
+
});
|
|
345
|
+
};
|
|
346
|
+
|
|
337
347
|
// 新增节点,收集依赖
|
|
338
348
|
const nodeAddHandler = (nodes: MNode[]) => {
|
|
339
|
-
|
|
349
|
+
collectIdle(nodes, true);
|
|
340
350
|
};
|
|
341
351
|
|
|
342
352
|
// 节点更新,收集依赖
|
|
343
353
|
const nodeUpdateHandler = (nodes: MNode[]) => {
|
|
344
|
-
|
|
354
|
+
collectIdle(nodes, false);
|
|
345
355
|
};
|
|
346
356
|
|
|
347
357
|
// 节点删除,清除对齐的依赖收集
|
|
@@ -351,7 +361,7 @@ export const initServiceEvents = (
|
|
|
351
361
|
|
|
352
362
|
// 由于历史记录变化是更新整个page,所以历史记录变化时,需要重新收集依赖
|
|
353
363
|
const historyChangeHandler = (page: MPage | MPageFragment) => {
|
|
354
|
-
depService.
|
|
364
|
+
depService.collectIdle([page], { pageId: page.id }, true);
|
|
355
365
|
};
|
|
356
366
|
|
|
357
367
|
editorService.on('history-change', historyChangeHandler);
|
|
@@ -386,7 +396,9 @@ export const initServiceEvents = (
|
|
|
386
396
|
removeDataSourceTarget(config.id);
|
|
387
397
|
initDataSourceDepTarget(config);
|
|
388
398
|
|
|
389
|
-
|
|
399
|
+
(root?.items || []).forEach((page) => {
|
|
400
|
+
depService.collectIdle([page], { pageId: page.id }, true);
|
|
401
|
+
});
|
|
390
402
|
|
|
391
403
|
const targets = depService.getTargets(DepTargetType.DATA_SOURCE);
|
|
392
404
|
|
|
@@ -410,25 +422,9 @@ export const initServiceEvents = (
|
|
|
410
422
|
dataSourceService.on('update', dataSourceUpdateHandler);
|
|
411
423
|
dataSourceService.on('remove', dataSourceRemoveHandler);
|
|
412
424
|
|
|
413
|
-
// 初始化复制组件相关的依赖收集器
|
|
414
|
-
if (props.collectorOptions && !depService.hasTarget(DepTargetType.RELATED_COMP_WHEN_COPY)) {
|
|
415
|
-
depService.addTarget(createRelatedTargetForCopy(props.collectorOptions, DepTargetType.RELATED_COMP_WHEN_COPY));
|
|
416
|
-
}
|
|
417
|
-
if (props.collectorOptionsForCode && !depService.hasTarget(DepTargetType.RELATED_CODE_WHEN_COPY)) {
|
|
418
|
-
depService.addTarget(
|
|
419
|
-
createRelatedTargetForCopy(props.collectorOptionsForCode, DepTargetType.RELATED_CODE_WHEN_COPY),
|
|
420
|
-
);
|
|
421
|
-
}
|
|
422
|
-
if (props.collectorOptionsForDataSource && !depService.hasTarget(DepTargetType.RELATED_DS_WHEN_COPY)) {
|
|
423
|
-
depService.addTarget(
|
|
424
|
-
createRelatedTargetForCopy(props.collectorOptionsForDataSource, DepTargetType.RELATED_DS_WHEN_COPY),
|
|
425
|
-
);
|
|
426
|
-
}
|
|
427
|
-
|
|
428
425
|
onBeforeUnmount(() => {
|
|
429
426
|
depService.off('add-target', targetAddHandler);
|
|
430
427
|
depService.off('remove-target', targetRemoveHandler);
|
|
431
|
-
depService.off('dep-update', depUpdateHandler);
|
|
432
428
|
depService.off('collected', collectedHandler);
|
|
433
429
|
|
|
434
430
|
editorService.off('history-change', historyChangeHandler);
|
|
@@ -58,26 +58,44 @@ const { codeBlockService, depService, editorService } = services || {};
|
|
|
58
58
|
|
|
59
59
|
// 代码块列表
|
|
60
60
|
const codeList = computed<TreeNodeData[]>(() =>
|
|
61
|
-
Object.
|
|
61
|
+
Object.entries(codeBlockService?.getCodeDsl() || {}).map(([codeId, code]) => {
|
|
62
|
+
const target = depService?.getTarget(codeId, DepTargetType.CODE_BLOCK);
|
|
63
|
+
|
|
64
|
+
// 按页面分类显示
|
|
65
|
+
const pageList: TreeNodeData[] =
|
|
66
|
+
editorService?.get('root')?.items.map((page) => ({
|
|
67
|
+
name: page.devconfig?.tabName || page.name,
|
|
68
|
+
type: 'node',
|
|
69
|
+
id: `${codeId}_${page.id}`,
|
|
70
|
+
key: page.id,
|
|
71
|
+
items: [],
|
|
72
|
+
})) || [];
|
|
73
|
+
|
|
62
74
|
// 组件节点
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
75
|
+
if (target) {
|
|
76
|
+
Object.entries(target.deps).forEach(([id, dep]) => {
|
|
77
|
+
const page = pageList.find((page) => page.key === dep.data?.pageId);
|
|
78
|
+
page?.items?.push({
|
|
79
|
+
name: dep.name,
|
|
80
|
+
type: 'node',
|
|
81
|
+
id: `${page.id}_${id}`,
|
|
82
|
+
key: id,
|
|
83
|
+
items: dep.keys.map((key) => {
|
|
84
|
+
const data: TreeNodeData = { name: `${key}`, id: `${target.id}_${id}_${key}`, type: 'key' };
|
|
85
|
+
return data;
|
|
86
|
+
}),
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
}
|
|
73
90
|
|
|
74
91
|
const data: TreeNodeData = {
|
|
75
|
-
id:
|
|
76
|
-
key:
|
|
77
|
-
name:
|
|
92
|
+
id: codeId,
|
|
93
|
+
key: codeId,
|
|
94
|
+
name: code.name,
|
|
78
95
|
type: 'code',
|
|
79
|
-
codeBlockContent: codeBlockService?.getCodeContentById(
|
|
80
|
-
|
|
96
|
+
codeBlockContent: codeBlockService?.getCodeContentById(codeId),
|
|
97
|
+
// 只有一个页面不显示页面分类
|
|
98
|
+
items: pageList.length > 1 ? pageList.filter((page) => page.items?.length) : pageList[0]?.items || [],
|
|
81
99
|
};
|
|
82
100
|
|
|
83
101
|
return data;
|
|
@@ -81,16 +81,19 @@ const getNodeTreeConfig = (id: string, dep: DepData[string], type?: string, pare
|
|
|
81
81
|
* @param deps 依赖
|
|
82
82
|
* @param type 依赖类型
|
|
83
83
|
*/
|
|
84
|
-
const mergeChildren = (dsId: Id,
|
|
84
|
+
const mergeChildren = (dsId: Id, pageItems: any[], deps: DepData, type?: string) => {
|
|
85
85
|
Object.entries(deps).forEach(([id, dep]) => {
|
|
86
|
+
// 按页面分类显示
|
|
87
|
+
const page = pageItems.find((page) => page.key === dep.data?.pageId);
|
|
88
|
+
|
|
86
89
|
// 已经生成过的节点
|
|
87
|
-
const nodeItem = items.find((item) => item.key === id);
|
|
90
|
+
const nodeItem = page?.items.find((item: any) => item.key === id);
|
|
88
91
|
// 节点存在,则追加依赖的key
|
|
89
92
|
if (nodeItem) {
|
|
90
93
|
nodeItem.items = nodeItem.items.concat(getKeyTreeConfig(dep, type, nodeItem.key));
|
|
91
94
|
} else {
|
|
92
95
|
// 节点不存在,则生成
|
|
93
|
-
items.push(getNodeTreeConfig(id, dep, type,
|
|
96
|
+
page?.items.push(getNodeTreeConfig(id, dep, type, page.id));
|
|
94
97
|
}
|
|
95
98
|
});
|
|
96
99
|
};
|
|
@@ -101,7 +104,15 @@ const list = computed(() =>
|
|
|
101
104
|
const dsMethodDeps = dsMethodDep.value[ds.id]?.deps || {};
|
|
102
105
|
const dsCondDeps = dsCondDep.value[ds.id]?.deps || {};
|
|
103
106
|
|
|
104
|
-
const items
|
|
107
|
+
const items =
|
|
108
|
+
editorService?.get('root')?.items.map((page) => ({
|
|
109
|
+
name: page.devconfig?.tabName || page.name,
|
|
110
|
+
type: 'node',
|
|
111
|
+
id: `${ds.id}_${page.id}`,
|
|
112
|
+
key: page.id,
|
|
113
|
+
items: [],
|
|
114
|
+
})) || [];
|
|
115
|
+
|
|
105
116
|
// 数据源依赖分为三种类型:key/node、method、cond,是分开存储,这里将其合并展示
|
|
106
117
|
mergeChildren(ds.id, items, dsDeps);
|
|
107
118
|
mergeChildren(ds.id, items, dsMethodDeps, 'method');
|
|
@@ -112,7 +123,8 @@ const list = computed(() =>
|
|
|
112
123
|
key: ds.id,
|
|
113
124
|
name: ds.title,
|
|
114
125
|
type: 'ds',
|
|
115
|
-
|
|
126
|
+
// 只有一个页面不显示页面分类
|
|
127
|
+
items: items.length > 1 ? items.filter((page) => page.items.length) : items[0]?.items || [],
|
|
116
128
|
};
|
|
117
129
|
}),
|
|
118
130
|
);
|
|
@@ -20,11 +20,10 @@ import { reactive } from 'vue';
|
|
|
20
20
|
import { cloneDeep, get, keys, pick } from 'lodash-es';
|
|
21
21
|
import type { Writable } from 'type-fest';
|
|
22
22
|
|
|
23
|
-
import {
|
|
23
|
+
import { Target, type TargetOptions, Watcher } from '@tmagic/dep';
|
|
24
24
|
import type { ColumnConfig } from '@tmagic/form';
|
|
25
25
|
import type { CodeBlockContent, CodeBlockDSL, Id, MNode } from '@tmagic/schema';
|
|
26
26
|
|
|
27
|
-
import depService from '@editor/services/dep';
|
|
28
27
|
import editorService from '@editor/services/editor';
|
|
29
28
|
import storageService, { Protocol } from '@editor/services/storage';
|
|
30
29
|
import type { AsyncHookPlugin, CodeState } from '@editor/type';
|
|
@@ -258,17 +257,21 @@ class CodeBlock extends BaseService {
|
|
|
258
257
|
* @param config 组件节点配置
|
|
259
258
|
* @returns
|
|
260
259
|
*/
|
|
261
|
-
public copyWithRelated(config: MNode | MNode[]): void {
|
|
260
|
+
public copyWithRelated(config: MNode | MNode[], collectorOptions?: TargetOptions): void {
|
|
262
261
|
const copyNodes: MNode[] = Array.isArray(config) ? config : [config];
|
|
263
|
-
// 关联的代码块也一并复制
|
|
264
|
-
depService.clearByType(DepTargetType.RELATED_CODE_WHEN_COPY);
|
|
265
|
-
depService.collect(copyNodes, true, DepTargetType.RELATED_CODE_WHEN_COPY);
|
|
266
|
-
const customTarget = depService.getTarget(
|
|
267
|
-
DepTargetType.RELATED_CODE_WHEN_COPY,
|
|
268
|
-
DepTargetType.RELATED_CODE_WHEN_COPY,
|
|
269
|
-
);
|
|
270
262
|
const copyData: CodeBlockDSL = {};
|
|
271
|
-
|
|
263
|
+
|
|
264
|
+
if (collectorOptions && typeof collectorOptions.isTarget === 'function') {
|
|
265
|
+
const customTarget = new Target({
|
|
266
|
+
...collectorOptions,
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
const coperWatcher = new Watcher();
|
|
270
|
+
|
|
271
|
+
coperWatcher.addTarget(customTarget);
|
|
272
|
+
|
|
273
|
+
coperWatcher.collect(copyNodes, {}, true, collectorOptions.type);
|
|
274
|
+
|
|
272
275
|
Object.keys(customTarget.deps).forEach((nodeId: Id) => {
|
|
273
276
|
const node = editorService.getNodeById(nodeId);
|
|
274
277
|
if (!node) return;
|
|
@@ -3,12 +3,11 @@ import { cloneDeep, get } from 'lodash-es';
|
|
|
3
3
|
import { Writable } from 'type-fest';
|
|
4
4
|
|
|
5
5
|
import type { EventOption } from '@tmagic/core';
|
|
6
|
-
import {
|
|
6
|
+
import { Target, type TargetOptions, Watcher } from '@tmagic/dep';
|
|
7
7
|
import type { FormConfig } from '@tmagic/form';
|
|
8
8
|
import type { DataSourceSchema, Id, MNode } from '@tmagic/schema';
|
|
9
9
|
import { guid, toLine } from '@tmagic/utils';
|
|
10
10
|
|
|
11
|
-
import depService from '@editor/services/dep';
|
|
12
11
|
import editorService from '@editor/services/editor';
|
|
13
12
|
import storageService, { Protocol } from '@editor/services/storage';
|
|
14
13
|
import type { DatasourceTypeOption, SyncHookPlugin } from '@editor/type';
|
|
@@ -163,13 +162,21 @@ class DataSource extends BaseService {
|
|
|
163
162
|
* @param config 组件节点配置
|
|
164
163
|
* @returns
|
|
165
164
|
*/
|
|
166
|
-
public copyWithRelated(config: MNode | MNode[]): void {
|
|
165
|
+
public copyWithRelated(config: MNode | MNode[], collectorOptions?: TargetOptions): void {
|
|
167
166
|
const copyNodes: MNode[] = Array.isArray(config) ? config : [config];
|
|
168
|
-
depService.clearByType(DepTargetType.RELATED_DS_WHEN_COPY);
|
|
169
|
-
depService.collect(copyNodes, true, DepTargetType.RELATED_DS_WHEN_COPY);
|
|
170
|
-
const customTarget = depService.getTarget(DepTargetType.RELATED_DS_WHEN_COPY, DepTargetType.RELATED_DS_WHEN_COPY);
|
|
171
167
|
const copyData: DataSourceSchema[] = [];
|
|
172
|
-
|
|
168
|
+
|
|
169
|
+
if (collectorOptions && typeof collectorOptions.isTarget === 'function') {
|
|
170
|
+
const customTarget = new Target({
|
|
171
|
+
...collectorOptions,
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
const coperWatcher = new Watcher();
|
|
175
|
+
|
|
176
|
+
coperWatcher.addTarget(customTarget);
|
|
177
|
+
|
|
178
|
+
coperWatcher.collect(copyNodes, {}, true, collectorOptions.type);
|
|
179
|
+
|
|
173
180
|
Object.keys(customTarget.deps).forEach((nodeId: Id) => {
|
|
174
181
|
const node = editorService.getNodeById(nodeId);
|
|
175
182
|
if (!node) return;
|