@tmagic/editor 1.3.0-alpha.8 → 1.3.0-beta.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 +82 -218
- package/dist/tmagic-editor.js +4985 -3999
- package/dist/tmagic-editor.js.map +1 -1
- package/dist/tmagic-editor.umd.cjs +5013 -4012
- package/dist/tmagic-editor.umd.cjs.map +1 -1
- package/package.json +15 -15
- package/src/Editor.vue +4 -5
- package/src/components/CodeBlockEditor.vue +257 -0
- package/src/components/CodeParams.vue +60 -0
- package/src/components/ContentMenu.vue +11 -3
- package/src/editorProps.ts +30 -5
- package/src/fields/Code.vue +23 -19
- package/src/fields/CodeLink.vue +6 -7
- package/src/fields/CodeSelect.vue +12 -9
- package/src/fields/CodeSelectCol.vue +70 -81
- package/src/fields/DataSourceFieldSelect.vue +47 -0
- package/src/fields/DataSourceFields.vue +28 -22
- package/src/fields/DataSourceInput.vue +21 -58
- package/src/fields/DataSourceMethodSelect.vue +136 -0
- package/src/fields/DataSourceMethods.vue +103 -0
- package/src/fields/DataSourceSelect.vue +68 -0
- package/src/fields/EventSelect.vue +53 -19
- package/src/fields/KeyValue.vue +9 -11
- package/src/fields/UISelect.vue +54 -14
- package/src/hooks/index.ts +21 -0
- package/src/hooks/use-code-block-edit.ts +84 -0
- package/src/hooks/use-data-source-method.ts +100 -0
- package/src/{utils/stage.ts → hooks/use-stage.ts} +4 -7
- package/src/icons/CenterIcon.vue +13 -0
- package/src/icons/CodeIcon.vue +0 -2
- package/src/icons/FolderMinusIcon.vue +22 -0
- package/src/index.ts +15 -0
- package/src/initService.ts +73 -16
- package/src/layouts/CodeEditor.vue +62 -10
- package/src/layouts/Framework.vue +7 -3
- package/src/layouts/PropsPanel.vue +8 -3
- package/src/layouts/sidebar/ComponentListPanel.vue +6 -9
- package/src/layouts/sidebar/LayerMenu.vue +20 -21
- package/src/layouts/sidebar/LayerNode.vue +40 -0
- package/src/layouts/sidebar/LayerPanel.vue +14 -5
- package/src/layouts/sidebar/Sidebar.vue +22 -36
- package/src/layouts/sidebar/code-block/CodeBlockList.vue +81 -119
- package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +64 -0
- package/src/layouts/sidebar/data-source/DataSourceConfigPanel.vue +27 -47
- package/src/layouts/sidebar/data-source/DataSourceList.vue +145 -0
- package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +58 -69
- package/src/layouts/workspace/Stage.vue +13 -5
- package/src/layouts/workspace/ViewerMenu.vue +10 -35
- package/src/services/codeBlock.ts +18 -71
- package/src/services/dataSource.ts +16 -1
- package/src/services/dep.ts +23 -20
- package/src/services/editor.ts +46 -18
- package/src/services/props.ts +2 -2
- package/src/theme/code-block.scss +5 -117
- package/src/theme/code-editor.scss +27 -2
- package/src/theme/content-menu.scss +1 -1
- package/src/theme/data-source-methods.scss +13 -0
- package/src/theme/data-source.scss +11 -0
- package/src/theme/event.scss +15 -12
- package/src/theme/framework.scss +0 -3
- package/src/theme/layer-panel.scss +6 -0
- package/src/theme/layout.scss +4 -0
- package/src/theme/sidebar.scss +18 -60
- package/src/theme/theme.scss +1 -0
- package/src/type.ts +47 -7
- package/src/utils/content-menu.ts +92 -0
- package/src/utils/data-source/formConfigs/base.ts +28 -30
- package/src/utils/data-source/index.ts +65 -2
- package/src/utils/dep.ts +39 -7
- package/src/utils/index.ts +1 -1
- package/src/utils/props.ts +298 -189
- package/src/utils/undo-redo.ts +1 -1
- package/types/Editor.vue.d.ts +30 -6
- package/types/components/CodeBlockEditor.vue.d.ts +23 -0
- package/types/components/CodeParams.vue.d.ts +26 -0
- package/types/components/ContentMenu.vue.d.ts +2 -2
- package/types/components/ToolButton.vue.d.ts +3 -3
- package/types/editorProps.d.ts +19 -5
- package/types/fields/Code.vue.d.ts +24 -19
- package/types/fields/CodeLink.vue.d.ts +12 -21
- package/types/fields/CodeSelect.vue.d.ts +6 -17
- package/types/fields/CodeSelectCol.vue.d.ts +10 -14
- package/types/fields/DataSourceFieldSelect.vue.d.ts +29 -0
- package/types/fields/DataSourceFields.vue.d.ts +7 -18
- package/types/fields/DataSourceInput.vue.d.ts +10 -30
- package/types/fields/DataSourceMethodSelect.vue.d.ts +29 -0
- package/types/fields/DataSourceMethods.vue.d.ts +32 -0
- package/types/fields/DataSourceSelect.vue.d.ts +40 -0
- package/types/fields/EventSelect.vue.d.ts +2 -13
- package/types/fields/KeyValue.vue.d.ts +9 -24
- package/types/fields/UISelect.vue.d.ts +2 -11
- package/types/hooks/index.d.ts +3 -0
- package/types/{components/FunctionEditor.vue.d.ts → hooks/use-code-block-edit.d.ts} +31 -119
- package/types/hooks/use-data-source-method.d.ts +123 -0
- package/types/icons/CenterIcon.vue.d.ts +2 -0
- package/types/icons/FolderMinusIcon.vue.d.ts +2 -0
- package/types/index.d.ts +7 -0
- package/types/initService.d.ts +2 -2
- package/types/layouts/CodeEditor.vue.d.ts +10 -4
- package/types/layouts/PropsPanel.vue.d.ts +274 -2
- package/types/layouts/sidebar/LayerNode.vue.d.ts +16 -0
- package/types/layouts/sidebar/Sidebar.vue.d.ts +0 -3
- package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +4 -9
- package/types/layouts/sidebar/code-block/{CodeBlockEditor.vue.d.ts → CodeBlockListPanel.vue.d.ts} +9 -5
- package/types/layouts/sidebar/data-source/DataSourceConfigPanel.vue.d.ts +3 -1
- package/types/layouts/sidebar/data-source/DataSourceList.vue.d.ts +14 -0
- package/types/layouts/sidebar/data-source/DataSourceListPanel.vue.d.ts +1 -11
- package/types/services/codeBlock.d.ts +6 -37
- package/types/services/dataSource.d.ts +7 -1
- package/types/services/dep.d.ts +12 -21
- package/types/services/editor.d.ts +1 -1
- package/types/services/props.d.ts +10 -115
- package/types/type.d.ts +42 -7
- package/types/utils/content-menu.d.ts +7 -0
- package/types/utils/data-source/formConfigs/base.d.ts +1 -2
- package/types/utils/data-source/index.d.ts +5 -0
- package/types/utils/dep.d.ts +4 -2
- package/types/utils/index.d.ts +1 -1
- package/types/utils/props.d.ts +13 -102
- package/src/components/CodeDraftEditor.vue +0 -148
- package/src/components/FunctionEditor.vue +0 -197
- package/src/layouts/sidebar/code-block/CodeBlockEditor.vue +0 -100
- package/types/components/CodeDraftEditor.vue.d.ts +0 -61
- /package/types/{utils/stage.d.ts → hooks/use-stage.d.ts} +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { computed } from 'vue';
|
|
2
2
|
|
|
3
|
+
import type { MNode } from '@tmagic/schema';
|
|
3
4
|
import StageCore, { GuidesType, RemoveEventData, SortEventData, UpdateEventData } from '@tmagic/stage';
|
|
4
5
|
|
|
5
6
|
import editorService from '@editor/services/editor';
|
|
6
7
|
import uiService from '@editor/services/ui';
|
|
7
8
|
import { H_GUIDE_LINE_STORAGE_KEY, StageOptions, V_GUIDE_LINE_STORAGE_KEY } from '@editor/type';
|
|
8
|
-
|
|
9
|
-
import { getGuideLineFromCache } from './editor';
|
|
9
|
+
import { getGuideLineFromCache } from '@editor/utils/editor';
|
|
10
10
|
|
|
11
11
|
const root = computed(() => editorService.get('root'));
|
|
12
12
|
const page = computed(() => editorService.get('page'));
|
|
@@ -74,11 +74,8 @@ export const useStage = (stageOptions: StageOptions) => {
|
|
|
74
74
|
});
|
|
75
75
|
|
|
76
76
|
stage.on('remove', (ev: RemoveEventData) => {
|
|
77
|
-
editorService.
|
|
78
|
-
|
|
79
|
-
id: el.id,
|
|
80
|
-
})),
|
|
81
|
-
);
|
|
77
|
+
const nodes = ev.data.map(({ el }) => editorService.getNodeById(el.id));
|
|
78
|
+
editorService.remove(nodes.filter((node) => Boolean(node)) as MNode[]);
|
|
82
79
|
});
|
|
83
80
|
|
|
84
81
|
stage.on('select-parent', () => {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M2 4H21V6H2V4Z" fill="black" fill-opacity="0.9" />
|
|
4
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M5 11H18V13H5V11Z" fill="black" fill-opacity="0.9" />
|
|
5
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M2 18H21V20H2V18Z" fill="black" fill-opacity="0.9" />
|
|
6
|
+
</svg>
|
|
7
|
+
</template>
|
|
8
|
+
|
|
9
|
+
<script lang="ts" setup>
|
|
10
|
+
defineOptions({
|
|
11
|
+
name: 'MEditorCenterIcon',
|
|
12
|
+
});
|
|
13
|
+
</script>
|
package/src/icons/CodeIcon.vue
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<!-- 代码icon,cdn链接:https://cloudcache.tencent-cloud.com/qcloud/ui/static/government/0d463ed5-6407-4498-8865-3d05b5e70115.svg -->
|
|
3
2
|
<svg viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
4
|
-
<!-- Generator: Sketch 60.1 (88133) - https://sketch.com -->
|
|
5
3
|
<defs><rect id="path-1" x="0" y="0" width="32" height="32"></rect></defs>
|
|
6
4
|
<g id="组件规范" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
|
7
5
|
<g id="03图标" transform="translate(-561.000000, -2356.000000)">
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg
|
|
3
|
+
width="1em"
|
|
4
|
+
height="1em"
|
|
5
|
+
viewBox="0 0 16 16"
|
|
6
|
+
class="bi bi-folder-minus"
|
|
7
|
+
fill="currentColor"
|
|
8
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
9
|
+
>
|
|
10
|
+
<path
|
|
11
|
+
fill-rule="evenodd"
|
|
12
|
+
d="M9.828 4H2.19a1 1 0 0 0-.996 1.09l.637 7a1 1 0 0 0 .995.91H9v1H2.826a2 2 0 0 1-1.991-1.819l-.637-7a1.99 1.99 0 0 1 .342-1.31L.5 3a2 2 0 0 1 2-2h3.672a2 2 0 0 1 1.414.586l.828.828A2 2 0 0 0 9.828 3h3.982a2 2 0 0 1 1.992 2.181L15.546 8H14.54l.265-2.91A1 1 0 0 0 13.81 4H9.828zm-2.95-1.707L7.587 3H2.19c-.24 0-.47.042-.684.12L1.5 2.98a1 1 0 0 1 1-.98h3.672a1 1 0 0 1 .707.293z"
|
|
13
|
+
/>
|
|
14
|
+
<path fill-rule="evenodd" d="M11 11.5a.5.5 0 0 1 .5-.5h4a.5.5 0 0 1 0 1h-4a.5.5 0 0 1-.5-.5z" />
|
|
15
|
+
</svg>
|
|
16
|
+
</template>
|
|
17
|
+
|
|
18
|
+
<script lang="ts" setup>
|
|
19
|
+
defineOptions({
|
|
20
|
+
name: 'MEditorFolderMinusIcon',
|
|
21
|
+
});
|
|
22
|
+
</script>
|
package/src/index.ts
CHANGED
|
@@ -22,7 +22,11 @@ import CodeLink from './fields/CodeLink.vue';
|
|
|
22
22
|
import CodeSelect from './fields/CodeSelect.vue';
|
|
23
23
|
import CodeSelectCol from './fields/CodeSelectCol.vue';
|
|
24
24
|
import DataSourceFields from './fields/DataSourceFields.vue';
|
|
25
|
+
import DataSourceFieldSelect from './fields/DataSourceFieldSelect.vue';
|
|
25
26
|
import DataSourceInput from './fields/DataSourceInput.vue';
|
|
27
|
+
import DataSourceMethods from './fields/DataSourceMethods.vue';
|
|
28
|
+
import DataSourceMethodSelect from './fields/DataSourceMethodSelect.vue';
|
|
29
|
+
import DataSourceSelect from './fields/DataSourceSelect.vue';
|
|
26
30
|
import EventSelect from './fields/EventSelect.vue';
|
|
27
31
|
import KeyValue from './fields/KeyValue.vue';
|
|
28
32
|
import uiSelect from './fields/UISelect.vue';
|
|
@@ -35,6 +39,7 @@ import './theme/index.scss';
|
|
|
35
39
|
|
|
36
40
|
export type { MoveableOptions } from '@tmagic/stage';
|
|
37
41
|
export * from './type';
|
|
42
|
+
export * from './hooks';
|
|
38
43
|
export * from './utils';
|
|
39
44
|
export { default as TMagicEditor } from './Editor.vue';
|
|
40
45
|
export { default as TMagicCodeEditor } from './layouts/CodeEditor.vue';
|
|
@@ -52,10 +57,15 @@ export { default as LayerPanel } from './layouts/sidebar/LayerPanel.vue';
|
|
|
52
57
|
export { default as CodeSelect } from './fields/CodeSelect.vue';
|
|
53
58
|
export { default as CodeSelectCol } from './fields/CodeSelectCol.vue';
|
|
54
59
|
export { default as DataSourceFields } from './fields/DataSourceFields.vue';
|
|
60
|
+
export { default as DataSourceMethods } from './fields/DataSourceMethods.vue';
|
|
55
61
|
export { default as DataSourceInput } from './fields/DataSourceInput.vue';
|
|
62
|
+
export { default as DataSourceSelect } from './fields/DataSourceSelect.vue';
|
|
63
|
+
export { default as DataSourceMethodSelect } from './fields/DataSourceMethodSelect.vue';
|
|
64
|
+
export { default as DataSourceFieldSelect } from './fields/DataSourceFieldSelect.vue';
|
|
56
65
|
export { default as EventSelect } from './fields/EventSelect.vue';
|
|
57
66
|
export { default as KeyValue } from './fields/KeyValue.vue';
|
|
58
67
|
export { default as CodeBlockList } from './layouts/sidebar/code-block/CodeBlockList.vue';
|
|
68
|
+
export { default as CodeBlockListPanel } from './layouts/sidebar/code-block/CodeBlockListPanel.vue';
|
|
59
69
|
export { default as PropsPanel } from './layouts/PropsPanel.vue';
|
|
60
70
|
export { default as ToolButton } from './components/ToolButton.vue';
|
|
61
71
|
export { default as ContentMenu } from './components/ContentMenu.vue';
|
|
@@ -63,6 +73,7 @@ export { default as Icon } from './components/Icon.vue';
|
|
|
63
73
|
export { default as LayoutContainer } from './components/SplitView.vue';
|
|
64
74
|
export { default as SplitView } from './components/SplitView.vue';
|
|
65
75
|
export { default as Resizer } from './components/Resizer.vue';
|
|
76
|
+
export { default as CodeBlockEditor } from './components/CodeBlockEditor.vue';
|
|
66
77
|
|
|
67
78
|
const defaultInstallOpt: InstallOptions = {
|
|
68
79
|
// eslint-disable-next-line no-eval
|
|
@@ -87,5 +98,9 @@ export default {
|
|
|
87
98
|
app.component('m-fields-data-source-fields', DataSourceFields);
|
|
88
99
|
app.component('m-fields-key-value', KeyValue);
|
|
89
100
|
app.component('m-fields-data-source-input', DataSourceInput);
|
|
101
|
+
app.component('m-fields-data-source-select', DataSourceSelect);
|
|
102
|
+
app.component('m-fields-data-source-methods', DataSourceMethods);
|
|
103
|
+
app.component('m-fields-data-source-method-select', DataSourceMethodSelect);
|
|
104
|
+
app.component('m-fields-data-source-field-select', DataSourceFieldSelect);
|
|
90
105
|
},
|
|
91
106
|
};
|
package/src/initService.ts
CHANGED
|
@@ -7,9 +7,14 @@ import type { CodeBlockContent, DataSourceSchema, Id, MApp, MNode, MPage } from
|
|
|
7
7
|
import { getNodes } from '@tmagic/utils';
|
|
8
8
|
|
|
9
9
|
import type { Target } from './services/dep';
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
createCodeBlockTarget,
|
|
12
|
+
createDataSourceCondTarget,
|
|
13
|
+
createDataSourceMethodTarget,
|
|
14
|
+
createDataSourceTarget,
|
|
15
|
+
} from './utils/dep';
|
|
11
16
|
import editorProps from './editorProps';
|
|
12
|
-
import
|
|
17
|
+
import { DepTargetType, Services } from './type';
|
|
13
18
|
|
|
14
19
|
export declare type LooseRequired<T> = {
|
|
15
20
|
[P in string & keyof T]: T[P];
|
|
@@ -26,6 +31,7 @@ export const initServiceState = (
|
|
|
26
31
|
uiService,
|
|
27
32
|
codeBlockService,
|
|
28
33
|
keybindingService,
|
|
34
|
+
dataSourceService,
|
|
29
35
|
}: Services,
|
|
30
36
|
) => {
|
|
31
37
|
// 初始值变化,重新设置节点信息
|
|
@@ -47,6 +53,14 @@ export const initServiceState = (
|
|
|
47
53
|
},
|
|
48
54
|
);
|
|
49
55
|
|
|
56
|
+
watch(
|
|
57
|
+
() => props.datasourceList,
|
|
58
|
+
(datasourceList) => dataSourceService.set('datasourceTypeList', datasourceList),
|
|
59
|
+
{
|
|
60
|
+
immediate: true,
|
|
61
|
+
},
|
|
62
|
+
);
|
|
63
|
+
|
|
50
64
|
watch(
|
|
51
65
|
() => props.propsConfigs,
|
|
52
66
|
(configs) => propsService.setPropsConfigs(configs),
|
|
@@ -82,6 +96,30 @@ export const initServiceState = (
|
|
|
82
96
|
},
|
|
83
97
|
);
|
|
84
98
|
|
|
99
|
+
watch(
|
|
100
|
+
() => props.datasourceConfigs,
|
|
101
|
+
(configs) => {
|
|
102
|
+
Object.entries(configs).forEach(([key, value]) => {
|
|
103
|
+
dataSourceService.setFormConfig(key, value);
|
|
104
|
+
});
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
immediate: true,
|
|
108
|
+
},
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
watch(
|
|
112
|
+
() => props.datasourceValues,
|
|
113
|
+
(values) => {
|
|
114
|
+
Object.entries(values).forEach(([key, value]) => {
|
|
115
|
+
dataSourceService.setFormValue(key, value);
|
|
116
|
+
});
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
immediate: true,
|
|
120
|
+
},
|
|
121
|
+
);
|
|
122
|
+
|
|
85
123
|
watch(
|
|
86
124
|
() => props.defaultSelected,
|
|
87
125
|
(defaultSelected) => defaultSelected && editorService.select(defaultSelected),
|
|
@@ -139,6 +177,7 @@ export const initServiceEvents = (
|
|
|
139
177
|
|
|
140
178
|
if (app.dsl) {
|
|
141
179
|
app.dsl.dataSourceDeps = root.dataSourceDeps;
|
|
180
|
+
app.dsl.dataSourceCondDeps = root.dataSourceCondDeps;
|
|
142
181
|
app.dsl.dataSources = root.dataSources;
|
|
143
182
|
}
|
|
144
183
|
|
|
@@ -159,23 +198,34 @@ export const initServiceEvents = (
|
|
|
159
198
|
};
|
|
160
199
|
|
|
161
200
|
const targetAddHandler = (target: Target) => {
|
|
162
|
-
if (target.type !== 'data-source') return;
|
|
163
|
-
|
|
164
201
|
const root = editorService.get('root');
|
|
165
202
|
if (!root) return;
|
|
166
203
|
|
|
167
|
-
if (
|
|
168
|
-
root.dataSourceDeps
|
|
204
|
+
if (target.type === DepTargetType.DATA_SOURCE) {
|
|
205
|
+
if (!root.dataSourceDeps) {
|
|
206
|
+
root.dataSourceDeps = {};
|
|
207
|
+
}
|
|
208
|
+
root.dataSourceDeps[target.id] = target.deps;
|
|
169
209
|
}
|
|
170
210
|
|
|
171
|
-
|
|
211
|
+
if (target.type === DepTargetType.DATA_SOURCE_COND) {
|
|
212
|
+
if (!root.dataSourceCondDeps) {
|
|
213
|
+
root.dataSourceCondDeps = {};
|
|
214
|
+
}
|
|
215
|
+
root.dataSourceCondDeps[target.id] = target.deps;
|
|
216
|
+
}
|
|
172
217
|
};
|
|
173
218
|
|
|
174
219
|
const targetRemoveHandler = (id: string | number) => {
|
|
175
220
|
const root = editorService.get('root');
|
|
176
|
-
if (!root?.dataSourceDeps) return;
|
|
177
221
|
|
|
178
|
-
|
|
222
|
+
if (root?.dataSourceDeps) {
|
|
223
|
+
delete root.dataSourceDeps[id];
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (root?.dataSourceCondDeps) {
|
|
227
|
+
delete root.dataSourceCondDeps[id];
|
|
228
|
+
}
|
|
179
229
|
};
|
|
180
230
|
|
|
181
231
|
const depUpdateHandler = (node: MNode) => {
|
|
@@ -191,6 +241,12 @@ export const initServiceEvents = (
|
|
|
191
241
|
depService.on('dep-update', depUpdateHandler);
|
|
192
242
|
depService.on('collected', collectedHandler);
|
|
193
243
|
|
|
244
|
+
const initDataSourceDepTarget = (ds: DataSourceSchema) => {
|
|
245
|
+
depService.addTarget(createDataSourceTarget(ds.id));
|
|
246
|
+
depService.addTarget(createDataSourceMethodTarget(ds.id));
|
|
247
|
+
depService.addTarget(createDataSourceCondTarget(ds.id));
|
|
248
|
+
};
|
|
249
|
+
|
|
194
250
|
const rootChangeHandler = async (value: MApp, preValue?: MApp | null) => {
|
|
195
251
|
const nodeId = editorService.get('node')?.id || props.defaultSelected;
|
|
196
252
|
let node;
|
|
@@ -218,14 +274,14 @@ export const initServiceEvents = (
|
|
|
218
274
|
codeBlockService.setCodeDsl(value.codeBlocks);
|
|
219
275
|
dataSourceService.set('dataSources', value.dataSources);
|
|
220
276
|
|
|
221
|
-
depService.removeTargets(
|
|
277
|
+
depService.removeTargets(DepTargetType.CODE_BLOCK);
|
|
222
278
|
|
|
223
279
|
Object.entries(value.codeBlocks).forEach(([id, code]) => {
|
|
224
280
|
depService.addTarget(createCodeBlockTarget(id, code));
|
|
225
281
|
});
|
|
226
282
|
|
|
227
283
|
value.dataSources.forEach((ds) => {
|
|
228
|
-
|
|
284
|
+
initDataSourceDepTarget(ds);
|
|
229
285
|
});
|
|
230
286
|
|
|
231
287
|
if (value && Array.isArray(value.items)) {
|
|
@@ -236,18 +292,22 @@ export const initServiceEvents = (
|
|
|
236
292
|
}
|
|
237
293
|
};
|
|
238
294
|
|
|
295
|
+
// 新增节点,收集依赖
|
|
239
296
|
const nodeAddHandler = (nodes: MNode[]) => {
|
|
240
297
|
depService.collect(nodes);
|
|
241
298
|
};
|
|
242
299
|
|
|
300
|
+
// 节点更新,收集依赖
|
|
243
301
|
const nodeUpdateHandler = (nodes: MNode[]) => {
|
|
244
302
|
depService.collect(nodes);
|
|
245
303
|
};
|
|
246
304
|
|
|
305
|
+
// 节点删除,清除对齐的依赖收集
|
|
247
306
|
const nodeRemoveHandler = (nodes: MNode[]) => {
|
|
248
307
|
depService.clear(nodes);
|
|
249
308
|
};
|
|
250
309
|
|
|
310
|
+
// 由于历史记录变化是更新整个page,所以历史记录变化时,需要重新收集依赖
|
|
251
311
|
const historyChangeHandler = (page: MPage) => {
|
|
252
312
|
depService.collect([page], true);
|
|
253
313
|
};
|
|
@@ -275,17 +335,14 @@ export const initServiceEvents = (
|
|
|
275
335
|
codeBlockService.on('remove', codeBlockRemoveHandler);
|
|
276
336
|
|
|
277
337
|
const dataSourceAddHandler = (config: DataSourceSchema) => {
|
|
278
|
-
|
|
338
|
+
initDataSourceDepTarget(config);
|
|
279
339
|
getApp()?.dataSourceManager?.addDataSource(config);
|
|
280
340
|
};
|
|
281
341
|
|
|
282
342
|
const dataSourceUpdateHandler = (config: DataSourceSchema) => {
|
|
283
|
-
if (config.title) {
|
|
284
|
-
depService.getTarget(config.id)!.name = config.title;
|
|
285
|
-
}
|
|
286
343
|
const root = editorService.get('root');
|
|
287
344
|
|
|
288
|
-
const targets = depService.getTargets(
|
|
345
|
+
const targets = depService.getTargets(DepTargetType.DATA_SOURCE);
|
|
289
346
|
|
|
290
347
|
const nodes = getNodes(Object.keys(targets[config.id].deps), root?.items);
|
|
291
348
|
|
|
@@ -1,26 +1,46 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
2
|
+
<div :class="`magic-code-editor`">
|
|
3
|
+
<Teleport to="body" :disabled="!fullScreen">
|
|
4
|
+
<div
|
|
5
|
+
:class="`magic-code-editor-wrapper${fullScreen ? ' full-screen' : ''}`"
|
|
6
|
+
:style="!fullScreen && height ? `height: ${height}` : '100%'"
|
|
7
|
+
>
|
|
8
|
+
<TMagicButton
|
|
9
|
+
class="magic-code-editor-full-screen-icon"
|
|
10
|
+
circle
|
|
11
|
+
size="small"
|
|
12
|
+
:icon="FullScreen"
|
|
13
|
+
@click="fullScreenHandler"
|
|
14
|
+
></TMagicButton>
|
|
15
|
+
<div ref="codeEditor" class="magic-code-editor-content"></div>
|
|
16
|
+
</div>
|
|
17
|
+
</Teleport>
|
|
18
|
+
</div>
|
|
3
19
|
</template>
|
|
4
20
|
|
|
5
21
|
<script lang="ts" setup>
|
|
6
22
|
import { onMounted, onUnmounted, ref, watch } from 'vue';
|
|
23
|
+
import { FullScreen } from '@element-plus/icons-vue';
|
|
7
24
|
import { throttle } from 'lodash-es';
|
|
8
25
|
import * as monaco from 'monaco-editor';
|
|
9
26
|
import serialize from 'serialize-javascript';
|
|
10
27
|
|
|
28
|
+
import { TMagicButton } from '@tmagic/design';
|
|
29
|
+
|
|
11
30
|
defineOptions({
|
|
12
31
|
name: 'MEditorCodeEditor',
|
|
13
32
|
});
|
|
14
33
|
|
|
15
34
|
const props = withDefaults(
|
|
16
35
|
defineProps<{
|
|
17
|
-
initValues?:
|
|
18
|
-
modifiedValues?:
|
|
36
|
+
initValues?: any;
|
|
37
|
+
modifiedValues?: any;
|
|
19
38
|
type?: 'diff';
|
|
20
39
|
language?: string;
|
|
21
40
|
options?: {
|
|
22
41
|
[key: string]: any;
|
|
23
42
|
};
|
|
43
|
+
height?: string;
|
|
24
44
|
autoSave?: boolean;
|
|
25
45
|
}>(),
|
|
26
46
|
{
|
|
@@ -37,10 +57,14 @@ const emit = defineEmits(['initd', 'save']);
|
|
|
37
57
|
const toString = (v: string | any, language: string): string => {
|
|
38
58
|
let value = '';
|
|
39
59
|
if (typeof v !== 'string') {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
60
|
+
if (props.language.toLocaleLowerCase() === 'json') {
|
|
61
|
+
value = JSON.stringify(v, null, 2);
|
|
62
|
+
} else {
|
|
63
|
+
value = serialize(v, {
|
|
64
|
+
space: 2,
|
|
65
|
+
unsafe: true,
|
|
66
|
+
}).replace(/"(\w+)":\s/g, '$1: ');
|
|
67
|
+
}
|
|
44
68
|
} else {
|
|
45
69
|
value = v;
|
|
46
70
|
}
|
|
@@ -81,7 +105,7 @@ const setEditorValue = (v: string | any, m: string | any) => {
|
|
|
81
105
|
};
|
|
82
106
|
|
|
83
107
|
const getEditorValue = () =>
|
|
84
|
-
props.type === 'diff' ? vsDiffEditor?.getModifiedEditor().getValue() : vsEditor?.getValue();
|
|
108
|
+
(props.type === 'diff' ? vsDiffEditor?.getModifiedEditor().getValue() : vsEditor?.getValue()) || '';
|
|
85
109
|
|
|
86
110
|
const init = async () => {
|
|
87
111
|
if (!codeEditor.value) return;
|
|
@@ -109,13 +133,19 @@ const init = async () => {
|
|
|
109
133
|
if (e.keyCode === 83 && (navigator.platform.match('Mac') ? e.metaKey : e.ctrlKey)) {
|
|
110
134
|
e.preventDefault();
|
|
111
135
|
e.stopPropagation();
|
|
112
|
-
|
|
136
|
+
const newValue = getEditorValue();
|
|
137
|
+
values.value = newValue;
|
|
138
|
+
emit('save', newValue);
|
|
113
139
|
}
|
|
114
140
|
});
|
|
115
141
|
|
|
116
142
|
if (props.type !== 'diff' && props.autoSave) {
|
|
117
143
|
vsEditor?.onDidBlurEditorWidget(() => {
|
|
118
|
-
|
|
144
|
+
const newValue = getEditorValue();
|
|
145
|
+
if (values.value !== newValue) {
|
|
146
|
+
values.value = newValue;
|
|
147
|
+
emit('save', newValue);
|
|
148
|
+
}
|
|
119
149
|
});
|
|
120
150
|
}
|
|
121
151
|
|
|
@@ -145,12 +175,34 @@ onUnmounted(() => {
|
|
|
145
175
|
resizeObserver.disconnect();
|
|
146
176
|
});
|
|
147
177
|
|
|
178
|
+
const fullScreen = ref(false);
|
|
179
|
+
const fullScreenHandler = () => {
|
|
180
|
+
fullScreen.value = !fullScreen.value;
|
|
181
|
+
setTimeout(() => {
|
|
182
|
+
vsEditor?.focus();
|
|
183
|
+
vsEditor?.layout();
|
|
184
|
+
vsDiffEditor?.focus();
|
|
185
|
+
vsDiffEditor?.layout();
|
|
186
|
+
});
|
|
187
|
+
};
|
|
188
|
+
|
|
148
189
|
defineExpose({
|
|
190
|
+
values,
|
|
191
|
+
|
|
149
192
|
getEditor() {
|
|
150
193
|
return vsEditor || vsDiffEditor;
|
|
151
194
|
},
|
|
152
195
|
|
|
196
|
+
getVsEditor() {
|
|
197
|
+
return vsEditor;
|
|
198
|
+
},
|
|
199
|
+
|
|
200
|
+
getVsDiffEditor() {
|
|
201
|
+
return vsDiffEditor;
|
|
202
|
+
},
|
|
203
|
+
|
|
153
204
|
setEditorValue,
|
|
205
|
+
getEditorValue,
|
|
154
206
|
|
|
155
207
|
focus() {
|
|
156
208
|
vsEditor?.focus();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="m-editor">
|
|
2
|
+
<div class="m-editor" ref="content">
|
|
3
3
|
<slot name="header"></slot>
|
|
4
4
|
|
|
5
5
|
<slot name="nav"></slot>
|
|
@@ -67,6 +67,8 @@ const DEFAULT_RIGHT_COLUMN_WIDTH = 480;
|
|
|
67
67
|
const codeOptions = inject('codeOptions', {});
|
|
68
68
|
const { editorService, uiService } = inject<Services>('services') || {};
|
|
69
69
|
|
|
70
|
+
const content = ref<HTMLDivElement>();
|
|
71
|
+
|
|
70
72
|
const root = computed(() => editorService?.get('root'));
|
|
71
73
|
|
|
72
74
|
const pageLength = computed(() => editorService?.get('pageLength') || 0);
|
|
@@ -91,13 +93,15 @@ watch(
|
|
|
91
93
|
|
|
92
94
|
columnWidth.value.left = left;
|
|
93
95
|
|
|
96
|
+
const container = content.value || document.body;
|
|
97
|
+
|
|
94
98
|
if (length <= 0) {
|
|
95
99
|
columnWidth.value.right = undefined;
|
|
96
|
-
columnWidth.value.center =
|
|
100
|
+
columnWidth.value.center = container.clientWidth - left;
|
|
97
101
|
} else {
|
|
98
102
|
const right = columnWidth.value.right || RightColumnWidthCacheData || DEFAULT_RIGHT_COLUMN_WIDTH;
|
|
99
103
|
columnWidth.value.right = right;
|
|
100
|
-
columnWidth.value.center =
|
|
104
|
+
columnWidth.value.center = container.clientWidth - left - right;
|
|
101
105
|
}
|
|
102
106
|
|
|
103
107
|
uiService?.set('columnWidth', columnWidth.value as GetColumnWidth);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="m-editor-props-panel" v-
|
|
2
|
+
<div class="m-editor-props-panel" v-show="nodes.length === 1">
|
|
3
3
|
<slot name="props-panel-header"></slot>
|
|
4
4
|
<MForm
|
|
5
5
|
ref="configForm"
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
:size="propsPanelSize"
|
|
9
9
|
:init-values="values"
|
|
10
10
|
:config="curFormConfig"
|
|
11
|
+
:extend-state="extendState"
|
|
11
12
|
@change="submit"
|
|
12
13
|
></MForm>
|
|
13
14
|
</div>
|
|
@@ -17,7 +18,7 @@
|
|
|
17
18
|
import { computed, getCurrentInstance, inject, onMounted, onUnmounted, ref, watchEffect } from 'vue';
|
|
18
19
|
|
|
19
20
|
import { tMagicMessage } from '@tmagic/design';
|
|
20
|
-
import type { FormValue } from '@tmagic/form';
|
|
21
|
+
import type { FormState, FormValue } from '@tmagic/form';
|
|
21
22
|
import { MForm } from '@tmagic/form';
|
|
22
23
|
|
|
23
24
|
import type { Services } from '@editor/type';
|
|
@@ -26,6 +27,10 @@ defineOptions({
|
|
|
26
27
|
name: 'MEditorPropsPanel',
|
|
27
28
|
});
|
|
28
29
|
|
|
30
|
+
defineProps<{
|
|
31
|
+
extendState?: (state: FormState) => Record<string, any> | Promise<Record<string, any>>;
|
|
32
|
+
}>();
|
|
33
|
+
|
|
29
34
|
const emit = defineEmits(['mounted']);
|
|
30
35
|
|
|
31
36
|
const internalInstance = getCurrentInstance();
|
|
@@ -78,5 +83,5 @@ const submit = async () => {
|
|
|
78
83
|
}
|
|
79
84
|
};
|
|
80
85
|
|
|
81
|
-
defineExpose({ submit });
|
|
86
|
+
defineExpose({ configForm, submit });
|
|
82
87
|
</script>
|
|
@@ -18,11 +18,9 @@
|
|
|
18
18
|
@drag="dragHandler"
|
|
19
19
|
>
|
|
20
20
|
<slot name="component-list-item" :component="item">
|
|
21
|
-
<MIcon :icon="item.icon"></MIcon>
|
|
21
|
+
<MIcon :title="item.text" :icon="item.icon"></MIcon>
|
|
22
22
|
|
|
23
|
-
<
|
|
24
|
-
<span>{{ item.text }}</span>
|
|
25
|
-
</TMagicTooltip>
|
|
23
|
+
<span :title="item.text">{{ item.text }}</span>
|
|
26
24
|
</slot>
|
|
27
25
|
</div>
|
|
28
26
|
</TMagicCollapseItem>
|
|
@@ -36,7 +34,7 @@ import { computed, inject, ref } from 'vue';
|
|
|
36
34
|
import { Grid } from '@element-plus/icons-vue';
|
|
37
35
|
import serialize from 'serialize-javascript';
|
|
38
36
|
|
|
39
|
-
import { TMagicCollapse, TMagicCollapseItem, TMagicScrollbar
|
|
37
|
+
import { TMagicCollapse, TMagicCollapseItem, TMagicScrollbar } from '@tmagic/design';
|
|
40
38
|
import { removeClassNameByClassName } from '@tmagic/utils';
|
|
41
39
|
|
|
42
40
|
import MIcon from '@editor/components/Icon.vue';
|
|
@@ -83,14 +81,13 @@ const appendComponent = ({ text, type, data = {} }: ComponentItem): void => {
|
|
|
83
81
|
|
|
84
82
|
const dragstartHandler = ({ text, type, data = {} }: ComponentItem, e: DragEvent) => {
|
|
85
83
|
if (e.dataTransfer) {
|
|
86
|
-
e.dataTransfer.effectAllowed = 'move';
|
|
87
84
|
e.dataTransfer.setData(
|
|
88
|
-
'
|
|
85
|
+
'text/json',
|
|
89
86
|
serialize({
|
|
90
87
|
name: text,
|
|
91
88
|
type,
|
|
92
89
|
...data,
|
|
93
|
-
})
|
|
90
|
+
}),
|
|
94
91
|
);
|
|
95
92
|
}
|
|
96
93
|
};
|
|
@@ -121,6 +118,6 @@ const dragHandler = (e: DragEvent) => {
|
|
|
121
118
|
|
|
122
119
|
if (timeout || !stage.value) return;
|
|
123
120
|
|
|
124
|
-
timeout = stage.value.
|
|
121
|
+
timeout = stage.value.delayedMarkContainer(e);
|
|
125
122
|
};
|
|
126
123
|
</script>
|
|
@@ -4,12 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
<script lang="ts" setup>
|
|
6
6
|
import { computed, inject, markRaw, ref } from 'vue';
|
|
7
|
-
import {
|
|
7
|
+
import { Files, Plus } from '@element-plus/icons-vue';
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { isPage } from '@tmagic/utils';
|
|
10
10
|
|
|
11
11
|
import ContentMenu from '@editor/components/ContentMenu.vue';
|
|
12
|
+
import FolderMinusIcon from '@editor/icons/FolderMinusIcon.vue';
|
|
12
13
|
import type { ComponentGroup, MenuButton, MenuComponent, Services } from '@editor/type';
|
|
14
|
+
import { useCopyMenu, useDeleteMenu, useMoveToMenu, usePasteMenu } from '@editor/utils/content-menu';
|
|
13
15
|
|
|
14
16
|
defineOptions({
|
|
15
17
|
name: 'MEditorLayerMenu',
|
|
@@ -19,12 +21,14 @@ const props = defineProps<{
|
|
|
19
21
|
layerContentMenu: (MenuButton | MenuComponent)[];
|
|
20
22
|
}>();
|
|
21
23
|
|
|
24
|
+
const emit = defineEmits<{
|
|
25
|
+
'collapse-all': [];
|
|
26
|
+
}>();
|
|
27
|
+
|
|
22
28
|
const services = inject<Services>('services');
|
|
23
29
|
const menu = ref<InstanceType<typeof ContentMenu>>();
|
|
24
30
|
const node = computed(() => services?.editorService.get('node'));
|
|
25
31
|
const nodes = computed(() => services?.editorService.get('nodes'));
|
|
26
|
-
const isRoot = computed(() => node.value?.type === NodeType.ROOT);
|
|
27
|
-
const isPage = computed(() => node.value?.type === NodeType.PAGE);
|
|
28
32
|
const componentList = computed(() => services?.componentListService.getList() || []);
|
|
29
33
|
|
|
30
34
|
const createMenuItems = (group: ComponentGroup): MenuButton[] =>
|
|
@@ -81,29 +85,24 @@ const getSubMenuData = computed<MenuButton[]>(() => {
|
|
|
81
85
|
const menuData = computed<(MenuButton | MenuComponent)[]>(() => [
|
|
82
86
|
{
|
|
83
87
|
type: 'button',
|
|
84
|
-
text: '
|
|
85
|
-
icon:
|
|
86
|
-
display: () => node.value
|
|
87
|
-
items: getSubMenuData.value,
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
type: 'button',
|
|
91
|
-
text: '复制',
|
|
92
|
-
icon: markRaw(CopyDocument),
|
|
93
|
-
display: () => !isRoot.value,
|
|
88
|
+
text: '全部折叠',
|
|
89
|
+
icon: FolderMinusIcon,
|
|
90
|
+
display: () => isPage(node.value),
|
|
94
91
|
handler: () => {
|
|
95
|
-
|
|
92
|
+
emit('collapse-all');
|
|
96
93
|
},
|
|
97
94
|
},
|
|
98
95
|
{
|
|
99
96
|
type: 'button',
|
|
100
|
-
text: '
|
|
101
|
-
icon: markRaw(
|
|
102
|
-
display: () =>
|
|
103
|
-
|
|
104
|
-
node.value && services?.editorService.remove(nodes.value || []);
|
|
105
|
-
},
|
|
97
|
+
text: '新增',
|
|
98
|
+
icon: markRaw(Plus),
|
|
99
|
+
display: () => node.value?.items && nodes.value?.length === 1,
|
|
100
|
+
items: getSubMenuData.value,
|
|
106
101
|
},
|
|
102
|
+
useCopyMenu(),
|
|
103
|
+
usePasteMenu(),
|
|
104
|
+
useDeleteMenu(),
|
|
105
|
+
useMoveToMenu(services),
|
|
107
106
|
...props.layerContentMenu,
|
|
108
107
|
]);
|
|
109
108
|
|