@tmagic/editor 1.3.0-alpha.13 → 1.3.0-alpha.14

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 (63) hide show
  1. package/dist/style.css +41 -113
  2. package/dist/tmagic-editor.js +1307 -1197
  3. package/dist/tmagic-editor.js.map +1 -1
  4. package/dist/tmagic-editor.umd.cjs +1318 -1204
  5. package/dist/tmagic-editor.umd.cjs.map +1 -1
  6. package/package.json +11 -11
  7. package/src/Editor.vue +0 -4
  8. package/src/components/CodeBlockEditor.vue +155 -0
  9. package/src/components/CodeParams.vue +59 -0
  10. package/src/fields/Code.vue +27 -19
  11. package/src/fields/CodeSelect.vue +7 -1
  12. package/src/fields/CodeSelectCol.vue +65 -74
  13. package/src/fields/DataSourceFields.vue +7 -9
  14. package/src/fields/DataSourceMethodSelect.vue +147 -0
  15. package/src/fields/DataSourceMethods.vue +103 -0
  16. package/src/fields/EventSelect.vue +33 -7
  17. package/src/icons/CodeIcon.vue +0 -2
  18. package/src/index.ts +8 -0
  19. package/src/layouts/CodeEditor.vue +32 -1
  20. package/src/layouts/Framework.vue +7 -3
  21. package/src/layouts/sidebar/Sidebar.vue +2 -10
  22. package/src/layouts/sidebar/code-block/CodeBlockList.vue +73 -124
  23. package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +64 -0
  24. package/src/layouts/sidebar/data-source/DataSourceConfigPanel.vue +23 -33
  25. package/src/layouts/sidebar/data-source/DataSourceList.vue +111 -0
  26. package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +13 -81
  27. package/src/services/codeBlock.ts +17 -70
  28. package/src/services/dataSource.ts +2 -0
  29. package/src/theme/code-block.scss +0 -122
  30. package/src/theme/code-editor.scss +27 -2
  31. package/src/theme/data-source-methods.scss +13 -0
  32. package/src/theme/event.scss +15 -12
  33. package/src/theme/theme.scss +1 -0
  34. package/src/type.ts +21 -6
  35. package/src/utils/data-source/index.ts +11 -0
  36. package/src/utils/use-code-block-edit.ts +84 -0
  37. package/src/utils/use-data-source-method.ts +101 -0
  38. package/types/components/CodeBlockEditor.vue.d.ts +21 -0
  39. package/types/components/CodeParams.vue.d.ts +26 -0
  40. package/types/components/ContentMenu.vue.d.ts +2 -2
  41. package/types/fields/Code.vue.d.ts +26 -6
  42. package/types/fields/CodeSelectCol.vue.d.ts +16 -5
  43. package/types/fields/DataSourceFields.vue.d.ts +2 -0
  44. package/types/fields/DataSourceMethodSelect.vue.d.ts +44 -0
  45. package/types/fields/DataSourceMethods.vue.d.ts +45 -0
  46. package/types/index.d.ts +4 -0
  47. package/types/layouts/CodeEditor.vue.d.ts +2 -0
  48. package/types/layouts/PropsPanel.vue.d.ts +8 -8
  49. package/types/layouts/sidebar/Sidebar.vue.d.ts +0 -3
  50. package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +4 -9
  51. package/types/layouts/sidebar/code-block/{CodeBlockEditor.vue.d.ts → CodeBlockListPanel.vue.d.ts} +5 -6
  52. package/types/layouts/sidebar/data-source/DataSourceConfigPanel.vue.d.ts +3 -1
  53. package/types/layouts/sidebar/data-source/DataSourceList.vue.d.ts +14 -0
  54. package/types/layouts/sidebar/data-source/DataSourceListPanel.vue.d.ts +1 -11
  55. package/types/services/codeBlock.d.ts +5 -36
  56. package/types/services/dataSource.d.ts +1 -0
  57. package/types/type.d.ts +19 -6
  58. package/types/{components/FunctionEditor.vue.d.ts → utils/use-code-block-edit.d.ts} +26 -123
  59. package/types/utils/use-data-source-method.d.ts +116 -0
  60. package/src/components/CodeDraftEditor.vue +0 -148
  61. package/src/components/FunctionEditor.vue +0 -197
  62. package/src/layouts/sidebar/code-block/CodeBlockEditor.vue +0 -100
  63. package/types/components/CodeDraftEditor.vue.d.ts +0 -61
