@tmagic/editor 1.5.2 → 1.5.4
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 +366 -6
- package/dist/tmagic-editor.js +1749 -829
- package/dist/tmagic-editor.umd.cjs +1764 -843
- package/package.json +7 -7
- package/src/components/CodeBlockEditor.vue +3 -3
- package/src/components/CodeParams.vue +2 -2
- package/src/components/ContentMenu.vue +13 -13
- package/src/components/FloatingBox.vue +9 -9
- package/src/components/Resizer.vue +2 -2
- package/src/components/ScrollBar.vue +6 -7
- package/src/components/ScrollViewer.vue +6 -6
- package/src/components/SplitView.vue +3 -3
- package/src/fields/DataSourceInput.vue +3 -3
- package/src/fields/DataSourceMethods.vue +4 -4
- package/src/fields/DisplayConds.vue +2 -1
- package/src/fields/StyleSetter/Index.vue +69 -0
- package/src/fields/StyleSetter/components/BackgroundPosition.vue +71 -0
- package/src/fields/StyleSetter/components/Border.vue +104 -0
- package/src/fields/StyleSetter/components/Box.vue +73 -0
- package/src/fields/StyleSetter/components/Position.vue +54 -0
- package/src/fields/StyleSetter/icons/background-position/LeftBottom.vue +7 -0
- package/src/fields/StyleSetter/icons/background-position/LeftCenter.vue +7 -0
- package/src/fields/StyleSetter/icons/background-position/LeftTop.vue +12 -0
- package/src/fields/StyleSetter/icons/background-position/index.ts +3 -0
- package/src/fields/StyleSetter/icons/background-repeat/NoRepeat.vue +8 -0
- package/src/fields/StyleSetter/icons/background-repeat/Repeat.vue +31 -0
- package/src/fields/StyleSetter/icons/background-repeat/RepeatX.vue +8 -0
- package/src/fields/StyleSetter/icons/background-repeat/RepeatY.vue +8 -0
- package/src/fields/StyleSetter/icons/background-repeat/index.ts +4 -0
- package/src/fields/StyleSetter/icons/display/Block.vue +7 -0
- package/src/fields/StyleSetter/icons/display/Flex.vue +7 -0
- package/src/fields/StyleSetter/icons/display/Inline.vue +7 -0
- package/src/fields/StyleSetter/icons/display/InlineBlock.vue +7 -0
- package/src/fields/StyleSetter/icons/display/None.vue +7 -0
- package/src/fields/StyleSetter/icons/display/index.ts +5 -0
- package/src/fields/StyleSetter/icons/flex-direction/Column.vue +7 -0
- package/src/fields/StyleSetter/icons/flex-direction/ColumnReverse.vue +7 -0
- package/src/fields/StyleSetter/icons/flex-direction/Row.vue +7 -0
- package/src/fields/StyleSetter/icons/flex-direction/RowReverse.vue +7 -0
- package/src/fields/StyleSetter/icons/flex-direction/index.ts +4 -0
- package/src/fields/StyleSetter/icons/justify-content/Center.vue +5 -0
- package/src/fields/StyleSetter/icons/justify-content/FlexEnd.vue +5 -0
- package/src/fields/StyleSetter/icons/justify-content/FlexStart.vue +5 -0
- package/src/fields/StyleSetter/icons/justify-content/SpaceAround.vue +7 -0
- package/src/fields/StyleSetter/icons/justify-content/SpaceBetween.vue +5 -0
- package/src/fields/StyleSetter/icons/justify-content/index.ts +5 -0
- package/src/fields/StyleSetter/icons/text-align/Center.vue +7 -0
- package/src/fields/StyleSetter/icons/text-align/Left.vue +7 -0
- package/src/fields/StyleSetter/icons/text-align/Right.vue +7 -0
- package/src/fields/StyleSetter/icons/text-align/index.ts +3 -0
- package/src/fields/StyleSetter/pro/Background.vue +78 -0
- package/src/fields/StyleSetter/pro/Border.vue +35 -0
- package/src/fields/StyleSetter/pro/Font.vue +90 -0
- package/src/fields/StyleSetter/pro/Layout.vue +164 -0
- package/src/fields/StyleSetter/pro/Position.vue +48 -0
- package/src/fields/StyleSetter/pro/index.ts +5 -0
- package/src/hooks/use-code-block-edit.ts +5 -5
- package/src/index.ts +3 -0
- package/src/initService.ts +104 -66
- package/src/layouts/CodeEditor.vue +6 -6
- package/src/layouts/Framework.vue +5 -5
- package/src/layouts/NavMenu.vue +6 -3
- package/src/layouts/page-bar/PageBar.vue +13 -13
- package/src/layouts/page-bar/PageBarScrollContainer.vue +12 -11
- package/src/layouts/props-panel/FormPanel.vue +7 -7
- package/src/layouts/props-panel/PropsPanel.vue +36 -4
- package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +3 -3
- package/src/layouts/sidebar/layer/LayerMenu.vue +2 -2
- package/src/layouts/sidebar/layer/LayerPanel.vue +5 -4
- package/src/layouts/sidebar/layer/use-click.ts +4 -6
- package/src/layouts/workspace/viewer/NodeListMenu.vue +5 -5
- package/src/layouts/workspace/viewer/Stage.vue +13 -13
- package/src/layouts/workspace/viewer/StageOverlay.vue +2 -2
- package/src/layouts/workspace/viewer/ViewerMenu.vue +3 -3
- package/src/services/componentList.ts +2 -2
- package/src/services/dep.ts +8 -2
- package/src/services/editor.ts +2 -2
- package/src/services/stageOverlay.ts +2 -2
- package/src/services/ui.ts +2 -2
- package/src/theme/props-panel.scss +13 -0
- package/src/theme/resizer.scss +2 -2
- package/src/theme/style-setter/background.scss +113 -0
- package/src/theme/style-setter/border.scss +53 -0
- package/src/theme/style-setter/index.scss +28 -0
- package/src/theme/style-setter/layout.scss +199 -0
- package/src/theme/theme.scss +1 -0
- package/src/utils/idle-task.ts +26 -10
- package/src/utils/props.ts +52 -297
- package/types/index.d.ts +432 -170
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<MContainer :config="config" :model="values" @change="change"></MContainer>
|
|
3
|
+
<Box :model="values" @change="change"></Box>
|
|
4
|
+
</template>
|
|
5
|
+
|
|
6
|
+
<script lang="ts" setup>
|
|
7
|
+
import { markRaw } from 'vue';
|
|
8
|
+
|
|
9
|
+
import type { ContainerChangeEventData, FormState } from '@tmagic/form';
|
|
10
|
+
import { MContainer } from '@tmagic/form';
|
|
11
|
+
import type { StyleSchema } from '@tmagic/schema';
|
|
12
|
+
|
|
13
|
+
import Box from '../components/Box.vue';
|
|
14
|
+
import { DisplayBlock, DisplayFlex, DisplayInline, DisplayInlineBlock, DisplayNone } from '../icons/display';
|
|
15
|
+
import {
|
|
16
|
+
FlexDirectionColumn,
|
|
17
|
+
FlexDirectionColumnReverse,
|
|
18
|
+
FlexDirectionRow,
|
|
19
|
+
FlexDirectionRowReverse,
|
|
20
|
+
} from '../icons/flex-direction';
|
|
21
|
+
import {
|
|
22
|
+
JustifyContentCenter,
|
|
23
|
+
JustifyContentFlexEnd,
|
|
24
|
+
JustifyContentFlexStart,
|
|
25
|
+
JustifyContentSpaceAround,
|
|
26
|
+
JustifyContentSpaceBetween,
|
|
27
|
+
} from '../icons/justify-content';
|
|
28
|
+
|
|
29
|
+
defineProps<{
|
|
30
|
+
values: Partial<StyleSchema>;
|
|
31
|
+
}>();
|
|
32
|
+
|
|
33
|
+
const emit = defineEmits<{
|
|
34
|
+
change: [v: string | StyleSchema, eventData: ContainerChangeEventData];
|
|
35
|
+
}>();
|
|
36
|
+
|
|
37
|
+
const config = {
|
|
38
|
+
items: [
|
|
39
|
+
{
|
|
40
|
+
name: 'display',
|
|
41
|
+
text: '模式',
|
|
42
|
+
type: 'radioGroup',
|
|
43
|
+
childType: 'button',
|
|
44
|
+
labelWidth: '68px',
|
|
45
|
+
options: [
|
|
46
|
+
{ value: 'inline', icon: markRaw(DisplayInline), tooltip: '内联布局 inline' },
|
|
47
|
+
{ value: 'flex', icon: markRaw(DisplayFlex), tooltip: '弹性布局 flex' },
|
|
48
|
+
{ value: 'block', icon: markRaw(DisplayBlock), tooltip: '块级布局 block' },
|
|
49
|
+
{ value: 'inline-block', icon: markRaw(DisplayInlineBlock), tooltip: '内联块布局 inline-block' },
|
|
50
|
+
{ value: 'none', icon: markRaw(DisplayNone), tooltip: '隐藏 none' },
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'flexDirection',
|
|
55
|
+
text: '主轴方向',
|
|
56
|
+
type: 'radioGroup',
|
|
57
|
+
childType: 'button',
|
|
58
|
+
labelWidth: '68px',
|
|
59
|
+
options: [
|
|
60
|
+
{ value: 'row', icon: markRaw(FlexDirectionRow), tooltip: '水平方向 起点在左侧 row' },
|
|
61
|
+
{ value: 'row-reverse', icon: markRaw(FlexDirectionRowReverse), tooltip: '水平方向 起点在右侧 row-reverse' },
|
|
62
|
+
{ value: 'column', icon: markRaw(FlexDirectionColumn), tooltip: '垂直方向 起点在上沿 column' },
|
|
63
|
+
{
|
|
64
|
+
value: 'column-reverse',
|
|
65
|
+
icon: markRaw(FlexDirectionColumnReverse),
|
|
66
|
+
tooltip: '垂直方向 起点在下沿 column-reverse',
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
display: (mForm: FormState, { model }: { model: Record<any, any> }) => model.display === 'flex',
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: 'justifyContent',
|
|
73
|
+
text: '主轴对齐',
|
|
74
|
+
type: 'radioGroup',
|
|
75
|
+
childType: 'button',
|
|
76
|
+
labelWidth: '68px',
|
|
77
|
+
options: [
|
|
78
|
+
{ value: 'flex-start', icon: markRaw(JustifyContentFlexStart), tooltip: '左对齐 flex-start' },
|
|
79
|
+
{ value: 'flex-end', icon: markRaw(JustifyContentFlexEnd), tooltip: '右对齐 flex-end' },
|
|
80
|
+
{ value: 'center', icon: markRaw(JustifyContentCenter), tooltip: '居中 center' },
|
|
81
|
+
{ value: 'space-between', icon: markRaw(JustifyContentSpaceBetween), tooltip: '两端对齐 space-between' },
|
|
82
|
+
{ value: 'space-around', icon: markRaw(JustifyContentSpaceAround), tooltip: '横向平分 space-around' },
|
|
83
|
+
],
|
|
84
|
+
display: (mForm: FormState, { model }: { model: Record<any, any> }) => model.display === 'flex',
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: 'alignItems',
|
|
88
|
+
text: '辅轴对齐',
|
|
89
|
+
type: 'radioGroup',
|
|
90
|
+
childType: 'button',
|
|
91
|
+
labelWidth: '68px',
|
|
92
|
+
options: [
|
|
93
|
+
{ value: 'flex-start', icon: markRaw(JustifyContentFlexStart), tooltip: '左对齐 flex-start' },
|
|
94
|
+
{ value: 'flex-end', icon: markRaw(JustifyContentFlexEnd), tooltip: '右对齐 flex-end' },
|
|
95
|
+
{ value: 'center', icon: markRaw(JustifyContentCenter), tooltip: '居中 center' },
|
|
96
|
+
{ value: 'space-between', icon: markRaw(JustifyContentSpaceBetween), tooltip: '两端对齐 space-between' },
|
|
97
|
+
{ value: 'space-around', icon: markRaw(JustifyContentSpaceAround), tooltip: '横向平分 space-around' },
|
|
98
|
+
],
|
|
99
|
+
display: (mForm: FormState, { model }: { model: Record<any, any> }) => model.display === 'flex',
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: 'flexWrap',
|
|
103
|
+
text: '换行',
|
|
104
|
+
type: 'radioGroup',
|
|
105
|
+
childType: 'button',
|
|
106
|
+
labelWidth: '68px',
|
|
107
|
+
options: [
|
|
108
|
+
{ value: 'nowrap', text: '不换行', tooltip: '不换行 nowrap' },
|
|
109
|
+
{ value: 'wrap', text: '正换行', tooltip: '第一行在上方 wrap' },
|
|
110
|
+
{ value: 'wrap-reverse', text: '逆换行', tooltip: '第一行在下方 wrap-reverse' },
|
|
111
|
+
],
|
|
112
|
+
display: (mForm: FormState, { model }: { model: Record<any, any> }) => model.display === 'flex',
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
type: 'row',
|
|
116
|
+
items: [
|
|
117
|
+
{
|
|
118
|
+
name: 'width',
|
|
119
|
+
text: '宽度',
|
|
120
|
+
labelWidth: '68px',
|
|
121
|
+
type: 'data-source-field-select',
|
|
122
|
+
fieldConfig: {
|
|
123
|
+
type: 'text',
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: 'height',
|
|
128
|
+
text: '宽度',
|
|
129
|
+
labelWidth: '68px',
|
|
130
|
+
type: 'data-source-field-select',
|
|
131
|
+
fieldConfig: {
|
|
132
|
+
type: 'text',
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
],
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
type: 'data-source-field-select',
|
|
139
|
+
text: 'overflow',
|
|
140
|
+
name: 'overflow',
|
|
141
|
+
checkStrictly: false,
|
|
142
|
+
dataSourceFieldType: ['string'],
|
|
143
|
+
fieldConfig: {
|
|
144
|
+
type: 'select',
|
|
145
|
+
clearable: true,
|
|
146
|
+
allowCreate: true,
|
|
147
|
+
options: [
|
|
148
|
+
{ text: 'visible', value: 'visible' },
|
|
149
|
+
{ text: 'hidden', value: 'hidden' },
|
|
150
|
+
{ text: 'clip', value: 'clip' },
|
|
151
|
+
{ text: 'scroll', value: 'scroll' },
|
|
152
|
+
{ text: 'auto', value: 'auto' },
|
|
153
|
+
{ text: 'overlay', value: 'overlay' },
|
|
154
|
+
{ text: 'initial', value: 'initial' },
|
|
155
|
+
],
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const change = (value: string | StyleSchema, eventData: ContainerChangeEventData) => {
|
|
162
|
+
emit('change', value, eventData);
|
|
163
|
+
};
|
|
164
|
+
</script>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<MContainer :config="config" :model="values" @change="change"></MContainer>
|
|
3
|
+
<Position v-show="values['position'] !== 'static'" :model="values" @change="change"></Position>
|
|
4
|
+
</template>
|
|
5
|
+
|
|
6
|
+
<script lang="ts" setup>
|
|
7
|
+
import { ContainerChangeEventData, MContainer } from '@tmagic/form';
|
|
8
|
+
import type { StyleSchema } from '@tmagic/schema';
|
|
9
|
+
|
|
10
|
+
import Position from '../components/Position.vue';
|
|
11
|
+
|
|
12
|
+
defineProps<{ values: Partial<StyleSchema> }>();
|
|
13
|
+
|
|
14
|
+
const emit = defineEmits<{
|
|
15
|
+
change: [v: string | StyleSchema, eventData: ContainerChangeEventData];
|
|
16
|
+
}>();
|
|
17
|
+
|
|
18
|
+
const config = {
|
|
19
|
+
items: [
|
|
20
|
+
{
|
|
21
|
+
name: 'position',
|
|
22
|
+
text: '定位',
|
|
23
|
+
labelWidth: '68px',
|
|
24
|
+
type: 'data-source-field-select',
|
|
25
|
+
fieldConfig: {
|
|
26
|
+
type: 'select',
|
|
27
|
+
options: ['static', 'relative', 'absolute', 'fixed', 'sticky'].map((item) => ({
|
|
28
|
+
value: item,
|
|
29
|
+
text: item,
|
|
30
|
+
})),
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
labelWidth: '68px',
|
|
35
|
+
name: 'zIndex',
|
|
36
|
+
text: 'zIndex',
|
|
37
|
+
type: 'data-source-field-select',
|
|
38
|
+
fieldConfig: {
|
|
39
|
+
type: 'text',
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const change = (value: string | StyleSchema, eventData: ContainerChangeEventData) => {
|
|
46
|
+
emit('change', value, eventData);
|
|
47
|
+
};
|
|
48
|
+
</script>
|
|
@@ -10,7 +10,7 @@ import type { CodeBlockService } from '@editor/services/codeBlock';
|
|
|
10
10
|
export const useCodeBlockEdit = (codeBlockService?: CodeBlockService) => {
|
|
11
11
|
const codeConfig = ref<CodeBlockContent>();
|
|
12
12
|
const codeId = ref<string>();
|
|
13
|
-
const
|
|
13
|
+
const codeBlockEditorRef = useTemplateRef<InstanceType<typeof CodeBlockEditor>>('codeBlockEditor');
|
|
14
14
|
|
|
15
15
|
// 新增代码块
|
|
16
16
|
const createCodeBlock = async () => {
|
|
@@ -29,7 +29,7 @@ export const useCodeBlockEdit = (codeBlockService?: CodeBlockService) => {
|
|
|
29
29
|
|
|
30
30
|
await nextTick();
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
codeBlockEditorRef.value?.show();
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
// 编辑代码块
|
|
@@ -54,7 +54,7 @@ export const useCodeBlockEdit = (codeBlockService?: CodeBlockService) => {
|
|
|
54
54
|
codeId.value = id;
|
|
55
55
|
|
|
56
56
|
await nextTick();
|
|
57
|
-
|
|
57
|
+
codeBlockEditorRef.value?.show();
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
// 删除代码块
|
|
@@ -67,13 +67,13 @@ export const useCodeBlockEdit = (codeBlockService?: CodeBlockService) => {
|
|
|
67
67
|
|
|
68
68
|
await codeBlockService?.setCodeDslById(codeId.value, values);
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
codeBlockEditorRef.value?.hide();
|
|
71
71
|
};
|
|
72
72
|
|
|
73
73
|
return {
|
|
74
74
|
codeId,
|
|
75
75
|
codeConfig,
|
|
76
|
-
codeBlockEditor,
|
|
76
|
+
codeBlockEditor: codeBlockEditorRef,
|
|
77
77
|
|
|
78
78
|
createCodeBlock,
|
|
79
79
|
editCode,
|
package/src/index.ts
CHANGED
|
@@ -39,6 +39,7 @@ import DisplayConds from './fields/DisplayConds.vue';
|
|
|
39
39
|
import EventSelect from './fields/EventSelect.vue';
|
|
40
40
|
import KeyValue from './fields/KeyValue.vue';
|
|
41
41
|
import PageFragmentSelect from './fields/PageFragmentSelect.vue';
|
|
42
|
+
import StyleSetter from './fields/StyleSetter/Index.vue';
|
|
42
43
|
import uiSelect from './fields/UISelect.vue';
|
|
43
44
|
import CodeEditor from './layouts/CodeEditor.vue';
|
|
44
45
|
import { setEditorConfig } from './utils/config';
|
|
@@ -106,6 +107,7 @@ export { default as TreeNode } from './components/TreeNode.vue';
|
|
|
106
107
|
export { default as PageFragmentSelect } from './fields/PageFragmentSelect.vue';
|
|
107
108
|
export { default as DisplayConds } from './fields/DisplayConds.vue';
|
|
108
109
|
export { default as CondOpSelect } from './fields/CondOpSelect.vue';
|
|
110
|
+
export { default as StyleSetter } from './fields/StyleSetter/Index.vue';
|
|
109
111
|
|
|
110
112
|
const defaultInstallOpt: EditorInstallOptions = {
|
|
111
113
|
// eslint-disable-next-line no-eval
|
|
@@ -143,5 +145,6 @@ export default {
|
|
|
143
145
|
app.component('m-fields-page-fragment-select', PageFragmentSelect);
|
|
144
146
|
app.component('m-fields-display-conds', DisplayConds);
|
|
145
147
|
app.component('m-fields-cond-op-select', CondOpSelect);
|
|
148
|
+
app.component('m-form-style-setter', StyleSetter);
|
|
146
149
|
},
|
|
147
150
|
};
|
package/src/initService.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { computed, onBeforeUnmount, reactive, toRaw, watch } from 'vue';
|
|
2
2
|
import { cloneDeep } from 'lodash-es';
|
|
3
3
|
|
|
4
|
+
import type TMagicCore from '@tmagic/core';
|
|
4
5
|
import type {
|
|
5
6
|
CodeBlockContent,
|
|
6
7
|
DataSourceSchema,
|
|
@@ -263,67 +264,46 @@ export const initServiceEvents = (
|
|
|
263
264
|
|
|
264
265
|
if (!node) return;
|
|
265
266
|
|
|
266
|
-
collectIdle([node], true)
|
|
267
|
-
|
|
268
|
-
});
|
|
267
|
+
collectIdle([node], true);
|
|
268
|
+
updateStage([node]);
|
|
269
269
|
});
|
|
270
270
|
});
|
|
271
271
|
|
|
272
|
-
const getApp = () =>
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
const app = getApp();
|
|
277
|
-
|
|
278
|
-
if (root && app?.dsl) {
|
|
279
|
-
app.dsl.dataSourceDeps = root.dataSourceDeps;
|
|
280
|
-
app.dsl.dataSourceCondDeps = root.dataSourceCondDeps;
|
|
281
|
-
app.dsl.dataSources = root.dataSources;
|
|
272
|
+
const getApp = () => {
|
|
273
|
+
const renderer = stage.value?.renderer;
|
|
274
|
+
if (!renderer) {
|
|
275
|
+
return undefined;
|
|
282
276
|
}
|
|
283
277
|
|
|
284
|
-
if (
|
|
285
|
-
getApp
|
|
278
|
+
if (renderer.runtime) {
|
|
279
|
+
return renderer.runtime.getApp?.();
|
|
286
280
|
}
|
|
287
281
|
|
|
288
|
-
|
|
282
|
+
return new Promise<TMagicCore | undefined>((resolve) => {
|
|
283
|
+
const timeout = globalThis.setTimeout(() => {
|
|
284
|
+
resolve(undefined);
|
|
285
|
+
}, 10000);
|
|
289
286
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
if (!allNodes.includes(node)) {
|
|
296
|
-
allNodes.push(node);
|
|
297
|
-
}
|
|
298
|
-
});
|
|
299
|
-
});
|
|
300
|
-
} else {
|
|
301
|
-
allNodes.push(...nodes);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
const deps = Object.values(root.dataSourceDeps || {});
|
|
305
|
-
deps.forEach((dep) => {
|
|
306
|
-
Object.keys(dep).forEach((id) => {
|
|
307
|
-
const node = allNodes.find((node) => node.id === id);
|
|
308
|
-
node &&
|
|
309
|
-
stage.value?.update({
|
|
310
|
-
config: cloneDeep(node),
|
|
311
|
-
parentId: editorService.getParentById(node.id)?.id,
|
|
312
|
-
root: cloneDeep(root),
|
|
313
|
-
});
|
|
287
|
+
renderer.on('runtime-ready', () => {
|
|
288
|
+
if (timeout) {
|
|
289
|
+
globalThis.clearTimeout(timeout);
|
|
290
|
+
}
|
|
291
|
+
resolve(renderer.runtime?.getApp?.());
|
|
314
292
|
});
|
|
315
293
|
});
|
|
316
294
|
};
|
|
317
295
|
|
|
318
|
-
const
|
|
296
|
+
const updateDataSourceSchema = async () => {
|
|
319
297
|
const root = editorService.get('root');
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
298
|
+
const app = await getApp();
|
|
299
|
+
|
|
300
|
+
if (root && app?.dsl) {
|
|
301
|
+
app.dsl.dataSourceDeps = root.dataSourceDeps;
|
|
302
|
+
app.dsl.dataSources = root.dataSources;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
if (root?.dataSources) {
|
|
306
|
+
app?.dataSourceManager?.updateSchema(root.dataSources);
|
|
327
307
|
}
|
|
328
308
|
};
|
|
329
309
|
|
|
@@ -360,18 +340,72 @@ export const initServiceEvents = (
|
|
|
360
340
|
}
|
|
361
341
|
};
|
|
362
342
|
|
|
363
|
-
|
|
343
|
+
/**
|
|
344
|
+
* 修改dsl后会执行依赖收集并调用此方法
|
|
345
|
+
* 所以这个方法是会被执行两次,当时updateStage应当时一次,所以通过inDeps参数来区分调用时机
|
|
346
|
+
* inDeps为true是则更新依赖收集到的节点,否则则更新没有依赖的节点
|
|
347
|
+
* @param nodes 需要更新的节点
|
|
348
|
+
* @param inDeps 是否依赖收集完成事件中执行的
|
|
349
|
+
* @returns
|
|
350
|
+
*/
|
|
351
|
+
const updateStage = (nodes: MNode[], inDeps = false) => {
|
|
364
352
|
const root = editorService.get('root');
|
|
365
353
|
if (!root) return;
|
|
366
|
-
|
|
354
|
+
|
|
355
|
+
const update = (node: MNode) =>
|
|
356
|
+
stage.value?.update({
|
|
357
|
+
config: cloneDeep(node),
|
|
358
|
+
parentId: editorService.getParentById(node.id)?.id,
|
|
359
|
+
root: cloneDeep(root),
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
nodes.forEach((node) => {
|
|
363
|
+
const inDepsNodeId: Id[] = [];
|
|
364
|
+
const deps = Object.values(root.dataSourceDeps || {});
|
|
365
|
+
deps.forEach((dep) => {
|
|
366
|
+
Object.keys(dep).forEach((id) => {
|
|
367
|
+
inDepsNodeId.push(id);
|
|
368
|
+
});
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
if (inDeps) {
|
|
372
|
+
if (inDepsNodeId.includes(node.id)) {
|
|
373
|
+
update(node);
|
|
374
|
+
}
|
|
375
|
+
} else {
|
|
376
|
+
if (!inDepsNodeId.includes(node.id)) {
|
|
377
|
+
update(node);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
const dsDepCollectedHandler = async (nodes: MNode[], deep: boolean) => {
|
|
384
|
+
const root = editorService.get('root');
|
|
385
|
+
if (!root) return;
|
|
386
|
+
const app = await getApp();
|
|
367
387
|
if (app?.dsl) {
|
|
368
388
|
app.dsl.dataSourceDeps = root.dataSourceDeps;
|
|
369
389
|
}
|
|
390
|
+
if (deep) {
|
|
391
|
+
nodes.forEach((node) => {
|
|
392
|
+
traverseNode<MNode>(
|
|
393
|
+
node,
|
|
394
|
+
(node) => {
|
|
395
|
+
updateStage([node], true);
|
|
396
|
+
},
|
|
397
|
+
[],
|
|
398
|
+
true,
|
|
399
|
+
);
|
|
400
|
+
});
|
|
401
|
+
} else {
|
|
402
|
+
updateStage(nodes, true);
|
|
403
|
+
}
|
|
370
404
|
};
|
|
371
405
|
|
|
372
406
|
depService.on('add-target', targetAddHandler);
|
|
373
407
|
depService.on('remove-target', targetRemoveHandler);
|
|
374
|
-
depService.on('collected',
|
|
408
|
+
depService.on('ds-collected', dsDepCollectedHandler);
|
|
375
409
|
|
|
376
410
|
const initDataSourceDepTarget = (ds: DataSourceSchema) => {
|
|
377
411
|
depService.addTarget(createDataSourceTarget(ds, reactive({})));
|
|
@@ -396,9 +430,9 @@ export const initServiceEvents = (
|
|
|
396
430
|
|
|
397
431
|
// 新增节点,收集依赖
|
|
398
432
|
const nodeAddHandler = (nodes: MNode[]) => {
|
|
399
|
-
collectIdle(nodes, true)
|
|
400
|
-
|
|
401
|
-
|
|
433
|
+
collectIdle(nodes, true);
|
|
434
|
+
|
|
435
|
+
updateStage(nodes);
|
|
402
436
|
};
|
|
403
437
|
|
|
404
438
|
// 节点更新,收集依赖
|
|
@@ -430,11 +464,10 @@ export const initServiceEvents = (
|
|
|
430
464
|
});
|
|
431
465
|
|
|
432
466
|
if (needRecollectNodes.length) {
|
|
433
|
-
collectIdle(needRecollectNodes, true)
|
|
434
|
-
|
|
435
|
-
});
|
|
467
|
+
collectIdle(needRecollectNodes, true);
|
|
468
|
+
updateStage(needRecollectNodes);
|
|
436
469
|
} else if (normalNodes.length) {
|
|
437
|
-
|
|
470
|
+
updateStage(normalNodes);
|
|
438
471
|
}
|
|
439
472
|
};
|
|
440
473
|
|
|
@@ -446,7 +479,7 @@ export const initServiceEvents = (
|
|
|
446
479
|
// 由于历史记录变化是更新整个page,所以历史记录变化时,需要重新收集依赖
|
|
447
480
|
const historyChangeHandler = (page: MPage | MPageFragment) => {
|
|
448
481
|
collectIdle([page], true).then(() => {
|
|
449
|
-
updateDataSourceSchema(
|
|
482
|
+
updateDataSourceSchema();
|
|
450
483
|
});
|
|
451
484
|
};
|
|
452
485
|
|
|
@@ -472,12 +505,16 @@ export const initServiceEvents = (
|
|
|
472
505
|
codeBlockService.on('addOrUpdate', codeBlockAddOrUpdateHandler);
|
|
473
506
|
codeBlockService.on('remove', codeBlockRemoveHandler);
|
|
474
507
|
|
|
475
|
-
const dataSourceAddHandler = (config: DataSourceSchema) => {
|
|
508
|
+
const dataSourceAddHandler = async (config: DataSourceSchema) => {
|
|
476
509
|
initDataSourceDepTarget(config);
|
|
477
|
-
getApp()
|
|
510
|
+
const app = await getApp();
|
|
511
|
+
app?.dataSourceManager?.addDataSource(config);
|
|
478
512
|
};
|
|
479
513
|
|
|
480
|
-
const dataSourceUpdateHandler = (
|
|
514
|
+
const dataSourceUpdateHandler = async (
|
|
515
|
+
config: DataSourceSchema,
|
|
516
|
+
{ changeRecords }: { changeRecords: ChangeRecord[] },
|
|
517
|
+
) => {
|
|
481
518
|
let needRecollectDep = false;
|
|
482
519
|
for (const changeRecord of changeRecords) {
|
|
483
520
|
if (!changeRecord.propPath) {
|
|
@@ -506,11 +543,12 @@ export const initServiceEvents = (
|
|
|
506
543
|
initDataSourceDepTarget(config);
|
|
507
544
|
|
|
508
545
|
collectIdle(root.items, true).then(() => {
|
|
509
|
-
updateDataSourceSchema(
|
|
546
|
+
updateDataSourceSchema();
|
|
510
547
|
});
|
|
511
548
|
}
|
|
512
549
|
} else if (root?.dataSources) {
|
|
513
|
-
getApp()
|
|
550
|
+
const app = await getApp();
|
|
551
|
+
app?.dataSourceManager?.updateSchema(root.dataSources);
|
|
514
552
|
}
|
|
515
553
|
};
|
|
516
554
|
|
|
@@ -525,7 +563,7 @@ export const initServiceEvents = (
|
|
|
525
563
|
const nodeIds = Object.keys(root?.dataSourceDeps?.[id] || {});
|
|
526
564
|
const nodes = getNodes(nodeIds, root?.items);
|
|
527
565
|
collectIdle(nodes, false).then(() => {
|
|
528
|
-
updateDataSourceSchema(
|
|
566
|
+
updateDataSourceSchema();
|
|
529
567
|
});
|
|
530
568
|
|
|
531
569
|
removeDataSourceTarget(id);
|
|
@@ -538,7 +576,7 @@ export const initServiceEvents = (
|
|
|
538
576
|
onBeforeUnmount(() => {
|
|
539
577
|
depService.off('add-target', targetAddHandler);
|
|
540
578
|
depService.off('remove-target', targetRemoveHandler);
|
|
541
|
-
depService.off('collected',
|
|
579
|
+
depService.off('ds-collected', dsDepCollectedHandler);
|
|
542
580
|
|
|
543
581
|
editorService.off('history-change', historyChangeHandler);
|
|
544
582
|
editorService.off('root-change', rootChangeHandler);
|
|
@@ -93,7 +93,7 @@ let vsDiffEditor: monaco.editor.IStandaloneDiffEditor | null = null;
|
|
|
93
93
|
|
|
94
94
|
const values = ref('');
|
|
95
95
|
const loading = ref(false);
|
|
96
|
-
const
|
|
96
|
+
const codeEditorEl = useTemplateRef<HTMLDivElement>('codeEditor');
|
|
97
97
|
|
|
98
98
|
const resizeObserver = new globalThis.ResizeObserver(
|
|
99
99
|
throttle((): void => {
|
|
@@ -122,7 +122,7 @@ const getEditorValue = () =>
|
|
|
122
122
|
(props.type === 'diff' ? vsDiffEditor?.getModifiedEditor().getValue() : vsEditor?.getValue()) || '';
|
|
123
123
|
|
|
124
124
|
const init = async () => {
|
|
125
|
-
if (!
|
|
125
|
+
if (!codeEditorEl.value) return;
|
|
126
126
|
|
|
127
127
|
const options = {
|
|
128
128
|
value: values.value,
|
|
@@ -132,9 +132,9 @@ const init = async () => {
|
|
|
132
132
|
};
|
|
133
133
|
|
|
134
134
|
if (props.type === 'diff') {
|
|
135
|
-
vsDiffEditor = monaco.editor.createDiffEditor(
|
|
135
|
+
vsDiffEditor = monaco.editor.createDiffEditor(codeEditorEl.value, options);
|
|
136
136
|
} else {
|
|
137
|
-
vsEditor = monaco.editor.create(
|
|
137
|
+
vsEditor = monaco.editor.create(codeEditorEl.value, options);
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
setEditorValue(props.initValues, props.modifiedValues);
|
|
@@ -143,7 +143,7 @@ const init = async () => {
|
|
|
143
143
|
|
|
144
144
|
emit('initd', vsEditor);
|
|
145
145
|
|
|
146
|
-
|
|
146
|
+
codeEditorEl.value.addEventListener('keydown', (e) => {
|
|
147
147
|
if (e.keyCode === 83 && (navigator.platform.match('Mac') ? e.metaKey : e.ctrlKey)) {
|
|
148
148
|
e.preventDefault();
|
|
149
149
|
e.stopPropagation();
|
|
@@ -163,7 +163,7 @@ const init = async () => {
|
|
|
163
163
|
});
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
-
resizeObserver.observe(
|
|
166
|
+
resizeObserver.observe(codeEditorEl.value);
|
|
167
167
|
};
|
|
168
168
|
|
|
169
169
|
watch(
|
|
@@ -90,8 +90,8 @@ const DEFAULT_RIGHT_COLUMN_WIDTH = 480;
|
|
|
90
90
|
const codeOptions = inject('codeOptions', {});
|
|
91
91
|
const { editorService, uiService } = inject<Services>('services') || {};
|
|
92
92
|
|
|
93
|
-
const
|
|
94
|
-
const
|
|
93
|
+
const contentEl = useTemplateRef<HTMLDivElement>('content');
|
|
94
|
+
const splitViewRef = useTemplateRef<InstanceType<typeof SplitView>>('splitView');
|
|
95
95
|
|
|
96
96
|
const root = computed(() => editorService?.get('root'));
|
|
97
97
|
const page = computed(() => editorService?.get('page'));
|
|
@@ -115,7 +115,7 @@ const columnWidth = ref<Partial<GetColumnWidth>>({
|
|
|
115
115
|
});
|
|
116
116
|
|
|
117
117
|
watch(pageLength, () => {
|
|
118
|
-
|
|
118
|
+
splitViewRef.value?.updateWidth();
|
|
119
119
|
});
|
|
120
120
|
|
|
121
121
|
watch(
|
|
@@ -146,8 +146,8 @@ const resizerObserver = new ResizeObserver((entries) => {
|
|
|
146
146
|
});
|
|
147
147
|
|
|
148
148
|
onMounted(() => {
|
|
149
|
-
if (
|
|
150
|
-
resizerObserver.observe(
|
|
149
|
+
if (contentEl.value) {
|
|
150
|
+
resizerObserver.observe(contentEl.value);
|
|
151
151
|
}
|
|
152
152
|
});
|
|
153
153
|
|
package/src/layouts/NavMenu.vue
CHANGED
|
@@ -179,8 +179,10 @@ const buttons = computed(() => {
|
|
|
179
179
|
return data;
|
|
180
180
|
});
|
|
181
181
|
|
|
182
|
+
const navMenuEl = useTemplateRef<HTMLDivElement>('navMenu');
|
|
183
|
+
|
|
182
184
|
const resizeObserver = new ResizeObserver(() => {
|
|
183
|
-
const rect =
|
|
185
|
+
const rect = navMenuEl.value?.getBoundingClientRect();
|
|
184
186
|
if (rect) {
|
|
185
187
|
uiService?.set('navMenuRect', {
|
|
186
188
|
left: rect.left,
|
|
@@ -190,10 +192,11 @@ const resizeObserver = new ResizeObserver(() => {
|
|
|
190
192
|
});
|
|
191
193
|
}
|
|
192
194
|
});
|
|
193
|
-
|
|
195
|
+
|
|
194
196
|
onMounted(() => {
|
|
195
|
-
|
|
197
|
+
navMenuEl.value && resizeObserver.observe(navMenuEl.value);
|
|
196
198
|
});
|
|
199
|
+
|
|
197
200
|
onBeforeUnmount(() => {
|
|
198
201
|
resizeObserver.disconnect();
|
|
199
202
|
});
|