@tmagic/editor 1.3.0-beta.6 → 1.3.0-beta.8
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 +57 -56
- package/dist/tmagic-editor.js +549 -436
- package/dist/tmagic-editor.js.map +1 -1
- package/dist/tmagic-editor.umd.cjs +567 -454
- package/dist/tmagic-editor.umd.cjs.map +1 -1
- package/package.json +10 -10
- package/src/Editor.vue +8 -0
- package/src/components/ContentMenu.vue +2 -6
- package/src/components/SplitView.vue +22 -6
- package/src/components/Tree.vue +66 -0
- package/src/components/TreeNode.vue +142 -0
- package/src/layouts/Framework.vue +11 -21
- package/src/layouts/sidebar/Sidebar.vue +13 -0
- package/src/layouts/sidebar/data-source/DataSourceList.vue +28 -17
- package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +8 -2
- package/src/layouts/sidebar/layer/LayerPanel.vue +40 -31
- package/src/layouts/sidebar/layer/use-click.ts +105 -0
- package/src/layouts/sidebar/layer/use-drag.ts +1 -1
- package/src/layouts/sidebar/layer/use-filter.ts +1 -12
- package/src/layouts/sidebar/layer/use-keybinding.ts +6 -2
- package/src/layouts/sidebar/layer/use-node-status.ts +4 -2
- package/src/layouts/workspace/viewer/NodeListMenu.vue +11 -2
- package/src/services/dep.ts +1 -1
- package/src/theme/layer-panel.scss +2 -74
- package/src/theme/theme.scss +1 -0
- package/src/theme/tree.scss +72 -0
- package/src/type.ts +16 -1
- package/src/utils/dep.ts +7 -2
- package/src/utils/tree.ts +15 -0
- package/types/components/ContentMenu.vue.d.ts +4 -1
- package/types/components/SplitView.vue.d.ts +3 -1
- package/types/{layouts/sidebar/layer/LayerNode.vue.d.ts → components/Tree.vue.d.ts} +19 -17
- package/types/components/TreeNode.vue.d.ts +47 -0
- package/types/layouts/sidebar/data-source/DataSourceList.vue.d.ts +2 -6
- package/types/layouts/sidebar/data-source/DataSourceListPanel.vue.d.ts +7 -1
- package/types/layouts/sidebar/layer/LayerPanel.vue.d.ts +1 -1
- package/types/layouts/sidebar/layer/use-click.d.ts +106 -0
- package/types/layouts/sidebar/layer/use-filter.d.ts +0 -1
- package/types/layouts/sidebar/layer/use-keybinding.d.ts +2 -1
- package/types/type.d.ts +20 -1
- package/types/utils/tree.d.ts +3 -0
- package/src/layouts/sidebar/layer/LayerNode.vue +0 -208
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.3.0-beta.
|
|
2
|
+
"version": "1.3.0-beta.8",
|
|
3
3
|
"name": "@tmagic/editor",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": [
|
|
@@ -47,13 +47,13 @@
|
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@babel/core": "^7.18.0",
|
|
49
49
|
"@element-plus/icons-vue": "^2.0.9",
|
|
50
|
-
"@tmagic/core": "1.3.0-beta.
|
|
51
|
-
"@tmagic/design": "1.3.0-beta.
|
|
52
|
-
"@tmagic/form": "1.3.0-beta.
|
|
53
|
-
"@tmagic/schema": "1.3.0-beta.
|
|
54
|
-
"@tmagic/stage": "1.3.0-beta.
|
|
55
|
-
"@tmagic/table": "1.3.0-beta.
|
|
56
|
-
"@tmagic/utils": "1.3.0-beta.
|
|
50
|
+
"@tmagic/core": "1.3.0-beta.8",
|
|
51
|
+
"@tmagic/design": "1.3.0-beta.8",
|
|
52
|
+
"@tmagic/form": "1.3.0-beta.8",
|
|
53
|
+
"@tmagic/schema": "1.3.0-beta.8",
|
|
54
|
+
"@tmagic/stage": "1.3.0-beta.8",
|
|
55
|
+
"@tmagic/table": "1.3.0-beta.8",
|
|
56
|
+
"@tmagic/utils": "1.3.0-beta.8",
|
|
57
57
|
"buffer": "^6.0.3",
|
|
58
58
|
"color": "^3.1.3",
|
|
59
59
|
"events": "^3.3.0",
|
|
@@ -65,8 +65,8 @@
|
|
|
65
65
|
"vue": "^3.3.4"
|
|
66
66
|
},
|
|
67
67
|
"peerDependencies": {
|
|
68
|
-
"@tmagic/design": "1.3.0-beta.
|
|
69
|
-
"@tmagic/form": "1.3.0-beta.
|
|
68
|
+
"@tmagic/design": "1.3.0-beta.8",
|
|
69
|
+
"@tmagic/form": "1.3.0-beta.8",
|
|
70
70
|
"monaco-editor": "^0.41.0",
|
|
71
71
|
"vue": "^3.3.4"
|
|
72
72
|
},
|
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-tool="{ data }">
|
|
29
|
+
<slot name="layer-node-tool" :data="data"></slot>
|
|
30
|
+
</template>
|
|
31
|
+
|
|
28
32
|
<template #component-list-panel-header>
|
|
29
33
|
<slot name="component-list-panel-header"></slot>
|
|
30
34
|
</template>
|
|
@@ -40,6 +44,10 @@
|
|
|
40
44
|
<template #code-block-panel-tool="{ id, data }">
|
|
41
45
|
<slot name="code-block-panel-tool" :id="id" :data="data"></slot>
|
|
42
46
|
</template>
|
|
47
|
+
|
|
48
|
+
<template #data-source-panel-tool="{ data }">
|
|
49
|
+
<slot name="data-source-panel-tool" :data="data"></slot>
|
|
50
|
+
</template>
|
|
43
51
|
</Sidebar>
|
|
44
52
|
</slot>
|
|
45
53
|
</template>
|
|
@@ -126,17 +126,13 @@ const setPosition = (e: { clientY: number; clientX: number }) => {
|
|
|
126
126
|
};
|
|
127
127
|
};
|
|
128
128
|
|
|
129
|
-
const show = (e?:
|
|
129
|
+
const show = (e?: { clientY: number; clientX: number }) => {
|
|
130
130
|
// 加settimeout是以为,如果菜单中的按钮监听的是mouseup,那么菜单显示出来时鼠标如果正好在菜单上就会马上触发按钮的mouseup
|
|
131
131
|
setTimeout(() => {
|
|
132
132
|
visible.value = true;
|
|
133
133
|
|
|
134
|
-
if (!e) {
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
134
|
nextTick(() => {
|
|
139
|
-
setPosition(e);
|
|
135
|
+
e && setPosition(e);
|
|
140
136
|
|
|
141
137
|
emit('show');
|
|
142
138
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div ref="el" class="m-editor-layout">
|
|
2
|
+
<div ref="el" class="m-editor-layout" :style="`min-width: ${props.minCenter + props.minLeft + props.minRight}px`">
|
|
3
3
|
<template v-if="hasLeft && $slots.left">
|
|
4
4
|
<div class="m-editor-layout-left" :class="leftClass" :style="`width: ${left}px`">
|
|
5
5
|
<slot name="left"></slot>
|
|
@@ -55,14 +55,18 @@ const el = ref<HTMLElement>();
|
|
|
55
55
|
const hasLeft = computed(() => typeof props.left !== 'undefined');
|
|
56
56
|
const hasRight = computed(() => typeof props.right !== 'undefined');
|
|
57
57
|
|
|
58
|
-
const getCenterWidth = (clientWidth: number,
|
|
58
|
+
const getCenterWidth = (clientWidth: number, l = 0, r = 0) => {
|
|
59
|
+
let right = r > 0 ? r : 0;
|
|
60
|
+
let left = l > 0 ? l : 0;
|
|
59
61
|
let center = clientWidth - left - right;
|
|
62
|
+
|
|
60
63
|
if (center < props.minCenter) {
|
|
61
64
|
center = props.minCenter;
|
|
62
|
-
if (
|
|
63
|
-
right = clientWidth - left -
|
|
65
|
+
if (right > center + props.minRight) {
|
|
66
|
+
right = clientWidth - left - center;
|
|
64
67
|
} else {
|
|
65
|
-
|
|
68
|
+
right = props.minRight;
|
|
69
|
+
left = clientWidth - right - center;
|
|
66
70
|
}
|
|
67
71
|
}
|
|
68
72
|
return {
|
|
@@ -141,7 +145,7 @@ const changeRight = ({ deltaX }: OnDrag) => {
|
|
|
141
145
|
right = props.right;
|
|
142
146
|
}
|
|
143
147
|
|
|
144
|
-
const columnWidth = getCenterWidth(clientWidth, props.left
|
|
148
|
+
const columnWidth = getCenterWidth(clientWidth, props.left, right);
|
|
145
149
|
|
|
146
150
|
center.value = columnWidth.center;
|
|
147
151
|
|
|
@@ -151,4 +155,16 @@ const changeRight = ({ deltaX }: OnDrag) => {
|
|
|
151
155
|
right: columnWidth.right,
|
|
152
156
|
});
|
|
153
157
|
};
|
|
158
|
+
|
|
159
|
+
defineExpose({
|
|
160
|
+
updateWidth() {
|
|
161
|
+
const columnWidth = getCenterWidth(el.value?.clientWidth || clientWidth, props.left, props.right);
|
|
162
|
+
|
|
163
|
+
emit('change', {
|
|
164
|
+
left: columnWidth.left,
|
|
165
|
+
center: center.value,
|
|
166
|
+
right: columnWidth.right,
|
|
167
|
+
});
|
|
168
|
+
},
|
|
169
|
+
});
|
|
154
170
|
</script>
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="m-editor-tree" @dragover="handleDragOver">
|
|
3
|
+
<template v-if="data?.length">
|
|
4
|
+
<TreeNode v-for="item in data" :key="item.id" :data="item" :indent="indent" :node-status-map="nodeStatusMap">
|
|
5
|
+
<template #tree-node-content="{ data: nodeData }">
|
|
6
|
+
<slot name="tree-node-content" :data="nodeData"> </slot>
|
|
7
|
+
</template>
|
|
8
|
+
|
|
9
|
+
<template #tree-node-tool="{ data: nodeData }">
|
|
10
|
+
<slot name="tree-node-tool" :data="nodeData"> </slot>
|
|
11
|
+
</template>
|
|
12
|
+
</TreeNode>
|
|
13
|
+
</template>
|
|
14
|
+
<div v-else>
|
|
15
|
+
<p>{{ emptyText }}</p>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
</template>
|
|
19
|
+
|
|
20
|
+
<script setup lang="ts">
|
|
21
|
+
import { provide } from 'vue';
|
|
22
|
+
|
|
23
|
+
import type { Id } from '@tmagic/schema';
|
|
24
|
+
|
|
25
|
+
import type { LayerNodeStatus, TreeNodeData } from '@editor/type';
|
|
26
|
+
|
|
27
|
+
import TreeNode from './TreeNode.vue';
|
|
28
|
+
|
|
29
|
+
defineSlots<{
|
|
30
|
+
'tree-node-content'(props: { data: TreeNodeData }): any;
|
|
31
|
+
'tree-node-tool'(props: { data: TreeNodeData }): any;
|
|
32
|
+
}>();
|
|
33
|
+
|
|
34
|
+
defineOptions({
|
|
35
|
+
name: 'MEditorTree',
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const emit = defineEmits<{
|
|
39
|
+
'node-dragover': [event: DragEvent];
|
|
40
|
+
'node-dragstart': [event: DragEvent, data: TreeNodeData];
|
|
41
|
+
'node-dragleave': [event: DragEvent, data: TreeNodeData];
|
|
42
|
+
'node-dragend': [event: DragEvent, data: TreeNodeData];
|
|
43
|
+
'node-contextmenu': [event: MouseEvent, data: TreeNodeData];
|
|
44
|
+
'node-mouseenter': [event: MouseEvent, data: TreeNodeData];
|
|
45
|
+
'node-click': [event: MouseEvent, data: TreeNodeData];
|
|
46
|
+
}>();
|
|
47
|
+
|
|
48
|
+
provide('treeEmit', emit);
|
|
49
|
+
|
|
50
|
+
withDefaults(
|
|
51
|
+
defineProps<{
|
|
52
|
+
data: TreeNodeData[];
|
|
53
|
+
nodeStatusMap: Map<Id, LayerNodeStatus>;
|
|
54
|
+
indent?: number;
|
|
55
|
+
emptyText?: string;
|
|
56
|
+
}>(),
|
|
57
|
+
{
|
|
58
|
+
indent: 0,
|
|
59
|
+
emptyText: '暂无数据',
|
|
60
|
+
},
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
const handleDragOver = (event: DragEvent) => {
|
|
64
|
+
emit('node-dragover', event);
|
|
65
|
+
};
|
|
66
|
+
</script>
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
v-show="visible"
|
|
4
|
+
class="m-editor-tree-node"
|
|
5
|
+
:draggable="draggable"
|
|
6
|
+
:data-node-id="data.id"
|
|
7
|
+
:data-is-container="Array.isArray(data.items)"
|
|
8
|
+
@dragstart="handleDragStart"
|
|
9
|
+
@dragleave="handleDragLeave"
|
|
10
|
+
@dragend="handleDragEnd"
|
|
11
|
+
>
|
|
12
|
+
<div
|
|
13
|
+
class="tree-node"
|
|
14
|
+
:class="{ selected, expanded }"
|
|
15
|
+
:style="`padding-left: ${indent}px`"
|
|
16
|
+
@contextmenu="nodeContentmenuHandler"
|
|
17
|
+
@mouseenter="mouseenterHandler"
|
|
18
|
+
>
|
|
19
|
+
<MIcon
|
|
20
|
+
class="expand-icon"
|
|
21
|
+
:style="hasChilren ? '' : 'color: transparent; cursor: default'"
|
|
22
|
+
:icon="expanded ? ArrowDown : ArrowRight"
|
|
23
|
+
@click="expandHandler"
|
|
24
|
+
></MIcon>
|
|
25
|
+
|
|
26
|
+
<div class="tree-node-content" @click="nodeClickHandler">
|
|
27
|
+
<slot name="tree-node-content" :data="data">
|
|
28
|
+
<div class="tree-node-label">{{ `${data.name} (${data.id})` }}</div>
|
|
29
|
+
<div class="tree-node-tool">
|
|
30
|
+
<slot name="tree-node-tool" :data="data"></slot>
|
|
31
|
+
</div>
|
|
32
|
+
</slot>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<div v-if="hasChilren && expanded" class="m-editor-tree-node-children">
|
|
37
|
+
<TreeNode
|
|
38
|
+
v-for="item in data.items"
|
|
39
|
+
:key="item.id"
|
|
40
|
+
:data="item"
|
|
41
|
+
:node-status-map="nodeStatusMap"
|
|
42
|
+
:indent="indent + 11"
|
|
43
|
+
>
|
|
44
|
+
<template #tree-node-content="{ data: nodeData }">
|
|
45
|
+
<slot name="tree-node-content" :data="nodeData"> </slot>
|
|
46
|
+
</template>
|
|
47
|
+
<template #tree-node-tool="{ data: nodeData }">
|
|
48
|
+
<slot name="tree-node-tool" :data="nodeData"> </slot>
|
|
49
|
+
</template>
|
|
50
|
+
</TreeNode>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
</template>
|
|
54
|
+
|
|
55
|
+
<script setup lang="ts">
|
|
56
|
+
import { computed, inject } from 'vue';
|
|
57
|
+
import { ArrowDown, ArrowRight } from '@element-plus/icons-vue';
|
|
58
|
+
|
|
59
|
+
import type { Id } from '@tmagic/schema';
|
|
60
|
+
|
|
61
|
+
import MIcon from '@editor/components/Icon.vue';
|
|
62
|
+
import type { LayerNodeStatus, TreeNodeData } from '@editor/type';
|
|
63
|
+
import { updateStatus } from '@editor/utils/tree';
|
|
64
|
+
|
|
65
|
+
defineSlots<{
|
|
66
|
+
'tree-node-tool'(props: { data: TreeNodeData }): any;
|
|
67
|
+
'tree-node-content'(props: { data: TreeNodeData }): any;
|
|
68
|
+
}>();
|
|
69
|
+
|
|
70
|
+
defineOptions({
|
|
71
|
+
name: 'MEditorTreeNode',
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const emit = defineEmits<{
|
|
75
|
+
'node-dragstart': [event: DragEvent, data: TreeNodeData];
|
|
76
|
+
'node-dragleave': [event: DragEvent, data: TreeNodeData];
|
|
77
|
+
'node-dragend': [event: DragEvent, data: TreeNodeData];
|
|
78
|
+
'node-contextmenu': [event: MouseEvent, data: TreeNodeData];
|
|
79
|
+
'node-mouseenter': [event: MouseEvent, data: TreeNodeData];
|
|
80
|
+
'node-click': [event: MouseEvent, data: TreeNodeData];
|
|
81
|
+
}>();
|
|
82
|
+
|
|
83
|
+
const treeEmit = inject<typeof emit>('treeEmit');
|
|
84
|
+
|
|
85
|
+
const props = withDefaults(
|
|
86
|
+
defineProps<{
|
|
87
|
+
data: TreeNodeData;
|
|
88
|
+
nodeStatusMap: Map<Id, LayerNodeStatus>;
|
|
89
|
+
indent?: number;
|
|
90
|
+
}>(),
|
|
91
|
+
{
|
|
92
|
+
indent: 0,
|
|
93
|
+
},
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
const nodeStatus = computed(
|
|
97
|
+
() =>
|
|
98
|
+
props.nodeStatusMap?.get(props.data.id) || {
|
|
99
|
+
selected: false,
|
|
100
|
+
expand: false,
|
|
101
|
+
visible: false,
|
|
102
|
+
draggable: false,
|
|
103
|
+
},
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
const expanded = computed(() => nodeStatus.value.expand);
|
|
107
|
+
const selected = computed(() => nodeStatus.value.selected);
|
|
108
|
+
const visible = computed(() => nodeStatus.value.visible);
|
|
109
|
+
const draggable = computed(() => nodeStatus.value.draggable);
|
|
110
|
+
|
|
111
|
+
const hasChilren = computed(() => props.data.items && props.data.items.length > 0);
|
|
112
|
+
|
|
113
|
+
const handleDragStart = (event: DragEvent) => {
|
|
114
|
+
treeEmit?.('node-dragstart', event, props.data);
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const handleDragLeave = (event: DragEvent) => {
|
|
118
|
+
treeEmit?.('node-dragleave', event, props.data);
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const handleDragEnd = (event: DragEvent) => {
|
|
122
|
+
treeEmit?.('node-dragend', event, props.data);
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const nodeContentmenuHandler = (event: MouseEvent) => {
|
|
126
|
+
treeEmit?.('node-contextmenu', event, props.data);
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const mouseenterHandler = (event: MouseEvent) => {
|
|
130
|
+
treeEmit?.('node-mouseenter', event, props.data);
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
const expandHandler = () => {
|
|
134
|
+
updateStatus(props.nodeStatusMap, props.data.id, {
|
|
135
|
+
expand: !expanded.value,
|
|
136
|
+
});
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const nodeClickHandler = (event: MouseEvent) => {
|
|
140
|
+
treeEmit?.('node-click', event, props.data);
|
|
141
|
+
};
|
|
142
|
+
</script>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="m-editor" ref="content">
|
|
2
|
+
<div class="m-editor" ref="content" style="min-width: 180px">
|
|
3
3
|
<slot name="header"></slot>
|
|
4
4
|
|
|
5
5
|
<slot name="nav"></slot>
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
<SplitView
|
|
14
14
|
v-else
|
|
15
|
+
ref="splitView"
|
|
15
16
|
class="m-editor-content"
|
|
16
17
|
left-class="m-editor-framework-left"
|
|
17
18
|
center-class="m-editor-framework-center"
|
|
@@ -20,6 +21,7 @@
|
|
|
20
21
|
v-model:right="columnWidth.right"
|
|
21
22
|
:min-left="65"
|
|
22
23
|
:min-right="20"
|
|
24
|
+
:min-center="100"
|
|
23
25
|
@change="columnWidthChange"
|
|
24
26
|
>
|
|
25
27
|
<template #left>
|
|
@@ -70,6 +72,7 @@ const codeOptions = inject('codeOptions', {});
|
|
|
70
72
|
const { editorService, uiService } = inject<Services>('services') || {};
|
|
71
73
|
|
|
72
74
|
const content = ref<HTMLDivElement>();
|
|
75
|
+
const splitView = ref<InstanceType<typeof SplitView>>();
|
|
73
76
|
|
|
74
77
|
const root = computed(() => editorService?.get('root'));
|
|
75
78
|
|
|
@@ -79,8 +82,10 @@ const showSrc = computed(() => uiService?.get('showSrc'));
|
|
|
79
82
|
const LEFT_COLUMN_WIDTH_STORAGE_KEY = '$MagicEditorLeftColumnWidthData';
|
|
80
83
|
const RIGHT_COLUMN_WIDTH_STORAGE_KEY = '$MagicEditorRightColumnWidthData';
|
|
81
84
|
|
|
82
|
-
const leftColumnWidthCacheData =
|
|
83
|
-
|
|
85
|
+
const leftColumnWidthCacheData =
|
|
86
|
+
Number(globalThis.localStorage.getItem(LEFT_COLUMN_WIDTH_STORAGE_KEY)) || DEFAULT_LEFT_COLUMN_WIDTH;
|
|
87
|
+
const RightColumnWidthCacheData =
|
|
88
|
+
Number(globalThis.localStorage.getItem(RIGHT_COLUMN_WIDTH_STORAGE_KEY)) || DEFAULT_RIGHT_COLUMN_WIDTH;
|
|
84
89
|
|
|
85
90
|
const columnWidth = ref<Partial<GetColumnWidth>>({
|
|
86
91
|
left: leftColumnWidthCacheData,
|
|
@@ -89,24 +94,9 @@ const columnWidth = ref<Partial<GetColumnWidth>>({
|
|
|
89
94
|
});
|
|
90
95
|
|
|
91
96
|
watch(
|
|
92
|
-
pageLength,
|
|
93
|
-
(
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
columnWidth.value.left = left;
|
|
97
|
-
|
|
98
|
-
const container = content.value || document.body;
|
|
99
|
-
|
|
100
|
-
if (length <= 0) {
|
|
101
|
-
columnWidth.value.right = undefined;
|
|
102
|
-
columnWidth.value.center = container.clientWidth - left;
|
|
103
|
-
} else {
|
|
104
|
-
const right = columnWidth.value.right || RightColumnWidthCacheData || DEFAULT_RIGHT_COLUMN_WIDTH;
|
|
105
|
-
columnWidth.value.right = right;
|
|
106
|
-
columnWidth.value.center = container.clientWidth - left - right;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
uiService?.set('columnWidth', columnWidth.value as GetColumnWidth);
|
|
97
|
+
[pageLength, splitView],
|
|
98
|
+
() => {
|
|
99
|
+
splitView.value?.updateWidth();
|
|
110
100
|
},
|
|
111
101
|
{
|
|
112
102
|
immediate: true,
|
|
@@ -64,6 +64,19 @@
|
|
|
64
64
|
<slot v-if="config.$key === 'layer'" name="layer-node-content" :data="nodeData"></slot>
|
|
65
65
|
<component v-else-if="config.slots?.layerNodeContent" :is="config.slots.layerNodeContent" :data="nodeData" />
|
|
66
66
|
</template>
|
|
67
|
+
|
|
68
|
+
<template #layer-node-tool="{ data: nodeData }" v-if="config.$key === 'layer' || config.slots?.layerNodeTool">
|
|
69
|
+
<slot v-if="config.$key === 'layer'" name="layer-node-tool" :data="nodeData"></slot>
|
|
70
|
+
<component v-else-if="config.slots?.layerNodeTool" :is="config.slots.layerNodeTool" :data="nodeData" />
|
|
71
|
+
</template>
|
|
72
|
+
|
|
73
|
+
<template
|
|
74
|
+
#data-source-panel-tool="{ data }"
|
|
75
|
+
v-if="config.$key === 'data-source' || config.slots?.codeBlockPanelTool"
|
|
76
|
+
>
|
|
77
|
+
<slot v-if="config.$key === 'data-source'" name="data-source-panel-tool" :data="data"></slot>
|
|
78
|
+
<component v-else-if="config.slots?.DataSourcePanelTool" :is="config.slots.DataSourcePanelTool" />
|
|
79
|
+
</template>
|
|
67
80
|
</component>
|
|
68
81
|
</div>
|
|
69
82
|
</div>
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
<TMagicTooltip v-if="editable" effect="dark" content="删除" placement="bottom">
|
|
27
27
|
<Icon :icon="Close" class="edit-icon" @click.stop="removeHandler(`${data.id}`)"></Icon>
|
|
28
28
|
</TMagicTooltip>
|
|
29
|
-
<slot name="data-source-panel-tool" :
|
|
29
|
+
<slot name="data-source-panel-tool" :data="data"></slot>
|
|
30
30
|
</div>
|
|
31
31
|
</div>
|
|
32
32
|
</div>
|
|
@@ -42,7 +42,9 @@ import { tMagicMessageBox, TMagicTooltip, TMagicTree } from '@tmagic/design';
|
|
|
42
42
|
import { Dep, Id } from '@tmagic/schema';
|
|
43
43
|
|
|
44
44
|
import Icon from '@editor/components/Icon.vue';
|
|
45
|
-
import { DepTargetType, Services } from '@editor/type';
|
|
45
|
+
import { type DataSourceListSlots, DepTargetType, type Services } from '@editor/type';
|
|
46
|
+
|
|
47
|
+
defineSlots<DataSourceListSlots>();
|
|
46
48
|
|
|
47
49
|
defineOptions({
|
|
48
50
|
name: 'MEditorDataSourceList',
|
|
@@ -73,6 +75,26 @@ const getNodeTreeConfig = (id: string, dep: Dep[string], type?: string) => ({
|
|
|
73
75
|
children: getKeyTreeConfig(dep, type),
|
|
74
76
|
});
|
|
75
77
|
|
|
78
|
+
/**
|
|
79
|
+
* 生成tree中依赖节点的数据
|
|
80
|
+
* @param children 节点
|
|
81
|
+
* @param deps 依赖
|
|
82
|
+
* @param type 依赖类型
|
|
83
|
+
*/
|
|
84
|
+
const mergeChildren = (children: any[], deps: Dep, type?: string) => {
|
|
85
|
+
Object.entries(deps).forEach(([id, dep]) => {
|
|
86
|
+
// 已经生成过的节点
|
|
87
|
+
const nodeItem = children.find((item) => item.id === id);
|
|
88
|
+
// 节点存在,则追加依赖的key
|
|
89
|
+
if (nodeItem) {
|
|
90
|
+
nodeItem.children = nodeItem.children.concat(getKeyTreeConfig(dep, type));
|
|
91
|
+
} else {
|
|
92
|
+
// 节点不存在,则生成
|
|
93
|
+
children.push(getNodeTreeConfig(id, dep, type));
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
|
|
76
98
|
const list = computed(() =>
|
|
77
99
|
dataSources.value.map((ds) => {
|
|
78
100
|
const dsDeps = dsDep.value[ds.id].deps;
|
|
@@ -80,21 +102,10 @@ const list = computed(() =>
|
|
|
80
102
|
const dsCondDeps = dsCondDep.value[ds.id].deps;
|
|
81
103
|
|
|
82
104
|
const children: any[] = [];
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if (nodeItem) {
|
|
88
|
-
nodeItem.children = nodeItem.children.concat(getKeyTreeConfig(dep, type));
|
|
89
|
-
} else {
|
|
90
|
-
children.push(getNodeTreeConfig(id, dep, type));
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
mergeChildren(dsDeps);
|
|
96
|
-
mergeChildren(dsMethodDeps, 'method');
|
|
97
|
-
mergeChildren(dsCondDeps, 'cond');
|
|
105
|
+
// 数据源依赖分为三种类型:key/node、method、cond,是分开存储,这里将其合并展示
|
|
106
|
+
mergeChildren(children, dsDeps);
|
|
107
|
+
mergeChildren(children, dsMethodDeps, 'method');
|
|
108
|
+
mergeChildren(children, dsCondDeps, 'cond');
|
|
98
109
|
|
|
99
110
|
return {
|
|
100
111
|
id: ds.id,
|
|
@@ -23,7 +23,11 @@
|
|
|
23
23
|
</div>
|
|
24
24
|
|
|
25
25
|
<!-- 数据源列表 -->
|
|
26
|
-
<DataSourceList @edit="editHandler" @remove="removeHandler"
|
|
26
|
+
<DataSourceList @edit="editHandler" @remove="removeHandler">
|
|
27
|
+
<template #data-source-panel-tool="{ data }">
|
|
28
|
+
<slot name="data-source-panel-tool" :data="data"></slot>
|
|
29
|
+
</template>
|
|
30
|
+
</DataSourceList>
|
|
27
31
|
|
|
28
32
|
<DataSourceConfigPanel
|
|
29
33
|
ref="editDialog"
|
|
@@ -44,11 +48,13 @@ import type { DataSourceSchema } from '@tmagic/schema';
|
|
|
44
48
|
|
|
45
49
|
import SearchInput from '@editor/components/SearchInput.vue';
|
|
46
50
|
import ToolButton from '@editor/components/ToolButton.vue';
|
|
47
|
-
import type { Services } from '@editor/type';
|
|
51
|
+
import type { DataSourceListSlots, Services } from '@editor/type';
|
|
48
52
|
|
|
49
53
|
import DataSourceConfigPanel from './DataSourceConfigPanel.vue';
|
|
50
54
|
import DataSourceList from './DataSourceList.vue';
|
|
51
55
|
|
|
56
|
+
defineSlots<DataSourceListSlots>();
|
|
57
|
+
|
|
52
58
|
defineOptions({
|
|
53
59
|
name: 'MEditorDataSourceListPanel',
|
|
54
60
|
});
|
|
@@ -1,22 +1,33 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<TMagicScrollbar class="
|
|
2
|
+
<TMagicScrollbar class="m-editor-layer-panel">
|
|
3
3
|
<slot name="layer-panel-header"></slot>
|
|
4
4
|
|
|
5
5
|
<SearchInput @search="filterTextChangeHandler"></SearchInput>
|
|
6
6
|
|
|
7
|
-
<
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
7
|
+
<Tree
|
|
8
|
+
v-if="page && nodeStatusMap"
|
|
9
|
+
tabindex="-1"
|
|
10
|
+
ref="tree"
|
|
11
|
+
:data="[page]"
|
|
12
|
+
:node-status-map="nodeStatusMap"
|
|
13
|
+
@node-dragover="handleDragOver"
|
|
14
|
+
@node-dragstart="handleDragStart"
|
|
15
|
+
@node-dragleave="handleDragLeave"
|
|
16
|
+
@node-dragend="handleDragEnd"
|
|
17
|
+
@node-contextmenu="nodeContentmenuHandler"
|
|
18
|
+
@node-mouseenter="mouseenterHandler"
|
|
19
|
+
@node-click="nodeClickHandler"
|
|
20
|
+
>
|
|
21
|
+
<template #tree-node-tool="{ data: nodeData }">
|
|
22
|
+
<slot name="layer-node-tool" :data="nodeData">
|
|
23
|
+
<LayerNodeTool :data="nodeData"></LayerNodeTool>
|
|
24
|
+
</slot>
|
|
25
|
+
</template>
|
|
26
|
+
|
|
27
|
+
<template #tree-node-content="{ data: nodeData }">
|
|
28
|
+
<slot name="layer-node-content" :data="nodeData"> </slot>
|
|
29
|
+
</template>
|
|
30
|
+
</Tree>
|
|
20
31
|
|
|
21
32
|
<Teleport to="body">
|
|
22
33
|
<LayerMenu ref="menu" :layer-content-menu="layerContentMenu" @collapse-all="collapseAllHandler"></LayerMenu>
|
|
@@ -25,15 +36,17 @@
|
|
|
25
36
|
</template>
|
|
26
37
|
|
|
27
38
|
<script setup lang="ts">
|
|
28
|
-
import { computed, inject,
|
|
39
|
+
import { computed, inject, ref } from 'vue';
|
|
29
40
|
|
|
30
41
|
import { TMagicScrollbar } from '@tmagic/design';
|
|
31
42
|
|
|
32
43
|
import SearchInput from '@editor/components/SearchInput.vue';
|
|
33
|
-
import
|
|
44
|
+
import Tree from '@editor/components/Tree.vue';
|
|
45
|
+
import { LayerPanelSlots, MenuButton, MenuComponent, Services } from '@editor/type';
|
|
34
46
|
|
|
35
47
|
import LayerMenu from './LayerMenu.vue';
|
|
36
|
-
import
|
|
48
|
+
import LayerNodeTool from './LayerNodeTool.vue';
|
|
49
|
+
import { useClick } from './use-click';
|
|
37
50
|
import { useDrag } from './use-drag';
|
|
38
51
|
import { useFilter } from './use-filter';
|
|
39
52
|
import { useKeybinding } from './use-keybinding';
|
|
@@ -52,17 +65,14 @@ defineProps<{
|
|
|
52
65
|
const services = inject<Services>('services');
|
|
53
66
|
const editorService = services?.editorService;
|
|
54
67
|
|
|
55
|
-
const
|
|
68
|
+
const tree = ref<InstanceType<typeof Tree>>();
|
|
56
69
|
|
|
57
70
|
const page = computed(() => editorService?.get('page'));
|
|
58
|
-
const root = computed(() => editorService?.get('root'));
|
|
59
71
|
|
|
60
72
|
const { nodeStatusMap } = useNodeStatus(services, page);
|
|
61
|
-
const { isCtrlKeyDown } = useKeybinding(services,
|
|
73
|
+
const { isCtrlKeyDown } = useKeybinding(services, tree);
|
|
62
74
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const { filterText, filterTextChangeHandler } = useFilter(nodeStatusMap, page);
|
|
75
|
+
const { filterTextChangeHandler } = useFilter(nodeStatusMap, page);
|
|
66
76
|
|
|
67
77
|
const collapseAllHandler = () => {
|
|
68
78
|
if (!page.value || !nodeStatusMap.value) return;
|
|
@@ -75,13 +85,12 @@ const collapseAllHandler = () => {
|
|
|
75
85
|
}
|
|
76
86
|
};
|
|
77
87
|
|
|
78
|
-
|
|
79
|
-
const menu = ref<InstanceType<typeof LayerMenu>>();
|
|
80
|
-
const contextmenu = (event: MouseEvent): void => {
|
|
81
|
-
event.preventDefault();
|
|
82
|
-
|
|
83
|
-
menu.value?.show(event);
|
|
84
|
-
};
|
|
88
|
+
const { handleDragStart, handleDragEnd, handleDragLeave, handleDragOver } = useDrag(services);
|
|
85
89
|
|
|
86
|
-
const {
|
|
90
|
+
const {
|
|
91
|
+
menu,
|
|
92
|
+
nodeClickHandler,
|
|
93
|
+
nodeContentmenuHandler,
|
|
94
|
+
highlightHandler: mouseenterHandler,
|
|
95
|
+
} = useClick(services, isCtrlKeyDown, nodeStatusMap);
|
|
87
96
|
</script>
|