@tmagic/editor 1.3.0-alpha.0 → 1.3.0-alpha.10
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 +46 -9
- package/dist/tmagic-editor.js +1764 -871
- package/dist/tmagic-editor.js.map +1 -1
- package/dist/tmagic-editor.umd.cjs +1781 -882
- package/dist/tmagic-editor.umd.cjs.map +1 -1
- package/package.json +19 -20
- package/src/Editor.vue +29 -3
- package/src/components/CodeDraftEditor.vue +5 -1
- package/src/components/ContentMenu.vue +30 -11
- package/src/components/FunctionEditor.vue +12 -5
- package/src/components/Icon.vue +5 -1
- package/src/components/Resizer.vue +45 -0
- package/src/components/ScrollBar.vue +5 -1
- package/src/components/ScrollViewer.vue +5 -1
- package/src/components/SearchInput.vue +4 -0
- package/src/components/{Layout.vue → SplitView.vue} +8 -4
- package/src/components/ToolButton.vue +5 -1
- package/src/editorProps.ts +5 -1
- package/src/fields/Code.vue +5 -1
- package/src/fields/CodeLink.vue +9 -3
- package/src/fields/CodeSelect.vue +8 -2
- package/src/fields/CodeSelectCol.vue +6 -2
- package/src/fields/DataSourceFields.vue +5 -1
- package/src/fields/DataSourceInput.vue +358 -0
- package/src/fields/DataSourceSelect.vue +75 -0
- package/src/fields/EventSelect.vue +9 -3
- package/src/fields/KeyValue.vue +4 -0
- package/src/fields/UISelect.vue +5 -1
- package/src/icons/AppManageIcon.vue +5 -1
- package/src/icons/CenterIcon.vue +13 -0
- package/src/icons/CodeIcon.vue +5 -1
- package/src/index.ts +13 -3
- package/src/initService.ts +73 -0
- package/src/layouts/AddPageBox.vue +5 -1
- package/src/layouts/CodeEditor.vue +34 -10
- package/src/layouts/Framework.vue +25 -25
- package/src/layouts/NavMenu.vue +5 -1
- package/src/layouts/PropsPanel.vue +14 -4
- package/src/layouts/sidebar/ComponentListPanel.vue +8 -5
- package/src/layouts/sidebar/LayerMenu.vue +13 -25
- package/src/layouts/sidebar/LayerNode.vue +40 -0
- package/src/layouts/sidebar/LayerPanel.vue +70 -27
- package/src/layouts/sidebar/Sidebar.vue +11 -7
- package/src/layouts/sidebar/code-block/CodeBlockEditor.vue +8 -4
- package/src/layouts/sidebar/code-block/CodeBlockList.vue +5 -1
- package/src/layouts/sidebar/data-source/DataSourceConfigPanel.vue +4 -0
- package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +22 -2
- package/src/layouts/workspace/Breadcrumb.vue +5 -1
- package/src/layouts/workspace/PageBar.vue +5 -1
- package/src/layouts/workspace/PageBarScrollContainer.vue +5 -1
- package/src/layouts/workspace/Stage.vue +29 -7
- package/src/layouts/workspace/ViewerMenu.vue +15 -36
- package/src/layouts/workspace/Workspace.vue +9 -134
- package/src/services/codeBlock.ts +3 -2
- package/src/services/dep.ts +4 -0
- package/src/services/keybinding.ts +185 -0
- package/src/services/storage.ts +3 -2
- package/src/theme/content-menu.scss +1 -1
- package/src/theme/data-source-input.scss +18 -0
- package/src/theme/framework.scss +0 -3
- package/src/theme/layer-panel.scss +6 -0
- package/src/theme/layout.scss +4 -0
- package/src/theme/resizer.scss +25 -10
- package/src/theme/stage.scss +4 -0
- package/src/theme/theme.scss +1 -0
- package/src/type.ts +59 -1
- package/src/utils/config.ts +1 -1
- package/src/utils/content-menu.ts +92 -0
- package/src/utils/dep.ts +7 -1
- package/src/utils/keybinding-config.ts +120 -0
- package/src/utils/props.ts +34 -0
- package/types/Editor.vue.d.ts +7 -1
- package/types/components/CodeDraftEditor.vue.d.ts +6 -3
- package/types/components/ContentMenu.vue.d.ts +10 -5
- package/types/components/FunctionEditor.vue.d.ts +74 -51
- package/types/components/Icon.vue.d.ts +2 -2
- package/types/{layouts → components}/Resizer.vue.d.ts +2 -2
- package/types/components/ScrollBar.vue.d.ts +1 -1
- package/types/components/ScrollViewer.vue.d.ts +8 -5
- package/types/components/SearchInput.vue.d.ts +1 -1
- package/types/components/{Layout.vue.d.ts → SplitView.vue.d.ts} +9 -6
- package/types/components/ToolButton.vue.d.ts +8 -5
- package/types/editorProps.d.ts +4 -1
- package/types/fields/Code.vue.d.ts +1 -1
- package/types/fields/CodeLink.vue.d.ts +9 -9
- package/types/fields/CodeSelect.vue.d.ts +10 -7
- package/types/fields/CodeSelectCol.vue.d.ts +8 -5
- package/types/fields/DataSourceFields.vue.d.ts +8 -5
- package/types/fields/DataSourceInput.vue.d.ts +54 -0
- package/types/fields/DataSourceSelect.vue.d.ts +56 -0
- package/types/fields/EventSelect.vue.d.ts +3 -3
- package/types/fields/KeyValue.vue.d.ts +8 -5
- package/types/fields/UISelect.vue.d.ts +1 -1
- package/types/icons/AppManageIcon.vue.d.ts +1 -1
- package/types/icons/CenterIcon.vue.d.ts +2 -0
- package/types/icons/CodeIcon.vue.d.ts +1 -1
- package/types/index.d.ts +7 -2
- package/types/initService.d.ts +1 -1
- package/types/layouts/AddPageBox.vue.d.ts +1 -1
- package/types/layouts/CodeEditor.vue.d.ts +16 -10
- package/types/layouts/Framework.vue.d.ts +11 -32
- package/types/layouts/NavMenu.vue.d.ts +7 -4
- package/types/layouts/PropsPanel.vue.d.ts +276 -4
- package/types/layouts/sidebar/ComponentListPanel.vue.d.ts +4 -4
- package/types/layouts/sidebar/LayerMenu.vue.d.ts +2 -2
- package/types/layouts/sidebar/LayerNode.vue.d.ts +16 -0
- package/types/layouts/sidebar/LayerPanel.vue.d.ts +5 -5
- package/types/layouts/sidebar/Sidebar.vue.d.ts +18 -15
- package/types/layouts/sidebar/code-block/CodeBlockEditor.vue.d.ts +4 -4
- package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +7 -7
- package/types/layouts/sidebar/data-source/DataSourceConfigPanel.vue.d.ts +1 -1
- package/types/layouts/sidebar/data-source/DataSourceListPanel.vue.d.ts +3 -3
- package/types/layouts/workspace/Breadcrumb.vue.d.ts +1 -1
- package/types/layouts/workspace/PageBar.vue.d.ts +5 -5
- package/types/layouts/workspace/PageBarScrollContainer.vue.d.ts +2 -2
- package/types/layouts/workspace/Stage.vue.d.ts +2 -2
- package/types/layouts/workspace/ViewerMenu.vue.d.ts +7 -4
- package/types/layouts/workspace/Workspace.vue.d.ts +9 -9
- package/types/services/keybinding.d.ts +20 -0
- package/types/type.d.ts +56 -1
- package/types/utils/config.d.ts +1 -1
- package/types/utils/content-menu.d.ts +7 -0
- package/types/utils/keybinding-config.d.ts +3 -0
- package/src/layouts/Resizer.vue +0 -32
package/src/initService.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { ExtractPropTypes } from 'vue';
|
|
2
2
|
import { onUnmounted, toRaw, watch } from 'vue';
|
|
3
|
+
import { cloneDeep } from 'lodash-es';
|
|
3
4
|
|
|
4
5
|
import type { EventOption } from '@tmagic/core';
|
|
5
6
|
import type { CodeBlockContent, DataSourceSchema, Id, MApp, MNode, MPage } from '@tmagic/schema';
|
|
7
|
+
import { getNodes } from '@tmagic/utils';
|
|
6
8
|
|
|
7
9
|
import type { Target } from './services/dep';
|
|
8
10
|
import { createCodeBlockTarget, createDataSourceTarget } from './utils/dep';
|
|
@@ -23,6 +25,7 @@ export const initServiceState = (
|
|
|
23
25
|
eventsService,
|
|
24
26
|
uiService,
|
|
25
27
|
codeBlockService,
|
|
28
|
+
keybindingService,
|
|
26
29
|
}: Services,
|
|
27
30
|
) => {
|
|
28
31
|
// 初始值变化,重新设置节点信息
|
|
@@ -102,6 +105,7 @@ export const initServiceState = (
|
|
|
102
105
|
uiService.resetState();
|
|
103
106
|
componentListService.resetState();
|
|
104
107
|
codeBlockService.resetState();
|
|
108
|
+
keybindingService.reset();
|
|
105
109
|
});
|
|
106
110
|
};
|
|
107
111
|
|
|
@@ -110,6 +114,50 @@ export const initServiceEvents = (
|
|
|
110
114
|
emit: (event: 'props-panel-mounted' | 'update:modelValue', ...args: any[]) => void,
|
|
111
115
|
{ editorService, codeBlockService, dataSourceService, depService }: Services,
|
|
112
116
|
) => {
|
|
117
|
+
const getApp = () => {
|
|
118
|
+
const stage = editorService.get('stage');
|
|
119
|
+
return stage?.renderer.runtime?.getApp?.();
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const updateDataSoucreSchema = () => {
|
|
123
|
+
const root = editorService.get('root');
|
|
124
|
+
|
|
125
|
+
if (root?.dataSources) {
|
|
126
|
+
getApp()?.dataSourceManager?.updateSchema(root.dataSources);
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
const upateNodeWhenDataSourceChange = (nodes: MNode[]) => {
|
|
131
|
+
const root = editorService.get('root');
|
|
132
|
+
const stage = editorService.get('stage');
|
|
133
|
+
|
|
134
|
+
if (!root || !stage) return;
|
|
135
|
+
|
|
136
|
+
const app = getApp();
|
|
137
|
+
|
|
138
|
+
if (!app) return;
|
|
139
|
+
|
|
140
|
+
if (app.dsl) {
|
|
141
|
+
app.dsl.dataSourceDeps = root.dataSourceDeps;
|
|
142
|
+
app.dsl.dataSources = root.dataSources;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
updateDataSoucreSchema();
|
|
146
|
+
|
|
147
|
+
nodes.forEach((node) => {
|
|
148
|
+
const deps = Object.values(root.dataSourceDeps || {});
|
|
149
|
+
deps.forEach((dep) => {
|
|
150
|
+
if (dep[node.id]) {
|
|
151
|
+
stage.update({
|
|
152
|
+
config: cloneDeep(node),
|
|
153
|
+
parentId: editorService.getParentById(node.id)?.id,
|
|
154
|
+
root: cloneDeep(root),
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
};
|
|
160
|
+
|
|
113
161
|
const targetAddHandler = (target: Target) => {
|
|
114
162
|
if (target.type !== 'data-source') return;
|
|
115
163
|
|
|
@@ -130,8 +178,18 @@ export const initServiceEvents = (
|
|
|
130
178
|
delete root.dataSourceDeps[id];
|
|
131
179
|
};
|
|
132
180
|
|
|
181
|
+
const depUpdateHandler = (node: MNode) => {
|
|
182
|
+
upateNodeWhenDataSourceChange([node]);
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
const collectedHandler = (nodes: MNode[]) => {
|
|
186
|
+
upateNodeWhenDataSourceChange(nodes);
|
|
187
|
+
};
|
|
188
|
+
|
|
133
189
|
depService.on('add-target', targetAddHandler);
|
|
134
190
|
depService.on('remove-target', targetRemoveHandler);
|
|
191
|
+
depService.on('dep-update', depUpdateHandler);
|
|
192
|
+
depService.on('collected', collectedHandler);
|
|
135
193
|
|
|
136
194
|
const rootChangeHandler = async (value: MApp, preValue?: MApp | null) => {
|
|
137
195
|
const nodeId = editorService.get('node')?.id || props.defaultSelected;
|
|
@@ -178,18 +236,22 @@ export const initServiceEvents = (
|
|
|
178
236
|
}
|
|
179
237
|
};
|
|
180
238
|
|
|
239
|
+
// 新增节点,收集依赖
|
|
181
240
|
const nodeAddHandler = (nodes: MNode[]) => {
|
|
182
241
|
depService.collect(nodes);
|
|
183
242
|
};
|
|
184
243
|
|
|
244
|
+
// 节点更新,收集依赖
|
|
185
245
|
const nodeUpdateHandler = (nodes: MNode[]) => {
|
|
186
246
|
depService.collect(nodes);
|
|
187
247
|
};
|
|
188
248
|
|
|
249
|
+
// 节点删除,清除对齐的依赖收集
|
|
189
250
|
const nodeRemoveHandler = (nodes: MNode[]) => {
|
|
190
251
|
depService.clear(nodes);
|
|
191
252
|
};
|
|
192
253
|
|
|
254
|
+
// 由于历史记录变化是更新整个page,所以历史记录变化时,需要重新收集依赖
|
|
193
255
|
const historyChangeHandler = (page: MPage) => {
|
|
194
256
|
depService.collect([page], true);
|
|
195
257
|
};
|
|
@@ -218,16 +280,25 @@ export const initServiceEvents = (
|
|
|
218
280
|
|
|
219
281
|
const dataSourceAddHandler = (config: DataSourceSchema) => {
|
|
220
282
|
depService.addTarget(createDataSourceTarget(config.id, config));
|
|
283
|
+
getApp()?.dataSourceManager?.addDataSource(config);
|
|
221
284
|
};
|
|
222
285
|
|
|
223
286
|
const dataSourceUpdateHandler = (config: DataSourceSchema) => {
|
|
224
287
|
if (config.title) {
|
|
225
288
|
depService.getTarget(config.id)!.name = config.title;
|
|
226
289
|
}
|
|
290
|
+
const root = editorService.get('root');
|
|
291
|
+
|
|
292
|
+
const targets = depService.getTargets('data-source');
|
|
293
|
+
|
|
294
|
+
const nodes = getNodes(Object.keys(targets[config.id].deps), root?.items);
|
|
295
|
+
|
|
296
|
+
upateNodeWhenDataSourceChange(nodes);
|
|
227
297
|
};
|
|
228
298
|
|
|
229
299
|
const dataSourceRemoveHandler = (id: string) => {
|
|
230
300
|
depService.removeTarget(id);
|
|
301
|
+
getApp()?.dataSourceManager?.removeDataSource(id);
|
|
231
302
|
};
|
|
232
303
|
|
|
233
304
|
dataSourceService.on('add', dataSourceAddHandler);
|
|
@@ -237,6 +308,8 @@ export const initServiceEvents = (
|
|
|
237
308
|
onUnmounted(() => {
|
|
238
309
|
depService.off('add-target', targetAddHandler);
|
|
239
310
|
depService.off('remove-target', targetRemoveHandler);
|
|
311
|
+
depService.off('dep-update', depUpdateHandler);
|
|
312
|
+
depService.off('collected', collectedHandler);
|
|
240
313
|
|
|
241
314
|
editorService.off('history-change', historyChangeHandler);
|
|
242
315
|
editorService.off('root-change', rootChangeHandler);
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
</div>
|
|
12
12
|
</template>
|
|
13
13
|
|
|
14
|
-
<script lang="ts" setup
|
|
14
|
+
<script lang="ts" setup>
|
|
15
15
|
import { inject, toRaw } from 'vue';
|
|
16
16
|
import { Plus } from '@element-plus/icons-vue';
|
|
17
17
|
|
|
@@ -21,6 +21,10 @@ import MIcon from '@editor/components/Icon.vue';
|
|
|
21
21
|
import type { Services } from '@editor/type';
|
|
22
22
|
import { generatePageNameByApp } from '@editor/utils';
|
|
23
23
|
|
|
24
|
+
defineOptions({
|
|
25
|
+
name: 'MEditorAddPageBox',
|
|
26
|
+
});
|
|
27
|
+
|
|
24
28
|
const services = inject<Services>('services');
|
|
25
29
|
|
|
26
30
|
const clickHandler = () => {
|
|
@@ -2,16 +2,20 @@
|
|
|
2
2
|
<div ref="codeEditor" class="magic-code-editor"></div>
|
|
3
3
|
</template>
|
|
4
4
|
|
|
5
|
-
<script lang="ts" setup
|
|
5
|
+
<script lang="ts" setup>
|
|
6
6
|
import { onMounted, onUnmounted, ref, watch } from 'vue';
|
|
7
7
|
import { throttle } from 'lodash-es';
|
|
8
8
|
import * as monaco from 'monaco-editor';
|
|
9
9
|
import serialize from 'serialize-javascript';
|
|
10
10
|
|
|
11
|
+
defineOptions({
|
|
12
|
+
name: 'MEditorCodeEditor',
|
|
13
|
+
});
|
|
14
|
+
|
|
11
15
|
const props = withDefaults(
|
|
12
16
|
defineProps<{
|
|
13
|
-
initValues?: string |
|
|
14
|
-
modifiedValues?: string |
|
|
17
|
+
initValues?: string | Record<string | number, any> | null;
|
|
18
|
+
modifiedValues?: string | Record<string | number, any> | null;
|
|
15
19
|
type?: 'diff';
|
|
16
20
|
language?: string;
|
|
17
21
|
options?: {
|
|
@@ -33,10 +37,14 @@ const emit = defineEmits(['initd', 'save']);
|
|
|
33
37
|
const toString = (v: string | any, language: string): string => {
|
|
34
38
|
let value = '';
|
|
35
39
|
if (typeof v !== 'string') {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
if (props.language.toLocaleLowerCase() === 'json') {
|
|
41
|
+
value = JSON.stringify(v, null, 2);
|
|
42
|
+
} else {
|
|
43
|
+
value = serialize(v, {
|
|
44
|
+
space: 2,
|
|
45
|
+
unsafe: true,
|
|
46
|
+
}).replace(/"(\w+)":\s/g, '$1: ');
|
|
47
|
+
}
|
|
40
48
|
} else {
|
|
41
49
|
value = v;
|
|
42
50
|
}
|
|
@@ -77,7 +85,7 @@ const setEditorValue = (v: string | any, m: string | any) => {
|
|
|
77
85
|
};
|
|
78
86
|
|
|
79
87
|
const getEditorValue = () =>
|
|
80
|
-
props.type === 'diff' ? vsDiffEditor?.getModifiedEditor().getValue() : vsEditor?.getValue();
|
|
88
|
+
(props.type === 'diff' ? vsDiffEditor?.getModifiedEditor().getValue() : vsEditor?.getValue()) || '';
|
|
81
89
|
|
|
82
90
|
const init = async () => {
|
|
83
91
|
if (!codeEditor.value) return;
|
|
@@ -105,13 +113,19 @@ const init = async () => {
|
|
|
105
113
|
if (e.keyCode === 83 && (navigator.platform.match('Mac') ? e.metaKey : e.ctrlKey)) {
|
|
106
114
|
e.preventDefault();
|
|
107
115
|
e.stopPropagation();
|
|
108
|
-
|
|
116
|
+
const newValue = getEditorValue();
|
|
117
|
+
values.value = newValue;
|
|
118
|
+
emit('save', newValue);
|
|
109
119
|
}
|
|
110
120
|
});
|
|
111
121
|
|
|
112
122
|
if (props.type !== 'diff' && props.autoSave) {
|
|
113
123
|
vsEditor?.onDidBlurEditorWidget(() => {
|
|
114
|
-
|
|
124
|
+
const newValue = getEditorValue();
|
|
125
|
+
if (values.value !== newValue) {
|
|
126
|
+
values.value = newValue;
|
|
127
|
+
emit('save', newValue);
|
|
128
|
+
}
|
|
115
129
|
});
|
|
116
130
|
}
|
|
117
131
|
|
|
@@ -142,10 +156,20 @@ onUnmounted(() => {
|
|
|
142
156
|
});
|
|
143
157
|
|
|
144
158
|
defineExpose({
|
|
159
|
+
values,
|
|
160
|
+
|
|
145
161
|
getEditor() {
|
|
146
162
|
return vsEditor || vsDiffEditor;
|
|
147
163
|
},
|
|
148
164
|
|
|
165
|
+
getVsEditor() {
|
|
166
|
+
return vsEditor;
|
|
167
|
+
},
|
|
168
|
+
|
|
169
|
+
getVsDiffEditor() {
|
|
170
|
+
return vsDiffEditor;
|
|
171
|
+
},
|
|
172
|
+
|
|
149
173
|
setEditorValue,
|
|
150
174
|
|
|
151
175
|
focus() {
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="m-editor">
|
|
3
|
-
<slot name="
|
|
3
|
+
<slot name="header"></slot>
|
|
4
4
|
|
|
5
|
-
<
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
@save="saveCode"
|
|
11
|
-
|
|
5
|
+
<slot name="nav"></slot>
|
|
6
|
+
|
|
7
|
+
<slot name="content-before"></slot>
|
|
8
|
+
|
|
9
|
+
<slot name="src-code" v-if="showSrc">
|
|
10
|
+
<CodeEditor class="m-editor-content" :init-values="root" :options="codeOptions" @save="saveCode"></CodeEditor>
|
|
11
|
+
</slot>
|
|
12
12
|
|
|
13
|
-
<
|
|
13
|
+
<SplitView
|
|
14
14
|
v-else
|
|
15
15
|
class="m-editor-content"
|
|
16
16
|
left-class="m-editor-framework-left"
|
|
@@ -33,41 +33,41 @@
|
|
|
33
33
|
</slot>
|
|
34
34
|
</template>
|
|
35
35
|
|
|
36
|
-
<template v-if="pageLength > 0
|
|
36
|
+
<template v-if="pageLength > 0" #right>
|
|
37
37
|
<TMagicScrollbar>
|
|
38
38
|
<slot name="props-panel"></slot>
|
|
39
39
|
</TMagicScrollbar>
|
|
40
40
|
</template>
|
|
41
|
-
</
|
|
41
|
+
</SplitView>
|
|
42
|
+
|
|
43
|
+
<slot name="content-after"></slot>
|
|
44
|
+
<slot name="footer"></slot>
|
|
42
45
|
</div>
|
|
43
46
|
</template>
|
|
44
47
|
|
|
45
|
-
<script lang="ts" setup
|
|
48
|
+
<script lang="ts" setup>
|
|
46
49
|
import { computed, inject, ref, watch } from 'vue';
|
|
47
50
|
|
|
48
51
|
import { TMagicScrollbar } from '@tmagic/design';
|
|
49
52
|
|
|
50
|
-
import
|
|
53
|
+
import SplitView from '@editor/components/SplitView.vue';
|
|
51
54
|
import type { GetColumnWidth, Services } from '@editor/type';
|
|
55
|
+
import { getConfig } from '@editor/utils/config';
|
|
52
56
|
|
|
53
57
|
import AddPageBox from './AddPageBox.vue';
|
|
58
|
+
import CodeEditor from './CodeEditor.vue';
|
|
59
|
+
|
|
60
|
+
defineOptions({
|
|
61
|
+
name: 'MEditorFramework',
|
|
62
|
+
});
|
|
54
63
|
|
|
55
64
|
const DEFAULT_LEFT_COLUMN_WIDTH = 310;
|
|
56
65
|
const DEFAULT_RIGHT_COLUMN_WIDTH = 480;
|
|
57
66
|
|
|
58
|
-
|
|
59
|
-
defineProps<{
|
|
60
|
-
codeOptions?: Record<string, any>;
|
|
61
|
-
}>(),
|
|
62
|
-
{
|
|
63
|
-
codeOptions: () => ({}),
|
|
64
|
-
},
|
|
65
|
-
);
|
|
66
|
-
|
|
67
|
+
const codeOptions = inject('codeOptions', {});
|
|
67
68
|
const { editorService, uiService } = inject<Services>('services') || {};
|
|
68
69
|
|
|
69
70
|
const root = computed(() => editorService?.get('root'));
|
|
70
|
-
const nodes = computed(() => editorService?.get('nodes') || []);
|
|
71
71
|
|
|
72
72
|
const pageLength = computed(() => editorService?.get('pageLength') || 0);
|
|
73
73
|
const showSrc = computed(() => uiService?.get('showSrc'));
|
|
@@ -131,8 +131,8 @@ const columnWidthChange = (columnW: GetColumnWidth) => {
|
|
|
131
131
|
|
|
132
132
|
const saveCode = (value: string) => {
|
|
133
133
|
try {
|
|
134
|
-
|
|
135
|
-
editorService?.set('root',
|
|
134
|
+
const parseDSL = getConfig('parseDSL');
|
|
135
|
+
editorService?.set('root', parseDSL(value));
|
|
136
136
|
} catch (e: any) {
|
|
137
137
|
console.error(e);
|
|
138
138
|
}
|
package/src/layouts/NavMenu.vue
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
</div>
|
|
7
7
|
</template>
|
|
8
8
|
|
|
9
|
-
<script lang="ts" setup
|
|
9
|
+
<script lang="ts" setup>
|
|
10
10
|
import { computed, inject, markRaw } from 'vue';
|
|
11
11
|
import { Back, Delete, FullScreen, Grid, Memo, Right, ScaleToOriginal, ZoomIn, ZoomOut } from '@element-plus/icons-vue';
|
|
12
12
|
|
|
@@ -15,6 +15,10 @@ import { NodeType } from '@tmagic/schema';
|
|
|
15
15
|
import ToolButton from '@editor/components/ToolButton.vue';
|
|
16
16
|
import { ColumnLayout, MenuBarData, MenuButton, MenuComponent, MenuItem, Services } from '@editor/type';
|
|
17
17
|
|
|
18
|
+
defineOptions({
|
|
19
|
+
name: 'MEditorNavMenu',
|
|
20
|
+
});
|
|
21
|
+
|
|
18
22
|
const props = withDefaults(
|
|
19
23
|
defineProps<{
|
|
20
24
|
data?: MenuBarData;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="m-editor-props-panel">
|
|
2
|
+
<div class="m-editor-props-panel" v-show="nodes.length === 1">
|
|
3
3
|
<slot name="props-panel-header"></slot>
|
|
4
4
|
<MForm
|
|
5
5
|
ref="configForm"
|
|
@@ -8,20 +8,29 @@
|
|
|
8
8
|
:size="propsPanelSize"
|
|
9
9
|
:init-values="values"
|
|
10
10
|
:config="curFormConfig"
|
|
11
|
+
:extend-state="extendState"
|
|
11
12
|
@change="submit"
|
|
12
13
|
></MForm>
|
|
13
14
|
</div>
|
|
14
15
|
</template>
|
|
15
16
|
|
|
16
|
-
<script lang="ts" setup
|
|
17
|
+
<script lang="ts" setup>
|
|
17
18
|
import { computed, getCurrentInstance, inject, onMounted, onUnmounted, ref, watchEffect } from 'vue';
|
|
18
19
|
|
|
19
20
|
import { tMagicMessage } from '@tmagic/design';
|
|
20
|
-
import type { FormValue } from '@tmagic/form';
|
|
21
|
+
import type { FormState, FormValue } from '@tmagic/form';
|
|
21
22
|
import { MForm } from '@tmagic/form';
|
|
22
23
|
|
|
23
24
|
import type { Services } from '@editor/type';
|
|
24
25
|
|
|
26
|
+
defineOptions({
|
|
27
|
+
name: 'MEditorPropsPanel',
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
defineProps<{
|
|
31
|
+
extendState?: (state: FormState) => Record<string, any> | Promise<Record<string, any>>;
|
|
32
|
+
}>();
|
|
33
|
+
|
|
25
34
|
const emit = defineEmits(['mounted']);
|
|
26
35
|
|
|
27
36
|
const internalInstance = getCurrentInstance();
|
|
@@ -31,6 +40,7 @@ const configForm = ref<InstanceType<typeof MForm>>();
|
|
|
31
40
|
const curFormConfig = ref<any>([]);
|
|
32
41
|
const services = inject<Services>('services');
|
|
33
42
|
const node = computed(() => services?.editorService.get('node'));
|
|
43
|
+
const nodes = computed(() => services?.editorService.get('nodes') || []);
|
|
34
44
|
const propsPanelSize = computed(() => services?.uiService.get('propsPanelSize') || 'small');
|
|
35
45
|
const stage = computed(() => services?.editorService.get('stage'));
|
|
36
46
|
|
|
@@ -73,5 +83,5 @@ const submit = async () => {
|
|
|
73
83
|
}
|
|
74
84
|
};
|
|
75
85
|
|
|
76
|
-
defineExpose({ submit });
|
|
86
|
+
defineExpose({ configForm, submit });
|
|
77
87
|
</script>
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
</TMagicScrollbar>
|
|
32
32
|
</template>
|
|
33
33
|
|
|
34
|
-
<script lang="ts" setup
|
|
34
|
+
<script lang="ts" setup>
|
|
35
35
|
import { computed, inject, ref } from 'vue';
|
|
36
36
|
import { Grid } from '@element-plus/icons-vue';
|
|
37
37
|
import serialize from 'serialize-javascript';
|
|
@@ -43,6 +43,10 @@ import MIcon from '@editor/components/Icon.vue';
|
|
|
43
43
|
import SearchInput from '@editor/components/SearchInput.vue';
|
|
44
44
|
import type { ComponentGroup, ComponentItem, Services, StageOptions } from '@editor/type';
|
|
45
45
|
|
|
46
|
+
defineOptions({
|
|
47
|
+
name: 'MEditorComponentListPanel',
|
|
48
|
+
});
|
|
49
|
+
|
|
46
50
|
const searchText = ref('');
|
|
47
51
|
|
|
48
52
|
const filterTextChangeHandler = (v: string) => {
|
|
@@ -79,14 +83,13 @@ const appendComponent = ({ text, type, data = {} }: ComponentItem): void => {
|
|
|
79
83
|
|
|
80
84
|
const dragstartHandler = ({ text, type, data = {} }: ComponentItem, e: DragEvent) => {
|
|
81
85
|
if (e.dataTransfer) {
|
|
82
|
-
e.dataTransfer.effectAllowed = 'move';
|
|
83
86
|
e.dataTransfer.setData(
|
|
84
|
-
'
|
|
87
|
+
'text/html',
|
|
85
88
|
serialize({
|
|
86
89
|
name: text,
|
|
87
90
|
type,
|
|
88
91
|
...data,
|
|
89
|
-
})
|
|
92
|
+
}),
|
|
90
93
|
);
|
|
91
94
|
}
|
|
92
95
|
};
|
|
@@ -117,6 +120,6 @@ const dragHandler = (e: DragEvent) => {
|
|
|
117
120
|
|
|
118
121
|
if (timeout || !stage.value) return;
|
|
119
122
|
|
|
120
|
-
timeout = stage.value.
|
|
123
|
+
timeout = stage.value.delayedMarkContainer(e);
|
|
121
124
|
};
|
|
122
125
|
</script>
|
|
@@ -2,14 +2,17 @@
|
|
|
2
2
|
<ContentMenu :menu-data="menuData" ref="menu" style="overflow: initial"></ContentMenu>
|
|
3
3
|
</template>
|
|
4
4
|
|
|
5
|
-
<script lang="ts" setup
|
|
5
|
+
<script lang="ts" setup>
|
|
6
6
|
import { computed, inject, markRaw, ref } from 'vue';
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
import { NodeType } from '@tmagic/schema';
|
|
7
|
+
import { Files, Plus } from '@element-plus/icons-vue';
|
|
10
8
|
|
|
11
9
|
import ContentMenu from '@editor/components/ContentMenu.vue';
|
|
12
10
|
import type { ComponentGroup, MenuButton, MenuComponent, Services } from '@editor/type';
|
|
11
|
+
import { useCopyMenu, useDeleteMenu, useMoveToMenu, usePasteMenu } from '@editor/utils/content-menu';
|
|
12
|
+
|
|
13
|
+
defineOptions({
|
|
14
|
+
name: 'MEditorLayerMenu',
|
|
15
|
+
});
|
|
13
16
|
|
|
14
17
|
const props = defineProps<{
|
|
15
18
|
layerContentMenu: (MenuButton | MenuComponent)[];
|
|
@@ -18,8 +21,7 @@ const props = defineProps<{
|
|
|
18
21
|
const services = inject<Services>('services');
|
|
19
22
|
const menu = ref<InstanceType<typeof ContentMenu>>();
|
|
20
23
|
const node = computed(() => services?.editorService.get('node'));
|
|
21
|
-
const
|
|
22
|
-
const isPage = computed(() => node.value?.type === NodeType.PAGE);
|
|
24
|
+
const nodes = computed(() => services?.editorService.get('nodes'));
|
|
23
25
|
const componentList = computed(() => services?.componentListService.getList() || []);
|
|
24
26
|
|
|
25
27
|
const createMenuItems = (group: ComponentGroup): MenuButton[] =>
|
|
@@ -78,27 +80,13 @@ const menuData = computed<(MenuButton | MenuComponent)[]>(() => [
|
|
|
78
80
|
type: 'button',
|
|
79
81
|
text: '新增',
|
|
80
82
|
icon: markRaw(Plus),
|
|
81
|
-
display: () => node.value?.items,
|
|
83
|
+
display: () => node.value?.items && nodes.value?.length === 1,
|
|
82
84
|
items: getSubMenuData.value,
|
|
83
85
|
},
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
display: () => !isRoot.value,
|
|
89
|
-
handler: () => {
|
|
90
|
-
node.value && services?.editorService.copy(node.value);
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
type: 'button',
|
|
95
|
-
text: '删除',
|
|
96
|
-
icon: markRaw(Delete),
|
|
97
|
-
display: () => !isRoot.value && !isPage.value,
|
|
98
|
-
handler: () => {
|
|
99
|
-
node.value && services?.editorService.remove(node.value);
|
|
100
|
-
},
|
|
101
|
-
},
|
|
86
|
+
useCopyMenu(),
|
|
87
|
+
usePasteMenu(),
|
|
88
|
+
useDeleteMenu(),
|
|
89
|
+
useMoveToMenu(services),
|
|
102
90
|
...props.layerContentMenu,
|
|
103
91
|
]);
|
|
104
92
|
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div>
|
|
3
|
+
{{ `${data.name} (${data.id})` }}
|
|
4
|
+
</div>
|
|
5
|
+
<div class="layer-node-tool">
|
|
6
|
+
<template v-if="data.type !== 'page'">
|
|
7
|
+
<el-icon v-if="data.visible === false" @click.stop="setNodeVisible(true)" title="点击显示">
|
|
8
|
+
<Hide />
|
|
9
|
+
</el-icon>
|
|
10
|
+
<el-icon v-else @click.stop="setNodeVisible(false)" class="node-lock" title="点击隐藏">
|
|
11
|
+
<View />
|
|
12
|
+
</el-icon>
|
|
13
|
+
</template>
|
|
14
|
+
</div>
|
|
15
|
+
</template>
|
|
16
|
+
|
|
17
|
+
<script lang="ts" setup>
|
|
18
|
+
import { inject } from 'vue';
|
|
19
|
+
import { Hide, View } from '@element-plus/icons-vue';
|
|
20
|
+
|
|
21
|
+
import { MNode } from '@tmagic/schema';
|
|
22
|
+
|
|
23
|
+
import { Services } from '@editor/type';
|
|
24
|
+
|
|
25
|
+
const props = defineProps<{
|
|
26
|
+
data: MNode;
|
|
27
|
+
}>();
|
|
28
|
+
|
|
29
|
+
const services = inject<Services>('services');
|
|
30
|
+
const editorService = services?.editorService;
|
|
31
|
+
|
|
32
|
+
const setNodeVisible = (visible: boolean) => {
|
|
33
|
+
if (!editorService) return;
|
|
34
|
+
|
|
35
|
+
editorService.update({
|
|
36
|
+
id: props.data.id,
|
|
37
|
+
visible,
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
</script>
|