@tmagic/editor 1.5.7 → 1.5.8
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 +17 -0
- package/dist/tmagic-editor.js +463 -470
- package/dist/tmagic-editor.umd.cjs +471 -469
- package/package.json +7 -7
- package/src/components/CodeBlockEditor.vue +4 -4
- package/src/components/FloatingBox.vue +4 -4
- package/src/components/ToolButton.vue +6 -4
- package/src/components/TreeNode.vue +2 -2
- package/src/fields/CodeSelect.vue +6 -6
- package/src/fields/CodeSelectCol.vue +5 -4
- package/src/fields/CondOpSelect.vue +5 -4
- package/src/fields/DataSourceFieldSelect/FieldSelect.vue +6 -5
- package/src/fields/DataSourceFieldSelect/Index.vue +4 -3
- package/src/fields/DataSourceFields.vue +3 -3
- package/src/fields/DataSourceInput.vue +4 -4
- package/src/fields/DataSourceMethodSelect.vue +8 -9
- package/src/fields/DataSourceMocks.vue +3 -3
- package/src/fields/DataSourceSelect.vue +6 -5
- package/src/fields/DisplayConds.vue +4 -4
- package/src/fields/EventSelect.vue +17 -23
- package/src/fields/PageFragmentSelect.vue +6 -5
- package/src/fields/UISelect.vue +16 -19
- package/src/hooks/index.ts +1 -0
- package/src/hooks/use-code-block-edit.ts +5 -10
- package/src/hooks/use-data-source-edit.ts +6 -6
- package/src/hooks/use-editor-content-height.ts +5 -5
- package/src/hooks/use-float-box.ts +5 -5
- package/src/hooks/use-next-float-box-position.ts +9 -9
- package/src/hooks/use-services.ts +13 -0
- package/src/hooks/use-stage.ts +2 -6
- package/src/layouts/AddPageBox.vue +3 -7
- package/src/layouts/Framework.vue +27 -27
- package/src/layouts/NavMenu.vue +16 -16
- package/src/layouts/page-bar/AddButton.vue +4 -7
- package/src/layouts/page-bar/PageBar.vue +10 -10
- package/src/layouts/page-bar/PageBarScrollContainer.vue +7 -8
- package/src/layouts/page-bar/PageList.vue +6 -8
- package/src/layouts/props-panel/FormPanel.vue +6 -4
- package/src/layouts/props-panel/PropsPanel.vue +39 -49
- package/src/layouts/props-panel/use-style-panel.ts +35 -19
- package/src/layouts/sidebar/ComponentListPanel.vue +5 -5
- package/src/layouts/sidebar/Sidebar.vue +15 -9
- package/src/layouts/sidebar/code-block/CodeBlockList.vue +13 -18
- package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +4 -3
- package/src/layouts/sidebar/code-block/useContentMenu.ts +3 -3
- package/src/layouts/sidebar/data-source/DataSourceConfigPanel.vue +5 -5
- package/src/layouts/sidebar/data-source/DataSourceList.vue +13 -17
- package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +6 -12
- package/src/layouts/sidebar/data-source/useContentMenu.ts +3 -3
- package/src/layouts/sidebar/layer/LayerMenu.vue +11 -8
- package/src/layouts/sidebar/layer/LayerNodeTool.vue +2 -6
- package/src/layouts/sidebar/layer/LayerPanel.vue +6 -12
- package/src/layouts/sidebar/layer/use-click.ts +16 -15
- package/src/layouts/sidebar/layer/use-drag.ts +6 -6
- package/src/layouts/sidebar/layer/use-keybinding.ts +6 -8
- package/src/layouts/sidebar/layer/use-node-status.ts +16 -7
- package/src/layouts/workspace/Breadcrumb.vue +8 -9
- package/src/layouts/workspace/Workspace.vue +4 -10
- package/src/layouts/workspace/viewer/NodeListMenu.vue +9 -8
- package/src/layouts/workspace/viewer/Stage.vue +24 -24
- package/src/layouts/workspace/viewer/StageOverlay.vue +15 -16
- package/src/layouts/workspace/viewer/ViewerMenu.vue +15 -14
- package/src/services/dep.ts +23 -8
- package/src/services/ui.ts +6 -2
- package/src/theme/common/var.scss +1 -0
- package/src/theme/sidebar.scss +20 -1
- package/src/type.ts +3 -9
- package/src/utils/const.ts +11 -0
- package/src/utils/content-menu.ts +28 -30
- package/src/utils/idle-task.ts +11 -0
- package/src/utils/index.ts +1 -0
- package/types/index.d.ts +28 -10
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
</template>
|
|
51
51
|
|
|
52
52
|
<script lang="ts" setup>
|
|
53
|
-
import { computed
|
|
53
|
+
import { computed } from 'vue';
|
|
54
54
|
import { Delete } from '@element-plus/icons-vue';
|
|
55
55
|
import { has } from 'lodash-es';
|
|
56
56
|
|
|
@@ -68,7 +68,8 @@ import type {
|
|
|
68
68
|
import { MContainer as MFormContainer, MPanel } from '@tmagic/form';
|
|
69
69
|
import { DATA_SOURCE_FIELDS_CHANGE_EVENT_PREFIX, traverseNode } from '@tmagic/utils';
|
|
70
70
|
|
|
71
|
-
import
|
|
71
|
+
import { useServices } from '@editor/hooks/use-services';
|
|
72
|
+
import type { CodeSelectColConfig, DataSourceMethodSelectConfig, EventSelectConfig } from '@editor/type';
|
|
72
73
|
import { getCascaderOptionsFromFields } from '@editor/utils';
|
|
73
74
|
|
|
74
75
|
defineOptions({
|
|
@@ -81,12 +82,7 @@ const emit = defineEmits<{
|
|
|
81
82
|
change: [v: any, eventData?: ContainerChangeEventData];
|
|
82
83
|
}>();
|
|
83
84
|
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
const editorService = services?.editorService;
|
|
87
|
-
const dataSourceService = services?.dataSourceService;
|
|
88
|
-
const eventsService = services?.eventsService;
|
|
89
|
-
const codeBlockService = services?.codeBlockService;
|
|
85
|
+
const { editorService, dataSourceService, eventsService, codeBlockService } = useServices();
|
|
90
86
|
|
|
91
87
|
// 事件名称下拉框表单配置
|
|
92
88
|
const eventNameConfig = computed(() => {
|
|
@@ -108,13 +104,11 @@ const eventNameConfig = computed(() => {
|
|
|
108
104
|
options: (mForm: FormState, { formValue }: any) => {
|
|
109
105
|
let events: EventOption[] | CascaderOption[] = [];
|
|
110
106
|
|
|
111
|
-
if (!eventsService || !dataSourceService) return events;
|
|
112
|
-
|
|
113
107
|
if (props.config.src === 'component') {
|
|
114
108
|
events = eventsService.getEvent(formValue.type);
|
|
115
109
|
|
|
116
110
|
if (formValue.type === 'page-fragment-container' && formValue.pageFragmentId) {
|
|
117
|
-
const pageFragment = editorService
|
|
111
|
+
const pageFragment = editorService.get('root')?.items?.find((page) => page.id === formValue.pageFragmentId);
|
|
118
112
|
if (pageFragment) {
|
|
119
113
|
events = [
|
|
120
114
|
{
|
|
@@ -185,7 +179,7 @@ const actionTypeConfig = computed(() => {
|
|
|
185
179
|
{
|
|
186
180
|
text: '代码',
|
|
187
181
|
label: '代码',
|
|
188
|
-
disabled: !Object.keys(codeBlockService
|
|
182
|
+
disabled: !Object.keys(codeBlockService.getCodeDsl() || {}).length,
|
|
189
183
|
value: ActionType.CODE,
|
|
190
184
|
},
|
|
191
185
|
{
|
|
@@ -193,7 +187,7 @@ const actionTypeConfig = computed(() => {
|
|
|
193
187
|
label: '数据源',
|
|
194
188
|
disabled: !dataSourceService
|
|
195
189
|
?.get('dataSources')
|
|
196
|
-
?.filter((ds) => ds.methods?.length || dataSourceService
|
|
190
|
+
?.filter((ds) => ds.methods?.length || dataSourceService.getFormMethod(ds.type).length).length,
|
|
197
191
|
value: ActionType.DATA_SOURCE,
|
|
198
192
|
},
|
|
199
193
|
],
|
|
@@ -222,7 +216,7 @@ const compActionConfig = computed(() => {
|
|
|
222
216
|
name: 'method',
|
|
223
217
|
text: '动作',
|
|
224
218
|
type: (mForm, { model }: any) => {
|
|
225
|
-
const to = editorService
|
|
219
|
+
const to = editorService.getNodeById(model.to);
|
|
226
220
|
|
|
227
221
|
if (to && to.type === 'page-fragment-container' && to.pageFragmentId) {
|
|
228
222
|
return 'cascader';
|
|
@@ -233,20 +227,20 @@ const compActionConfig = computed(() => {
|
|
|
233
227
|
checkStrictly: () => props.config.src !== 'component',
|
|
234
228
|
display: (mForm, { model }: any) => model.actionType === ActionType.COMP,
|
|
235
229
|
options: (mForm: FormState, { model }: any) => {
|
|
236
|
-
const node = editorService
|
|
230
|
+
const node = editorService.getNodeById(model.to);
|
|
237
231
|
if (!node?.type) return [];
|
|
238
232
|
|
|
239
233
|
let methods: EventOption[] | CascaderOption[] = [];
|
|
240
234
|
|
|
241
|
-
methods = eventsService
|
|
235
|
+
methods = eventsService.getMethod(node.type);
|
|
242
236
|
|
|
243
237
|
if (node.type === 'page-fragment-container' && node.pageFragmentId) {
|
|
244
|
-
const pageFragment = editorService
|
|
238
|
+
const pageFragment = editorService.get('root')?.items?.find((page) => page.id === node.pageFragmentId);
|
|
245
239
|
if (pageFragment) {
|
|
246
240
|
methods = [];
|
|
247
241
|
pageFragment.items.forEach((node: MComponent | MContainer) => {
|
|
248
242
|
traverseNode<MComponent | MContainer>(node, (node) => {
|
|
249
|
-
const nodeMethods = (node.type && eventsService
|
|
243
|
+
const nodeMethods = (node.type && eventsService.getMethod(node.type)) || [];
|
|
250
244
|
|
|
251
245
|
if (nodeMethods.length) {
|
|
252
246
|
methods.push({
|
|
@@ -277,7 +271,7 @@ const codeActionConfig = computed(() => {
|
|
|
277
271
|
type: 'code-select-col',
|
|
278
272
|
text: '代码块',
|
|
279
273
|
name: 'codeId',
|
|
280
|
-
notEditable: () => !codeBlockService
|
|
274
|
+
notEditable: () => !codeBlockService.getEditStatus(),
|
|
281
275
|
display: (mForm, { model }) => model.actionType === ActionType.CODE,
|
|
282
276
|
};
|
|
283
277
|
return { ...defaultCodeActionConfig, ...props.config.codeActionConfig };
|
|
@@ -289,7 +283,7 @@ const dataSourceActionConfig = computed(() => {
|
|
|
289
283
|
type: 'data-source-method-select',
|
|
290
284
|
text: '数据源方法',
|
|
291
285
|
name: 'dataSourceMethod',
|
|
292
|
-
notEditable: () => !
|
|
286
|
+
notEditable: () => !dataSourceService.get('editable'),
|
|
293
287
|
display: (mForm, { model }) => model.actionType === ActionType.DATA_SOURCE,
|
|
294
288
|
};
|
|
295
289
|
return { ...defaultDataSourceActionConfig, ...props.config.dataSourceActionConfig };
|
|
@@ -305,7 +299,7 @@ const tableConfig = computed(() => ({
|
|
|
305
299
|
label: '事件名',
|
|
306
300
|
type: eventNameConfig.value.type,
|
|
307
301
|
options: (mForm: FormState, { formValue }: any) =>
|
|
308
|
-
eventsService
|
|
302
|
+
eventsService.getEvent(formValue.type).map((option: any) => ({
|
|
309
303
|
text: option.label,
|
|
310
304
|
value: option.value,
|
|
311
305
|
})),
|
|
@@ -320,10 +314,10 @@ const tableConfig = computed(() => ({
|
|
|
320
314
|
label: '动作',
|
|
321
315
|
type: compActionConfig.value.type,
|
|
322
316
|
options: (mForm: FormState, { model }: any) => {
|
|
323
|
-
const node = editorService
|
|
317
|
+
const node = editorService.getNodeById(model.to);
|
|
324
318
|
if (!node?.type) return [];
|
|
325
319
|
|
|
326
|
-
return eventsService
|
|
320
|
+
return eventsService.getMethod(node.type).map((option: any) => ({
|
|
327
321
|
text: option.label,
|
|
328
322
|
value: option.value,
|
|
329
323
|
}));
|
|
@@ -16,27 +16,28 @@
|
|
|
16
16
|
</template>
|
|
17
17
|
|
|
18
18
|
<script lang="ts" setup>
|
|
19
|
-
import { computed
|
|
19
|
+
import { computed } from 'vue';
|
|
20
20
|
import { Edit } from '@element-plus/icons-vue';
|
|
21
21
|
|
|
22
22
|
import { Id, NodeType } from '@tmagic/core';
|
|
23
23
|
import { FieldProps } from '@tmagic/form';
|
|
24
24
|
|
|
25
25
|
import Icon from '@editor/components/Icon.vue';
|
|
26
|
-
import
|
|
26
|
+
import { useServices } from '@editor/hooks/use-services';
|
|
27
|
+
import type { PageFragmentSelectConfig } from '@editor/type';
|
|
27
28
|
|
|
28
29
|
defineOptions({
|
|
29
30
|
name: 'MFieldsPageFragmentSelect',
|
|
30
31
|
});
|
|
31
32
|
|
|
32
|
-
const
|
|
33
|
+
const { editorService } = useServices();
|
|
33
34
|
const emit = defineEmits(['change']);
|
|
34
35
|
|
|
35
36
|
const props = withDefaults(defineProps<FieldProps<PageFragmentSelectConfig>>(), {
|
|
36
37
|
disabled: false,
|
|
37
38
|
});
|
|
38
39
|
const pageList = computed(() =>
|
|
39
|
-
|
|
40
|
+
editorService.get('root')?.items.filter((item) => item.type === NodeType.PAGE_FRAGMENT),
|
|
40
41
|
);
|
|
41
42
|
|
|
42
43
|
const selectConfig = {
|
|
@@ -58,6 +59,6 @@ const changeHandler = async () => {
|
|
|
58
59
|
};
|
|
59
60
|
|
|
60
61
|
const editPageFragment = (id: Id) => {
|
|
61
|
-
|
|
62
|
+
editorService.select(id);
|
|
62
63
|
};
|
|
63
64
|
</script>
|
package/src/fields/UISelect.vue
CHANGED
|
@@ -50,7 +50,8 @@ import { TMagicButton, TMagicTooltip } from '@tmagic/design';
|
|
|
50
50
|
import type { FieldProps, FormItem, FormState } from '@tmagic/form';
|
|
51
51
|
import { getIdFromEl } from '@tmagic/utils';
|
|
52
52
|
|
|
53
|
-
import {
|
|
53
|
+
import { useServices } from '@editor/hooks/use-services';
|
|
54
|
+
import { UI_SELECT_MODE_EVENT_NAME } from '@editor/utils/const';
|
|
54
55
|
|
|
55
56
|
defineOptions({
|
|
56
57
|
name: 'MFieldsUISelect',
|
|
@@ -60,14 +61,14 @@ const props = defineProps<FieldProps<{ type: 'ui-select' } & FormItem>>();
|
|
|
60
61
|
|
|
61
62
|
const emit = defineEmits(['change']);
|
|
62
63
|
|
|
63
|
-
const
|
|
64
|
+
const { editorService, uiService, stageOverlayService } = useServices();
|
|
64
65
|
const mForm = inject<FormState>('mForm');
|
|
66
|
+
|
|
65
67
|
const val = computed(() => props.model[props.name]);
|
|
66
68
|
const uiSelectMode = ref(false);
|
|
67
69
|
|
|
68
70
|
const cancelHandler = () => {
|
|
69
|
-
|
|
70
|
-
services.uiService.set('uiSelectMode', false);
|
|
71
|
+
uiService.set('uiSelectMode', false);
|
|
71
72
|
uiSelectMode.value = false;
|
|
72
73
|
globalThis.document.removeEventListener(UI_SELECT_MODE_EVENT_NAME, clickHandler as EventListener);
|
|
73
74
|
};
|
|
@@ -89,13 +90,12 @@ const clickHandler = ({ detail }: Event & { detail: HTMLElement | MNode }) => {
|
|
|
89
90
|
};
|
|
90
91
|
|
|
91
92
|
const toName = computed(() => {
|
|
92
|
-
const config =
|
|
93
|
+
const config = editorService.getNodeById(val.value);
|
|
93
94
|
return config?.name || '';
|
|
94
95
|
});
|
|
95
96
|
|
|
96
97
|
const startSelect = () => {
|
|
97
|
-
|
|
98
|
-
services.uiService.set('uiSelectMode', true);
|
|
98
|
+
uiService.set('uiSelectMode', true);
|
|
99
99
|
uiSelectMode.value = true;
|
|
100
100
|
globalThis.document.addEventListener(UI_SELECT_MODE_EVENT_NAME, clickHandler as EventListener);
|
|
101
101
|
};
|
|
@@ -109,24 +109,21 @@ const deleteHandler = () => {
|
|
|
109
109
|
};
|
|
110
110
|
|
|
111
111
|
const selectNode = async (id: Id) => {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
services.stageOverlayService.get('stage')?.select(id);
|
|
112
|
+
await editorService.select(id);
|
|
113
|
+
editorService.get('stage')?.select(id);
|
|
114
|
+
stageOverlayService.get('stage')?.select(id);
|
|
116
115
|
};
|
|
117
116
|
|
|
118
117
|
const highlight = throttle((id: Id) => {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
services.stageOverlayService.get('stage')?.highlight(id);
|
|
118
|
+
editorService.highlight(id);
|
|
119
|
+
editorService.get('stage')?.highlight(id);
|
|
120
|
+
stageOverlayService.get('stage')?.highlight(id);
|
|
123
121
|
}, 150);
|
|
124
122
|
|
|
125
123
|
const unhighlight = () => {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
services.stageOverlayService.get('stage')?.clearHighlight();
|
|
124
|
+
editorService.set('highlightNode', null);
|
|
125
|
+
editorService.get('stage')?.clearHighlight();
|
|
126
|
+
stageOverlayService.get('stage')?.clearHighlight();
|
|
130
127
|
};
|
|
131
128
|
</script>
|
|
132
129
|
|
package/src/hooks/index.ts
CHANGED
|
@@ -5,20 +5,15 @@ import type { CodeBlockContent } from '@tmagic/core';
|
|
|
5
5
|
import { tMagicMessage } from '@tmagic/design';
|
|
6
6
|
|
|
7
7
|
import CodeBlockEditor from '@editor/components/CodeBlockEditor.vue';
|
|
8
|
-
import type {
|
|
8
|
+
import type { Services } from '@editor/type';
|
|
9
9
|
|
|
10
|
-
export const useCodeBlockEdit = (codeBlockService
|
|
10
|
+
export const useCodeBlockEdit = (codeBlockService: Services['codeBlockService']) => {
|
|
11
11
|
const codeConfig = ref<CodeBlockContent>();
|
|
12
12
|
const codeId = ref<string>();
|
|
13
13
|
const codeBlockEditorRef = useTemplateRef<InstanceType<typeof CodeBlockEditor>>('codeBlockEditor');
|
|
14
14
|
|
|
15
15
|
// 新增代码块
|
|
16
16
|
const createCodeBlock = async () => {
|
|
17
|
-
if (!codeBlockService) {
|
|
18
|
-
tMagicMessage.error('新增代码块失败');
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
17
|
codeConfig.value = {
|
|
23
18
|
name: '',
|
|
24
19
|
content: `({app, params, flowState}) => {\n // place your code here\n}`,
|
|
@@ -34,7 +29,7 @@ export const useCodeBlockEdit = (codeBlockService?: CodeBlockService) => {
|
|
|
34
29
|
|
|
35
30
|
// 编辑代码块
|
|
36
31
|
const editCode = async (id: string) => {
|
|
37
|
-
const codeBlock = await codeBlockService
|
|
32
|
+
const codeBlock = await codeBlockService.getCodeContentById(id);
|
|
38
33
|
|
|
39
34
|
if (!codeBlock) {
|
|
40
35
|
tMagicMessage.error('获取代码块内容失败');
|
|
@@ -59,13 +54,13 @@ export const useCodeBlockEdit = (codeBlockService?: CodeBlockService) => {
|
|
|
59
54
|
|
|
60
55
|
// 删除代码块
|
|
61
56
|
const deleteCode = async (key: string) => {
|
|
62
|
-
codeBlockService
|
|
57
|
+
codeBlockService.deleteCodeDslByIds([key]);
|
|
63
58
|
};
|
|
64
59
|
|
|
65
60
|
const submitCodeBlockHandler = async (values: CodeBlockContent) => {
|
|
66
61
|
if (!codeId.value) return;
|
|
67
62
|
|
|
68
|
-
await codeBlockService
|
|
63
|
+
await codeBlockService.setCodeDslById(codeId.value, values);
|
|
69
64
|
|
|
70
65
|
codeBlockEditorRef.value?.hide();
|
|
71
66
|
};
|
|
@@ -4,20 +4,20 @@ import type { DataSourceSchema } from '@tmagic/core';
|
|
|
4
4
|
import type { ContainerChangeEventData } from '@tmagic/form';
|
|
5
5
|
|
|
6
6
|
import DataSourceConfigPanel from '@editor/layouts/sidebar/data-source/DataSourceConfigPanel.vue';
|
|
7
|
-
import type {
|
|
7
|
+
import type { Services } from '@editor/type';
|
|
8
8
|
|
|
9
|
-
export const useDataSourceEdit = (dataSourceService
|
|
9
|
+
export const useDataSourceEdit = (dataSourceService: Services['dataSourceService']) => {
|
|
10
10
|
const dialogTitle = ref('');
|
|
11
11
|
const editDialog = ref<InstanceType<typeof DataSourceConfigPanel>>();
|
|
12
12
|
const dataSourceValues = ref<Record<string, any>>({});
|
|
13
13
|
|
|
14
|
-
const editable = computed(() => dataSourceService
|
|
14
|
+
const editable = computed(() => dataSourceService.get('editable'));
|
|
15
15
|
|
|
16
16
|
const editHandler = (id: string) => {
|
|
17
17
|
if (!editDialog.value) return;
|
|
18
18
|
|
|
19
19
|
dataSourceValues.value = {
|
|
20
|
-
...dataSourceService
|
|
20
|
+
...(dataSourceService.getDataSourceById(id) || {}),
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
dialogTitle.value = `编辑${dataSourceValues.value.title || ''}`;
|
|
@@ -27,9 +27,9 @@ export const useDataSourceEdit = (dataSourceService?: DataSourceService) => {
|
|
|
27
27
|
|
|
28
28
|
const submitDataSourceHandler = (value: DataSourceSchema, eventData: ContainerChangeEventData) => {
|
|
29
29
|
if (value.id) {
|
|
30
|
-
dataSourceService
|
|
30
|
+
dataSourceService.update(value, { changeRecords: eventData.changeRecords });
|
|
31
31
|
} else {
|
|
32
|
-
dataSourceService
|
|
32
|
+
dataSourceService.add(value);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
editDialog.value?.hide();
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { computed,
|
|
1
|
+
import { computed, ref, watch } from 'vue';
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import { useServices } from './use-services';
|
|
4
4
|
|
|
5
5
|
export const useEditorContentHeight = () => {
|
|
6
|
-
const
|
|
7
|
-
const frameworkHeight = computed(() =>
|
|
8
|
-
const navMenuHeight = computed(() =>
|
|
6
|
+
const { uiService } = useServices();
|
|
7
|
+
const frameworkHeight = computed(() => uiService.get('frameworkRect').height);
|
|
8
|
+
const navMenuHeight = computed(() => uiService.get('navMenuRect').height);
|
|
9
9
|
const editorContentHeight = computed(() => frameworkHeight.value - navMenuHeight.value);
|
|
10
10
|
|
|
11
11
|
const height = ref(0);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { computed, ComputedRef,
|
|
1
|
+
import { computed, ComputedRef, onBeforeUnmount, ref, watch } from 'vue';
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import { useServices } from './use-services';
|
|
4
4
|
|
|
5
5
|
interface State {
|
|
6
6
|
status: boolean;
|
|
@@ -9,7 +9,7 @@ interface State {
|
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export const useFloatBox = (slideKeys: ComputedRef<string[]>) => {
|
|
12
|
-
const
|
|
12
|
+
const { uiService } = useServices();
|
|
13
13
|
|
|
14
14
|
const floatBoxStates = ref<{
|
|
15
15
|
[key in (typeof slideKeys.value)[number]]: State;
|
|
@@ -57,10 +57,10 @@ export const useFloatBox = (slideKeys: ComputedRef<string[]>) => {
|
|
|
57
57
|
Math.abs(startOffset.x - e.clientX) > effectiveDistance ||
|
|
58
58
|
Math.abs(startOffset.y - e.clientY) > effectiveDistance
|
|
59
59
|
) {
|
|
60
|
-
const navMenuRect =
|
|
60
|
+
const navMenuRect = uiService.get('navMenuRect');
|
|
61
61
|
floatBoxStates.value[key] = {
|
|
62
62
|
left: e.clientX,
|
|
63
|
-
top:
|
|
63
|
+
top: navMenuRect.top + navMenuRect.height,
|
|
64
64
|
status: true,
|
|
65
65
|
};
|
|
66
66
|
}
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { Ref, ref } from 'vue';
|
|
1
|
+
import { type Ref, ref } from 'vue';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import type { Services } from '@editor/type';
|
|
4
4
|
|
|
5
|
-
export const useNextFloatBoxPosition = (uiService
|
|
5
|
+
export const useNextFloatBoxPosition = (uiService: Services['uiService'], parent?: Ref<HTMLDivElement | null>) => {
|
|
6
6
|
const boxPosition = ref({
|
|
7
7
|
left: 0,
|
|
8
8
|
top: 0,
|
|
9
9
|
});
|
|
10
10
|
|
|
11
11
|
const calcBoxPosition = () => {
|
|
12
|
-
const columnWidth = uiService
|
|
13
|
-
const navMenuRect = uiService
|
|
14
|
-
let left = columnWidth
|
|
12
|
+
const columnWidth = uiService.get('columnWidth');
|
|
13
|
+
const navMenuRect = uiService.get('navMenuRect');
|
|
14
|
+
let left = columnWidth.left ?? 0;
|
|
15
15
|
if (parent?.value) {
|
|
16
|
-
const rect = parent
|
|
17
|
-
left =
|
|
16
|
+
const rect = parent.value.getBoundingClientRect();
|
|
17
|
+
left = rect.left + rect.width;
|
|
18
18
|
}
|
|
19
19
|
boxPosition.value = {
|
|
20
20
|
left,
|
|
21
|
-
top:
|
|
21
|
+
top: navMenuRect.top + navMenuRect.height,
|
|
22
22
|
};
|
|
23
23
|
};
|
|
24
24
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { inject } from 'vue';
|
|
2
|
+
|
|
3
|
+
import type { Services } from '@editor/type';
|
|
4
|
+
|
|
5
|
+
export const useServices = () => {
|
|
6
|
+
const services = inject<Services>('services');
|
|
7
|
+
|
|
8
|
+
if (!services) {
|
|
9
|
+
throw new Error('services is required');
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return services;
|
|
13
|
+
};
|
package/src/hooks/use-stage.ts
CHANGED
|
@@ -6,12 +6,8 @@ import { getIdFromEl } from '@tmagic/utils';
|
|
|
6
6
|
|
|
7
7
|
import editorService from '@editor/services/editor';
|
|
8
8
|
import uiService from '@editor/services/ui';
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
StageOptions,
|
|
12
|
-
UI_SELECT_MODE_EVENT_NAME,
|
|
13
|
-
V_GUIDE_LINE_STORAGE_KEY,
|
|
14
|
-
} from '@editor/type';
|
|
9
|
+
import type { StageOptions } from '@editor/type';
|
|
10
|
+
import { H_GUIDE_LINE_STORAGE_KEY, UI_SELECT_MODE_EVENT_NAME, V_GUIDE_LINE_STORAGE_KEY } from '@editor/utils/const';
|
|
15
11
|
import { getGuideLineFromCache } from '@editor/utils/editor';
|
|
16
12
|
|
|
17
13
|
const root = computed(() => editorService.get('root'));
|
|
@@ -19,13 +19,13 @@
|
|
|
19
19
|
</template>
|
|
20
20
|
|
|
21
21
|
<script lang="ts" setup>
|
|
22
|
-
import {
|
|
22
|
+
import { toRaw } from 'vue';
|
|
23
23
|
import { Plus } from '@element-plus/icons-vue';
|
|
24
24
|
|
|
25
25
|
import { NodeType } from '@tmagic/core';
|
|
26
26
|
|
|
27
27
|
import MIcon from '@editor/components/Icon.vue';
|
|
28
|
-
import
|
|
28
|
+
import { useServices } from '@editor/hooks/use-services';
|
|
29
29
|
import { generatePageNameByApp } from '@editor/utils';
|
|
30
30
|
|
|
31
31
|
defineOptions({
|
|
@@ -36,13 +36,9 @@ defineProps<{
|
|
|
36
36
|
disabledPageFragment: boolean;
|
|
37
37
|
}>();
|
|
38
38
|
|
|
39
|
-
const
|
|
39
|
+
const { editorService } = useServices();
|
|
40
40
|
|
|
41
41
|
const clickHandler = (type: NodeType.PAGE | NodeType.PAGE_FRAGMENT) => {
|
|
42
|
-
const { editorService } = services || {};
|
|
43
|
-
|
|
44
|
-
if (!editorService) return;
|
|
45
|
-
|
|
46
42
|
const root = toRaw(editorService.get('root'));
|
|
47
43
|
if (!root) throw new Error('root 不能为空');
|
|
48
44
|
|
|
@@ -19,10 +19,10 @@
|
|
|
19
19
|
right-class="m-editor-framework-right"
|
|
20
20
|
:left="columnWidth.left"
|
|
21
21
|
:right="columnWidth.right"
|
|
22
|
-
:min-left="
|
|
23
|
-
:min-right="
|
|
24
|
-
:min-center="
|
|
25
|
-
:width="frameworkRect
|
|
22
|
+
:min-left="MIN_LEFT_COLUMN_WIDTH"
|
|
23
|
+
:min-right="MIN_RIGHT_COLUMN_WIDTH"
|
|
24
|
+
:min-center="MIN_CENTER_COLUMN_WIDTH"
|
|
25
|
+
:width="frameworkRect.width"
|
|
26
26
|
@change="columnWidthChange"
|
|
27
27
|
>
|
|
28
28
|
<template #left>
|
|
@@ -65,11 +65,16 @@ import { computed, inject, onBeforeUnmount, onMounted, useTemplateRef, watch } f
|
|
|
65
65
|
import type { MPage, MPageFragment } from '@tmagic/core';
|
|
66
66
|
|
|
67
67
|
import SplitView from '@editor/components/SplitView.vue';
|
|
68
|
-
import
|
|
68
|
+
import { useServices } from '@editor/hooks/use-services';
|
|
69
|
+
import { Protocol } from '@editor/services/storage';
|
|
70
|
+
import type { FrameworkSlots, GetColumnWidth, PageBarSortOptions } from '@editor/type';
|
|
69
71
|
import { getEditorConfig } from '@editor/utils/config';
|
|
70
72
|
import {
|
|
71
73
|
DEFAULT_LEFT_COLUMN_WIDTH,
|
|
72
74
|
LEFT_COLUMN_WIDTH_STORAGE_KEY,
|
|
75
|
+
MIN_CENTER_COLUMN_WIDTH,
|
|
76
|
+
MIN_LEFT_COLUMN_WIDTH,
|
|
77
|
+
MIN_RIGHT_COLUMN_WIDTH,
|
|
73
78
|
RIGHT_COLUMN_WIDTH_STORAGE_KEY,
|
|
74
79
|
} from '@editor/utils/const';
|
|
75
80
|
|
|
@@ -90,53 +95,48 @@ defineProps<{
|
|
|
90
95
|
}>();
|
|
91
96
|
|
|
92
97
|
const codeOptions = inject('codeOptions', {});
|
|
93
|
-
const { editorService, uiService } =
|
|
98
|
+
const { editorService, uiService, storageService } = useServices();
|
|
94
99
|
|
|
95
100
|
const contentEl = useTemplateRef<HTMLDivElement>('content');
|
|
96
101
|
const splitViewRef = useTemplateRef<InstanceType<typeof SplitView>>('splitView');
|
|
97
102
|
|
|
98
|
-
const root = computed(() => editorService
|
|
99
|
-
const page = computed(() => editorService
|
|
103
|
+
const root = computed(() => editorService.get('root'));
|
|
104
|
+
const page = computed(() => editorService.get('page'));
|
|
100
105
|
|
|
101
|
-
const pageLength = computed(() => editorService
|
|
102
|
-
const showSrc = computed(() => uiService
|
|
106
|
+
const pageLength = computed(() => editorService.get('pageLength') || 0);
|
|
107
|
+
const showSrc = computed(() => uiService.get('showSrc'));
|
|
103
108
|
|
|
104
|
-
const columnWidth = computed(
|
|
105
|
-
() =>
|
|
106
|
-
uiService?.get('columnWidth') || {
|
|
107
|
-
left: 0,
|
|
108
|
-
center: 0,
|
|
109
|
-
right: 0,
|
|
110
|
-
},
|
|
111
|
-
);
|
|
109
|
+
const columnWidth = computed(() => uiService.get('columnWidth'));
|
|
112
110
|
|
|
113
111
|
watch(pageLength, () => {
|
|
114
112
|
splitViewRef.value?.updateWidth();
|
|
115
113
|
});
|
|
116
114
|
|
|
117
115
|
watch(
|
|
118
|
-
() => uiService
|
|
116
|
+
() => uiService.get('hideSlideBar'),
|
|
119
117
|
(hideSlideBar) => {
|
|
120
|
-
uiService
|
|
118
|
+
uiService.set('columnWidth', {
|
|
121
119
|
...columnWidth.value,
|
|
122
120
|
left: hideSlideBar
|
|
123
121
|
? 0
|
|
124
|
-
:
|
|
122
|
+
: storageService.getItem(LEFT_COLUMN_WIDTH_STORAGE_KEY, { protocol: Protocol.NUMBER }) ||
|
|
123
|
+
DEFAULT_LEFT_COLUMN_WIDTH,
|
|
125
124
|
});
|
|
126
125
|
},
|
|
127
126
|
);
|
|
128
127
|
|
|
129
128
|
const columnWidthChange = (columnW: GetColumnWidth) => {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
129
|
+
storageService.setItem(LEFT_COLUMN_WIDTH_STORAGE_KEY, columnW.left, { protocol: Protocol.NUMBER });
|
|
130
|
+
storageService.setItem(RIGHT_COLUMN_WIDTH_STORAGE_KEY, columnW.right, { protocol: Protocol.NUMBER });
|
|
131
|
+
|
|
132
|
+
uiService.set('columnWidth', columnW);
|
|
133
133
|
};
|
|
134
134
|
|
|
135
|
-
const frameworkRect = computed(() => uiService
|
|
135
|
+
const frameworkRect = computed(() => uiService.get('frameworkRect'));
|
|
136
136
|
|
|
137
137
|
const resizerObserver = new ResizeObserver((entries) => {
|
|
138
138
|
const { contentRect } = entries[0];
|
|
139
|
-
uiService
|
|
139
|
+
uiService.set('frameworkRect', {
|
|
140
140
|
width: contentRect.width,
|
|
141
141
|
height: contentRect.height,
|
|
142
142
|
left: contentRect.left,
|
|
@@ -157,7 +157,7 @@ onBeforeUnmount(() => {
|
|
|
157
157
|
const saveCode = (value: string) => {
|
|
158
158
|
try {
|
|
159
159
|
const parseDSL = getEditorConfig('parseDSL');
|
|
160
|
-
editorService
|
|
160
|
+
editorService.set('root', parseDSL(value));
|
|
161
161
|
} catch (e: any) {
|
|
162
162
|
console.error(e);
|
|
163
163
|
}
|