@tmagic/editor 1.3.0-alpha.9 → 1.3.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/dist/style.css +77 -218
  2. package/dist/tmagic-editor.js +4143 -3302
  3. package/dist/tmagic-editor.js.map +1 -1
  4. package/dist/tmagic-editor.umd.cjs +5289 -4434
  5. package/dist/tmagic-editor.umd.cjs.map +1 -1
  6. package/package.json +15 -15
  7. package/src/Editor.vue +4 -5
  8. package/src/components/CodeBlockEditor.vue +257 -0
  9. package/src/components/CodeParams.vue +60 -0
  10. package/src/components/ContentMenu.vue +11 -3
  11. package/src/editorProps.ts +30 -5
  12. package/src/fields/Code.vue +23 -19
  13. package/src/fields/CodeLink.vue +6 -7
  14. package/src/fields/CodeSelect.vue +12 -9
  15. package/src/fields/CodeSelectCol.vue +70 -81
  16. package/src/fields/DataSourceFieldSelect.vue +47 -0
  17. package/src/fields/DataSourceFields.vue +28 -22
  18. package/src/fields/DataSourceInput.vue +21 -58
  19. package/src/fields/DataSourceMethodSelect.vue +136 -0
  20. package/src/fields/DataSourceMethods.vue +103 -0
  21. package/src/fields/DataSourceSelect.vue +5 -12
  22. package/src/fields/EventSelect.vue +53 -19
  23. package/src/fields/KeyValue.vue +9 -11
  24. package/src/fields/UISelect.vue +54 -14
  25. package/src/hooks/index.ts +21 -0
  26. package/src/hooks/use-code-block-edit.ts +84 -0
  27. package/src/hooks/use-data-source-method.ts +100 -0
  28. package/src/{utils/stage.ts → hooks/use-stage.ts} +4 -7
  29. package/src/icons/CenterIcon.vue +13 -0
  30. package/src/icons/CodeIcon.vue +0 -2
  31. package/src/icons/FolderMinusIcon.vue +22 -0
  32. package/src/index.ts +12 -0
  33. package/src/initService.ts +69 -16
  34. package/src/layouts/CodeEditor.vue +35 -3
  35. package/src/layouts/Framework.vue +7 -3
  36. package/src/layouts/PropsPanel.vue +8 -3
  37. package/src/layouts/sidebar/ComponentListPanel.vue +4 -6
  38. package/src/layouts/sidebar/LayerMenu.vue +20 -21
  39. package/src/layouts/sidebar/LayerPanel.vue +12 -2
  40. package/src/layouts/sidebar/Sidebar.vue +22 -36
  41. package/src/layouts/sidebar/code-block/CodeBlockList.vue +81 -119
  42. package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +64 -0
  43. package/src/layouts/sidebar/data-source/DataSourceConfigPanel.vue +27 -47
  44. package/src/layouts/sidebar/data-source/DataSourceList.vue +145 -0
  45. package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +58 -85
  46. package/src/layouts/workspace/Stage.vue +3 -2
  47. package/src/layouts/workspace/ViewerMenu.vue +10 -35
  48. package/src/services/codeBlock.ts +18 -71
  49. package/src/services/dataSource.ts +16 -1
  50. package/src/services/dep.ts +22 -20
  51. package/src/services/editor.ts +46 -18
  52. package/src/services/props.ts +2 -2
  53. package/src/theme/code-block.scss +5 -117
  54. package/src/theme/code-editor.scss +27 -2
  55. package/src/theme/content-menu.scss +1 -1
  56. package/src/theme/data-source-methods.scss +13 -0
  57. package/src/theme/data-source.scss +11 -0
  58. package/src/theme/event.scss +15 -12
  59. package/src/theme/framework.scss +0 -3
  60. package/src/theme/layout.scss +4 -0
  61. package/src/theme/sidebar.scss +18 -60
  62. package/src/theme/theme.scss +1 -0
  63. package/src/type.ts +47 -7
  64. package/src/utils/content-menu.ts +92 -0
  65. package/src/utils/data-source/formConfigs/base.ts +28 -30
  66. package/src/utils/data-source/index.ts +65 -2
  67. package/src/utils/dep.ts +33 -7
  68. package/src/utils/index.ts +1 -1
  69. package/src/utils/props.ts +298 -189
  70. package/src/utils/undo-redo.ts +1 -1
  71. package/types/Editor.vue.d.ts +30 -6
  72. package/types/components/CodeBlockEditor.vue.d.ts +23 -0
  73. package/types/components/CodeParams.vue.d.ts +26 -0
  74. package/types/components/ContentMenu.vue.d.ts +2 -2
  75. package/types/components/ToolButton.vue.d.ts +3 -3
  76. package/types/editorProps.d.ts +19 -5
  77. package/types/fields/Code.vue.d.ts +24 -19
  78. package/types/fields/CodeLink.vue.d.ts +12 -21
  79. package/types/fields/CodeSelect.vue.d.ts +6 -17
  80. package/types/fields/CodeSelectCol.vue.d.ts +10 -14
  81. package/types/fields/DataSourceFieldSelect.vue.d.ts +29 -0
  82. package/types/fields/DataSourceFields.vue.d.ts +7 -18
  83. package/types/fields/DataSourceInput.vue.d.ts +10 -30
  84. package/types/fields/DataSourceMethodSelect.vue.d.ts +29 -0
  85. package/types/fields/DataSourceMethods.vue.d.ts +32 -0
  86. package/types/fields/DataSourceSelect.vue.d.ts +13 -29
  87. package/types/fields/EventSelect.vue.d.ts +2 -13
  88. package/types/fields/KeyValue.vue.d.ts +9 -24
  89. package/types/fields/UISelect.vue.d.ts +2 -11
  90. package/types/hooks/index.d.ts +3 -0
  91. package/types/{components/FunctionEditor.vue.d.ts → hooks/use-code-block-edit.d.ts} +31 -121
  92. package/types/hooks/use-data-source-method.d.ts +123 -0
  93. package/types/icons/CenterIcon.vue.d.ts +2 -0
  94. package/types/icons/FolderMinusIcon.vue.d.ts +2 -0
  95. package/types/index.d.ts +6 -0
  96. package/types/initService.d.ts +2 -2
  97. package/types/layouts/CodeEditor.vue.d.ts +7 -4
  98. package/types/layouts/PropsPanel.vue.d.ts +274 -2
  99. package/types/layouts/sidebar/Sidebar.vue.d.ts +0 -3
  100. package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +4 -9
  101. package/types/layouts/sidebar/code-block/{CodeBlockEditor.vue.d.ts → CodeBlockListPanel.vue.d.ts} +9 -5
  102. package/types/layouts/sidebar/data-source/DataSourceConfigPanel.vue.d.ts +3 -1
  103. package/types/layouts/sidebar/data-source/DataSourceList.vue.d.ts +14 -0
  104. package/types/layouts/sidebar/data-source/DataSourceListPanel.vue.d.ts +1 -11
  105. package/types/services/codeBlock.d.ts +6 -37
  106. package/types/services/dataSource.d.ts +7 -1
  107. package/types/services/dep.d.ts +12 -21
  108. package/types/services/editor.d.ts +1 -1
  109. package/types/services/props.d.ts +10 -115
  110. package/types/type.d.ts +42 -7
  111. package/types/utils/content-menu.d.ts +7 -0
  112. package/types/utils/data-source/formConfigs/base.d.ts +1 -2
  113. package/types/utils/data-source/index.d.ts +5 -0
  114. package/types/utils/dep.d.ts +4 -2
  115. package/types/utils/index.d.ts +1 -1
  116. package/types/utils/props.d.ts +13 -102
  117. package/src/components/CodeDraftEditor.vue +0 -148
  118. package/src/components/FunctionEditor.vue +0 -197
  119. package/src/layouts/sidebar/code-block/CodeBlockEditor.vue +0 -100
  120. package/types/components/CodeDraftEditor.vue.d.ts +0 -61
  121. /package/types/{utils/stage.d.ts → hooks/use-stage.d.ts} +0 -0
