@tmagic/editor 1.3.4 → 1.3.6
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 +73 -51
- package/dist/tmagic-editor.js +1171 -1102
- package/dist/tmagic-editor.js.map +1 -1
- package/dist/tmagic-editor.umd.cjs +1188 -1119
- package/dist/tmagic-editor.umd.cjs.map +1 -1
- package/package.json +17 -17
- package/src/Editor.vue +5 -0
- package/src/components/FloatingBox.vue +117 -0
- package/src/components/Tree.vue +5 -0
- package/src/components/TreeNode.vue +8 -2
- package/src/editorProps.ts +7 -0
- package/src/hooks/use-filter.ts +55 -0
- package/src/hooks/use-node-status.ts +48 -0
- package/src/hooks/use-stage.ts +1 -0
- package/src/initService.ts +28 -12
- package/src/layouts/sidebar/Sidebar.vue +7 -2
- package/src/layouts/sidebar/code-block/CodeBlockList.vue +55 -65
- package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +2 -1
- package/src/layouts/sidebar/data-source/DataSourceList.vue +63 -59
- package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +1 -1
- package/src/layouts/sidebar/layer/LayerPanel.vue +24 -7
- package/src/layouts/sidebar/layer/use-node-status.ts +8 -11
- package/src/layouts/workspace/viewer/NodeListMenu.vue +67 -128
- package/src/layouts/workspace/viewer/Stage.vue +2 -1
- package/src/layouts/workspace/viewer/ViewerMenu.vue +1 -6
- package/src/services/BaseService.ts +63 -26
- package/src/services/codeBlock.ts +7 -1
- package/src/services/dep.ts +12 -8
- package/src/services/editor.ts +66 -30
- package/src/services/props.ts +70 -12
- package/src/services/storage.ts +23 -13
- package/src/services/ui.ts +4 -1
- package/src/theme/floating-box.scss +30 -0
- package/src/theme/layer-panel.scss +19 -0
- package/src/theme/stage.scss +24 -0
- package/src/theme/theme.scss +1 -1
- package/src/theme/tree.scss +12 -1
- package/src/type.ts +6 -3
- package/src/utils/compose.ts +25 -6
- package/src/utils/content-menu.ts +4 -5
- package/src/utils/editor.ts +12 -3
- package/src/utils/operator.ts +1 -2
- package/types/components/CodeBlockEditor.vue.d.ts +6 -2
- package/types/components/CodeParams.vue.d.ts +3 -1
- package/types/components/ContentMenu.vue.d.ts +13 -5
- package/types/components/FloatingBox.vue.d.ts +78 -0
- package/types/components/Resizer.vue.d.ts +6 -1
- package/types/components/ScrollBar.vue.d.ts +3 -1
- package/types/components/ScrollViewer.vue.d.ts +3 -3
- package/types/components/SearchInput.vue.d.ts +3 -1
- package/types/components/SplitView.vue.d.ts +8 -4
- package/types/components/ToolButton.vue.d.ts +1 -1
- package/types/components/Tree.vue.d.ts +27 -8
- package/types/components/TreeNode.vue.d.ts +24 -7
- package/types/editorProps.d.ts +7 -1
- package/types/fields/Code.vue.d.ts +6 -2
- package/types/fields/CodeLink.vue.d.ts +5 -3
- package/types/fields/CodeSelect.vue.d.ts +3 -1
- package/types/fields/CodeSelectCol.vue.d.ts +3 -1
- package/types/fields/DataSourceFieldSelect.vue.d.ts +3 -1
- package/types/fields/DataSourceFields.vue.d.ts +5 -3
- package/types/fields/DataSourceInput.vue.d.ts +8 -4
- package/types/fields/DataSourceMethodSelect.vue.d.ts +3 -1
- package/types/fields/DataSourceMethods.vue.d.ts +5 -3
- package/types/fields/DataSourceMocks.vue.d.ts +5 -3
- package/types/fields/DataSourceSelect.vue.d.ts +5 -3
- package/types/fields/EventSelect.vue.d.ts +3 -1
- package/types/fields/KeyValue.vue.d.ts +2 -2
- package/types/fields/UISelect.vue.d.ts +3 -1
- package/types/hooks/use-code-block-edit.d.ts +14 -5
- package/types/hooks/use-data-source-method.d.ts +14 -5
- package/types/hooks/use-filter.d.ts +7 -0
- package/types/hooks/use-node-status.d.ts +6 -0
- package/types/layouts/CodeEditor.vue.d.ts +4 -1
- package/types/layouts/Framework.vue.d.ts +1 -1
- package/types/layouts/PropsPanel.vue.d.ts +10 -4
- package/types/layouts/sidebar/ComponentListPanel.vue.d.ts +1 -1
- package/types/layouts/sidebar/Sidebar.vue.d.ts +5 -5
- package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +9 -3
- package/types/layouts/sidebar/code-block/CodeBlockListPanel.vue.d.ts +1 -1
- package/types/layouts/sidebar/data-source/DataSourceConfigPanel.vue.d.ts +3 -1
- package/types/layouts/sidebar/data-source/DataSourceList.vue.d.ts +8 -2
- package/types/layouts/sidebar/data-source/DataSourceListPanel.vue.d.ts +1 -1
- package/types/layouts/sidebar/layer/LayerMenu.vue.d.ts +6 -2
- package/types/layouts/sidebar/layer/LayerPanel.vue.d.ts +1 -1
- package/types/layouts/sidebar/layer/use-click.d.ts +14 -5
- package/types/layouts/sidebar/layer/use-node-status.d.ts +3 -4
- package/types/layouts/workspace/Workspace.vue.d.ts +1 -1
- package/types/layouts/workspace/viewer/NodeListMenu.vue.d.ts +1 -14
- package/types/layouts/workspace/viewer/ViewerMenu.vue.d.ts +1 -1
- package/types/services/BaseService.d.ts +4 -1
- package/types/services/dep.d.ts +6 -5
- package/types/services/editor.d.ts +9 -3
- package/types/services/props.d.ts +25 -1
- package/types/services/storage.d.ts +7 -7
- package/types/type.d.ts +8 -6
- package/types/utils/compose.d.ts +1 -1
- package/types/utils/editor.d.ts +5 -1
- package/src/layouts/sidebar/layer/use-filter.ts +0 -59
- package/src/layouts/workspace/viewer/NodeListMenuTitle.vue +0 -68
- package/src/theme/dep-list.scss +0 -59
- package/types/layouts/sidebar/layer/use-filter.d.ts +0 -7
- package/types/layouts/workspace/viewer/NodeListMenuTitle.vue.d.ts +0 -15
package/src/services/props.ts
CHANGED
|
@@ -17,12 +17,15 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import { reactive } from 'vue';
|
|
20
|
-
import { cloneDeep, mergeWith } from 'lodash-es';
|
|
20
|
+
import { cloneDeep, get, mergeWith, set } from 'lodash-es';
|
|
21
21
|
|
|
22
|
+
import { DepTargetType } from '@tmagic/dep';
|
|
22
23
|
import type { FormConfig } from '@tmagic/form';
|
|
23
|
-
import type { MComponent, MNode } from '@tmagic/schema';
|
|
24
|
+
import type { Id, MComponent, MNode } from '@tmagic/schema';
|
|
24
25
|
import { guid, toLine } from '@tmagic/utils';
|
|
25
26
|
|
|
27
|
+
import depService from '@editor/services/dep';
|
|
28
|
+
import editorService from '@editor/services/editor';
|
|
26
29
|
import type { PropsState } from '@editor/type';
|
|
27
30
|
import { fillConfig } from '@editor/utils/props';
|
|
28
31
|
|
|
@@ -32,18 +35,19 @@ class Props extends BaseService {
|
|
|
32
35
|
private state = reactive<PropsState>({
|
|
33
36
|
propsConfigMap: {},
|
|
34
37
|
propsValueMap: {},
|
|
38
|
+
relateIdMap: {},
|
|
35
39
|
});
|
|
36
40
|
|
|
37
41
|
constructor() {
|
|
38
42
|
super([
|
|
39
|
-
'setPropsConfig',
|
|
40
|
-
'getPropsConfig',
|
|
41
|
-
'setPropsValue',
|
|
42
|
-
'getPropsValue',
|
|
43
|
-
'createId',
|
|
44
|
-
'setNewItemId',
|
|
45
|
-
'fillConfig',
|
|
46
|
-
'getDefaultPropsValue',
|
|
43
|
+
{ name: 'setPropsConfig', isAsync: true },
|
|
44
|
+
{ name: 'getPropsConfig', isAsync: true },
|
|
45
|
+
{ name: 'setPropsValue', isAsync: true },
|
|
46
|
+
{ name: 'getPropsValue', isAsync: true },
|
|
47
|
+
{ name: 'createId', isAsync: false },
|
|
48
|
+
{ name: 'setNewItemId', isAsync: true },
|
|
49
|
+
{ name: 'fillConfig', isAsync: true },
|
|
50
|
+
{ name: 'getDefaultPropsValue', isAsync: true },
|
|
47
51
|
]);
|
|
48
52
|
}
|
|
49
53
|
|
|
@@ -135,11 +139,17 @@ class Props extends BaseService {
|
|
|
135
139
|
|
|
136
140
|
/**
|
|
137
141
|
* 将组件与组件的子元素配置中的id都设置成一个新的ID
|
|
142
|
+
* 如果没有相同ID并且force为false则保持不变
|
|
138
143
|
* @param {Object} config 组件配置
|
|
144
|
+
* @param {Boolean} force 是否强制设置新的ID
|
|
139
145
|
*/
|
|
140
146
|
/* eslint no-param-reassign: ["error", { "props": false }] */
|
|
141
|
-
public async setNewItemId(config: MNode) {
|
|
142
|
-
|
|
147
|
+
public async setNewItemId(config: MNode, force = true) {
|
|
148
|
+
if (force || editorService.getNodeById(config.id)) {
|
|
149
|
+
const newId = await this.createId(config.type || 'component');
|
|
150
|
+
this.setRelateId(config.id, newId);
|
|
151
|
+
config.id = newId;
|
|
152
|
+
}
|
|
143
153
|
|
|
144
154
|
if (config.items && Array.isArray(config.items)) {
|
|
145
155
|
for (const item of config.items) {
|
|
@@ -176,11 +186,59 @@ class Props extends BaseService {
|
|
|
176
186
|
this.state.propsValueMap = {};
|
|
177
187
|
}
|
|
178
188
|
|
|
189
|
+
/**
|
|
190
|
+
* 替换关联ID
|
|
191
|
+
* @param originConfigs 原组件配置
|
|
192
|
+
* @param targetConfigs 待替换的组件配置
|
|
193
|
+
*/
|
|
194
|
+
public replaceRelateId(originConfigs: MNode[], targetConfigs: MNode[]) {
|
|
195
|
+
const relateIdMap = this.getRelateIdMap();
|
|
196
|
+
if (Object.keys(relateIdMap).length === 0) return;
|
|
197
|
+
const target = depService.getTarget(DepTargetType.RELATED_COMP_WHEN_COPY, DepTargetType.RELATED_COMP_WHEN_COPY);
|
|
198
|
+
if (!target) return;
|
|
199
|
+
originConfigs.forEach((config: MNode) => {
|
|
200
|
+
const newId = relateIdMap[config.id];
|
|
201
|
+
const targetConfig = targetConfigs.find((targetConfig) => targetConfig.id === newId);
|
|
202
|
+
if (!targetConfig) return;
|
|
203
|
+
target.deps[config.id]?.keys?.forEach((fullKey) => {
|
|
204
|
+
const relateOriginId = get(config, fullKey);
|
|
205
|
+
const relateTargetId = relateIdMap[relateOriginId];
|
|
206
|
+
if (!relateTargetId) return;
|
|
207
|
+
set(targetConfig, fullKey, relateTargetId);
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* 清除setNewItemId前后映射关系
|
|
214
|
+
*/
|
|
215
|
+
public clearRelateId() {
|
|
216
|
+
this.state.relateIdMap = {};
|
|
217
|
+
}
|
|
218
|
+
|
|
179
219
|
public destroy() {
|
|
180
220
|
this.resetState();
|
|
181
221
|
this.removeAllListeners();
|
|
182
222
|
this.removeAllPlugins();
|
|
183
223
|
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* 获取setNewItemId前后映射关系
|
|
227
|
+
* @param oldId 原组件ID
|
|
228
|
+
* @returns 新旧ID映射
|
|
229
|
+
*/
|
|
230
|
+
private getRelateIdMap() {
|
|
231
|
+
return this.state.relateIdMap;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* 记录setNewItemId前后映射关系
|
|
236
|
+
* @param oldId 原组件ID
|
|
237
|
+
* @param newId 分配的新ID
|
|
238
|
+
*/
|
|
239
|
+
private setRelateId(oldId: Id, newId: Id) {
|
|
240
|
+
this.state.relateIdMap[oldId] = newId;
|
|
241
|
+
}
|
|
184
242
|
}
|
|
185
243
|
|
|
186
244
|
export type PropsService = Props;
|
package/src/services/storage.ts
CHANGED
|
@@ -25,7 +25,14 @@ export class WebStorage extends BaseService {
|
|
|
25
25
|
private namespace = 'tmagic';
|
|
26
26
|
|
|
27
27
|
constructor() {
|
|
28
|
-
super([
|
|
28
|
+
super([
|
|
29
|
+
{ name: 'getStorage', isAsync: false },
|
|
30
|
+
{ name: 'getNamespace', isAsync: false },
|
|
31
|
+
{ name: 'clear', isAsync: false },
|
|
32
|
+
{ name: 'getItem', isAsync: false },
|
|
33
|
+
{ name: 'removeItem', isAsync: false },
|
|
34
|
+
{ name: 'setItem', isAsync: false },
|
|
35
|
+
]);
|
|
29
36
|
}
|
|
30
37
|
|
|
31
38
|
/**
|
|
@@ -38,26 +45,27 @@ export class WebStorage extends BaseService {
|
|
|
38
45
|
* },
|
|
39
46
|
* });
|
|
40
47
|
*/
|
|
41
|
-
public
|
|
48
|
+
public getStorage(): Storage {
|
|
42
49
|
return this.storage;
|
|
43
50
|
}
|
|
44
51
|
|
|
45
|
-
public
|
|
52
|
+
public getNamespace(): string {
|
|
46
53
|
return this.namespace;
|
|
47
54
|
}
|
|
48
55
|
|
|
49
56
|
/**
|
|
50
57
|
* 清理,支持storageService.usePlugin
|
|
51
58
|
*/
|
|
52
|
-
public
|
|
53
|
-
const storage =
|
|
59
|
+
public clear(): void {
|
|
60
|
+
const storage = this.getStorage();
|
|
54
61
|
storage.clear();
|
|
55
62
|
}
|
|
56
63
|
/**
|
|
57
64
|
* 获取存储项,支持storageService.usePlugin
|
|
58
65
|
*/
|
|
59
|
-
public
|
|
60
|
-
const
|
|
66
|
+
public getItem(key: string, options: Options = {}): any {
|
|
67
|
+
const storage = this.getStorage();
|
|
68
|
+
const namespace = this.getNamespace();
|
|
61
69
|
const { protocol = options.protocol, item } = this.getValueAndProtocol(
|
|
62
70
|
storage.getItem(`${options.namespace || namespace}:${key}`),
|
|
63
71
|
);
|
|
@@ -80,24 +88,26 @@ export class WebStorage extends BaseService {
|
|
|
80
88
|
/**
|
|
81
89
|
* 获取指定索引位置的key
|
|
82
90
|
*/
|
|
83
|
-
public
|
|
84
|
-
const storage =
|
|
91
|
+
public key(index: number): string | null {
|
|
92
|
+
const storage = this.getStorage();
|
|
85
93
|
return storage.key(index);
|
|
86
94
|
}
|
|
87
95
|
|
|
88
96
|
/**
|
|
89
97
|
* 移除存储项,支持storageService.usePlugin
|
|
90
98
|
*/
|
|
91
|
-
public
|
|
92
|
-
const
|
|
99
|
+
public removeItem(key: string, options: Options = {}): void {
|
|
100
|
+
const storage = this.getStorage();
|
|
101
|
+
const namespace = this.getNamespace();
|
|
93
102
|
storage.removeItem(`${options.namespace || namespace}:${key}`);
|
|
94
103
|
}
|
|
95
104
|
|
|
96
105
|
/**
|
|
97
106
|
* 设置存储项,支持storageService.usePlugin
|
|
98
107
|
*/
|
|
99
|
-
public
|
|
100
|
-
const
|
|
108
|
+
public setItem(key: string, value: any, options: Options = {}): void {
|
|
109
|
+
const storage = this.getStorage();
|
|
110
|
+
const namespace = this.getNamespace();
|
|
101
111
|
let item = value;
|
|
102
112
|
const protocol = options.protocol ? `${options.protocol}:` : '';
|
|
103
113
|
if (typeof value === Protocol.STRING || typeof value === Protocol.NUMBER) {
|
package/src/services/ui.ts
CHANGED
|
@@ -52,7 +52,10 @@ const state = reactive<UiState>({
|
|
|
52
52
|
|
|
53
53
|
class Ui extends BaseService {
|
|
54
54
|
constructor() {
|
|
55
|
-
super([
|
|
55
|
+
super([
|
|
56
|
+
{ name: 'zoom', isAsync: true },
|
|
57
|
+
{ name: 'calcZoom', isAsync: true },
|
|
58
|
+
]);
|
|
56
59
|
}
|
|
57
60
|
|
|
58
61
|
public set<K extends keyof UiState, T extends UiState[K]>(name: K, value: T) {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
.m-editor-float-box {
|
|
2
|
+
position: absolute;
|
|
3
|
+
background-color: #fff;
|
|
4
|
+
z-index: 100;
|
|
5
|
+
border: 1px solid $--border-color;
|
|
6
|
+
display: flex;
|
|
7
|
+
flex-direction: column;
|
|
8
|
+
|
|
9
|
+
.m-editor-float-box-title {
|
|
10
|
+
text-align: center;
|
|
11
|
+
font-size: 14px;
|
|
12
|
+
font-weight: 600;
|
|
13
|
+
padding: 5px;
|
|
14
|
+
cursor: move;
|
|
15
|
+
display: flex;
|
|
16
|
+
justify-content: space-between;
|
|
17
|
+
align-items: center;
|
|
18
|
+
border-bottom: 1px solid $--border-color;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.m-editor-float-box-body {
|
|
22
|
+
padding: 5px;
|
|
23
|
+
flex: 1;
|
|
24
|
+
overflow: auto;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.m-editor-floating-box-moveable {
|
|
29
|
+
opacity: 0;
|
|
30
|
+
}
|
|
@@ -4,4 +4,23 @@
|
|
|
4
4
|
.m-editor-tree {
|
|
5
5
|
padding-top: 48px;
|
|
6
6
|
}
|
|
7
|
+
|
|
8
|
+
.search-wrapper {
|
|
9
|
+
display: flex;
|
|
10
|
+
align-items: center;
|
|
11
|
+
justify-content: center;
|
|
12
|
+
position: absolute;
|
|
13
|
+
top: 0;
|
|
14
|
+
width: 100%;
|
|
15
|
+
z-index: 1;
|
|
16
|
+
|
|
17
|
+
.search-input {
|
|
18
|
+
flex: 1;
|
|
19
|
+
position: relative;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.tmagic-design-button {
|
|
23
|
+
margin-right: 10px;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
7
26
|
}
|
package/src/theme/stage.scss
CHANGED
|
@@ -25,3 +25,27 @@
|
|
|
25
25
|
width: 0 !important;
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
+
|
|
29
|
+
.m-editor-stage-float-button {
|
|
30
|
+
cursor: pointer;
|
|
31
|
+
transform: translateY(-50%);
|
|
32
|
+
width: 12px;
|
|
33
|
+
font-size: 12px;
|
|
34
|
+
line-height: 1.2;
|
|
35
|
+
position: absolute;
|
|
36
|
+
left: 100%;
|
|
37
|
+
top: 50%;
|
|
38
|
+
padding: 5px;
|
|
39
|
+
background-color: #ffffff;
|
|
40
|
+
transition: background-color 0.2s;
|
|
41
|
+
color: rgba(0, 0, 0, 0.88);
|
|
42
|
+
box-shadow: 0 6px 16px 0 rgba(0, 0, 0, 0.08),
|
|
43
|
+
0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 9px 28px 8px rgba(0, 0, 0, 0.05);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.m-editor-node-list-menu {
|
|
47
|
+
height: 100%;
|
|
48
|
+
width: 100%;
|
|
49
|
+
min-width: 300px;
|
|
50
|
+
max-height: 500px;
|
|
51
|
+
}
|
package/src/theme/theme.scss
CHANGED
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
@import "./event.scss";
|
|
17
17
|
@import "./layout.scss";
|
|
18
18
|
@import "./breadcrumb.scss";
|
|
19
|
-
@import "./dep-list.scss";
|
|
20
19
|
@import "./data-source.scss";
|
|
21
20
|
@import "./data-source-fields.scss";
|
|
22
21
|
@import "./data-source-methods.scss";
|
|
@@ -24,3 +23,4 @@
|
|
|
24
23
|
@import "./key-value.scss";
|
|
25
24
|
@import "./floatbox.scss";
|
|
26
25
|
@import "./tree.scss";
|
|
26
|
+
@import "./floating-box.scss";
|
package/src/theme/tree.scss
CHANGED
|
@@ -59,13 +59,24 @@
|
|
|
59
59
|
width: 100px;
|
|
60
60
|
overflow: hidden;
|
|
61
61
|
text-overflow: ellipsis;
|
|
62
|
+
|
|
63
|
+
.disabled {
|
|
64
|
+
cursor: default;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.hook {
|
|
68
|
+
color: #999;
|
|
69
|
+
}
|
|
62
70
|
}
|
|
63
71
|
}
|
|
64
72
|
|
|
65
73
|
.tree-node-tool {
|
|
66
|
-
margin-right: 15px;
|
|
67
74
|
display: flex;
|
|
68
75
|
align-items: center;
|
|
76
|
+
|
|
77
|
+
.tmagic-design-icon {
|
|
78
|
+
margin-right: 10px;
|
|
79
|
+
}
|
|
69
80
|
}
|
|
70
81
|
}
|
|
71
82
|
}
|
package/src/type.ts
CHANGED
|
@@ -25,6 +25,7 @@ import type {
|
|
|
25
25
|
ContainerHighlightType,
|
|
26
26
|
CustomizeMoveableOptionsCallbackConfig,
|
|
27
27
|
MoveableOptions,
|
|
28
|
+
RenderType,
|
|
28
29
|
UpdateDragEl,
|
|
29
30
|
} from '@tmagic/stage';
|
|
30
31
|
|
|
@@ -72,7 +73,7 @@ export interface CodeBlockListPanelSlots extends CodeBlockListSlots {
|
|
|
72
73
|
}
|
|
73
74
|
|
|
74
75
|
export interface CodeBlockListSlots {
|
|
75
|
-
'code-block-panel-tool'(props: { id: Id; data:
|
|
76
|
+
'code-block-panel-tool'(props: { id: Id; data: any }): any;
|
|
76
77
|
}
|
|
77
78
|
|
|
78
79
|
export interface DataSourceListSlots {
|
|
@@ -81,12 +82,12 @@ export interface DataSourceListSlots {
|
|
|
81
82
|
|
|
82
83
|
export interface LayerNodeSlots {
|
|
83
84
|
'layer-node-content'(props: { data: MNode }): any;
|
|
85
|
+
'layer-node-tool'(props: { data: MNode }): any;
|
|
86
|
+
'layer-node-label'(props: { data: MNode }): any;
|
|
84
87
|
}
|
|
85
88
|
|
|
86
89
|
export interface LayerPanelSlots extends LayerNodeSlots {
|
|
87
90
|
'layer-panel-header'(props: {}): any;
|
|
88
|
-
'layer-node-tool'(props: { data: MNode }): any;
|
|
89
|
-
'layer-node-content'(props: { data: MNode }): any;
|
|
90
91
|
}
|
|
91
92
|
|
|
92
93
|
export interface PropsPanelSlots {
|
|
@@ -129,6 +130,7 @@ export interface StageOptions {
|
|
|
129
130
|
canSelect: (el: HTMLElement) => boolean | Promise<boolean>;
|
|
130
131
|
isContainer: (el: HTMLElement) => boolean | Promise<boolean>;
|
|
131
132
|
updateDragEl: UpdateDragEl;
|
|
133
|
+
renderType: RenderType;
|
|
132
134
|
}
|
|
133
135
|
|
|
134
136
|
export interface StoreState {
|
|
@@ -148,6 +150,7 @@ export type StoreStateKey = keyof StoreState;
|
|
|
148
150
|
export interface PropsState {
|
|
149
151
|
propsConfigMap: Record<string, FormConfig>;
|
|
150
152
|
propsValueMap: Record<string, Partial<MNode>>;
|
|
153
|
+
relateIdMap: Record<Id, Id>;
|
|
151
154
|
}
|
|
152
155
|
|
|
153
156
|
export interface ComponentGroupState {
|
package/src/utils/compose.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @param {Array} middleware
|
|
3
3
|
* @return {Function}
|
|
4
4
|
*/
|
|
5
|
-
export const compose = (middleware: Function[]) => {
|
|
5
|
+
export const compose = (middleware: Function[], isAsync: boolean) => {
|
|
6
6
|
if (!Array.isArray(middleware)) throw new TypeError('Middleware 必须是一个数组!');
|
|
7
7
|
for (const fn of middleware) {
|
|
8
8
|
if (typeof fn !== 'function') throw new TypeError('Middleware 必须由函数组成!');
|
|
@@ -17,16 +17,35 @@ export const compose = (middleware: Function[]) => {
|
|
|
17
17
|
// last called middleware #
|
|
18
18
|
let index = -1;
|
|
19
19
|
return dispatch(0);
|
|
20
|
-
function dispatch(i: number): Promise<void> {
|
|
21
|
-
if (i <= index)
|
|
20
|
+
function dispatch(i: number): Promise<void> | void {
|
|
21
|
+
if (i <= index) {
|
|
22
|
+
const error = new Error('next() 被多次调用');
|
|
23
|
+
if (isAsync) {
|
|
24
|
+
return Promise.reject(error);
|
|
25
|
+
}
|
|
26
|
+
throw error;
|
|
27
|
+
}
|
|
22
28
|
index = i;
|
|
23
29
|
let fn = middleware[i];
|
|
24
30
|
if (i === middleware.length && next) fn = next;
|
|
25
|
-
if (!fn)
|
|
31
|
+
if (!fn) {
|
|
32
|
+
if (isAsync) {
|
|
33
|
+
return Promise.resolve();
|
|
34
|
+
}
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (isAsync) {
|
|
39
|
+
try {
|
|
40
|
+
return Promise.resolve(fn(...args, dispatch.bind(null, i + 1)));
|
|
41
|
+
} catch (err) {
|
|
42
|
+
return Promise.reject(err);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
26
45
|
try {
|
|
27
|
-
return
|
|
46
|
+
return fn(...args, dispatch.bind(null, i + 1));
|
|
28
47
|
} catch (err) {
|
|
29
|
-
|
|
48
|
+
throw err;
|
|
30
49
|
}
|
|
31
50
|
}
|
|
32
51
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { computed, markRaw, Ref
|
|
1
|
+
import { computed, markRaw, Ref } from 'vue';
|
|
2
2
|
import { CopyDocument, Delete, DocumentCopy } from '@element-plus/icons-vue';
|
|
3
3
|
|
|
4
4
|
import { Id, MContainer, NodeType } from '@tmagic/schema';
|
|
@@ -7,6 +7,8 @@ import { isPage } from '@tmagic/utils';
|
|
|
7
7
|
import ContentMenu from '@editor/components/ContentMenu.vue';
|
|
8
8
|
import type { MenuButton, Services } from '@editor/type';
|
|
9
9
|
|
|
10
|
+
import { COPY_STORAGE_KEY } from './editor';
|
|
11
|
+
|
|
10
12
|
export const useDeleteMenu = (): MenuButton => ({
|
|
11
13
|
type: 'button',
|
|
12
14
|
text: '删除',
|
|
@@ -21,8 +23,6 @@ export const useDeleteMenu = (): MenuButton => ({
|
|
|
21
23
|
},
|
|
22
24
|
});
|
|
23
25
|
|
|
24
|
-
const canPaste = ref(false);
|
|
25
|
-
|
|
26
26
|
export const useCopyMenu = (): MenuButton => ({
|
|
27
27
|
type: 'button',
|
|
28
28
|
text: '复制',
|
|
@@ -30,7 +30,6 @@ export const useCopyMenu = (): MenuButton => ({
|
|
|
30
30
|
handler: (services) => {
|
|
31
31
|
const nodes = services?.editorService?.get('nodes');
|
|
32
32
|
nodes && services?.editorService?.copy(nodes);
|
|
33
|
-
canPaste.value = true;
|
|
34
33
|
},
|
|
35
34
|
});
|
|
36
35
|
|
|
@@ -38,7 +37,7 @@ export const usePasteMenu = (menu?: Ref<InstanceType<typeof ContentMenu> | undef
|
|
|
38
37
|
type: 'button',
|
|
39
38
|
text: '粘贴',
|
|
40
39
|
icon: markRaw(DocumentCopy),
|
|
41
|
-
display: () =>
|
|
40
|
+
display: (services) => !!services?.storageService?.getItem(COPY_STORAGE_KEY),
|
|
42
41
|
handler: (services) => {
|
|
43
42
|
const nodes = services?.editorService?.get('nodes');
|
|
44
43
|
if (!nodes || nodes.length === 0) return;
|
package/src/utils/editor.ts
CHANGED
|
@@ -257,13 +257,22 @@ export const serializeConfig = (config: any) =>
|
|
|
257
257
|
unsafe: true,
|
|
258
258
|
}).replace(/"(\w+)":\s/g, '$1: ');
|
|
259
259
|
|
|
260
|
-
export
|
|
260
|
+
export interface NodeItem {
|
|
261
|
+
items?: NodeItem[];
|
|
262
|
+
[key: string]: any;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export const traverseNode = <T extends NodeItem = NodeItem>(
|
|
266
|
+
node: T,
|
|
267
|
+
cb: (node: T, parents: T[]) => void,
|
|
268
|
+
parents: T[] = [],
|
|
269
|
+
) => {
|
|
261
270
|
cb(node, parents);
|
|
262
271
|
|
|
263
272
|
if (node.items?.length) {
|
|
264
273
|
parents.push(node);
|
|
265
|
-
node.items.forEach((item
|
|
266
|
-
traverseNode(item, cb, parents);
|
|
274
|
+
node.items.forEach((item) => {
|
|
275
|
+
traverseNode(item as T, cb, [...parents]);
|
|
267
276
|
});
|
|
268
277
|
}
|
|
269
278
|
};
|
package/src/utils/operator.ts
CHANGED
|
@@ -40,8 +40,7 @@ export const beforePaste = async (position: PastePosition, config: MNode[]): Pro
|
|
|
40
40
|
if (pastePosition.top && configItem.style?.top) {
|
|
41
41
|
pastePosition.top = configItem.style?.top - referenceTop + pastePosition.top;
|
|
42
42
|
}
|
|
43
|
-
|
|
44
|
-
const pasteConfig = await propsService.setNewItemId(configItem);
|
|
43
|
+
const pasteConfig = await propsService.setNewItemId(configItem, false);
|
|
45
44
|
|
|
46
45
|
if (pasteConfig.style) {
|
|
47
46
|
const { left, top } = pasteConfig.style;
|
|
@@ -9,13 +9,17 @@ declare const _default: import("vue").DefineComponent<__VLS_TypePropsToRuntimePr
|
|
|
9
9
|
}>, {
|
|
10
10
|
show(): void;
|
|
11
11
|
hide(): void;
|
|
12
|
-
}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
12
|
+
}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
13
|
+
submit: (values: CodeBlockContent) => void;
|
|
14
|
+
}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{
|
|
13
15
|
content: CodeBlockContent;
|
|
14
16
|
disabled?: boolean | undefined;
|
|
15
17
|
isDataSource?: boolean | undefined;
|
|
16
18
|
dataSourceType?: string | undefined;
|
|
17
19
|
slideType?: SlideType | undefined;
|
|
18
|
-
}
|
|
20
|
+
}>>> & {
|
|
21
|
+
onSubmit?: ((values: CodeBlockContent) => any) | undefined;
|
|
22
|
+
}, {}, {}>;
|
|
19
23
|
export default _default;
|
|
20
24
|
type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
|
|
21
25
|
type __VLS_TypePropsToRuntimeProps<T> = {
|
|
@@ -5,7 +5,9 @@ declare const _default: import("vue").DefineComponent<__VLS_TypePropsToRuntimePr
|
|
|
5
5
|
disabled?: boolean | undefined;
|
|
6
6
|
name: string;
|
|
7
7
|
paramsConfig: CodeParamStatement[];
|
|
8
|
-
}>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin,
|
|
8
|
+
}>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
9
|
+
change: (...args: any[]) => void;
|
|
10
|
+
}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{
|
|
9
11
|
model: any;
|
|
10
12
|
size?: "default" | "small" | "large" | undefined;
|
|
11
13
|
disabled?: boolean | undefined;
|
|
@@ -24,7 +24,11 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
|
|
|
24
24
|
clientY: number;
|
|
25
25
|
clientX: number;
|
|
26
26
|
}) => void;
|
|
27
|
-
}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
27
|
+
}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
28
|
+
mouseenter: () => void;
|
|
29
|
+
show: () => void;
|
|
30
|
+
hide: () => void;
|
|
31
|
+
}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
|
|
28
32
|
menuData?: (MenuButton | MenuComponent)[] | undefined;
|
|
29
33
|
isSubMenu?: boolean | undefined;
|
|
30
34
|
active?: string | number | undefined;
|
|
@@ -33,7 +37,11 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
|
|
|
33
37
|
menuData: () => never[];
|
|
34
38
|
isSubMenu: boolean;
|
|
35
39
|
autoHide: boolean;
|
|
36
|
-
}
|
|
40
|
+
}>>> & {
|
|
41
|
+
onMouseenter?: (() => any) | undefined;
|
|
42
|
+
onShow?: (() => any) | undefined;
|
|
43
|
+
onHide?: (() => any) | undefined;
|
|
44
|
+
}, {
|
|
37
45
|
menuData: (MenuButton | MenuComponent)[];
|
|
38
46
|
isSubMenu: boolean;
|
|
39
47
|
autoHide: boolean;
|
|
@@ -55,11 +63,11 @@ type __VLS_WithDefaults<P, D> = {
|
|
|
55
63
|
default: D[K];
|
|
56
64
|
}> : P[K];
|
|
57
65
|
};
|
|
66
|
+
type __VLS_Prettify<T> = {
|
|
67
|
+
[K in keyof T]: T[K];
|
|
68
|
+
} & {};
|
|
58
69
|
type __VLS_WithTemplateSlots<T, S> = T & {
|
|
59
70
|
new (): {
|
|
60
71
|
$slots: S;
|
|
61
72
|
};
|
|
62
73
|
};
|
|
63
|
-
type __VLS_Prettify<T> = {
|
|
64
|
-
[K in keyof T]: T[K];
|
|
65
|
-
} & {};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
interface Position {
|
|
2
|
+
left: number;
|
|
3
|
+
top: number;
|
|
4
|
+
}
|
|
5
|
+
interface Rect {
|
|
6
|
+
width: number | string;
|
|
7
|
+
height: number | string;
|
|
8
|
+
}
|
|
9
|
+
declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
|
|
10
|
+
visible: boolean;
|
|
11
|
+
position?: Position | undefined;
|
|
12
|
+
rect?: Rect | undefined;
|
|
13
|
+
title?: string | undefined;
|
|
14
|
+
}>, {
|
|
15
|
+
visible: boolean;
|
|
16
|
+
title: string;
|
|
17
|
+
position: () => {
|
|
18
|
+
left: number;
|
|
19
|
+
top: number;
|
|
20
|
+
};
|
|
21
|
+
rect: () => {
|
|
22
|
+
width: string;
|
|
23
|
+
height: string;
|
|
24
|
+
};
|
|
25
|
+
}>, {
|
|
26
|
+
target: import("vue").Ref<HTMLDivElement | undefined>;
|
|
27
|
+
}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
28
|
+
"update:visible": (args_0: boolean) => void;
|
|
29
|
+
}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
|
|
30
|
+
visible: boolean;
|
|
31
|
+
position?: Position | undefined;
|
|
32
|
+
rect?: Rect | undefined;
|
|
33
|
+
title?: string | undefined;
|
|
34
|
+
}>, {
|
|
35
|
+
visible: boolean;
|
|
36
|
+
title: string;
|
|
37
|
+
position: () => {
|
|
38
|
+
left: number;
|
|
39
|
+
top: number;
|
|
40
|
+
};
|
|
41
|
+
rect: () => {
|
|
42
|
+
width: string;
|
|
43
|
+
height: string;
|
|
44
|
+
};
|
|
45
|
+
}>>> & {
|
|
46
|
+
"onUpdate:visible"?: ((args_0: boolean) => any) | undefined;
|
|
47
|
+
}, {
|
|
48
|
+
title: string;
|
|
49
|
+
rect: Rect;
|
|
50
|
+
position: Position;
|
|
51
|
+
visible: boolean;
|
|
52
|
+
}, {}>, {
|
|
53
|
+
title?(_: {}): any;
|
|
54
|
+
body?(_: {}): any;
|
|
55
|
+
}>;
|
|
56
|
+
export default _default;
|
|
57
|
+
type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
|
|
58
|
+
type __VLS_TypePropsToRuntimeProps<T> = {
|
|
59
|
+
[K in keyof T]-?: {} extends Pick<T, K> ? {
|
|
60
|
+
type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
|
|
61
|
+
} : {
|
|
62
|
+
type: import('vue').PropType<T[K]>;
|
|
63
|
+
required: true;
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
type __VLS_WithDefaults<P, D> = {
|
|
67
|
+
[K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_Prettify<P[K] & {
|
|
68
|
+
default: D[K];
|
|
69
|
+
}> : P[K];
|
|
70
|
+
};
|
|
71
|
+
type __VLS_Prettify<T> = {
|
|
72
|
+
[K in keyof T]: T[K];
|
|
73
|
+
} & {};
|
|
74
|
+
type __VLS_WithTemplateSlots<T, S> = T & {
|
|
75
|
+
new (): {
|
|
76
|
+
$slots: S;
|
|
77
|
+
};
|
|
78
|
+
};
|