@tmagic/editor 1.3.0-alpha.9 → 1.3.0-beta.1
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 +106 -219
- package/dist/tmagic-editor.js +6253 -5042
- package/dist/tmagic-editor.js.map +1 -1
- package/dist/tmagic-editor.umd.cjs +6280 -5055
- package/dist/tmagic-editor.umd.cjs.map +1 -1
- package/package.json +15 -15
- package/src/Editor.vue +4 -5
- package/src/components/CodeBlockEditor.vue +266 -0
- package/src/components/CodeParams.vue +60 -0
- package/src/components/ContentMenu.vue +97 -43
- package/src/components/Resizer.vue +8 -30
- package/src/components/SplitView.vue +3 -2
- package/src/editorProps.ts +30 -5
- package/src/fields/Code.vue +23 -19
- package/src/fields/CodeLink.vue +6 -7
- package/src/fields/CodeSelect.vue +12 -9
- package/src/fields/CodeSelectCol.vue +70 -81
- package/src/fields/DataSourceFieldSelect.vue +47 -0
- package/src/fields/DataSourceFields.vue +38 -22
- package/src/fields/DataSourceInput.vue +21 -58
- package/src/fields/DataSourceMethodSelect.vue +136 -0
- package/src/fields/DataSourceMethods.vue +104 -0
- package/src/fields/DataSourceSelect.vue +5 -12
- package/src/fields/EventSelect.vue +53 -19
- package/src/fields/KeyValue.vue +9 -11
- package/src/fields/UISelect.vue +54 -14
- package/src/hooks/index.ts +21 -0
- package/src/hooks/use-code-block-edit.ts +84 -0
- package/src/hooks/use-data-source-method.ts +100 -0
- package/src/hooks/use-getso.ts +35 -0
- package/src/{utils/stage.ts → hooks/use-stage.ts} +4 -7
- package/src/icons/CenterIcon.vue +13 -0
- package/src/icons/CodeIcon.vue +0 -2
- package/src/icons/FolderMinusIcon.vue +22 -0
- package/src/icons/PinIcon.vue +25 -0
- package/src/icons/PinnedIcon.vue +25 -0
- package/src/index.ts +14 -0
- package/src/initService.ts +69 -16
- package/src/layouts/CodeEditor.vue +35 -3
- package/src/layouts/Framework.vue +7 -3
- package/src/layouts/PropsPanel.vue +8 -3
- package/src/layouts/sidebar/ComponentListPanel.vue +4 -6
- package/src/layouts/sidebar/LayerMenu.vue +20 -21
- package/src/layouts/sidebar/LayerPanel.vue +12 -2
- package/src/layouts/sidebar/Sidebar.vue +22 -36
- package/src/layouts/sidebar/code-block/CodeBlockList.vue +81 -119
- package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +64 -0
- package/src/layouts/sidebar/data-source/DataSourceConfigPanel.vue +27 -47
- package/src/layouts/sidebar/data-source/DataSourceList.vue +145 -0
- package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +58 -85
- package/src/layouts/workspace/Workspace.vue +1 -1
- package/src/layouts/workspace/viewer/NodeListMenu.vue +159 -0
- package/src/layouts/workspace/viewer/NodeListMenuTitle.vue +68 -0
- package/src/layouts/workspace/{Stage.vue → viewer/Stage.vue} +5 -2
- package/src/layouts/workspace/{ViewerMenu.vue → viewer/ViewerMenu.vue} +10 -35
- package/src/services/codeBlock.ts +18 -71
- package/src/services/dataSource.ts +16 -1
- package/src/services/dep.ts +22 -20
- package/src/services/editor.ts +46 -18
- package/src/services/props.ts +2 -2
- package/src/theme/code-block.scss +5 -117
- package/src/theme/code-editor.scss +27 -2
- package/src/theme/content-menu.scss +26 -2
- package/src/theme/data-source-methods.scss +13 -0
- package/src/theme/data-source.scss +11 -0
- package/src/theme/event.scss +15 -12
- package/src/theme/framework.scss +0 -3
- package/src/theme/index.scss +8 -0
- package/src/theme/layout.scss +4 -0
- package/src/theme/sidebar.scss +18 -60
- package/src/theme/theme.scss +1 -0
- package/src/type.ts +49 -7
- package/src/utils/content-menu.ts +92 -0
- package/src/utils/data-source/formConfigs/base.ts +28 -30
- package/src/utils/data-source/formConfigs/http.ts +9 -0
- package/src/utils/data-source/index.ts +65 -2
- package/src/utils/dep.ts +33 -7
- package/src/utils/index.ts +1 -1
- package/src/utils/props.ts +308 -189
- package/src/utils/undo-redo.ts +1 -1
- package/types/Editor.vue.d.ts +30 -6
- package/types/components/CodeBlockEditor.vue.d.ts +25 -0
- package/types/components/CodeParams.vue.d.ts +26 -0
- package/types/components/ContentMenu.vue.d.ts +27 -8
- package/types/components/Resizer.vue.d.ts +1 -3
- package/types/components/ToolButton.vue.d.ts +3 -3
- package/types/editorProps.d.ts +19 -5
- package/types/fields/Code.vue.d.ts +24 -19
- package/types/fields/CodeLink.vue.d.ts +12 -21
- package/types/fields/CodeSelect.vue.d.ts +6 -17
- package/types/fields/CodeSelectCol.vue.d.ts +10 -14
- package/types/fields/DataSourceFieldSelect.vue.d.ts +29 -0
- package/types/fields/DataSourceFields.vue.d.ts +7 -18
- package/types/fields/DataSourceInput.vue.d.ts +10 -30
- package/types/fields/DataSourceMethodSelect.vue.d.ts +29 -0
- package/types/fields/DataSourceMethods.vue.d.ts +32 -0
- package/types/fields/DataSourceSelect.vue.d.ts +13 -29
- package/types/fields/EventSelect.vue.d.ts +2 -13
- package/types/fields/KeyValue.vue.d.ts +9 -24
- package/types/fields/UISelect.vue.d.ts +2 -11
- package/types/hooks/index.d.ts +3 -0
- package/types/{components/FunctionEditor.vue.d.ts → hooks/use-code-block-edit.d.ts} +36 -119
- package/types/hooks/use-data-source-method.d.ts +130 -0
- package/types/hooks/use-getso.d.ts +5 -0
- package/types/icons/CenterIcon.vue.d.ts +2 -0
- package/types/icons/FolderMinusIcon.vue.d.ts +2 -0
- package/types/icons/PinIcon.vue.d.ts +2 -0
- package/types/icons/PinnedIcon.vue.d.ts +2 -0
- package/types/index.d.ts +7 -0
- package/types/initService.d.ts +2 -2
- package/types/layouts/CodeEditor.vue.d.ts +7 -4
- package/types/layouts/PropsPanel.vue.d.ts +274 -2
- package/types/layouts/sidebar/Sidebar.vue.d.ts +0 -3
- package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +4 -9
- package/types/layouts/sidebar/code-block/{CodeBlockEditor.vue.d.ts → CodeBlockListPanel.vue.d.ts} +9 -5
- package/types/layouts/sidebar/data-source/DataSourceConfigPanel.vue.d.ts +3 -1
- package/types/layouts/sidebar/data-source/DataSourceList.vue.d.ts +14 -0
- package/types/layouts/sidebar/data-source/DataSourceListPanel.vue.d.ts +1 -11
- package/types/layouts/workspace/viewer/NodeListMenu.vue.d.ts +15 -0
- package/types/layouts/workspace/viewer/NodeListMenuTitle.vue.d.ts +15 -0
- package/types/layouts/workspace/{Stage.vue.d.ts → viewer/Stage.vue.d.ts} +1 -1
- package/types/layouts/workspace/{ViewerMenu.vue.d.ts → viewer/ViewerMenu.vue.d.ts} +1 -1
- package/types/services/codeBlock.d.ts +6 -37
- package/types/services/dataSource.d.ts +7 -1
- package/types/services/dep.d.ts +12 -21
- package/types/services/editor.d.ts +1 -1
- package/types/services/props.d.ts +10 -115
- package/types/type.d.ts +44 -7
- package/types/utils/content-menu.d.ts +7 -0
- package/types/utils/data-source/formConfigs/base.d.ts +1 -2
- package/types/utils/data-source/index.d.ts +5 -0
- package/types/utils/dep.d.ts +4 -2
- package/types/utils/index.d.ts +1 -1
- package/types/utils/props.d.ts +13 -102
- package/src/components/CodeDraftEditor.vue +0 -148
- package/src/components/FunctionEditor.vue +0 -197
- package/src/layouts/sidebar/code-block/CodeBlockEditor.vue +0 -100
- package/types/components/CodeDraftEditor.vue.d.ts +0 -61
- /package/types/{utils/stage.d.ts → hooks/use-stage.d.ts} +0 -0
package/src/theme/event.scss
CHANGED
|
@@ -19,18 +19,21 @@
|
|
|
19
19
|
box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.12);
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
-
.m-fields-code-select-col
|
|
22
|
+
.m-fields-code-select-col,
|
|
23
|
+
.m-fields-data-source-method-select {
|
|
23
24
|
width: 100%;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.code-select-container,
|
|
28
|
+
.data-source-method-select-container {
|
|
29
|
+
display: flex;
|
|
30
|
+
align-items: center;
|
|
31
|
+
.select {
|
|
32
|
+
flex: 10 0 100px;
|
|
33
|
+
}
|
|
34
|
+
.icon {
|
|
35
|
+
flex: 1 0 20px;
|
|
36
|
+
cursor: pointer;
|
|
37
|
+
margin-right: 5px;
|
|
35
38
|
}
|
|
36
39
|
}
|
package/src/theme/framework.scss
CHANGED
package/src/theme/index.scss
CHANGED
package/src/theme/layout.scss
CHANGED
package/src/theme/sidebar.scss
CHANGED
|
@@ -1,76 +1,33 @@
|
|
|
1
|
-
.m-editor-sidebar
|
|
1
|
+
.m-editor-sidebar {
|
|
2
|
+
display: flex;
|
|
2
3
|
height: 100%;
|
|
3
4
|
|
|
4
|
-
.
|
|
5
|
-
.t-tabs__header {
|
|
5
|
+
.m-editor-sidebar-header {
|
|
6
6
|
background: $--sidebar-heder-background-color;
|
|
7
|
-
border: 0;
|
|
8
7
|
height: 100%;
|
|
8
|
+
width: 40px;
|
|
9
9
|
|
|
10
|
-
.
|
|
11
|
-
background-color: transparent;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
.t-tabs__nav--card.t-tabs__nav-item:not(.t-is-disabled):not(
|
|
15
|
-
.t-is-active
|
|
16
|
-
):hover {
|
|
17
|
-
background-color: transparent;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
&.is-left,
|
|
21
|
-
&.t-is-left {
|
|
22
|
-
width: 40px;
|
|
23
|
-
margin-right: 0;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
.el-tabs__nav-wrap {
|
|
27
|
-
margin: 0;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
.el-tabs__nav {
|
|
31
|
-
border: 0;
|
|
32
|
-
border-radius: 0;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
.tab-label {
|
|
36
|
-
margin-left: 2px;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
.el-tabs__item.is-left,
|
|
40
|
-
.t-tabs__nav-item {
|
|
10
|
+
.m-editor-sidebar-header-item {
|
|
41
11
|
line-height: 15px;
|
|
42
|
-
border: 0;
|
|
43
12
|
height: auto;
|
|
44
13
|
padding: 8px;
|
|
45
14
|
color: rgb(255, 255, 255);
|
|
46
15
|
box-sizing: border-box;
|
|
16
|
+
cursor: pointer;
|
|
47
17
|
|
|
48
|
-
&.is-
|
|
49
|
-
|
|
50
|
-
&.is-active,
|
|
51
|
-
&.t-is-active {
|
|
52
|
-
background: $--sidebar-content-background-color;
|
|
53
|
-
border: 0;
|
|
54
|
-
|
|
55
|
-
i {
|
|
56
|
-
color: #353140;
|
|
57
|
-
}
|
|
18
|
+
&.is-active {
|
|
19
|
+
background: $--sidebar-content-background-color;
|
|
58
20
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
21
|
+
i {
|
|
22
|
+
color: #353140;
|
|
62
23
|
}
|
|
63
24
|
|
|
64
|
-
|
|
65
|
-
|
|
25
|
+
.magic-editor-tab-panel-title {
|
|
26
|
+
color: #353140;
|
|
66
27
|
}
|
|
67
28
|
}
|
|
68
29
|
}
|
|
69
30
|
|
|
70
|
-
.t-tabs__nav-item {
|
|
71
|
-
padding: 7px;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
31
|
i {
|
|
75
32
|
font-size: 25px;
|
|
76
33
|
color: rgba(255, 255, 255, 0.6);
|
|
@@ -86,6 +43,12 @@
|
|
|
86
43
|
}
|
|
87
44
|
}
|
|
88
45
|
|
|
46
|
+
.m-editor-sidebar-content {
|
|
47
|
+
height: 100%;
|
|
48
|
+
width: calc(100% - 40px);
|
|
49
|
+
overflow: auto;
|
|
50
|
+
}
|
|
51
|
+
|
|
89
52
|
.el-scrollbar {
|
|
90
53
|
height: 100%;
|
|
91
54
|
}
|
|
@@ -109,9 +72,4 @@
|
|
|
109
72
|
background: rgba(0, 0, 0, 0.2);
|
|
110
73
|
}
|
|
111
74
|
}
|
|
112
|
-
|
|
113
|
-
.el-tabs__content,
|
|
114
|
-
.el-tab-pane {
|
|
115
|
-
height: 100%;
|
|
116
|
-
}
|
|
117
75
|
}
|
package/src/theme/theme.scss
CHANGED
package/src/type.ts
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
import type { Component } from 'vue';
|
|
20
20
|
|
|
21
|
-
import type { FormConfig, FormItem } from '@tmagic/form';
|
|
21
|
+
import type { ColumnConfig, FilterFunction, FormConfig, FormItem } from '@tmagic/form';
|
|
22
22
|
import type { CodeBlockContent, CodeBlockDSL, Id, MApp, MContainer, MNode, MPage } from '@tmagic/schema';
|
|
23
23
|
import type StageCore from '@tmagic/stage';
|
|
24
24
|
import type {
|
|
@@ -45,7 +45,7 @@ export type BeforeAdd = (config: MNode, parent: MContainer) => Promise<MNode> |
|
|
|
45
45
|
export type GetConfig = (config: FormConfig) => Promise<FormConfig> | FormConfig;
|
|
46
46
|
|
|
47
47
|
export interface InstallOptions {
|
|
48
|
-
parseDSL: (dsl: string) =>
|
|
48
|
+
parseDSL: <T = any>(dsl: string) => T;
|
|
49
49
|
[key: string]: any;
|
|
50
50
|
}
|
|
51
51
|
|
|
@@ -93,7 +93,7 @@ export type StoreStateKey = keyof StoreState;
|
|
|
93
93
|
|
|
94
94
|
export interface PropsState {
|
|
95
95
|
propsConfigMap: Record<string, FormConfig>;
|
|
96
|
-
propsValueMap: Record<string, MNode
|
|
96
|
+
propsValueMap: Record<string, Partial<MNode>>;
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
export interface ComponentGroupState {
|
|
@@ -201,6 +201,8 @@ export interface MenuButton {
|
|
|
201
201
|
className?: string;
|
|
202
202
|
/** type为dropdown时,下拉的菜单列表, 或者有子菜单时 */
|
|
203
203
|
items?: MenuButton[];
|
|
204
|
+
/** 唯一标识,用于高亮 */
|
|
205
|
+
id?: string | number;
|
|
204
206
|
}
|
|
205
207
|
|
|
206
208
|
export interface MenuComponent {
|
|
@@ -334,18 +336,15 @@ export interface ScrollViewerEvent {
|
|
|
334
336
|
}
|
|
335
337
|
|
|
336
338
|
export type CodeState = {
|
|
337
|
-
/** 是否展示代码块编辑区 */
|
|
338
|
-
isShowCodeEditor: boolean;
|
|
339
339
|
/** 代码块DSL数据源 */
|
|
340
340
|
codeDsl: CodeBlockDSL | null;
|
|
341
|
-
/** 当前选中的代码块id */
|
|
342
|
-
id: Id;
|
|
343
341
|
/** 代码块是否可编辑 */
|
|
344
342
|
editable: boolean;
|
|
345
343
|
/** list模式下左侧展示的代码列表 */
|
|
346
344
|
combineIds: string[];
|
|
347
345
|
/** 为业务逻辑预留的不可删除的代码块列表,由业务逻辑维护(如代码块上线后不可删除) */
|
|
348
346
|
undeletableList: Id[];
|
|
347
|
+
paramsColConfig?: ColumnConfig;
|
|
349
348
|
};
|
|
350
349
|
|
|
351
350
|
export type HookData = {
|
|
@@ -429,6 +428,8 @@ export interface EventSelectConfig {
|
|
|
429
428
|
compActionConfig?: FormItem;
|
|
430
429
|
/** 联动代码配置 */
|
|
431
430
|
codeActionConfig?: FormItem;
|
|
431
|
+
/** 联动数据源配置 */
|
|
432
|
+
dataSourceActionConfig?: FormItem;
|
|
432
433
|
}
|
|
433
434
|
|
|
434
435
|
export enum KeyBindingCommand {
|
|
@@ -485,3 +486,44 @@ export interface KeyBindingCacheItem {
|
|
|
485
486
|
eventType: 'keyup' | 'keydown';
|
|
486
487
|
binded: boolean;
|
|
487
488
|
}
|
|
489
|
+
|
|
490
|
+
export interface CodeSelectColConfig {
|
|
491
|
+
type: 'code-select-col';
|
|
492
|
+
name: string;
|
|
493
|
+
labelWidth?: number | string;
|
|
494
|
+
disabled?: boolean | FilterFunction;
|
|
495
|
+
display?: boolean | FilterFunction;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
export interface DataSourceMethodSelectConfig {
|
|
499
|
+
type: 'data-source-method-select';
|
|
500
|
+
name: string;
|
|
501
|
+
labelWidth?: number | string;
|
|
502
|
+
disabled?: boolean | FilterFunction;
|
|
503
|
+
display?: boolean | FilterFunction;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
export interface DataSourceFieldSelectConfig {
|
|
507
|
+
type: 'data-source-field-select';
|
|
508
|
+
name: string;
|
|
509
|
+
labelWidth?: number | string;
|
|
510
|
+
disabled?: boolean | FilterFunction;
|
|
511
|
+
display?: boolean | FilterFunction;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
export enum DepTargetType {
|
|
515
|
+
DEFAULT = 'default',
|
|
516
|
+
/** 代码块 */
|
|
517
|
+
CODE_BLOCK = 'code-block',
|
|
518
|
+
/** 数据源 */
|
|
519
|
+
DATA_SOURCE = 'data-source',
|
|
520
|
+
/** 数据源方法 */
|
|
521
|
+
DATA_SOURCE_METHOD = 'data-source-method',
|
|
522
|
+
/** 数据源条件 */
|
|
523
|
+
DATA_SOURCE_COND = 'data-source-cond',
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
export interface DatasourceTypeOption {
|
|
527
|
+
type: string;
|
|
528
|
+
text: string;
|
|
529
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { computed, markRaw, Ref, ref } from 'vue';
|
|
2
|
+
import { CopyDocument, Delete, DocumentCopy } from '@element-plus/icons-vue';
|
|
3
|
+
|
|
4
|
+
import { Id, MContainer, NodeType } from '@tmagic/schema';
|
|
5
|
+
import { isPage } from '@tmagic/utils';
|
|
6
|
+
|
|
7
|
+
import ContentMenu from '@editor/components/ContentMenu.vue';
|
|
8
|
+
import type { MenuButton, Services } from '@editor/type';
|
|
9
|
+
|
|
10
|
+
export const useDeleteMenu = (): MenuButton => ({
|
|
11
|
+
type: 'button',
|
|
12
|
+
text: '删除',
|
|
13
|
+
icon: Delete,
|
|
14
|
+
display: (services) => {
|
|
15
|
+
const node = services?.editorService?.get('node');
|
|
16
|
+
return node?.type !== NodeType.ROOT && !isPage(node);
|
|
17
|
+
},
|
|
18
|
+
handler: (services) => {
|
|
19
|
+
const nodes = services?.editorService?.get('nodes');
|
|
20
|
+
nodes && services?.editorService?.remove(nodes);
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const canPaste = ref(false);
|
|
25
|
+
|
|
26
|
+
export const useCopyMenu = (): MenuButton => ({
|
|
27
|
+
type: 'button',
|
|
28
|
+
text: '复制',
|
|
29
|
+
icon: markRaw(CopyDocument),
|
|
30
|
+
handler: (services) => {
|
|
31
|
+
const nodes = services?.editorService?.get('nodes');
|
|
32
|
+
nodes && services?.editorService?.copy(nodes);
|
|
33
|
+
canPaste.value = true;
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
export const usePasteMenu = (menu?: Ref<InstanceType<typeof ContentMenu> | undefined>): MenuButton => ({
|
|
38
|
+
type: 'button',
|
|
39
|
+
text: '粘贴',
|
|
40
|
+
icon: markRaw(DocumentCopy),
|
|
41
|
+
display: () => canPaste.value,
|
|
42
|
+
handler: (services) => {
|
|
43
|
+
const nodes = services?.editorService?.get('nodes');
|
|
44
|
+
if (!nodes || nodes.length === 0) return;
|
|
45
|
+
|
|
46
|
+
if (menu?.value?.$el) {
|
|
47
|
+
const stage = services?.editorService?.get('stage');
|
|
48
|
+
const rect = menu.value.$el.getBoundingClientRect();
|
|
49
|
+
const parentRect = stage?.container?.getBoundingClientRect();
|
|
50
|
+
const initialLeft = (rect.left || 0) - (parentRect?.left || 0);
|
|
51
|
+
const initialTop = (rect.top || 0) - (parentRect?.top || 0);
|
|
52
|
+
services?.editorService?.paste({ left: initialLeft, top: initialTop });
|
|
53
|
+
} else {
|
|
54
|
+
services?.editorService?.paste();
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const moveTo = (id: Id, services?: Services) => {
|
|
60
|
+
if (!services?.editorService) return;
|
|
61
|
+
|
|
62
|
+
const nodes = services.editorService.get('nodes') || [];
|
|
63
|
+
const parent = services.editorService.getNodeById(id) as MContainer;
|
|
64
|
+
|
|
65
|
+
if (!parent) return;
|
|
66
|
+
|
|
67
|
+
services?.editorService.add(nodes, parent);
|
|
68
|
+
services?.editorService.remove(nodes);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export const useMoveToMenu = (services?: Services): MenuButton => {
|
|
72
|
+
const root = computed(() => services?.editorService?.get('root'));
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
type: 'button',
|
|
76
|
+
text: '移动至',
|
|
77
|
+
display: (services) => {
|
|
78
|
+
const node = services?.editorService?.get('node');
|
|
79
|
+
const pageLength = services?.editorService?.get('pageLength') || 0;
|
|
80
|
+
return !isPage(node) && pageLength > 1;
|
|
81
|
+
},
|
|
82
|
+
items: (root.value?.items || [])
|
|
83
|
+
.filter((page) => page.id !== services?.editorService?.get('page')?.id)
|
|
84
|
+
.map((page) => ({
|
|
85
|
+
text: `${page.name}(${page.id})`,
|
|
86
|
+
type: 'button',
|
|
87
|
+
handler: (services?: Services) => {
|
|
88
|
+
moveTo(page.id, services);
|
|
89
|
+
},
|
|
90
|
+
})),
|
|
91
|
+
};
|
|
92
|
+
};
|
|
@@ -1,32 +1,30 @@
|
|
|
1
1
|
import type { FormConfig } from '@tmagic/form';
|
|
2
2
|
|
|
3
|
-
export default
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
},
|
|
32
|
-
] as FormConfig;
|
|
3
|
+
export default function (): FormConfig {
|
|
4
|
+
return [
|
|
5
|
+
{
|
|
6
|
+
name: 'id',
|
|
7
|
+
type: 'hidden',
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
name: 'type',
|
|
11
|
+
text: '类型',
|
|
12
|
+
type: 'hidden',
|
|
13
|
+
defaultValue: 'base',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
name: 'title',
|
|
17
|
+
text: '名称',
|
|
18
|
+
rules: [
|
|
19
|
+
{
|
|
20
|
+
required: true,
|
|
21
|
+
message: '请输入名称',
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: 'description',
|
|
27
|
+
text: '描述',
|
|
28
|
+
},
|
|
29
|
+
];
|
|
30
|
+
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { FormConfig } from '@tmagic/form';
|
|
2
|
+
import { DataSchema, DataSourceSchema } from '@tmagic/schema';
|
|
2
3
|
|
|
3
4
|
import BaseFormConfig from './formConfigs/base';
|
|
4
5
|
import HttpFormConfig from './formConfigs/http';
|
|
5
6
|
|
|
6
7
|
const fillConfig = (config: FormConfig): FormConfig => [
|
|
7
|
-
...BaseFormConfig,
|
|
8
|
+
...BaseFormConfig(),
|
|
8
9
|
...config,
|
|
9
10
|
{
|
|
10
11
|
type: 'panel',
|
|
@@ -13,7 +14,18 @@ const fillConfig = (config: FormConfig): FormConfig => [
|
|
|
13
14
|
{
|
|
14
15
|
name: 'fields',
|
|
15
16
|
type: 'data-source-fields',
|
|
16
|
-
defaultValue: [],
|
|
17
|
+
defaultValue: () => [],
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
type: 'panel',
|
|
23
|
+
title: '方法定义',
|
|
24
|
+
items: [
|
|
25
|
+
{
|
|
26
|
+
name: 'methods',
|
|
27
|
+
type: 'data-source-methods',
|
|
28
|
+
defaultValue: () => [],
|
|
17
29
|
},
|
|
18
30
|
],
|
|
19
31
|
},
|
|
@@ -29,3 +41,54 @@ export const getFormConfig = (type: string, configs: Record<string, FormConfig>)
|
|
|
29
41
|
return fillConfig(configs[type] || []);
|
|
30
42
|
}
|
|
31
43
|
};
|
|
44
|
+
|
|
45
|
+
export const getDisplayField = (dataSources: DataSourceSchema[], key: string) => {
|
|
46
|
+
const displayState: { value: string; type: 'var' | 'text' }[] = [];
|
|
47
|
+
|
|
48
|
+
// 匹配es6字符串模块
|
|
49
|
+
const matches = key.matchAll(/\$\{([\s\S]+?)\}/g);
|
|
50
|
+
let index = 0;
|
|
51
|
+
for (const match of matches) {
|
|
52
|
+
if (typeof match.index === 'undefined') break;
|
|
53
|
+
|
|
54
|
+
// 字符串常量
|
|
55
|
+
displayState.push({
|
|
56
|
+
type: 'text',
|
|
57
|
+
value: key.substring(index, match.index),
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
let dsText = '';
|
|
61
|
+
let ds: DataSourceSchema | undefined;
|
|
62
|
+
let fields: DataSchema[] | undefined;
|
|
63
|
+
|
|
64
|
+
// 将模块解析成数据源对应的值
|
|
65
|
+
match[1].split('.').forEach((item, index) => {
|
|
66
|
+
if (index === 0) {
|
|
67
|
+
ds = dataSources.find((ds) => ds.id === item);
|
|
68
|
+
dsText += ds?.title || item;
|
|
69
|
+
fields = ds?.fields;
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const field = fields?.find((field) => field.name === item);
|
|
74
|
+
fields = field?.fields;
|
|
75
|
+
dsText += `.${field?.title || item}`;
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
displayState.push({
|
|
79
|
+
type: 'var',
|
|
80
|
+
value: dsText,
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
index = match.index + match[0].length;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (index < key.length) {
|
|
87
|
+
displayState.push({
|
|
88
|
+
type: 'text',
|
|
89
|
+
value: key.substring(index),
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return displayState;
|
|
94
|
+
};
|
package/src/utils/dep.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { isEmpty } from 'lodash-es';
|
|
2
2
|
|
|
3
|
-
import { CodeBlockContent,
|
|
3
|
+
import { CodeBlockContent, HookType, Id } from '@tmagic/schema';
|
|
4
4
|
|
|
5
|
+
import dataSourceService from '@editor/services/dataSource';
|
|
5
6
|
import { Target } from '@editor/services/dep';
|
|
6
|
-
import
|
|
7
|
+
import { DepTargetType, HookData } from '@editor/type';
|
|
7
8
|
|
|
8
9
|
export const createCodeBlockTarget = (id: Id, codeBlock: CodeBlockContent) =>
|
|
9
10
|
new Target({
|
|
10
|
-
type:
|
|
11
|
+
type: DepTargetType.CODE_BLOCK,
|
|
11
12
|
id,
|
|
12
13
|
name: codeBlock.name,
|
|
13
14
|
isTarget: (key: string | number, value: any) => {
|
|
@@ -24,12 +25,37 @@ export const createCodeBlockTarget = (id: Id, codeBlock: CodeBlockContent) =>
|
|
|
24
25
|
},
|
|
25
26
|
});
|
|
26
27
|
|
|
27
|
-
export const createDataSourceTarget = (id: Id
|
|
28
|
+
export const createDataSourceTarget = (id: Id) =>
|
|
28
29
|
new Target({
|
|
29
|
-
type:
|
|
30
|
+
type: DepTargetType.DATA_SOURCE,
|
|
30
31
|
id,
|
|
31
|
-
name: ds.title || `${id}`,
|
|
32
32
|
isTarget: (key: string | number, value: any) =>
|
|
33
33
|
// 关联数据源对象或者在模板在使用数据源
|
|
34
|
-
(value
|
|
34
|
+
(value?.isBindDataSource && value.dataSourceId) || (typeof value === 'string' && value.includes(`${id}`)),
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
export const createDataSourceCondTarget = (id: string) =>
|
|
38
|
+
new Target({
|
|
39
|
+
type: DepTargetType.DATA_SOURCE_COND,
|
|
40
|
+
id,
|
|
41
|
+
isTarget: (key: string | number, value: any) => {
|
|
42
|
+
if (!Array.isArray(value) || value[0] !== id) return false;
|
|
43
|
+
|
|
44
|
+
const ds = dataSourceService.getDataSourceById(id);
|
|
45
|
+
|
|
46
|
+
return Boolean(ds?.fields?.find((field) => field.name === value[1]));
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
export const createDataSourceMethodTarget = (id: string) =>
|
|
51
|
+
new Target({
|
|
52
|
+
type: DepTargetType.DATA_SOURCE_METHOD,
|
|
53
|
+
id,
|
|
54
|
+
isTarget: (key: string | number, value: any) => {
|
|
55
|
+
if (!Array.isArray(value) || value[0] !== id) return false;
|
|
56
|
+
|
|
57
|
+
const ds = dataSourceService.getDataSourceById(id);
|
|
58
|
+
|
|
59
|
+
return Boolean(ds?.methods?.find((method) => method.name === value[1]));
|
|
60
|
+
},
|
|
35
61
|
});
|