@@ -2,122 +2,110 @@
2
2
  <TMagicScrollbar class="data-source-list-panel m-editor-dep-list-panel">
3
3
  <div class="search-wrapper">
4
4
  <SearchInput @search="filterTextChangeHandler"></SearchInput>
5
- <TMagicButton type="primary" size="small" @click="addHandler">新增</TMagicButton>
5
+ <TMagicPopover v-if="editable" placement="right">
6
+ <template #reference>
7
+ <TMagicButton type="primary" size="small">新增</TMagicButton>
8
+ </template>
9
+ <div class="data-source-list-panel-add-menu">
10
+ <ToolButton
11
+ v-for="(item, index) in datasourceTypeList"
12
+ :data="{
13
+ type: 'button',
14
+ text: item.text,
15
+ handler: () => {
16
+ addHandler(item.type);
17
+ },
18
+ }"
19
+ :key="index"
20
+ ></ToolButton>
21
+ </div>
22
+ </TMagicPopover>
6
23
  </div>
7
24
 
8
25
  <!-- 数据源列表 -->
9
- <TMagicTree
10
- ref="tree"
11
- class="magic-editor-layer-tree"
12
- node-key="id"
13
- empty-text="暂无代码块"
14
- default-expand-all
15
- :expand-on-click-node="false"
16
- :data="list"
17
- :highlight-current="true"
18
- @node-click="clickHandler"
19
- >
20
- <template #default="{ data }">
21
- <div :id="data.id" class="list-container">
22
- <div class="list-item">
23
- <Icon v-if="data.type === 'code'" class="codeIcon" :icon="Coin"></Icon>
24
- <Icon v-if="data.type === 'node'" class="compIcon" :icon="Aim"></Icon>
25
- <span class="name" :class="{ code: data.type === 'code', hook: data.type === 'key' }"
26
- >{{ data.name }}({{ data.id }})</span
27
- >
28
- <!-- 右侧工具栏 -->
29
- <div class="right-tool" v-if="data.type === 'code'">
30
- <TMagicTooltip effect="dark" content="编辑" placement="bottom">
31
- <Icon class="edit-icon" :icon="Edit" @click.stop="editHandler(`${data.id}`)"></Icon>
32
- </TMagicTooltip>
33
- <TMagicTooltip effect="dark" content="删除" placement="bottom">
34
- <Icon :icon="Close" class="edit-icon" @click.stop="removeHandler(`${data.id}`)"></Icon>
35
- </TMagicTooltip>
36
- <slot name="data-source-panel-tool" :id="data.id" :data="data.codeBlockContent"></slot>
37
- </div>
38
- </div>
39
- </div>
40
- </template>
41
- </TMagicTree>
26
+ <DataSourceList @edit="editHandler" @remove="removeHandler"></DataSourceList>
42
27
 
