@tmagic/editor 1.5.0-beta.11 → 1.5.0-beta.12
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 +15 -11
- package/dist/tmagic-editor.js +285 -281
- package/dist/tmagic-editor.umd.cjs +281 -277
- package/package.json +7 -7
- package/src/Editor.vue +1 -0
- package/src/initService.ts +94 -70
- package/src/layouts/Framework.vue +1 -0
- package/src/layouts/page-bar/AddButton.vue +29 -9
- package/src/layouts/page-bar/PageBar.vue +25 -61
- package/src/layouts/page-bar/PageBarScrollContainer.vue +45 -84
- package/src/layouts/page-bar/PageList.vue +1 -1
- package/src/layouts/page-bar/Search.vue +64 -0
- package/src/layouts/workspace/viewer/Stage.vue +11 -0
- package/src/services/dep.ts +5 -2
- package/src/services/editor.ts +20 -40
- package/src/theme/page-bar.scss +19 -12
- package/src/type.ts +2 -1
- package/src/utils/idle-task.ts +3 -2
- package/types/index.d.ts +3 -2
- package/src/layouts/page-bar/SwitchTypeButton.vue +0 -45
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.5.0-beta.
|
|
2
|
+
"version": "1.5.0-beta.12",
|
|
3
3
|
"name": "@tmagic/editor",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": [
|
|
@@ -56,11 +56,11 @@
|
|
|
56
56
|
"moveable": "^0.53.0",
|
|
57
57
|
"serialize-javascript": "^6.0.0",
|
|
58
58
|
"sortablejs": "^1.15.2",
|
|
59
|
-
"@tmagic/design": "1.5.0-beta.
|
|
60
|
-
"@tmagic/
|
|
61
|
-
"@tmagic/
|
|
62
|
-
"@tmagic/table": "1.5.0-beta.
|
|
63
|
-
"@tmagic/utils": "1.5.0-beta.
|
|
59
|
+
"@tmagic/design": "1.5.0-beta.12",
|
|
60
|
+
"@tmagic/form": "1.5.0-beta.12",
|
|
61
|
+
"@tmagic/stage": "1.5.0-beta.12",
|
|
62
|
+
"@tmagic/table": "1.5.0-beta.12",
|
|
63
|
+
"@tmagic/utils": "1.5.0-beta.12"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
66
|
"@types/events": "^3.0.0",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"monaco-editor": "^0.48.0",
|
|
82
82
|
"typescript": "*",
|
|
83
83
|
"vue": "^3.5.0",
|
|
84
|
-
"@tmagic/core": "1.5.0-beta.
|
|
84
|
+
"@tmagic/core": "1.5.0-beta.12"
|
|
85
85
|
},
|
|
86
86
|
"peerDependenciesMeta": {
|
|
87
87
|
"typescript": {
|
package/src/Editor.vue
CHANGED
|
@@ -114,6 +114,7 @@
|
|
|
114
114
|
</template>
|
|
115
115
|
|
|
116
116
|
<template #page-bar><slot name="page-bar"></slot></template>
|
|
117
|
+
<template #page-bar-add-button><slot name="page-bar-add-button"></slot></template>
|
|
117
118
|
<template #page-bar-title="{ page }"><slot name="page-bar-title" :page="page"></slot></template>
|
|
118
119
|
<template #page-bar-popover="{ page }"><slot name="page-bar-popover" :page="page"></slot></template>
|
|
119
120
|
<template #page-list-popover="{ list }"><slot name="page-list-popover" :list="list"></slot></template>
|
package/src/initService.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { onBeforeUnmount, reactive, toRaw, watch } from 'vue';
|
|
2
|
-
import { cloneDeep
|
|
2
|
+
import { cloneDeep } from 'lodash-es';
|
|
3
3
|
|
|
4
4
|
import type {
|
|
5
5
|
CodeBlockContent,
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
DepTargetType,
|
|
20
20
|
Target,
|
|
21
21
|
} from '@tmagic/core';
|
|
22
|
-
import { isPage, traverseNode } from '@tmagic/utils';
|
|
22
|
+
import { getNodes, isPage, traverseNode } from '@tmagic/utils';
|
|
23
23
|
|
|
24
24
|
import PropsPanel from './layouts/PropsPanel.vue';
|
|
25
25
|
import { EditorProps } from './editorProps';
|
|
@@ -252,63 +252,24 @@ export const initServiceEvents = (
|
|
|
252
252
|
return stage?.renderer?.runtime?.getApp?.();
|
|
253
253
|
};
|
|
254
254
|
|
|
255
|
-
const updateDataSourceSchema = () => {
|
|
256
|
-
const root = editorService.get('root');
|
|
257
|
-
|
|
258
|
-
if (root?.dataSources) {
|
|
259
|
-
getApp()?.dataSourceManager?.updateSchema(root.dataSources);
|
|
260
|
-
}
|
|
261
|
-
};
|
|
262
|
-
|
|
263
|
-
const targetAddHandler = (target: Target) => {
|
|
264
|
-
const root = editorService.get('root');
|
|
265
|
-
if (!root) return;
|
|
266
|
-
|
|
267
|
-
if (target.type === DepTargetType.DATA_SOURCE) {
|
|
268
|
-
if (!root.dataSourceDeps) {
|
|
269
|
-
root.dataSourceDeps = {};
|
|
270
|
-
}
|
|
271
|
-
root.dataSourceDeps[target.id] = target.deps;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
if (target.type === DepTargetType.DATA_SOURCE_COND) {
|
|
275
|
-
if (!root.dataSourceCondDeps) {
|
|
276
|
-
root.dataSourceCondDeps = {};
|
|
277
|
-
}
|
|
278
|
-
root.dataSourceCondDeps[target.id] = target.deps;
|
|
279
|
-
}
|
|
280
|
-
};
|
|
281
|
-
|
|
282
|
-
const targetRemoveHandler = (id: string | number) => {
|
|
255
|
+
const updateDataSourceSchema = (nodes: MNode[], deep: boolean) => {
|
|
283
256
|
const root = editorService.get('root');
|
|
257
|
+
const app = getApp();
|
|
284
258
|
|
|
285
|
-
if (root?.
|
|
286
|
-
|
|
259
|
+
if (root && app?.dsl) {
|
|
260
|
+
app.dsl.dataSourceDeps = root.dataSourceDeps;
|
|
261
|
+
app.dsl.dataSourceCondDeps = root.dataSourceCondDeps;
|
|
262
|
+
app.dsl.dataSources = root.dataSources;
|
|
287
263
|
}
|
|
288
264
|
|
|
289
|
-
if (root?.
|
|
290
|
-
|
|
265
|
+
if (root?.dataSources) {
|
|
266
|
+
getApp()?.dataSourceManager?.updateSchema(root.dataSources);
|
|
291
267
|
}
|
|
292
|
-
};
|
|
293
268
|
|
|
294
|
-
const collectedHandler = debounce((nodes: MNode[], deep: boolean) => {
|
|
295
|
-
const root = editorService.get('root');
|
|
296
269
|
const stage = editorService.get('stage');
|
|
297
270
|
|
|
298
271
|
if (!root || !stage) return;
|
|
299
272
|
|
|
300
|
-
const app = getApp();
|
|
301
|
-
|
|
302
|
-
if (!app) return;
|
|
303
|
-
|
|
304
|
-
if (app.dsl) {
|
|
305
|
-
app.dsl.dataSourceDeps = root.dataSourceDeps;
|
|
306
|
-
app.dsl.dataSourceCondDeps = root.dataSourceCondDeps;
|
|
307
|
-
app.dsl.dataSources = root.dataSources;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
updateDataSourceSchema();
|
|
311
|
-
|
|
312
273
|
const allNodes: MNode[] = [];
|
|
313
274
|
|
|
314
275
|
if (deep) {
|
|
@@ -335,11 +296,60 @@ export const initServiceEvents = (
|
|
|
335
296
|
});
|
|
336
297
|
});
|
|
337
298
|
});
|
|
338
|
-
}
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
const afterUpdateNodes = (nodes: MNode[]) => {
|
|
302
|
+
const root = editorService.get('root');
|
|
303
|
+
if (!root) return;
|
|
304
|
+
const stage = editorService.get('stage');
|
|
305
|
+
const app = getApp();
|
|
306
|
+
if (app?.dsl) {
|
|
307
|
+
app.dsl.dataSourceDeps = root.dataSourceDeps;
|
|
308
|
+
}
|
|
309
|
+
for (const node of nodes) {
|
|
310
|
+
stage?.update({
|
|
311
|
+
config: cloneDeep(node),
|
|
312
|
+
parentId: editorService.getParentById(node.id)?.id,
|
|
313
|
+
root: cloneDeep(root),
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
const targetAddHandler = (target: Target) => {
|
|
319
|
+
const root = editorService.get('root');
|
|
320
|
+
if (!root) return;
|
|
321
|
+
|
|
322
|
+
if (target.type === DepTargetType.DATA_SOURCE) {
|
|
323
|
+
if (!root.dataSourceDeps) {
|
|
324
|
+
root.dataSourceDeps = {};
|
|
325
|
+
}
|
|
326
|
+
root.dataSourceDeps[target.id] = target.deps;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (target.type === DepTargetType.DATA_SOURCE_COND) {
|
|
330
|
+
if (!root.dataSourceCondDeps) {
|
|
331
|
+
root.dataSourceCondDeps = {};
|
|
332
|
+
}
|
|
333
|
+
root.dataSourceCondDeps[target.id] = target.deps;
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
const targetRemoveHandler = (id: string | number) => {
|
|
338
|
+
const root = editorService.get('root');
|
|
339
|
+
|
|
340
|
+
if (!root) return;
|
|
341
|
+
|
|
342
|
+
if (root.dataSourceDeps) {
|
|
343
|
+
delete root.dataSourceDeps[id];
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
if (root.dataSourceCondDeps) {
|
|
347
|
+
delete root.dataSourceCondDeps[id];
|
|
348
|
+
}
|
|
349
|
+
};
|
|
339
350
|
|
|
340
351
|
depService.on('add-target', targetAddHandler);
|
|
341
352
|
depService.on('remove-target', targetRemoveHandler);
|
|
342
|
-
depService.on('collected', collectedHandler);
|
|
343
353
|
|
|
344
354
|
const initDataSourceDepTarget = (ds: DataSourceSchema) => {
|
|
345
355
|
depService.addTarget(createDataSourceTarget(ds, reactive({})));
|
|
@@ -347,28 +357,33 @@ export const initServiceEvents = (
|
|
|
347
357
|
depService.addTarget(createDataSourceCondTarget(ds, reactive({})));
|
|
348
358
|
};
|
|
349
359
|
|
|
350
|
-
const collectIdle = (nodes: MNode[], deep: boolean) =>
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
360
|
+
const collectIdle = (nodes: MNode[], deep: boolean) =>
|
|
361
|
+
Promise.all(
|
|
362
|
+
nodes.map((node) => {
|
|
363
|
+
let pageId: Id | undefined;
|
|
364
|
+
|
|
365
|
+
if (isPage(node)) {
|
|
366
|
+
pageId = node.id;
|
|
367
|
+
} else {
|
|
368
|
+
const info = editorService.getNodeInfo(node.id);
|
|
369
|
+
pageId = info.page?.id;
|
|
370
|
+
}
|
|
371
|
+
return depService.collectIdle([node], { pageId }, deep);
|
|
372
|
+
}),
|
|
373
|
+
);
|
|
363
374
|
|
|
364
375
|
// 新增节点,收集依赖
|
|
365
376
|
const nodeAddHandler = (nodes: MNode[]) => {
|
|
366
|
-
collectIdle(nodes, true)
|
|
377
|
+
collectIdle(nodes, true).then(() => {
|
|
378
|
+
afterUpdateNodes(nodes);
|
|
379
|
+
});
|
|
367
380
|
};
|
|
368
381
|
|
|
369
382
|
// 节点更新,收集依赖
|
|
370
383
|
const nodeUpdateHandler = (nodes: MNode[]) => {
|
|
371
|
-
collectIdle(nodes, true)
|
|
384
|
+
collectIdle(nodes, true).then(() => {
|
|
385
|
+
afterUpdateNodes(nodes);
|
|
386
|
+
});
|
|
372
387
|
};
|
|
373
388
|
|
|
374
389
|
// 节点删除,清除对齐的依赖收集
|
|
@@ -378,7 +393,9 @@ export const initServiceEvents = (
|
|
|
378
393
|
|
|
379
394
|
// 由于历史记录变化是更新整个page,所以历史记录变化时,需要重新收集依赖
|
|
380
395
|
const historyChangeHandler = (page: MPage | MPageFragment) => {
|
|
381
|
-
collectIdle([page], true)
|
|
396
|
+
collectIdle([page], true).then(() => {
|
|
397
|
+
updateDataSourceSchema([page], true);
|
|
398
|
+
});
|
|
382
399
|
};
|
|
383
400
|
|
|
384
401
|
editorService.on('history-change', historyChangeHandler);
|
|
@@ -413,7 +430,9 @@ export const initServiceEvents = (
|
|
|
413
430
|
removeDataSourceTarget(config.id);
|
|
414
431
|
initDataSourceDepTarget(config);
|
|
415
432
|
|
|
416
|
-
collectIdle(root?.items || [], true)
|
|
433
|
+
collectIdle(root?.items || [], true).then(() => {
|
|
434
|
+
updateDataSourceSchema(root?.items || [], true);
|
|
435
|
+
});
|
|
417
436
|
};
|
|
418
437
|
|
|
419
438
|
const removeDataSourceTarget = (id: string) => {
|
|
@@ -423,8 +442,14 @@ export const initServiceEvents = (
|
|
|
423
442
|
};
|
|
424
443
|
|
|
425
444
|
const dataSourceRemoveHandler = (id: string) => {
|
|
445
|
+
const root = editorService.get('root');
|
|
446
|
+
const nodeIds = Object.keys(root?.dataSourceDeps?.[id] || {});
|
|
447
|
+
const nodes = getNodes(nodeIds, root?.items);
|
|
448
|
+
collectIdle(nodes, false).then(() => {
|
|
449
|
+
updateDataSourceSchema(nodes, false);
|
|
450
|
+
});
|
|
451
|
+
|
|
426
452
|
removeDataSourceTarget(id);
|
|
427
|
-
getApp()?.dataSourceManager?.removeDataSource(id);
|
|
428
453
|
};
|
|
429
454
|
|
|
430
455
|
dataSourceService.on('add', dataSourceAddHandler);
|
|
@@ -434,7 +459,6 @@ export const initServiceEvents = (
|
|
|
434
459
|
onBeforeUnmount(() => {
|
|
435
460
|
depService.off('add-target', targetAddHandler);
|
|
436
461
|
depService.off('remove-target', targetRemoveHandler);
|
|
437
|
-
depService.off('collected', collectedHandler);
|
|
438
462
|
|
|
439
463
|
editorService.off('history-change', historyChangeHandler);
|
|
440
464
|
editorService.off('root-change', rootChangeHandler);
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
|
|
40
40
|
<slot name="page-bar">
|
|
41
41
|
<PageBar :disabled-page-fragment="disabledPageFragment" :page-bar-sort-options="pageBarSortOptions">
|
|
42
|
+
<template #page-bar-add-button><slot name="page-bar-add-button"></slot></template>
|
|
42
43
|
<template #page-bar-title="{ page }"><slot name="page-bar-title" :page="page"></slot></template>
|
|
43
44
|
<template #page-bar-popover="{ page }"><slot name="page-bar-popover" :page="page"></slot></template>
|
|
44
45
|
<template #page-list-popover="{ list }"><slot name="page-list-popover" :list="list"></slot></template>
|
|
@@ -3,9 +3,31 @@
|
|
|
3
3
|
v-if="showAddPageButton"
|
|
4
4
|
id="m-editor-page-bar-add-icon"
|
|
5
5
|
class="m-editor-page-bar-item m-editor-page-bar-item-icon"
|
|
6
|
-
@click="addPage"
|
|
7
6
|
>
|
|
8
|
-
<
|
|
7
|
+
<TMagicPopover popper-class="data-source-list-panel-add-menu">
|
|
8
|
+
<template #reference>
|
|
9
|
+
<Icon :icon="Plus"></Icon>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<ToolButton
|
|
13
|
+
:data="{
|
|
14
|
+
type: 'button',
|
|
15
|
+
text: '页面',
|
|
16
|
+
handler: () => {
|
|
17
|
+
addPage(NodeType.PAGE);
|
|
18
|
+
},
|
|
19
|
+
}"
|
|
20
|
+
></ToolButton>
|
|
21
|
+
<ToolButton
|
|
22
|
+
:data="{
|
|
23
|
+
type: 'button',
|
|
24
|
+
text: '页面片',
|
|
25
|
+
handler: () => {
|
|
26
|
+
addPage(NodeType.PAGE_FRAGMENT);
|
|
27
|
+
},
|
|
28
|
+
}"
|
|
29
|
+
></ToolButton>
|
|
30
|
+
</TMagicPopover>
|
|
9
31
|
</div>
|
|
10
32
|
<div v-else style="width: 21px"></div>
|
|
11
33
|
</template>
|
|
@@ -15,8 +37,10 @@ import { computed, inject, toRaw } from 'vue';
|
|
|
15
37
|
import { Plus } from '@element-plus/icons-vue';
|
|
16
38
|
|
|
17
39
|
import { NodeType } from '@tmagic/core';
|
|
40
|
+
import { TMagicPopover } from '@tmagic/design';
|
|
18
41
|
|
|
19
42
|
import Icon from '@editor/components/Icon.vue';
|
|
43
|
+
import ToolButton from '@editor/components/ToolButton.vue';
|
|
20
44
|
import type { Services } from '@editor/type';
|
|
21
45
|
import { generatePageNameByApp } from '@editor/utils/editor';
|
|
22
46
|
|
|
@@ -24,23 +48,19 @@ defineOptions({
|
|
|
24
48
|
name: 'MEditorPageBarAddButton',
|
|
25
49
|
});
|
|
26
50
|
|
|
27
|
-
const props = defineProps<{
|
|
28
|
-
type: NodeType.PAGE | NodeType.PAGE_FRAGMENT;
|
|
29
|
-
}>();
|
|
30
|
-
|
|
31
51
|
const services = inject<Services>('services');
|
|
32
52
|
const uiService = services?.uiService;
|
|
33
53
|
const editorService = services?.editorService;
|
|
34
54
|
|
|
35
55
|
const showAddPageButton = computed(() => uiService?.get('showAddPageButton'));
|
|
36
56
|
|
|
37
|
-
const addPage = () => {
|
|
57
|
+
const addPage = (type: NodeType.PAGE | NodeType.PAGE_FRAGMENT) => {
|
|
38
58
|
if (!editorService) return;
|
|
39
59
|
const root = toRaw(editorService.get('root'));
|
|
40
60
|
if (!root) throw new Error('root 不能为空');
|
|
41
61
|
const pageConfig = {
|
|
42
|
-
type
|
|
43
|
-
name: generatePageNameByApp(root,
|
|
62
|
+
type,
|
|
63
|
+
name: generatePageNameByApp(root, type),
|
|
44
64
|
items: [],
|
|
45
65
|
};
|
|
46
66
|
editorService.add(pageConfig);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="m-editor-page-bar-tabs">
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
<PageBarScrollContainer :type="active" :page-bar-sort-options="pageBarSortOptions">
|
|
3
|
+
<PageBarScrollContainer :page-bar-sort-options="pageBarSortOptions" :length="list.length">
|
|
6
4
|
<template #prepend>
|
|
7
|
-
<
|
|
5
|
+
<slot name="page-bar-add-button"><AddButton></AddButton></slot>
|
|
6
|
+
|
|
7
|
+
<Search v-model:query="query"></Search>
|
|
8
8
|
<PageList :list="list">
|
|
9
9
|
<template #page-list-popover="{ list }"><slot name="page-list-popover" :list="list"></slot></template>
|
|
10
10
|
</PageList>
|
|
@@ -63,21 +63,19 @@
|
|
|
63
63
|
</template>
|
|
64
64
|
|
|
65
65
|
<script lang="ts" setup>
|
|
66
|
-
import { computed, inject, ref
|
|
66
|
+
import { computed, inject, ref } from 'vue';
|
|
67
67
|
import { CaretBottom, Delete, DocumentCopy } from '@element-plus/icons-vue';
|
|
68
68
|
|
|
69
69
|
import { type Id, type MPage, type MPageFragment, NodeType } from '@tmagic/core';
|
|
70
70
|
import { TMagicIcon, TMagicPopover } from '@tmagic/design';
|
|
71
|
-
import { isPage, isPageFragment } from '@tmagic/utils';
|
|
72
71
|
|
|
73
72
|
import ToolButton from '@editor/components/ToolButton.vue';
|
|
74
73
|
import type { PageBarSortOptions, Services } from '@editor/type';
|
|
75
|
-
import { getPageFragmentList, getPageList } from '@editor/utils';
|
|
76
74
|
|
|
77
75
|
import AddButton from './AddButton.vue';
|
|
78
76
|
import PageBarScrollContainer from './PageBarScrollContainer.vue';
|
|
79
77
|
import PageList from './PageList.vue';
|
|
80
|
-
import
|
|
78
|
+
import Search from './Search.vue';
|
|
81
79
|
|
|
82
80
|
defineOptions({
|
|
83
81
|
name: 'MEditorPageBar',
|
|
@@ -88,69 +86,35 @@ defineProps<{
|
|
|
88
86
|
pageBarSortOptions?: PageBarSortOptions;
|
|
89
87
|
}>();
|
|
90
88
|
|
|
91
|
-
const active = ref<NodeType.PAGE | NodeType.PAGE_FRAGMENT>(NodeType.PAGE);
|
|
92
|
-
|
|
93
89
|
const services = inject<Services>('services');
|
|
94
90
|
const editorService = services?.editorService;
|
|
95
91
|
|
|
96
92
|
const root = computed(() => editorService?.get('root'));
|
|
97
93
|
const page = computed(() => editorService?.get('page'));
|
|
98
|
-
const pageList = computed(() => getPageList(root.value));
|
|
99
|
-
const pageFragmentList = computed(() => getPageFragmentList(root.value));
|
|
100
|
-
|
|
101
|
-
const list = computed(() => (active.value === NodeType.PAGE ? pageList.value : pageFragmentList.value));
|
|
102
94
|
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
if (active.value === NodeType.PAGE) {
|
|
111
|
-
activePage.value = '';
|
|
112
|
-
}
|
|
113
|
-
if (active.value === NodeType.PAGE_FRAGMENT) {
|
|
114
|
-
activePageFragment.value = '';
|
|
115
|
-
}
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
95
|
+
const query = ref<{
|
|
96
|
+
pageType: NodeType[];
|
|
97
|
+
keyword: string;
|
|
98
|
+
}>({
|
|
99
|
+
pageType: [NodeType.PAGE, NodeType.PAGE_FRAGMENT],
|
|
100
|
+
keyword: '',
|
|
101
|
+
});
|
|
118
102
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
} else if (isPageFragment(page)) {
|
|
125
|
-
activePageFragment.value = page?.id;
|
|
126
|
-
if (active.value !== NodeType.PAGE_FRAGMENT) {
|
|
127
|
-
active.value = NodeType.PAGE_FRAGMENT;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
},
|
|
131
|
-
{
|
|
132
|
-
immediate: true,
|
|
133
|
-
},
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
watch(active, (active) => {
|
|
137
|
-
if (active === NodeType.PAGE) {
|
|
138
|
-
if (!activePage.value && !pageList.value.length) {
|
|
139
|
-
editorService?.selectRoot();
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
switchPage(activePage.value);
|
|
143
|
-
return;
|
|
103
|
+
const list = computed(() => {
|
|
104
|
+
const { pageType, keyword } = query.value;
|
|
105
|
+
if (pageType.length === 0) {
|
|
106
|
+
return [];
|
|
144
107
|
}
|
|
145
108
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
109
|
+
return (root.value?.items || []).filter((item) => {
|
|
110
|
+
if (pageType.includes(item.type)) {
|
|
111
|
+
if (keyword) {
|
|
112
|
+
return item.name?.includes(keyword);
|
|
113
|
+
}
|
|
114
|
+
return true;
|
|
151
115
|
}
|
|
152
|
-
|
|
153
|
-
}
|
|
116
|
+
return false;
|
|
117
|
+
});
|
|
154
118
|
});
|
|
155
119
|
|
|
156
120
|
const switchPage = (id: Id) => {
|
|
@@ -6,12 +6,7 @@
|
|
|
6
6
|
<Icon :icon="ArrowLeftBold"></Icon>
|
|
7
7
|
</div>
|
|
8
8
|
|
|
9
|
-
<div
|
|
10
|
-
v-if="(type === NodeType.PAGE && pageLength) || (type === NodeType.PAGE_FRAGMENT && pageFragmentLength)"
|
|
11
|
-
class="m-editor-page-bar-items"
|
|
12
|
-
ref="itemsContainer"
|
|
13
|
-
:style="`width: ${itemsContainerWidth}px`"
|
|
14
|
-
>
|
|
9
|
+
<div v-if="length" class="m-editor-page-bar-items" ref="itemsContainer" :style="`width: ${itemsContainerWidth}px`">
|
|
15
10
|
<slot></slot>
|
|
16
11
|
</div>
|
|
17
12
|
|
|
@@ -22,21 +17,11 @@
|
|
|
22
17
|
</template>
|
|
23
18
|
|
|
24
19
|
<script setup lang="ts">
|
|
25
|
-
import {
|
|
26
|
-
computed,
|
|
27
|
-
type ComputedRef,
|
|
28
|
-
inject,
|
|
29
|
-
nextTick,
|
|
30
|
-
onBeforeUnmount,
|
|
31
|
-
onMounted,
|
|
32
|
-
ref,
|
|
33
|
-
watch,
|
|
34
|
-
type WatchStopHandle,
|
|
35
|
-
} from 'vue';
|
|
20
|
+
import { computed, inject, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
|
36
21
|
import { ArrowLeftBold, ArrowRightBold } from '@element-plus/icons-vue';
|
|
37
|
-
import Sortable, { SortableEvent } from 'sortablejs';
|
|
22
|
+
import Sortable, { type SortableEvent } from 'sortablejs';
|
|
38
23
|
|
|
39
|
-
import { Id
|
|
24
|
+
import type { Id } from '@tmagic/core';
|
|
40
25
|
|
|
41
26
|
import Icon from '@editor/components/Icon.vue';
|
|
42
27
|
import type { PageBarSortOptions, Services } from '@editor/type';
|
|
@@ -46,8 +31,8 @@ defineOptions({
|
|
|
46
31
|
});
|
|
47
32
|
|
|
48
33
|
const props = defineProps<{
|
|
49
|
-
type: NodeType.PAGE | NodeType.PAGE_FRAGMENT;
|
|
50
34
|
pageBarSortOptions?: PageBarSortOptions;
|
|
35
|
+
length: number;
|
|
51
36
|
}>();
|
|
52
37
|
|
|
53
38
|
const services = inject<Services>('services');
|
|
@@ -63,11 +48,12 @@ const showPageListButton = computed(() => uiService?.get('showPageListButton'));
|
|
|
63
48
|
const itemsContainerWidth = ref(0);
|
|
64
49
|
|
|
65
50
|
const setCanScroll = () => {
|
|
66
|
-
//
|
|
51
|
+
// 减去新增、搜索、页面列表、左移、右移5个按钮的宽度
|
|
67
52
|
// 37 = icon width 16 + padding 10 * 2 + border-right 1
|
|
68
53
|
itemsContainerWidth.value =
|
|
69
54
|
(pageBar.value?.clientWidth || 0) -
|
|
70
55
|
37 * 2 -
|
|
56
|
+
37 -
|
|
71
57
|
(showAddPageButton.value ? 37 : 21) -
|
|
72
58
|
(showPageListButton.value ? 37 : 0);
|
|
73
59
|
|
|
@@ -119,71 +105,46 @@ const scroll = (type: 'left' | 'right' | 'start' | 'end') => {
|
|
|
119
105
|
itemsContainer.value.style.transform = `translate(${translateLeft}px, 0px)`;
|
|
120
106
|
};
|
|
121
107
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
if (typeof props.pageBarSortOptions?.beforeStart === 'function') {
|
|
144
|
-
await props.pageBarSortOptions.beforeStart(event, sortable);
|
|
145
|
-
}
|
|
146
|
-
beforeDragList = sortable.toArray();
|
|
147
|
-
},
|
|
148
|
-
onUpdate: async (event: SortableEvent) => {
|
|
149
|
-
await editorService?.sort(
|
|
150
|
-
beforeDragList[event.oldIndex as number],
|
|
151
|
-
beforeDragList[event.newIndex as number],
|
|
152
|
-
);
|
|
153
|
-
if (typeof props.pageBarSortOptions?.afterUpdate === 'function') {
|
|
154
|
-
await props.pageBarSortOptions.afterUpdate(event, sortable);
|
|
155
|
-
}
|
|
156
|
-
},
|
|
108
|
+
watch(
|
|
109
|
+
() => props.length,
|
|
110
|
+
(length = 0, preLength = 0) => {
|
|
111
|
+
setTimeout(() => {
|
|
112
|
+
setCanScroll();
|
|
113
|
+
if (length < preLength) {
|
|
114
|
+
scroll('start');
|
|
115
|
+
} else {
|
|
116
|
+
scroll('end');
|
|
117
|
+
}
|
|
118
|
+
if (length > 1) {
|
|
119
|
+
const el = document.querySelector('.m-editor-page-bar-items') as HTMLElement;
|
|
120
|
+
let beforeDragList: Id[] = [];
|
|
121
|
+
const options = {
|
|
122
|
+
...{
|
|
123
|
+
dataIdAttr: 'page-id', // 获取排序后的数据
|
|
124
|
+
onStart: async (event: SortableEvent) => {
|
|
125
|
+
if (typeof props.pageBarSortOptions?.beforeStart === 'function') {
|
|
126
|
+
await props.pageBarSortOptions.beforeStart(event, sortable);
|
|
127
|
+
}
|
|
128
|
+
beforeDragList = sortable.toArray();
|
|
157
129
|
},
|
|
158
|
-
|
|
159
|
-
|
|
130
|
+
onUpdate: async (event: SortableEvent) => {
|
|
131
|
+
await editorService?.sort(
|
|
132
|
+
beforeDragList[event.oldIndex as number],
|
|
133
|
+
beforeDragList[event.newIndex as number],
|
|
134
|
+
);
|
|
135
|
+
if (typeof props.pageBarSortOptions?.afterUpdate === 'function') {
|
|
136
|
+
await props.pageBarSortOptions.afterUpdate(event, sortable);
|
|
137
|
+
}
|
|
160
138
|
},
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
let unWatchPageLength: WatchStopHandle | null;
|
|
173
|
-
let unWatchPageFragmentLength: WatchStopHandle | null;
|
|
174
|
-
|
|
175
|
-
watch(
|
|
176
|
-
() => props.type,
|
|
177
|
-
(type) => {
|
|
178
|
-
if (type === NodeType.PAGE) {
|
|
179
|
-
unWatchPageFragmentLength?.();
|
|
180
|
-
unWatchPageFragmentLength = null;
|
|
181
|
-
unWatchPageLength = crateWatchLength(pageLength);
|
|
182
|
-
} else {
|
|
183
|
-
unWatchPageLength?.();
|
|
184
|
-
unWatchPageLength = null;
|
|
185
|
-
unWatchPageFragmentLength = crateWatchLength(pageFragmentLength);
|
|
186
|
-
}
|
|
139
|
+
},
|
|
140
|
+
...{
|
|
141
|
+
...(props.pageBarSortOptions ? props.pageBarSortOptions : {}),
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
if (!el) return;
|
|
145
|
+
const sortable = new Sortable(el, options);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
187
148
|
},
|
|
188
149
|
{
|
|
189
150
|
immediate: true,
|