@tmagic/editor 1.3.6 → 1.3.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/LICENSE +5432 -0
- package/dist/style.css +34 -11
- package/dist/tmagic-editor.js +1360 -957
- package/dist/tmagic-editor.js.map +1 -1
- package/dist/tmagic-editor.umd.cjs +1382 -977
- package/dist/tmagic-editor.umd.cjs.map +1 -1
- package/package.json +17 -17
- package/src/Editor.vue +15 -7
- package/src/components/CodeBlockEditor.vue +2 -2
- package/src/components/ContentMenu.vue +5 -5
- package/src/components/ScrollBar.vue +2 -2
- package/src/components/ScrollViewer.vue +2 -2
- package/src/components/SplitView.vue +2 -2
- package/src/components/Tree.vue +1 -1
- package/src/components/TreeNode.vue +3 -3
- package/src/editorProps.ts +14 -4
- package/src/fields/PageFragmentSelect.vue +63 -0
- package/src/hooks/use-getso.ts +2 -2
- package/src/hooks/use-stage.ts +18 -1
- package/src/index.ts +3 -0
- package/src/initService.ts +15 -5
- package/src/layouts/AddPageBox.vue +16 -4
- package/src/layouts/CodeEditor.vue +2 -2
- package/src/layouts/Framework.vue +19 -3
- package/src/layouts/PropsPanel.vue +9 -7
- package/src/layouts/page-bar/AddButton.vue +48 -0
- package/src/layouts/page-bar/PageBar.vue +158 -0
- package/src/layouts/{workspace → page-bar}/PageBarScrollContainer.vue +61 -35
- package/src/layouts/page-bar/SwitchTypeButton.vue +45 -0
- package/src/layouts/sidebar/Sidebar.vue +2 -0
- package/src/layouts/sidebar/layer/LayerMenu.vue +39 -27
- package/src/layouts/sidebar/layer/LayerPanel.vue +7 -1
- package/src/layouts/sidebar/layer/use-click.ts +5 -3
- package/src/layouts/sidebar/layer/use-keybinding.ts +8 -8
- package/src/layouts/sidebar/layer/use-node-status.ts +3 -3
- package/src/layouts/workspace/Workspace.vue +6 -7
- package/src/layouts/workspace/viewer/NodeListMenu.vue +2 -2
- package/src/layouts/workspace/viewer/Stage.vue +12 -5
- package/src/layouts/workspace/viewer/ViewerMenu.vue +93 -80
- package/src/services/dataSource.ts +17 -0
- package/src/services/dep.ts +4 -0
- package/src/services/editor.ts +66 -35
- package/src/services/history.ts +6 -2
- package/src/services/keybinding.ts +48 -13
- package/src/theme/code-block.scss +0 -16
- package/src/theme/page-bar.scss +18 -1
- package/src/theme/page-fragment-select.scss +14 -0
- package/src/theme/theme.scss +1 -0
- package/src/theme/tree.scss +6 -0
- package/src/type.ts +23 -7
- package/src/utils/content-menu.ts +2 -2
- package/src/utils/editor.ts +22 -15
- package/src/utils/operator.ts +4 -4
- package/types/components/ToolButton.vue.d.ts +2 -2
- package/types/editorProps.d.ts +11 -2
- package/types/fields/PageFragmentSelect.vue.d.ts +31 -0
- package/types/index.d.ts +1 -0
- package/types/layouts/AddPageBox.vue.d.ts +14 -1
- package/types/layouts/Framework.vue.d.ts +14 -1
- package/types/layouts/PropsPanel.vue.d.ts +19 -10
- package/types/layouts/page-bar/AddButton.vue.d.ts +16 -0
- package/types/layouts/page-bar/PageBar.vue.d.ts +28 -0
- package/types/layouts/page-bar/PageBarScrollContainer.vue.d.ts +24 -0
- package/types/layouts/page-bar/SwitchTypeButton.vue.d.ts +20 -0
- package/types/layouts/sidebar/Sidebar.vue.d.ts +2 -0
- package/types/layouts/sidebar/layer/LayerMenu.vue.d.ts +22 -3
- package/types/layouts/sidebar/layer/LayerPanel.vue.d.ts +2 -0
- package/types/layouts/sidebar/layer/use-click.d.ts +25 -3
- package/types/layouts/sidebar/layer/use-keybinding.d.ts +1 -1
- package/types/layouts/workspace/Workspace.vue.d.ts +2 -0
- package/types/layouts/workspace/viewer/Stage.vue.d.ts +2 -0
- package/types/layouts/workspace/viewer/ViewerMenu.vue.d.ts +8 -0
- package/types/services/dataSource.d.ts +2 -0
- package/types/services/dep.d.ts +1 -0
- package/types/services/editor.d.ts +3 -2
- package/types/services/history.d.ts +3 -2
- package/types/services/keybinding.d.ts +21 -1
- package/types/type.d.ts +26 -12
- package/types/utils/editor.d.ts +9 -7
- package/src/layouts/workspace/PageBar.vue +0 -87
- package/types/layouts/workspace/PageBar.vue.d.ts +0 -15
- package/types/layouts/workspace/PageBarScrollContainer.vue.d.ts +0 -9
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.3.
|
|
2
|
+
"version": "1.3.8",
|
|
3
3
|
"name": "@tmagic/editor",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": [
|
|
@@ -23,11 +23,6 @@
|
|
|
23
23
|
"./*": "./*"
|
|
24
24
|
},
|
|
25
25
|
"license": "Apache-2.0",
|
|
26
|
-
"scripts": {
|
|
27
|
-
"build": "npm run build:type && vite build",
|
|
28
|
-
"build:type": "npm run clear:type && vue-tsc --declaration --emitDeclarationOnly --project tsconfig.build.json && tsc-alias -p tsconfig.build.json",
|
|
29
|
-
"clear:type": "rimraf ./types"
|
|
30
|
-
},
|
|
31
26
|
"engines": {
|
|
32
27
|
"node": ">=18"
|
|
33
28
|
},
|
|
@@ -47,14 +42,14 @@
|
|
|
47
42
|
"dependencies": {
|
|
48
43
|
"@babel/core": "^7.18.0",
|
|
49
44
|
"@element-plus/icons-vue": "^2.3.1",
|
|
50
|
-
"@tmagic/core": "1.3.
|
|
51
|
-
"@tmagic/dep": "1.3.
|
|
52
|
-
"@tmagic/design": "1.3.
|
|
53
|
-
"@tmagic/form": "1.3.
|
|
54
|
-
"@tmagic/schema": "1.3.
|
|
55
|
-
"@tmagic/stage": "1.3.
|
|
56
|
-
"@tmagic/table": "1.3.
|
|
57
|
-
"@tmagic/utils": "1.3.
|
|
45
|
+
"@tmagic/core": "1.3.8",
|
|
46
|
+
"@tmagic/dep": "1.3.8",
|
|
47
|
+
"@tmagic/design": "1.3.8",
|
|
48
|
+
"@tmagic/form": "1.3.8",
|
|
49
|
+
"@tmagic/schema": "1.3.8",
|
|
50
|
+
"@tmagic/stage": "1.3.8",
|
|
51
|
+
"@tmagic/table": "1.3.8",
|
|
52
|
+
"@tmagic/utils": "1.3.8",
|
|
58
53
|
"buffer": "^6.0.3",
|
|
59
54
|
"color": "^3.1.3",
|
|
60
55
|
"events": "^3.3.0",
|
|
@@ -67,8 +62,8 @@
|
|
|
67
62
|
"vue": "^3.3.8"
|
|
68
63
|
},
|
|
69
64
|
"peerDependencies": {
|
|
70
|
-
"@tmagic/design": "1.3.
|
|
71
|
-
"@tmagic/form": "1.3.
|
|
65
|
+
"@tmagic/design": "1.3.8",
|
|
66
|
+
"@tmagic/form": "1.3.8",
|
|
72
67
|
"monaco-editor": "^0.41.0",
|
|
73
68
|
"vue": "^3.3.8"
|
|
74
69
|
},
|
|
@@ -86,5 +81,10 @@
|
|
|
86
81
|
"typescript": "^5.0.4",
|
|
87
82
|
"vite": "^5.0.7",
|
|
88
83
|
"vue-tsc": "^1.8.25"
|
|
84
|
+
},
|
|
85
|
+
"scripts": {
|
|
86
|
+
"build": "npm run build:type && vite build",
|
|
87
|
+
"build:type": "npm run clear:type && vue-tsc --declaration --emitDeclarationOnly --project tsconfig.build.json && tsc-alias -p tsconfig.build.json",
|
|
88
|
+
"clear:type": "rimraf ./types"
|
|
89
89
|
}
|
|
90
|
-
}
|
|
90
|
+
}
|
package/src/Editor.vue
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<Framework>
|
|
2
|
+
<Framework :disabled-page-fragment="disabledPageFragment">
|
|
3
3
|
<template #header>
|
|
4
4
|
<slot name="header"></slot>
|
|
5
5
|
</template>
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
<template #sidebar>
|
|
18
18
|
<slot name="sidebar" :editorService="editorService">
|
|
19
|
-
<Sidebar :data="sidebar" :layer-content-menu="layerContentMenu">
|
|
19
|
+
<Sidebar :data="sidebar" :layer-content-menu="layerContentMenu" :custom-content-menu="customContentMenu">
|
|
20
20
|
<template #layer-panel-header>
|
|
21
21
|
<slot name="layer-panel-header"></slot>
|
|
22
22
|
</template>
|
|
@@ -58,11 +58,9 @@
|
|
|
58
58
|
|
|
59
59
|
<template #workspace>
|
|
60
60
|
<slot name="workspace" :editorService="editorService">
|
|
61
|
-
<Workspace :stage-content-menu="stageContentMenu">
|
|
61
|
+
<Workspace :stage-content-menu="stageContentMenu" :custom-content-menu="customContentMenu">
|
|
62
62
|
<template #stage><slot name="stage"></slot></template>
|
|
63
63
|
<template #workspace-content><slot name="workspace-content" :editorService="editorService"></slot></template>
|
|
64
|
-
<template #page-bar-title="{ page }"><slot name="page-bar-title" :page="page"></slot></template>
|
|
65
|
-
<template #page-bar-popover="{ page }"><slot name="page-bar-popover" :page="page"></slot></template>
|
|
66
64
|
</Workspace>
|
|
67
65
|
</slot>
|
|
68
66
|
</template>
|
|
@@ -72,6 +70,8 @@
|
|
|
72
70
|
<PropsPanel
|
|
73
71
|
:extend-state="extendFormState"
|
|
74
72
|
@mounted="(instance: any) => $emit('props-panel-mounted', instance)"
|
|
73
|
+
@form-error="(e: any) => $emit('props-form-error', e)"
|
|
74
|
+
@submit-error="(e: any) => $emit('props-submit-error', e)"
|
|
75
75
|
>
|
|
76
76
|
<template #props-panel-header>
|
|
77
77
|
<slot name="props-panel-header"></slot>
|
|
@@ -89,6 +89,10 @@
|
|
|
89
89
|
<template #footer>
|
|
90
90
|
<slot name="footer"></slot>
|
|
91
91
|
</template>
|
|
92
|
+
|
|
93
|
+
<template #page-bar><slot name="page-bar"></slot></template>
|
|
94
|
+
<template #page-bar-title="{ page }"><slot name="page-bar-title" :page="page"></slot></template>
|
|
95
|
+
<template #page-bar-popover="{ page }"><slot name="page-bar-popover" :page="page"></slot></template>
|
|
92
96
|
</Framework>
|
|
93
97
|
</template>
|
|
94
98
|
|
|
@@ -135,6 +139,8 @@ defineOptions({
|
|
|
135
139
|
const emit = defineEmits<{
|
|
136
140
|
'props-panel-mounted': [instance: InstanceType<typeof PropsPanel>];
|
|
137
141
|
'update:modelValue': [value: MApp | null];
|
|
142
|
+
'props-form-error': [e: any];
|
|
143
|
+
'props-submit-error': [e: any];
|
|
138
144
|
}>();
|
|
139
145
|
|
|
140
146
|
const props = withDefaults(defineProps<EditorProps>(), defaultEditorProps);
|
|
@@ -155,8 +161,8 @@ const services: Services = {
|
|
|
155
161
|
|
|
156
162
|
initServiceEvents(props, emit, services);
|
|
157
163
|
initServiceState(props, services);
|
|
158
|
-
keybindingService.
|
|
159
|
-
keybindingService.
|
|
164
|
+
keybindingService.register(keybindingConfig);
|
|
165
|
+
keybindingService.registerEl('global');
|
|
160
166
|
|
|
161
167
|
provide('services', services);
|
|
162
168
|
|
|
@@ -176,6 +182,8 @@ provide(
|
|
|
176
182
|
containerHighlightType: props.containerHighlightType,
|
|
177
183
|
disabledDragStart: props.disabledDragStart,
|
|
178
184
|
renderType: props.renderType,
|
|
185
|
+
guidesOptions: props.guidesOptions,
|
|
186
|
+
disabledMultiSelect: props.disabledMultiSelect,
|
|
179
187
|
}),
|
|
180
188
|
);
|
|
181
189
|
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
</template>
|
|
49
49
|
|
|
50
50
|
<script lang="ts" setup>
|
|
51
|
-
import { computed, inject,
|
|
51
|
+
import { computed, inject, onBeforeUnmount, ref } from 'vue';
|
|
52
52
|
|
|
53
53
|
import { TMagicButton, TMagicDialog, tMagicMessage, tMagicMessageBox, TMagicTag } from '@tmagic/design';
|
|
54
54
|
import { ColumnConfig, FormConfig, FormState, MFormBox, MFormDrawer } from '@tmagic/form';
|
|
@@ -85,7 +85,7 @@ const windowReizehandler = () => {
|
|
|
85
85
|
|
|
86
86
|
globalThis.addEventListener('resize', windowReizehandler);
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
onBeforeUnmount(() => {
|
|
89
89
|
globalThis.removeEventListener('resize', windowReizehandler);
|
|
90
90
|
});
|
|
91
91
|
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
</template>
|
|
37
37
|
|
|
38
38
|
<script lang="ts" setup>
|
|
39
|
-
import { computed, nextTick,
|
|
39
|
+
import { computed, nextTick, onBeforeUnmount, onMounted, ref } from 'vue';
|
|
40
40
|
|
|
41
41
|
import { MenuButton, MenuComponent } from '@editor/type';
|
|
42
42
|
|
|
@@ -99,7 +99,7 @@ const clickHandler = () => {
|
|
|
99
99
|
hide();
|
|
100
100
|
};
|
|
101
101
|
|
|
102
|
-
const
|
|
102
|
+
const outsideClickHideHandler = (e: MouseEvent) => {
|
|
103
103
|
if (!props.autoHide) return;
|
|
104
104
|
|
|
105
105
|
const target = e.target as HTMLElement | undefined;
|
|
@@ -173,13 +173,13 @@ const mouseenterHandler = () => {
|
|
|
173
173
|
onMounted(() => {
|
|
174
174
|
if (props.isSubMenu) return;
|
|
175
175
|
|
|
176
|
-
globalThis.addEventListener('mousedown',
|
|
176
|
+
globalThis.addEventListener('mousedown', outsideClickHideHandler, true);
|
|
177
177
|
});
|
|
178
178
|
|
|
179
|
-
|
|
179
|
+
onBeforeUnmount(() => {
|
|
180
180
|
if (props.isSubMenu) return;
|
|
181
181
|
|
|
182
|
-
globalThis.removeEventListener('mousedown',
|
|
182
|
+
globalThis.removeEventListener('mousedown', outsideClickHideHandler, true);
|
|
183
183
|
});
|
|
184
184
|
|
|
185
185
|
defineExpose({
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
</template>
|
|
6
6
|
|
|
7
7
|
<script lang="ts" setup>
|
|
8
|
-
import { computed,
|
|
8
|
+
import { computed, onBeforeUnmount, onMounted, ref } from 'vue';
|
|
9
9
|
import Gesto from 'gesto';
|
|
10
10
|
|
|
11
11
|
defineOptions({
|
|
@@ -53,7 +53,7 @@ onMounted(() => {
|
|
|
53
53
|
bar.value?.addEventListener('wheel', wheelHandler, false);
|
|
54
54
|
});
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
onBeforeUnmount(() => {
|
|
57
57
|
if (gesto) gesto.off();
|
|
58
58
|
bar.value?.removeEventListener('wheel', wheelHandler, false);
|
|
59
59
|
});
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
</template>
|
|
24
24
|
|
|
25
25
|
<script lang="ts" setup>
|
|
26
|
-
import { computed,
|
|
26
|
+
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
|
27
27
|
|
|
28
28
|
import { isNumber } from '@tmagic/utils';
|
|
29
29
|
|
|
@@ -94,7 +94,7 @@ onMounted(() => {
|
|
|
94
94
|
});
|
|
95
95
|
});
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
onBeforeUnmount(() => {
|
|
98
98
|
scrollViewer.destroy();
|
|
99
99
|
});
|
|
100
100
|
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
</template>
|
|
22
22
|
|
|
23
23
|
<script lang="ts" setup>
|
|
24
|
-
import { computed,
|
|
24
|
+
import { computed, onBeforeUnmount, onMounted, ref } from 'vue';
|
|
25
25
|
import { OnDrag } from 'gesto';
|
|
26
26
|
|
|
27
27
|
import Resizer from './Resizer.vue';
|
|
@@ -110,7 +110,7 @@ onMounted(() => {
|
|
|
110
110
|
}
|
|
111
111
|
});
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
onBeforeUnmount(() => {
|
|
114
114
|
resizerObserver.disconnect();
|
|
115
115
|
});
|
|
116
116
|
|
package/src/components/Tree.vue
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
>
|
|
19
19
|
<MIcon
|
|
20
20
|
class="expand-icon"
|
|
21
|
-
:style="
|
|
21
|
+
:style="hasChildren ? '' : 'color: transparent; cursor: default'"
|
|
22
22
|
:icon="expanded ? ArrowDown : ArrowRight"
|
|
23
23
|
@click="expandHandler"
|
|
24
24
|
></MIcon>
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
</div>
|
|
36
36
|
</div>
|
|
37
37
|
|
|
38
|
-
<div v-if="
|
|
38
|
+
<div v-if="hasChildren && expanded" class="m-editor-tree-node-children">
|
|
39
39
|
<TreeNode
|
|
40
40
|
v-for="item in data.items"
|
|
41
41
|
:key="item.id"
|
|
@@ -114,7 +114,7 @@ const selected = computed(() => nodeStatus.value.selected);
|
|
|
114
114
|
const visible = computed(() => nodeStatus.value.visible);
|
|
115
115
|
const draggable = computed(() => nodeStatus.value.draggable);
|
|
116
116
|
|
|
117
|
-
const
|
|
117
|
+
const hasChildren = computed(() => props.data.items?.some((item) => props.nodeStatusMap.get(item.id)?.visible));
|
|
118
118
|
|
|
119
119
|
const handleDragStart = (event: DragEvent) => {
|
|
120
120
|
treeEmit?.('node-dragstart', event, props.data);
|
package/src/editorProps.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import type { EventOption } from '@tmagic/core';
|
|
2
|
-
import { CustomTargetOptions } from '@tmagic/dep';
|
|
2
|
+
import type { CustomTargetOptions } from '@tmagic/dep';
|
|
3
3
|
import type { FormConfig, FormState } from '@tmagic/form';
|
|
4
4
|
import type { DataSourceSchema, Id, MApp, MNode } from '@tmagic/schema';
|
|
5
5
|
import StageCore, {
|
|
6
6
|
CONTAINER_HIGHLIGHT_CLASS_NAME,
|
|
7
7
|
ContainerHighlightType,
|
|
8
|
-
CustomizeMoveableOptionsCallbackConfig,
|
|
9
|
-
|
|
8
|
+
type CustomizeMoveableOptionsCallbackConfig,
|
|
9
|
+
type GuidesOptions,
|
|
10
|
+
type MoveableOptions,
|
|
10
11
|
RenderType,
|
|
11
|
-
UpdateDragEl,
|
|
12
|
+
type UpdateDragEl,
|
|
12
13
|
} from '@tmagic/stage';
|
|
13
14
|
|
|
14
15
|
import type {
|
|
@@ -71,6 +72,13 @@ export interface EditorProps {
|
|
|
71
72
|
extendFormState?: (state: FormState) => Record<string, any> | Promise<Record<string, any>>;
|
|
72
73
|
/** 自定义依赖收集器,复制组件时会将关联依赖一并复制 */
|
|
73
74
|
collectorOptions?: CustomTargetOptions;
|
|
75
|
+
/** 标尺配置 */
|
|
76
|
+
guidesOptions?: Partial<GuidesOptions>;
|
|
77
|
+
/** 禁止多选 */
|
|
78
|
+
disabledMultiSelect?: boolean;
|
|
79
|
+
/** 禁用页面片 */
|
|
80
|
+
disabledPageFragment?: boolean;
|
|
81
|
+
customContentMenu?: (menus: (MenuButton | MenuComponent)[], type: string) => (MenuButton | MenuComponent)[];
|
|
74
82
|
}
|
|
75
83
|
|
|
76
84
|
export const defaultEditorProps = {
|
|
@@ -91,4 +99,6 @@ export const defaultEditorProps = {
|
|
|
91
99
|
containerHighlightType: ContainerHighlightType.DEFAULT,
|
|
92
100
|
codeOptions: () => ({}),
|
|
93
101
|
renderType: RenderType.IFRAME,
|
|
102
|
+
disabledMultiSelect: false,
|
|
103
|
+
disabledPageFragment: false,
|
|
94
104
|
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="m-fields-page-fragment-select">
|
|
3
|
+
<div class="page-fragment-select-container">
|
|
4
|
+
<!-- 页面片下拉框 -->
|
|
5
|
+
<m-form-container
|
|
6
|
+
class="select"
|
|
7
|
+
:config="selectConfig"
|
|
8
|
+
:model="model"
|
|
9
|
+
:size="size"
|
|
10
|
+
@change="changeHandler"
|
|
11
|
+
></m-form-container>
|
|
12
|
+
<!-- 编辑按钮 -->
|
|
13
|
+
<Icon v-if="model[name]" class="icon" :icon="Edit" @click="editPageFragment(model[name])"></Icon>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
</template>
|
|
17
|
+
|
|
18
|
+
<script lang="ts" setup>
|
|
19
|
+
import { computed, inject } from 'vue';
|
|
20
|
+
import { Edit } from '@element-plus/icons-vue';
|
|
21
|
+
|
|
22
|
+
import { FieldProps } from '@tmagic/form';
|
|
23
|
+
import { Id, NodeType } from '@tmagic/schema';
|
|
24
|
+
|
|
25
|
+
import Icon from '@editor/components/Icon.vue';
|
|
26
|
+
import type { PageFragmentSelectConfig, Services } from '@editor/type';
|
|
27
|
+
|
|
28
|
+
defineOptions({
|
|
29
|
+
name: 'MEditorPageFragmentSelect',
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const services = inject<Services>('services');
|
|
33
|
+
const emit = defineEmits(['change']);
|
|
34
|
+
|
|
35
|
+
const props = withDefaults(defineProps<FieldProps<PageFragmentSelectConfig>>(), {
|
|
36
|
+
disabled: false,
|
|
37
|
+
});
|
|
38
|
+
const pageList = computed(() =>
|
|
39
|
+
services?.editorService.get('root')?.items.filter((item) => item.type === NodeType.PAGE_FRAGMENT),
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
const selectConfig = {
|
|
43
|
+
type: 'select',
|
|
44
|
+
name: props.name,
|
|
45
|
+
options: () => {
|
|
46
|
+
if (pageList.value) {
|
|
47
|
+
return pageList.value.map((item) => ({
|
|
48
|
+
text: `${item.devconfig?.tabName || item.title || item.name}(${item.id})`,
|
|
49
|
+
label: `${item.devconfig?.tabName || item.title || item.name}(${item.id})`,
|
|
50
|
+
value: item.id,
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
53
|
+
return [];
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
const changeHandler = async () => {
|
|
57
|
+
emit('change', props.model[props.name]);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const editPageFragment = (id: Id) => {
|
|
61
|
+
services?.editorService.select(id);
|
|
62
|
+
};
|
|
63
|
+
</script>
|
package/src/hooks/use-getso.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { onBeforeUnmount, onMounted, type Ref, ref } from 'vue';
|
|
2
2
|
import Gesto, { type OnDrag } from 'gesto';
|
|
3
3
|
|
|
4
4
|
export const useGetSo = (target: Ref<HTMLElement | undefined>, emit: (evt: 'change', e: OnDrag<Gesto>) => void) => {
|
|
@@ -24,7 +24,7 @@ export const useGetSo = (target: Ref<HTMLElement | undefined>, emit: (evt: 'chan
|
|
|
24
24
|
});
|
|
25
25
|
});
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
onBeforeUnmount(() => {
|
|
28
28
|
getso?.unset();
|
|
29
29
|
isDraging.value = false;
|
|
30
30
|
});
|
package/src/hooks/use-stage.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { computed } from 'vue';
|
|
1
|
+
import { computed, watch } from 'vue';
|
|
2
2
|
|
|
3
3
|
import type { MNode } from '@tmagic/schema';
|
|
4
4
|
import StageCore, { GuidesType, RemoveEventData, SortEventData, UpdateEventData } from '@tmagic/stage';
|
|
@@ -44,13 +44,30 @@ export const useStage = (stageOptions: StageOptions) => {
|
|
|
44
44
|
},
|
|
45
45
|
moveableOptions: stageOptions.moveableOptions,
|
|
46
46
|
updateDragEl: stageOptions.updateDragEl,
|
|
47
|
+
guidesOptions: stageOptions.guidesOptions,
|
|
48
|
+
disabledMultiSelect: stageOptions.disabledMultiSelect,
|
|
47
49
|
});
|
|
48
50
|
|
|
51
|
+
watch(
|
|
52
|
+
() => editorService.get('disabledMultiSelect'),
|
|
53
|
+
(disabledMultiSelect) => {
|
|
54
|
+
if (disabledMultiSelect) {
|
|
55
|
+
stage.disableMultiSelect();
|
|
56
|
+
} else {
|
|
57
|
+
stage.enableMultiSelect();
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
);
|
|
61
|
+
|
|
49
62
|
stage.mask.setGuides([
|
|
50
63
|
getGuideLineFromCache(getGuideLineKey(H_GUIDE_LINE_STORAGE_KEY)),
|
|
51
64
|
getGuideLineFromCache(getGuideLineKey(V_GUIDE_LINE_STORAGE_KEY)),
|
|
52
65
|
]);
|
|
53
66
|
|
|
67
|
+
stage.on('page-el-update', () => {
|
|
68
|
+
editorService.set('stageLoading', false);
|
|
69
|
+
});
|
|
70
|
+
|
|
54
71
|
stage.on('select', (el: HTMLElement) => {
|
|
55
72
|
if (`${editorService.get('node')?.id}` === el.id && editorService.get('nodes').length === 1) return;
|
|
56
73
|
editorService.select(el.id);
|
package/src/index.ts
CHANGED
|
@@ -30,6 +30,7 @@ import DataSourceMocks from './fields/DataSourceMocks.vue';
|
|
|
30
30
|
import DataSourceSelect from './fields/DataSourceSelect.vue';
|
|
31
31
|
import EventSelect from './fields/EventSelect.vue';
|
|
32
32
|
import KeyValue from './fields/KeyValue.vue';
|
|
33
|
+
import PageFragmentSelect from './fields/PageFragmentSelect.vue';
|
|
33
34
|
import uiSelect from './fields/UISelect.vue';
|
|
34
35
|
import CodeEditor from './layouts/CodeEditor.vue';
|
|
35
36
|
import { setConfig } from './utils/config';
|
|
@@ -79,6 +80,7 @@ export { default as LayoutContainer } from './components/SplitView.vue';
|
|
|
79
80
|
export { default as SplitView } from './components/SplitView.vue';
|
|
80
81
|
export { default as Resizer } from './components/Resizer.vue';
|
|
81
82
|
export { default as CodeBlockEditor } from './components/CodeBlockEditor.vue';
|
|
83
|
+
export { default as PageFragmentSelect } from './fields/PageFragmentSelect.vue';
|
|
82
84
|
|
|
83
85
|
const defaultInstallOpt: InstallOptions = {
|
|
84
86
|
// eslint-disable-next-line no-eval
|
|
@@ -108,5 +110,6 @@ export default {
|
|
|
108
110
|
app.component('m-fields-data-source-methods', DataSourceMethods);
|
|
109
111
|
app.component('m-fields-data-source-method-select', DataSourceMethodSelect);
|
|
110
112
|
app.component('m-fields-data-source-field-select', DataSourceFieldSelect);
|
|
113
|
+
app.component('m-fields-page-fragment-select', PageFragmentSelect);
|
|
111
114
|
},
|
|
112
115
|
};
|
package/src/initService.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { onBeforeUnmount, reactive, toRaw, watch } from 'vue';
|
|
2
2
|
import { cloneDeep } from 'lodash-es';
|
|
3
3
|
|
|
4
4
|
import type { EventOption } from '@tmagic/core';
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
DepTargetType,
|
|
12
12
|
Target,
|
|
13
13
|
} from '@tmagic/dep';
|
|
14
|
-
import type { CodeBlockContent, DataSourceSchema, Id, MApp, MNode, MPage } from '@tmagic/schema';
|
|
14
|
+
import type { CodeBlockContent, DataSourceSchema, Id, MApp, MNode, MPage, MPageFragment } from '@tmagic/schema';
|
|
15
15
|
import { getNodes } from '@tmagic/utils';
|
|
16
16
|
|
|
17
17
|
import PropsPanel from './layouts/PropsPanel.vue';
|
|
@@ -47,6 +47,16 @@ export const initServiceState = (
|
|
|
47
47
|
},
|
|
48
48
|
);
|
|
49
49
|
|
|
50
|
+
watch(
|
|
51
|
+
() => props.disabledMultiSelect,
|
|
52
|
+
(disabledMultiSelect) => {
|
|
53
|
+
editorService.set('disabledMultiSelect', disabledMultiSelect || false);
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
immediate: true,
|
|
57
|
+
},
|
|
58
|
+
);
|
|
59
|
+
|
|
50
60
|
watch(
|
|
51
61
|
() => props.componentGroupList,
|
|
52
62
|
(componentGroupList) => componentGroupList && componentListService.setList(componentGroupList),
|
|
@@ -165,7 +175,7 @@ export const initServiceState = (
|
|
|
165
175
|
},
|
|
166
176
|
);
|
|
167
177
|
|
|
168
|
-
|
|
178
|
+
onBeforeUnmount(() => {
|
|
169
179
|
editorService.resetState();
|
|
170
180
|
historyService.resetState();
|
|
171
181
|
propsService.resetState();
|
|
@@ -340,7 +350,7 @@ export const initServiceEvents = (
|
|
|
340
350
|
};
|
|
341
351
|
|
|
342
352
|
// 由于历史记录变化是更新整个page,所以历史记录变化时,需要重新收集依赖
|
|
343
|
-
const historyChangeHandler = (page: MPage) => {
|
|
353
|
+
const historyChangeHandler = (page: MPage | MPageFragment) => {
|
|
344
354
|
depService.collect([page], true);
|
|
345
355
|
};
|
|
346
356
|
|
|
@@ -405,7 +415,7 @@ export const initServiceEvents = (
|
|
|
405
415
|
depService.addTarget(createRelatedCompTarget(props.collectorOptions));
|
|
406
416
|
}
|
|
407
417
|
|
|
408
|
-
|
|
418
|
+
onBeforeUnmount(() => {
|
|
409
419
|
depService.off('add-target', targetAddHandler);
|
|
410
420
|
depService.off('remove-target', targetRemoveHandler);
|
|
411
421
|
depService.off('dep-update', depUpdateHandler);
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="m-editor-empty-panel">
|
|
3
3
|
<div class="m-editor-empty-content">
|
|
4
|
-
<div class="m-editor-empty-button" @click="clickHandler">
|
|
4
|
+
<div class="m-editor-empty-button" @click="clickHandler(NodeType.PAGE)">
|
|
5
5
|
<div>
|
|
6
6
|
<MIcon :icon="Plus"></MIcon>
|
|
7
7
|
</div>
|
|
8
8
|
<p>新增页面</p>
|
|
9
9
|
</div>
|
|
10
|
+
|
|
11
|
+
<div v-if="!disabledPageFragment" class="m-editor-empty-button" @click="clickHandler(NodeType.PAGE_FRAGMENT)">
|
|
12
|
+
<div>
|
|
13
|
+
<MIcon :icon="Plus"></MIcon>
|
|
14
|
+
</div>
|
|
15
|
+
<p>新增页面片</p>
|
|
16
|
+
</div>
|
|
10
17
|
</div>
|
|
11
18
|
</div>
|
|
12
19
|
</template>
|
|
@@ -25,9 +32,13 @@ defineOptions({
|
|
|
25
32
|
name: 'MEditorAddPageBox',
|
|
26
33
|
});
|
|
27
34
|
|
|
35
|
+
defineProps<{
|
|
36
|
+
disabledPageFragment: boolean;
|
|
37
|
+
}>();
|
|
38
|
+
|
|
28
39
|
const services = inject<Services>('services');
|
|
29
40
|
|
|
30
|
-
const clickHandler = () => {
|
|
41
|
+
const clickHandler = (type: NodeType.PAGE | NodeType.PAGE_FRAGMENT) => {
|
|
31
42
|
const { editorService } = services || {};
|
|
32
43
|
|
|
33
44
|
if (!editorService) return;
|
|
@@ -36,8 +47,9 @@ const clickHandler = () => {
|
|
|
36
47
|
if (!root) throw new Error('root 不能为空');
|
|
37
48
|
|
|
38
49
|
editorService.add({
|
|
39
|
-
type
|
|
40
|
-
name: generatePageNameByApp(root),
|
|
50
|
+
type,
|
|
51
|
+
name: generatePageNameByApp(root, type),
|
|
52
|
+
items: [],
|
|
41
53
|
});
|
|
42
54
|
};
|
|
43
55
|
</script>
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
</template>
|
|
20
20
|
|
|
21
21
|
<script lang="ts" setup>
|
|
22
|
-
import {
|
|
22
|
+
import { onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
|
23
23
|
import { FullScreen } from '@element-plus/icons-vue';
|
|
24
24
|
import { throttle } from 'lodash-es';
|
|
25
25
|
import * as monaco from 'monaco-editor';
|
|
@@ -188,7 +188,7 @@ onMounted(async () => {
|
|
|
188
188
|
init();
|
|
189
189
|
});
|
|
190
190
|
|
|
191
|
-
|
|
191
|
+
onBeforeUnmount(() => {
|
|
192
192
|
resizeObserver.disconnect();
|
|
193
193
|
});
|
|
194
194
|
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
</slot>
|
|
12
12
|
|
|
13
13
|
<SplitView
|
|
14
|
+
v-loading="stageLoading"
|
|
15
|
+
element-loading-text="Runtime 加载中..."
|
|
14
16
|
v-else
|
|
15
17
|
ref="splitView"
|
|
16
18
|
class="m-editor-content"
|
|
@@ -29,13 +31,20 @@
|
|
|
29
31
|
</template>
|
|
30
32
|
|
|
31
33
|
<template #center>
|
|
32
|
-
<slot v-if="
|
|
34
|
+
<slot v-if="page" name="workspace"></slot>
|
|
33
35
|
<slot v-else name="empty">
|
|
34
|
-
<AddPageBox></AddPageBox>
|
|
36
|
+
<AddPageBox :disabled-page-fragment="disabledPageFragment"></AddPageBox>
|
|
37
|
+
</slot>
|
|
38
|
+
|
|
39
|
+
<slot name="page-bar">
|
|
40
|
+
<PageBar :disabled-page-fragment="disabledPageFragment">
|
|
41
|
+
<template #page-bar-title="{ page }"><slot name="page-bar-title" :page="page"></slot></template>
|
|
42
|
+
<template #page-bar-popover="{ page }"><slot name="page-bar-popover" :page="page"></slot></template>
|
|
43
|
+
</PageBar>
|
|
35
44
|
</slot>
|
|
36
45
|
</template>
|
|
37
46
|
|
|
38
|
-
<template v-if="
|
|
47
|
+
<template v-if="page" #right>
|
|
39
48
|
<TMagicScrollbar>
|
|
40
49
|
<slot name="props-panel"></slot>
|
|
41
50
|
</TMagicScrollbar>
|
|
@@ -56,6 +65,7 @@ import SplitView from '@editor/components/SplitView.vue';
|
|
|
56
65
|
import type { FrameworkSlots, GetColumnWidth, Services } from '@editor/type';
|
|
57
66
|
import { getConfig } from '@editor/utils/config';
|
|
58
67
|
|
|
68
|
+
import PageBar from './page-bar/PageBar.vue';
|
|
59
69
|
import AddPageBox from './AddPageBox.vue';
|
|
60
70
|
import CodeEditor from './CodeEditor.vue';
|
|
61
71
|
|
|
@@ -65,6 +75,10 @@ defineOptions({
|
|
|
65
75
|
name: 'MEditorFramework',
|
|
66
76
|
});
|
|
67
77
|
|
|
78
|
+
defineProps<{
|
|
79
|
+
disabledPageFragment: boolean;
|
|
80
|
+
}>();
|
|
81
|
+
|
|
68
82
|
const DEFAULT_LEFT_COLUMN_WIDTH = 310;
|
|
69
83
|
const DEFAULT_RIGHT_COLUMN_WIDTH = 480;
|
|
70
84
|
|
|
@@ -75,8 +89,10 @@ const content = ref<HTMLDivElement>();
|
|
|
75
89
|
const splitView = ref<InstanceType<typeof SplitView>>();
|
|
76
90
|
|
|
77
91
|
const root = computed(() => editorService?.get('root'));
|
|
92
|
+
const page = computed(() => editorService?.get('page'));
|
|
78
93
|
|
|
79
94
|
const pageLength = computed(() => editorService?.get('pageLength') || 0);
|
|
95
|
+
const stageLoading = computed(() => editorService?.get('stageLoading') || false);
|
|
80
96
|
const showSrc = computed(() => uiService?.get('showSrc'));
|
|
81
97
|
|
|
82
98
|
const LEFT_COLUMN_WIDTH_STORAGE_KEY = '$MagicEditorLeftColumnWidthData';
|