@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.
Files changed (81) hide show
  1. package/dist/style.css +67 -75
  2. package/dist/tmagic-editor.js +1667 -1062
  3. package/dist/tmagic-editor.js.map +1 -1
  4. package/dist/tmagic-editor.umd.cjs +1692 -1084
  5. package/dist/tmagic-editor.umd.cjs.map +1 -1
  6. package/package.json +10 -10
  7. package/src/Editor.vue +70 -65
  8. package/src/components/ContentMenu.vue +5 -1
  9. package/src/components/SearchInput.vue +5 -1
  10. package/src/components/ToolButton.vue +1 -1
  11. package/src/editorProps.ts +51 -129
  12. package/src/fields/Code.vue +9 -3
  13. package/src/fields/DataSourceFieldSelect.vue +28 -16
  14. package/src/fields/DataSourceFields.vue +95 -7
  15. package/src/fields/DataSourceMethodSelect.vue +23 -14
  16. package/src/fields/DataSourceMocks.vue +237 -0
  17. package/src/fields/EventSelect.vue +30 -11
  18. package/src/index.ts +4 -1
  19. package/src/initService.ts +50 -20
  20. package/src/layouts/CodeEditor.vue +20 -4
  21. package/src/layouts/Framework.vue +3 -1
  22. package/src/layouts/PropsPanel.vue +3 -1
  23. package/src/layouts/sidebar/ComponentListPanel.vue +18 -8
  24. package/src/layouts/sidebar/Sidebar.vue +7 -10
  25. package/src/layouts/sidebar/code-block/CodeBlockList.vue +3 -1
  26. package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +3 -1
  27. package/src/layouts/sidebar/layer/LayerNode.vue +206 -0
  28. package/src/layouts/sidebar/layer/LayerNodeTool.vue +32 -0
  29. package/src/layouts/sidebar/layer/LayerPanel.vue +85 -0
  30. package/src/layouts/sidebar/layer/use-drag.ts +157 -0
  31. package/src/layouts/sidebar/layer/use-filter.ts +70 -0
  32. package/src/layouts/sidebar/layer/use-keybinding.ts +47 -0
  33. package/src/layouts/sidebar/layer/use-node-status.ts +103 -0
  34. package/src/layouts/workspace/Workspace.vue +3 -1
  35. package/src/layouts/workspace/viewer/NodeListMenu.vue +16 -9
  36. package/src/layouts/workspace/viewer/Stage.vue +19 -17
  37. package/src/layouts/workspace/viewer/ViewerMenu.vue +1 -1
  38. package/src/services/dataSource.ts +21 -0
  39. package/src/services/editor.ts +45 -5
  40. package/src/theme/common/var.scss +2 -2
  41. package/src/theme/content-menu.scss +22 -20
  42. package/src/theme/framework.scss +2 -0
  43. package/src/theme/layer-panel.scss +63 -63
  44. package/src/theme/props-panel.scss +8 -0
  45. package/src/theme/sidebar.scss +1 -5
  46. package/src/type.ts +61 -0
  47. package/src/utils/data-source/index.ts +23 -0
  48. package/src/utils/dep.ts +26 -11
  49. package/src/utils/editor.ts +14 -3
  50. package/src/utils/props.ts +4 -0
  51. package/types/editorProps.d.ts +61 -107
  52. package/types/fields/Code.vue.d.ts +10 -6
  53. package/types/fields/DataSourceMocks.vue.d.ts +32 -0
  54. package/types/index.d.ts +2 -1
  55. package/types/initService.d.ts +5 -4
  56. package/types/layouts/CodeEditor.vue.d.ts +5 -0
  57. package/types/layouts/Framework.vue.d.ts +2 -12
  58. package/types/layouts/PropsPanel.vue.d.ts +2 -3
  59. package/types/layouts/sidebar/ComponentListPanel.vue.d.ts +2 -7
  60. package/types/layouts/sidebar/Sidebar.vue.d.ts +2 -17
  61. package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +2 -7
  62. package/types/layouts/sidebar/code-block/CodeBlockListPanel.vue.d.ts +2 -9
  63. package/types/layouts/sidebar/{LayerMenu.vue.d.ts → layer/LayerMenu.vue.d.ts} +1 -1
  64. package/types/layouts/sidebar/layer/LayerNode.vue.d.ts +50 -0
  65. package/types/layouts/sidebar/{LayerNode.vue.d.ts → layer/LayerNodeTool.vue.d.ts} +1 -1
  66. package/types/layouts/sidebar/{LayerPanel.vue.d.ts → layer/LayerPanel.vue.d.ts} +2 -8
  67. package/types/layouts/sidebar/layer/use-drag.d.ts +14 -0
  68. package/types/layouts/sidebar/layer/use-filter.d.ts +8 -0
  69. package/types/layouts/sidebar/layer/use-keybinding.d.ts +4 -0
  70. package/types/layouts/sidebar/layer/use-node-status.d.ts +7 -0
  71. package/types/layouts/workspace/Workspace.vue.d.ts +2 -11
  72. package/types/layouts/workspace/viewer/Stage.vue.d.ts +1 -1
  73. package/types/services/dataSource.d.ts +7 -0
  74. package/types/services/editor.d.ts +1 -0
  75. package/types/type.d.ts +61 -0
  76. package/types/utils/dep.d.ts +1 -1
  77. package/types/utils/editor.d.ts +3 -2
  78. package/src/layouts/sidebar/LayerNode.vue +0 -40
  79. package/src/layouts/sidebar/LayerPanel.vue +0 -369
  80. package/types/Editor.vue.d.ts +0 -233
  81. /package/src/layouts/sidebar/{LayerMenu.vue → layer/LayerMenu.vue} +0 -0