43
28
  <DataSourceConfigPanel
44
29
  ref="editDialog"
30
+ :disabled="!editable"
45
31
  :values="dataSourceValues"
46
- :title="typeof dataSourceValues.id !== 'undefined' ? `编辑${dataSourceValues.title}` : '新增'"
32
+ :title="dialogTitle"
47
33
  @submit="submitDataSourceHandler"
48
34
  ></DataSourceConfigPanel>
49
35
  </TMagicScrollbar>
50
36
  </template>
51
37
 
52
- <script setup lang="ts" name="MEditorDataSourceListPanel">
38
+ <script setup lang="ts">
53
39
  import { computed, inject, ref } from 'vue';
54
- import { Aim, Close, Coin, Edit } from '@element-plus/icons-vue';
40
+ import { mergeWith } from 'lodash-es';
55
41
 
56
- import { TMagicButton, tMagicMessageBox, TMagicScrollbar, TMagicTooltip, TMagicTree } from '@tmagic/design';
57
- import { DataSourceSchema, Id } from '@tmagic/schema';
42
+ import { TMagicButton, TMagicPopover, TMagicScrollbar } from '@tmagic/design';
43
+ import type { DataSourceSchema } from '@tmagic/schema';
58
44
 
59
- import Icon from '@editor/components/Icon.vue';
60
45
  import SearchInput from '@editor/components/SearchInput.vue';
46
+ import ToolButton from '@editor/components/ToolButton.vue';
61
47
  import type { Services } from '@editor/type';
62
48
 
63
49
  import DataSourceConfigPanel from './DataSourceConfigPanel.vue';
50
+ import DataSourceList from './DataSourceList.vue';
64
51
 
65
52
  defineOptions({
66
53
  name: 'MEditorDataSourceListPanel',
67
54
  });
68
55
 
69
- const services = inject<Partial<Services>>('services', {});
70
- const { dataSourceService, depService, editorService } = inject<Services>('services') || {};
71
-
72
- const list = computed(() =>
73
- Object.values(depService?.targets['data-source'] || {}).map((target) => ({
74
- id: target.id,
75
- name: target.name,
76
- type: 'code',
77
- children: Object.entries(target.deps).map(([id, dep]) => ({
78
- name: dep.name,
79
- type: 'node',
80
- id,
81
- children: dep.keys.map((key) => ({ name: key, id: key, type: 'key' })),
82
- })),
83
- })),
84
- );
56
+ const { dataSourceService } = inject<Services>('services') || {};
85
57
 
