@tmagic/editor 1.5.0-beta.8 → 1.5.0
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/style.css +75 -16
- package/dist/tmagic-editor.js +797 -518
- package/dist/tmagic-editor.umd.cjs +802 -525
- package/package.json +13 -10
- package/src/Editor.vue +6 -1
- package/src/components/CodeBlockEditor.vue +11 -5
- package/src/components/CodeParams.vue +3 -3
- package/src/editorProps.ts +3 -1
- package/src/fields/Code.vue +1 -2
- package/src/fields/CodeSelect.vue +13 -11
- package/src/fields/CodeSelectCol.vue +32 -5
- package/src/fields/CondOpSelect.vue +5 -2
- package/src/fields/DataSourceFields.vue +31 -12
- package/src/fields/DataSourceMethods.vue +72 -14
- package/src/fields/DisplayConds.vue +8 -3
- package/src/fields/EventSelect.vue +28 -11
- package/src/fields/KeyValue.vue +15 -10
- package/src/fields/UISelect.vue +6 -3
- package/src/hooks/index.ts +0 -1
- package/src/hooks/use-code-block-edit.ts +1 -1
- package/src/hooks/use-data-source-edit.ts +3 -2
- package/src/hooks/use-filter.ts +1 -1
- package/src/hooks/use-node-status.ts +2 -2
- package/src/initService.ts +177 -74
- package/src/layouts/Framework.vue +8 -4
- package/src/layouts/PropsPanel.vue +3 -3
- package/src/layouts/page-bar/AddButton.vue +29 -9
- package/src/layouts/page-bar/PageBar.vue +78 -65
- package/src/layouts/page-bar/PageBarScrollContainer.vue +82 -96
- package/src/layouts/page-bar/PageList.vue +5 -3
- package/src/layouts/page-bar/Search.vue +67 -0
- package/src/layouts/sidebar/Sidebar.vue +3 -0
- package/src/layouts/sidebar/code-block/CodeBlockList.vue +6 -1
- package/src/layouts/sidebar/data-source/DataSourceConfigPanel.vue +7 -5
- package/src/layouts/sidebar/data-source/DataSourceList.vue +6 -1
- package/src/layouts/sidebar/layer/use-node-status.ts +2 -3
- package/src/layouts/workspace/Workspace.vue +5 -2
- package/src/layouts/workspace/viewer/Stage.vue +23 -5
- package/src/services/dataSource.ts +12 -5
- package/src/services/dep.ts +61 -13
- package/src/services/editor.ts +46 -51
- package/src/theme/page-bar.scss +38 -16
- package/src/theme/search-input.scss +1 -0
- package/src/type.ts +2 -1
- package/src/utils/data-source/formConfigs/http.ts +2 -0
- package/src/utils/data-source/index.ts +2 -2
- package/src/utils/editor.ts +78 -22
- package/src/utils/idle-task.ts +36 -4
- package/src/utils/props.ts +3 -3
- package/types/index.d.ts +835 -1169
- package/src/hooks/use-data-source-method.ts +0 -100
- package/src/layouts/page-bar/SwitchTypeButton.vue +0 -45
package/src/fields/KeyValue.vue
CHANGED
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
v-if="config.advanced && showCode"
|
|
40
40
|
height="200px"
|
|
41
41
|
:init-values="model[name]"
|
|
42
|
-
language="
|
|
42
|
+
language="javascript"
|
|
43
43
|
:options="{
|
|
44
44
|
readOnly: disabled,
|
|
45
45
|
}"
|
|
@@ -86,22 +86,27 @@ const props = withDefaults(
|
|
|
86
86
|
},
|
|
87
87
|
);
|
|
88
88
|
|
|
89
|
-
const emit = defineEmits<
|
|
89
|
+
const emit = defineEmits<{
|
|
90
|
+
change: [value: Record<string, any>];
|
|
91
|
+
}>();
|
|
90
92
|
|
|
91
93
|
const records = ref<[string, string][]>([]);
|
|
92
94
|
const showCode = ref(false);
|
|
93
95
|
|
|
94
96
|
watchEffect(() => {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
97
|
+
if (typeof props.model[props.name] === 'function') {
|
|
98
|
+
showCode.value = true;
|
|
99
|
+
} else {
|
|
100
|
+
const initValues: [string, any][] = Object.entries(props.model[props.name] || {});
|
|
101
|
+
|
|
102
|
+
for (const [, value] of initValues) {
|
|
103
|
+
if (typeof value !== 'string') {
|
|
104
|
+
showCode.value = true;
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
101
107
|
}
|
|
108
|
+
records.value = initValues;
|
|
102
109
|
}
|
|
103
|
-
|
|
104
|
-
records.value = initValues;
|
|
105
110
|
});
|
|
106
111
|
|
|
107
112
|
const getValue = () => {
|
package/src/fields/UISelect.vue
CHANGED
|
@@ -45,7 +45,7 @@ import { computed, inject, ref } from 'vue';
|
|
|
45
45
|
import { Close, Delete } from '@element-plus/icons-vue';
|
|
46
46
|
import { throttle } from 'lodash-es';
|
|
47
47
|
|
|
48
|
-
import type { Id } from '@tmagic/core';
|
|
48
|
+
import type { Id, MNode } from '@tmagic/core';
|
|
49
49
|
import { TMagicButton, TMagicTooltip } from '@tmagic/design';
|
|
50
50
|
import type { FieldProps, FormItem, FormState } from '@tmagic/form';
|
|
51
51
|
import { getIdFromEl } from '@tmagic/utils';
|
|
@@ -72,8 +72,11 @@ const cancelHandler = () => {
|
|
|
72
72
|
globalThis.document.removeEventListener(UI_SELECT_MODE_EVENT_NAME, clickHandler as EventListener);
|
|
73
73
|
};
|
|
74
74
|
|
|
75
|
-
const clickHandler = ({ detail }: Event & { detail: HTMLElement }) => {
|
|
76
|
-
|
|
75
|
+
const clickHandler = ({ detail }: Event & { detail: HTMLElement | MNode }) => {
|
|
76
|
+
let { id } = detail;
|
|
77
|
+
if (detail.nodeType) {
|
|
78
|
+
id = getIdFromEl()(detail as HTMLElement) || id;
|
|
79
|
+
}
|
|
77
80
|
if (id) {
|
|
78
81
|
props.model[props.name] = id;
|
|
79
82
|
emit('change', id);
|
package/src/hooks/index.ts
CHANGED
|
@@ -21,7 +21,7 @@ export const useCodeBlockEdit = (codeBlockService?: CodeBlockService) => {
|
|
|
21
21
|
|
|
22
22
|
codeConfig.value = {
|
|
23
23
|
name: '',
|
|
24
|
-
content: `({app, params}) => {\n // place your code here\n}`,
|
|
24
|
+
content: `({app, params, flowState}) => {\n // place your code here\n}`,
|
|
25
25
|
params: [],
|
|
26
26
|
};
|
|
27
27
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { computed, ref } from 'vue';
|
|
2
2
|
|
|
3
3
|
import type { DataSourceSchema } from '@tmagic/core';
|
|
4
|
+
import type { ContainerChangeEventData } from '@tmagic/form';
|
|
4
5
|
|
|
5
6
|
import DataSourceConfigPanel from '@editor/layouts/sidebar/data-source/DataSourceConfigPanel.vue';
|
|
6
7
|
import type { DataSourceService } from '@editor/services/dataSource';
|
|
@@ -24,9 +25,9 @@ export const useDataSourceEdit = (dataSourceService?: DataSourceService) => {
|
|
|
24
25
|
editDialog.value.show();
|
|
25
26
|
};
|
|
26
27
|
|
|
27
|
-
const submitDataSourceHandler = (value: DataSourceSchema) => {
|
|
28
|
+
const submitDataSourceHandler = (value: DataSourceSchema, eventData: ContainerChangeEventData) => {
|
|
28
29
|
if (value.id) {
|
|
29
|
-
dataSourceService?.update(value);
|
|
30
|
+
dataSourceService?.update(value, { changeRecords: eventData.changeRecords });
|
|
30
31
|
} else {
|
|
31
32
|
dataSourceService?.add(value);
|
|
32
33
|
}
|
package/src/hooks/use-filter.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { type Ref, ref } from 'vue';
|
|
2
2
|
|
|
3
3
|
import type { Id, MNode } from '@tmagic/core';
|
|
4
|
+
import { traverseNode } from '@tmagic/utils';
|
|
4
5
|
|
|
5
6
|
import type { LayerNodeStatus, TreeNodeData } from '@editor/type';
|
|
6
|
-
import { traverseNode } from '@editor/utils';
|
|
7
7
|
import { updateStatus } from '@editor/utils/tree';
|
|
8
8
|
|
|
9
9
|
export const useFilter = (
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { ComputedRef, ref, watch } from 'vue';
|
|
1
|
+
import { type ComputedRef, ref, watch } from 'vue';
|
|
2
2
|
|
|
3
3
|
import type { Id, MNode } from '@tmagic/core';
|
|
4
|
+
import { traverseNode } from '@tmagic/utils';
|
|
4
5
|
|
|
5
6
|
import { LayerNodeStatus, TreeNodeData } from '@editor/type';
|
|
6
|
-
import { traverseNode } from '@editor/utils';
|
|
7
7
|
|
|
8
8
|
const createPageNodeStatus = (nodeData: TreeNodeData[], initialLayerNodeStatus?: Map<Id, LayerNodeStatus>) => {
|
|
9
9
|
const map = new Map<Id, LayerNodeStatus>();
|
package/src/initService.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { onBeforeUnmount, reactive, toRaw, watch } from 'vue';
|
|
1
|
+
import { computed, onBeforeUnmount, reactive, toRaw, watch } from 'vue';
|
|
2
2
|
import { cloneDeep } from 'lodash-es';
|
|
3
3
|
|
|
4
4
|
import type {
|
|
@@ -17,14 +17,16 @@ import {
|
|
|
17
17
|
createDataSourceMethodTarget,
|
|
18
18
|
createDataSourceTarget,
|
|
19
19
|
DepTargetType,
|
|
20
|
+
NODE_CONDS_KEY,
|
|
20
21
|
Target,
|
|
21
22
|
} from '@tmagic/core';
|
|
22
|
-
import {
|
|
23
|
+
import { ChangeRecord } from '@tmagic/form';
|
|
24
|
+
import { getNodes, isPage, isValueIncludeDataSource, traverseNode } from '@tmagic/utils';
|
|
23
25
|
|
|
24
26
|
import PropsPanel from './layouts/PropsPanel.vue';
|
|
27
|
+
import { isIncludeDataSource } from './utils/editor';
|
|
25
28
|
import { EditorProps } from './editorProps';
|
|
26
29
|
import { Services } from './type';
|
|
27
|
-
import { traverseNode } from './utils';
|
|
28
30
|
|
|
29
31
|
export declare type LooseRequired<T> = {
|
|
30
32
|
[P in string & keyof T]: T[P];
|
|
@@ -220,6 +222,7 @@ export const initServiceEvents = (
|
|
|
220
222
|
});
|
|
221
223
|
|
|
222
224
|
if (Array.isArray(value.items)) {
|
|
225
|
+
depService.clearIdleTasks();
|
|
223
226
|
collectIdle(value.items, true);
|
|
224
227
|
} else {
|
|
225
228
|
depService.clear();
|
|
@@ -248,67 +251,41 @@ export const initServiceEvents = (
|
|
|
248
251
|
}
|
|
249
252
|
};
|
|
250
253
|
|
|
251
|
-
const
|
|
252
|
-
const stage = editorService.get('stage');
|
|
253
|
-
return stage?.renderer?.runtime?.getApp?.();
|
|
254
|
-
};
|
|
255
|
-
|
|
256
|
-
const updateDataSourceSchema = () => {
|
|
257
|
-
const root = editorService.get('root');
|
|
258
|
-
|
|
259
|
-
if (root?.dataSources) {
|
|
260
|
-
getApp()?.dataSourceManager?.updateSchema(root.dataSources);
|
|
261
|
-
}
|
|
262
|
-
};
|
|
254
|
+
const stage = computed(() => editorService.get('stage'));
|
|
263
255
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
if (target.type === DepTargetType.DATA_SOURCE) {
|
|
269
|
-
if (!root.dataSourceDeps) {
|
|
270
|
-
root.dataSourceDeps = {};
|
|
271
|
-
}
|
|
272
|
-
root.dataSourceDeps[target.id] = target.deps;
|
|
256
|
+
watch(stage, (stage) => {
|
|
257
|
+
if (!stage) {
|
|
258
|
+
return;
|
|
273
259
|
}
|
|
274
260
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
root.dataSourceCondDeps = {};
|
|
278
|
-
}
|
|
279
|
-
root.dataSourceCondDeps[target.id] = target.deps;
|
|
280
|
-
}
|
|
281
|
-
};
|
|
261
|
+
stage.on('rerender', () => {
|
|
262
|
+
const node = editorService.get('node');
|
|
282
263
|
|
|
283
|
-
|
|
284
|
-
const root = editorService.get('root');
|
|
264
|
+
if (!node) return;
|
|
285
265
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
266
|
+
collectIdle([node], true).then(() => {
|
|
267
|
+
afterUpdateNodes([node]);
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
});
|
|
289
271
|
|
|
290
|
-
|
|
291
|
-
delete root.dataSourceCondDeps[id];
|
|
292
|
-
}
|
|
293
|
-
};
|
|
272
|
+
const getApp = () => stage.value?.renderer?.runtime?.getApp?.();
|
|
294
273
|
|
|
295
|
-
const
|
|
274
|
+
const updateDataSourceSchema = (nodes: MNode[], deep: boolean) => {
|
|
296
275
|
const root = editorService.get('root');
|
|
297
|
-
const stage = editorService.get('stage');
|
|
298
|
-
|
|
299
|
-
if (!root || !stage) return;
|
|
300
|
-
|
|
301
276
|
const app = getApp();
|
|
302
277
|
|
|
303
|
-
if (
|
|
304
|
-
|
|
305
|
-
if (app.dsl) {
|
|
278
|
+
if (root && app?.dsl) {
|
|
306
279
|
app.dsl.dataSourceDeps = root.dataSourceDeps;
|
|
307
280
|
app.dsl.dataSourceCondDeps = root.dataSourceCondDeps;
|
|
308
281
|
app.dsl.dataSources = root.dataSources;
|
|
309
282
|
}
|
|
310
283
|
|
|
311
|
-
|
|
284
|
+
if (root?.dataSources) {
|
|
285
|
+
getApp()?.dataSourceManager?.updateSchema(root.dataSources);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (!root || !stage.value) return;
|
|
312
289
|
|
|
313
290
|
const allNodes: MNode[] = [];
|
|
314
291
|
|
|
@@ -329,7 +306,7 @@ export const initServiceEvents = (
|
|
|
329
306
|
Object.keys(dep).forEach((id) => {
|
|
330
307
|
const node = allNodes.find((node) => node.id === id);
|
|
331
308
|
node &&
|
|
332
|
-
stage.update({
|
|
309
|
+
stage.value?.update({
|
|
333
310
|
config: cloneDeep(node),
|
|
334
311
|
parentId: editorService.getParentById(node.id)?.id,
|
|
335
312
|
root: cloneDeep(root),
|
|
@@ -338,9 +315,63 @@ export const initServiceEvents = (
|
|
|
338
315
|
});
|
|
339
316
|
};
|
|
340
317
|
|
|
318
|
+
const afterUpdateNodes = (nodes: MNode[]) => {
|
|
319
|
+
const root = editorService.get('root');
|
|
320
|
+
if (!root) return;
|
|
321
|
+
for (const node of nodes) {
|
|
322
|
+
stage.value?.update({
|
|
323
|
+
config: cloneDeep(node),
|
|
324
|
+
parentId: editorService.getParentById(node.id)?.id,
|
|
325
|
+
root: cloneDeep(root),
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
const targetAddHandler = (target: Target) => {
|
|
331
|
+
const root = editorService.get('root');
|
|
332
|
+
if (!root) return;
|
|
333
|
+
|
|
334
|
+
if (target.type === DepTargetType.DATA_SOURCE) {
|
|
335
|
+
if (!root.dataSourceDeps) {
|
|
336
|
+
root.dataSourceDeps = {};
|
|
337
|
+
}
|
|
338
|
+
root.dataSourceDeps[target.id] = target.deps;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
if (target.type === DepTargetType.DATA_SOURCE_COND) {
|
|
342
|
+
if (!root.dataSourceCondDeps) {
|
|
343
|
+
root.dataSourceCondDeps = {};
|
|
344
|
+
}
|
|
345
|
+
root.dataSourceCondDeps[target.id] = target.deps;
|
|
346
|
+
}
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
const targetRemoveHandler = (id: string | number) => {
|
|
350
|
+
const root = editorService.get('root');
|
|
351
|
+
|
|
352
|
+
if (!root) return;
|
|
353
|
+
|
|
354
|
+
if (root.dataSourceDeps) {
|
|
355
|
+
delete root.dataSourceDeps[id];
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
if (root.dataSourceCondDeps) {
|
|
359
|
+
delete root.dataSourceCondDeps[id];
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
const depCollectedHandler = () => {
|
|
364
|
+
const root = editorService.get('root');
|
|
365
|
+
if (!root) return;
|
|
366
|
+
const app = getApp();
|
|
367
|
+
if (app?.dsl) {
|
|
368
|
+
app.dsl.dataSourceDeps = root.dataSourceDeps;
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
|
|
341
372
|
depService.on('add-target', targetAddHandler);
|
|
342
373
|
depService.on('remove-target', targetRemoveHandler);
|
|
343
|
-
depService.on('collected',
|
|
374
|
+
depService.on('collected', depCollectedHandler);
|
|
344
375
|
|
|
345
376
|
const initDataSourceDepTarget = (ds: DataSourceSchema) => {
|
|
346
377
|
depService.addTarget(createDataSourceTarget(ds, reactive({})));
|
|
@@ -348,28 +379,63 @@ export const initServiceEvents = (
|
|
|
348
379
|
depService.addTarget(createDataSourceCondTarget(ds, reactive({})));
|
|
349
380
|
};
|
|
350
381
|
|
|
351
|
-
const collectIdle = (nodes: MNode[], deep: boolean) =>
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
382
|
+
const collectIdle = (nodes: MNode[], deep: boolean) =>
|
|
383
|
+
Promise.all(
|
|
384
|
+
nodes.map((node) => {
|
|
385
|
+
let pageId: Id | undefined;
|
|
386
|
+
|
|
387
|
+
if (isPage(node)) {
|
|
388
|
+
pageId = node.id;
|
|
389
|
+
} else {
|
|
390
|
+
const info = editorService.getNodeInfo(node.id);
|
|
391
|
+
pageId = info.page?.id;
|
|
392
|
+
}
|
|
393
|
+
return depService.collectIdle([node], { pageId }, deep);
|
|
394
|
+
}),
|
|
395
|
+
);
|
|
364
396
|
|
|
365
397
|
// 新增节点,收集依赖
|
|
366
398
|
const nodeAddHandler = (nodes: MNode[]) => {
|
|
367
|
-
collectIdle(nodes, true)
|
|
399
|
+
collectIdle(nodes, true).then(() => {
|
|
400
|
+
afterUpdateNodes(nodes);
|
|
401
|
+
});
|
|
368
402
|
};
|
|
369
403
|
|
|
370
404
|
// 节点更新,收集依赖
|
|
371
|
-
|
|
372
|
-
|
|
405
|
+
// 仅当修改到数据源相关的才收集
|
|
406
|
+
const nodeUpdateHandler = (data: { newNode: MNode; oldNode: MNode; changeRecords?: ChangeRecord[] }[]) => {
|
|
407
|
+
const needRecollectNodes: MNode[] = [];
|
|
408
|
+
const normalNodes: MNode[] = [];
|
|
409
|
+
data.forEach(({ newNode, oldNode, changeRecords }) => {
|
|
410
|
+
if (changeRecords?.length) {
|
|
411
|
+
for (const record of changeRecords) {
|
|
412
|
+
// NODE_CONDS_KEY为显示条件key
|
|
413
|
+
if (
|
|
414
|
+
!record.propPath ||
|
|
415
|
+
new RegExp(`${NODE_CONDS_KEY}.(\\d)+.cond`).test(record.propPath) ||
|
|
416
|
+
new RegExp(`${NODE_CONDS_KEY}.(\\d)+.cond.(\\d)+.value`).test(record.propPath) ||
|
|
417
|
+
record.propPath === NODE_CONDS_KEY ||
|
|
418
|
+
isValueIncludeDataSource(record.value)
|
|
419
|
+
) {
|
|
420
|
+
needRecollectNodes.push(newNode);
|
|
421
|
+
} else {
|
|
422
|
+
normalNodes.push(newNode);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
} else if (isIncludeDataSource(newNode, oldNode)) {
|
|
426
|
+
needRecollectNodes.push(newNode);
|
|
427
|
+
} else {
|
|
428
|
+
normalNodes.push(newNode);
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
if (needRecollectNodes.length) {
|
|
433
|
+
collectIdle(needRecollectNodes, true).then(() => {
|
|
434
|
+
afterUpdateNodes(needRecollectNodes);
|
|
435
|
+
});
|
|
436
|
+
} else if (normalNodes.length) {
|
|
437
|
+
afterUpdateNodes(normalNodes);
|
|
438
|
+
}
|
|
373
439
|
};
|
|
374
440
|
|
|
375
441
|
// 节点删除,清除对齐的依赖收集
|
|
@@ -379,7 +445,9 @@ export const initServiceEvents = (
|
|
|
379
445
|
|
|
380
446
|
// 由于历史记录变化是更新整个page,所以历史记录变化时,需要重新收集依赖
|
|
381
447
|
const historyChangeHandler = (page: MPage | MPageFragment) => {
|
|
382
|
-
collectIdle([page], true)
|
|
448
|
+
collectIdle([page], true).then(() => {
|
|
449
|
+
updateDataSourceSchema([page], true);
|
|
450
|
+
});
|
|
383
451
|
};
|
|
384
452
|
|
|
385
453
|
editorService.on('history-change', historyChangeHandler);
|
|
@@ -409,12 +477,41 @@ export const initServiceEvents = (
|
|
|
409
477
|
getApp()?.dataSourceManager?.addDataSource(config);
|
|
410
478
|
};
|
|
411
479
|
|
|
412
|
-
const dataSourceUpdateHandler = (config: DataSourceSchema) => {
|
|
480
|
+
const dataSourceUpdateHandler = (config: DataSourceSchema, { changeRecords }: { changeRecords: ChangeRecord[] }) => {
|
|
481
|
+
let needRecollectDep = false;
|
|
482
|
+
for (const changeRecord of changeRecords) {
|
|
483
|
+
if (!changeRecord.propPath) {
|
|
484
|
+
continue;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
needRecollectDep =
|
|
488
|
+
changeRecord.propPath === 'fields' ||
|
|
489
|
+
changeRecord.propPath === 'methods' ||
|
|
490
|
+
/fields.(\d)+.name/.test(changeRecord.propPath) ||
|
|
491
|
+
/fields.(\d)+$/.test(changeRecord.propPath) ||
|
|
492
|
+
/methods.(\d)+.name/.test(changeRecord.propPath) ||
|
|
493
|
+
/methods.(\d)+$/.test(changeRecord.propPath);
|
|
494
|
+
|
|
495
|
+
if (needRecollectDep) {
|
|
496
|
+
break;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
413
500
|
const root = editorService.get('root');
|
|
414
|
-
|
|
415
|
-
|
|
501
|
+
if (needRecollectDep) {
|
|
502
|
+
if (Array.isArray(root?.items)) {
|
|
503
|
+
depService.clearIdleTasks();
|
|
504
|
+
|
|
505
|
+
removeDataSourceTarget(config.id);
|
|
506
|
+
initDataSourceDepTarget(config);
|
|
416
507
|
|
|
417
|
-
|
|
508
|
+
collectIdle(root.items, true).then(() => {
|
|
509
|
+
updateDataSourceSchema(root?.items || [], true);
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
} else if (root?.dataSources) {
|
|
513
|
+
getApp()?.dataSourceManager?.updateSchema(root.dataSources);
|
|
514
|
+
}
|
|
418
515
|
};
|
|
419
516
|
|
|
420
517
|
const removeDataSourceTarget = (id: string) => {
|
|
@@ -424,8 +521,14 @@ export const initServiceEvents = (
|
|
|
424
521
|
};
|
|
425
522
|
|
|
426
523
|
const dataSourceRemoveHandler = (id: string) => {
|
|
524
|
+
const root = editorService.get('root');
|
|
525
|
+
const nodeIds = Object.keys(root?.dataSourceDeps?.[id] || {});
|
|
526
|
+
const nodes = getNodes(nodeIds, root?.items);
|
|
527
|
+
collectIdle(nodes, false).then(() => {
|
|
528
|
+
updateDataSourceSchema(nodes, false);
|
|
529
|
+
});
|
|
530
|
+
|
|
427
531
|
removeDataSourceTarget(id);
|
|
428
|
-
getApp()?.dataSourceManager?.removeDataSource(id);
|
|
429
532
|
};
|
|
430
533
|
|
|
431
534
|
dataSourceService.on('add', dataSourceAddHandler);
|
|
@@ -435,7 +538,7 @@ export const initServiceEvents = (
|
|
|
435
538
|
onBeforeUnmount(() => {
|
|
436
539
|
depService.off('add-target', targetAddHandler);
|
|
437
540
|
depService.off('remove-target', targetRemoveHandler);
|
|
438
|
-
depService.off('collected',
|
|
541
|
+
depService.off('collected', depCollectedHandler);
|
|
439
542
|
|
|
440
543
|
editorService.off('history-change', historyChangeHandler);
|
|
441
544
|
editorService.off('root-change', rootChangeHandler);
|
|
@@ -11,8 +11,6 @@
|
|
|
11
11
|
</slot>
|
|
12
12
|
|
|
13
13
|
<SplitView
|
|
14
|
-
v-loading="stageLoading"
|
|
15
|
-
element-loading-text="Runtime 加载中..."
|
|
16
14
|
v-else
|
|
17
15
|
ref="splitView"
|
|
18
16
|
class="m-editor-content"
|
|
@@ -38,7 +36,12 @@
|
|
|
38
36
|
</slot>
|
|
39
37
|
|
|
40
38
|
<slot name="page-bar">
|
|
41
|
-
<PageBar
|
|
39
|
+
<PageBar
|
|
40
|
+
:disabled-page-fragment="disabledPageFragment"
|
|
41
|
+
:page-bar-sort-options="pageBarSortOptions"
|
|
42
|
+
:filter-function="pageFilterFunction"
|
|
43
|
+
>
|
|
44
|
+
<template #page-bar-add-button><slot name="page-bar-add-button"></slot></template>
|
|
42
45
|
<template #page-bar-title="{ page }"><slot name="page-bar-title" :page="page"></slot></template>
|
|
43
46
|
<template #page-bar-popover="{ page }"><slot name="page-bar-popover" :page="page"></slot></template>
|
|
44
47
|
<template #page-list-popover="{ list }"><slot name="page-list-popover" :list="list"></slot></template>
|
|
@@ -61,6 +64,7 @@
|
|
|
61
64
|
<script lang="ts" setup>
|
|
62
65
|
import { computed, inject, onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
|
63
66
|
|
|
67
|
+
import type { MPage, MPageFragment } from '@tmagic/core';
|
|
64
68
|
import { TMagicScrollbar } from '@tmagic/design';
|
|
65
69
|
|
|
66
70
|
import SplitView from '@editor/components/SplitView.vue';
|
|
@@ -80,6 +84,7 @@ defineOptions({
|
|
|
80
84
|
defineProps<{
|
|
81
85
|
disabledPageFragment: boolean;
|
|
82
86
|
pageBarSortOptions?: PageBarSortOptions;
|
|
87
|
+
pageFilterFunction?: (page: MPage | MPageFragment, keyword: string) => boolean;
|
|
83
88
|
}>();
|
|
84
89
|
|
|
85
90
|
const DEFAULT_LEFT_COLUMN_WIDTH = 310;
|
|
@@ -95,7 +100,6 @@ const root = computed(() => editorService?.get('root'));
|
|
|
95
100
|
const page = computed(() => editorService?.get('page'));
|
|
96
101
|
|
|
97
102
|
const pageLength = computed(() => editorService?.get('pageLength') || 0);
|
|
98
|
-
const stageLoading = computed(() => editorService?.get('stageLoading') || false);
|
|
99
103
|
const showSrc = computed(() => uiService?.get('showSrc'));
|
|
100
104
|
|
|
101
105
|
const LEFT_COLUMN_WIDTH_STORAGE_KEY = '$MagicEditorLeftColumnWidthData';
|
|
@@ -43,7 +43,7 @@ import { Document as DocumentIcon } from '@element-plus/icons-vue';
|
|
|
43
43
|
|
|
44
44
|
import type { MNode } from '@tmagic/core';
|
|
45
45
|
import { TMagicButton } from '@tmagic/design';
|
|
46
|
-
import type { FormState, FormValue } from '@tmagic/form';
|
|
46
|
+
import type { ContainerChangeEventData, FormState, FormValue } from '@tmagic/form';
|
|
47
47
|
import { MForm } from '@tmagic/form';
|
|
48
48
|
|
|
49
49
|
import MIcon from '@editor/components/Icon.vue';
|
|
@@ -110,10 +110,10 @@ watchEffect(() => {
|
|
|
110
110
|
}
|
|
111
111
|
});
|
|
112
112
|
|
|
113
|
-
const submit = async () => {
|
|
113
|
+
const submit = async (v: FormValue, eventData: ContainerChangeEventData) => {
|
|
114
114
|
try {
|
|
115
115
|
const values = await configForm.value?.submitForm();
|
|
116
|
-
services?.editorService.update(values);
|
|
116
|
+
services?.editorService.update(values, { changeRecords: eventData.changeRecords });
|
|
117
117
|
} catch (e: any) {
|
|
118
118
|
emit('submit-error', e);
|
|
119
119
|
}
|
|
@@ -3,9 +3,31 @@
|
|
|
3
3
|
v-if="showAddPageButton"
|
|
4
4
|
id="m-editor-page-bar-add-icon"
|
|
5
5
|
class="m-editor-page-bar-item m-editor-page-bar-item-icon"
|
|
6
|
-
@click="addPage"
|
|
7
6
|
>
|
|
8
|
-
<
|
|
7
|
+
<TMagicPopover popper-class="data-source-list-panel-add-menu">
|
|
8
|
+
<template #reference>
|
|
9
|
+
<Icon :icon="Plus"></Icon>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<ToolButton
|
|
13
|
+
:data="{
|
|
14
|
+
type: 'button',
|
|
15
|
+
text: '页面',
|
|
16
|
+
handler: () => {
|
|
17
|
+
addPage(NodeType.PAGE);
|
|
18
|
+
},
|
|
19
|
+
}"
|
|
20
|
+
></ToolButton>
|
|
21
|
+
<ToolButton
|
|
22
|
+
:data="{
|
|
23
|
+
type: 'button',
|
|
24
|
+
text: '页面片',
|
|
25
|
+
handler: () => {
|
|
26
|
+
addPage(NodeType.PAGE_FRAGMENT);
|
|
27
|
+
},
|
|
28
|
+
}"
|
|
29
|
+
></ToolButton>
|
|
30
|
+
</TMagicPopover>
|
|
9
31
|
</div>
|
|
10
32
|
<div v-else style="width: 21px"></div>
|
|
11
33
|
</template>
|
|
@@ -15,8 +37,10 @@ import { computed, inject, toRaw } from 'vue';
|
|
|
15
37
|
import { Plus } from '@element-plus/icons-vue';
|
|
16
38
|
|
|
17
39
|
import { NodeType } from '@tmagic/core';
|
|
40
|
+
import { TMagicPopover } from '@tmagic/design';
|
|
18
41
|
|
|
19
42
|
import Icon from '@editor/components/Icon.vue';
|
|
43
|
+
import ToolButton from '@editor/components/ToolButton.vue';
|
|
20
44
|
import type { Services } from '@editor/type';
|
|
21
45
|
import { generatePageNameByApp } from '@editor/utils/editor';
|
|
22
46
|
|
|
@@ -24,23 +48,19 @@ defineOptions({
|
|
|
24
48
|
name: 'MEditorPageBarAddButton',
|
|
25
49
|
});
|
|
26
50
|
|
|
27
|
-
const props = defineProps<{
|
|
28
|
-
type: NodeType.PAGE | NodeType.PAGE_FRAGMENT;
|
|
29
|
-
}>();
|
|
30
|
-
|
|
31
51
|
const services = inject<Services>('services');
|
|
32
52
|
const uiService = services?.uiService;
|
|
33
53
|
const editorService = services?.editorService;
|
|
34
54
|
|
|
35
55
|
const showAddPageButton = computed(() => uiService?.get('showAddPageButton'));
|
|
36
56
|
|
|
37
|
-
const addPage = () => {
|
|
57
|
+
const addPage = (type: NodeType.PAGE | NodeType.PAGE_FRAGMENT) => {
|
|
38
58
|
if (!editorService) return;
|
|
39
59
|
const root = toRaw(editorService.get('root'));
|
|
40
60
|
if (!root) throw new Error('root 不能为空');
|
|
41
61
|
const pageConfig = {
|
|
42
|
-
type
|
|
43
|
-
name: generatePageNameByApp(root,
|
|
62
|
+
type,
|
|
63
|
+
name: generatePageNameByApp(root, type),
|
|
44
64
|
items: [],
|
|
45
65
|
};
|
|
46
66
|
editorService.add(pageConfig);
|