@@ -80,6 +80,7 @@ class Editor extends BaseService {
80
80
  'undo',
81
81
  'redo',
82
82
  'highlight',
83
+ 'dragTo',
83
84
  ],
84
85
  // 需要注意循环依赖问题,如果函数间有相互调用的话,不能设置为串行调用
85
86
  ['select', 'update', 'moveLayer'],
@@ -253,7 +254,7 @@ class Editor extends BaseService {
253
254
 
254
255
  if (!parent) return node;
255
256
 
256
- const index = getNodeIndex(node, parent);
257
+ const index = getNodeIndex(node.id, parent);
257
258
 
258
259
  const nextNode = parent.items[index + 1] || parent.items[0];
259
260
 
@@ -270,7 +271,7 @@ class Editor extends BaseService {
270
271
  if (!page) throw new Error('page不能为空');
271
272
  if (!root) throw new Error('root不能为空');
272
273
 
273
- const index = getNodeIndex(page, root);
274
+ const index = getNodeIndex(page.id, root);
274
275
 
275
276
  const nextPage = root.items[index + 1] || root.items[0];
276
277
 
@@ -418,7 +419,7 @@ class Editor extends BaseService {
418
419
 
419
420
  if (!parent || !curNode) throw new Error('找不要删除的节点');
420
421
 
421
- const index = getNodeIndex(curNode, parent);
422
+ const index = getNodeIndex(curNode.id, parent);
422
423
 
423
424
  if (typeof index !== 'number' || index === -1) throw new Error('找不要删除的节点');
424
425
 
@@ -503,7 +504,7 @@ class Editor extends BaseService {
503
504
  if (!parent) throw new Error('获取不到父级节点');
504
505
 
505
506
  const parentNodeItems = parent.items;
506
- const index = getNodeIndex(newConfig, parent);
507
+ const index = getNodeIndex(newConfig.id, parent);
507
508
 
508
509
  if (!parentNodeItems || typeof index === 'undefined' || index === -1) throw new Error('更新的节点未找到');
509
510
 
@@ -737,7 +738,7 @@ class Editor extends BaseService {
737
738
 
738
739
  const stage = this.get('stage');
739
740
  if (root && node && parent && stage) {
740
- const index = getNodeIndex(node, parent);
741
+ const index = getNodeIndex(node.id, parent);
741
742
  parent.items?.splice(index, 1);
742
743
 
743
744
  await stage.remove({ id: node.id, parentId: parent.id, root });
@@ -769,6 +770,45 @@ class Editor extends BaseService {
769
770
  }
770
771
  }
771
772
 
773
+ public async dragTo(config: MNode, targetParent: MContainer, targetIndex: number) {
774
+ if (!targetParent || !Array.isArray(targetParent.items)) return;
775
+
776
+ const { parent, node: curNode } = this.getNodeInfo(config.id, false);
777
+ if (!parent || !curNode) throw new Error('找不要删除的节点');
778
+
779
+ const index = getNodeIndex(curNode.id, parent);
780
+
781
+ if (typeof index !== 'number' || index === -1) throw new Error('找不要删除的节点');
782
+
783
+ if (parent.id === targetParent.id) {
784
+ if (index === targetIndex) return;
785
+
786
+ if (index < targetIndex) {
787
+ targetIndex -= 1;
788
+ }
789
+ }
790
+
791
+ parent.items?.splice(index, 1);
792
+ targetParent.items?.splice(targetIndex, 0, config);
793
+
794
+ const page = this.get('page');
795
+ const root = this.get('root');
796
+ const stage = this.get('stage');
797
+
798
+ if (stage && page && root) {
799
+ stage.update({
800
+ config: cloneDeep(page),
801
+ parentId: root.id,
802
+ root: cloneDeep(root),
803
+ });
804
+ }
805
+
806
+ this.addModifiedNodeId(config.id);
807
+ this.addModifiedNodeId(parent.id);
808
+
809
+ this.pushHistoryState();
810
+ }
811
+
772
812
  /**
773
813
  * 撤销当前操作
774
814
  * @returns 上一次数据
@@ -1,11 +1,11 @@
1
1
  $--theme-color: #2882e0;
2
2
 
3
- $--font-color: #070303;
3
+ $--font-color: #313a40;
4
4
  $--border-color: #d9dbdd;
5
5
  $--hover-color: #f3f5f9;
6
6
 
7
7
  $--nav-height: 35px;
8
- $--nav-color: #070303;
8
+ $--nav-color: #313a40;
9
9
  $--nav--background-color: #ffffff;
10
10
 
11
11
  $--sidebar-heder-background-color: $--theme-color;
@@ -44,30 +44,32 @@
44
44
  }
45
45
  }
46
46
 
47
- &.active {
48
- background-color: $--theme-color;
49
- .tmagic-design-button,
50
- .tmagic-design-button:active,
51
- .tmagic-design-button:focus {
52
- color: #fff;
53
- background-color: $--theme-color;
54
- }
47
+ &.button {
48
+ &:hover {
49
+ background-color: $--hover-color;
50
+ .tmagic-design-button,
51
+ .tmagic-design-button:active,
52
+ .tmagic-design-button:focus {
53
+ color: $--font-color;
54
+ }
55
55
 
56
- &.menu-item i {
57
- color: #fff;
56
+ &.menu-item i {
57
+ color: $--font-color;
58
+ }
58
59
  }
59
- }
60
60
 
61
- &:hover {
62
- background-color: $--hover-color;
63
- .tmagic-design-button,
64
- .tmagic-design-button:active,
65
- .tmagic-design-button:focus {
66
- color: $--font-color;
67
- }
61
+ &.active {
62
+ background-color: $--theme-color;
63
+ .tmagic-design-button,
64
+ .tmagic-design-button:active,
65
+ .tmagic-design-button:focus {
66
+ color: #fff;
67
+ background-color: transparent;
68
+ }
68
69
 
69
- &.menu-item i {
70
- color: $--font-color;
70
+ &.menu-item i {
71
+ color: #fff;
72
+ }
71
73
  }
72
74
  }
73
75
  }
@@ -2,6 +2,8 @@
2
2
  display: flex;
3
3
  flex-direction: column;
4
4
  width: 100%;
5
+ font-family: -apple-system, BlinkMacSystemFont, Segoe WPC, Segoe UI,
6
+ Microsoft YaHei, sans-serif;
5
7
 
6
8
  &-content {
7
9
  height: calc(100% - #{$--nav-height});
@@ -1,75 +1,75 @@
1
1
  .magic-editor-layer-panel {
2
+ $--node-height: 22px;
3
+
2
4
  background: $--sidebar-content-background-color;
3
5
 
4
6
  .magic-editor-layer-tree {
5
7
  padding-top: 48px;
6
- }
8
+ background-color: $--sidebar-content-background-color;
9
+ color: $--font-color;
10
+ font-size: 13px;
7
11
 
8
- .node-content {
9
- flex: 1;
10
- display: flex;
11
- width: 100%;
12
- > div {
13
- width: 8px;
14
- }
15
- > span {
16
- width: calc(100% - 68px);
17
- white-space: nowrap;
18
- overflow: hidden;
19
- text-overflow: ellipsis;
20
- }
21
- > i {
22
- margin-right: 10px;
23
- font-size: 20px;
24
- &.lock {
25
- color: #bbb;
26
- }
27
- }
28
- }
29
- }
30
- .magic-editor-layer-panel,
31
- .magic-editor-layer-panel .el-tree {
32
- background-color: $--sidebar-content-background-color;
33
- color: #313a40;
34
- }
12
+ .magic-editor-layer-node {
13
+ cursor: pointer;
35
14
 
36
- .magic-editor-layer-panel
37
- .el-tree--highlight-current
38
- .el-tree-node.is-current
39
- > .el-tree-node__content {
40
- background-color: $--sidebar-heder-background-color;
41
- color: #fff;
42
- }
15
+ .layer-node {
16
+ display: flex;
17
+ align-items: center;
43
18
 
44
- .magic-editor-layer-panel .cus-tree-node {
45
- width: 100%;
46
- overflow: hidden;
47
- display: flex;
48
- justify-content: space-between;
19
+ &:hover {
20
+ background-color: $--hover-color;
21
+ color: $--font-color;
22
+ }
49
23
 
50
- .layer-node-tool {
51
- margin-right: 15px;
52
- }
53
- }
24
+ &.selected {
25
+ background-color: $--theme-color;
26
+ color: $--hover-color;
27
+ }
54
28
 
55
- .magic-editor-layer-panel .cus-tree-node-hover {
56
- background-color: $--hover-color;
57
- width: 100%;
58
- }
29
+ &.drag-inner {
30
+ .layer-node-content {
31
+ background-color: rgba($color: $--theme-color, $alpha: 0.5);
32
+ color: $--hover-color;
33
+ }
34
+ }
59
35
 
60
- .magic-editor-layer-panel .el-tree-node:focus > .el-tree-node__content {
61
- background-color: $--sidebar-heder-background-color;
62
- color: #fff;
63
- }
64
- .ui-tree-tip {
65
- width: 100%;
66
- height: 25px;
67
- margin-left: 10px;
68
- background: $--sidebar-content-background-color;
69
- font-style: italic;
70
- color: #555554;
71
- position: absolute;
72
- top: 40px;
73
- left: 0;
74
- z-index: 1;
36
+ &.drag-before {
37
+ .layer-node-content {
38
+ border-top-color: rgba($color: $--theme-color, $alpha: 0.5);
39
+ }
40
+ }
41
+
42
+ &.drag-after {
43
+ .layer-node-content {
44
+ border-bottom-color: rgba($color: $--theme-color, $alpha: 0.5);
45
+ }
46
+ }
47
+
48
+ .expand-icon {
49
+ padding: 4px;
50
+ box-sizing: content-box;
51
+ font-size: 14px;
52
+ }
53
+
54
+ .layer-node-content {
55
+ display: flex;
56
+ flex: 1;
57
+ justify-content: space-between;
58
+ height: $--node-height;
59
+ border-top: 2px solid transparent;
60
+ border-bottom: 2px solid transparent;
61
+ .layer-node-label {
62
+ line-height: $--node-height;
63
+ flex: 1;
64
+ }
65
+ }
66
+
67
+ .layer-node-tool {
68
+ margin-right: 15px;
69
+ display: flex;
70
+ align-items: center;
71
+ }
72
+ }
73
+ }
74
+ }
75
75
  }
@@ -20,6 +20,14 @@
20
20
  .el-input__wrapper {
21
21
  border-radius: 0;
22
22
  }
23
+
24
+ .m-fields-group-list {
25
+ .tmagic-design-table {
26
+ th {
27
+ font-size: 12px;
28
+ }
29
+ }
30
+ }
23
31
  }
24
32
 
25
33
  .m-editor-props-panel-popper {
@@ -49,14 +49,10 @@
49
49
  overflow: auto;
50
50
  }
51
51
 
52
- .el-scrollbar {
52
+ .tmagic-design-scrollbar {
53
53
  height: 100%;
54
54
  }
55
55
 
56
- .el-tree {
57
- min-height: 100%;
58
- }
59
-
60
56
  .fold-icon {
61
57
  position: absolute;
62
58
  bottom: 8px;
package/src/type.ts CHANGED
@@ -41,6 +41,54 @@ import type { StorageService } from './services/storage';
41
41
  import type { UiService } from './services/ui';
42
42
  import type { UndoRedo } from './utils/undo-redo';
43
43
 
44
+ export interface FrameworkSlots {
45
+ header(props: {}): any;
46
+ nav(props: {}): any;
47
+ 'content-before'(props: {}): any;
48
+ 'content-after'(props: {}): any;
49
+ 'src-code'(props: {}): any;
50
+ sidebar(props: {}): any;
51
+ empty(props: {}): any;
52
+ workspace(props: {}): any;
53
+ 'props-panel'(props: {}): any;
54
+ 'footer'(props: {}): any;
55
+ }
56
+
57
+ export interface WorkspaceSlots {
58
+ stage(props: {}): any;
59
+ 'workspace-content'(props: {}): any;
60
+ 'page-bar-title'(props: { page: MPage }): any;
61
+ 'page-bar-popover'(props: { page: MPage }): any;
62
+ }
63
+
64
+ export interface ComponentListPanelSlots {
65
+ 'component-list-panel-header'(props: {}): any;
66
+ 'component-list-item'(props: { component: ComponentItem }): any;
67
+ }
68
+
69
+ export interface CodeBlockListPanelSlots extends CodeBlockListSlots {
70
+ 'code-block-panel-search'(props: {}): any;
71
+ 'code-block-panel-header'(props: {}): any;
72
+ }
73
+
74
+ export interface CodeBlockListSlots {
75
+ 'code-block-panel-tool'(props: { id: Id; data: CodeBlockContent }): any;
76
+ }
77
+
78
+ export interface LayerNodeSlots {
79
+ 'layer-node-content'(props: { data: MNode }): any;
80
+ }
81
+
82
+ export interface LayerPanelSlots extends LayerNodeSlots {
83
+ 'layer-panel-header'(props: {}): any;
84
+ }
85
+
86
+ export interface PropsPanelSlots {
87
+ 'props-panel-header'(props: {}): any;
88
+ }
89
+
90
+ export type SidebarSlots = LayerPanelSlots & CodeBlockListPanelSlots & ComponentListPanelSlots;
91
+
44
92
  export type BeforeAdd = (config: MNode, parent: MContainer) => Promise<MNode> | MNode;
45
93
  export type GetConfig = (config: FormConfig) => Promise<FormConfig> | FormConfig;
46
94
 
@@ -418,6 +466,7 @@ export interface HistoryState {
418
466
  export interface EventSelectConfig {
419
467
  name: string;
420
468
  type: 'event-select';
469
+ src: 'datasource' | 'component';
421
470
  /** 事件名称表单配置 */
422
471
  eventNameConfig?: FormItem;
423
472
  /** 动作类型配置 */
@@ -506,6 +555,7 @@ export interface DataSourceMethodSelectConfig {
506
555
  export interface DataSourceFieldSelectConfig {
507
556
  type: 'data-source-field-select';
508
557
  name: string;
558
+ value?: 'key' | 'value';
509
559
  labelWidth?: number | string;
510
560
  disabled?: boolean | FilterFunction;
511
561
  display?: boolean | FilterFunction;
@@ -527,3 +577,14 @@ export interface DatasourceTypeOption {
527
577
  type: string;
528
578
  text: string;
529
579
  }
580
+
581
+ export interface LayerNodeStatus {
582
+ visible: boolean;
583
+ expand: boolean;
584
+ selected: boolean;
585
+ }
586
+
587
+ export enum DragType {
588
+ COMPONENT_LIST = 'component-list',
589
+ LAYER_TREE = 'layer-tree',
590
+ }
@@ -29,6 +29,29 @@ const fillConfig = (config: FormConfig): FormConfig => [
29
29
  },
30
30
  ],
31
31
  },
32
+ {
33
+ type: 'panel',
34
+ title: '事件配置',
35
+ display: false,
36
+ items: [
37
+ {
38
+ name: 'events',
39
+ src: 'datasource',
40
+ type: 'event-select',
41
+ },
42
+ ],
43
+ },
44
+ {
45
+ type: 'panel',
46
+ title: 'mock数据',
47
+ items: [
48
+ {
49
+ name: 'mocks',
50
+ type: 'data-source-mocks',
51
+ defaultValue: () => [],
52
+ },
53
+ ],
54
+ },
32
55
  ];
33
56
 
34
57
  export const getFormConfig = (type: string, configs: Record<string, FormConfig>): FormConfig => {
package/src/utils/dep.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import { isEmpty } from 'lodash-es';
2
2
 
3
- import { CodeBlockContent, HookType, Id } from '@tmagic/schema';
3
+ import { type CodeBlockContent, HookType, type Id } from '@tmagic/schema';
4
+ import { DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX } from '@tmagic/utils';
4
5
 
5
6
  import dataSourceService from '@editor/services/dataSource';
6
7
  import { Target } from '@editor/services/dep';
7
- import { DepTargetType, HookData } from '@editor/type';
8
+ import { DepTargetType, type HookData } from '@editor/type';
8
9
 
9
10
  export const createCodeBlockTarget = (id: Id, codeBlock: CodeBlockContent) =>
10
11
  new Target({
@@ -29,22 +30,36 @@ export const createDataSourceTarget = (id: Id) =>
29
30
  new Target({
30
31
  type: DepTargetType.DATA_SOURCE,
31
32
  id,
32
- isTarget: (key: string | number, value: any) =>
33
+ isTarget: (key: string | number, value: any) => {
33
34
  // 关联数据源对象或者在模板在使用数据源
34
- (value?.isBindDataSource && value.dataSourceId) || (typeof value === 'string' && value.includes(`${id}`)),
35
+ if ((value?.isBindDataSource && value.dataSourceId) || (typeof value === 'string' && value.includes(`${id}`))) {
36
+ return true;
37
+ }
38
+
39
+ // 关联数据源字段,格式为 [前缀+数据源ID, 字段名]
40
+ if (!Array.isArray(value) || typeof value[0] !== 'string') {
41
+ return false;
42
+ }
43
+
44
+ const [prefixId] = value;
45
+ const prefixIndex = prefixId.indexOf(DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX);
46
+
47
+ if (prefixIndex === -1) {
48
+ return false;
49
+ }
50
+
51
+ const dsId = prefixId.substring(prefixIndex + DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX.length);
52
+
53
+ return dsId === id && Boolean(dataSourceService.getDataSourceById(id));
54
+ },
35
55
  });
36
56
 
37
57
  export const createDataSourceCondTarget = (id: string) =>
38
58
  new Target({
39
59
  type: DepTargetType.DATA_SOURCE_COND,
40
60
  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
- },
61
+ isTarget: (key: string | number, value: any) =>
62
+ Array.isArray(value) && value[0] === id && Boolean(dataSourceService.getDataSourceById(id)),
48
63
  });
49
64
 
50
65
  export const createDataSourceMethodTarget = (id: string) =>
@@ -18,7 +18,7 @@
18
18
 
19
19
  import serialize from 'serialize-javascript';
20
20
 
21
- import type { MApp, MContainer, MNode, MPage } from '@tmagic/schema';
21
+ import type { Id, MApp, MContainer, MNode, MPage } from '@tmagic/schema';
22
22
  import { NodeType } from '@tmagic/schema';
23
23
  import type StageCore from '@tmagic/stage';
24
24
  import { getNodePath, isNumber, isPage, isPop } from '@tmagic/utils';
@@ -77,9 +77,9 @@ export const generatePageNameByApp = (app: MApp): string => generatePageName(get
77
77
  */
78
78
  export const isFixed = (node: MNode): boolean => node.style?.position === 'fixed';
79
79
 
80
- export const getNodeIndex = (node: MNode, parent: MContainer | MApp): number => {
80
+ export const getNodeIndex = (id: Id, parent: MContainer | MApp): number => {
81
81
  const items = parent?.items || [];
82
- return items.findIndex((item: MNode) => `${item.id}` === `${node.id}`);
82
+ return items.findIndex((item: MNode) => `${item.id}` === `${id}`);
83
83
  };
84
84
 
85
85
  export const getRelativeStyle = (style: Record<string, any> = {}): Record<string, any> => ({
@@ -251,3 +251,14 @@ export const serializeConfig = (config: any) =>
251
251
  space: 2,
252
252
  unsafe: true,
253
253
  }).replace(/"(\w+)":\s/g, '$1: ');
254
+
255
+ export const traverseNode = (node: MNode, cb: (node: MNode, parents: MNode[]) => void, parents: MNode[] = []) => {
256
+ cb(node, parents);
257
+
258
+ if (node.items?.length) {
259
+ parents.push(node);
260
+ node.items.forEach((item: MNode) => {
261
+ traverseNode(item, cb, parents);
262
+ });
263
+ }
264
+ };
@@ -205,6 +205,7 @@ export const eventTabConfig: TabPaneConfig = {
205
205
  items: [
206
206
  {
207
207
  name: 'events',
208
+ src: 'component',
208
209
  type: 'event-select',
209
210
  },
210
211
  ],
@@ -236,6 +237,8 @@ export const displayTabConfig: TabPaneConfig = {
236
237
  {
237
238
  type: 'groupList',
238
239
  name: 'displayConds',
240
+ titlePrefix: '条件组',
241
+ expandAll: true,
239
242
  items: [
240
243
  {
241
244
  type: 'table',
@@ -244,6 +247,7 @@ export const displayTabConfig: TabPaneConfig = {
244
247
  {
245
248
  type: 'data-source-field-select',
246
249
  name: 'field',
250
+ value: 'key',
247
251
  label: '字段',
248
252
  },
249
253
  {