@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.
- package/dist/style.css +73 -51
- package/dist/tmagic-editor.js +1171 -1102
- package/dist/tmagic-editor.js.map +1 -1
- package/dist/tmagic-editor.umd.cjs +1188 -1119
- package/dist/tmagic-editor.umd.cjs.map +1 -1
- package/package.json +17 -17
- package/src/Editor.vue +5 -0
- package/src/components/FloatingBox.vue +117 -0
- package/src/components/Tree.vue +5 -0
- package/src/components/TreeNode.vue +8 -2
- package/src/editorProps.ts +7 -0
- package/src/hooks/use-filter.ts +55 -0
- package/src/hooks/use-node-status.ts +48 -0
- package/src/hooks/use-stage.ts +1 -0
- package/src/initService.ts +28 -12
- package/src/layouts/sidebar/Sidebar.vue +7 -2
- package/src/layouts/sidebar/code-block/CodeBlockList.vue +55 -65
- package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +2 -1
- package/src/layouts/sidebar/data-source/DataSourceList.vue +63 -59
- package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +1 -1
- package/src/layouts/sidebar/layer/LayerPanel.vue +24 -7
- package/src/layouts/sidebar/layer/use-node-status.ts +8 -11
- package/src/layouts/workspace/viewer/NodeListMenu.vue +67 -128
- package/src/layouts/workspace/viewer/Stage.vue +2 -1
- package/src/layouts/workspace/viewer/ViewerMenu.vue +1 -6
- package/src/services/BaseService.ts +63 -26
- package/src/services/codeBlock.ts +7 -1
- package/src/services/dep.ts +12 -8
- package/src/services/editor.ts +66 -30
- package/src/services/props.ts +70 -12
- package/src/services/storage.ts +23 -13
- package/src/services/ui.ts +4 -1
- package/src/theme/floating-box.scss +30 -0
- package/src/theme/layer-panel.scss +19 -0
- package/src/theme/stage.scss +24 -0
- package/src/theme/theme.scss +1 -1
- package/src/theme/tree.scss +12 -1
- package/src/type.ts +6 -3
- package/src/utils/compose.ts +25 -6
- package/src/utils/content-menu.ts +4 -5
- package/src/utils/editor.ts +12 -3
- package/src/utils/operator.ts +1 -2
- package/types/components/CodeBlockEditor.vue.d.ts +6 -2
- package/types/components/CodeParams.vue.d.ts +3 -1
- package/types/components/ContentMenu.vue.d.ts +13 -5
- package/types/components/FloatingBox.vue.d.ts +78 -0
- package/types/components/Resizer.vue.d.ts +6 -1
- package/types/components/ScrollBar.vue.d.ts +3 -1
- package/types/components/ScrollViewer.vue.d.ts +3 -3
- package/types/components/SearchInput.vue.d.ts +3 -1
- package/types/components/SplitView.vue.d.ts +8 -4
- package/types/components/ToolButton.vue.d.ts +1 -1
- package/types/components/Tree.vue.d.ts +27 -8
- package/types/components/TreeNode.vue.d.ts +24 -7
- package/types/editorProps.d.ts +7 -1
- package/types/fields/Code.vue.d.ts +6 -2
- package/types/fields/CodeLink.vue.d.ts +5 -3
- package/types/fields/CodeSelect.vue.d.ts +3 -1
- package/types/fields/CodeSelectCol.vue.d.ts +3 -1
- package/types/fields/DataSourceFieldSelect.vue.d.ts +3 -1
- package/types/fields/DataSourceFields.vue.d.ts +5 -3
- package/types/fields/DataSourceInput.vue.d.ts +8 -4
- package/types/fields/DataSourceMethodSelect.vue.d.ts +3 -1
- package/types/fields/DataSourceMethods.vue.d.ts +5 -3
- package/types/fields/DataSourceMocks.vue.d.ts +5 -3
- package/types/fields/DataSourceSelect.vue.d.ts +5 -3
- package/types/fields/EventSelect.vue.d.ts +3 -1
- package/types/fields/KeyValue.vue.d.ts +2 -2
- package/types/fields/UISelect.vue.d.ts +3 -1
- package/types/hooks/use-code-block-edit.d.ts +14 -5
- package/types/hooks/use-data-source-method.d.ts +14 -5
- package/types/hooks/use-filter.d.ts +7 -0
- package/types/hooks/use-node-status.d.ts +6 -0
- package/types/layouts/CodeEditor.vue.d.ts +4 -1
- package/types/layouts/Framework.vue.d.ts +1 -1
- package/types/layouts/PropsPanel.vue.d.ts +10 -4
- package/types/layouts/sidebar/ComponentListPanel.vue.d.ts +1 -1
- package/types/layouts/sidebar/Sidebar.vue.d.ts +5 -5
- package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +9 -3
- package/types/layouts/sidebar/code-block/CodeBlockListPanel.vue.d.ts +1 -1
- package/types/layouts/sidebar/data-source/DataSourceConfigPanel.vue.d.ts +3 -1
- package/types/layouts/sidebar/data-source/DataSourceList.vue.d.ts +8 -2
- package/types/layouts/sidebar/data-source/DataSourceListPanel.vue.d.ts +1 -1
- package/types/layouts/sidebar/layer/LayerMenu.vue.d.ts +6 -2
- package/types/layouts/sidebar/layer/LayerPanel.vue.d.ts +1 -1
- package/types/layouts/sidebar/layer/use-click.d.ts +14 -5
- package/types/layouts/sidebar/layer/use-node-status.d.ts +3 -4
- package/types/layouts/workspace/Workspace.vue.d.ts +1 -1
- package/types/layouts/workspace/viewer/NodeListMenu.vue.d.ts +1 -14
- package/types/layouts/workspace/viewer/ViewerMenu.vue.d.ts +1 -1
- package/types/services/BaseService.d.ts +4 -1
- package/types/services/dep.d.ts +6 -5
- package/types/services/editor.d.ts +9 -3
- package/types/services/props.d.ts +25 -1
- package/types/services/storage.d.ts +7 -7
- package/types/type.d.ts +8 -6
- package/types/utils/compose.d.ts +1 -1
- package/types/utils/editor.d.ts +5 -1
- package/src/layouts/sidebar/layer/use-filter.ts +0 -59
- package/src/layouts/workspace/viewer/NodeListMenuTitle.vue +0 -68
- package/src/theme/dep-list.scss +0 -59
- package/types/layouts/sidebar/layer/use-filter.d.ts +0 -7
- 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.
|
|
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": ">=
|
|
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.
|
|
50
|
-
"@tmagic/core": "1.3.
|
|
51
|
-
"@tmagic/dep": "1.3.
|
|
52
|
-
"@tmagic/design": "1.3.
|
|
53
|
-
"@tmagic/form": "1.3.
|
|
54
|
-
"@tmagic/schema": "1.3.
|
|
55
|
-
"@tmagic/stage": "1.3.
|
|
56
|
-
"@tmagic/table": "1.3.
|
|
57
|
-
"@tmagic/utils": "1.3.
|
|
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.
|
|
71
|
-
"@tmagic/form": "1.3.
|
|
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": "^
|
|
78
|
+
"@types/node": "^18.19.0",
|
|
79
79
|
"@types/serialize-javascript": "^5.0.1",
|
|
80
|
-
"@vitejs/plugin-vue": "^4.2
|
|
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": "^
|
|
88
|
-
"vue-tsc": "^1.
|
|
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>
|
package/src/components/Tree.vue
CHANGED
|
@@ -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">
|
|
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
|
|
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);
|
package/src/editorProps.ts
CHANGED
|
@@ -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
|
+
};
|
package/src/hooks/use-stage.ts
CHANGED
|
@@ -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
|
package/src/initService.ts
CHANGED
|
@@ -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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
262
|
+
updateNodeWhenDataSourceChange([node]);
|
|
262
263
|
};
|
|
263
264
|
|
|
264
265
|
const collectedHandler = (nodes: MNode[]) => {
|
|
265
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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" />
|