@tmagic/editor 1.3.0-beta.1 → 1.3.0-beta.3
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 +67 -75
- package/dist/tmagic-editor.js +1667 -1062
- package/dist/tmagic-editor.js.map +1 -1
- package/dist/tmagic-editor.umd.cjs +1692 -1084
- package/dist/tmagic-editor.umd.cjs.map +1 -1
- package/package.json +10 -10
- package/src/Editor.vue +70 -65
- package/src/components/ContentMenu.vue +5 -1
- package/src/components/SearchInput.vue +5 -1
- package/src/components/ToolButton.vue +1 -1
- package/src/editorProps.ts +51 -129
- package/src/fields/Code.vue +9 -3
- package/src/fields/DataSourceFieldSelect.vue +28 -16
- package/src/fields/DataSourceFields.vue +95 -7
- package/src/fields/DataSourceMethodSelect.vue +23 -14
- package/src/fields/DataSourceMocks.vue +237 -0
- package/src/fields/EventSelect.vue +30 -11
- package/src/index.ts +4 -1
- package/src/initService.ts +50 -20
- package/src/layouts/CodeEditor.vue +20 -4
- package/src/layouts/Framework.vue +3 -1
- package/src/layouts/PropsPanel.vue +3 -1
- package/src/layouts/sidebar/ComponentListPanel.vue +18 -8
- package/src/layouts/sidebar/Sidebar.vue +7 -10
- package/src/layouts/sidebar/code-block/CodeBlockList.vue +3 -1
- package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +3 -1
- package/src/layouts/sidebar/layer/LayerNode.vue +206 -0
- package/src/layouts/sidebar/layer/LayerNodeTool.vue +32 -0
- package/src/layouts/sidebar/layer/LayerPanel.vue +85 -0
- package/src/layouts/sidebar/layer/use-drag.ts +157 -0
- package/src/layouts/sidebar/layer/use-filter.ts +70 -0
- package/src/layouts/sidebar/layer/use-keybinding.ts +47 -0
- package/src/layouts/sidebar/layer/use-node-status.ts +103 -0
- package/src/layouts/workspace/Workspace.vue +3 -1
- package/src/layouts/workspace/viewer/NodeListMenu.vue +16 -9
- package/src/layouts/workspace/viewer/Stage.vue +19 -17
- package/src/layouts/workspace/viewer/ViewerMenu.vue +1 -1
- package/src/services/dataSource.ts +21 -0
- package/src/services/editor.ts +45 -5
- package/src/theme/common/var.scss +2 -2
- package/src/theme/content-menu.scss +22 -20
- package/src/theme/framework.scss +2 -0
- package/src/theme/layer-panel.scss +63 -63
- package/src/theme/props-panel.scss +8 -0
- package/src/theme/sidebar.scss +1 -5
- package/src/type.ts +61 -0
- package/src/utils/data-source/index.ts +23 -0
- package/src/utils/dep.ts +26 -11
- package/src/utils/editor.ts +14 -3
- package/src/utils/props.ts +4 -0
- package/types/editorProps.d.ts +61 -107
- package/types/fields/Code.vue.d.ts +10 -6
- package/types/fields/DataSourceMocks.vue.d.ts +32 -0
- package/types/index.d.ts +2 -1
- package/types/initService.d.ts +5 -4
- package/types/layouts/CodeEditor.vue.d.ts +5 -0
- package/types/layouts/Framework.vue.d.ts +2 -12
- package/types/layouts/PropsPanel.vue.d.ts +2 -3
- package/types/layouts/sidebar/ComponentListPanel.vue.d.ts +2 -7
- package/types/layouts/sidebar/Sidebar.vue.d.ts +2 -17
- package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +2 -7
- package/types/layouts/sidebar/code-block/CodeBlockListPanel.vue.d.ts +2 -9
- package/types/layouts/sidebar/{LayerMenu.vue.d.ts → layer/LayerMenu.vue.d.ts} +1 -1
- package/types/layouts/sidebar/layer/LayerNode.vue.d.ts +50 -0
- package/types/layouts/sidebar/{LayerNode.vue.d.ts → layer/LayerNodeTool.vue.d.ts} +1 -1
- package/types/layouts/sidebar/{LayerPanel.vue.d.ts → layer/LayerPanel.vue.d.ts} +2 -8
- package/types/layouts/sidebar/layer/use-drag.d.ts +14 -0
- package/types/layouts/sidebar/layer/use-filter.d.ts +8 -0
- package/types/layouts/sidebar/layer/use-keybinding.d.ts +4 -0
- package/types/layouts/sidebar/layer/use-node-status.d.ts +7 -0
- package/types/layouts/workspace/Workspace.vue.d.ts +2 -11
- package/types/layouts/workspace/viewer/Stage.vue.d.ts +1 -1
- package/types/services/dataSource.d.ts +7 -0
- package/types/services/editor.d.ts +1 -0
- package/types/type.d.ts +61 -0
- package/types/utils/dep.d.ts +1 -1
- package/types/utils/editor.d.ts +3 -2
- package/src/layouts/sidebar/LayerNode.vue +0 -40
- package/src/layouts/sidebar/LayerPanel.vue +0 -369
- package/types/Editor.vue.d.ts +0 -233
- /package/src/layouts/sidebar/{LayerMenu.vue → layer/LayerMenu.vue} +0 -0
package/types/type.d.ts
CHANGED
|
@@ -15,6 +15,56 @@ import type { PropsService } from './services/props';
|
|
|
15
15
|
import type { StorageService } from './services/storage';
|
|
16
16
|
import type { UiService } from './services/ui';
|
|
17
17
|
import type { UndoRedo } from './utils/undo-redo';
|
|
18
|
+
export interface FrameworkSlots {
|
|
19
|
+
header(props: {}): any;
|
|
20
|
+
nav(props: {}): any;
|
|
21
|
+
'content-before'(props: {}): any;
|
|
22
|
+
'content-after'(props: {}): any;
|
|
23
|
+
'src-code'(props: {}): any;
|
|
24
|
+
sidebar(props: {}): any;
|
|
25
|
+
empty(props: {}): any;
|
|
26
|
+
workspace(props: {}): any;
|
|
27
|
+
'props-panel'(props: {}): any;
|
|
28
|
+
'footer'(props: {}): any;
|
|
29
|
+
}
|
|
30
|
+
export interface WorkspaceSlots {
|
|
31
|
+
stage(props: {}): any;
|
|
32
|
+
'workspace-content'(props: {}): any;
|
|
33
|
+
'page-bar-title'(props: {
|
|
34
|
+
page: MPage;
|
|
35
|
+
}): any;
|
|
36
|
+
'page-bar-popover'(props: {
|
|
37
|
+
page: MPage;
|
|
38
|
+
}): any;
|
|
39
|
+
}
|
|
40
|
+
export interface ComponentListPanelSlots {
|
|
41
|
+
'component-list-panel-header'(props: {}): any;
|
|
42
|
+
'component-list-item'(props: {
|
|
43
|
+
component: ComponentItem;
|
|
44
|
+
}): any;
|
|
45
|
+
}
|
|
46
|
+
export interface CodeBlockListPanelSlots extends CodeBlockListSlots {
|
|
47
|
+
'code-block-panel-search'(props: {}): any;
|
|
48
|
+
'code-block-panel-header'(props: {}): any;
|
|
49
|
+
}
|
|
50
|
+
export interface CodeBlockListSlots {
|
|
51
|
+
'code-block-panel-tool'(props: {
|
|
52
|
+
id: Id;
|
|
53
|
+
data: CodeBlockContent;
|
|
54
|
+
}): any;
|
|
55
|
+
}
|
|
56
|
+
export interface LayerNodeSlots {
|
|
57
|
+
'layer-node-content'(props: {
|
|
58
|
+
data: MNode;
|
|
59
|
+
}): any;
|
|
60
|
+
}
|
|
61
|
+
export interface LayerPanelSlots extends LayerNodeSlots {
|
|
62
|
+
'layer-panel-header'(props: {}): any;
|
|
63
|
+
}
|
|
64
|
+
export interface PropsPanelSlots {
|
|
65
|
+
'props-panel-header'(props: {}): any;
|
|
66
|
+
}
|
|
67
|
+
export type SidebarSlots = LayerPanelSlots & CodeBlockListPanelSlots & ComponentListPanelSlots;
|
|
18
68
|
export type BeforeAdd = (config: MNode, parent: MContainer) => Promise<MNode> | MNode;
|
|
19
69
|
export type GetConfig = (config: FormConfig) => Promise<FormConfig> | FormConfig;
|
|
20
70
|
export interface InstallOptions {
|
|
@@ -335,6 +385,7 @@ export interface HistoryState {
|
|
|
335
385
|
export interface EventSelectConfig {
|
|
336
386
|
name: string;
|
|
337
387
|
type: 'event-select';
|
|
388
|
+
src: 'datasource' | 'component';
|
|
338
389
|
/** 事件名称表单配置 */
|
|
339
390
|
eventNameConfig?: FormItem;
|
|
340
391
|
/** 动作类型配置 */
|
|
@@ -417,6 +468,7 @@ export interface DataSourceMethodSelectConfig {
|
|
|
417
468
|
export interface DataSourceFieldSelectConfig {
|
|
418
469
|
type: 'data-source-field-select';
|
|
419
470
|
name: string;
|
|
471
|
+
value?: 'key' | 'value';
|
|
420
472
|
labelWidth?: number | string;
|
|
421
473
|
disabled?: boolean | FilterFunction;
|
|
422
474
|
display?: boolean | FilterFunction;
|
|
@@ -436,3 +488,12 @@ export interface DatasourceTypeOption {
|
|
|
436
488
|
type: string;
|
|
437
489
|
text: string;
|
|
438
490
|
}
|
|
491
|
+
export interface LayerNodeStatus {
|
|
492
|
+
visible: boolean;
|
|
493
|
+
expand: boolean;
|
|
494
|
+
selected: boolean;
|
|
495
|
+
}
|
|
496
|
+
export declare enum DragType {
|
|
497
|
+
COMPONENT_LIST = "component-list",
|
|
498
|
+
LAYER_TREE = "layer-tree"
|
|
499
|
+
}
|
package/types/utils/dep.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CodeBlockContent, Id } from '@tmagic/schema';
|
|
1
|
+
import { type CodeBlockContent, type Id } from '@tmagic/schema';
|
|
2
2
|
import { Target } from '../services/dep';
|
|
3
3
|
export declare const createCodeBlockTarget: (id: Id, codeBlock: CodeBlockContent) => Target;
|
|
4
4
|
export declare const createDataSourceTarget: (id: Id) => Target;
|
package/types/utils/editor.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { MApp, MContainer, MNode, MPage } from '@tmagic/schema';
|
|
1
|
+
import type { Id, MApp, MContainer, MNode, MPage } from '@tmagic/schema';
|
|
2
2
|
import type StageCore from '@tmagic/stage';
|
|
3
3
|
import { Layout } from '../type';
|
|
4
4
|
export declare const COPY_STORAGE_KEY = "$MagicEditorCopyData";
|
|
@@ -31,7 +31,7 @@ export declare const generatePageNameByApp: (app: MApp) => string;
|
|
|
31
31
|
* @returns {boolean}
|
|
32
32
|
*/
|
|
33
33
|
export declare const isFixed: (node: MNode) => boolean;
|
|
34
|
-
export declare const getNodeIndex: (
|
|
34
|
+
export declare const getNodeIndex: (id: Id, parent: MContainer | MApp) => number;
|
|
35
35
|
export declare const getRelativeStyle: (style?: Record<string, any>) => Record<string, any>;
|
|
36
36
|
export declare const getInitPositionStyle: (style: Record<string, any> | undefined, layout: Layout) => Record<string, any>;
|
|
37
37
|
export declare const setLayout: (node: MNode, layout: Layout) => MNode;
|
|
@@ -46,3 +46,4 @@ export declare const fixNodePosition: (config: MNode, parent: MContainer, stage:
|
|
|
46
46
|
[key: string]: any;
|
|
47
47
|
} | undefined;
|
|
48
48
|
export declare const serializeConfig: (config: any) => string;
|
|
49
|
+
export declare const traverseNode: (node: MNode, cb: (node: MNode, parents: MNode[]) => void, parents?: MNode[]) => void;
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div>
|
|
3
|
-
{{ `${data.name} (${data.id})` }}
|
|
4
|
-
</div>
|
|
5
|
-
<div class="layer-node-tool">
|
|
6
|
-
<template v-if="data.type !== 'page'">
|
|
7
|
-
<el-icon v-if="data.visible === false" @click.stop="setNodeVisible(true)" title="点击显示">
|
|
8
|
-
<Hide />
|
|
9
|
-
</el-icon>
|
|
10
|
-
<el-icon v-else @click.stop="setNodeVisible(false)" class="node-lock" title="点击隐藏">
|
|
11
|
-
<View />
|
|
12
|
-
</el-icon>
|
|
13
|
-
</template>
|
|
14
|
-
</div>
|
|
15
|
-
</template>
|
|
16
|
-
|
|
17
|
-
<script lang="ts" setup>
|
|
18
|
-
import { inject } from 'vue';
|
|
19
|
-
import { Hide, View } from '@element-plus/icons-vue';
|
|
20
|
-
|
|
21
|
-
import { MNode } from '@tmagic/schema';
|
|
22
|
-
|
|
23
|
-
import { Services } from '@editor/type';
|
|
24
|
-
|
|
25
|
-
const props = defineProps<{
|
|
26
|
-
data: MNode;
|
|
27
|
-
}>();
|
|
28
|
-
|
|
29
|
-
const services = inject<Services>('services');
|
|
30
|
-
const editorService = services?.editorService;
|
|
31
|
-
|
|
32
|
-
const setNodeVisible = (visible: boolean) => {
|
|
33
|
-
if (!editorService) return;
|
|
34
|
-
|
|
35
|
-
editorService.update({
|
|
36
|
-
id: props.data.id,
|
|
37
|
-
visible,
|
|
38
|
-
});
|
|
39
|
-
};
|
|
40
|
-
</script>
|
|
@@ -1,369 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<TMagicScrollbar class="magic-editor-layer-panel">
|
|
3
|
-
<slot name="layer-panel-header"></slot>
|
|
4
|
-
|
|
5
|
-
<SearchInput @search="filterTextChangeHandler"></SearchInput>
|
|
6
|
-
|
|
7
|
-
<TMagicTree
|
|
8
|
-
v-if="values.length"
|
|
9
|
-
class="magic-editor-layer-tree"
|
|
10
|
-
ref="tree"
|
|
11
|
-
node-key="id"
|
|
12
|
-
empty-text="页面空荡荡的"
|
|
13
|
-
tabindex="-1"
|
|
14
|
-
draggable
|
|
15
|
-
:default-expanded-keys="expandedKeys"
|
|
16
|
-
:default-checked-keys="checkedKeys"
|
|
17
|
-
:current-node-key="currentNodeKey"
|
|
18
|
-
:data="values"
|
|
19
|
-
:expand-on-click-node="false"
|
|
20
|
-
:highlight-current="!isMultiSelect"
|
|
21
|
-
:check-on-click-node="true"
|
|
22
|
-
:props="treeProps"
|
|
23
|
-
:filter-node-method="filterNode"
|
|
24
|
-
:allow-drop="allowDrop"
|
|
25
|
-
:show-checkbox="isMultiSelect"
|
|
26
|
-
@node-click="clickHandler"
|
|
27
|
-
@node-contextmenu="contextmenu"
|
|
28
|
-
@node-drag-end="handleDragEnd"
|
|
29
|
-
@node-collapse="handleCollapse"
|
|
30
|
-
@node-expand="handleExpand"
|
|
31
|
-
@check="checkHandler"
|
|
32
|
-
@mousedown="toggleClickFlag"
|
|
33
|
-
@mouseup="toggleClickFlag"
|
|
34
|
-
>
|
|
35
|
-
<template #default="{ node, data }">
|
|
36
|
-
<div class="cus-tree-node" :id="data.id" @mouseenter="highlightHandler(data)">
|
|
37
|
-
<slot name="layer-node-content" :node="node" :data="data">
|
|
38
|
-
<LayerNode :data="data"></LayerNode>
|
|
39
|
-
</slot>
|
|
40
|
-
</div>
|
|
41
|
-
</template>
|
|
42
|
-
</TMagicTree>
|
|
43
|
-
|
|
44
|
-
<Teleport to="body">
|
|
45
|
-
<LayerMenu ref="menu" :layer-content-menu="layerContentMenu" @collapse-all="collapseAllHandler"></LayerMenu>
|
|
46
|
-
</Teleport>
|
|
47
|
-
</TMagicScrollbar>
|
|
48
|
-
</template>
|
|
49
|
-
|
|
50
|
-
<script lang="ts" setup>
|
|
51
|
-
import { computed, inject, onBeforeUnmount, onMounted, onUnmounted, ref, watch } from 'vue';
|
|
52
|
-
import { difference, throttle, union } from 'lodash-es';
|
|
53
|
-
|
|
54
|
-
import { TMagicScrollbar, TMagicTree } from '@tmagic/design';
|
|
55
|
-
import type { Id, MNode, MPage } from '@tmagic/schema';
|
|
56
|
-
import { MContainer, NodeType } from '@tmagic/schema';
|
|
57
|
-
import { getNodePath, isPage } from '@tmagic/utils';
|
|
58
|
-
|
|
59
|
-
import SearchInput from '@editor/components/SearchInput.vue';
|
|
60
|
-
import type { MenuButton, MenuComponent, Services } from '@editor/type';
|
|
61
|
-
import { Layout } from '@editor/type';
|
|
62
|
-
|
|
63
|
-
import LayerMenu from './LayerMenu.vue';
|
|
64
|
-
import LayerNode from './LayerNode.vue';
|
|
65
|
-
|
|
66
|
-
defineOptions({
|
|
67
|
-
name: 'MEditorLayerPanel',
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
defineProps<{
|
|
71
|
-
layerContentMenu: (MenuButton | MenuComponent)[];
|
|
72
|
-
}>();
|
|
73
|
-
|
|
74
|
-
const throttleTime = 150;
|
|
75
|
-
const services = inject<Services>('services');
|
|
76
|
-
const editorService = services?.editorService;
|
|
77
|
-
const keybindingService = services?.keybindingService;
|
|
78
|
-
|
|
79
|
-
const tree = ref<InstanceType<typeof TMagicTree>>();
|
|
80
|
-
const menu = ref<InstanceType<typeof LayerMenu>>();
|
|
81
|
-
|
|
82
|
-
// 多选选中的组件id数组
|
|
83
|
-
const checkedKeys = ref<Id[]>([]);
|
|
84
|
-
// 是否多选
|
|
85
|
-
const isCtrlKeyDown = ref(false);
|
|
86
|
-
// 默认展开节点
|
|
87
|
-
const expandedKeys = ref<Id[]>([]);
|
|
88
|
-
const currentNodeKey = ref<Id>();
|
|
89
|
-
// 鼠标是否按下标志,用于高亮状态互斥
|
|
90
|
-
const clicked = ref(false);
|
|
91
|
-
|
|
92
|
-
const treeProps = {
|
|
93
|
-
children: 'items',
|
|
94
|
-
label: 'name',
|
|
95
|
-
value: 'id',
|
|
96
|
-
disabled: (data: MNode) => Boolean(data.items?.length),
|
|
97
|
-
class: (data: MNode) => {
|
|
98
|
-
if (clicked.value || isPage(data)) return '';
|
|
99
|
-
if (data.id === highlightNode?.value?.id && !checkedKeys.value.includes(data.id)) {
|
|
100
|
-
return 'cus-tree-node-hover';
|
|
101
|
-
}
|
|
102
|
-
},
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
const isMultiSelect = computed(() => isCtrlKeyDown.value || checkedKeys.value.length > 1);
|
|
106
|
-
|
|
107
|
-
const nodes = computed(() => editorService?.get('nodes') || []);
|
|
108
|
-
const page = computed(() => editorService?.get('page'));
|
|
109
|
-
const values = computed(() => (page.value ? [page.value] : []));
|
|
110
|
-
// 高亮的节点
|
|
111
|
-
const highlightNode = computed(() => editorService?.get('highlightNode'));
|
|
112
|
-
|
|
113
|
-
// 触发画布单选
|
|
114
|
-
const select = async (data: MNode) => {
|
|
115
|
-
if (!data.id) {
|
|
116
|
-
throw new Error('没有id');
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
await editorService?.select(data);
|
|
120
|
-
editorService?.get('stage')?.select(data.id);
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
// 触发画布多选
|
|
124
|
-
const multiSelect = async (data: Id[]) => {
|
|
125
|
-
await editorService?.multiSelect(data);
|
|
126
|
-
editorService?.get('stage')?.multiSelect(data);
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
// 触发画布高亮
|
|
130
|
-
const highlight = (data: MNode) => {
|
|
131
|
-
if (!data?.id) {
|
|
132
|
-
throw new Error('没有id');
|
|
133
|
-
}
|
|
134
|
-
editorService?.highlight(data);
|
|
135
|
-
editorService?.get('stage')?.highlight(data.id);
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
// tree方法:拖拽时判定目标节点能否成为拖动目标位置
|
|
139
|
-
const allowDrop = (draggingNode: any, dropNode: any, type: string): boolean => {
|
|
140
|
-
const { data } = dropNode || {};
|
|
141
|
-
const { data: ingData } = draggingNode;
|
|
142
|
-
|
|
143
|
-
const { type: ingType } = ingData;
|
|
144
|
-
|
|
145
|
-
if (ingType !== NodeType.PAGE && data.type === NodeType.PAGE) return false;
|
|
146
|
-
if (ingType === NodeType.PAGE && data.type !== NodeType.PAGE) return false;
|
|
147
|
-
if (!data?.type) return false;
|
|
148
|
-
if (['prev', 'next'].includes(type)) return true;
|
|
149
|
-
if (data.items || data.type === 'container') return true;
|
|
150
|
-
|
|
151
|
-
return false;
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
// tree事件:拖拽结束时(可能未成功)触发的事件
|
|
155
|
-
const handleDragEnd = async (e: any) => {
|
|
156
|
-
if (!tree.value) return;
|
|
157
|
-
const { data: node } = e;
|
|
158
|
-
const parent = editorService?.getParentById(node.id, false) as MContainer;
|
|
159
|
-
const layout = await editorService?.getLayout(parent, node);
|
|
160
|
-
node.style.position = layout;
|
|
161
|
-
if (layout === Layout.RELATIVE) {
|
|
162
|
-
node.style.top = 0;
|
|
163
|
-
node.style.left = 0;
|
|
164
|
-
}
|
|
165
|
-
const data = tree.value.getData();
|
|
166
|
-
const [page] = data as [MPage];
|
|
167
|
-
editorService?.update(page);
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
// tree事件:节点被关闭时触发的事件
|
|
171
|
-
const handleCollapse = (data: MNode) => {
|
|
172
|
-
expandedKeys.value = expandedKeys.value.filter((id) => id !== data.id);
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
// tree事件:节点被展开时触发的事件
|
|
176
|
-
const handleExpand = (data: MNode) => {
|
|
177
|
-
if (!page.value) {
|
|
178
|
-
expandedKeys.value = [];
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
expandedKeys.value = union(
|
|
183
|
-
expandedKeys.value,
|
|
184
|
-
getNodePath(data.id, [page.value]).map((node) => node.id),
|
|
185
|
-
);
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
// tree方法:对树节点进行筛选时执行的方法
|
|
189
|
-
const filterNode = (value: string, data: MNode): boolean => {
|
|
190
|
-
if (!value) {
|
|
191
|
-
return true;
|
|
192
|
-
}
|
|
193
|
-
let name = '';
|
|
194
|
-
if (data.name) {
|
|
195
|
-
name = data.name;
|
|
196
|
-
} else if (data.items) {
|
|
197
|
-
name = 'container';
|
|
198
|
-
}
|
|
199
|
-
return `${data.id}${name}${data.type}`.indexOf(value) !== -1;
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
// 过滤关键字
|
|
203
|
-
const filterTextChangeHandler = (val: string) => {
|
|
204
|
-
tree.value?.filter(val);
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
watch(nodes, (nodes) => {
|
|
208
|
-
const ids = nodes?.map((node) => node.id) || [];
|
|
209
|
-
|
|
210
|
-
const idsLength = ids.length;
|
|
211
|
-
const checkedKeysLength = checkedKeys.value.length;
|
|
212
|
-
|
|
213
|
-
if (
|
|
214
|
-
difference(
|
|
215
|
-
idsLength > checkedKeysLength ? ids : checkedKeys.value,
|
|
216
|
-
idsLength > checkedKeysLength ? checkedKeys.value : ids,
|
|
217
|
-
).length
|
|
218
|
-
) {
|
|
219
|
-
tree.value?.setCheckedKeys([], false);
|
|
220
|
-
|
|
221
|
-
checkedKeys.value = ids.filter((id) => id !== page.value?.id);
|
|
222
|
-
expandedKeys.value = union(expandedKeys.value, ids);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
[currentNodeKey.value] = ids;
|
|
226
|
-
|
|
227
|
-
setTimeout(() => {
|
|
228
|
-
tree.value?.setCurrentKey(currentNodeKey.value);
|
|
229
|
-
});
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
watch(isMultiSelect, (isMultiSelect) => {
|
|
233
|
-
if (!isMultiSelect) {
|
|
234
|
-
currentNodeKey.value = editorService?.get('node')?.id;
|
|
235
|
-
tree.value?.setCurrentKey(currentNodeKey.value);
|
|
236
|
-
}
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
const editorServiceRemoveHandler = () => {
|
|
240
|
-
setTimeout(() => {
|
|
241
|
-
tree.value?.getNode(editorService?.get('node')?.id)?.updateChildren();
|
|
242
|
-
}, 0);
|
|
243
|
-
};
|
|
244
|
-
|
|
245
|
-
const windowBlurHandler = () => {
|
|
246
|
-
isCtrlKeyDown.value = false;
|
|
247
|
-
};
|
|
248
|
-
|
|
249
|
-
keybindingService?.registeCommand('layer-panel-not-ctrl-keydown', (e) => {
|
|
250
|
-
if (e.key !== keybindingService.ctrlKey) {
|
|
251
|
-
isCtrlKeyDown.value = false;
|
|
252
|
-
}
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
keybindingService?.registeCommand('layer-panel-ctrl-keydown', () => {
|
|
256
|
-
isCtrlKeyDown.value = true;
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
keybindingService?.registeCommand('layer-panel-ctrl-keyup', () => {
|
|
260
|
-
isCtrlKeyDown.value = false;
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
keybindingService?.registeCommand('layer-panel-global-keydwon', () => {
|
|
264
|
-
if (!tree.value?.$el.contains(document.activeElement)) {
|
|
265
|
-
isCtrlKeyDown.value = false;
|
|
266
|
-
}
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
keybindingService?.registe([
|
|
270
|
-
{
|
|
271
|
-
command: 'layer-panel-not-ctrl-keydown',
|
|
272
|
-
when: [['layer-panel', 'keydown']],
|
|
273
|
-
},
|
|
274
|
-
{
|
|
275
|
-
command: 'layer-panel-ctrl-keydown',
|
|
276
|
-
keybinding: 'ctrl',
|
|
277
|
-
when: [['layer-panel', 'keydown']],
|
|
278
|
-
},
|
|
279
|
-
{
|
|
280
|
-
command: 'layer-panel-ctrl-keyup',
|
|
281
|
-
keybinding: 'ctrl',
|
|
282
|
-
when: [['layer-panel', 'keyup']],
|
|
283
|
-
},
|
|
284
|
-
{
|
|
285
|
-
command: 'layer-panel-global-keydwon',
|
|
286
|
-
keybinding: 'ctrl',
|
|
287
|
-
when: [['global', 'keydown']],
|
|
288
|
-
},
|
|
289
|
-
]);
|
|
290
|
-
|
|
291
|
-
watch(tree, () => {
|
|
292
|
-
if (tree.value?.$el) {
|
|
293
|
-
keybindingService?.registeEl('layer-panel', tree.value.$el);
|
|
294
|
-
|
|
295
|
-
tree.value.$el.addEventListener('blur', windowBlurHandler);
|
|
296
|
-
} else {
|
|
297
|
-
keybindingService?.unregisteEl('layer-panel');
|
|
298
|
-
}
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
onMounted(() => {
|
|
302
|
-
editorService?.on('remove', editorServiceRemoveHandler);
|
|
303
|
-
|
|
304
|
-
globalThis.addEventListener('blur', windowBlurHandler);
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
onBeforeUnmount(() => {
|
|
308
|
-
tree.value?.$el.removeEventListener('blur', windowBlurHandler);
|
|
309
|
-
});
|
|
310
|
-
|
|
311
|
-
onUnmounted(() => {
|
|
312
|
-
editorService?.off('remove', editorServiceRemoveHandler);
|
|
313
|
-
globalThis.removeEventListener('blur', windowBlurHandler);
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
// 鼠标在组件树移动触发高亮
|
|
317
|
-
const highlightHandler = throttle((data: MNode) => {
|
|
318
|
-
highlight(data);
|
|
319
|
-
}, throttleTime);
|
|
320
|
-
|
|
321
|
-
const toggleClickFlag = () => {
|
|
322
|
-
clicked.value = !clicked.value;
|
|
323
|
-
};
|
|
324
|
-
|
|
325
|
-
// 选择节点多选框
|
|
326
|
-
const checkHandler = (data: MNode, { checkedNodes }: any): void => {
|
|
327
|
-
if (!isCtrlKeyDown.value && nodes.value.length < 2) {
|
|
328
|
-
return;
|
|
329
|
-
}
|
|
330
|
-
if (checkedNodes.length > 0) {
|
|
331
|
-
multiSelect(checkedNodes.map((node: MNode) => node.id));
|
|
332
|
-
} else {
|
|
333
|
-
multiSelect(nodes.value.map((node: MNode) => node.id));
|
|
334
|
-
}
|
|
335
|
-
};
|
|
336
|
-
|
|
337
|
-
// 点击节点
|
|
338
|
-
const clickHandler = (data: MNode): void => {
|
|
339
|
-
if (isCtrlKeyDown.value) {
|
|
340
|
-
return;
|
|
341
|
-
}
|
|
342
|
-
if (services?.uiService.get('uiSelectMode')) {
|
|
343
|
-
document.dispatchEvent(new CustomEvent('ui-select', { detail: data }));
|
|
344
|
-
return;
|
|
345
|
-
}
|
|
346
|
-
select(data);
|
|
347
|
-
};
|
|
348
|
-
|
|
349
|
-
// 右键菜单
|
|
350
|
-
const contextmenu = async (event: MouseEvent, data: MNode): Promise<void> => {
|
|
351
|
-
event.preventDefault();
|
|
352
|
-
|
|
353
|
-
if (nodes.value.length < 2) {
|
|
354
|
-
await select(data);
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
menu.value?.show(event);
|
|
358
|
-
};
|
|
359
|
-
|
|
360
|
-
const collapseAllHandler = () => {
|
|
361
|
-
const page = editorService?.get('page');
|
|
362
|
-
if (!tree.value || !page) return;
|
|
363
|
-
const rootNode = tree.value.getNode(page.id);
|
|
364
|
-
rootNode.childNodes.forEach((node: any) => {
|
|
365
|
-
node.collapse();
|
|
366
|
-
handleCollapse(node.data);
|
|
367
|
-
});
|
|
368
|
-
};
|
|
369
|
-
</script>
|