@tmagic/editor 1.3.16 → 1.4.0-beta.2
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 +25 -9
- package/dist/tmagic-editor.js +1048 -632
- package/dist/tmagic-editor.umd.cjs +1065 -647
- package/package.json +23 -21
- package/src/components/CodeBlockEditor.vue +82 -59
- package/src/components/FloatingBox.vue +71 -25
- package/src/components/SplitView.vue +46 -35
- package/src/fields/Code.vue +12 -10
- package/src/fields/CodeLink.vue +9 -9
- package/src/fields/CodeSelect.vue +7 -5
- package/src/fields/CodeSelectCol.vue +1 -1
- package/src/fields/DataSourceFieldSelect.vue +118 -27
- package/src/fields/DataSourceFields.vue +10 -3
- package/src/fields/DataSourceInput.vue +7 -7
- package/src/fields/DataSourceMethodSelect.vue +1 -1
- package/src/fields/DataSourceMethods.vue +3 -3
- package/src/fields/DataSourceMocks.vue +3 -3
- package/src/fields/DataSourceSelect.vue +6 -18
- package/src/fields/EventSelect.vue +1 -1
- package/src/fields/KeyValue.vue +8 -8
- package/src/fields/PageFragmentSelect.vue +1 -1
- package/src/fields/UISelect.vue +5 -5
- package/src/hooks/index.ts +2 -0
- package/src/hooks/use-code-block-edit.ts +1 -2
- package/src/hooks/use-editor-content-height.ts +20 -0
- package/src/hooks/use-float-box.ts +8 -8
- package/src/hooks/use-window-rect.ts +20 -0
- package/src/index.ts +2 -2
- package/src/layouts/Framework.vue +33 -34
- package/src/layouts/NavMenu.vue +21 -2
- package/src/layouts/PropsPanel.vue +35 -0
- package/src/layouts/sidebar/Sidebar.vue +18 -8
- package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +0 -1
- package/src/layouts/workspace/viewer/NodeListMenu.vue +1 -0
- package/src/services/BaseService.ts +5 -2
- package/src/services/codeBlock.ts +14 -8
- package/src/services/dataSource.ts +39 -26
- package/src/services/editor.ts +46 -25
- package/src/services/events.ts +4 -4
- package/src/services/props.ts +44 -35
- package/src/services/stageOverlay.ts +16 -9
- package/src/services/storage.ts +14 -8
- package/src/services/ui.ts +26 -19
- package/src/theme/code-block.scss +0 -5
- package/src/theme/code-editor.scss +6 -0
- package/src/theme/floating-box.scss +4 -2
- package/src/theme/props-panel.scss +14 -0
- package/src/theme/sidebar.scss +6 -3
- package/src/type.ts +87 -37
- package/src/utils/operator.ts +37 -39
- package/src/utils/props.ts +174 -37
- package/types/components/CodeBlockEditor.vue.d.ts +46 -25
- package/types/components/CodeParams.vue.d.ts +5 -5
- package/types/components/ContentMenu.vue.d.ts +12 -12
- package/types/components/FloatingBox.vue.d.ts +42 -55
- package/types/components/Icon.vue.d.ts +3 -3
- package/types/components/Resizer.vue.d.ts +3 -3
- package/types/components/ScrollBar.vue.d.ts +3 -3
- package/types/components/ScrollViewer.vue.d.ts +12 -12
- package/types/components/SearchInput.vue.d.ts +1 -1
- package/types/components/SplitView.vue.d.ts +13 -11
- package/types/components/ToolButton.vue.d.ts +13 -13
- package/types/components/Tree.vue.d.ts +24 -14
- package/types/components/TreeNode.vue.d.ts +22 -12
- package/types/fields/Code.vue.d.ts +14 -14
- package/types/fields/CodeLink.vue.d.ts +6 -10
- package/types/fields/CodeSelect.vue.d.ts +14 -14
- package/types/fields/CodeSelectCol.vue.d.ts +11 -11
- package/types/fields/DataSourceFieldSelect.vue.d.ts +11 -11
- package/types/fields/DataSourceFields.vue.d.ts +11 -11
- package/types/fields/DataSourceInput.vue.d.ts +14 -18
- package/types/fields/DataSourceMethodSelect.vue.d.ts +11 -11
- package/types/fields/DataSourceMethods.vue.d.ts +11 -11
- package/types/fields/DataSourceMocks.vue.d.ts +11 -11
- package/types/fields/DataSourceSelect.vue.d.ts +13 -26
- package/types/fields/EventSelect.vue.d.ts +3 -3
- package/types/fields/KeyValue.vue.d.ts +14 -18
- package/types/fields/PageFragmentSelect.vue.d.ts +11 -11
- package/types/fields/UISelect.vue.d.ts +8 -4
- package/types/hooks/index.d.ts +2 -0
- package/types/hooks/use-code-block-edit.d.ts +66 -90
- package/types/hooks/use-data-source-method.d.ts +66 -90
- package/types/hooks/use-editor-content-height.d.ts +3 -0
- package/types/hooks/use-node-status.d.ts +6 -1
- package/types/hooks/use-window-rect.d.ts +6 -0
- package/types/icons/AppManageIcon.vue.d.ts +1 -1
- package/types/icons/CenterIcon.vue.d.ts +1 -1
- package/types/icons/CodeIcon.vue.d.ts +1 -1
- package/types/icons/FolderMinusIcon.vue.d.ts +1 -1
- package/types/icons/PinIcon.vue.d.ts +1 -1
- package/types/icons/PinnedIcon.vue.d.ts +1 -1
- package/types/layouts/AddPageBox.vue.d.ts +3 -3
- package/types/layouts/CodeEditor.vue.d.ts +12 -12
- package/types/layouts/Framework.vue.d.ts +9 -9
- package/types/layouts/NavMenu.vue.d.ts +11 -11
- package/types/layouts/PropsPanel.vue.d.ts +193 -243
- package/types/layouts/page-bar/AddButton.vue.d.ts +3 -3
- package/types/layouts/page-bar/PageBar.vue.d.ts +8 -8
- package/types/layouts/page-bar/PageBarScrollContainer.vue.d.ts +8 -8
- package/types/layouts/page-bar/SwitchTypeButton.vue.d.ts +3 -3
- package/types/layouts/sidebar/ComponentListPanel.vue.d.ts +1 -1
- package/types/layouts/sidebar/Sidebar.vue.d.ts +13 -13
- package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +10 -10
- package/types/layouts/sidebar/code-block/CodeBlockListPanel.vue.d.ts +9 -9
- package/types/layouts/sidebar/data-source/DataSourceConfigPanel.vue.d.ts +3 -3
- package/types/layouts/sidebar/data-source/DataSourceList.vue.d.ts +3 -3
- package/types/layouts/sidebar/data-source/DataSourceListPanel.vue.d.ts +9 -9
- package/types/layouts/sidebar/layer/LayerMenu.vue.d.ts +11 -11
- package/types/layouts/sidebar/layer/LayerNodeTool.vue.d.ts +3 -3
- package/types/layouts/sidebar/layer/LayerPanel.vue.d.ts +9 -9
- package/types/layouts/sidebar/layer/use-click.d.ts +42 -76
- package/types/layouts/sidebar/layer/use-node-status.d.ts +6 -1
- package/types/layouts/workspace/Breadcrumb.vue.d.ts +1 -1
- package/types/layouts/workspace/Workspace.vue.d.ts +12 -12
- package/types/layouts/workspace/viewer/NodeListMenu.vue.d.ts +1 -1
- package/types/layouts/workspace/viewer/Stage.vue.d.ts +11 -11
- package/types/layouts/workspace/viewer/StageOverlay.vue.d.ts +1 -1
- package/types/layouts/workspace/viewer/ViewerMenu.vue.d.ts +12 -12
- package/types/services/BaseService.d.ts +5 -2
- package/types/services/codeBlock.d.ts +8 -0
- package/types/services/dataSource.d.ts +9 -2
- package/types/services/editor.d.ts +8 -1
- package/types/services/props.d.ts +15 -22
- package/types/services/stageOverlay.d.ts +9 -2
- package/types/services/storage.d.ts +8 -0
- package/types/services/ui.d.ts +20 -8
- package/types/type.d.ts +56 -32
- package/types/utils/operator.d.ts +1 -1
- package/types/utils/props.d.ts +2 -13
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
:min-left="65"
|
|
25
25
|
:min-right="20"
|
|
26
26
|
:min-center="100"
|
|
27
|
+
:width="frameworkRect?.width || 0"
|
|
27
28
|
@change="columnWidthChange"
|
|
28
29
|
>
|
|
29
30
|
<template #left>
|
|
@@ -57,7 +58,7 @@
|
|
|
57
58
|
</template>
|
|
58
59
|
|
|
59
60
|
<script lang="ts" setup>
|
|
60
|
-
import { computed, inject, ref, watch } from 'vue';
|
|
61
|
+
import { computed, inject, onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
|
61
62
|
|
|
62
63
|
import { TMagicScrollbar } from '@tmagic/design';
|
|
63
64
|
|
|
@@ -101,40 +102,15 @@ const RIGHT_COLUMN_WIDTH_STORAGE_KEY = '$MagicEditorRightColumnWidthData';
|
|
|
101
102
|
const getLeftColumnWidthCacheData = () =>
|
|
102
103
|
Number(globalThis.localStorage.getItem(LEFT_COLUMN_WIDTH_STORAGE_KEY)) || DEFAULT_LEFT_COLUMN_WIDTH;
|
|
103
104
|
|
|
104
|
-
const leftColumnWidthCacheData = getLeftColumnWidthCacheData();
|
|
105
|
-
const RightColumnWidthCacheData =
|
|
106
|
-
Number(globalThis.localStorage.getItem(RIGHT_COLUMN_WIDTH_STORAGE_KEY)) || DEFAULT_RIGHT_COLUMN_WIDTH;
|
|
107
|
-
|
|
108
105
|
const columnWidth = ref<Partial<GetColumnWidth>>({
|
|
109
|
-
left:
|
|
106
|
+
left: getLeftColumnWidthCacheData(),
|
|
110
107
|
center: 0,
|
|
111
|
-
right:
|
|
108
|
+
right: Number(globalThis.localStorage.getItem(RIGHT_COLUMN_WIDTH_STORAGE_KEY)) || DEFAULT_RIGHT_COLUMN_WIDTH,
|
|
112
109
|
});
|
|
113
110
|
|
|
114
|
-
watch(
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
splitView.value?.updateWidth();
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
immediate: true,
|
|
121
|
-
},
|
|
122
|
-
);
|
|
123
|
-
|
|
124
|
-
watch(
|
|
125
|
-
() => columnWidth.value.right,
|
|
126
|
-
(right) => {
|
|
127
|
-
if (typeof right === 'undefined') return;
|
|
128
|
-
globalThis.localStorage.setItem(RIGHT_COLUMN_WIDTH_STORAGE_KEY, `${right}`);
|
|
129
|
-
},
|
|
130
|
-
);
|
|
131
|
-
|
|
132
|
-
watch(
|
|
133
|
-
() => columnWidth.value.left,
|
|
134
|
-
(left) => {
|
|
135
|
-
globalThis.localStorage.setItem(LEFT_COLUMN_WIDTH_STORAGE_KEY, `${left}`);
|
|
136
|
-
},
|
|
137
|
-
);
|
|
111
|
+
watch(pageLength, () => {
|
|
112
|
+
splitView.value?.updateWidth();
|
|
113
|
+
});
|
|
138
114
|
|
|
139
115
|
watch(
|
|
140
116
|
() => uiService?.get('hideSlideBar'),
|
|
@@ -144,12 +120,35 @@ watch(
|
|
|
144
120
|
);
|
|
145
121
|
|
|
146
122
|
const columnWidthChange = (columnW: GetColumnWidth) => {
|
|
147
|
-
columnWidth.value
|
|
148
|
-
|
|
149
|
-
|
|
123
|
+
columnWidth.value = columnW;
|
|
124
|
+
|
|
125
|
+
globalThis.localStorage.setItem(LEFT_COLUMN_WIDTH_STORAGE_KEY, `${columnW.left}`);
|
|
126
|
+
globalThis.localStorage.setItem(RIGHT_COLUMN_WIDTH_STORAGE_KEY, `${columnW.right}`);
|
|
150
127
|
uiService?.set('columnWidth', columnW);
|
|
151
128
|
};
|
|
152
129
|
|
|
130
|
+
const frameworkRect = computed(() => uiService?.get('frameworkRect'));
|
|
131
|
+
|
|
132
|
+
const resizerObserver = new ResizeObserver((entries) => {
|
|
133
|
+
const { contentRect } = entries[0];
|
|
134
|
+
uiService?.set('frameworkRect', {
|
|
135
|
+
width: contentRect.width,
|
|
136
|
+
height: contentRect.height,
|
|
137
|
+
left: contentRect.left,
|
|
138
|
+
top: contentRect.top,
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
onMounted(() => {
|
|
143
|
+
if (content.value) {
|
|
144
|
+
resizerObserver.observe(content.value);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
onBeforeUnmount(() => {
|
|
149
|
+
resizerObserver.disconnect();
|
|
150
|
+
});
|
|
151
|
+
|
|
153
152
|
const saveCode = (value: string) => {
|
|
154
153
|
try {
|
|
155
154
|
const parseDSL = getConfig('parseDSL');
|
package/src/layouts/NavMenu.vue
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="m-editor-nav-menu" :style="{ height: `${height}px` }">
|
|
2
|
+
<div class="m-editor-nav-menu" :style="{ height: `${height}px` }" ref="navMenu">
|
|
3
3
|
<div v-for="key in keys" :class="`menu-${key}`" :key="key" :style="`width: ${columnWidth?.[key]}px`">
|
|
4
4
|
<ToolButton :data="item" v-for="(item, index) in buttons[key]" :key="index"></ToolButton>
|
|
5
5
|
</div>
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
</template>
|
|
8
8
|
|
|
9
9
|
<script lang="ts" setup>
|
|
10
|
-
import { computed, inject, markRaw } from 'vue';
|
|
10
|
+
import { computed, inject, markRaw, onBeforeUnmount, onMounted, ref } from 'vue';
|
|
11
11
|
import { Back, Delete, FullScreen, Grid, Memo, Right, ScaleToOriginal, ZoomIn, ZoomOut } from '@element-plus/icons-vue';
|
|
12
12
|
|
|
13
13
|
import { NodeType } from '@tmagic/schema';
|
|
@@ -178,4 +178,23 @@ const buttons = computed(() => {
|
|
|
178
178
|
});
|
|
179
179
|
return data;
|
|
180
180
|
});
|
|
181
|
+
|
|
182
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
183
|
+
const rect = navMenu.value?.getBoundingClientRect();
|
|
184
|
+
if (rect) {
|
|
185
|
+
uiService?.set('navMenuRect', {
|
|
186
|
+
left: rect.left,
|
|
187
|
+
top: rect.top,
|
|
188
|
+
width: rect.width,
|
|
189
|
+
height: rect.height,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
const navMenu = ref<HTMLDivElement>();
|
|
194
|
+
onMounted(() => {
|
|
195
|
+
navMenu.value && resizeObserver.observe(navMenu.value);
|
|
196
|
+
});
|
|
197
|
+
onBeforeUnmount(() => {
|
|
198
|
+
resizeObserver.disconnect();
|
|
199
|
+
});
|
|
181
200
|
</script>
|
|
@@ -12,17 +12,42 @@
|
|
|
12
12
|
@change="submit"
|
|
13
13
|
@error="errorHandler"
|
|
14
14
|
></MForm>
|
|
15
|
+
|
|
16
|
+
<TMagicButton
|
|
17
|
+
class="m-editor-props-panel-src-icon"
|
|
18
|
+
circle
|
|
19
|
+
size="large"
|
|
20
|
+
title="源码"
|
|
21
|
+
:icon="DocumentIcon"
|
|
22
|
+
:type="showSrc ? 'primary' : ''"
|
|
23
|
+
@click="showSrc = !showSrc"
|
|
24
|
+
></TMagicButton>
|
|
25
|
+
|
|
26
|
+
<CodeEditor
|
|
27
|
+
v-if="showSrc"
|
|
28
|
+
:height="`${editorContentHeight}px`"
|
|
29
|
+
:init-values="values"
|
|
30
|
+
:options="codeOptions"
|
|
31
|
+
:parse="true"
|
|
32
|
+
@save="saveCode"
|
|
33
|
+
></CodeEditor>
|
|
15
34
|
</div>
|
|
16
35
|
</template>
|
|
17
36
|
|
|
18
37
|
<script lang="ts" setup>
|
|
19
38
|
import { computed, getCurrentInstance, inject, onBeforeUnmount, onMounted, ref, watchEffect } from 'vue';
|
|
39
|
+
import { Document as DocumentIcon } from '@element-plus/icons-vue';
|
|
20
40
|
|
|
41
|
+
import { TMagicButton } from '@tmagic/design';
|
|
21
42
|
import type { FormState, FormValue } from '@tmagic/form';
|
|
22
43
|
import { MForm } from '@tmagic/form';
|
|
44
|
+
import type { MNode } from '@tmagic/schema';
|
|
23
45
|
|
|
46
|
+
import { useEditorContentHeight } from '@editor/hooks/use-editor-content-height';
|
|
24
47
|
import type { PropsPanelSlots, Services } from '@editor/type';
|
|
25
48
|
|
|
49
|
+
import CodeEditor from './CodeEditor.vue';
|
|
50
|
+
|
|
26
51
|
defineSlots<PropsPanelSlots>();
|
|
27
52
|
|
|
28
53
|
defineOptions({
|
|
@@ -33,8 +58,12 @@ defineProps<{
|
|
|
33
58
|
extendState?: (state: FormState) => Record<string, any> | Promise<Record<string, any>>;
|
|
34
59
|
}>();
|
|
35
60
|
|
|
61
|
+
const codeOptions = inject('codeOptions', {});
|
|
62
|
+
|
|
36
63
|
const emit = defineEmits(['mounted', 'submit-error', 'form-error']);
|
|
37
64
|
|
|
65
|
+
const showSrc = ref(false);
|
|
66
|
+
|
|
38
67
|
const internalInstance = getCurrentInstance();
|
|
39
68
|
const values = ref<FormValue>({});
|
|
40
69
|
const configForm = ref<InstanceType<typeof MForm>>();
|
|
@@ -46,6 +75,8 @@ const nodes = computed(() => services?.editorService.get('nodes') || []);
|
|
|
46
75
|
const propsPanelSize = computed(() => services?.uiService.get('propsPanelSize') || 'small');
|
|
47
76
|
const stage = computed(() => services?.editorService.get('stage'));
|
|
48
77
|
|
|
78
|
+
const { height: editorContentHeight } = useEditorContentHeight();
|
|
79
|
+
|
|
49
80
|
const init = async () => {
|
|
50
81
|
if (!node.value) {
|
|
51
82
|
curFormConfig.value = [];
|
|
@@ -87,5 +118,9 @@ const errorHandler = (e: any) => {
|
|
|
87
118
|
emit('form-error', e);
|
|
88
119
|
};
|
|
89
120
|
|
|
121
|
+
const saveCode = (values: MNode) => {
|
|
122
|
+
services?.editorService.update(values);
|
|
123
|
+
};
|
|
124
|
+
|
|
90
125
|
defineExpose({ configForm, submit });
|
|
91
126
|
</script>
|
|
@@ -111,6 +111,8 @@
|
|
|
111
111
|
:key="config.$key ?? index"
|
|
112
112
|
v-if="floatBoxStates[config.$key]?.status"
|
|
113
113
|
v-model:visible="floatBoxStates[config.$key].status"
|
|
114
|
+
:width="columnLeftWitch"
|
|
115
|
+
:height="600"
|
|
114
116
|
:title="config.text"
|
|
115
117
|
:position="{
|
|
116
118
|
left: floatBoxStates[config.$key].left,
|
|
@@ -139,14 +141,15 @@ import { Coin, EditPen, Goods, List } from '@element-plus/icons-vue';
|
|
|
139
141
|
import FloatingBox from '@editor/components/FloatingBox.vue';
|
|
140
142
|
import MIcon from '@editor/components/Icon.vue';
|
|
141
143
|
import { useFloatBox } from '@editor/hooks/use-float-box';
|
|
142
|
-
import
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
144
|
+
import {
|
|
145
|
+
ColumnLayout,
|
|
146
|
+
type MenuButton,
|
|
147
|
+
type MenuComponent,
|
|
148
|
+
type Services,
|
|
149
|
+
type SideBarData,
|
|
150
|
+
type SidebarSlots,
|
|
151
|
+
type SideComponent,
|
|
152
|
+
type SideItem,
|
|
150
153
|
} from '@editor/type';
|
|
151
154
|
|
|
152
155
|
import CodeBlockListPanel from './code-block/CodeBlockListPanel.vue';
|
|
@@ -173,6 +176,8 @@ const props = withDefaults(
|
|
|
173
176
|
|
|
174
177
|
const services = inject<Services>('services');
|
|
175
178
|
|
|
179
|
+
const columnLeftWitch = computed(() => services?.uiService.get('columnWidth')[ColumnLayout.LEFT] || 0);
|
|
180
|
+
|
|
176
181
|
const activeTabName = ref(props.data?.status);
|
|
177
182
|
|
|
178
183
|
const getItemConfig = (data: SideItem): SideComponent => {
|
|
@@ -204,6 +209,11 @@ const getItemConfig = (data: SideItem): SideComponent => {
|
|
|
204
209
|
text: '代码编辑',
|
|
205
210
|
component: CodeBlockListPanel,
|
|
206
211
|
slots: {},
|
|
212
|
+
boxComponentConfig: {
|
|
213
|
+
props: {
|
|
214
|
+
slideType: 'box',
|
|
215
|
+
},
|
|
216
|
+
},
|
|
207
217
|
},
|
|
208
218
|
'data-source': {
|
|
209
219
|
$key: 'data-source',
|
|
@@ -103,7 +103,7 @@ const doAsyncAction = async (
|
|
|
103
103
|
* 例如:
|
|
104
104
|
* Class EditorService extends BaseService {
|
|
105
105
|
* constructor() {
|
|
106
|
-
* super(['add']);
|
|
106
|
+
* super([ { name: 'add', isAsync: true },]);
|
|
107
107
|
* }
|
|
108
108
|
* add(value) { return result; }
|
|
109
109
|
* };
|
|
@@ -131,7 +131,7 @@ const doAsyncAction = async (
|
|
|
131
131
|
* 例如:
|
|
132
132
|
* Class EditorService extends BaseService {
|
|
133
133
|
* constructor() {
|
|
134
|
-
* super(['add']);
|
|
134
|
+
* super([ { name: 'add', isAsync: true },]);
|
|
135
135
|
* }
|
|
136
136
|
* add(value) { return result; }
|
|
137
137
|
* };
|
|
@@ -194,6 +194,9 @@ export default class extends EventEmitter {
|
|
|
194
194
|
});
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
+
/**
|
|
198
|
+
* @deprecated 请使用usePlugin代替
|
|
199
|
+
*/
|
|
197
200
|
public use(options: Record<string, Function>) {
|
|
198
201
|
Object.entries(options).forEach(([methodName, method]: [string, Function]) => {
|
|
199
202
|
if (typeof method === 'function') this.middleware[methodName].push(method);
|
|
@@ -18,16 +18,24 @@
|
|
|
18
18
|
|
|
19
19
|
import { reactive } from 'vue';
|
|
20
20
|
import { keys, pick } from 'lodash-es';
|
|
21
|
+
import type { Writable } from 'type-fest';
|
|
21
22
|
|
|
22
23
|
import type { ColumnConfig } from '@tmagic/form';
|
|
23
24
|
import type { CodeBlockContent, CodeBlockDSL, Id } from '@tmagic/schema';
|
|
24
25
|
|
|
25
|
-
import type { CodeState } from '@editor/type';
|
|
26
|
+
import type { AsyncHookPlugin, CodeState } from '@editor/type';
|
|
26
27
|
import { CODE_DRAFT_STORAGE_KEY } from '@editor/type';
|
|
27
28
|
import { getConfig } from '@editor/utils/config';
|
|
28
29
|
|
|
29
30
|
import BaseService from './BaseService';
|
|
30
31
|
|
|
32
|
+
const canUsePluginMethods = {
|
|
33
|
+
async: ['setCodeDslById', 'setEditStatus', 'setCombineIds', 'setUndeleteableList', 'deleteCodeDslByIds'] as const,
|
|
34
|
+
sync: [],
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
type AsyncMethodName = Writable<(typeof canUsePluginMethods)['async']>;
|
|
38
|
+
|
|
31
39
|
class CodeBlock extends BaseService {
|
|
32
40
|
private state = reactive<CodeState>({
|
|
33
41
|
codeDsl: null,
|
|
@@ -38,13 +46,7 @@ class CodeBlock extends BaseService {
|
|
|
38
46
|
});
|
|
39
47
|
|
|
40
48
|
constructor() {
|
|
41
|
-
super(
|
|
42
|
-
{ name: 'setCodeDslById', isAsync: true },
|
|
43
|
-
{ name: 'setEditStatus', isAsync: true },
|
|
44
|
-
{ name: 'setCombineIds', isAsync: true },
|
|
45
|
-
{ name: 'setUndeleteableList', isAsync: true },
|
|
46
|
-
{ name: 'deleteCodeDslByIds', isAsync: true },
|
|
47
|
-
]);
|
|
49
|
+
super(canUsePluginMethods.async.map((methodName) => ({ name: methodName, isAsync: true })));
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
/**
|
|
@@ -243,6 +245,10 @@ class CodeBlock extends BaseService {
|
|
|
243
245
|
this.removeAllListeners();
|
|
244
246
|
this.removeAllPlugins();
|
|
245
247
|
}
|
|
248
|
+
|
|
249
|
+
public usePlugin(options: AsyncHookPlugin<AsyncMethodName, CodeBlock>): void {
|
|
250
|
+
super.usePlugin(options);
|
|
251
|
+
}
|
|
246
252
|
}
|
|
247
253
|
|
|
248
254
|
export type CodeBlockService = CodeBlock;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { reactive } from 'vue';
|
|
2
2
|
import { cloneDeep } from 'lodash-es';
|
|
3
|
+
import { Writable } from 'type-fest';
|
|
3
4
|
|
|
4
5
|
import type { EventOption } from '@tmagic/core';
|
|
5
6
|
import type { FormConfig } from '@tmagic/form';
|
|
6
7
|
import type { DataSourceSchema } from '@tmagic/schema';
|
|
7
|
-
import { guid } from '@tmagic/utils';
|
|
8
|
+
import { guid, toLine } from '@tmagic/utils';
|
|
8
9
|
|
|
9
|
-
import type { DatasourceTypeOption } from '@editor/type';
|
|
10
|
+
import type { DatasourceTypeOption, SyncHookPlugin } from '@editor/type';
|
|
10
11
|
import { getFormConfig, getFormValue } from '@editor/utils/data-source';
|
|
11
12
|
|
|
12
13
|
import BaseService from './BaseService';
|
|
@@ -22,6 +23,27 @@ interface State {
|
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
type StateKey = keyof State;
|
|
26
|
+
|
|
27
|
+
const canUsePluginMethods = {
|
|
28
|
+
async: [],
|
|
29
|
+
sync: [
|
|
30
|
+
'getFormConfig',
|
|
31
|
+
'setFormConfig',
|
|
32
|
+
'getFormValue',
|
|
33
|
+
'setFormValue',
|
|
34
|
+
'getFormEvent',
|
|
35
|
+
'setFormEvent',
|
|
36
|
+
'getFormMethod',
|
|
37
|
+
'setFormMethod',
|
|
38
|
+
'add',
|
|
39
|
+
'update',
|
|
40
|
+
'remove',
|
|
41
|
+
'createId',
|
|
42
|
+
] as const,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
type SyncMethodName = Writable<(typeof canUsePluginMethods)['sync']>;
|
|
46
|
+
|
|
25
47
|
class DataSource extends BaseService {
|
|
26
48
|
private state = reactive<State>({
|
|
27
49
|
datasourceTypeList: [],
|
|
@@ -34,20 +56,7 @@ class DataSource extends BaseService {
|
|
|
34
56
|
});
|
|
35
57
|
|
|
36
58
|
constructor() {
|
|
37
|
-
super(
|
|
38
|
-
{ name: 'getFormConfig', isAsync: false },
|
|
39
|
-
{ name: 'setFormConfig', isAsync: false },
|
|
40
|
-
{ name: 'getFormValue', isAsync: false },
|
|
41
|
-
{ name: 'setFormValue', isAsync: false },
|
|
42
|
-
{ name: 'getFormEvent', isAsync: false },
|
|
43
|
-
{ name: 'setFormEvent', isAsync: false },
|
|
44
|
-
{ name: 'getFormMethod', isAsync: false },
|
|
45
|
-
{ name: 'setFormMethod', isAsync: false },
|
|
46
|
-
{ name: 'add', isAsync: false },
|
|
47
|
-
{ name: 'update', isAsync: false },
|
|
48
|
-
{ name: 'remove', isAsync: false },
|
|
49
|
-
{ name: 'createId', isAsync: false },
|
|
50
|
-
]);
|
|
59
|
+
super(canUsePluginMethods.sync.map((methodName) => ({ name: methodName, isAsync: false })));
|
|
51
60
|
}
|
|
52
61
|
|
|
53
62
|
public set<K extends StateKey, T extends State[K]>(name: K, value: T) {
|
|
@@ -59,35 +68,35 @@ class DataSource extends BaseService {
|
|
|
59
68
|
}
|
|
60
69
|
|
|
61
70
|
public getFormConfig(type = 'base') {
|
|
62
|
-
return getFormConfig(type, this.get('configs'));
|
|
71
|
+
return getFormConfig(toLine(type), this.get('configs'));
|
|
63
72
|
}
|
|
64
73
|
|
|
65
74
|
public setFormConfig(type: string, config: FormConfig) {
|
|
66
|
-
this.get('configs')[type] = config;
|
|
75
|
+
this.get('configs')[toLine(type)] = config;
|
|
67
76
|
}
|
|
68
77
|
|
|
69
78
|
public getFormValue(type = 'base') {
|
|
70
|
-
return getFormValue(type, this.get('values')[type]);
|
|
79
|
+
return getFormValue(toLine(type), this.get('values')[type]);
|
|
71
80
|
}
|
|
72
81
|
|
|
73
82
|
public setFormValue(type: string, value: Partial<DataSourceSchema>) {
|
|
74
|
-
this.get('values')[type] = value;
|
|
83
|
+
this.get('values')[toLine(type)] = value;
|
|
75
84
|
}
|
|
76
85
|
|
|
77
86
|
public getFormEvent(type = 'base') {
|
|
78
|
-
return this.get('events')[type] || [];
|
|
87
|
+
return this.get('events')[toLine(type)] || [];
|
|
79
88
|
}
|
|
80
89
|
|
|
81
90
|
public setFormEvent(type: string, value: EventOption[] = []) {
|
|
82
|
-
this.get('events')[type] = value;
|
|
91
|
+
this.get('events')[toLine(type)] = value;
|
|
83
92
|
}
|
|
84
93
|
|
|
85
94
|
public getFormMethod(type = 'base') {
|
|
86
|
-
return this.get('methods')[type] || [];
|
|
95
|
+
return this.get('methods')[toLine(type)] || [];
|
|
87
96
|
}
|
|
88
97
|
|
|
89
98
|
public setFormMethod(type: string, value: EventOption[] = []) {
|
|
90
|
-
this.get('methods')[type] = value;
|
|
99
|
+
this.get('methods')[toLine(type)] = value;
|
|
91
100
|
}
|
|
92
101
|
|
|
93
102
|
public add(config: DataSourceSchema) {
|
|
@@ -123,6 +132,10 @@ class DataSource extends BaseService {
|
|
|
123
132
|
this.emit('remove', id);
|
|
124
133
|
}
|
|
125
134
|
|
|
135
|
+
public createId(): string {
|
|
136
|
+
return `ds_${guid()}`;
|
|
137
|
+
}
|
|
138
|
+
|
|
126
139
|
public getDataSourceById(id: string) {
|
|
127
140
|
return this.get('dataSources').find((ds) => ds.id === id);
|
|
128
141
|
}
|
|
@@ -137,8 +150,8 @@ class DataSource extends BaseService {
|
|
|
137
150
|
this.removeAllPlugins();
|
|
138
151
|
}
|
|
139
152
|
|
|
140
|
-
|
|
141
|
-
|
|
153
|
+
public usePlugin(options: SyncHookPlugin<SyncMethodName, DataSource>): void {
|
|
154
|
+
super.usePlugin(options);
|
|
142
155
|
}
|
|
143
156
|
}
|
|
144
157
|
|
package/src/services/editor.ts
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
import { reactive, toRaw } from 'vue';
|
|
20
20
|
import { cloneDeep, get, isObject, mergeWith, uniq } from 'lodash-es';
|
|
21
|
+
import { Writable } from 'type-fest';
|
|
21
22
|
|
|
22
23
|
import { DepTargetType } from '@tmagic/dep';
|
|
23
24
|
import type { Id, MApp, MComponent, MContainer, MNode, MPage, MPageFragment } from '@tmagic/schema';
|
|
@@ -29,7 +30,15 @@ import propsService from '@editor/services//props';
|
|
|
29
30
|
import depService from '@editor/services/dep';
|
|
30
31
|
import historyService from '@editor/services/history';
|
|
31
32
|
import storageService, { Protocol } from '@editor/services/storage';
|
|
32
|
-
import type {
|
|
33
|
+
import type {
|
|
34
|
+
AddMNode,
|
|
35
|
+
AsyncHookPlugin,
|
|
36
|
+
EditorNodeInfo,
|
|
37
|
+
PastePosition,
|
|
38
|
+
StepValue,
|
|
39
|
+
StoreState,
|
|
40
|
+
StoreStateKey,
|
|
41
|
+
} from '@editor/type';
|
|
33
42
|
import { LayerOffset, Layout } from '@editor/type';
|
|
34
43
|
import {
|
|
35
44
|
change2Fixed,
|
|
@@ -46,6 +55,36 @@ import {
|
|
|
46
55
|
} from '@editor/utils/editor';
|
|
47
56
|
import { beforePaste, getAddParent } from '@editor/utils/operator';
|
|
48
57
|
|
|
58
|
+
const canUsePluginMethods = {
|
|
59
|
+
async: [
|
|
60
|
+
'getLayout',
|
|
61
|
+
'highlight',
|
|
62
|
+
'select',
|
|
63
|
+
'multiSelect',
|
|
64
|
+
'doAdd',
|
|
65
|
+
'add',
|
|
66
|
+
'doRemove',
|
|
67
|
+
'remove',
|
|
68
|
+
'doUpdate',
|
|
69
|
+
'update',
|
|
70
|
+
'sort',
|
|
71
|
+
'copy',
|
|
72
|
+
'paste',
|
|
73
|
+
'doPaste',
|
|
74
|
+
'doAlignCenter',
|
|
75
|
+
'alignCenter',
|
|
76
|
+
'moveLayer',
|
|
77
|
+
'moveToContainer',
|
|
78
|
+
'dragTo',
|
|
79
|
+
'undo',
|
|
80
|
+
'redo',
|
|
81
|
+
'move',
|
|
82
|
+
] as const,
|
|
83
|
+
sync: [],
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
type AsyncMethodName = Writable<(typeof canUsePluginMethods)['async']>;
|
|
87
|
+
|
|
49
88
|
class Editor extends BaseService {
|
|
50
89
|
public state: StoreState = reactive({
|
|
51
90
|
root: null,
|
|
@@ -65,29 +104,7 @@ class Editor extends BaseService {
|
|
|
65
104
|
|
|
66
105
|
constructor() {
|
|
67
106
|
super(
|
|
68
|
-
|
|
69
|
-
{ name: 'getLayout', isAsync: true },
|
|
70
|
-
{ name: 'select', isAsync: true },
|
|
71
|
-
{ name: 'doAdd', isAsync: true },
|
|
72
|
-
{ name: 'add', isAsync: true },
|
|
73
|
-
{ name: 'doRemove', isAsync: true },
|
|
74
|
-
{ name: 'remove', isAsync: true },
|
|
75
|
-
{ name: 'doUpdate', isAsync: true },
|
|
76
|
-
{ name: 'update', isAsync: true },
|
|
77
|
-
{ name: 'sort', isAsync: true },
|
|
78
|
-
{ name: 'copy', isAsync: true },
|
|
79
|
-
{ name: 'paste', isAsync: true },
|
|
80
|
-
{ name: 'doPaste', isAsync: true },
|
|
81
|
-
{ name: 'doAlignCenter', isAsync: true },
|
|
82
|
-
{ name: 'alignCenter', isAsync: true },
|
|
83
|
-
{ name: 'moveLayer', isAsync: true },
|
|
84
|
-
{ name: 'moveToContainer', isAsync: true },
|
|
85
|
-
{ name: 'move', isAsync: true },
|
|
86
|
-
{ name: 'undo', isAsync: true },
|
|
87
|
-
{ name: 'redo', isAsync: true },
|
|
88
|
-
{ name: 'highlight', isAsync: true },
|
|
89
|
-
{ name: 'dragTo', isAsync: true },
|
|
90
|
-
],
|
|
107
|
+
canUsePluginMethods.async.map((methodName) => ({ name: methodName, isAsync: true })),
|
|
91
108
|
// 需要注意循环依赖问题,如果函数间有相互调用的话,不能设置为串行调用
|
|
92
109
|
['select', 'update', 'moveLayer'],
|
|
93
110
|
);
|
|
@@ -696,7 +713,7 @@ class Editor extends BaseService {
|
|
|
696
713
|
|
|
697
714
|
public async doPaste(config: MNode[], position: PastePosition = {}): Promise<MNode[]> {
|
|
698
715
|
propsService.clearRelateId();
|
|
699
|
-
const pasteConfigs =
|
|
716
|
+
const pasteConfigs = beforePaste(position, cloneDeep(config));
|
|
700
717
|
return pasteConfigs;
|
|
701
718
|
}
|
|
702
719
|
|
|
@@ -985,6 +1002,10 @@ class Editor extends BaseService {
|
|
|
985
1002
|
this.get('modifiedNodeIds').clear();
|
|
986
1003
|
}
|
|
987
1004
|
|
|
1005
|
+
public usePlugin(options: AsyncHookPlugin<AsyncMethodName, Editor>): void {
|
|
1006
|
+
super.usePlugin(options);
|
|
1007
|
+
}
|
|
1008
|
+
|
|
988
1009
|
private addModifiedNodeId(id: Id) {
|
|
989
1010
|
if (!this.isHistoryStateChange) {
|
|
990
1011
|
this.get('modifiedNodeIds').set(id, id);
|
package/src/services/events.ts
CHANGED
|
@@ -55,11 +55,11 @@ class Events extends BaseService {
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
public setEvent(type: string, events: EventOption[]) {
|
|
58
|
-
eventMap[type] = [...DEFAULT_EVENTS, ...events];
|
|
58
|
+
eventMap[toLine(type)] = [...DEFAULT_EVENTS, ...events];
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
public getEvent(type: string): EventOption[] {
|
|
62
|
-
return cloneDeep(eventMap[type] || DEFAULT_EVENTS);
|
|
62
|
+
return cloneDeep(eventMap[toLine(type)] || DEFAULT_EVENTS);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
public setMethods(methods: Record<string, EventOption[]>) {
|
|
@@ -69,11 +69,11 @@ class Events extends BaseService {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
public setMethod(type: string, method: EventOption[]) {
|
|
72
|
-
methodMap[type] = [...DEFAULT_METHODS, ...method];
|
|
72
|
+
methodMap[toLine(type)] = [...DEFAULT_METHODS, ...method];
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
public getMethod(type: string) {
|
|
76
|
-
return cloneDeep(methodMap[type] || DEFAULT_METHODS);
|
|
76
|
+
return cloneDeep(methodMap[toLine(type)] || DEFAULT_METHODS);
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
public resetState() {
|