@tmagic/editor 1.5.21 → 1.5.24
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 +16 -11
- package/dist/tmagic-editor.js +1596 -344
- package/dist/tmagic-editor.umd.cjs +1592 -340
- package/package.json +15 -15
- package/src/Editor.vue +5 -0
- package/src/components/CodeBlockEditor.vue +3 -3
- package/src/editorProps.ts +6 -0
- package/src/fields/DataSourceFieldSelect/Index.vue +8 -3
- package/src/fields/DataSourceFields.vue +1 -1
- package/src/fields/DataSourceInput.vue +12 -3
- package/src/fields/DataSourceMethods.vue +1 -1
- package/src/fields/EventSelect.vue +34 -19
- package/src/fields/StyleSetter/pro/Position.vue +10 -2
- package/src/hooks/use-filter.ts +6 -4
- package/src/hooks/use-stage.ts +1 -0
- package/src/index.ts +3 -0
- package/src/initService.ts +81 -11
- package/src/layouts/CodeEditor.vue +36 -10
- package/src/layouts/page-bar/PageBarScrollContainer.vue +2 -1
- package/src/layouts/props-panel/FormPanel.vue +6 -1
- package/src/layouts/props-panel/PropsPanel.vue +6 -0
- package/src/layouts/sidebar/Sidebar.vue +14 -2
- package/src/layouts/workspace/viewer/Stage.vue +21 -32
- package/src/layouts/workspace/viewer/StageOverlay.vue +25 -6
- package/src/services/BaseService.ts +17 -8
- package/src/services/keybinding.ts +12 -0
- package/src/services/props.ts +25 -1
- package/src/services/stageOverlay.ts +1 -1
- package/src/theme/code-editor.scss +7 -2
- package/src/theme/props-panel.scss +10 -0
- package/src/theme/stage.scss +6 -11
- package/src/type.ts +17 -0
- package/src/utils/props.ts +54 -19
- package/types/index.d.ts +395 -457
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.5.
|
|
2
|
+
"version": "1.5.24",
|
|
3
3
|
"name": "@tmagic/editor",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": [
|
|
@@ -50,33 +50,33 @@
|
|
|
50
50
|
"buffer": "^6.0.3",
|
|
51
51
|
"color": "^3.1.3",
|
|
52
52
|
"deep-object-diff": "^1.1.9",
|
|
53
|
-
"emmet-monaco-es": "^5.
|
|
53
|
+
"emmet-monaco-es": "^5.5.0",
|
|
54
54
|
"events": "^3.3.0",
|
|
55
|
-
"gesto": "^1.19.
|
|
55
|
+
"gesto": "^1.19.4",
|
|
56
56
|
"keycon": "^1.4.0",
|
|
57
57
|
"lodash-es": "^4.17.21",
|
|
58
58
|
"moveable": "^0.53.0",
|
|
59
|
-
"serialize-javascript": "^6.0.
|
|
60
|
-
"sortablejs": "^1.15.
|
|
61
|
-
"@tmagic/
|
|
62
|
-
"@tmagic/
|
|
63
|
-
"@tmagic/
|
|
64
|
-
"@tmagic/
|
|
65
|
-
"@tmagic/table": "1.5.
|
|
59
|
+
"serialize-javascript": "^6.0.2",
|
|
60
|
+
"sortablejs": "^1.15.6",
|
|
61
|
+
"@tmagic/form": "1.5.24",
|
|
62
|
+
"@tmagic/stage": "1.5.24",
|
|
63
|
+
"@tmagic/utils": "1.5.24",
|
|
64
|
+
"@tmagic/design": "1.5.24",
|
|
65
|
+
"@tmagic/table": "1.5.24"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
|
-
"@types/events": "^3.0.
|
|
68
|
+
"@types/events": "^3.0.3",
|
|
69
69
|
"@types/lodash-es": "^4.17.4",
|
|
70
|
-
"@types/serialize-javascript": "^5.0.
|
|
70
|
+
"@types/serialize-javascript": "^5.0.4",
|
|
71
71
|
"@types/sortablejs": "^1.15.8",
|
|
72
72
|
"@vue/test-utils": "^2.4.6",
|
|
73
73
|
"type-fest": "^4.10.3"
|
|
74
74
|
},
|
|
75
75
|
"peerDependencies": {
|
|
76
76
|
"monaco-editor": "^0.48.0",
|
|
77
|
-
"typescript": "
|
|
78
|
-
"vue": "
|
|
79
|
-
"@tmagic/core": "1.5.
|
|
77
|
+
"typescript": "^5.8.3",
|
|
78
|
+
"vue": "^3.5.17",
|
|
79
|
+
"@tmagic/core": "1.5.24"
|
|
80
80
|
},
|
|
81
81
|
"peerDependenciesMeta": {
|
|
82
82
|
"typescript": {
|
package/src/Editor.vue
CHANGED
|
@@ -97,6 +97,7 @@
|
|
|
97
97
|
:extend-state="extendFormState"
|
|
98
98
|
:disabled-show-src="disabledShowSrc"
|
|
99
99
|
@mounted="propsPanelMountedHandler"
|
|
100
|
+
@unmounted="propsPanelUnmountedHandler"
|
|
100
101
|
@form-error="propsPanelFormErrorHandler"
|
|
101
102
|
@submit-error="propsPanelSubmitErrorHandler"
|
|
102
103
|
>
|
|
@@ -163,6 +164,7 @@ defineOptions({
|
|
|
163
164
|
|
|
164
165
|
const emit = defineEmits<{
|
|
165
166
|
'props-panel-mounted': [instance: InstanceType<typeof FormPanel>];
|
|
167
|
+
'props-panel-unmounted': [];
|
|
166
168
|
'update:modelValue': [value: MApp | null];
|
|
167
169
|
'props-form-error': [e: any];
|
|
168
170
|
'props-submit-error': [e: any];
|
|
@@ -235,6 +237,9 @@ provide<EventBus>('eventBus', new EventEmitter());
|
|
|
235
237
|
const propsPanelMountedHandler = (e: InstanceType<typeof FormPanel>) => {
|
|
236
238
|
emit('props-panel-mounted', e);
|
|
237
239
|
};
|
|
240
|
+
const propsPanelUnmountedHandler = () => {
|
|
241
|
+
emit('props-panel-unmounted');
|
|
242
|
+
};
|
|
238
243
|
|
|
239
244
|
const propsPanelSubmitErrorHandler = (e: any) => {
|
|
240
245
|
emit('props-submit-error', e);
|
|
@@ -32,20 +32,20 @@
|
|
|
32
32
|
</FloatingBox>
|
|
33
33
|
|
|
34
34
|
<Teleport to="body">
|
|
35
|
-
<TMagicDialog title="查看修改" v-model="difVisible" fullscreen>
|
|
35
|
+
<TMagicDialog title="查看修改" v-model="difVisible" fullscreen destroy-on-close>
|
|
36
36
|
<div style="display: flex; margin-bottom: 10px">
|
|
37
37
|
<div style="flex: 1"><TMagicTag size="small" type="info">修改前</TMagicTag></div>
|
|
38
38
|
<div style="flex: 1"><TMagicTag size="small" type="success">修改后</TMagicTag></div>
|
|
39
39
|
</div>
|
|
40
40
|
|
|
41
41
|
<CodeEditor
|
|
42
|
-
v-if="difVisible"
|
|
43
42
|
ref="magicVsEditor"
|
|
44
43
|
type="diff"
|
|
45
44
|
language="json"
|
|
45
|
+
:disabled-full-screen="true"
|
|
46
46
|
:initValues="content.content"
|
|
47
47
|
:modifiedValues="formBox?.form?.values.content"
|
|
48
|
-
:
|
|
48
|
+
:height="`${windowRect.height - 150}px`"
|
|
49
49
|
></CodeEditor>
|
|
50
50
|
|
|
51
51
|
<template #footer>
|
package/src/editorProps.ts
CHANGED
|
@@ -81,6 +81,10 @@ export interface EditorProps {
|
|
|
81
81
|
disabledStageOverlay?: boolean;
|
|
82
82
|
/** 禁用属性配置面板右下角显示源码的按钮 */
|
|
83
83
|
disabledShowSrc?: boolean;
|
|
84
|
+
/** 禁用数据源 */
|
|
85
|
+
disabledDataSource?: boolean;
|
|
86
|
+
/** 禁用代码块 */
|
|
87
|
+
disabledCodeBlock?: boolean;
|
|
84
88
|
/** 已选组件、代码编辑、数据源缩进配置 */
|
|
85
89
|
treeIndent?: number;
|
|
86
90
|
/** 已选组件、代码编辑、数据源子节点缩进增量配置 */
|
|
@@ -111,6 +115,8 @@ export const defaultEditorProps = {
|
|
|
111
115
|
containerHighlightDuration: 800,
|
|
112
116
|
containerHighlightType: ContainerHighlightType.DEFAULT,
|
|
113
117
|
disabledShowSrc: false,
|
|
118
|
+
disabledDataSource: false,
|
|
119
|
+
disabledCodeBlock: false,
|
|
114
120
|
componentGroupList: () => [],
|
|
115
121
|
datasourceList: () => [],
|
|
116
122
|
menu: () => ({ left: [], right: [] }),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="m-fields-data-source-field-select">
|
|
3
3
|
<FieldSelect
|
|
4
|
-
v-if="showDataSourceFieldSelect || !config.fieldConfig"
|
|
4
|
+
v-if="!disabledDataSource && (showDataSourceFieldSelect || !config.fieldConfig)"
|
|
5
5
|
:model-value="model[name]"
|
|
6
6
|
:disabled="disabled"
|
|
7
7
|
:size="size"
|
|
@@ -26,7 +26,11 @@
|
|
|
26
26
|
@change="onChangeHandler"
|
|
27
27
|
></component>
|
|
28
28
|
|
|
29
|
-
<TMagicTooltip
|
|
29
|
+
<TMagicTooltip
|
|
30
|
+
v-if="config.fieldConfig && !disabledDataSource"
|
|
31
|
+
:disabled="showDataSourceFieldSelect"
|
|
32
|
+
content="选择数据源"
|
|
33
|
+
>
|
|
30
34
|
<TMagicButton
|
|
31
35
|
style="margin-left: 5px"
|
|
32
36
|
:type="showDataSourceFieldSelect ? 'primary' : 'default'"
|
|
@@ -83,10 +87,11 @@ watch(
|
|
|
83
87
|
},
|
|
84
88
|
);
|
|
85
89
|
|
|
86
|
-
const { dataSourceService } = useServices();
|
|
90
|
+
const { dataSourceService, propsService } = useServices();
|
|
87
91
|
const mForm = inject<FormState | undefined>('mForm');
|
|
88
92
|
|
|
89
93
|
const dataSources = computed(() => dataSourceService.get('dataSources') || []);
|
|
94
|
+
const disabledDataSource = computed(() => propsService.getDisabledDataSource());
|
|
90
95
|
|
|
91
96
|
const type = computed((): string => {
|
|
92
97
|
let type = props.config.fieldConfig?.type;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="m-editor-data-source-fields">
|
|
3
|
-
<MagicTable :data="model[name]" :columns="fieldColumns"></MagicTable>
|
|
3
|
+
<MagicTable :data="model[name]" :columns="fieldColumns" :border="true"></MagicTable>
|
|
4
4
|
|
|
5
5
|
<div class="m-editor-data-source-fields-footer">
|
|
6
6
|
<TMagicButton size="small" :disabled="disabled" plain @click="newFromJsonHandler()">快速添加</TMagicButton>
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
|
+
<TMagicInput
|
|
3
|
+
v-if="disabledDataSource"
|
|
4
|
+
v-model="state"
|
|
5
|
+
:disabled="disabled"
|
|
6
|
+
:size="size"
|
|
7
|
+
:clearable="true"
|
|
8
|
+
@change="changeHandler"
|
|
9
|
+
></TMagicInput>
|
|
2
10
|
<component
|
|
3
|
-
v-if="disabled || isFocused"
|
|
11
|
+
v-else-if="disabled || isFocused"
|
|
4
12
|
:is="getDesignConfig('components')?.autocomplete.component || 'el-autocomplete'"
|
|
5
13
|
class="tmagic-design-auto-complete"
|
|
6
14
|
ref="autocomplete"
|
|
@@ -52,7 +60,7 @@ import { computed, nextTick, ref, useTemplateRef, watch } from 'vue';
|
|
|
52
60
|
import { Coin } from '@element-plus/icons-vue';
|
|
53
61
|
|
|
54
62
|
import type { DataSchema, DataSourceSchema } from '@tmagic/core';
|
|
55
|
-
import { getDesignConfig, TMagicAutocomplete, TMagicTag } from '@tmagic/design';
|
|
63
|
+
import { getDesignConfig, TMagicAutocomplete, TMagicInput, TMagicTag } from '@tmagic/design';
|
|
56
64
|
import type { DataSourceInputConfig, FieldProps } from '@tmagic/form';
|
|
57
65
|
import { getKeysArray, isNumber } from '@tmagic/utils';
|
|
58
66
|
|
|
@@ -72,7 +80,7 @@ const emit = defineEmits<{
|
|
|
72
80
|
change: [value: string];
|
|
73
81
|
}>();
|
|
74
82
|
|
|
75
|
-
const { dataSourceService } = useServices();
|
|
83
|
+
const { dataSourceService, propsService } = useServices();
|
|
76
84
|
|
|
77
85
|
const autocompleteRef = useTemplateRef<InstanceType<typeof TMagicAutocomplete>>('autocomplete');
|
|
78
86
|
const isFocused = ref(false);
|
|
@@ -81,6 +89,7 @@ const displayState = ref<{ value: string; type: 'var' | 'text' }[]>([]);
|
|
|
81
89
|
|
|
82
90
|
const input = computed<HTMLInputElement>(() => autocompleteRef.value?.inputRef?.input);
|
|
83
91
|
const dataSources = computed(() => dataSourceService.get('dataSources'));
|
|
92
|
+
const disabledDataSource = computed(() => propsService.getDisabledDataSource());
|
|
84
93
|
|
|
85
94
|
const setDisplayState = () => {
|
|
86
95
|
displayState.value = getDisplayField(dataSources.value, state.value);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="m-editor-data-source-methods">
|
|
3
|
-
<MagicTable :data="model[name]" :columns="methodColumns"></MagicTable>
|
|
3
|
+
<MagicTable :data="model[name]" :columns="methodColumns" :border="true"></MagicTable>
|
|
4
4
|
|
|
5
5
|
<div class="m-editor-data-source-methods-footer">
|
|
6
6
|
<TMagicButton size="small" type="primary" :disabled="disabled" plain @click="createCodeHandler"
|
|
@@ -85,7 +85,7 @@ const emit = defineEmits<{
|
|
|
85
85
|
change: [v: any, eventData?: ContainerChangeEventData];
|
|
86
86
|
}>();
|
|
87
87
|
|
|
88
|
-
const { editorService, dataSourceService, eventsService, codeBlockService } = useServices();
|
|
88
|
+
const { editorService, dataSourceService, eventsService, codeBlockService, propsService } = useServices();
|
|
89
89
|
|
|
90
90
|
// 事件名称下拉框表单配置
|
|
91
91
|
const eventNameConfig = computed(() => {
|
|
@@ -173,24 +173,39 @@ const actionTypeConfig = computed(() => {
|
|
|
173
173
|
text: '联动类型',
|
|
174
174
|
type: 'select',
|
|
175
175
|
defaultValue: ActionType.COMP,
|
|
176
|
-
options: () =>
|
|
177
|
-
{
|
|
178
|
-
text:
|
|
179
|
-
label:
|
|
180
|
-
value:
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
176
|
+
options: () => {
|
|
177
|
+
const o: {
|
|
178
|
+
text: string;
|
|
179
|
+
label: string;
|
|
180
|
+
value: string;
|
|
181
|
+
disabled?: boolean;
|
|
182
|
+
}[] = [
|
|
183
|
+
{
|
|
184
|
+
text: '组件',
|
|
185
|
+
label: '组件',
|
|
186
|
+
value: ActionType.COMP,
|
|
187
|
+
},
|
|
188
|
+
];
|
|
189
|
+
|
|
190
|
+
if (!propsService.getDisabledCodeBlock()) {
|
|
191
|
+
o.push({
|
|
192
|
+
text: '代码',
|
|
193
|
+
label: '代码',
|
|
194
|
+
disabled: !Object.keys(codeBlockService.getCodeDsl() || {}).length,
|
|
195
|
+
value: ActionType.CODE,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (!propsService.getDisabledDataSource()) {
|
|
200
|
+
o.push({
|
|
201
|
+
text: '数据源',
|
|
202
|
+
label: '数据源',
|
|
203
|
+
value: ActionType.DATA_SOURCE,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return o;
|
|
208
|
+
},
|
|
194
209
|
};
|
|
195
210
|
return { ...defaultActionTypeConfig, ...props.config.actionTypeConfig };
|
|
196
211
|
});
|
|
@@ -12,6 +12,14 @@ const emit = defineEmits<{
|
|
|
12
12
|
change: [v: string | StyleSchema, eventData: ContainerChangeEventData];
|
|
13
13
|
}>();
|
|
14
14
|
|
|
15
|
+
const positionText: Record<string, string> = {
|
|
16
|
+
static: '不定位',
|
|
17
|
+
relative: '相对定位',
|
|
18
|
+
absolute: '绝对定位',
|
|
19
|
+
fixed: '固定定位',
|
|
20
|
+
sticky: '粘性定位',
|
|
21
|
+
};
|
|
22
|
+
|
|
15
23
|
const config = {
|
|
16
24
|
items: [
|
|
17
25
|
{
|
|
@@ -21,9 +29,9 @@ const config = {
|
|
|
21
29
|
type: 'data-source-field-select',
|
|
22
30
|
fieldConfig: {
|
|
23
31
|
type: 'select',
|
|
24
|
-
options:
|
|
32
|
+
options: Object.keys(positionText).map((item) => ({
|
|
25
33
|
value: item,
|
|
26
|
-
text: item
|
|
34
|
+
text: `${item}(${positionText[item]})`,
|
|
27
35
|
})),
|
|
28
36
|
},
|
|
29
37
|
},
|
package/src/hooks/use-filter.ts
CHANGED
|
@@ -32,10 +32,12 @@ export const useFilter = (
|
|
|
32
32
|
const visible = filterIsMatch(text, node);
|
|
33
33
|
if (visible && parents.length) {
|
|
34
34
|
parents.forEach((parent) => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
if (text || text.length) {
|
|
36
|
+
updateStatus(nodeStatusMap.value!, parent.id, {
|
|
37
|
+
visible,
|
|
38
|
+
expand: true,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
39
41
|
});
|
|
40
42
|
}
|
|
41
43
|
|
package/src/hooks/use-stage.ts
CHANGED
|
@@ -45,6 +45,7 @@ export const useStage = (stageOptions: StageOptions) => {
|
|
|
45
45
|
updateDragEl: stageOptions.updateDragEl,
|
|
46
46
|
guidesOptions: stageOptions.guidesOptions,
|
|
47
47
|
disabledMultiSelect: stageOptions.disabledMultiSelect,
|
|
48
|
+
disabledRule: stageOptions.disabledRule,
|
|
48
49
|
});
|
|
49
50
|
|
|
50
51
|
watch(
|
package/src/index.ts
CHANGED
|
@@ -112,6 +112,9 @@ export { default as StyleSetter } from './fields/StyleSetter/Index.vue';
|
|
|
112
112
|
const defaultInstallOpt: EditorInstallOptions = {
|
|
113
113
|
// eslint-disable-next-line no-eval
|
|
114
114
|
parseDSL: (dsl: string) => eval(dsl),
|
|
115
|
+
customCreateMonacoEditor: (monaco, codeEditorEl, options) => monaco.editor.create(codeEditorEl, options),
|
|
116
|
+
customCreateMonacoDiffEditor: (monaco, codeEditorEl, options) =>
|
|
117
|
+
monaco.editor.createDiffEditor(codeEditorEl, options),
|
|
115
118
|
};
|
|
116
119
|
|
|
117
120
|
export default {
|
package/src/initService.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { onBeforeUnmount, reactive, toRaw, watch } from 'vue';
|
|
1
|
+
import { nextTick, onBeforeUnmount, reactive, toRaw, watch } from 'vue';
|
|
2
2
|
import { cloneDeep } from 'lodash-es';
|
|
3
3
|
|
|
4
4
|
import type TMagicCore from '@tmagic/core';
|
|
@@ -21,9 +21,11 @@ import {
|
|
|
21
21
|
NODE_CONDS_KEY,
|
|
22
22
|
NodeType,
|
|
23
23
|
Target,
|
|
24
|
+
updateNode,
|
|
24
25
|
} from '@tmagic/core';
|
|
25
26
|
import { ChangeRecord } from '@tmagic/form';
|
|
26
|
-
import
|
|
27
|
+
import StageCore from '@tmagic/stage';
|
|
28
|
+
import { getDepNodeIds, getNodes, isPage, isValueIncludeDataSource } from '@tmagic/utils';
|
|
27
29
|
|
|
28
30
|
import PropsPanel from './layouts/PropsPanel.vue';
|
|
29
31
|
import { isIncludeDataSource } from './utils/editor';
|
|
@@ -197,6 +199,22 @@ export const initServiceState = (
|
|
|
197
199
|
},
|
|
198
200
|
);
|
|
199
201
|
|
|
202
|
+
watch(
|
|
203
|
+
() => props.disabledCodeBlock,
|
|
204
|
+
(disabledCodeBlock) => propsService.setDisabledCodeBlock(disabledCodeBlock ?? false),
|
|
205
|
+
{
|
|
206
|
+
immediate: true,
|
|
207
|
+
},
|
|
208
|
+
);
|
|
209
|
+
|
|
210
|
+
watch(
|
|
211
|
+
() => props.disabledDataSource,
|
|
212
|
+
(disabledDataSource) => propsService.setDisabledDataSource(disabledDataSource ?? false),
|
|
213
|
+
{
|
|
214
|
+
immediate: true,
|
|
215
|
+
},
|
|
216
|
+
);
|
|
217
|
+
|
|
200
218
|
onBeforeUnmount(() => {
|
|
201
219
|
editorService.resetState();
|
|
202
220
|
historyService.resetState();
|
|
@@ -217,14 +235,15 @@ export const initServiceEvents = (
|
|
|
217
235
|
) => {
|
|
218
236
|
let getTMagicAppPrimise: Promise<TMagicCore | undefined> | null = null;
|
|
219
237
|
|
|
220
|
-
const getTMagicApp = (): Promise<TMagicCore | undefined> => {
|
|
221
|
-
const
|
|
238
|
+
const getTMagicApp = async (): Promise<TMagicCore | undefined> => {
|
|
239
|
+
const stage = await getStage();
|
|
240
|
+
const { renderer } = stage;
|
|
222
241
|
if (!renderer) {
|
|
223
|
-
return
|
|
242
|
+
return void 0;
|
|
224
243
|
}
|
|
225
244
|
|
|
226
245
|
if (renderer.runtime) {
|
|
227
|
-
return
|
|
246
|
+
return renderer.runtime.getApp?.();
|
|
228
247
|
}
|
|
229
248
|
|
|
230
249
|
if (getTMagicAppPrimise) {
|
|
@@ -328,6 +347,61 @@ export const initServiceEvents = (
|
|
|
328
347
|
},
|
|
329
348
|
);
|
|
330
349
|
|
|
350
|
+
const getStage = (): Promise<StageCore> => {
|
|
351
|
+
const stage = editorService.get('stage');
|
|
352
|
+
if (stage) {
|
|
353
|
+
return Promise.resolve(stage);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
return new Promise<StageCore>((resolve) => {
|
|
357
|
+
const unWatch = watch(
|
|
358
|
+
() => editorService.get('stage'),
|
|
359
|
+
(stage) => {
|
|
360
|
+
if (stage) {
|
|
361
|
+
resolve(stage);
|
|
362
|
+
nextTick(() => {
|
|
363
|
+
unWatch();
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
},
|
|
367
|
+
);
|
|
368
|
+
});
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
const updateStageDsl = async (value: MApp | null) => {
|
|
372
|
+
const stage = await getStage();
|
|
373
|
+
|
|
374
|
+
const runtime = await stage.renderer?.getRuntime();
|
|
375
|
+
const app = await getTMagicApp();
|
|
376
|
+
|
|
377
|
+
if (!app?.dataSourceManager) {
|
|
378
|
+
runtime?.updateRootConfig?.(cloneDeep(toRaw(value))!);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const page = editorService.get('page');
|
|
382
|
+
const node = editorService.get('node');
|
|
383
|
+
page?.id && runtime?.updatePageId?.(page.id);
|
|
384
|
+
setTimeout(() => {
|
|
385
|
+
node && stage?.select(toRaw(node.id));
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
if (value) {
|
|
389
|
+
depService.clearIdleTasks();
|
|
390
|
+
|
|
391
|
+
const dsl = cloneDeep(toRaw(value));
|
|
392
|
+
|
|
393
|
+
await (typeof Worker === 'undefined' ? collectIdle(dsl.items, true) : depService.collectByWorker(dsl));
|
|
394
|
+
|
|
395
|
+
if (dsl.dataSources && dsl.dataSourceDeps && app?.dataSourceManager) {
|
|
396
|
+
for (const node of getNodes(getDepNodeIds(dsl.dataSourceDeps), dsl.items)) {
|
|
397
|
+
updateNode(app.dataSourceManager.compiledNode(node), dsl);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
runtime?.updateRootConfig?.(dsl);
|
|
402
|
+
}
|
|
403
|
+
};
|
|
404
|
+
|
|
331
405
|
const initDataSourceDepTarget = (ds: DataSourceSchema) => {
|
|
332
406
|
depService.addTarget(createDataSourceTarget(ds, reactive({})));
|
|
333
407
|
depService.addTarget(createDataSourceMethodTarget(ds, reactive({})));
|
|
@@ -354,11 +428,7 @@ export const initServiceEvents = (
|
|
|
354
428
|
}
|
|
355
429
|
|
|
356
430
|
if (Array.isArray(value.items)) {
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
(typeof Worker === 'undefined' ? collectIdle(value.items, true) : depService.collectByWorker(value)).then(() => {
|
|
360
|
-
updateStageNodes(value.items);
|
|
361
|
-
});
|
|
431
|
+
updateStageDsl(value);
|
|
362
432
|
} else {
|
|
363
433
|
depService.clear();
|
|
364
434
|
delete value.dataSourceDeps;
|
|
@@ -5,7 +5,12 @@
|
|
|
5
5
|
:class="`magic-code-editor-wrapper${fullScreen ? ' full-screen' : ''}`"
|
|
6
6
|
:style="!fullScreen && height ? `height: ${height}` : '100%'"
|
|
7
7
|
>
|
|
8
|
-
<TMagicButton
|
|
8
|
+
<TMagicButton
|
|
9
|
+
v-if="!disabledFullScreen"
|
|
10
|
+
class="magic-code-editor-full-screen-icon"
|
|
11
|
+
circle
|
|
12
|
+
size="small"
|
|
13
|
+
@click="fullScreenHandler"
|
|
9
14
|
><MIcon :icon="FullScreen"></MIcon
|
|
10
15
|
></TMagicButton>
|
|
11
16
|
<div ref="codeEditor" class="magic-code-editor-content"></div>
|
|
@@ -15,7 +20,7 @@
|
|
|
15
20
|
</template>
|
|
16
21
|
|
|
17
22
|
<script lang="ts" setup>
|
|
18
|
-
import { onBeforeUnmount, onMounted, ref, useTemplateRef, watch } from 'vue';
|
|
23
|
+
import { nextTick, onBeforeUnmount, onMounted, ref, useTemplateRef, watch } from 'vue';
|
|
19
24
|
import { FullScreen } from '@element-plus/icons-vue';
|
|
20
25
|
import { throttle } from 'lodash-es';
|
|
21
26
|
import serialize from 'serialize-javascript';
|
|
@@ -36,12 +41,11 @@ const props = withDefaults(
|
|
|
36
41
|
modifiedValues?: any;
|
|
37
42
|
type?: 'diff';
|
|
38
43
|
language?: string;
|
|
39
|
-
options?:
|
|
40
|
-
[key: string]: any;
|
|
41
|
-
};
|
|
44
|
+
options?: monaco.editor.IStandaloneEditorConstructionOptions;
|
|
42
45
|
height?: string;
|
|
43
46
|
autoSave?: boolean;
|
|
44
47
|
parse?: boolean;
|
|
48
|
+
disabledFullScreen?: boolean;
|
|
45
49
|
}>(),
|
|
46
50
|
{
|
|
47
51
|
initValues: '',
|
|
@@ -51,6 +55,7 @@ const props = withDefaults(
|
|
|
51
55
|
tabSize: 2,
|
|
52
56
|
}),
|
|
53
57
|
parse: false,
|
|
58
|
+
disabledFullScreen: false,
|
|
54
59
|
},
|
|
55
60
|
);
|
|
56
61
|
|
|
@@ -124,6 +129,10 @@ const getEditorValue = () =>
|
|
|
124
129
|
const init = async () => {
|
|
125
130
|
if (!codeEditorEl.value) return;
|
|
126
131
|
|
|
132
|
+
if (codeEditorEl.value.clientHeight === 0) {
|
|
133
|
+
await nextTick();
|
|
134
|
+
}
|
|
135
|
+
|
|
127
136
|
const options = {
|
|
128
137
|
value: values.value,
|
|
129
138
|
language: props.language,
|
|
@@ -132,15 +141,13 @@ const init = async () => {
|
|
|
132
141
|
};
|
|
133
142
|
|
|
134
143
|
if (props.type === 'diff') {
|
|
135
|
-
vsDiffEditor = monaco
|
|
144
|
+
vsDiffEditor = getEditorConfig('customCreateMonacoDiffEditor')(monaco, codeEditorEl.value, options);
|
|
136
145
|
} else {
|
|
137
|
-
vsEditor = monaco
|
|
146
|
+
vsEditor = getEditorConfig('customCreateMonacoEditor')(monaco, codeEditorEl.value, options);
|
|
138
147
|
}
|
|
139
148
|
|
|
140
149
|
setEditorValue(props.initValues, props.modifiedValues);
|
|
141
150
|
|
|
142
|
-
loading.value = false;
|
|
143
|
-
|
|
144
151
|
emit('initd', vsEditor);
|
|
145
152
|
|
|
146
153
|
codeEditorEl.value.addEventListener('keydown', (e) => {
|
|
@@ -179,14 +186,33 @@ watch(
|
|
|
179
186
|
},
|
|
180
187
|
);
|
|
181
188
|
|
|
189
|
+
watch(
|
|
190
|
+
() => props.options,
|
|
191
|
+
(v) => {
|
|
192
|
+
vsEditor?.updateOptions(v);
|
|
193
|
+
vsDiffEditor?.updateOptions(v);
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
deep: true,
|
|
197
|
+
},
|
|
198
|
+
);
|
|
199
|
+
|
|
182
200
|
onMounted(async () => {
|
|
183
201
|
loading.value = true;
|
|
184
202
|
|
|
185
|
-
init();
|
|
203
|
+
await init();
|
|
204
|
+
|
|
205
|
+
loading.value = false;
|
|
186
206
|
});
|
|
187
207
|
|
|
188
208
|
onBeforeUnmount(() => {
|
|
189
209
|
resizeObserver.disconnect();
|
|
210
|
+
|
|
211
|
+
vsEditor?.dispose();
|
|
212
|
+
vsDiffEditor?.dispose();
|
|
213
|
+
|
|
214
|
+
vsEditor = null;
|
|
215
|
+
vsDiffEditor = null;
|
|
190
216
|
});
|
|
191
217
|
|
|
192
218
|
const fullScreen = ref(false);
|
|
@@ -78,6 +78,7 @@ const resizeObserver = new ResizeObserver(() => {
|
|
|
78
78
|
|
|
79
79
|
onMounted(() => {
|
|
80
80
|
pageBarEl.value && resizeObserver.observe(pageBarEl.value);
|
|
81
|
+
itemsContainerEl.value && resizeObserver.observe(itemsContainerEl.value);
|
|
81
82
|
});
|
|
82
83
|
|
|
83
84
|
onBeforeUnmount(() => {
|
|
@@ -136,7 +137,7 @@ watch(
|
|
|
136
137
|
let beforeDragList: Id[] = [];
|
|
137
138
|
const options = {
|
|
138
139
|
...{
|
|
139
|
-
dataIdAttr: 'page-id', // 获取排序后的数据
|
|
140
|
+
dataIdAttr: 'data-page-id', // 获取排序后的数据
|
|
140
141
|
onStart: async (event: SortableEvent) => {
|
|
141
142
|
if (typeof props.pageBarSortOptions?.beforeStart === 'function') {
|
|
142
143
|
await props.pageBarSortOptions.beforeStart(event, sortable);
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
</template>
|
|
43
43
|
|
|
44
44
|
<script setup lang="ts">
|
|
45
|
-
import { computed, getCurrentInstance, inject, onMounted, ref, useTemplateRef, watchEffect } from 'vue';
|
|
45
|
+
import { computed, getCurrentInstance, inject, onMounted, onUnmounted, ref, useTemplateRef, watchEffect } from 'vue';
|
|
46
46
|
import { Document as DocumentIcon } from '@element-plus/icons-vue';
|
|
47
47
|
|
|
48
48
|
import { TMagicButton, TMagicScrollbar } from '@tmagic/design';
|
|
@@ -78,6 +78,7 @@ const emit = defineEmits<{
|
|
|
78
78
|
'submit-error': [e: any];
|
|
79
79
|
'form-error': [e: any];
|
|
80
80
|
mounted: [internalInstance: any];
|
|
81
|
+
unmounted: [];
|
|
81
82
|
}>();
|
|
82
83
|
|
|
83
84
|
const services = useServices();
|
|
@@ -104,6 +105,10 @@ onMounted(() => {
|
|
|
104
105
|
emit('mounted', internalInstance?.proxy);
|
|
105
106
|
});
|
|
106
107
|
|
|
108
|
+
onUnmounted(() => {
|
|
109
|
+
emit('unmounted');
|
|
110
|
+
});
|
|
111
|
+
|
|
107
112
|
const submit = async (v: FormValue, eventData: ContainerChangeEventData) => {
|
|
108
113
|
try {
|
|
109
114
|
const values = await configFormRef.value?.submitForm();
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
@submit-error="errorHandler"
|
|
14
14
|
@form-error="errorHandler"
|
|
15
15
|
@mounted="mountedHandler"
|
|
16
|
+
@unmounted="unmountedHandler"
|
|
16
17
|
></FormPanel>
|
|
17
18
|
|
|
18
19
|
<Resizer v-if="showStylePanel" @change="widthChange"></Resizer>
|
|
@@ -89,6 +90,7 @@ const emit = defineEmits<{
|
|
|
89
90
|
'submit-error': [e: any];
|
|
90
91
|
'form-error': [e: any];
|
|
91
92
|
mounted: [internalInstance: InstanceType<typeof FormPanel>];
|
|
93
|
+
unmounted: [];
|
|
92
94
|
}>();
|
|
93
95
|
|
|
94
96
|
const { editorService, uiService, propsService, storageService } = useServices();
|
|
@@ -165,6 +167,10 @@ const mountedHandler = () => {
|
|
|
165
167
|
}
|
|
166
168
|
};
|
|
167
169
|
|
|
170
|
+
const unmountedHandler = () => {
|
|
171
|
+
emit('unmounted');
|
|
172
|
+
};
|
|
173
|
+
|
|
168
174
|
const propsPanelEl = useTemplateRef('propsPanel');
|
|
169
175
|
const propsPanelWidth = ref(
|
|
170
176
|
storageService.getItem(PROPS_PANEL_WIDTH_STORAGE_KEY, { protocol: Protocol.NUMBER }) || 300,
|