@@ -2,46 +2,15 @@
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
+ <TMagicButton v-if="editable" type="primary" size="small" @click="addHandler">新增</TMagicButton>
6
6
  </div>
7
7
 
8
8
  <!-- 数据源列表 -->
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>
9
+ <DataSourceList @edit="editHandler" @remove="removeHandler"></DataSourceList>
42
10
 
43
11
  <DataSourceConfigPanel
44
12
  ref="editDialog"
13
+ :disabled="!editable"
45
14
  :values="dataSourceValues"
46
15
  :title="typeof dataSourceValues.id !== 'undefined' ? `编辑${dataSourceValues.title}` : '新增'"
47
16
  @submit="submitDataSourceHandler"
@@ -51,42 +20,28 @@
51
20
 
52
21
  <script setup lang="ts" name="MEditorDataSourceListPanel">
53
22
  import { computed, inject, ref } from 'vue';
54
- import { Aim, Close, Coin, Edit } from '@element-plus/icons-vue';
55
23
 
56
- import { TMagicButton, tMagicMessageBox, TMagicScrollbar, TMagicTooltip, TMagicTree } from '@tmagic/design';
57
- import { DataSourceSchema, Id } from '@tmagic/schema';
24
+ import { TMagicButton, TMagicScrollbar } from '@tmagic/design';
25
+ import type { DataSourceSchema } from '@tmagic/schema';
58
26
 
59
- import Icon from '@editor/components/Icon.vue';
60
27
  import SearchInput from '@editor/components/SearchInput.vue';
61
28
  import type { Services } from '@editor/type';
62
29
 
63
30
  import DataSourceConfigPanel from './DataSourceConfigPanel.vue';
31
+ import DataSourceList from './DataSourceList.vue';
64
32
 
65
33
  defineOptions({
66
34
  name: 'MEditorDataSourceListPanel',
67
35
  });
68
36
 
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
- );
37
+ const { dataSourceService } = inject<Services>('services') || {};
85
38
 
86
39
  const editDialog = ref<InstanceType<typeof DataSourceConfigPanel>>();
87
40
 
88
41
  const dataSourceValues = ref<Record<string, any>>({});
89
42
 
