@tmagic/editor 1.2.10 → 1.2.12
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 +26 -32
- package/dist/tmagic-editor.js +1689 -1308
- package/dist/tmagic-editor.js.map +1 -1
- package/dist/tmagic-editor.umd.cjs +1694 -1310
- package/dist/tmagic-editor.umd.cjs.map +1 -1
- package/package.json +9 -9
- package/src/Editor.vue +10 -244
- package/src/components/CodeDraftEditor.vue +10 -6
- package/src/editorProps.ts +135 -0
- package/src/fields/CodeSelect.vue +23 -12
- package/src/fields/CodeSelectCol.vue +117 -0
- package/src/fields/EventSelect.vue +216 -0
- package/src/index.ts +7 -0
- package/src/initService.ts +198 -0
- package/src/layouts/sidebar/code-block/CodeBlockList.vue +49 -127
- package/src/services/codeBlock.ts +8 -115
- package/src/services/dep.ts +328 -0
- package/src/services/editor.ts +1 -1
- package/src/theme/code-block.scss +5 -33
- package/src/theme/event.scss +24 -0
- package/src/theme/theme.scss +1 -0
- package/src/type.ts +18 -3
- package/src/utils/dep.ts +21 -0
- package/src/utils/props.ts +1 -35
- package/types/Editor.vue.d.ts +49 -82
- package/types/editorProps.d.ts +109 -0
- package/types/fields/CodeSelect.vue.d.ts +28 -5
- package/types/fields/CodeSelectCol.vue.d.ts +30 -0
- package/types/fields/EventSelect.vue.d.ts +26 -0
- package/types/index.d.ts +3 -0
- package/types/initService.d.ts +8 -0
- package/types/services/codeBlock.d.ts +1 -32
- package/types/services/dep.d.ts +130 -0
- package/types/services/props.d.ts +1 -15
- package/types/type.d.ts +17 -3
- package/types/utils/dep.d.ts +3 -0
- package/types/utils/props.d.ts +2 -16
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.2.
|
|
2
|
+
"version": "1.2.12",
|
|
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.12",
|
|
50
|
+
"@tmagic/design": "1.2.12",
|
|
51
|
+
"@tmagic/form": "1.2.12",
|
|
52
|
+
"@tmagic/schema": "1.2.12",
|
|
53
|
+
"@tmagic/stage": "1.2.12",
|
|
54
|
+
"@tmagic/utils": "1.2.12",
|
|
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.12",
|
|
67
|
+
"@tmagic/form": "1.2.12",
|
|
68
68
|
"monaco-editor": "^0.34.0",
|
|
69
69
|
"vue": "^3.2.37"
|
|
70
70
|
},
|
package/src/Editor.vue
CHANGED
|
@@ -64,18 +64,7 @@
|
|
|
64
64
|
</template>
|
|
65
65
|
|
|
66
66
|
<script lang="ts">
|
|
67
|
-
import { defineComponent,
|
|
68
|
-
|
|
69
|
-
import { EventOption } from '@tmagic/core';
|
|
70
|
-
import type { FormConfig } from '@tmagic/form';
|
|
71
|
-
import type { MApp, MNode } from '@tmagic/schema';
|
|
72
|
-
import StageCore, {
|
|
73
|
-
CONTAINER_HIGHLIGHT_CLASS_NAME,
|
|
74
|
-
ContainerHighlightType,
|
|
75
|
-
CustomizeMoveableOptionsCallbackConfig,
|
|
76
|
-
MoveableOptions,
|
|
77
|
-
UpdateDragEl,
|
|
78
|
-
} from '@tmagic/stage';
|
|
67
|
+
import { defineComponent, provide, reactive } from 'vue';
|
|
79
68
|
|
|
80
69
|
import Framework from './layouts/Framework.vue';
|
|
81
70
|
import NavMenu from './layouts/NavMenu.vue';
|
|
@@ -84,13 +73,16 @@ import Sidebar from './layouts/sidebar/Sidebar.vue';
|
|
|
84
73
|
import Workspace from './layouts/workspace/Workspace.vue';
|
|
85
74
|
import codeBlockService from './services/codeBlock';
|
|
86
75
|
import componentListService from './services/componentList';
|
|
76
|
+
import depService from './services/dep';
|
|
87
77
|
import editorService from './services/editor';
|
|
88
78
|
import eventsService from './services/events';
|
|
89
79
|
import historyService from './services/history';
|
|
90
80
|
import propsService from './services/props';
|
|
91
81
|
import storageService from './services/storage';
|
|
92
82
|
import uiService from './services/ui';
|
|
93
|
-
import
|
|
83
|
+
import editorProps from './editorProps';
|
|
84
|
+
import { initServiceEvents, initServiceState } from './initService';
|
|
85
|
+
import type { Services } from './type';
|
|
94
86
|
|
|
95
87
|
export default defineComponent({
|
|
96
88
|
name: 'm-editor',
|
|
@@ -103,239 +95,11 @@ export default defineComponent({
|
|
|
103
95
|
Framework,
|
|
104
96
|
},
|
|
105
97
|
|
|
106
|
-
props:
|
|
107
|
-
/** 页面初始值 */
|
|
108
|
-
modelValue: {
|
|
109
|
-
type: Object as PropType<MApp>,
|
|
110
|
-
default: () => ({}),
|
|
111
|
-
require: true,
|
|
112
|
-
},
|
|
113
|
-
|
|
114
|
-
/** 左侧面板中的组件列表 */
|
|
115
|
-
componentGroupList: {
|
|
116
|
-
type: Array as PropType<ComponentGroup[]>,
|
|
117
|
-
default: () => [],
|
|
118
|
-
},
|
|
119
|
-
|
|
120
|
-
/** 左侧面板配置 */
|
|
121
|
-
sidebar: {
|
|
122
|
-
type: Object as PropType<SideBarData>,
|
|
123
|
-
},
|
|
124
|
-
|
|
125
|
-
/** 顶部工具栏配置 */
|
|
126
|
-
menu: {
|
|
127
|
-
type: Object as PropType<MenuBarData>,
|
|
128
|
-
default: () => ({ left: [], right: [] }),
|
|
129
|
-
},
|
|
130
|
-
|
|
131
|
-
/** 组件树右键菜单 */
|
|
132
|
-
layerContentMenu: {
|
|
133
|
-
type: Array as PropType<(MenuButton | MenuComponent)[]>,
|
|
134
|
-
default: () => [],
|
|
135
|
-
},
|
|
136
|
-
|
|
137
|
-
/** 画布右键菜单 */
|
|
138
|
-
stageContentMenu: {
|
|
139
|
-
type: Array as PropType<(MenuButton | MenuComponent)[]>,
|
|
140
|
-
default: () => [],
|
|
141
|
-
},
|
|
142
|
-
|
|
143
|
-
/** 中间工作区域中画布渲染的内容 */
|
|
144
|
-
render: {
|
|
145
|
-
type: Function as PropType<(stage: StageCore) => HTMLDivElement | Promise<HTMLDivElement>>,
|
|
146
|
-
},
|
|
147
|
-
|
|
148
|
-
/** 中间工作区域中画布通过iframe渲染时的页面url */
|
|
149
|
-
runtimeUrl: String,
|
|
150
|
-
|
|
151
|
-
/** 选中时是否自动滚动到可视区域 */
|
|
152
|
-
autoScrollIntoView: Boolean,
|
|
153
|
-
|
|
154
|
-
/** 组件的属性配置表单的dsl */
|
|
155
|
-
propsConfigs: {
|
|
156
|
-
type: Object as PropType<Record<string, FormConfig>>,
|
|
157
|
-
default: () => ({}),
|
|
158
|
-
},
|
|
159
|
-
|
|
160
|
-
/** 添加组件时的默认值 */
|
|
161
|
-
propsValues: {
|
|
162
|
-
type: Object as PropType<Record<string, MNode>>,
|
|
163
|
-
default: () => ({}),
|
|
164
|
-
},
|
|
165
|
-
|
|
166
|
-
/** 组件联动事件选项列表 */
|
|
167
|
-
eventMethodList: {
|
|
168
|
-
type: Object as PropType<Record<string, { events: EventOption[]; methods: EventOption[] }>>,
|
|
169
|
-
default: () => ({}),
|
|
170
|
-
},
|
|
171
|
-
|
|
172
|
-
/** 画布中组件选中框的移动范围 */
|
|
173
|
-
moveableOptions: {
|
|
174
|
-
type: [Object, Function] as PropType<
|
|
175
|
-
MoveableOptions | ((config?: CustomizeMoveableOptionsCallbackConfig) => MoveableOptions)
|
|
176
|
-
>,
|
|
177
|
-
},
|
|
178
|
-
|
|
179
|
-
/** 编辑器初始化时默认选中的组件ID */
|
|
180
|
-
defaultSelected: {
|
|
181
|
-
type: [Number, String],
|
|
182
|
-
},
|
|
183
|
-
|
|
184
|
-
canSelect: {
|
|
185
|
-
type: Function as PropType<(el: HTMLElement) => boolean | Promise<boolean>>,
|
|
186
|
-
default: (el: HTMLElement) => Boolean(el.id),
|
|
187
|
-
},
|
|
188
|
-
|
|
189
|
-
isContainer: {
|
|
190
|
-
type: Function as PropType<(el: HTMLElement) => boolean | Promise<boolean>>,
|
|
191
|
-
default: (el: HTMLElement) => el.classList.contains('magic-ui-container'),
|
|
192
|
-
},
|
|
193
|
-
|
|
194
|
-
containerHighlightClassName: {
|
|
195
|
-
type: String,
|
|
196
|
-
default: CONTAINER_HIGHLIGHT_CLASS_NAME,
|
|
197
|
-
},
|
|
198
|
-
|
|
199
|
-
containerHighlightDuration: {
|
|
200
|
-
type: Number,
|
|
201
|
-
default: 800,
|
|
202
|
-
},
|
|
203
|
-
|
|
204
|
-
containerHighlightType: {
|
|
205
|
-
type: String as PropType<ContainerHighlightType>,
|
|
206
|
-
default: ContainerHighlightType.DEFAULT,
|
|
207
|
-
},
|
|
208
|
-
|
|
209
|
-
stageRect: {
|
|
210
|
-
type: [String, Object] as PropType<StageRect>,
|
|
211
|
-
},
|
|
212
|
-
|
|
213
|
-
codeOptions: {
|
|
214
|
-
type: Object,
|
|
215
|
-
default: () => ({}),
|
|
216
|
-
},
|
|
217
|
-
|
|
218
|
-
updateDragEl: {
|
|
219
|
-
type: Function as PropType<UpdateDragEl>,
|
|
220
|
-
},
|
|
221
|
-
|
|
222
|
-
disabledDragStart: {
|
|
223
|
-
type: Boolean,
|
|
224
|
-
},
|
|
225
|
-
},
|
|
98
|
+
props: editorProps,
|
|
226
99
|
|
|
227
100
|
emits: ['props-panel-mounted', 'update:modelValue'],
|
|
228
101
|
|
|
229
102
|
setup(props, { emit }) {
|
|
230
|
-
const rootChangeHandler = (value: MApp, preValue?: MApp | null) => {
|
|
231
|
-
const nodeId = editorService.get('node')?.id || props.defaultSelected;
|
|
232
|
-
let node;
|
|
233
|
-
if (nodeId) {
|
|
234
|
-
node = editorService.getNodeById(nodeId);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
if (node && node !== value) {
|
|
238
|
-
editorService.select(node.id);
|
|
239
|
-
} else if (value?.items?.length) {
|
|
240
|
-
editorService.select(value.items[0]);
|
|
241
|
-
} else if (value?.id) {
|
|
242
|
-
editorService.set('nodes', [value]);
|
|
243
|
-
editorService.set('parent', null);
|
|
244
|
-
editorService.set('page', null);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
if (toRaw(value) !== toRaw(preValue)) {
|
|
248
|
-
emit('update:modelValue', value);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
value.codeBlocks = value.codeBlocks || {};
|
|
252
|
-
|
|
253
|
-
codeBlockService.setCodeDsl(value.codeBlocks);
|
|
254
|
-
};
|
|
255
|
-
|
|
256
|
-
editorService.on('root-change', rootChangeHandler);
|
|
257
|
-
|
|
258
|
-
// 初始值变化,重新设置节点信息
|
|
259
|
-
watch(
|
|
260
|
-
() => props.modelValue,
|
|
261
|
-
(modelValue) => {
|
|
262
|
-
editorService.set('root', modelValue);
|
|
263
|
-
},
|
|
264
|
-
{
|
|
265
|
-
immediate: true,
|
|
266
|
-
},
|
|
267
|
-
);
|
|
268
|
-
|
|
269
|
-
watch(
|
|
270
|
-
() => props.componentGroupList,
|
|
271
|
-
(componentGroupList) => componentListService.setList(componentGroupList),
|
|
272
|
-
{
|
|
273
|
-
immediate: true,
|
|
274
|
-
},
|
|
275
|
-
);
|
|
276
|
-
|
|
277
|
-
watch(
|
|
278
|
-
() => props.propsConfigs,
|
|
279
|
-
(configs) => propsService.setPropsConfigs(configs),
|
|
280
|
-
{
|
|
281
|
-
immediate: true,
|
|
282
|
-
},
|
|
283
|
-
);
|
|
284
|
-
|
|
285
|
-
watch(
|
|
286
|
-
() => props.propsValues,
|
|
287
|
-
(values) => propsService.setPropsValues(values),
|
|
288
|
-
{
|
|
289
|
-
immediate: true,
|
|
290
|
-
},
|
|
291
|
-
);
|
|
292
|
-
|
|
293
|
-
watch(
|
|
294
|
-
() => props.eventMethodList,
|
|
295
|
-
(eventMethodList) => {
|
|
296
|
-
const eventsList: Record<string, EventOption[]> = {};
|
|
297
|
-
const methodsList: Record<string, EventOption[]> = {};
|
|
298
|
-
|
|
299
|
-
Object.keys(eventMethodList).forEach((type: string) => {
|
|
300
|
-
eventsList[type] = eventMethodList[type].events;
|
|
301
|
-
methodsList[type] = eventMethodList[type].methods;
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
eventsService.setEvents(eventsList);
|
|
305
|
-
eventsService.setMethods(methodsList);
|
|
306
|
-
},
|
|
307
|
-
{
|
|
308
|
-
immediate: true,
|
|
309
|
-
},
|
|
310
|
-
);
|
|
311
|
-
|
|
312
|
-
watch(
|
|
313
|
-
() => props.defaultSelected,
|
|
314
|
-
(defaultSelected) => defaultSelected && editorService.select(defaultSelected),
|
|
315
|
-
{
|
|
316
|
-
immediate: true,
|
|
317
|
-
},
|
|
318
|
-
);
|
|
319
|
-
|
|
320
|
-
watch(
|
|
321
|
-
() => props.stageRect,
|
|
322
|
-
(stageRect) => stageRect && uiService.set('stageRect', stageRect),
|
|
323
|
-
{
|
|
324
|
-
immediate: true,
|
|
325
|
-
},
|
|
326
|
-
);
|
|
327
|
-
|
|
328
|
-
onUnmounted(() => {
|
|
329
|
-
editorService.resetState();
|
|
330
|
-
historyService.resetState();
|
|
331
|
-
propsService.resetState();
|
|
332
|
-
uiService.resetState();
|
|
333
|
-
componentListService.resetState();
|
|
334
|
-
codeBlockService.resetState();
|
|
335
|
-
|
|
336
|
-
editorService.off('root-change', rootChangeHandler);
|
|
337
|
-
});
|
|
338
|
-
|
|
339
103
|
const services: Services = {
|
|
340
104
|
componentListService,
|
|
341
105
|
eventsService,
|
|
@@ -345,8 +109,12 @@ export default defineComponent({
|
|
|
345
109
|
uiService,
|
|
346
110
|
storageService,
|
|
347
111
|
codeBlockService,
|
|
112
|
+
depService,
|
|
348
113
|
};
|
|
349
114
|
|
|
115
|
+
initServiceEvents(props, emit, services);
|
|
116
|
+
initServiceState(props, services);
|
|
117
|
+
|
|
350
118
|
provide('services', services);
|
|
351
119
|
|
|
352
120
|
provide('codeOptions', props.codeOptions);
|
|
@@ -366,8 +134,6 @@ export default defineComponent({
|
|
|
366
134
|
disabledDragStart: props.disabledDragStart,
|
|
367
135
|
}),
|
|
368
136
|
);
|
|
369
|
-
// 监听组件update
|
|
370
|
-
codeBlockService.addCodeRelationListener();
|
|
371
137
|
|
|
372
138
|
return services;
|
|
373
139
|
},
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
</template>
|
|
26
26
|
<script lang="ts" setup name="MEditorCodeDraftEditor">
|
|
27
27
|
import { computed, inject, ref, watchEffect } from 'vue';
|
|
28
|
+
import type { Action } from 'element-plus';
|
|
28
29
|
import type * as monaco from 'monaco-editor';
|
|
29
30
|
|
|
30
31
|
import { TMagicButton, tMagicMessage, tMagicMessageBox } from '@tmagic/design';
|
|
@@ -109,18 +110,21 @@ const close = async (): Promise<void> => {
|
|
|
109
110
|
if (codeDraft) {
|
|
110
111
|
tMagicMessageBox
|
|
111
112
|
.confirm('您有代码修改未保存,是否保存后再关闭?', '提示', {
|
|
112
|
-
confirmButtonText: '
|
|
113
|
-
cancelButtonText: '
|
|
113
|
+
confirmButtonText: '保存并关闭',
|
|
114
|
+
cancelButtonText: '直接关闭',
|
|
114
115
|
type: 'warning',
|
|
116
|
+
distinguishCancelAndClose: true,
|
|
115
117
|
})
|
|
116
118
|
.then(async () => {
|
|
117
119
|
// 保存之后再关闭
|
|
118
120
|
saveAndClose();
|
|
119
121
|
})
|
|
120
|
-
.catch(() => {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
122
|
+
.catch((action: Action) => {
|
|
123
|
+
if (action === 'cancel') {
|
|
124
|
+
// 删除草稿 直接关闭
|
|
125
|
+
services?.codeBlockService.removeCodeDraft(props.id);
|
|
126
|
+
emit('close');
|
|
127
|
+
}
|
|
124
128
|
});
|
|
125
129
|
} else {
|
|
126
130
|
emit('close');
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { PropType } from 'vue';
|
|
2
|
+
|
|
3
|
+
import type { EventOption } from '@tmagic/core';
|
|
4
|
+
import type { FormConfig } from '@tmagic/form';
|
|
5
|
+
import type { MApp, MNode } from '@tmagic/schema';
|
|
6
|
+
import StageCore, {
|
|
7
|
+
CONTAINER_HIGHLIGHT_CLASS_NAME,
|
|
8
|
+
ContainerHighlightType,
|
|
9
|
+
CustomizeMoveableOptionsCallbackConfig,
|
|
10
|
+
MoveableOptions,
|
|
11
|
+
UpdateDragEl,
|
|
12
|
+
} from '@tmagic/stage';
|
|
13
|
+
|
|
14
|
+
import type { ComponentGroup, MenuBarData, MenuButton, MenuComponent, SideBarData, StageRect } from './type';
|
|
15
|
+
|
|
16
|
+
export default {
|
|
17
|
+
/** 页面初始值 */
|
|
18
|
+
modelValue: {
|
|
19
|
+
type: Object as PropType<MApp>,
|
|
20
|
+
default: () => ({}),
|
|
21
|
+
require: true,
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
/** 左侧面板中的组件列表 */
|
|
25
|
+
componentGroupList: {
|
|
26
|
+
type: Array as PropType<ComponentGroup[]>,
|
|
27
|
+
default: () => [],
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
/** 左侧面板配置 */
|
|
31
|
+
sidebar: {
|
|
32
|
+
type: Object as PropType<SideBarData>,
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
/** 顶部工具栏配置 */
|
|
36
|
+
menu: {
|
|
37
|
+
type: Object as PropType<MenuBarData>,
|
|
38
|
+
default: () => ({ left: [], right: [] }),
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
/** 组件树右键菜单 */
|
|
42
|
+
layerContentMenu: {
|
|
43
|
+
type: Array as PropType<(MenuButton | MenuComponent)[]>,
|
|
44
|
+
default: () => [],
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
/** 画布右键菜单 */
|
|
48
|
+
stageContentMenu: {
|
|
49
|
+
type: Array as PropType<(MenuButton | MenuComponent)[]>,
|
|
50
|
+
default: () => [],
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
/** 中间工作区域中画布渲染的内容 */
|
|
54
|
+
render: {
|
|
55
|
+
type: Function as PropType<(stage: StageCore) => HTMLDivElement | Promise<HTMLDivElement>>,
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
/** 中间工作区域中画布通过iframe渲染时的页面url */
|
|
59
|
+
runtimeUrl: String,
|
|
60
|
+
|
|
61
|
+
/** 选中时是否自动滚动到可视区域 */
|
|
62
|
+
autoScrollIntoView: Boolean,
|
|
63
|
+
|
|
64
|
+
/** 组件的属性配置表单的dsl */
|
|
65
|
+
propsConfigs: {
|
|
66
|
+
type: Object as PropType<Record<string, FormConfig>>,
|
|
67
|
+
default: () => ({}),
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
/** 添加组件时的默认值 */
|
|
71
|
+
propsValues: {
|
|
72
|
+
type: Object as PropType<Record<string, MNode>>,
|
|
73
|
+
default: () => ({}),
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
/** 组件联动事件选项列表 */
|
|
77
|
+
eventMethodList: {
|
|
78
|
+
type: Object as PropType<Record<string, { events: EventOption[]; methods: EventOption[] }>>,
|
|
79
|
+
default: () => ({}),
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
/** 画布中组件选中框的移动范围 */
|
|
83
|
+
moveableOptions: {
|
|
84
|
+
type: [Object, Function] as PropType<
|
|
85
|
+
MoveableOptions | ((config?: CustomizeMoveableOptionsCallbackConfig) => MoveableOptions)
|
|
86
|
+
>,
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
/** 编辑器初始化时默认选中的组件ID */
|
|
90
|
+
defaultSelected: {
|
|
91
|
+
type: [Number, String],
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
canSelect: {
|
|
95
|
+
type: Function as PropType<(el: HTMLElement) => boolean | Promise<boolean>>,
|
|
96
|
+
default: (el: HTMLElement) => Boolean(el.id),
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
isContainer: {
|
|
100
|
+
type: Function as PropType<(el: HTMLElement) => boolean | Promise<boolean>>,
|
|
101
|
+
default: (el: HTMLElement) => el.classList.contains('magic-ui-container'),
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
containerHighlightClassName: {
|
|
105
|
+
type: String,
|
|
106
|
+
default: CONTAINER_HIGHLIGHT_CLASS_NAME,
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
containerHighlightDuration: {
|
|
110
|
+
type: Number,
|
|
111
|
+
default: 800,
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
containerHighlightType: {
|
|
115
|
+
type: String as PropType<ContainerHighlightType>,
|
|
116
|
+
default: ContainerHighlightType.DEFAULT,
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
stageRect: {
|
|
120
|
+
type: [String, Object] as PropType<StageRect>,
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
codeOptions: {
|
|
124
|
+
type: Object,
|
|
125
|
+
default: () => ({}),
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
updateDragEl: {
|
|
129
|
+
type: Function as PropType<UpdateDragEl>,
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
disabledDragStart: {
|
|
133
|
+
type: Boolean,
|
|
134
|
+
},
|
|
135
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="m-fields-code-select">
|
|
2
|
+
<div class="m-fields-code-select" :class="config.className">
|
|
3
3
|
<m-form-table
|
|
4
4
|
:config="tableConfig"
|
|
5
5
|
:model="model[name]"
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
>
|
|
12
12
|
<template #operateCol="{ scope }">
|
|
13
13
|
<Icon
|
|
14
|
-
v-if="scope.row.codeId"
|
|
14
|
+
v-if="scope.row.codeId && config.editable"
|
|
15
15
|
:icon="editable ? Edit : View"
|
|
16
16
|
class="edit-icon"
|
|
17
17
|
@click="editCode(scope.row.codeId)"
|
|
@@ -35,15 +35,25 @@ const services = inject<Services>('services');
|
|
|
35
35
|
const mForm = inject<FormState>('mForm');
|
|
36
36
|
const emit = defineEmits(['change']);
|
|
37
37
|
|
|
38
|
-
const props =
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
38
|
+
const props = withDefaults(
|
|
39
|
+
defineProps<{
|
|
40
|
+
config: {
|
|
41
|
+
tableConfig?: TableConfig;
|
|
42
|
+
className?: string;
|
|
43
|
+
editable?: boolean;
|
|
44
|
+
};
|
|
45
|
+
model: any;
|
|
46
|
+
prop: string;
|
|
47
|
+
name: string;
|
|
48
|
+
size: 'small' | 'default' | 'large';
|
|
49
|
+
}>(),
|
|
50
|
+
{
|
|
51
|
+
config: () => ({
|
|
52
|
+
editable: true,
|
|
53
|
+
}),
|
|
54
|
+
},
|
|
55
|
+
);
|
|
56
|
+
|
|
47
57
|
const codeDsl = computed(() => services?.codeBlockService.getCodeDsl());
|
|
48
58
|
|
|
49
59
|
const tableConfig = computed<FormItem>(() => {
|
|
@@ -80,7 +90,7 @@ const tableConfig = computed<FormItem>(() => {
|
|
|
80
90
|
itemsFunction: (row: HookData) => {
|
|
81
91
|
const paramsConfig = getParamsConfig(row.codeId);
|
|
82
92
|
// 如果参数没有填值,则使用createValues补全空值
|
|
83
|
-
if (
|
|
93
|
+
if (!row.params || isEmpty(row.params)) {
|
|
84
94
|
createValues(mForm, paramsConfig, {}, row.params);
|
|
85
95
|
}
|
|
86
96
|
return paramsConfig;
|
|
@@ -124,6 +134,7 @@ const getParamsConfig = (codeId: Id): CodeParamStatement[] => {
|
|
|
124
134
|
return paramStatements.map((paramState: CodeParamStatement) => ({
|
|
125
135
|
labelWidth: '100px',
|
|
126
136
|
text: paramState.name,
|
|
137
|
+
inline: true,
|
|
127
138
|
...paramState,
|
|
128
139
|
}));
|
|
129
140
|
};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="m-fields-code-select-col">
|
|
3
|
+
<!-- 代码块下拉框 -->
|
|
4
|
+
<m-form-container :config="selectConfig" :model="model" @change="onParamsChangeHandler"></m-form-container>
|
|
5
|
+
<!-- 参数填写框 -->
|
|
6
|
+
<m-form-container :config="codeParamsConfig" :model="model" @change="onParamsChangeHandler"></m-form-container>
|
|
7
|
+
</div>
|
|
8
|
+
</template>
|
|
9
|
+
|
|
10
|
+
<script lang="ts" setup name="MEditorCodeSelectCol">
|
|
11
|
+
import { computed, defineEmits, defineProps, inject, ref, watch } from 'vue';
|
|
12
|
+
import { isEmpty, map } from 'lodash-es';
|
|
13
|
+
|
|
14
|
+
import { createValues, FieldsetConfig, FormState } from '@tmagic/form';
|
|
15
|
+
import { Id } from '@tmagic/schema';
|
|
16
|
+
|
|
17
|
+
import { CodeParamStatement, Services } from '../type';
|
|
18
|
+
const services = inject<Services>('services');
|
|
19
|
+
const mForm = inject<FormState>('mForm');
|
|
20
|
+
const emit = defineEmits(['change']);
|
|
21
|
+
|
|
22
|
+
const props = withDefaults(
|
|
23
|
+
defineProps<{
|
|
24
|
+
config: any;
|
|
25
|
+
model: any;
|
|
26
|
+
prop: string;
|
|
27
|
+
name: string;
|
|
28
|
+
size: 'small' | 'default' | 'large';
|
|
29
|
+
}>(),
|
|
30
|
+
{},
|
|
31
|
+
);
|
|
32
|
+
const codeDsl = computed(() => services?.codeBlockService.getCodeDsl());
|
|
33
|
+
const codeParamsConfig = ref<FieldsetConfig>({
|
|
34
|
+
type: 'fieldset',
|
|
35
|
+
items: [],
|
|
36
|
+
legend: '参数',
|
|
37
|
+
labelWidth: '70px',
|
|
38
|
+
name: 'params',
|
|
39
|
+
display: false,
|
|
40
|
+
});
|
|
41
|
+
const selectConfig = {
|
|
42
|
+
type: 'select',
|
|
43
|
+
text: '代码块',
|
|
44
|
+
name: 'codeId',
|
|
45
|
+
labelWidth: '70px',
|
|
46
|
+
options: () => {
|
|
47
|
+
if (codeDsl.value) {
|
|
48
|
+
return map(codeDsl.value, (value, key) => ({
|
|
49
|
+
text: `${value.name}(${key})`,
|
|
50
|
+
label: `${value.name}(${key})`,
|
|
51
|
+
value: key,
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
54
|
+
return [];
|
|
55
|
+
},
|
|
56
|
+
onChange: (formState: any, codeId: Id, { model }: any) => {
|
|
57
|
+
// 通过下拉框选择的codeId变化后修正model的值,避免写入其他codeId的params
|
|
58
|
+
model.params = {};
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* 根据代码块id获取代码块参数配置
|
|
64
|
+
* @param codeId 代码块ID
|
|
65
|
+
*/
|
|
66
|
+
const getParamItemsConfig = (codeId: Id): CodeParamStatement[] => {
|
|
67
|
+
if (!codeDsl.value) return [];
|
|
68
|
+
const paramStatements = codeDsl.value[codeId]?.params;
|
|
69
|
+
if (isEmpty(paramStatements)) return [];
|
|
70
|
+
return paramStatements.map((paramState: CodeParamStatement) => ({
|
|
71
|
+
labelWidth: '100px',
|
|
72
|
+
text: paramState.name,
|
|
73
|
+
...paramState,
|
|
74
|
+
}));
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* 根据代码块id获取参数fieldset表单配置
|
|
79
|
+
* @param codeId 代码块ID
|
|
80
|
+
*/
|
|
81
|
+
const getCodeParamsConfig = (codeId: Id) => {
|
|
82
|
+
const paramsConfig = getParamItemsConfig(codeId);
|
|
83
|
+
// 如果参数没有填值,则使用createValues补全空值
|
|
84
|
+
if (!props.model.params || isEmpty(props.model.params)) {
|
|
85
|
+
props.model.params = {};
|
|
86
|
+
createValues(mForm, paramsConfig, {}, props.model.params);
|
|
87
|
+
}
|
|
88
|
+
codeParamsConfig.value = {
|
|
89
|
+
type: 'fieldset',
|
|
90
|
+
items: paramsConfig,
|
|
91
|
+
legend: '参数',
|
|
92
|
+
labelWidth: '70px',
|
|
93
|
+
name: 'params',
|
|
94
|
+
display: !isEmpty(paramsConfig),
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* 参数值修改更新
|
|
100
|
+
*/
|
|
101
|
+
const onParamsChangeHandler = () => {
|
|
102
|
+
emit('change', props.model);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
// 监听代码块顺序变化以及下拉选择的变化,并更新参数配置
|
|
106
|
+
// TODO onchange在watch之前触发
|
|
107
|
+
watch(
|
|
108
|
+
() => props.model.codeId,
|
|
109
|
+
(codeId: Id) => {
|
|
110
|
+
if (!codeId) return;
|
|
111
|
+
getCodeParamsConfig(codeId);
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
immediate: true,
|
|
115
|
+
},
|
|
116
|
+
);
|
|
117
|
+
</script>
|