86
58
  const editDialog = ref<InstanceType<typeof DataSourceConfigPanel>>();
87
59
 
88
60
  const dataSourceValues = ref<Record<string, any>>({});
89
61
 
90
- const addHandler = () => {
62
+ const dialogTitle = ref('');
63
+
64
+ const editable = computed(() => dataSourceService?.get('editable') ?? true);
65
+ const datasourceTypeList = computed(() =>
66
+ [
67
+ { text: '基础', type: 'base' },
68
+ { text: 'HTTP', type: 'http' },
69
+ ].concat(dataSourceService?.get('datasourceTypeList') ?? []),
70
+ );
71
+
72
+ const addHandler = (type: string) => {
91
73
  if (!editDialog.value) return;
92
74
 
93
- dataSourceValues.value = {};
75
+ const datasourceType = datasourceTypeList.value.find((item) => item.type === type);
76
+
77
+ dataSourceValues.value = mergeWith(
78
+ { type, title: datasourceType?.text },
79
+ dataSourceService?.getFormValue(type) || {},
80
+ (objValue, srcValue) => {
81
+ if (Array.isArray(srcValue)) {
82
+ return srcValue;
83
+ }
84
+ },
85
+ );
86
+
87
+ dialogTitle.value = `新增${datasourceType?.text || ''}`;
94
88
 
95
89
  editDialog.value.show();
96
90
  };
97
91
 
98
92
  const editHandler = (id: string) => {
99
- if (!editDialog.value || !services) return;
93
+ if (!editDialog.value) return;
100
94
 
101
95
  dataSourceValues.value = {
102
96
  ...dataSourceService?.getDataSourceById(id),
103
97
  };
104
98
 
99
+ dialogTitle.value = `新增${dataSourceValues.value.title || ''}`;
100
+
105
101
  editDialog.value.show();
106
102
  };
107
103
 
108
- const removeHandler = async (id: string) => {
109
- await tMagicMessageBox.confirm('确定删除?', '提示', {
110
- confirmButtonText: '确定',
111
- cancelButtonText: '取消',
112
- type: 'warning',
113
- });
114
-
104
+ const removeHandler = (id: string) => {
115
105
  dataSourceService?.remove(id);
116
106
  };
117
107
 
118
108
  const submitDataSourceHandler = (value: DataSourceSchema) => {
119
- if (!services) return;
120
-
121
109
  if (value.id) {
122
110
  dataSourceService?.update(value);
123
111
  } else {
@@ -127,24 +115,9 @@ const submitDataSourceHandler = (value: DataSourceSchema) => {
127
115
  editDialog.value?.hide();
128
116
  };
129
117
 
130
- const tree = ref<InstanceType<typeof TMagicTree>>();
118
+ const dataSourceList = ref<InstanceType<typeof DataSourceList>>();
131
119
 
132
120
  const filterTextChangeHandler = (val: string) => {
133
- tree.value?.filter(val);
134
- };
135
-
136
- // 选中组件
137
- const selectComp = (compId: Id) => {
138
- const stage = editorService?.get('stage');
139
- editorService?.select(compId);
140
- stage?.select(compId);
141
- };
142
-
143
- const clickHandler = (data: any, node: any) => {
144
- if (data.type === 'node') {
145
- selectComp(data.id);
146
- } else if (data.type === 'key') {
147
- selectComp(node.parent.data.id);
148
- }
121
+ dataSourceList.value?.filter(val);
149
122
  };
150
123
  </script>
@@ -12,6 +12,7 @@
12
12
  width: 60,
13
13
  height: 50,
14
14
  }"
15
+ @click="stageWrap?.container?.focus()"
15
16
  >
16
17
  <div
17
18
  class="m-editor-stage-container"
@@ -35,9 +36,9 @@ import type { MContainer } from '@tmagic/schema';
35
36
  import StageCore, { calcValueByFontsize, getOffset, Runtime } from '@tmagic/stage';
36
37
 
37
38
  import ScrollViewer from '@editor/components/ScrollViewer.vue';
39
+ import { useStage } from '@editor/hooks/use-stage';
38
40
  import { Layout, MenuButton, MenuComponent, Services, StageOptions } from '@editor/type';
39
41
  import { getConfig } from '@editor/utils/config';
40
- import { useStage } from '@editor/utils/stage';
41
42
 
42
43
  import ViewerMenu from './ViewerMenu.vue';
43
44
 
@@ -164,7 +165,7 @@ const dropHandler = async (e: DragEvent) => {
164
165
  if (e.dataTransfer && parent && stageContainer.value && stage) {
165
166
  const parseDSL = getConfig('parseDSL');
166
167
 
167
- const data = e.dataTransfer.getData('text/html');
168
+ const data = e.dataTransfer.getData('text/json');
168
169
 
169
170
  if (!data) return;
170
171
 
@@ -4,14 +4,16 @@
4
4
 
5
5
  <script lang="ts" setup>
6
6
  import { computed, inject, markRaw, ref, watch } from 'vue';
7
- import { Bottom, CopyDocument, Delete, DocumentCopy, Top } from '@element-plus/icons-vue';
7
+ import { Bottom, Top } from '@element-plus/icons-vue';
8
8
 
9
9
  import { NodeType } from '@tmagic/schema';
10
10
  import { isPage } from '@tmagic/utils';
11
11
 
12
12
  import ContentMenu from '@editor/components/ContentMenu.vue';
13
+ import CenterIcon from '@editor/icons/CenterIcon.vue';
13
14
  import storageService from '@editor/services/storage';
14
15
  import { LayerOffset, Layout, MenuButton, MenuComponent, Services } from '@editor/type';
16
+ import { useCopyMenu, useDeleteMenu, useMoveToMenu, usePasteMenu } from '@editor/utils/content-menu';
15
17
  import { COPY_STORAGE_KEY } from '@editor/utils/editor';
16
18
 
17
19
  defineOptions({
@@ -32,42 +34,20 @@ const canCenter = ref(false);
32
34
  const node = computed(() => editorService?.get('node'));
33
35
  const nodes = computed(() => editorService?.get('nodes'));
34
36
  const parent = computed(() => editorService?.get('parent'));
35
- const stage = computed(() => editorService?.get('stage'));
36
37
 
37
38
  const menuData = computed<(MenuButton | MenuComponent)[]>(() => [
38
39
  {
39
40
  type: 'button',
40
41
  text: '水平居中',
42
+ icon: markRaw(CenterIcon),
41
43
  display: () => canCenter.value,
42
44
  handler: () => {
43
45
  if (!nodes.value) return;
44
46
  editorService?.alignCenter(nodes.value);
45
47
  },
46
48
  },
47
- {
48
- type: 'button',
49
- text: '复制',
50
- icon: markRaw(CopyDocument),
51
- handler: () => {
52
- nodes.value && editorService?.copy(nodes.value);
53
- canPaste.value = true;
54
- },
55
- },
56
- {
57
- type: 'button',
58
- text: '粘贴',
59
- icon: markRaw(DocumentCopy),
60
- display: () => canPaste.value,
61
- handler: () => {
62
- const rect = menu.value?.$el.getBoundingClientRect();
63
- const parentRect = stage.value?.container?.getBoundingClientRect();
64
- const initialLeft = (rect?.left || 0) - (parentRect?.left || 0);
65
- const initialTop = (rect?.top || 0) - (parentRect?.top || 0);
66
-
67
- if (!nodes.value || nodes.value.length === 0) return;
68
- editorService?.paste({ left: initialLeft, top: initialTop });
69
- },
70
- },
49
+ useCopyMenu(),
50
+ usePasteMenu(menu),
71
51
  {
72
52
  type: 'divider',
73
53
  direction: 'horizontal',
@@ -97,6 +77,7 @@ const menuData = computed<(MenuButton | MenuComponent)[]>(() => [
97
77
  {
98
78
  type: 'button',
99
79
  text: '置顶',
80
+ icon: markRaw(Top),
100
81
  display: () => !isPage(node.value) && !props.isMultiSelect,
101
82
  handler: () => {
102
83
  editorService?.moveLayer(LayerOffset.TOP);
@@ -105,25 +86,19 @@ const menuData = computed<(MenuButton | MenuComponent)[]>(() => [
105
86
  {
106
87
  type: 'button',
107
88
  text: '置底',
89
+ icon: markRaw(Bottom),
108
90
  display: () => !isPage(node.value) && !props.isMultiSelect,
109
91
  handler: () => {
110
92
  editorService?.moveLayer(LayerOffset.BOTTOM);
111
93
  },
112
94
  },
95
+ useMoveToMenu(services),
113
96
  {
114
97
  type: 'divider',
115
98
  direction: 'horizontal',
116
99
  display: () => !isPage(node.value) && !props.isMultiSelect,
117
100
  },
118
- {
119
- type: 'button',
120
- text: '删除',
121
- icon: Delete,
122
- display: () => !isPage(node.value),
123
- handler: () => {
124
- nodes.value && editorService?.remove(nodes.value);
125
- },
126
- },
101
+ useDeleteMenu(),
127
102
  {
128
103
  type: 'divider',
129
104
  direction: 'horizontal',
@@ -19,7 +19,8 @@
19
19
  import { reactive } from 'vue';
20
20
  import { keys, pick } from 'lodash-es';
21
21
 
22
- import { CodeBlockContent, CodeBlockDSL, Id } from '@tmagic/schema';
22
+ import type { ColumnConfig } from '@tmagic/form';
23
+ import type { CodeBlockContent, CodeBlockDSL, Id } from '@tmagic/schema';
23
24
 
24
25
  import type { CodeState } from '@editor/type';
25
26
  import { CODE_DRAFT_STORAGE_KEY } from '@editor/type';
@@ -29,23 +30,15 @@ import BaseService from './BaseService';
29
30
 
30
31
  class CodeBlock extends BaseService {
31
32
  private state = reactive<CodeState>({
32
- isShowCodeEditor: false,
33
33
  codeDsl: null,
34
- id: '',
35
34
  editable: true,
36
35
  combineIds: [],
37
36
  undeletableList: [],
37
+ paramsColConfig: undefined,
38
38
  });
39
39
 
40
40
  constructor() {
41
- super([
42
- 'setCodeDslById',
43
- 'setCodeEditorShowStatus',
44
- 'setEditStatus',
45
- 'setCombineIds',
46
- 'setUndeleteableList',
47
- 'deleteCodeDslByIds',
48
- ]);
41
+ super(['setCodeDslById', 'setEditStatus', 'setCombineIds', 'setUndeleteableList', 'deleteCodeDslByIds']);
49
42
  }
50
43
 
51
44
  /**
@@ -86,7 +79,7 @@ class CodeBlock extends BaseService {
86
79
  * @param {CodeBlockContent} codeConfig 代码块内容配置信息
87
80
  * @returns {void}
88
81
  */
89
- public async setCodeDslById(id: Id, codeConfig: CodeBlockContent): Promise<void> {
82
+ public async setCodeDslById(id: Id, codeConfig: Partial<CodeBlockContent>): Promise<void> {
90
83
  const codeDsl = this.getCodeDsl();
91
84
 
92
85
  if (!codeDsl) {
@@ -97,7 +90,10 @@ class CodeBlock extends BaseService {
97
90
  if (codeConfig.content) {
98
91
  // 在保存的时候转换代码内容
99
92
  const parseDSL = getConfig('parseDSL');
100
- codeConfigProcessed.content = parseDSL(codeConfig.content);
93
+ if (typeof codeConfig.content === 'string') {
94
+ codeConfig.content = parseDSL<(...args: any[]) => any>(codeConfig.content);
95
+ }
96
+ codeConfigProcessed.content = codeConfig.content;
101
97
  }
102
98
 
103
99
  const existContent = codeDsl[id] || {};
@@ -120,43 +116,6 @@ class CodeBlock extends BaseService {
120
116
  return pick(codeDsl, ids) as CodeBlockDSL;
121
117
  }
122
118
 
123
- /**
124
- * 设置代码编辑面板展示状态
125
- * @param {boolean} status 是否展示代码编辑面板
126
- * @returns {void}
127
- */
128
- public async setCodeEditorShowStatus(status: boolean): Promise<void> {
129
- this.state.isShowCodeEditor = status;
130
- }
131
-
132
- /**
133
- * 获取代码编辑面板展示状态
134
- * @returns {boolean} 是否展示代码编辑面板
135
- */
136
- public getCodeEditorShowStatus(): boolean {
137
- return this.state.isShowCodeEditor;
138
- }
139
-
140
- /**
141
- * 设置代码编辑面板展示状态及展示内容
142
- * @param {boolean} status 是否展示代码编辑面板
143
- * @param {Id} id 代码块id
144
- * @returns {void}
145
- */
146
- public setCodeEditorContent(status: boolean, id: Id): void {
147
- if (!id) return;
148
- this.setId(id);
149
- this.state.isShowCodeEditor = status;
150
- }
151
-
152
- /**
153
- * 获取当前选中的代码块内容
154
- * @returns {CodeBlockContent | null}
155
- */
156
- public getCurrentDsl(): CodeBlockContent | null {
157
- return this.getCodeContentById(this.state.id);
158
- }
159
-
160
119
  /**
161
120
  * 获取编辑状态
162
121
  * @returns {boolean} 是否可编辑
@@ -174,24 +133,6 @@ class CodeBlock extends BaseService {
174
133
  this.state.editable = status;
175
134
  }
176
135
 
177
- /**
178
- * 设置当前选中的代码块ID
179
- * @param {Id} id 代码块id
180
- * @returns {void}
181
- */
182
- public setId(id: Id): void {
183
- if (!id) return;
184
- this.state.id = id;
185
- }
186
-
187
- /**
188
- * 获取当前选中的代码块ID
189
- * @returns {Id} id 代码块id
190
- */
191
- public getId(): Id {
192
- return this.state.id;
193
- }
194
-
195
136
  /**
196
137
  * 设置当前选中组件已关联绑定的代码块id数组
197
138
  * @param {string[]} ids 代码块id数组
@@ -263,11 +204,19 @@ class CodeBlock extends BaseService {
263
204
  });
264
205
  }
265
206
 
207
+ public setParamsColConfig(config: ColumnConfig): void {
208
+ this.state.paramsColConfig = config;
209
+ }
210
+
211
+ public getParamsColConfig(): ColumnConfig | undefined {
212
+ return this.state.paramsColConfig;
213
+ }
214
+
266
215
  /**
267
216
  * 生成代码块唯一id
268
217
  * @returns {Id} 代码块唯一id
269
218
  */
270
- public async getUniqueId(): Promise<Id> {
219
+ public async getUniqueId(): Promise<string> {
271
220
  const newId = `code_${Math.random().toString(10).substring(2).substring(0, 4)}`;
272
221
  // 判断是否重复
273
222
  const dsl = await this.getCodeDsl();
@@ -277,9 +226,7 @@ class CodeBlock extends BaseService {
277
226
  }
278
227
 
279
228
  public resetState() {
280
- this.state.isShowCodeEditor = false;
281
229
  this.state.codeDsl = null;
282
- this.state.id = '';
283
230
  this.state.editable = true;
284
231
  this.state.combineIds = [];
285
232
  this.state.undeletableList = [];
@@ -2,23 +2,30 @@ import { reactive } from 'vue';
2
2
  import { cloneDeep } from 'lodash-es';
3
3
 
4
4
  import type { FormConfig } from '@tmagic/form';
5
- import { DataSourceSchema } from '@tmagic/schema';
5
+ import type { DataSourceSchema } from '@tmagic/schema';
6
6
  import { guid } from '@tmagic/utils';
7
7
 
8
+ import type { DatasourceTypeOption } from '@editor/type';
8
9
  import { getFormConfig } from '@editor/utils/data-source';
9
10
 
10
11
  import BaseService from './BaseService';
11
12
 
12
13
  interface State {
14
+ datasourceTypeList: DatasourceTypeOption[];
13
15
  dataSources: DataSourceSchema[];
16
+ editable: boolean;
14
17
  configs: Record<string, FormConfig>;
18
+ values: Record<string, Partial<DataSourceSchema>>;
15
19
  }
16
20
 
17
21
  type StateKey = keyof State;
18
22
  class DataSource extends BaseService {
19
23
  private state = reactive<State>({
24
+ datasourceTypeList: [],
20
25
  dataSources: [],
26
+ editable: true,
21
27
  configs: {},
28
+ values: {},
22
29
  });
23
30
 
24
31
  public set<K extends StateKey, T extends State[K]>(name: K, value: T) {
@@ -37,6 +44,14 @@ class DataSource extends BaseService {
37
44
  this.get('configs')[type] = config;
38
45
  }
39
46
 
47
+ public getFormValue(type = 'base') {
48
+ return this.get('values')[type];
49
+ }
50
+
51
+ public setFormValue(type: string, value: Partial<DataSourceSchema>) {
52
+ this.get('values')[type] = value;
53
+ }
54
+
40
55
  public add(config: DataSourceSchema) {
41
56
  const newConfig = {
42
57
  ...config,
@@ -19,27 +19,24 @@ import { EventEmitter } from 'events';
19
19
 
20
20
  import { reactive } from 'vue';
21
21
 
22
- import { MNode } from '@tmagic/schema';
22
+ import type { Dep, Id, MNode } from '@tmagic/schema';
23
+ import { isObject } from '@tmagic/utils';
24
+
25
+ import { DepTargetType } from '@editor/type';
23
26
 
24
27
  type IsTarget = (key: string | number, value: any) => boolean;
25
28
 
26
29
  interface TargetOptions {
27
30
  isTarget: IsTarget;
28
31
  id: string | number;
29
- type?: string;
30
- name: string;
31
- }
32
-
33
- interface Dep {
34
- [key: string | number]: {
35
- name: string;
36
- keys: (string | number)[];
37
- };
32
+ /** 类型,数据源、代码块或其他 */
33
+ type?: DepTargetType | string;
34
+ name?: string;
38
35
  }
39
36
 
40
37
  interface TargetList {
41
- [key: string]: {
42
- [key: string | number]: Target;
38
+ [type: DepTargetType | string]: {
39
+ [targetId: string | number]: Target;
43
40
  };
44
41
  }
45
42
 
@@ -60,11 +57,11 @@ export class Target extends EventEmitter {
60
57
  /**
61
58
  * 目标名称,用于显示在依赖列表中
62
59
  */
63
- public name: string;
60
+ public name?: string;
64
61
  /**
65
62
  * 不同的目标可以进行分类,例如代码块,数据源可以为两个不同的type
66
63
  */
67
- public type = 'default';
64
+ public type: DepTargetType | string = DepTargetType.DEFAULT;
68
65
  /**
69
66
  * 依赖详情
70
67
  * 实例:{ 'node_id': { name: 'node_name', keys: [ created, mounted ] } }
@@ -156,14 +153,14 @@ export class Target extends EventEmitter {
156
153
  }
157
154
 
158
155
  export class Watcher extends EventEmitter {
159
- public targets = reactive<TargetList>({});
156
+ private targets = reactive<TargetList>({});
160
157
 
161
158
  /**
162
159
  * 获取指定类型中的所有target
163
160
  * @param type 分类
164
161
  * @returns Target[]
165
162
  */
166
- public getTargets(type = 'default') {
163
+ public getTargets(type: DepTargetType | string = DepTargetType.DEFAULT) {
167
164
  return this.targets[type] || {};
168
165
  }
169
166
 
@@ -230,7 +227,7 @@ export class Watcher extends EventEmitter {
230
227
  * @param type 分类
231
228
  * @returns void
232
229
  */
233
- public removeTargets(type = 'default') {
230
+ public removeTargets(type: DepTargetType | string = DepTargetType.DEFAULT) {
234
231
  const targets = this.targets[type];
235
232
 
236
233
  if (!targets) return;
@@ -277,13 +274,15 @@ export class Watcher extends EventEmitter {
277
274
  * @param nodes 需要清除依赖的节点
278
275
  */
279
276
  public clear(nodes?: MNode[]) {
277
+ const clearedItemsNodeIds: Id[] = [];
280
278
  Object.values(this.targets).forEach((targets) => {
281
279
  Object.values(targets).forEach((target) => {
282
280
  if (nodes) {
283
281
  nodes.forEach((node) => {
284
282
  target.removeDep(node);
285
283
 
286
- if (Array.isArray(node.items)) {
284
+ if (Array.isArray(node.items) && node.items.length && !clearedItemsNodeIds.includes(node.id)) {
285
+ clearedItemsNodeIds.push(node.id);
287
286
  this.clear(node.items);
288
287
  }
289
288
  });
@@ -305,9 +304,11 @@ export class Watcher extends EventEmitter {
305
304
  this.emit('update-dep', node, fullKey);
306
305
  } else if (!keyIsItems && Array.isArray(value)) {
307
306
  value.forEach((item, index) => {
308
- collectTarget(item, `${fullKey}.${index}`);
307
+ if (isObject(item)) {
308
+ collectTarget(item, `${fullKey}.${index}`);
309
+ }
309
310
  });
310
- } else if (Object.prototype.toString.call(value) === '[object Object]') {
311
+ } else if (isObject(value)) {
311
312
  collectTarget(value, fullKey);
312
313
  }
313
314
 
@@ -319,6 +320,7 @@ export class Watcher extends EventEmitter {
319
320
  };
320
321
 
321
322
  Object.entries(config).forEach(([key, value]) => {
323
+ if (typeof value === 'undefined' || value === '') return;
322
324
  doCollect(key, value);
323
325
  });
324
326
  };