@tmagic/editor 1.2.0 → 1.2.2
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 +4 -0
- package/dist/tmagic-editor.js +305 -249
- package/dist/tmagic-editor.js.map +1 -1
- package/dist/tmagic-editor.umd.cjs +308 -253
- package/dist/tmagic-editor.umd.cjs.map +1 -1
- package/package.json +9 -9
- package/src/Editor.vue +1 -1
- package/src/components/CodeDraftEditor.vue +2 -10
- package/src/components/FunctionEditor.vue +58 -13
- package/src/components/Layout.vue +1 -1
- package/src/fields/CodeSelect.vue +23 -7
- package/src/fields/UISelect.vue +2 -2
- package/src/index.ts +1 -1
- package/src/layouts/AddPageBox.vue +4 -1
- package/src/layouts/Framework.vue +10 -8
- package/src/layouts/NavMenu.vue +9 -6
- package/src/layouts/PropsPanel.vue +3 -7
- package/src/layouts/sidebar/ComponentListPanel.vue +1 -2
- package/src/layouts/sidebar/LayerPanel.vue +8 -9
- package/src/layouts/sidebar/code-block/CodeBlockEditor.vue +10 -39
- package/src/layouts/sidebar/code-block/CodeBlockList.vue +5 -6
- package/src/layouts/workspace/Breadcrumb.vue +5 -6
- package/src/layouts/workspace/PageBar.vue +2 -2
- package/src/layouts/workspace/PageBarScrollContainer.vue +4 -2
- package/src/layouts/workspace/Stage.vue +11 -10
- package/src/layouts/workspace/ViewerMenu.vue +5 -6
- package/src/layouts/workspace/Workspace.vue +2 -3
- package/src/services/BaseService.ts +1 -1
- package/src/services/codeBlock.ts +15 -24
- package/src/services/componentList.ts +1 -1
- package/src/services/editor.ts +119 -79
- package/src/services/events.ts +1 -1
- package/src/services/history.ts +1 -1
- package/src/services/props.ts +1 -1
- package/src/services/ui.ts +8 -10
- package/src/theme/code-block.scss +4 -0
- package/src/type.ts +7 -13
- package/src/utils/config.ts +1 -1
- package/src/utils/editor.ts +8 -2
- package/src/utils/index.ts +1 -1
- package/src/utils/logger.ts +1 -1
- package/src/utils/operator.ts +12 -12
- package/src/utils/props.ts +1 -1
- package/src/utils/stage.ts +6 -6
- package/src/utils/undo-redo.ts +1 -1
- package/types/Editor.vue.d.ts +1 -1
- package/types/components/CodeDraftEditor.vue.d.ts +1 -2
- package/types/components/FunctionEditor.vue.d.ts +17 -0
- package/types/layouts/sidebar/code-block/CodeBlockEditor.vue.d.ts +23 -5
- package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +5 -0
- package/types/layouts/workspace/Workspace.vue.d.ts +2 -3
- package/types/services/codeBlock.d.ts +0 -12
- package/types/services/editor.d.ts +6 -6
- package/types/services/ui.d.ts +23 -24
- package/types/type.d.ts +5 -11
- package/types/utils/operator.d.ts +1 -1
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.2.
|
|
2
|
+
"version": "1.2.2",
|
|
3
3
|
"name": "@tmagic/editor",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": [
|
|
@@ -46,12 +46,12 @@
|
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@babel/core": "^7.18.0",
|
|
48
48
|
"@element-plus/icons-vue": "^2.0.9",
|
|
49
|
-
"@tmagic/core": "1.2.
|
|
50
|
-
"@tmagic/design": "1.2.
|
|
51
|
-
"@tmagic/form": "1.2.
|
|
52
|
-
"@tmagic/schema": "1.2.
|
|
53
|
-
"@tmagic/stage": "1.2.
|
|
54
|
-
"@tmagic/utils": "1.2.
|
|
49
|
+
"@tmagic/core": "1.2.2",
|
|
50
|
+
"@tmagic/design": "1.2.2",
|
|
51
|
+
"@tmagic/form": "1.2.2",
|
|
52
|
+
"@tmagic/schema": "1.2.2",
|
|
53
|
+
"@tmagic/stage": "1.2.2",
|
|
54
|
+
"@tmagic/utils": "1.2.2",
|
|
55
55
|
"buffer": "^6.0.3",
|
|
56
56
|
"color": "^3.1.3",
|
|
57
57
|
"events": "^3.3.0",
|
|
@@ -63,8 +63,8 @@
|
|
|
63
63
|
"vue": "^3.2.37"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
66
|
-
"@tmagic/design": "1.2.
|
|
67
|
-
"@tmagic/form": "1.2.
|
|
66
|
+
"@tmagic/design": "1.2.2",
|
|
67
|
+
"@tmagic/form": "1.2.2",
|
|
68
68
|
"monaco-editor": "^0.34.0",
|
|
69
69
|
"vue": "^3.2.37"
|
|
70
70
|
},
|
package/src/Editor.vue
CHANGED
|
@@ -228,7 +228,7 @@ export default defineComponent({
|
|
|
228
228
|
|
|
229
229
|
setup(props, { emit }) {
|
|
230
230
|
const rootChangeHandler = (value: MApp, preValue?: MApp | null) => {
|
|
231
|
-
const nodeId = editorService.get
|
|
231
|
+
const nodeId = editorService.get('node')?.id || props.defaultSelected;
|
|
232
232
|
let node;
|
|
233
233
|
if (nodeId) {
|
|
234
234
|
node = editorService.getNodeById(nodeId);
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<TMagicButton type="primary" class="button" @click="toggleFullScreen">
|
|
13
13
|
{{ isFullScreen ? '退出全屏' : '全屏' }}</TMagicButton
|
|
14
14
|
>
|
|
15
|
-
<TMagicButton type="primary" class="button" @click="
|
|
15
|
+
<TMagicButton type="primary" class="button" @click="saveAndClose">确认</TMagicButton>
|
|
16
16
|
<TMagicButton type="primary" class="button" @click="close">关闭</TMagicButton>
|
|
17
17
|
</div>
|
|
18
18
|
<div class="m-editor-content-bottom" v-else>
|
|
@@ -54,7 +54,7 @@ const props = withDefaults(
|
|
|
54
54
|
autoSaveDraft: true,
|
|
55
55
|
},
|
|
56
56
|
);
|
|
57
|
-
const emit = defineEmits(['
|
|
57
|
+
const emit = defineEmits(['close', 'saveAndClose']);
|
|
58
58
|
|
|
59
59
|
const services = inject<Services>('services');
|
|
60
60
|
|
|
@@ -95,14 +95,6 @@ const saveCodeDraft = async (codeValue: string) => {
|
|
|
95
95
|
tMagicMessage.success(`代码草稿保存成功 ${datetimeFormatter(new Date())}`);
|
|
96
96
|
};
|
|
97
97
|
|
|
98
|
-
// 保存代码
|
|
99
|
-
const saveCode = (): void => {
|
|
100
|
-
if (!codeEditor.value || !props.editable) return;
|
|
101
|
-
// 代码内容
|
|
102
|
-
editorContent.value = (codeEditor.value.getEditor() as monaco.editor.IStandaloneCodeEditor)?.getValue();
|
|
103
|
-
emit('save', editorContent.value);
|
|
104
|
-
};
|
|
105
|
-
|
|
106
98
|
// 保存并关闭
|
|
107
99
|
const saveAndClose = (): void => {
|
|
108
100
|
if (!codeEditor.value || !props.editable) return;
|
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
<TMagicInput class="code-name-input" v-model="codeName" :disabled="!editable" />
|
|
7
7
|
</div>
|
|
8
8
|
<div class="code-name-wrapper">
|
|
9
|
-
<div class="code-name-label"
|
|
9
|
+
<div class="code-name-label">参数</div>
|
|
10
10
|
<m-form-table
|
|
11
|
-
style="width:
|
|
11
|
+
style="width: 800px"
|
|
12
12
|
:config="tableConfig"
|
|
13
13
|
:model="tableModel"
|
|
14
14
|
:enableToggleMode="false"
|
|
@@ -26,7 +26,6 @@
|
|
|
26
26
|
:autoSaveDraft="autoSaveDraft"
|
|
27
27
|
:codeOptions="codeOptions"
|
|
28
28
|
language="javascript"
|
|
29
|
-
@save="saveCode"
|
|
30
29
|
@saveAndClose="saveAndClose"
|
|
31
30
|
@close="close"
|
|
32
31
|
></CodeDraftEditor>
|
|
@@ -34,36 +33,56 @@
|
|
|
34
33
|
</template>
|
|
35
34
|
<script lang="ts" setup name="MEditorFunctionEditor">
|
|
36
35
|
import { inject, provide, ref, watchEffect } from 'vue';
|
|
36
|
+
import { cloneDeep } from 'lodash-es';
|
|
37
37
|
|
|
38
38
|
import { TMagicCard, TMagicInput, tMagicMessage } from '@tmagic/design';
|
|
39
|
+
import { ColumnConfig, TableConfig } from '@tmagic/form';
|
|
39
40
|
import { CodeParam, Id } from '@tmagic/schema';
|
|
40
41
|
|
|
41
42
|
import type { Services } from '../type';
|
|
42
43
|
|
|
43
44
|
import CodeDraftEditor from './CodeDraftEditor.vue';
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
enableFullscreen: false,
|
|
48
|
-
name: 'params',
|
|
49
|
-
maxHeight: '150px',
|
|
45
|
+
const defaultParamColConfig: ColumnConfig = {
|
|
46
|
+
type: 'row',
|
|
47
|
+
label: '参数类型',
|
|
50
48
|
items: [
|
|
51
49
|
{
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
text: '参数类型',
|
|
51
|
+
labelWidth: '70px',
|
|
52
|
+
type: 'select',
|
|
53
|
+
name: 'type',
|
|
54
|
+
options: [
|
|
55
|
+
{
|
|
56
|
+
text: '数字',
|
|
57
|
+
label: '数字',
|
|
58
|
+
value: 'number',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
text: '字符串',
|
|
62
|
+
label: '字符串',
|
|
63
|
+
value: 'text',
|
|
64
|
+
},
|
|
65
|
+
],
|
|
55
66
|
},
|
|
56
67
|
],
|
|
57
68
|
};
|
|
58
69
|
|
|
59
70
|
const props = withDefaults(
|
|
60
71
|
defineProps<{
|
|
72
|
+
/** 代码块id */
|
|
61
73
|
id: Id;
|
|
74
|
+
/** 代码块名称 */
|
|
62
75
|
name: string;
|
|
76
|
+
/** 代码内容 */
|
|
63
77
|
content: string;
|
|
78
|
+
/** 是否可编辑 */
|
|
64
79
|
editable?: boolean;
|
|
80
|
+
/** 是否自动保存草稿 */
|
|
65
81
|
autoSaveDraft?: boolean;
|
|
82
|
+
/** 编辑器扩展参数 */
|
|
66
83
|
codeOptions?: object;
|
|
84
|
+
/** 代码参数扩展配置 */
|
|
85
|
+
paramsColConfig?: ColumnConfig;
|
|
67
86
|
}>(),
|
|
68
87
|
{
|
|
69
88
|
editable: true,
|
|
@@ -71,6 +90,32 @@ const props = withDefaults(
|
|
|
71
90
|
},
|
|
72
91
|
);
|
|
73
92
|
|
|
93
|
+
const paramsColConfig = props.paramsColConfig || defaultParamColConfig;
|
|
94
|
+
|
|
95
|
+
const tableConfig: TableConfig = {
|
|
96
|
+
type: 'table',
|
|
97
|
+
border: true,
|
|
98
|
+
enableFullscreen: false,
|
|
99
|
+
name: 'params',
|
|
100
|
+
maxHeight: '300px',
|
|
101
|
+
dropSort: false,
|
|
102
|
+
items: [
|
|
103
|
+
{
|
|
104
|
+
type: 'text',
|
|
105
|
+
label: '参数名',
|
|
106
|
+
name: 'name',
|
|
107
|
+
width: 200,
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
type: 'text',
|
|
111
|
+
label: '参数注释',
|
|
112
|
+
name: 'tip',
|
|
113
|
+
width: 200,
|
|
114
|
+
},
|
|
115
|
+
paramsColConfig,
|
|
116
|
+
],
|
|
117
|
+
};
|
|
118
|
+
|
|
74
119
|
const emit = defineEmits(['change', 'field-input']);
|
|
75
120
|
|
|
76
121
|
const services = inject<Services>('services');
|
|
@@ -91,7 +136,7 @@ watchEffect(() => {
|
|
|
91
136
|
});
|
|
92
137
|
|
|
93
138
|
const initTableModel = (): void => {
|
|
94
|
-
const codeDsl = services?.codeBlockService.getCodeDslSync();
|
|
139
|
+
const codeDsl = cloneDeep(services?.codeBlockService.getCodeDslSync());
|
|
95
140
|
if (!codeDsl) return;
|
|
96
141
|
tableModel.value = {
|
|
97
142
|
params: codeDsl[props.id]?.params || [],
|
|
@@ -9,17 +9,27 @@
|
|
|
9
9
|
:size="size"
|
|
10
10
|
@change="changeHandler"
|
|
11
11
|
>
|
|
12
|
+
<template #operateCol="{ scope }">
|
|
13
|
+
<Icon
|
|
14
|
+
v-if="scope.row.codeId"
|
|
15
|
+
:icon="editable ? Edit : View"
|
|
16
|
+
class="edit-icon"
|
|
17
|
+
@click="editCode(scope.row.codeId)"
|
|
18
|
+
></Icon>
|
|
19
|
+
</template>
|
|
12
20
|
</m-form-table>
|
|
13
21
|
</div>
|
|
14
22
|
</template>
|
|
15
23
|
|
|
16
24
|
<script lang="ts" setup name="MEditorCodeSelect">
|
|
17
25
|
import { computed, defineEmits, defineProps, inject, watch } from 'vue';
|
|
26
|
+
import { Edit, View } from '@element-plus/icons-vue';
|
|
18
27
|
import { isEmpty, map } from 'lodash-es';
|
|
19
28
|
|
|
20
29
|
import { createValues, FormItem, FormState, TableConfig } from '@tmagic/form';
|
|
21
30
|
import { HookType, Id } from '@tmagic/schema';
|
|
22
31
|
|
|
32
|
+
import Icon from '../components/Icon.vue';
|
|
23
33
|
import { CodeParamStatement, HookData, Services } from '../type';
|
|
24
34
|
const services = inject<Services>('services');
|
|
25
35
|
const mForm = inject<FormState>('mForm');
|
|
@@ -38,9 +48,10 @@ const codeDsl = computed(() => services?.codeBlockService.getCodeDslSync());
|
|
|
38
48
|
|
|
39
49
|
const tableConfig = computed<FormItem>(() => {
|
|
40
50
|
const defaultConfig = {
|
|
41
|
-
dropSort:
|
|
51
|
+
dropSort: false,
|
|
42
52
|
enableFullscreen: false,
|
|
43
53
|
border: true,
|
|
54
|
+
operateColWidth: 60,
|
|
44
55
|
items: [
|
|
45
56
|
{
|
|
46
57
|
type: 'select',
|
|
@@ -68,8 +79,8 @@ const tableConfig = computed<FormItem>(() => {
|
|
|
68
79
|
defaultValue: {},
|
|
69
80
|
itemsFunction: (row: HookData) => {
|
|
70
81
|
const paramsConfig = getParamsConfig(row.codeId);
|
|
71
|
-
|
|
72
|
-
if (isEmpty(row.params)) {
|
|
82
|
+
// 如果参数没有填值,则使用createValues补全空值
|
|
83
|
+
if (isEmpty(row.params) || !row.params) {
|
|
73
84
|
createValues(mForm, paramsConfig, {}, row.params);
|
|
74
85
|
}
|
|
75
86
|
return paramsConfig;
|
|
@@ -83,6 +94,8 @@ const tableConfig = computed<FormItem>(() => {
|
|
|
83
94
|
};
|
|
84
95
|
});
|
|
85
96
|
|
|
97
|
+
const editable = computed(() => services?.codeBlockService.getEditStatus());
|
|
98
|
+
|
|
86
99
|
watch(
|
|
87
100
|
() => props.model[props.name],
|
|
88
101
|
(value) => {
|
|
@@ -104,15 +117,18 @@ const changeHandler = async () => {
|
|
|
104
117
|
emit('change', props.model[props.name]);
|
|
105
118
|
};
|
|
106
119
|
|
|
107
|
-
const getParamsConfig = (codeId: Id) => {
|
|
120
|
+
const getParamsConfig = (codeId: Id): CodeParamStatement[] => {
|
|
108
121
|
if (!codeDsl.value) return [];
|
|
109
122
|
const paramStatements = codeDsl.value[codeId]?.params;
|
|
110
123
|
if (isEmpty(paramStatements)) return [];
|
|
111
124
|
return paramStatements.map((paramState: CodeParamStatement) => ({
|
|
112
|
-
name: paramState.name,
|
|
113
|
-
text: paramState.name,
|
|
114
125
|
labelWidth: '100px',
|
|
115
|
-
|
|
126
|
+
text: paramState.name,
|
|
127
|
+
...paramState,
|
|
116
128
|
}));
|
|
117
129
|
};
|
|
130
|
+
|
|
131
|
+
const editCode = (codeId: Id) => {
|
|
132
|
+
services?.codeBlockService.setCodeEditorContent(true, codeId);
|
|
133
|
+
};
|
|
118
134
|
</script>
|
package/src/fields/UISelect.vue
CHANGED
|
@@ -37,7 +37,7 @@ const uiSelectMode = ref(false);
|
|
|
37
37
|
|
|
38
38
|
const cancelHandler = () => {
|
|
39
39
|
if (!services?.uiService) return;
|
|
40
|
-
services.uiService.set
|
|
40
|
+
services.uiService.set('uiSelectMode', false);
|
|
41
41
|
uiSelectMode.value = false;
|
|
42
42
|
globalThis.document.removeEventListener('ui-select', clickHandler as EventListener);
|
|
43
43
|
};
|
|
@@ -61,7 +61,7 @@ const toName = computed(() => {
|
|
|
61
61
|
|
|
62
62
|
const startSelect = () => {
|
|
63
63
|
if (!services?.uiService) return;
|
|
64
|
-
services.uiService.set
|
|
64
|
+
services.uiService.set('uiSelectMode', true);
|
|
65
65
|
uiSelectMode.value = true;
|
|
66
66
|
globalThis.document.addEventListener('ui-select', clickHandler as EventListener);
|
|
67
67
|
};
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Tencent is pleased to support the open source community by making TMagicEditor available.
|
|
3
3
|
*
|
|
4
|
-
* Copyright (C)
|
|
4
|
+
* Copyright (C) 2023 THL A29 Limited, a Tencent company. All rights reserved.
|
|
5
5
|
*
|
|
6
6
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
7
|
* you may not use this file except in compliance with the License.
|
|
@@ -28,9 +28,12 @@ const clickHandler = () => {
|
|
|
28
28
|
|
|
29
29
|
if (!editorService) return;
|
|
30
30
|
|
|
31
|
+
const root = toRaw(editorService.get('root'));
|
|
32
|
+
if (!root) throw new Error('root 不能为空');
|
|
33
|
+
|
|
31
34
|
editorService.add({
|
|
32
35
|
type: NodeType.PAGE,
|
|
33
|
-
name: generatePageNameByApp(
|
|
36
|
+
name: generatePageNameByApp(root),
|
|
34
37
|
});
|
|
35
38
|
};
|
|
36
39
|
</script>
|
|
@@ -46,7 +46,6 @@
|
|
|
46
46
|
import { computed, inject, ref, watch } from 'vue';
|
|
47
47
|
|
|
48
48
|
import { TMagicScrollbar } from '@tmagic/design';
|
|
49
|
-
import type { MApp } from '@tmagic/schema';
|
|
50
49
|
|
|
51
50
|
import Layout from '../components/Layout.vue';
|
|
52
51
|
import { GetColumnWidth, Services } from '../type';
|
|
@@ -67,11 +66,11 @@ withDefaults(
|
|
|
67
66
|
|
|
68
67
|
const { editorService, uiService } = inject<Services>('services') || {};
|
|
69
68
|
|
|
70
|
-
const root = computed(() => editorService?.get
|
|
71
|
-
const nodes = computed(() => editorService?.get
|
|
69
|
+
const root = computed(() => editorService?.get('root'));
|
|
70
|
+
const nodes = computed(() => editorService?.get('nodes') || []);
|
|
72
71
|
|
|
73
|
-
const pageLength = computed(() => editorService?.get
|
|
74
|
-
const showSrc = computed(() => uiService?.get
|
|
72
|
+
const pageLength = computed(() => editorService?.get('pageLength') || 0);
|
|
73
|
+
const showSrc = computed(() => uiService?.get('showSrc'));
|
|
75
74
|
|
|
76
75
|
const LEFT_COLUMN_WIDTH_STORAGE_KEY = '$MagicEditorLeftColumnWidthData';
|
|
77
76
|
const RIGHT_COLUMN_WIDTH_STORAGE_KEY = '$MagicEditorRightColumnWidthData';
|
|
@@ -101,7 +100,7 @@ watch(
|
|
|
101
100
|
columnWidth.value.center = globalThis.document.body.clientWidth - left - right;
|
|
102
101
|
}
|
|
103
102
|
|
|
104
|
-
uiService?.set('columnWidth', columnWidth);
|
|
103
|
+
uiService?.set('columnWidth', columnWidth.value as GetColumnWidth);
|
|
105
104
|
},
|
|
106
105
|
{
|
|
107
106
|
immediate: true,
|
|
@@ -123,8 +122,11 @@ watch(
|
|
|
123
122
|
},
|
|
124
123
|
);
|
|
125
124
|
|
|
126
|
-
const columnWidthChange = (
|
|
127
|
-
|
|
125
|
+
const columnWidthChange = (columnW: GetColumnWidth) => {
|
|
126
|
+
columnWidth.value.left = columnW.left;
|
|
127
|
+
columnWidth.value.center = columnW.center;
|
|
128
|
+
columnWidth.value.right = columnW.right;
|
|
129
|
+
uiService?.set('columnWidth', columnW);
|
|
128
130
|
};
|
|
129
131
|
|
|
130
132
|
const saveCode = (value: string) => {
|
package/src/layouts/NavMenu.vue
CHANGED
|
@@ -13,7 +13,7 @@ import { Back, Delete, FullScreen, Grid, Memo, Right, ScaleToOriginal, ZoomIn, Z
|
|
|
13
13
|
import { NodeType } from '@tmagic/schema';
|
|
14
14
|
|
|
15
15
|
import ToolButton from '../components/ToolButton.vue';
|
|
16
|
-
import { ColumnLayout,
|
|
16
|
+
import { ColumnLayout, MenuBarData, MenuButton, MenuComponent, MenuItem, Services } from '../type';
|
|
17
17
|
|
|
18
18
|
const props = withDefaults(
|
|
19
19
|
defineProps<{
|
|
@@ -29,12 +29,12 @@ const props = withDefaults(
|
|
|
29
29
|
const services = inject<Services>('services');
|
|
30
30
|
const uiService = services?.uiService;
|
|
31
31
|
|
|
32
|
-
const columnWidth = computed(() => services?.uiService.get
|
|
32
|
+
const columnWidth = computed(() => services?.uiService.get('columnWidth'));
|
|
33
33
|
const keys = Object.values(ColumnLayout);
|
|
34
34
|
|
|
35
|
-
const showGuides = computed((): boolean => uiService?.get
|
|
36
|
-
const showRule = computed((): boolean => uiService?.get
|
|
37
|
-
const zoom = computed((): number => uiService?.get
|
|
35
|
+
const showGuides = computed((): boolean => uiService?.get('showGuides') ?? true);
|
|
36
|
+
const showRule = computed((): boolean => uiService?.get('showRule') ?? true);
|
|
37
|
+
const zoom = computed((): number => uiService?.get('zoom') ?? 1);
|
|
38
38
|
|
|
39
39
|
const isMac = /mac os x/.test(navigator.userAgent.toLowerCase());
|
|
40
40
|
const ctrl = isMac ? 'Command' : 'Ctrl';
|
|
@@ -67,7 +67,10 @@ const getConfig = (item: MenuItem): (MenuButton | MenuComponent)[] => {
|
|
|
67
67
|
icon: markRaw(Delete),
|
|
68
68
|
tooltip: `刪除(Delete)`,
|
|
69
69
|
disabled: () => services?.editorService.get('node')?.type === NodeType.PAGE,
|
|
70
|
-
handler: () =>
|
|
70
|
+
handler: () => {
|
|
71
|
+
const node = services?.editorService.get('node');
|
|
72
|
+
node && services?.editorService.remove(node);
|
|
73
|
+
},
|
|
71
74
|
});
|
|
72
75
|
break;
|
|
73
76
|
case 'undo':
|
|
@@ -19,8 +19,6 @@ import { computed, getCurrentInstance, inject, onMounted, onUnmounted, ref, watc
|
|
|
19
19
|
import { tMagicMessage } from '@tmagic/design';
|
|
20
20
|
import type { FormValue } from '@tmagic/form';
|
|
21
21
|
import { MForm } from '@tmagic/form';
|
|
22
|
-
import type { MNode } from '@tmagic/schema';
|
|
23
|
-
import type StageCore from '@tmagic/stage';
|
|
24
22
|
|
|
25
23
|
import type { Services } from '../type';
|
|
26
24
|
|
|
@@ -32,11 +30,9 @@ const configForm = ref<InstanceType<typeof MForm>>();
|
|
|
32
30
|
// ts类型应该是FormConfig, 但是打包时会出错,所以暂时用any
|
|
33
31
|
const curFormConfig = ref<any>([]);
|
|
34
32
|
const services = inject<Services>('services');
|
|
35
|
-
const node = computed(() => services?.editorService.get
|
|
36
|
-
const propsPanelSize = computed(
|
|
37
|
-
|
|
38
|
-
);
|
|
39
|
-
const stage = computed(() => services?.editorService.get<StageCore>('stage'));
|
|
33
|
+
const node = computed(() => services?.editorService.get('node'));
|
|
34
|
+
const propsPanelSize = computed(() => services?.uiService.get('propsPanelSize') || 'small');
|
|
35
|
+
const stage = computed(() => services?.editorService.get('stage'));
|
|
40
36
|
|
|
41
37
|
const init = async () => {
|
|
42
38
|
if (!node.value) {
|
|
@@ -44,7 +44,6 @@ import { Grid, Search } from '@element-plus/icons-vue';
|
|
|
44
44
|
import serialize from 'serialize-javascript';
|
|
45
45
|
|
|
46
46
|
import { TMagicCollapse, TMagicCollapseItem, TMagicInput, TMagicScrollbar, TMagicTooltip } from '@tmagic/design';
|
|
47
|
-
import type StageCore from '@tmagic/stage';
|
|
48
47
|
import { removeClassNameByClassName } from '@tmagic/utils';
|
|
49
48
|
|
|
50
49
|
import MIcon from '../../components/Icon.vue';
|
|
@@ -54,7 +53,7 @@ const searchText = ref('');
|
|
|
54
53
|
const services = inject<Services>('services');
|
|
55
54
|
const stageOptions = inject<StageOptions>('stageOptions');
|
|
56
55
|
|
|
57
|
-
const stage = computed(() => services?.editorService.get
|
|
56
|
+
const stage = computed(() => services?.editorService.get('stage'));
|
|
58
57
|
const list = computed(() =>
|
|
59
58
|
services?.componentListService.getList().map((group: ComponentGroup) => ({
|
|
60
59
|
...group,
|
|
@@ -65,7 +65,6 @@ import { difference, throttle, union } from 'lodash-es';
|
|
|
65
65
|
import { TMagicInput, TMagicScrollbar, TMagicTree } from '@tmagic/design';
|
|
66
66
|
import type { Id, MNode, MPage } from '@tmagic/schema';
|
|
67
67
|
import { MContainer, NodeType } from '@tmagic/schema';
|
|
68
|
-
import StageCore from '@tmagic/stage';
|
|
69
68
|
import { getNodePath, isPage } from '@tmagic/utils';
|
|
70
69
|
|
|
71
70
|
import type { MenuButton, MenuComponent, Services } from '../../type';
|
|
@@ -108,8 +107,8 @@ const treeProps = {
|
|
|
108
107
|
|
|
109
108
|
const isMultiSelect = computed(() => isCtrlKeyDown.value || checkedKeys.value.length > 1);
|
|
110
109
|
|
|
111
|
-
const nodes = computed(() => editorService?.get
|
|
112
|
-
const page = computed(() => editorService?.get
|
|
110
|
+
const nodes = computed(() => editorService?.get('nodes') || []);
|
|
111
|
+
const page = computed(() => editorService?.get('page'));
|
|
113
112
|
const values = computed(() => (page.value ? [page.value] : []));
|
|
114
113
|
// 高亮的节点
|
|
115
114
|
const highlightNode = computed(() => editorService?.get('highlightNode'));
|
|
@@ -121,13 +120,13 @@ const select = async (data: MNode) => {
|
|
|
121
120
|
}
|
|
122
121
|
|
|
123
122
|
await editorService?.select(data);
|
|
124
|
-
editorService?.get
|
|
123
|
+
editorService?.get('stage')?.select(data.id);
|
|
125
124
|
};
|
|
126
125
|
|
|
127
126
|
// 触发画布多选
|
|
128
127
|
const multiSelect = async (data: Id[]) => {
|
|
129
128
|
await editorService?.multiSelect(data);
|
|
130
|
-
editorService?.get
|
|
129
|
+
editorService?.get('stage')?.multiSelect(data);
|
|
131
130
|
};
|
|
132
131
|
|
|
133
132
|
// 触发画布高亮
|
|
@@ -136,7 +135,7 @@ const highlight = (data: MNode) => {
|
|
|
136
135
|
throw new Error('没有id');
|
|
137
136
|
}
|
|
138
137
|
editorService?.highlight(data);
|
|
139
|
-
editorService?.get
|
|
138
|
+
editorService?.get('stage')?.highlight(data.id);
|
|
140
139
|
};
|
|
141
140
|
|
|
142
141
|
// tree方法:拖拽时判定目标节点能否成为拖动目标位置
|
|
@@ -230,14 +229,14 @@ watch(nodes, (nodes) => {
|
|
|
230
229
|
|
|
231
230
|
watch(isMultiSelect, (isMultiSelect) => {
|
|
232
231
|
if (!isMultiSelect) {
|
|
233
|
-
currentNodeKey.value = editorService?.get
|
|
232
|
+
currentNodeKey.value = editorService?.get('node')?.id;
|
|
234
233
|
tree.value?.setCurrentKey(currentNodeKey.value);
|
|
235
234
|
}
|
|
236
235
|
});
|
|
237
236
|
|
|
238
237
|
const editorServiceRemoveHandler = () => {
|
|
239
238
|
setTimeout(() => {
|
|
240
|
-
tree.value?.getNode(editorService?.get('node')
|
|
239
|
+
tree.value?.getNode(editorService?.get('node')?.id)?.updateChildren();
|
|
241
240
|
}, 0);
|
|
242
241
|
};
|
|
243
242
|
|
|
@@ -300,7 +299,7 @@ const clickHandler = (data: MNode): void => {
|
|
|
300
299
|
if (isCtrlKeyDown.value) {
|
|
301
300
|
return;
|
|
302
301
|
}
|
|
303
|
-
if (services?.uiService.get
|
|
302
|
+
if (services?.uiService.get('uiSelectMode')) {
|
|
304
303
|
document.dispatchEvent(new CustomEvent('ui-select', { detail: data }));
|
|
305
304
|
return;
|
|
306
305
|
}
|
|
@@ -9,45 +9,18 @@
|
|
|
9
9
|
:show-close="false"
|
|
10
10
|
>
|
|
11
11
|
<Layout v-model:left="left" :min-left="45" class="code-editor-layout">
|
|
12
|
-
<!-- 左侧列表 -->
|
|
13
|
-
<template #left v-if="mode === CodeEditorMode.LIST">
|
|
14
|
-
<TMagicTree
|
|
15
|
-
v-if="!isEmpty(state.codeList)"
|
|
16
|
-
class="side-tree"
|
|
17
|
-
node-key="id"
|
|
18
|
-
empty-text="暂无代码块"
|
|
19
|
-
:data="state.codeList"
|
|
20
|
-
:highlight-current="true"
|
|
21
|
-
:current-node-key="state.codeList[0].id"
|
|
22
|
-
@node-click="selectHandler"
|
|
23
|
-
>
|
|
24
|
-
<template #default="{ data }">
|
|
25
|
-
<div :id="data.id" class="list-container">
|
|
26
|
-
<div class="list-item">
|
|
27
|
-
<div class="code-name">{{ data.name }}({{ data.id }})</div>
|
|
28
|
-
</div>
|
|
29
|
-
</div>
|
|
30
|
-
</template>
|
|
31
|
-
</TMagicTree>
|
|
32
|
-
</template>
|
|
33
12
|
<!-- 右侧区域 -->
|
|
34
13
|
<template #center>
|
|
35
|
-
<div
|
|
36
|
-
v-if="!isEmpty(codeConfig)"
|
|
37
|
-
:class="[
|
|
38
|
-
mode === CodeEditorMode.LIST
|
|
39
|
-
? 'm-editor-code-block-editor-panel-list-mode'
|
|
40
|
-
: 'm-editor-code-block-editor-panel',
|
|
41
|
-
]"
|
|
42
|
-
>
|
|
14
|
+
<div v-if="!isEmpty(codeConfig)" class="m-editor-code-block-editor-panel">
|
|
43
15
|
<slot name="code-block-edit-panel-header" :id="id"></slot>
|
|
44
16
|
<FunctionEditor
|
|
45
17
|
v-if="codeConfig"
|
|
46
18
|
:id="id"
|
|
47
19
|
:name="codeConfig.name"
|
|
48
20
|
:content="codeConfig.content"
|
|
21
|
+
:paramsColConfig="paramsColConfig"
|
|
49
22
|
:editable="!!editable"
|
|
50
|
-
:autoSaveDraft="
|
|
23
|
+
:autoSaveDraft="true"
|
|
51
24
|
:codeOptions="codeOptions"
|
|
52
25
|
></FunctionEditor>
|
|
53
26
|
</div>
|
|
@@ -60,18 +33,22 @@
|
|
|
60
33
|
import { computed, inject, reactive, ref, watchEffect } from 'vue';
|
|
61
34
|
import { cloneDeep, forIn, isEmpty } from 'lodash-es';
|
|
62
35
|
|
|
63
|
-
import { TMagicDialog
|
|
36
|
+
import { TMagicDialog } from '@tmagic/design';
|
|
37
|
+
import { ColumnConfig } from '@tmagic/form';
|
|
64
38
|
import { CodeBlockContent } from '@tmagic/schema';
|
|
65
39
|
|
|
66
40
|
import FunctionEditor from '../../../components/FunctionEditor.vue';
|
|
67
41
|
import Layout from '../../../components/Layout.vue';
|
|
68
|
-
import type {
|
|
69
|
-
import { CodeEditorMode } from '../../../type';
|
|
42
|
+
import type { ListState, Services } from '../../../type';
|
|
70
43
|
import { serializeConfig } from '../../../utils/editor';
|
|
71
44
|
|
|
72
45
|
const services = inject<Services>('services');
|
|
73
46
|
const codeOptions = inject('codeOptions', {});
|
|
74
47
|
|
|
48
|
+
defineProps<{
|
|
49
|
+
paramsColConfig?: ColumnConfig;
|
|
50
|
+
}>();
|
|
51
|
+
|
|
75
52
|
const left = ref(200);
|
|
76
53
|
const currentTitle = ref('');
|
|
77
54
|
// 编辑器当前需展示的代码块内容
|
|
@@ -81,7 +58,6 @@ const state = reactive<ListState>({
|
|
|
81
58
|
codeList: [],
|
|
82
59
|
});
|
|
83
60
|
|
|
84
|
-
const mode = computed(() => services?.codeBlockService.getMode());
|
|
85
61
|
const id = computed(() => services?.codeBlockService.getId() || '');
|
|
86
62
|
const editable = computed(() => services?.codeBlockService.getEditStatus());
|
|
87
63
|
// 当前选中组件绑定的代码块id数组
|
|
@@ -105,9 +81,4 @@ watchEffect(async () => {
|
|
|
105
81
|
});
|
|
106
82
|
currentTitle.value = state.codeList[0]?.name || '';
|
|
107
83
|
});
|
|
108
|
-
|
|
109
|
-
const selectHandler = (data: CodeDslItem) => {
|
|
110
|
-
services?.codeBlockService.setId(data.id);
|
|
111
|
-
currentTitle.value = data.name;
|
|
112
|
-
};
|
|
113
84
|
</script>
|