43
+ const editable = computed(() => dataSourceService?.get('editable') ?? true);
44
+
90
45
  const addHandler = () => {
91
46
  if (!editDialog.value) return;
92
47
 
@@ -96,7 +51,7 @@ const addHandler = () => {
96
51
  };
97
52
 
98
53
  const editHandler = (id: string) => {
99
- if (!editDialog.value || !services) return;
54
+ if (!editDialog.value) return;
100
55
 
101
56
  dataSourceValues.value = {
102
57
  ...dataSourceService?.getDataSourceById(id),
@@ -105,19 +60,11 @@ const editHandler = (id: string) => {
105
60
  editDialog.value.show();
106
61
  };
107
62
 
108
- const removeHandler = async (id: string) => {
109
- await tMagicMessageBox.confirm('确定删除?', '提示', {
110
- confirmButtonText: '确定',
111
- cancelButtonText: '取消',
112
- type: 'warning',
113
- });
114
-
63
+ const removeHandler = (id: string) => {
115
64
  dataSourceService?.remove(id);
116
65
  };
117
66
 
118
67
  const submitDataSourceHandler = (value: DataSourceSchema) => {
119
- if (!services) return;
120
-
121
68
  if (value.id) {
122
69
  dataSourceService?.update(value);
123
70
  } else {
@@ -127,24 +74,9 @@ const submitDataSourceHandler = (value: DataSourceSchema) => {
127
74
  editDialog.value?.hide();
128
75
  };
129
76
 
130
- const tree = ref<InstanceType<typeof TMagicTree>>();
77
+ const dataSourceList = ref<InstanceType<typeof DataSourceList>>();
131
78
 
132
79
  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
- }
80
+ dataSourceList.value?.filter(val);
149
81
  };
150
82
  </script>
@@ -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
  /**
@@ -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 = [];
@@ -11,6 +11,7 @@ import BaseService from './BaseService';
11
11
 
12
12
  interface State {
13
13
  dataSources: DataSourceSchema[];
14
+ editable: boolean;
14
15
  configs: Record<string, FormConfig>;
15
16
  }
16
17
 
@@ -18,6 +19,7 @@ type StateKey = keyof State;
18
19
  class DataSource extends BaseService {
19
20
  private state = reactive<State>({
20
21
  dataSources: [],
22
+ editable: true,
21
23
  configs: {},
22
24
  });
23
25
 
@@ -24,125 +24,3 @@
24
24
  display: none;
25
25
  }
26
26
  }
27
-
28
- .el-dialog.is-fullscreen.code-editor-dialog {
29
- overflow: hidden;
30
- }
31
-
32
- .code-editor-dialog {
33
- .tmagic-design-card {
34
- .t-card__header {
35
- display: block;
36
- }
37
- }
38
-
39
- .el-dialog__body,
40
- .t-dialog__body {
41
- height: 90%;
42
- padding-top: 10px;
43
- }
44
- .tmagic-design-card {
45
- height: 100%;
46
- background: #fff;
47
- .el-card__body,
48
- .t-card__body {
49
- height: 100%;
50
- background: #fff;
51
- }
52
- }
53
-
54
- .code-editor-layout {
55
- height: 100%;
56
- border: 1px solid #e4e7ed;
57
-
58
- .side-tree {
59
- height: 100%;
60
- overflow: auto;
61
- .el-tree-node__label {
62
- width: 100%;
63
- }
64
-
65
- .list-container {
66
- width: 100%;
67
- overflow: hidden;
68
- margin-left: -10px;
69
- .list-item {
70
- width: 100%;
71
- margin: 10px 0;
72
- line-height: 30px;
73
- .code-name {
74
- width: 100%;
75
- font-size: 14px;
76
- overflow: hidden;
77
- white-space: nowrap;
78
- text-overflow: ellipsis;
79
- }
80
- }
81
- }
82
- }
83
- }
84
-
85
- .code-name-wrapper {
86
- display: flex;
87
- align-items: center;
88
- font-size: 16px;
89
- margin-bottom: 10px;
90
- .code-name-label {
91
- margin-right: 10px;
92
- }
93
- .code-name-input {
94
- width: 300px;
95
- }
96
- }
97
-
98
- .m-editor-code-block-editor-panel-list-mode {
99
- height: 100%;
100
- z-index: 10;
101
- background: #fff;
102
- .el-card {
103
- border: 0;
104
- }
105
- }
106
-
107
- .m-editor-code-block-editor-panel {
108
- position: absolute;
109
- top: 0;
110
- left: 4px;
111
- width: calc(100% - 9px);
112
- height: 100%;
113
- z-index: 10;
114
- background: #fff;
115
- .el-card {
116
- border: 0;
117
- }
118
- }
119
-
120
- .m-editor-wrapper {
121
- height: 100%;
122
- &.fullScreen {
123
- height: 100%;
124
- width: 100%;
125
- position: fixed;
126
- top: 0;
127
- left: 0;
128
- z-index: 100;
129
- }
130
- .m-editor-container {
131
- height: calc(100% - 45px);
132
- }
133
- .m-editor-content-bottom {
134
- height: 45px;
135
- width: 100%;
136
- display: flex;
137
- justify-content: end;
138
- background: #fff;
139
- position: absolute;
140
- right: 20px;
141
- bottom: 0;
142
- > button {
143
- height: 30px;
144
- margin-top: 5px;
145
- }
146
- }
147
- }
148
- }
@@ -1,7 +1,32 @@
1
1
  .magic-code-editor {
2
2
  width: 100%;
3
+ }
4
+
5
+ .magic-code-editor-wrapper {
6
+ width: 100%;
7
+ height: 100%;
8
+ position: relative;
9
+
10
+ &.full-screen {
11
+ position: fixed;
12
+ z-index: 10000;
13
+ top: 0;
14
+ left: 0;
15
+ }
16
+
17
+ .magic-code-editor-content {
18
+ width: 100%;
19
+ height: 100%;
20
+
21
+ .margin {
22
+ margin: 0;
23
+ }
24
+ }
3
25
 
4
- .margin {
5
- margin: 0;
26
+ .magic-code-editor-full-screen-icon {
27
+ position: absolute;
28
+ top: 5px;
29
+ right: 0;
30
+ z-index: 1;
6
31
  }
7
32
  }
@@ -0,0 +1,13 @@
1
+ .m-editor-data-source-methods {
2
+ width: 100%;
3
+
4
+ .tmagic-design-table {
5
+ width: 100%;
6
+ }
7
+
8
+ .m-editor-data-source-methods-footer {
9
+ display: flex;
10
+ justify-content: flex-end;
11
+ margin-top: 15px;
12
+ }
13
+ }
@@ -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
- .code-select-container {
25
- display: flex;
26
- align-items: center;
27
- .select {
28
- flex: 10 0 100px;
29
- }
30
- .icon {
31
- flex: 1 0 20px;
32
- cursor: pointer;
33
- margin-right: 5px;
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
  }
@@ -19,5 +19,6 @@
19
19
  @import "./dep-list.scss";
20
20
  @import "./data-source.scss";
21
21
  @import "./data-source-fields.scss";
22
+ @import "./data-source-methods.scss";
22
23
  @import "./data-source-input.scss";
23
24
  @import "./key-value.scss";
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) => MApp;
48
+ parseDSL: <T = any>(dsl: string) => T;
49
49
  [key: string]: any;
50
50
  }
51
51
 
@@ -334,18 +334,15 @@ export interface ScrollViewerEvent {
334
334
  }
335
335
 
336
336
  export type CodeState = {
337
- /** 是否展示代码块编辑区 */
338
- isShowCodeEditor: boolean;
339
337
  /** 代码块DSL数据源 */
340
338
  codeDsl: CodeBlockDSL | null;
341
- /** 当前选中的代码块id */
342
- id: Id;
343
339
  /** 代码块是否可编辑 */
344
340
  editable: boolean;
345
341
  /** list模式下左侧展示的代码列表 */
346
342
  combineIds: string[];
347
343
  /** 为业务逻辑预留的不可删除的代码块列表,由业务逻辑维护(如代码块上线后不可删除) */
348
344
  undeletableList: Id[];
345
+ paramsColConfig?: ColumnConfig;
349
346
  };
350
347
 
351
348
  export type HookData = {
@@ -429,6 +426,8 @@ export interface EventSelectConfig {
429
426
  compActionConfig?: FormItem;
430
427
  /** 联动代码配置 */
431
428
  codeActionConfig?: FormItem;
429
+ /** 联动数据源配置 */
430
+ dataSourceActionConfig?: FormItem;
432
431
  }
433
432
 
434
433
  export enum KeyBindingCommand {
@@ -485,3 +484,19 @@ export interface KeyBindingCacheItem {
485
484
  eventType: 'keyup' | 'keydown';
486
485
  binded: boolean;
487
486
  }
487
+
488
+ export interface CodeSelectColConfig {
489
+ type: 'code-select-col';
490
+ name: string;
491
+ labelWidth?: number | string;
492
+ disabled?: boolean | FilterFunction;
493
+ display?: boolean | FilterFunction;
494
+ }
495
+
496
+ export interface DataSourceMethodSelectConfig {
497
+ type: 'data-source-method-select';
498
+ name: string;
499
+ labelWidth?: number | string;
500
+ disabled?: boolean | FilterFunction;
501
+ display?: boolean | FilterFunction;
502
+ }
@@ -17,6 +17,17 @@ const fillConfig = (config: FormConfig): FormConfig => [
17
17
  },
18
18
  ],
19
19
  },
20
+ {
21
+ type: 'panel',
22
+ title: '方法定义',
23
+ items: [
24
+ {
25
+ name: 'methods',
26
+ type: 'data-source-methods',
27
+ defaultValue: [],
28
+ },
29
+ ],
30
+ },
20
31
  ];
21
32
 
22
33
  export const getFormConfig = (type: string, configs: Record<string, FormConfig>): FormConfig => {
@@ -0,0 +1,84 @@
1
+ import { nextTick, ref } from 'vue';
2
+ import { cloneDeep } from 'lodash-es';
3
+
4
+ import { tMagicMessage } from '@tmagic/design';
5
+ import type { CodeBlockContent } from '@tmagic/schema';
6
+
7
+ import CodeBlockEditor from '@editor/components/CodeBlockEditor.vue';
8
+ import type { CodeBlockService } from '@editor/services/codeBlock';
9
+
10
+ export const useCodeBlockEdit = (codeBlockService?: CodeBlockService) => {
11
+ const codeConfig = ref<CodeBlockContent>();
12
+ const codeId = ref<string>();
13
+ const codeBlockEditor = ref<InstanceType<typeof CodeBlockEditor>>();
14
+
15
+ // 新增代码块
16
+ const createCodeBlock = async () => {
17
+ if (!codeBlockService) {
18
+ tMagicMessage.error('新增代码块失败');
19
+ return;
20
+ }
21
+
22
+ codeConfig.value = {
23
+ name: '代码块',
24
+ content: `({app, params}) => {\n // place your code here\n}`,
25
+ params: [],
26
+ };
27
+
28
+ codeId.value = await codeBlockService.getUniqueId();
29
+
30
+ await nextTick();
31
+
32
+ codeBlockEditor.value?.show();
33
+ };
34
+
35
+ // 编辑代码块
36
+ const editCode = async (id: string) => {
37
+ const codeBlock = await codeBlockService?.getCodeContentById(id);
38
+
39
+ if (!codeBlock) {
40
+ tMagicMessage.error('获取代码块内容失败');
41
+ return;
42
+ }
43
+
44
+ let codeContent = codeBlock.content;
45
+
46
+ if (typeof codeContent !== 'string') {
47
+ codeContent = codeContent.toString();
48
+ }
49
+
50
+ codeConfig.value = {
51
+ ...cloneDeep(codeBlock),
52
+ content: codeContent,
53
+ };
54
+ codeId.value = id;
55
+
56
+ await nextTick();
57
+
58
+ codeBlockEditor.value?.show();
59
+ };
60
+
61
+ // 删除代码块
62
+ const deleteCode = async (key: string) => {
63
+ codeBlockService?.deleteCodeDslByIds([key]);
64
+ };
65
+
66
+ const submitCodeBlockHandler = async (values: CodeBlockContent) => {
67
+ if (!codeId.value) return;
68
+
69
+ await codeBlockService?.setCodeDslById(codeId.value, values);
70
+
71
+ codeBlockEditor.value?.hide();
72
+ };
73
+
74
+ return {
75
+ codeId,
76
+ codeConfig,
77
+ codeBlockEditor,
78
+
79
+ createCodeBlock,
80
+ editCode,
81
+ deleteCode,
82
+ submitCodeBlockHandler,
83
+ };
84
+ };