@tmagic/editor 1.5.0-beta.9 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/style.css +75 -16
- package/dist/tmagic-editor.js +797 -518
- package/dist/tmagic-editor.umd.cjs +802 -525
- package/package.json +12 -10
- package/src/Editor.vue +6 -1
- package/src/components/CodeBlockEditor.vue +11 -5
- package/src/components/CodeParams.vue +3 -3
- package/src/editorProps.ts +3 -1
- package/src/fields/Code.vue +1 -2
- package/src/fields/CodeSelect.vue +13 -11
- package/src/fields/CodeSelectCol.vue +32 -5
- package/src/fields/CondOpSelect.vue +5 -2
- package/src/fields/DataSourceFields.vue +31 -12
- package/src/fields/DataSourceMethods.vue +72 -14
- package/src/fields/DisplayConds.vue +8 -3
- package/src/fields/EventSelect.vue +28 -11
- package/src/fields/KeyValue.vue +15 -10
- package/src/fields/UISelect.vue +6 -3
- package/src/hooks/index.ts +0 -1
- package/src/hooks/use-code-block-edit.ts +1 -1
- package/src/hooks/use-data-source-edit.ts +3 -2
- package/src/hooks/use-filter.ts +1 -1
- package/src/hooks/use-node-status.ts +2 -2
- package/src/initService.ts +177 -74
- package/src/layouts/Framework.vue +8 -4
- package/src/layouts/PropsPanel.vue +3 -3
- package/src/layouts/page-bar/AddButton.vue +29 -9
- package/src/layouts/page-bar/PageBar.vue +78 -65
- package/src/layouts/page-bar/PageBarScrollContainer.vue +82 -96
- package/src/layouts/page-bar/PageList.vue +5 -3
- package/src/layouts/page-bar/Search.vue +67 -0
- package/src/layouts/sidebar/Sidebar.vue +3 -0
- package/src/layouts/sidebar/code-block/CodeBlockList.vue +6 -1
- package/src/layouts/sidebar/data-source/DataSourceConfigPanel.vue +7 -5
- package/src/layouts/sidebar/data-source/DataSourceList.vue +6 -1
- package/src/layouts/sidebar/layer/use-node-status.ts +2 -3
- package/src/layouts/workspace/Workspace.vue +5 -2
- package/src/layouts/workspace/viewer/Stage.vue +23 -5
- package/src/services/dataSource.ts +12 -5
- package/src/services/dep.ts +61 -13
- package/src/services/editor.ts +46 -51
- package/src/theme/page-bar.scss +38 -16
- package/src/theme/search-input.scss +1 -0
- package/src/type.ts +2 -1
- package/src/utils/data-source/formConfigs/http.ts +2 -0
- package/src/utils/data-source/index.ts +2 -2
- package/src/utils/editor.ts +78 -22
- package/src/utils/idle-task.ts +36 -4
- package/src/utils/props.ts +3 -3
- package/types/index.d.ts +835 -1169
- package/src/hooks/use-data-source-method.ts +0 -100
- package/src/layouts/page-bar/SwitchTypeButton.vue +0 -45
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
<slot name="stage">
|
|
6
6
|
<MagicStage
|
|
7
|
-
v-if="page"
|
|
7
|
+
v-if="page && (stageOptions?.render || stageOptions?.runtimeUrl)"
|
|
8
|
+
:stage-options="stageOptions"
|
|
8
9
|
:disabled-stage-overlay="disabledStageOverlay"
|
|
9
10
|
:stage-content-menu="stageContentMenu"
|
|
10
11
|
:custom-content-menu="customContentMenu"
|
|
@@ -18,7 +19,7 @@
|
|
|
18
19
|
<script lang="ts" setup>
|
|
19
20
|
import { computed, inject } from 'vue';
|
|
20
21
|
|
|
21
|
-
import type { MenuButton, MenuComponent, Services, WorkspaceSlots } from '@editor/type';
|
|
22
|
+
import type { MenuButton, MenuComponent, Services, StageOptions, WorkspaceSlots } from '@editor/type';
|
|
22
23
|
|
|
23
24
|
import MagicStage from './viewer/Stage.vue';
|
|
24
25
|
import Breadcrumb from './Breadcrumb.vue';
|
|
@@ -40,6 +41,8 @@ withDefaults(
|
|
|
40
41
|
},
|
|
41
42
|
);
|
|
42
43
|
|
|
44
|
+
const stageOptions = inject<StageOptions>('stageOptions');
|
|
45
|
+
|
|
43
46
|
const services = inject<Services>('services');
|
|
44
47
|
|
|
45
48
|
const page = computed(() => services?.editorService.get('page'));
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
class="m-editor-stage"
|
|
4
4
|
ref="stageWrap"
|
|
5
5
|
tabindex="-1"
|
|
6
|
+
v-loading="stageLoading"
|
|
7
|
+
element-loading-text="Runtime 加载中..."
|
|
6
8
|
:width="stageRect?.width"
|
|
7
9
|
:height="stageRect?.height"
|
|
8
10
|
:wrap-width="stageContainerRect?.width"
|
|
@@ -62,8 +64,9 @@ defineOptions({
|
|
|
62
64
|
name: 'MEditorStage',
|
|
63
65
|
});
|
|
64
66
|
|
|
65
|
-
withDefaults(
|
|
67
|
+
const props = withDefaults(
|
|
66
68
|
defineProps<{
|
|
69
|
+
stageOptions: StageOptions;
|
|
67
70
|
stageContentMenu: (MenuButton | MenuComponent)[];
|
|
68
71
|
disabledStageOverlay?: boolean;
|
|
69
72
|
customContentMenu?: (menus: (MenuButton | MenuComponent)[], type: string) => (MenuButton | MenuComponent)[];
|
|
@@ -77,7 +80,8 @@ let stage: StageCore | null = null;
|
|
|
77
80
|
let runtime: Runtime | null = null;
|
|
78
81
|
|
|
79
82
|
const services = inject<Services>('services');
|
|
80
|
-
|
|
83
|
+
|
|
84
|
+
const stageLoading = computed(() => services?.editorService.get('stageLoading') || false);
|
|
81
85
|
|
|
82
86
|
const stageWrap = ref<InstanceType<typeof ScrollViewer>>();
|
|
83
87
|
const stageContainer = ref<HTMLDivElement>();
|
|
@@ -96,9 +100,9 @@ watchEffect(() => {
|
|
|
96
100
|
if (stage || !page.value) return;
|
|
97
101
|
|
|
98
102
|
if (!stageContainer.value) return;
|
|
99
|
-
if (!(stageOptions?.runtimeUrl || stageOptions?.render) || !root.value) return;
|
|
103
|
+
if (!(props.stageOptions?.runtimeUrl || props.stageOptions?.render) || !root.value) return;
|
|
100
104
|
|
|
101
|
-
stage = useStage(stageOptions);
|
|
105
|
+
stage = useStage(props.stageOptions);
|
|
102
106
|
|
|
103
107
|
stage.on('select', () => {
|
|
104
108
|
stageWrap.value?.container?.focus();
|
|
@@ -125,6 +129,7 @@ watchEffect(() => {
|
|
|
125
129
|
|
|
126
130
|
onBeforeUnmount(() => {
|
|
127
131
|
stage?.destroy();
|
|
132
|
+
services?.editorService.set('stage', null);
|
|
128
133
|
});
|
|
129
134
|
|
|
130
135
|
watch(zoom, (zoom) => {
|
|
@@ -132,9 +137,20 @@ watch(zoom, (zoom) => {
|
|
|
132
137
|
stage.setZoom(zoom);
|
|
133
138
|
});
|
|
134
139
|
|
|
140
|
+
let timeoutId: NodeJS.Timeout | null = null;
|
|
135
141
|
watch(page, (page) => {
|
|
136
142
|
if (runtime && page) {
|
|
137
143
|
services?.editorService.set('stageLoading', true);
|
|
144
|
+
|
|
145
|
+
if (timeoutId) {
|
|
146
|
+
globalThis.clearTimeout(timeoutId);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
timeoutId = globalThis.setTimeout(() => {
|
|
150
|
+
services?.editorService.set('stageLoading', false);
|
|
151
|
+
timeoutId = null;
|
|
152
|
+
}, 3000);
|
|
153
|
+
|
|
138
154
|
runtime.updatePageId?.(page.id);
|
|
139
155
|
nextTick(() => {
|
|
140
156
|
stage?.select(page.id);
|
|
@@ -201,7 +217,9 @@ const dropHandler = async (e: DragEvent) => {
|
|
|
201
217
|
e.preventDefault();
|
|
202
218
|
|
|
203
219
|
const doc = stage?.renderer?.contentWindow?.document;
|
|
204
|
-
const parentEl: HTMLElement | null | undefined = doc?.querySelector(
|
|
220
|
+
const parentEl: HTMLElement | null | undefined = doc?.querySelector(
|
|
221
|
+
`.${props.stageOptions?.containerHighlightClassName}`,
|
|
222
|
+
);
|
|
205
223
|
|
|
206
224
|
let parent: MContainer | undefined | null = page.value;
|
|
207
225
|
const parentId = getIdFromEl()(parentEl);
|
|
@@ -4,7 +4,7 @@ import type { Writable } from 'type-fest';
|
|
|
4
4
|
|
|
5
5
|
import type { DataSourceSchema, EventOption, Id, MNode, TargetOptions } from '@tmagic/core';
|
|
6
6
|
import { Target, Watcher } from '@tmagic/core';
|
|
7
|
-
import type { FormConfig } from '@tmagic/form';
|
|
7
|
+
import type { ChangeRecord, FormConfig } from '@tmagic/form';
|
|
8
8
|
import { guid, toLine } from '@tmagic/utils';
|
|
9
9
|
|
|
10
10
|
import editorService from '@editor/services/editor';
|
|
@@ -115,15 +115,22 @@ class DataSource extends BaseService {
|
|
|
115
115
|
return newConfig;
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
public update(config: DataSourceSchema) {
|
|
118
|
+
public update(config: DataSourceSchema, { changeRecords = [] }: { changeRecords?: ChangeRecord[] } = {}) {
|
|
119
119
|
const dataSources = this.get('dataSources');
|
|
120
120
|
|
|
121
121
|
const index = dataSources.findIndex((ds) => ds.id === config.id);
|
|
122
|
-
dataSources[index] = cloneDeep(config);
|
|
123
122
|
|
|
124
|
-
|
|
123
|
+
const oldConfig = dataSources[index];
|
|
124
|
+
const newConfig = cloneDeep(config);
|
|
125
125
|
|
|
126
|
-
|
|
126
|
+
dataSources[index] = newConfig;
|
|
127
|
+
|
|
128
|
+
this.emit('update', newConfig, {
|
|
129
|
+
oldConfig,
|
|
130
|
+
changeRecords,
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
return newConfig;
|
|
127
134
|
}
|
|
128
135
|
|
|
129
136
|
public remove(id: string) {
|
package/src/services/dep.ts
CHANGED
|
@@ -31,11 +31,29 @@ export interface DepEvents {
|
|
|
31
31
|
collected: [nodes: MNode[], deep: boolean];
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
interface State {
|
|
35
|
+
collecting: boolean;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
type StateKey = keyof State;
|
|
39
|
+
|
|
34
40
|
const idleTask = new IdleTask<{ node: TargetNode; deep: boolean; target: Target }>();
|
|
35
41
|
|
|
36
42
|
class Dep extends BaseService {
|
|
43
|
+
private state = reactive<State>({
|
|
44
|
+
collecting: false,
|
|
45
|
+
});
|
|
46
|
+
|
|
37
47
|
private watcher = new Watcher({ initialTargets: reactive({}) });
|
|
38
48
|
|
|
49
|
+
public set<K extends StateKey, T extends State[K]>(name: K, value: T) {
|
|
50
|
+
this.state[name] = value;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public get<K extends StateKey>(name: K): State[K] {
|
|
54
|
+
return this.state[name];
|
|
55
|
+
}
|
|
56
|
+
|
|
39
57
|
public removeTargets(type: string = DepTargetType.DEFAULT) {
|
|
40
58
|
this.watcher.removeTargets(type);
|
|
41
59
|
|
|
@@ -71,33 +89,40 @@ class Dep extends BaseService {
|
|
|
71
89
|
}
|
|
72
90
|
|
|
73
91
|
public collect(nodes: MNode[], depExtendedData: DepExtendedData = {}, deep = false, type?: DepTargetType) {
|
|
92
|
+
this.set('collecting', true);
|
|
74
93
|
this.watcher.collectByCallback(nodes, type, ({ node, target }) => {
|
|
75
94
|
this.collectNode(node, target, depExtendedData, deep);
|
|
76
95
|
});
|
|
96
|
+
this.set('collecting', false);
|
|
77
97
|
|
|
78
98
|
this.emit('collected', nodes, deep);
|
|
79
99
|
}
|
|
80
100
|
|
|
81
101
|
public collectIdle(nodes: MNode[], depExtendedData: DepExtendedData = {}, deep = false, type?: DepTargetType) {
|
|
102
|
+
this.set('collecting', true);
|
|
103
|
+
let startTask = false;
|
|
82
104
|
this.watcher.collectByCallback(nodes, type, ({ node, target }) => {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
node,
|
|
89
|
-
deep,
|
|
90
|
-
target,
|
|
91
|
-
},
|
|
92
|
-
);
|
|
105
|
+
startTask = true;
|
|
106
|
+
|
|
107
|
+
this.enqueueTask(node, target, depExtendedData, deep);
|
|
93
108
|
});
|
|
94
109
|
|
|
95
|
-
|
|
96
|
-
|
|
110
|
+
return new Promise<void>((resolve) => {
|
|
111
|
+
if (!startTask) {
|
|
112
|
+
this.emit('collected', nodes, deep);
|
|
113
|
+
this.set('collecting', false);
|
|
114
|
+
resolve();
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
idleTask.once('finish', () => {
|
|
118
|
+
this.emit('collected', nodes, deep);
|
|
119
|
+
this.set('collecting', false);
|
|
120
|
+
resolve();
|
|
121
|
+
});
|
|
97
122
|
});
|
|
98
123
|
}
|
|
99
124
|
|
|
100
|
-
collectNode(node: MNode, target: Target, depExtendedData: DepExtendedData = {}, deep = false) {
|
|
125
|
+
public collectNode(node: MNode, target: Target, depExtendedData: DepExtendedData = {}, deep = false) {
|
|
101
126
|
// 先删除原有依赖,重新收集
|
|
102
127
|
if (isPage(node)) {
|
|
103
128
|
Object.entries(target.deps).forEach(([depKey, dep]) => {
|
|
@@ -128,6 +153,10 @@ class Dep extends BaseService {
|
|
|
128
153
|
return this.watcher.hasSpecifiedTypeTarget(type);
|
|
129
154
|
}
|
|
130
155
|
|
|
156
|
+
public clearIdleTasks() {
|
|
157
|
+
idleTask.clearTasks();
|
|
158
|
+
}
|
|
159
|
+
|
|
131
160
|
public on<Name extends keyof DepEvents, Param extends DepEvents[Name]>(
|
|
132
161
|
eventName: Name,
|
|
133
162
|
listener: (...args: Param) => void | Promise<void>,
|
|
@@ -145,6 +174,25 @@ class Dep extends BaseService {
|
|
|
145
174
|
public emit<Name extends keyof DepEvents, Param extends DepEvents[Name]>(eventName: Name, ...args: Param) {
|
|
146
175
|
return super.emit(eventName, ...args);
|
|
147
176
|
}
|
|
177
|
+
|
|
178
|
+
private enqueueTask(node: MNode, target: Target, depExtendedData: DepExtendedData, deep: boolean) {
|
|
179
|
+
idleTask.enqueueTask(
|
|
180
|
+
({ node, deep, target }) => {
|
|
181
|
+
this.collectNode(node, target, depExtendedData, deep);
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
node,
|
|
185
|
+
deep: false,
|
|
186
|
+
target,
|
|
187
|
+
},
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
if (deep && Array.isArray(node.items) && node.items.length) {
|
|
191
|
+
node.items.forEach((item) => {
|
|
192
|
+
this.enqueueTask(item, target, depExtendedData, deep);
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
148
196
|
}
|
|
149
197
|
|
|
150
198
|
export type DepService = Dep;
|
package/src/services/editor.ts
CHANGED
|
@@ -20,10 +20,20 @@ import { reactive, toRaw } from 'vue';
|
|
|
20
20
|
import { cloneDeep, get, isObject, mergeWith, uniq } from 'lodash-es';
|
|
21
21
|
import type { Writable } from 'type-fest';
|
|
22
22
|
|
|
23
|
-
import type { Id, MApp,
|
|
23
|
+
import type { Id, MApp, MContainer, MNode, MPage, MPageFragment, TargetOptions } from '@tmagic/core';
|
|
24
24
|
import { NodeType, Target, Watcher } from '@tmagic/core';
|
|
25
|
+
import type { ChangeRecord } from '@tmagic/form';
|
|
25
26
|
import { isFixed } from '@tmagic/stage';
|
|
26
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
calcValueByFontsize,
|
|
29
|
+
getElById,
|
|
30
|
+
getNodeInfo,
|
|
31
|
+
getNodePath,
|
|
32
|
+
isNumber,
|
|
33
|
+
isPage,
|
|
34
|
+
isPageFragment,
|
|
35
|
+
isPop,
|
|
36
|
+
} from '@tmagic/utils';
|
|
27
37
|
|
|
28
38
|
import BaseService from '@editor/services//BaseService';
|
|
29
39
|
import propsService from '@editor/services//props';
|
|
@@ -59,7 +69,7 @@ export interface EditorEvents {
|
|
|
59
69
|
select: [node: MNode | null];
|
|
60
70
|
add: [nodes: MNode[]];
|
|
61
71
|
remove: [nodes: MNode[]];
|
|
62
|
-
update: [nodes: MNode[]];
|
|
72
|
+
update: [nodes: { newNode: MNode; oldNode: MNode; changeRecords?: ChangeRecord[] }[]];
|
|
63
73
|
'move-layer': [offset: number | LayerOffset];
|
|
64
74
|
'drag-to': [data: { targetIndex: number; configs: MNode | MNode[]; targetParent: MContainer }];
|
|
65
75
|
'history-change': [data: MPage | MPageFragment];
|
|
@@ -175,36 +185,7 @@ class Editor extends BaseService {
|
|
|
175
185
|
root = toRaw(root);
|
|
176
186
|
}
|
|
177
187
|
|
|
178
|
-
|
|
179
|
-
node: null,
|
|
180
|
-
parent: null,
|
|
181
|
-
page: null,
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
if (!root) return info;
|
|
185
|
-
|
|
186
|
-
if (id === root.id) {
|
|
187
|
-
info.node = root;
|
|
188
|
-
return info;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
const path = getNodePath(id, root.items);
|
|
192
|
-
|
|
193
|
-
if (!path.length) return info;
|
|
194
|
-
|
|
195
|
-
path.unshift(root);
|
|
196
|
-
|
|
197
|
-
info.node = path[path.length - 1] as MComponent;
|
|
198
|
-
info.parent = path[path.length - 2] as MContainer;
|
|
199
|
-
|
|
200
|
-
path.forEach((item) => {
|
|
201
|
-
if (isPage(item) || isPageFragment(item)) {
|
|
202
|
-
info.page = item as MPage | MPageFragment;
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
return info;
|
|
188
|
+
return getNodeInfo(id, root);
|
|
208
189
|
}
|
|
209
190
|
|
|
210
191
|
/**
|
|
@@ -494,11 +475,11 @@ class Editor extends BaseService {
|
|
|
494
475
|
if (isPage(node)) {
|
|
495
476
|
this.state.pageLength -= 1;
|
|
496
477
|
|
|
497
|
-
await selectDefault(
|
|
478
|
+
await selectDefault(rootItems);
|
|
498
479
|
} else if (isPageFragment(node)) {
|
|
499
480
|
this.state.pageFragmentLength -= 1;
|
|
500
481
|
|
|
501
|
-
await selectDefault(
|
|
482
|
+
await selectDefault(rootItems);
|
|
502
483
|
} else {
|
|
503
484
|
await this.select(parent);
|
|
504
485
|
stage?.select(parent.id);
|
|
@@ -529,7 +510,10 @@ class Editor extends BaseService {
|
|
|
529
510
|
this.emit('remove', nodes);
|
|
530
511
|
}
|
|
531
512
|
|
|
532
|
-
public async doUpdate(
|
|
513
|
+
public async doUpdate(
|
|
514
|
+
config: MNode,
|
|
515
|
+
{ changeRecords = [] }: { changeRecords?: ChangeRecord[] } = {},
|
|
516
|
+
): Promise<{ newNode: MNode; oldNode: MNode; changeRecords?: ChangeRecord[] }> {
|
|
533
517
|
const root = this.get('root');
|
|
534
518
|
if (!root) throw new Error('root为空');
|
|
535
519
|
|
|
@@ -539,7 +523,7 @@ class Editor extends BaseService {
|
|
|
539
523
|
|
|
540
524
|
if (!info.node) throw new Error(`获取不到id为${config.id}的节点`);
|
|
541
525
|
|
|
542
|
-
const node =
|
|
526
|
+
const node = toRaw(info.node);
|
|
543
527
|
|
|
544
528
|
let newConfig = await this.toggleFixedPosition(toRaw(config), node, root);
|
|
545
529
|
|
|
@@ -561,7 +545,11 @@ class Editor extends BaseService {
|
|
|
561
545
|
|
|
562
546
|
if (newConfig.type === NodeType.ROOT) {
|
|
563
547
|
this.set('root', newConfig as MApp);
|
|
564
|
-
return
|
|
548
|
+
return {
|
|
549
|
+
oldNode: node,
|
|
550
|
+
newNode: newConfig,
|
|
551
|
+
changeRecords,
|
|
552
|
+
};
|
|
565
553
|
}
|
|
566
554
|
|
|
567
555
|
const { parent } = info;
|
|
@@ -586,11 +574,7 @@ class Editor extends BaseService {
|
|
|
586
574
|
nodes.splice(targetIndex, 1, newConfig);
|
|
587
575
|
this.set('nodes', [...nodes]);
|
|
588
576
|
|
|
589
|
-
|
|
590
|
-
config: cloneDeep(newConfig),
|
|
591
|
-
parentId: parent.id,
|
|
592
|
-
root: cloneDeep(root),
|
|
593
|
-
});
|
|
577
|
+
// update后会触发依赖收集,收集完后会掉stage.update方法
|
|
594
578
|
|
|
595
579
|
if (isPage(newConfig) || isPageFragment(newConfig)) {
|
|
596
580
|
this.set('page', newConfig as MPage | MPageFragment);
|
|
@@ -598,7 +582,11 @@ class Editor extends BaseService {
|
|
|
598
582
|
|
|
599
583
|
this.addModifiedNodeId(newConfig.id);
|
|
600
584
|
|
|
601
|
-
return
|
|
585
|
+
return {
|
|
586
|
+
oldNode: node,
|
|
587
|
+
newNode: newConfig,
|
|
588
|
+
changeRecords,
|
|
589
|
+
};
|
|
602
590
|
}
|
|
603
591
|
|
|
604
592
|
/**
|
|
@@ -606,17 +594,20 @@ class Editor extends BaseService {
|
|
|
606
594
|
* @param config 新的节点配置,配置中需要有id信息
|
|
607
595
|
* @returns 更新后的节点配置
|
|
608
596
|
*/
|
|
609
|
-
public async update(
|
|
597
|
+
public async update(
|
|
598
|
+
config: MNode | MNode[],
|
|
599
|
+
data: { changeRecords?: ChangeRecord[] } = {},
|
|
600
|
+
): Promise<MNode | MNode[]> {
|
|
610
601
|
const nodes = Array.isArray(config) ? config : [config];
|
|
611
602
|
|
|
612
|
-
const
|
|
603
|
+
const updateData = await Promise.all(nodes.map((node) => this.doUpdate(node, data)));
|
|
613
604
|
|
|
614
|
-
if (
|
|
605
|
+
if (updateData[0].oldNode?.type !== NodeType.ROOT) {
|
|
615
606
|
this.pushHistoryState();
|
|
616
607
|
}
|
|
617
608
|
|
|
618
|
-
this.emit('update',
|
|
619
|
-
return Array.isArray(config) ?
|
|
609
|
+
this.emit('update', updateData);
|
|
610
|
+
return Array.isArray(config) ? updateData.map((item) => item.newNode) : updateData[0].newNode;
|
|
620
611
|
}
|
|
621
612
|
|
|
622
613
|
/**
|
|
@@ -863,7 +854,7 @@ class Editor extends BaseService {
|
|
|
863
854
|
|
|
864
855
|
const layout = await this.getLayout(target);
|
|
865
856
|
|
|
866
|
-
const newConfig = mergeWith(cloneDeep(node), config, (
|
|
857
|
+
const newConfig = mergeWith(cloneDeep(node), config, (_objValue, srcValue) => {
|
|
867
858
|
if (Array.isArray(srcValue)) {
|
|
868
859
|
return srcValue;
|
|
869
860
|
}
|
|
@@ -875,7 +866,11 @@ class Editor extends BaseService {
|
|
|
875
866
|
await stage.select(targetId);
|
|
876
867
|
|
|
877
868
|
const targetParent = this.getParentById(target.id);
|
|
878
|
-
await stage.update({
|
|
869
|
+
await stage.update({
|
|
870
|
+
config: cloneDeep(target),
|
|
871
|
+
parentId: targetParent?.id,
|
|
872
|
+
root: cloneDeep(root),
|
|
873
|
+
});
|
|
879
874
|
|
|
880
875
|
await this.select(newConfig);
|
|
881
876
|
stage.select(newConfig.id);
|
package/src/theme/page-bar.scss
CHANGED
|
@@ -3,20 +3,7 @@
|
|
|
3
3
|
bottom: 0;
|
|
4
4
|
left: 0;
|
|
5
5
|
width: 100%;
|
|
6
|
-
|
|
7
|
-
.tmagic-design-button.m-editor-page-bar-switch-type-button {
|
|
8
|
-
margin-left: 10px;
|
|
9
|
-
position: relative;
|
|
10
|
-
top: 1px;
|
|
11
|
-
border-radius: 3px 3px 0 0;
|
|
12
|
-
border: 1px solid $--border-color;
|
|
13
|
-
border-bottom: 1px solid transparent;
|
|
14
|
-
padding: 5px 10px;
|
|
15
|
-
|
|
16
|
-
&.active {
|
|
17
|
-
background-color: #f3f3f3;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
6
|
+
user-select: none;
|
|
20
7
|
}
|
|
21
8
|
|
|
22
9
|
.m-editor-page-list-item {
|
|
@@ -70,6 +57,11 @@
|
|
|
70
57
|
&-icon {
|
|
71
58
|
position: relative;
|
|
72
59
|
z-index: 1;
|
|
60
|
+
|
|
61
|
+
.icon-active {
|
|
62
|
+
font-weight: bold;
|
|
63
|
+
color: $--theme-color;
|
|
64
|
+
}
|
|
73
65
|
}
|
|
74
66
|
|
|
75
67
|
&-title {
|
|
@@ -78,6 +70,18 @@
|
|
|
78
70
|
white-space: nowrap;
|
|
79
71
|
overflow: hidden;
|
|
80
72
|
}
|
|
73
|
+
|
|
74
|
+
&-left-icon,
|
|
75
|
+
&-right-icon {
|
|
76
|
+
position: absolute;
|
|
77
|
+
right: 0;
|
|
78
|
+
top: 0;
|
|
79
|
+
height: 100%;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
&-left-icon {
|
|
83
|
+
right: 34px;
|
|
84
|
+
}
|
|
81
85
|
}
|
|
82
86
|
}
|
|
83
87
|
|
|
@@ -91,13 +95,31 @@
|
|
|
91
95
|
transition: all 0.2s ease 0s;
|
|
92
96
|
padding: 5px 14px;
|
|
93
97
|
|
|
94
|
-
.
|
|
95
|
-
i {
|
|
98
|
+
.tmagic-design-button {
|
|
96
99
|
color: $--font-color;
|
|
97
100
|
}
|
|
98
101
|
|
|
99
102
|
&:hover {
|
|
100
103
|
background-color: $--hover-color;
|
|
101
104
|
}
|
|
105
|
+
|
|
106
|
+
&.active {
|
|
107
|
+
.tmagic-design-button {
|
|
108
|
+
color: $--theme-color;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.m-editor-page-bar-search-panel {
|
|
115
|
+
position: absolute;
|
|
116
|
+
bottom: $--page-bar-height;
|
|
117
|
+
border: 1px solid $--border-color;
|
|
118
|
+
padding: 6px 10px;
|
|
119
|
+
width: 100%;
|
|
120
|
+
box-sizing: border-box;
|
|
121
|
+
|
|
122
|
+
.tmagic-design-form-item {
|
|
123
|
+
margin-bottom: 0;
|
|
102
124
|
}
|
|
103
125
|
}
|
package/src/type.ts
CHANGED
|
@@ -77,9 +77,10 @@ export interface FrameworkSlots {
|
|
|
77
77
|
'props-panel'(props: {}): any;
|
|
78
78
|
'footer'(props: {}): any;
|
|
79
79
|
'page-bar'(props: {}): any;
|
|
80
|
+
'page-bar-add-button'(props: {}): any;
|
|
80
81
|
'page-bar-title'(props: { page: MPage | MPageFragment }): any;
|
|
81
82
|
'page-bar-popover'(props: { page: MPage | MPageFragment }): any;
|
|
82
|
-
'page-list-popover'(props: { list: MPage
|
|
83
|
+
'page-list-popover'(props: { list: (MPage | MPageFragment)[] }): any;
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
export interface WorkspaceSlots {
|
|
@@ -40,6 +40,7 @@ export default [
|
|
|
40
40
|
name: 'params',
|
|
41
41
|
type: 'key-value',
|
|
42
42
|
defaultValue: {},
|
|
43
|
+
advanced: true,
|
|
43
44
|
text: '参数',
|
|
44
45
|
},
|
|
45
46
|
{
|
|
@@ -53,6 +54,7 @@ export default [
|
|
|
53
54
|
name: 'headers',
|
|
54
55
|
type: 'key-value',
|
|
55
56
|
defaultValue: {},
|
|
57
|
+
advanced: true,
|
|
56
58
|
text: '请求头',
|
|
57
59
|
},
|
|
58
60
|
],
|
|
@@ -58,7 +58,7 @@ const fillConfig = (config: FormConfig): FormConfig => [
|
|
|
58
58
|
},
|
|
59
59
|
{
|
|
60
60
|
title: '请求参数裁剪',
|
|
61
|
-
display: (
|
|
61
|
+
display: (_formState: FormState, { model }: any) => model.type === 'http',
|
|
62
62
|
items: [
|
|
63
63
|
{
|
|
64
64
|
name: 'beforeRequest',
|
|
@@ -70,7 +70,7 @@ const fillConfig = (config: FormConfig): FormConfig => [
|
|
|
70
70
|
},
|
|
71
71
|
{
|
|
72
72
|
title: '响应数据裁剪',
|
|
73
|
-
display: (
|
|
73
|
+
display: (_formState: FormState, { model }: any) => model.type === 'http',
|
|
74
74
|
items: [
|
|
75
75
|
{
|
|
76
76
|
name: 'afterResponse',
|