@tmagic/editor 1.2.0-beta.8 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/style.css +59 -35
- package/dist/{tmagic-editor.mjs → tmagic-editor.js} +1473 -1161
- package/dist/tmagic-editor.js.map +1 -0
- package/dist/{tmagic-editor.umd.js → tmagic-editor.umd.cjs} +1483 -1166
- package/dist/tmagic-editor.umd.cjs.map +1 -0
- package/package.json +16 -14
- package/src/Editor.vue +66 -40
- package/src/components/CodeDraftEditor.vue +145 -0
- package/src/components/ContentMenu.vue +2 -2
- package/src/components/FunctionEditor.vue +145 -0
- package/src/components/Icon.vue +1 -1
- package/src/{layouts → components}/Layout.vue +54 -15
- package/src/components/ScrollBar.vue +1 -1
- package/src/components/ScrollViewer.vue +10 -1
- package/src/components/ToolButton.vue +1 -1
- package/src/fields/Code.vue +1 -1
- package/src/fields/CodeLink.vue +1 -1
- package/src/fields/CodeSelect.vue +84 -110
- package/src/fields/UISelect.vue +1 -1
- package/src/index.ts +1 -0
- package/src/layouts/AddPageBox.vue +1 -1
- package/src/layouts/CodeEditor.vue +2 -3
- package/src/layouts/Framework.vue +2 -2
- package/src/layouts/NavMenu.vue +2 -2
- package/src/layouts/PropsPanel.vue +13 -6
- package/src/layouts/Resizer.vue +1 -1
- package/src/layouts/sidebar/ComponentListPanel.vue +1 -1
- package/src/layouts/sidebar/LayerMenu.vue +9 -7
- package/src/layouts/sidebar/LayerPanel.vue +127 -174
- package/src/layouts/sidebar/Sidebar.vue +110 -26
- package/src/layouts/sidebar/code-block/CodeBlockEditor.vue +27 -83
- package/src/layouts/sidebar/code-block/CodeBlockList.vue +90 -122
- package/src/layouts/workspace/Breadcrumb.vue +1 -1
- package/src/layouts/workspace/PageBar.vue +1 -1
- package/src/layouts/workspace/PageBarScrollContainer.vue +1 -1
- package/src/layouts/workspace/Stage.vue +26 -9
- package/src/layouts/workspace/ViewerMenu.vue +11 -9
- package/src/layouts/workspace/Workspace.vue +7 -3
- package/src/services/BaseService.ts +10 -1
- package/src/services/codeBlock.ts +124 -125
- package/src/services/componentList.ts +6 -1
- package/src/services/editor.ts +54 -18
- package/src/services/events.ts +6 -1
- package/src/services/history.ts +7 -16
- package/src/services/props.ts +7 -2
- package/src/services/storage.ts +1 -0
- package/src/services/ui.ts +12 -0
- package/src/theme/code-block.scss +43 -24
- package/src/theme/component-list-panel.scss +8 -5
- package/src/type.ts +77 -50
- package/src/utils/editor.ts +9 -1
- package/src/utils/index.ts +1 -0
- package/src/utils/props.ts +2 -2
- package/src/utils/scroll-viewer.ts +18 -2
- package/src/utils/stage.ts +4 -3
- package/types/Editor.vue.d.ts +47 -27
- package/types/components/CodeDraftEditor.vue.d.ts +56 -0
- package/types/components/ContentMenu.vue.d.ts +11 -87
- package/types/components/FunctionEditor.vue.d.ts +43 -0
- package/types/components/Icon.vue.d.ts +4 -50
- package/types/{layouts → components}/Layout.vue.d.ts +12 -1
- package/types/components/ScrollBar.vue.d.ts +7 -65
- package/types/components/ScrollViewer.vue.d.ts +45 -1
- package/types/components/ToolButton.vue.d.ts +12 -78
- package/types/fields/Code.vue.d.ts +11 -77
- package/types/fields/CodeLink.vue.d.ts +12 -82
- package/types/fields/CodeSelect.vue.d.ts +13 -77
- package/types/fields/UISelect.vue.d.ts +7 -65
- package/types/index.d.ts +1 -0
- package/types/layouts/AddPageBox.vue.d.ts +1 -43
- package/types/layouts/CodeEditor.vue.d.ts +22 -130
- package/types/layouts/NavMenu.vue.d.ts +9 -69
- package/types/layouts/sidebar/LayerMenu.vue.d.ts +16 -48
- package/types/layouts/sidebar/LayerPanel.vue.d.ts +24 -7
- package/types/layouts/sidebar/Sidebar.vue.d.ts +10 -5
- package/types/layouts/sidebar/code-block/CodeBlockEditor.vue.d.ts +1 -1
- package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +6 -5
- package/types/layouts/workspace/Breadcrumb.vue.d.ts +1 -43
- package/types/layouts/workspace/Stage.vue.d.ts +15 -43
- package/types/layouts/workspace/ViewerMenu.vue.d.ts +11 -66
- package/types/layouts/workspace/Workspace.vue.d.ts +23 -5
- package/types/services/BaseService.d.ts +2 -1
- package/types/services/codeBlock.d.ts +57 -36
- package/types/services/componentList.d.ts +1 -0
- package/types/services/editor.d.ts +5 -6
- package/types/services/events.d.ts +1 -0
- package/types/services/history.d.ts +5 -15
- package/types/services/props.d.ts +3 -2
- package/types/services/ui.d.ts +2 -1
- package/types/type.d.ts +65 -48
- package/types/utils/editor.d.ts +1 -0
- package/types/utils/index.d.ts +1 -0
- package/types/utils/props.d.ts +1 -1
- package/types/utils/scroll-viewer.d.ts +5 -0
- package/dist/tmagic-editor.mjs.map +0 -1
- package/dist/tmagic-editor.umd.js.map +0 -1
- package/src/layouts/sidebar/TabPane.vue +0 -118
- package/types/layouts/sidebar/TabPane.vue.d.ts +0 -82
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div ref="el" class="m-editor-layout">
|
|
3
|
-
<template v-if="
|
|
3
|
+
<template v-if="hasLeft">
|
|
4
4
|
<div class="m-editor-layout-left" :class="leftClass" :style="`width: ${left}px`">
|
|
5
5
|
<slot name="left"></slot>
|
|
6
6
|
</div>
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
<slot name="center"></slot>
|
|
12
12
|
</div>
|
|
13
13
|
|
|
14
|
-
<template v-if="
|
|
14
|
+
<template v-if="hasRight">
|
|
15
15
|
<Resizer @change="changeRight"></Resizer>
|
|
16
16
|
<div class="m-editor-layout-right" :class="rightClass" :style="`width: ${right}px`">
|
|
17
17
|
<slot name="right"></slot>
|
|
@@ -20,10 +20,10 @@
|
|
|
20
20
|
</div>
|
|
21
21
|
</template>
|
|
22
22
|
|
|
23
|
-
<script lang="ts" setup>
|
|
24
|
-
import { onMounted, onUnmounted, ref } from 'vue';
|
|
23
|
+
<script lang="ts" setup name="MEditorLayout">
|
|
24
|
+
import { computed, onMounted, onUnmounted, ref } from 'vue';
|
|
25
25
|
|
|
26
|
-
import Resizer from '
|
|
26
|
+
import Resizer from '../layouts/Resizer.vue';
|
|
27
27
|
|
|
28
28
|
const emit = defineEmits(['update:left', 'change', 'update:right']);
|
|
29
29
|
|
|
@@ -33,29 +33,64 @@ const props = withDefaults(
|
|
|
33
33
|
right?: number;
|
|
34
34
|
minLeft?: number;
|
|
35
35
|
minRight?: number;
|
|
36
|
+
minCenter?: number;
|
|
36
37
|
leftClass?: string;
|
|
37
38
|
rightClass?: string;
|
|
38
39
|
centerClass?: string;
|
|
39
40
|
}>(),
|
|
40
41
|
{
|
|
41
|
-
minLeft:
|
|
42
|
+
minLeft: 46,
|
|
42
43
|
minRight: 1,
|
|
44
|
+
minCenter: 1,
|
|
43
45
|
},
|
|
44
46
|
);
|
|
45
47
|
|
|
46
48
|
const el = ref<HTMLElement>();
|
|
47
49
|
|
|
50
|
+
const hasLeft = computed(() => typeof props.left !== 'undefined');
|
|
51
|
+
const hasRight = computed(() => typeof props.right !== 'undefined');
|
|
52
|
+
|
|
53
|
+
const getCenterWidth = (clientWidth: number, left: number, right: number) => {
|
|
54
|
+
let center = clientWidth - left - right;
|
|
55
|
+
if (center < props.minCenter) {
|
|
56
|
+
center = props.minCenter;
|
|
57
|
+
if (left < right) {
|
|
58
|
+
right = clientWidth - left - props.minCenter;
|
|
59
|
+
} else {
|
|
60
|
+
left = clientWidth - right - props.minCenter;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
center,
|
|
65
|
+
left,
|
|
66
|
+
right,
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
|
|
48
70
|
let clientWidth = 0;
|
|
49
71
|
const resizerObserver = new ResizeObserver((entries) => {
|
|
50
72
|
for (const { contentRect } of entries) {
|
|
51
73
|
clientWidth = contentRect.width;
|
|
52
74
|
|
|
53
|
-
|
|
75
|
+
let left = props.left || 0;
|
|
76
|
+
let right = props.right || 0;
|
|
77
|
+
|
|
78
|
+
if (left > clientWidth) {
|
|
79
|
+
left = clientWidth / 3;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (right > clientWidth) {
|
|
83
|
+
right = clientWidth / 3;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const columnWidth = getCenterWidth(clientWidth, left, right);
|
|
87
|
+
|
|
88
|
+
center.value = columnWidth.center;
|
|
54
89
|
|
|
55
90
|
emit('change', {
|
|
56
|
-
left:
|
|
91
|
+
left: columnWidth.left,
|
|
57
92
|
center: center.value,
|
|
58
|
-
right:
|
|
93
|
+
right: columnWidth.right,
|
|
59
94
|
});
|
|
60
95
|
}
|
|
61
96
|
});
|
|
@@ -81,12 +116,14 @@ const changeLeft = (deltaX: number) => {
|
|
|
81
116
|
left = props.left;
|
|
82
117
|
}
|
|
83
118
|
|
|
84
|
-
|
|
119
|
+
const columnWidth = getCenterWidth(clientWidth, left, props.right || 0);
|
|
120
|
+
|
|
121
|
+
center.value = columnWidth.center;
|
|
85
122
|
|
|
86
123
|
emit('change', {
|
|
87
|
-
left,
|
|
124
|
+
left: columnWidth.left,
|
|
88
125
|
center: center.value,
|
|
89
|
-
right:
|
|
126
|
+
right: columnWidth.right,
|
|
90
127
|
});
|
|
91
128
|
};
|
|
92
129
|
|
|
@@ -99,12 +136,14 @@ const changeRight = (deltaX: number) => {
|
|
|
99
136
|
right = props.right;
|
|
100
137
|
}
|
|
101
138
|
|
|
102
|
-
|
|
139
|
+
const columnWidth = getCenterWidth(clientWidth, props.left || 0, right);
|
|
140
|
+
|
|
141
|
+
center.value = columnWidth.center;
|
|
103
142
|
|
|
104
143
|
emit('change', {
|
|
105
|
-
left:
|
|
144
|
+
left: columnWidth.left,
|
|
106
145
|
center: center.value,
|
|
107
|
-
right,
|
|
146
|
+
right: columnWidth.right,
|
|
108
147
|
});
|
|
109
148
|
};
|
|
110
149
|
</script>
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
</div>
|
|
23
23
|
</template>
|
|
24
24
|
|
|
25
|
-
<script lang="ts" setup>
|
|
25
|
+
<script lang="ts" setup name="MEditorScrollViewer">
|
|
26
26
|
import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
|
|
27
27
|
|
|
28
28
|
import { ScrollViewerEvent } from '../type';
|
|
@@ -37,6 +37,10 @@ const props = withDefaults(
|
|
|
37
37
|
wrapWidth?: number;
|
|
38
38
|
wrapHeight?: number;
|
|
39
39
|
zoom?: number;
|
|
40
|
+
correctionScrollSize?: {
|
|
41
|
+
width: number;
|
|
42
|
+
height: number;
|
|
43
|
+
};
|
|
40
44
|
}>(),
|
|
41
45
|
{
|
|
42
46
|
width: 0,
|
|
@@ -44,6 +48,10 @@ const props = withDefaults(
|
|
|
44
48
|
wrapWidth: 0,
|
|
45
49
|
wrapHeight: 0,
|
|
46
50
|
zoom: 1,
|
|
51
|
+
correctionScrollSize: () => ({
|
|
52
|
+
width: 0,
|
|
53
|
+
height: 0,
|
|
54
|
+
}),
|
|
47
55
|
},
|
|
48
56
|
);
|
|
49
57
|
|
|
@@ -69,6 +77,7 @@ onMounted(() => {
|
|
|
69
77
|
container: container.value,
|
|
70
78
|
target: el.value,
|
|
71
79
|
zoom: props.zoom,
|
|
80
|
+
correctionScrollSize: props.correctionScrollSize,
|
|
72
81
|
});
|
|
73
82
|
|
|
74
83
|
scrollViewer.on('scroll', (data: ScrollViewerEvent) => {
|
package/src/fields/Code.vue
CHANGED
package/src/fields/CodeLink.vue
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<m-fields-link :config="formConfig" :model="modelValue" name="form" @change="changeHandler"></m-fields-link>
|
|
3
3
|
</template>
|
|
4
4
|
|
|
5
|
-
<script lang="ts" setup>
|
|
5
|
+
<script lang="ts" setup name="MEditorCodeLink">
|
|
6
6
|
import { computed, reactive, watch } from 'vue';
|
|
7
7
|
import serialize from 'serialize-javascript';
|
|
8
8
|
|
|
@@ -1,144 +1,118 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="m-fields-code-select"
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
</template>
|
|
14
|
-
<div class="tool-bar">
|
|
15
|
-
<TMagicTooltip class="tool-item" effect="dark" content="查看代码块" placement="top">
|
|
16
|
-
<svg
|
|
17
|
-
@click="viewHandler"
|
|
18
|
-
preserveAspectRatio="xMidYMid meet"
|
|
19
|
-
viewBox="0 0 24 24"
|
|
20
|
-
width="15px"
|
|
21
|
-
height="15px"
|
|
22
|
-
data-v-65a7fb6c=""
|
|
23
|
-
>
|
|
24
|
-
<path
|
|
25
|
-
fill="currentColor"
|
|
26
|
-
d="m23 12l-7.071 7.071l-1.414-1.414L20.172 12l-5.657-5.657l1.414-1.414L23 12zM3.828 12l5.657 5.657l-1.414 1.414L1 12l7.071-7.071l1.414 1.414L3.828 12z"
|
|
27
|
-
></path>
|
|
28
|
-
</svg>
|
|
29
|
-
</TMagicTooltip>
|
|
30
|
-
</div>
|
|
31
|
-
</TMagicCard>
|
|
2
|
+
<div class="m-fields-code-select">
|
|
3
|
+
<m-form-table
|
|
4
|
+
:config="tableConfig"
|
|
5
|
+
:model="model[name]"
|
|
6
|
+
name="hookData"
|
|
7
|
+
:enableToggleMode="false"
|
|
8
|
+
:prop="prop"
|
|
9
|
+
:size="size"
|
|
10
|
+
@change="changeHandler"
|
|
11
|
+
>
|
|
12
|
+
</m-form-table>
|
|
32
13
|
</div>
|
|
33
14
|
</template>
|
|
34
15
|
|
|
35
|
-
<script lang="ts" setup>
|
|
36
|
-
import { computed, defineEmits, defineProps, inject,
|
|
37
|
-
import {
|
|
16
|
+
<script lang="ts" setup name="MEditorCodeSelect">
|
|
17
|
+
import { computed, defineEmits, defineProps, inject, watch } from 'vue';
|
|
18
|
+
import { isEmpty, map } from 'lodash-es';
|
|
38
19
|
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
20
|
+
import { createValues, FormItem, FormState, TableConfig } from '@tmagic/form';
|
|
21
|
+
import { HookType, Id } from '@tmagic/schema';
|
|
41
22
|
|
|
42
|
-
import
|
|
43
|
-
import { CodeEditorMode, CodeSelectOp } from '../type';
|
|
23
|
+
import { CodeParamStatement, HookData, Services } from '../type';
|
|
44
24
|
const services = inject<Services>('services');
|
|
45
|
-
|
|
25
|
+
const mForm = inject<FormState>('mForm');
|
|
46
26
|
const emit = defineEmits(['change']);
|
|
47
27
|
|
|
48
28
|
const props = defineProps<{
|
|
49
29
|
config: {
|
|
50
|
-
|
|
30
|
+
tableConfig?: TableConfig;
|
|
51
31
|
};
|
|
52
32
|
model: any;
|
|
53
33
|
prop: string;
|
|
54
34
|
name: string;
|
|
55
|
-
size:
|
|
35
|
+
size: 'mini' | 'small' | 'medium';
|
|
56
36
|
}>();
|
|
37
|
+
const codeDsl = computed(() => services?.codeBlockService.getCodeDslSync());
|
|
57
38
|
|
|
58
|
-
const
|
|
39
|
+
const tableConfig = computed<FormItem>(() => {
|
|
59
40
|
const defaultConfig = {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
41
|
+
dropSort: true,
|
|
42
|
+
enableFullscreen: false,
|
|
43
|
+
border: true,
|
|
44
|
+
items: [
|
|
45
|
+
{
|
|
46
|
+
type: 'select',
|
|
47
|
+
label: '代码块',
|
|
48
|
+
name: 'codeId',
|
|
49
|
+
width: '200px',
|
|
50
|
+
options: () => {
|
|
51
|
+
if (codeDsl.value) {
|
|
52
|
+
return map(codeDsl.value, (value, key) => ({
|
|
53
|
+
text: `${value.name}(${key})`,
|
|
54
|
+
label: `${value.name}(${key})`,
|
|
55
|
+
value: key,
|
|
56
|
+
}));
|
|
57
|
+
}
|
|
58
|
+
return [];
|
|
59
|
+
},
|
|
60
|
+
onChange: (formState: any, codeId: Id, { model }: any) => {
|
|
61
|
+
// 参数的items是根据函数生成的,当codeId变化后修正model的值,避免写入其他codeId的params
|
|
62
|
+
model.params = {};
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: 'params',
|
|
67
|
+
label: '参数',
|
|
68
|
+
defaultValue: {},
|
|
69
|
+
itemsFunction: (row: HookData) => {
|
|
70
|
+
const paramsConfig = getParamsConfig(row.codeId);
|
|
71
|
+
if (!row.params) row.params = {};
|
|
72
|
+
if (isEmpty(row.params)) {
|
|
73
|
+
createValues(mForm, paramsConfig, {}, row.params);
|
|
74
|
+
}
|
|
75
|
+
return paramsConfig;
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
],
|
|
72
79
|
};
|
|
73
80
|
return {
|
|
74
81
|
...defaultConfig,
|
|
75
|
-
...props.config.
|
|
82
|
+
...props.config.tableConfig,
|
|
76
83
|
};
|
|
77
84
|
});
|
|
78
|
-
const fieldKey = ref('');
|
|
79
|
-
const multiple = ref(true);
|
|
80
|
-
let lastTagSnapshot = cloneDeep(props.model[props.name]) || [];
|
|
81
|
-
let shouldWatch = true;
|
|
82
85
|
|
|
83
|
-
// 管理端和editor有表现不一致的地方,管理端切换组件表单不会重新渲染,因此增加shouldWatch控制lastTagSnapshot的记录
|
|
84
86
|
watch(
|
|
85
87
|
() => props.model[props.name],
|
|
86
|
-
(
|
|
87
|
-
|
|
88
|
-
|
|
88
|
+
(value) => {
|
|
89
|
+
// 兼容旧的数据结构
|
|
90
|
+
if (isEmpty(value)) {
|
|
91
|
+
// 空值或者空数组
|
|
92
|
+
props.model[props.name] = {
|
|
93
|
+
hookType: HookType.CODE,
|
|
94
|
+
hookData: [],
|
|
95
|
+
};
|
|
89
96
|
}
|
|
90
97
|
},
|
|
98
|
+
{
|
|
99
|
+
immediate: true,
|
|
100
|
+
},
|
|
91
101
|
);
|
|
92
102
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
props.model[props.name].map(async (id: string) => {
|
|
96
|
-
const { name = '' } = (await services?.codeBlockService.getCodeContentById(id)) || {};
|
|
97
|
-
return name;
|
|
98
|
-
}),
|
|
99
|
-
);
|
|
100
|
-
fieldKey.value = combineNames.join('-');
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
const changeHandler = async (value: any) => {
|
|
104
|
-
shouldWatch = false;
|
|
105
|
-
let codeIds = value;
|
|
106
|
-
if (typeof value === 'string') {
|
|
107
|
-
multiple.value = false;
|
|
108
|
-
lastTagSnapshot = [lastTagSnapshot];
|
|
109
|
-
codeIds = value ? [value] : [];
|
|
110
|
-
}
|
|
111
|
-
await setCombineRelation(codeIds);
|
|
112
|
-
emit('change', value);
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
// 同步绑定关系
|
|
116
|
-
const setCombineRelation = async (codeIds: string[]) => {
|
|
117
|
-
// 组件id
|
|
118
|
-
const { id = '' } = services?.editorService.get('node') || {};
|
|
119
|
-
|
|
120
|
-
// 兼容单选
|
|
121
|
-
let opFlag = CodeSelectOp.CHANGE;
|
|
122
|
-
let diffValues = codeIds;
|
|
123
|
-
if (multiple.value) {
|
|
124
|
-
opFlag = codeIds.length < lastTagSnapshot.length ? CodeSelectOp.DELETE : CodeSelectOp.ADD;
|
|
125
|
-
diffValues = xor(codeIds, lastTagSnapshot) as string[];
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// 记录绑定关系
|
|
129
|
-
await services?.codeBlockService.setCombineRelation(id, diffValues, opFlag, props.prop);
|
|
130
|
-
lastTagSnapshot = codeIds;
|
|
131
|
-
shouldWatch = true;
|
|
103
|
+
const changeHandler = async () => {
|
|
104
|
+
emit('change', props.model[props.name]);
|
|
132
105
|
};
|
|
133
106
|
|
|
134
|
-
const
|
|
135
|
-
if (
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
107
|
+
const getParamsConfig = (codeId: Id) => {
|
|
108
|
+
if (!codeDsl.value) return [];
|
|
109
|
+
const paramStatements = codeDsl.value[codeId]?.params;
|
|
110
|
+
if (isEmpty(paramStatements)) return [];
|
|
111
|
+
return paramStatements.map((paramState: CodeParamStatement) => ({
|
|
112
|
+
name: paramState.name,
|
|
113
|
+
text: paramState.name,
|
|
114
|
+
labelWidth: '100px',
|
|
115
|
+
type: 'text',
|
|
116
|
+
}));
|
|
143
117
|
};
|
|
144
118
|
</script>
|
package/src/fields/UISelect.vue
CHANGED
package/src/index.ts
CHANGED
|
@@ -48,6 +48,7 @@ export { default as PropsPanel } from './layouts/PropsPanel.vue';
|
|
|
48
48
|
export { default as ToolButton } from './components/ToolButton.vue';
|
|
49
49
|
export { default as ContentMenu } from './components/ContentMenu.vue';
|
|
50
50
|
export { default as Icon } from './components/Icon.vue';
|
|
51
|
+
export { default as LayoutContainer } from './components/Layout.vue';
|
|
51
52
|
|
|
52
53
|
const defaultInstallOpt: InstallOptions = {
|
|
53
54
|
// @todo, 自定义图片上传方法等编辑器依赖的外部选项
|
|
@@ -2,7 +2,7 @@
|
|
|
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 name="MEditorCodeEditor">
|
|
6
6
|
import { onMounted, onUnmounted, ref, watch } from 'vue';
|
|
7
7
|
import { throttle } from 'lodash-es';
|
|
8
8
|
import * as monaco from 'monaco-editor';
|
|
@@ -12,7 +12,7 @@ const props = withDefaults(
|
|
|
12
12
|
defineProps<{
|
|
13
13
|
initValues?: string | Object;
|
|
14
14
|
modifiedValues?: string | Object;
|
|
15
|
-
type?:
|
|
15
|
+
type?: 'diff';
|
|
16
16
|
language?: string;
|
|
17
17
|
options?: {
|
|
18
18
|
[key: string]: any;
|
|
@@ -20,7 +20,6 @@ const props = withDefaults(
|
|
|
20
20
|
autoSave?: boolean;
|
|
21
21
|
}>(),
|
|
22
22
|
{
|
|
23
|
-
type: '',
|
|
24
23
|
autoSave: true,
|
|
25
24
|
language: 'javascript',
|
|
26
25
|
options: () => ({
|
|
@@ -42,16 +42,16 @@
|
|
|
42
42
|
</div>
|
|
43
43
|
</template>
|
|
44
44
|
|
|
45
|
-
<script lang="ts" setup>
|
|
45
|
+
<script lang="ts" setup name="MEditorFramework">
|
|
46
46
|
import { computed, inject, ref, watch } from 'vue';
|
|
47
47
|
|
|
48
48
|
import { TMagicScrollbar } from '@tmagic/design';
|
|
49
49
|
import type { MApp } from '@tmagic/schema';
|
|
50
50
|
|
|
51
|
+
import Layout from '../components/Layout.vue';
|
|
51
52
|
import { GetColumnWidth, Services } from '../type';
|
|
52
53
|
|
|
53
54
|
import AddPageBox from './AddPageBox.vue';
|
|
54
|
-
import Layout from './Layout.vue';
|
|
55
55
|
|
|
56
56
|
const DEFAULT_LEFT_COLUMN_WIDTH = 310;
|
|
57
57
|
const DEFAULT_RIGHT_COLUMN_WIDTH = 480;
|
package/src/layouts/NavMenu.vue
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="m-editor-nav-menu" :style="{ height: `${height}px` }">
|
|
3
3
|
<div v-for="key in keys" :class="`menu-${key}`" :key="key" :style="`width: ${columnWidth?.[key]}px`">
|
|
4
|
-
<
|
|
4
|
+
<ToolButton :data="item" v-for="(item, index) in buttons[key]" :key="index"></ToolButton>
|
|
5
5
|
</div>
|
|
6
6
|
</div>
|
|
7
7
|
</template>
|
|
8
8
|
|
|
9
|
-
<script lang="ts" setup>
|
|
9
|
+
<script lang="ts" setup name="MEditorNavMenu">
|
|
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
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="m-editor-props-panel">
|
|
3
3
|
<slot name="props-panel-header"></slot>
|
|
4
|
-
<
|
|
4
|
+
<MForm
|
|
5
5
|
ref="configForm"
|
|
6
6
|
:class="`m-editor-props-panel ${propsPanelSize}`"
|
|
7
7
|
:popper-class="`m-editor-props-panel-popper ${propsPanelSize}`"
|
|
@@ -9,15 +9,16 @@
|
|
|
9
9
|
:init-values="values"
|
|
10
10
|
:config="curFormConfig"
|
|
11
11
|
@change="submit"
|
|
12
|
-
></
|
|
12
|
+
></MForm>
|
|
13
13
|
</div>
|
|
14
14
|
</template>
|
|
15
15
|
|
|
16
|
-
<script lang="ts" setup>
|
|
17
|
-
import { computed, getCurrentInstance, inject, onMounted, ref, watchEffect } from 'vue';
|
|
16
|
+
<script lang="ts" setup name="MEditorPropsPanel">
|
|
17
|
+
import { computed, getCurrentInstance, inject, onMounted, onUnmounted, ref, watchEffect } from 'vue';
|
|
18
18
|
|
|
19
19
|
import { tMagicMessage } from '@tmagic/design';
|
|
20
|
-
import type { FormValue
|
|
20
|
+
import type { FormValue } from '@tmagic/form';
|
|
21
|
+
import { MForm } from '@tmagic/form';
|
|
21
22
|
import type { MNode } from '@tmagic/schema';
|
|
22
23
|
import type StageCore from '@tmagic/stage';
|
|
23
24
|
|
|
@@ -32,7 +33,9 @@ const configForm = ref<InstanceType<typeof MForm>>();
|
|
|
32
33
|
const curFormConfig = ref<any>([]);
|
|
33
34
|
const services = inject<Services>('services');
|
|
34
35
|
const node = computed(() => services?.editorService.get<MNode | null>('node'));
|
|
35
|
-
const propsPanelSize = computed(
|
|
36
|
+
const propsPanelSize = computed(
|
|
37
|
+
() => services?.uiService.get<'large' | 'default' | 'small'>('propsPanelSize') || 'small',
|
|
38
|
+
);
|
|
36
39
|
const stage = computed(() => services?.editorService.get<StageCore>('stage'));
|
|
37
40
|
|
|
38
41
|
const init = async () => {
|
|
@@ -53,6 +56,10 @@ onMounted(() => {
|
|
|
53
56
|
emit('mounted', internalInstance);
|
|
54
57
|
});
|
|
55
58
|
|
|
59
|
+
onUnmounted(() => {
|
|
60
|
+
services?.propsService.off('props-configs-change', init);
|
|
61
|
+
});
|
|
62
|
+
|
|
56
63
|
watchEffect(() => {
|
|
57
64
|
if (configForm.value && stage.value) {
|
|
58
65
|
configForm.value.formState.stage = stage.value;
|
package/src/layouts/Resizer.vue
CHANGED
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
</TMagicScrollbar>
|
|
39
39
|
</template>
|
|
40
40
|
|
|
41
|
-
<script lang="ts" setup>
|
|
41
|
+
<script lang="ts" setup name="MEditorComponentListPanel">
|
|
42
42
|
import { computed, inject, ref } from 'vue';
|
|
43
43
|
import { Grid, Search } from '@element-plus/icons-vue';
|
|
44
44
|
import serialize from 'serialize-javascript';
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
<template>
|
|
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 name="MEditorLayerMenu">
|
|
6
6
|
import { computed, inject, markRaw, ref } from 'vue';
|
|
7
|
-
import {
|
|
7
|
+
import { CopyDocument, Delete, Files, Plus } from '@element-plus/icons-vue';
|
|
8
8
|
|
|
9
9
|
import { NodeType } from '@tmagic/schema';
|
|
10
10
|
|
|
11
11
|
import ContentMenu from '../../components/ContentMenu.vue';
|
|
12
12
|
import type { ComponentGroup, MenuButton, MenuComponent, Services } from '../../type';
|
|
13
13
|
|
|
14
|
+
const props = defineProps<{
|
|
15
|
+
layerContentMenu: (MenuButton | MenuComponent)[];
|
|
16
|
+
}>();
|
|
17
|
+
|
|
14
18
|
const services = inject<Services>('services');
|
|
15
19
|
const menu = ref<InstanceType<typeof ContentMenu>>();
|
|
16
20
|
const node = computed(() => services?.editorService.get('node'));
|
|
@@ -18,8 +22,6 @@ const isRoot = computed(() => node.value?.type === NodeType.ROOT);
|
|
|
18
22
|
const isPage = computed(() => node.value?.type === NodeType.PAGE);
|
|
19
23
|
const componentList = computed(() => services?.componentListService.getList() || []);
|
|
20
24
|
|
|
21
|
-
const layerContentMenu = inject<(MenuComponent | MenuButton)[]>('layerContentMenu', []);
|
|
22
|
-
|
|
23
25
|
const createMenuItems = (group: ComponentGroup): MenuButton[] =>
|
|
24
26
|
group.items.map((component) => ({
|
|
25
27
|
text: component.text,
|
|
@@ -82,7 +84,7 @@ const menuData = computed<(MenuButton | MenuComponent)[]>(() => [
|
|
|
82
84
|
{
|
|
83
85
|
type: 'button',
|
|
84
86
|
text: '复制',
|
|
85
|
-
icon: markRaw(
|
|
87
|
+
icon: markRaw(CopyDocument),
|
|
86
88
|
display: () => !isRoot.value,
|
|
87
89
|
handler: () => {
|
|
88
90
|
node.value && services?.editorService.copy(node.value);
|
|
@@ -97,7 +99,7 @@ const menuData = computed<(MenuButton | MenuComponent)[]>(() => [
|
|
|
97
99
|
node.value && services?.editorService.remove(node.value);
|
|
98
100
|
},
|
|
99
101
|
},
|
|
100
|
-
...layerContentMenu,
|
|
102
|
+
...props.layerContentMenu,
|
|
101
103
|
]);
|
|
102
104
|
|
|
103
105
|
const show = (e: MouseEvent) => {
|