@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.
Files changed (139) hide show
  1. package/dist/style.css +106 -219
  2. package/dist/tmagic-editor.js +6253 -5042
  3. package/dist/tmagic-editor.js.map +1 -1
  4. package/dist/tmagic-editor.umd.cjs +6280 -5055
  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 +266 -0
  9. package/src/components/CodeParams.vue +60 -0
  10. package/src/components/ContentMenu.vue +97 -43
  11. package/src/components/Resizer.vue +8 -30
  12. package/src/components/SplitView.vue +3 -2
  13. package/src/editorProps.ts +30 -5
  14. package/src/fields/Code.vue +23 -19
  15. package/src/fields/CodeLink.vue +6 -7
  16. package/src/fields/CodeSelect.vue +12 -9
  17. package/src/fields/CodeSelectCol.vue +70 -81
  18. package/src/fields/DataSourceFieldSelect.vue +47 -0
  19. package/src/fields/DataSourceFields.vue +38 -22
  20. package/src/fields/DataSourceInput.vue +21 -58
  21. package/src/fields/DataSourceMethodSelect.vue +136 -0
  22. package/src/fields/DataSourceMethods.vue +104 -0
  23. package/src/fields/DataSourceSelect.vue +5 -12
  24. package/src/fields/EventSelect.vue +53 -19
  25. package/src/fields/KeyValue.vue +9 -11
  26. package/src/fields/UISelect.vue +54 -14
  27. package/src/hooks/index.ts +21 -0
  28. package/src/hooks/use-code-block-edit.ts +84 -0
  29. package/src/hooks/use-data-source-method.ts +100 -0
  30. package/src/hooks/use-getso.ts +35 -0
  31. package/src/{utils/stage.ts → hooks/use-stage.ts} +4 -7
  32. package/src/icons/CenterIcon.vue +13 -0
  33. package/src/icons/CodeIcon.vue +0 -2
  34. package/src/icons/FolderMinusIcon.vue +22 -0
  35. package/src/icons/PinIcon.vue +25 -0
  36. package/src/icons/PinnedIcon.vue +25 -0
  37. package/src/index.ts +14 -0
  38. package/src/initService.ts +69 -16
  39. package/src/layouts/CodeEditor.vue +35 -3
  40. package/src/layouts/Framework.vue +7 -3
  41. package/src/layouts/PropsPanel.vue +8 -3
  42. package/src/layouts/sidebar/ComponentListPanel.vue +4 -6
  43. package/src/layouts/sidebar/LayerMenu.vue +20 -21
  44. package/src/layouts/sidebar/LayerPanel.vue +12 -2
  45. package/src/layouts/sidebar/Sidebar.vue +22 -36
  46. package/src/layouts/sidebar/code-block/CodeBlockList.vue +81 -119
  47. package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +64 -0
  48. package/src/layouts/sidebar/data-source/DataSourceConfigPanel.vue +27 -47
  49. package/src/layouts/sidebar/data-source/DataSourceList.vue +145 -0
  50. package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +58 -85
  51. package/src/layouts/workspace/Workspace.vue +1 -1
  52. package/src/layouts/workspace/viewer/NodeListMenu.vue +159 -0
  53. package/src/layouts/workspace/viewer/NodeListMenuTitle.vue +68 -0
  54. package/src/layouts/workspace/{Stage.vue → viewer/Stage.vue} +5 -2
  55. package/src/layouts/workspace/{ViewerMenu.vue → viewer/ViewerMenu.vue} +10 -35
  56. package/src/services/codeBlock.ts +18 -71
  57. package/src/services/dataSource.ts +16 -1
  58. package/src/services/dep.ts +22 -20
  59. package/src/services/editor.ts +46 -18
  60. package/src/services/props.ts +2 -2
  61. package/src/theme/code-block.scss +5 -117
  62. package/src/theme/code-editor.scss +27 -2
  63. package/src/theme/content-menu.scss +26 -2
  64. package/src/theme/data-source-methods.scss +13 -0
  65. package/src/theme/data-source.scss +11 -0
  66. package/src/theme/event.scss +15 -12
  67. package/src/theme/framework.scss +0 -3
  68. package/src/theme/index.scss +8 -0
  69. package/src/theme/layout.scss +4 -0
  70. package/src/theme/sidebar.scss +18 -60
  71. package/src/theme/theme.scss +1 -0
  72. package/src/type.ts +49 -7
  73. package/src/utils/content-menu.ts +92 -0
  74. package/src/utils/data-source/formConfigs/base.ts +28 -30
  75. package/src/utils/data-source/formConfigs/http.ts +9 -0
  76. package/src/utils/data-source/index.ts +65 -2
  77. package/src/utils/dep.ts +33 -7
  78. package/src/utils/index.ts +1 -1
  79. package/src/utils/props.ts +308 -189
  80. package/src/utils/undo-redo.ts +1 -1
  81. package/types/Editor.vue.d.ts +30 -6
  82. package/types/components/CodeBlockEditor.vue.d.ts +25 -0
  83. package/types/components/CodeParams.vue.d.ts +26 -0
  84. package/types/components/ContentMenu.vue.d.ts +27 -8
  85. package/types/components/Resizer.vue.d.ts +1 -3
  86. package/types/components/ToolButton.vue.d.ts +3 -3
  87. package/types/editorProps.d.ts +19 -5
  88. package/types/fields/Code.vue.d.ts +24 -19
  89. package/types/fields/CodeLink.vue.d.ts +12 -21
  90. package/types/fields/CodeSelect.vue.d.ts +6 -17
  91. package/types/fields/CodeSelectCol.vue.d.ts +10 -14
  92. package/types/fields/DataSourceFieldSelect.vue.d.ts +29 -0
  93. package/types/fields/DataSourceFields.vue.d.ts +7 -18
  94. package/types/fields/DataSourceInput.vue.d.ts +10 -30
  95. package/types/fields/DataSourceMethodSelect.vue.d.ts +29 -0
  96. package/types/fields/DataSourceMethods.vue.d.ts +32 -0
  97. package/types/fields/DataSourceSelect.vue.d.ts +13 -29
  98. package/types/fields/EventSelect.vue.d.ts +2 -13
  99. package/types/fields/KeyValue.vue.d.ts +9 -24
  100. package/types/fields/UISelect.vue.d.ts +2 -11
  101. package/types/hooks/index.d.ts +3 -0
  102. package/types/{components/FunctionEditor.vue.d.ts → hooks/use-code-block-edit.d.ts} +36 -119
  103. package/types/hooks/use-data-source-method.d.ts +130 -0
  104. package/types/hooks/use-getso.d.ts +5 -0
  105. package/types/icons/CenterIcon.vue.d.ts +2 -0
  106. package/types/icons/FolderMinusIcon.vue.d.ts +2 -0
  107. package/types/icons/PinIcon.vue.d.ts +2 -0
  108. package/types/icons/PinnedIcon.vue.d.ts +2 -0
  109. package/types/index.d.ts +7 -0
  110. package/types/initService.d.ts +2 -2
  111. package/types/layouts/CodeEditor.vue.d.ts +7 -4
  112. package/types/layouts/PropsPanel.vue.d.ts +274 -2
  113. package/types/layouts/sidebar/Sidebar.vue.d.ts +0 -3
  114. package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +4 -9
  115. package/types/layouts/sidebar/code-block/{CodeBlockEditor.vue.d.ts → CodeBlockListPanel.vue.d.ts} +9 -5
  116. package/types/layouts/sidebar/data-source/DataSourceConfigPanel.vue.d.ts +3 -1
  117. package/types/layouts/sidebar/data-source/DataSourceList.vue.d.ts +14 -0
  118. package/types/layouts/sidebar/data-source/DataSourceListPanel.vue.d.ts +1 -11
  119. package/types/layouts/workspace/viewer/NodeListMenu.vue.d.ts +15 -0
  120. package/types/layouts/workspace/viewer/NodeListMenuTitle.vue.d.ts +15 -0
  121. package/types/layouts/workspace/{Stage.vue.d.ts → viewer/Stage.vue.d.ts} +1 -1
  122. package/types/layouts/workspace/{ViewerMenu.vue.d.ts → viewer/ViewerMenu.vue.d.ts} +1 -1
  123. package/types/services/codeBlock.d.ts +6 -37
  124. package/types/services/dataSource.d.ts +7 -1
  125. package/types/services/dep.d.ts +12 -21
  126. package/types/services/editor.d.ts +1 -1
  127. package/types/services/props.d.ts +10 -115
  128. package/types/type.d.ts +44 -7
  129. package/types/utils/content-menu.d.ts +7 -0
  130. package/types/utils/data-source/formConfigs/base.d.ts +1 -2
  131. package/types/utils/data-source/index.d.ts +5 -0
  132. package/types/utils/dep.d.ts +4 -2
  133. package/types/utils/index.d.ts +1 -1
  134. package/types/utils/props.d.ts +13 -102
  135. package/src/components/CodeDraftEditor.vue +0 -148
  136. package/src/components/FunctionEditor.vue +0 -197
  137. package/src/layouts/sidebar/code-block/CodeBlockEditor.vue +0 -100
  138. package/types/components/CodeDraftEditor.vue.d.ts +0 -61
  139. /package/types/{utils/stage.d.ts → hooks/use-stage.d.ts} +0 -0
@@ -16,7 +16,6 @@
16
16
  "
17
17
  style="width: 100%"
18
18
  @blur="blurHandler"
19
- @change="changeHandler"
20
19
  @input="inputHandler"
21
20
  @select="selectHandler"
22
21
  >
@@ -48,36 +47,34 @@
48
47
  import { computed, inject, nextTick, ref, watch } from 'vue';
49
48
  import { Coin } from '@element-plus/icons-vue';
50
49
 
51
- import { FieldSize, getConfig, TMagicAutocomplete, TMagicTag } from '@tmagic/design';
50
+ import { getConfig, TMagicAutocomplete, TMagicTag } from '@tmagic/design';
51
+ import type { FieldProps } from '@tmagic/form';
52
52
  import type { DataSchema, DataSourceSchema } from '@tmagic/schema';
53
53
 
54
54
  import Icon from '@editor/components/Icon.vue';
55
55
  import type { Services } from '@editor/type';
56
+ import { getDisplayField } from '@editor/utils/data-source';
56
57
 
57
58
  defineOptions({
58
59
  name: 'MEditorDataSourceInput',
59
60
  });
60
61
 
61
62
  const props = withDefaults(
62
- defineProps<{
63
- config: {
63
+ defineProps<
64
+ FieldProps<{
64
65
  type: 'data-source-input';
65
66
  name: string;
66
67
  text: string;
67
- };
68
- model: Record<string, any>;
69
- name: string;
70
- prop: string;
71
- disabled: boolean;
72
- lastValues?: Record<string, any>;
73
- size?: FieldSize;
74
- }>(),
68
+ }>
69
+ >(),
75
70
  {
76
71
  disabled: false,
77
72
  },
78
73
  );
79
74
 
80
- const emit = defineEmits<(e: 'change', value: string) => void>();
75
+ const emit = defineEmits<{
76
+ change: [value: string];
77
+ }>();
81
78
 
82
79
  const { dataSourceService } = inject<Services>('services') || {};
83
80
 
@@ -90,49 +87,7 @@ const input = computed<HTMLInputElement>(() => autocomplete.value?.inputRef?.inp
90
87
  const dataSources = computed(() => dataSourceService?.get('dataSources') || []);
91
88
 
92
89
  const setDisplayState = () => {
93
- displayState.value = [];
94
-
95
- const matches = state.value.matchAll(/\$\{([\s\S]+?)\}/g);
96
- let index = 0;
97
- for (const match of matches) {
98
- if (typeof match.index === 'undefined') break;
99
-
100
- displayState.value.push({
101
- type: 'text',
102
- value: state.value.substring(index, match.index),
103
- });
104
-
105
- let dsText = '';
106
- let ds: DataSourceSchema | undefined;
107
- let fields: DataSchema[] | undefined;
108
-
109
- match[1].split('.').forEach((item, index) => {
110
- if (index === 0) {
111
- ds = dataSources.value.find((ds) => ds.id === item);
112
- dsText += ds?.title || item;
113
- fields = ds?.fields;
114
- return;
115
- }
116
-
117
- const field = fields?.find((field) => field.name === item);
118
- fields = field?.fields;
119
- dsText += `.${field?.title || item}`;
120
- });
121
-
122
- displayState.value.push({
123
- type: 'var',
124
- value: dsText,
125
- });
126
-
127
- index = match.index + match[0].length;
128
- }
129
-
130
- if (index < state.value.length) {
131
- displayState.value.push({
132
- type: 'text',
133
- value: state.value.substring(index),
134
- });
135
- }
90
+ displayState.value = getDisplayField(dataSources.value, state.value);
136
91
  };
137
92
 
138
93
  watch(
@@ -155,6 +110,8 @@ const blurHandler = () => {
155
110
  isFocused.value = false;
156
111
 
157
112
  setDisplayState();
113
+
114
+ emit('change', state.value);
158
115
  };
159
116
 
160
117
  const changeHandler = (v: string) => {
@@ -246,17 +203,21 @@ const fieldQuerySearch = (
246
203
  let result: DataSchema[] = [];
247
204
 
248
205
  const dsKey = queryString.substring(leftAngleIndex + 1, dotIndex);
206
+
249
207
  // 可能是xx.xx.xx,存在链式调用
250
208
  const keys = dsKey.split('.');
209
+
251
210
  // 最前的是数据源id
252
- const ds = dataSources.value.find((ds) => ds.id === keys.shift());
211
+ const dsId = keys.shift();
212
+ const ds = dataSources.value.find((ds) => ds.id === dsId);
253
213
  if (!ds) {
214
+ cb([]);
254
215
  return;
255
216
  }
256
217
 
257
218
  let fields = ds.fields || [];
258
219
 
259
- // 后面这些事字段
220
+ // 后面这些是字段
260
221
  let key = keys.shift();
261
222
  while (key) {
262
223
  for (const field of fields) {
@@ -354,5 +315,7 @@ const selectHandler = async ({ value, type }: { value: string; type: 'dataSource
354
315
  newSelectionStart = dotIndex + suggestText.length + 1;
355
316
  }
356
317
  input.value?.setSelectionRange(newSelectionStart, newSelectionStart);
318
+
319
+ changeHandler(state.value);
357
320
  };
358
321
  </script>
@@ -0,0 +1,136 @@
1
+ <template>
2
+ <div class="m-fields-data-source-method-select">
3
+ <div class="data-source-method-select-container">
4
+ <m-form-container
5
+ class="select"
6
+ :config="cascaderConfig"
7
+ :model="model"
8
+ @change="onChangeHandler"
9
+ ></m-form-container>
10
+ <Icon v-if="model[name]" class="icon" :icon="!disabled ? Edit : View" @click="editCodeHandler"></Icon>
11
+ </div>
12
+
13
+ <CodeParams
14
+ v-if="paramsConfig.length"
15
+ name="params"
16
+ :model="model"
17
+ :size="size"
18
+ :disabled="disabled"
19
+ :params-config="paramsConfig"
20
+ @change="onChangeHandler"
21
+ ></CodeParams>
22
+
23
+ <CodeBlockEditor
24
+ ref="codeBlockEditor"
25
+ v-if="codeConfig"
26
+ :disabled="disabled"
27
+ :content="codeConfig"
28
+ @submit="submitCodeBlockHandler"
29
+ ></CodeBlockEditor>
30
+ </div>
31
+ </template>
32
+
33
+ <script lang="ts" setup name="">
34
+ import { computed, inject, ref } from 'vue';
35
+ import { Edit, View } from '@element-plus/icons-vue';
36
+
37
+ import { createValues, FieldProps } from '@tmagic/form';
38
+ import type { CodeBlockContent, Id } from '@tmagic/schema';
39
+
40
+ import CodeBlockEditor from '@editor/components/CodeBlockEditor.vue';
41
+ import CodeParams from '@editor/components/CodeParams.vue';
42
+ import Icon from '@editor/components/Icon.vue';
43
+ import { useDataSourceMethod } from '@editor/hooks/use-data-source-method';
44
+ import type { CodeParamStatement, DataSourceMethodSelectConfig, Services } from '@editor/type';
45
+
46
+ defineOptions({
47
+ name: 'MEditorDataSourceMethodSelect',
48
+ });
49
+
50
+ const services = inject<Services>('services');
51
+ const emit = defineEmits(['change']);
52
+
53
+ const props = withDefaults(defineProps<FieldProps<DataSourceMethodSelectConfig>>(), {
54
+ disabled: false,
55
+ });
56
+
57
+ const dataSources = computed(() => services?.dataSourceService.get('dataSources'));
58
+
59
+ const getParamItemsConfig = ([dataSourceId, medthodName]: [Id, string] = ['', '']): CodeParamStatement[] => {
60
+ if (!dataSourceId) return [];
61
+
62
+ const paramStatements = dataSources.value
63
+ ?.find((item) => item.id === dataSourceId)
64
+ ?.methods?.find((item) => item.name === medthodName)?.params;
65
+
66
+ if (!paramStatements) return [];
67
+
68
+ return paramStatements.map((paramState: CodeParamStatement) => ({
69
+ labelWidth: '100px',
70
+ text: paramState.name,
71
+ ...paramState,
72
+ }));
73
+ };
74
+
75
+ const paramsConfig = ref<CodeParamStatement[]>(getParamItemsConfig(props.model.dataSourceMethod));
76
+
77
+ const setParamsConfig = (dataSourceMethod: [Id, string], formState: any = {}) => {
78
+ // 通过下拉框选择的codeId变化后修正model的值,避免写入其他codeId的params
79
+ paramsConfig.value = dataSourceMethod ? getParamItemsConfig(dataSourceMethod) : [];
80
+
81
+ if (paramsConfig.value.length) {
82
+ props.model.params = createValues(formState, paramsConfig.value, {}, props.model.params);
83
+ } else {
84
+ props.model.params = {};
85
+ }
86
+ };
87
+
88
+ const cascaderConfig = {
89
+ type: 'cascader',
90
+ text: '数据源方法',
91
+ name: props.name,
92
+ labelWidth: '80px',
93
+ options: () =>
94
+ dataSources.value
95
+ ?.filter((ds) => ds.methods?.length)
96
+ ?.map((ds) => ({
97
+ label: ds.title || ds.id,
98
+ value: ds.id,
99
+ children: ds.methods?.map((method) => ({
100
+ label: method.name,
101
+ value: method.name,
102
+ })),
103
+ })) || [],
104
+ onChange: (formState: any, dataSourceMethod: [Id, string]) => {
105
+ setParamsConfig(dataSourceMethod, formState);
106
+
107
+ return dataSourceMethod;
108
+ },
109
+ };
110
+
111
+ /**
112
+ * 参数值修改更新
113
+ */
114
+ const onChangeHandler = (value: any) => {
115
+ props.model.params = value.params;
116
+ emit('change', props.model);
117
+ };
118
+
119
+ const { codeBlockEditor, codeConfig, editCode, submitCode } = useDataSourceMethod();
120
+
121
+ const editCodeHandler = () => {
122
+ const [id, name] = props.model[props.name];
123
+
124
+ const dataSource = services?.dataSourceService.getDataSourceById(id);
125
+
126
+ if (!dataSource) return;
127
+
128
+ editCode(dataSource, name);
129
+
130
+ setParamsConfig([id, name]);
131
+ };
132
+
133
+ const submitCodeBlockHandler = (value: CodeBlockContent) => {
134
+ submitCode(value);
135
+ };
136
+ </script>
@@ -0,0 +1,104 @@
1
+ <template>
2
+ <div class="m-editor-data-source-methods">
3
+ <MagicTable :data="model[name]" :columns="methodColumns"></MagicTable>
4
+
5
+ <div class="m-editor-data-source-methods-footer">
6
+ <TMagicButton size="small" type="primary" :disabled="disabled" plain @click="createCodeHandler"
7
+ >添加</TMagicButton
8
+ >
9
+ </div>
10
+
11
+ <CodeBlockEditor
12
+ v-if="codeConfig"
13
+ ref="codeBlockEditor"
14
+ :disabled="disabled"
15
+ :content="codeConfig"
16
+ :is-data-source="true"
17
+ :data-source-type="model.type"
18
+ @submit="submitCodeHandler"
19
+ ></CodeBlockEditor>
20
+ </div>
21
+ </template>
22
+
23
+ <script setup lang="ts">
24
+ import { TMagicButton } from '@tmagic/design';
25
+ import type { FieldProps } from '@tmagic/form';
26
+ import type { CodeBlockContent } from '@tmagic/schema';
27
+ import { MagicTable } from '@tmagic/table';
28
+
29
+ import CodeBlockEditor from '@editor/components/CodeBlockEditor.vue';
30
+ import { useDataSourceMethod } from '@editor/hooks/use-data-source-method';
31
+ import type { CodeParamStatement } from '@editor/type';
32
+
33
+ defineOptions({
34
+ name: 'MEditorDataSourceMethods',
35
+ });
36
+
37
+ const props = withDefaults(
38
+ defineProps<
39
+ FieldProps<{
40
+ type: 'data-source-methods';
41
+ }>
42
+ >(),
43
+ {
44
+ disabled: false,
45
+ },
46
+ );
47
+
48
+ const emit = defineEmits(['change']);
49
+
50
+ const { codeConfig, codeBlockEditor, createCode, editCode, deleteCode, submitCode } = useDataSourceMethod();
51
+
52
+ const methodColumns = [
53
+ {
54
+ label: '名称',
55
+ prop: 'name',
56
+ },
57
+ {
58
+ label: '描述',
59
+ prop: 'desc',
60
+ },
61
+ {
62
+ label: '执行时机',
63
+ prop: 'timing',
64
+ },
65
+ {
66
+ label: '参数',
67
+ prop: 'params',
68
+ formatter: (params: CodeParamStatement[]) => params.map((item) => item.name).join(', '),
69
+ },
70
+ {
71
+ label: '操作',
72
+ fixed: 'right',
73
+ actions: [
74
+ {
75
+ text: '编辑',
76
+ handler: (row: CodeBlockContent) => {
77
+ editCode(props.model, row.name);
78
+ emit('change', props.model[props.name]);
79
+ },
80
+ },
81
+ {
82
+ text: '删除',
83
+ buttonType: 'danger',
84
+ handler: (row: CodeBlockContent) => {
85
+ deleteCode(props.model, row.name);
86
+ emit('change', props.model[props.name]);
87
+ },
88
+ },
89
+ ],
90
+ },
91
+ ];
92
+
93
+ const createCodeHandler = () => {
94
+ createCode(props.model);
95
+
96
+ emit('change', props.model[props.name]);
97
+ };
98
+
99
+ const submitCodeHandler = (values: CodeBlockContent) => {
100
+ submitCode(values);
101
+
102
+ emit('change', props.model[props.name]);
103
+ };
104
+ </script>
@@ -14,8 +14,7 @@
14
14
  <script setup lang="ts">
15
15
  import { computed, inject } from 'vue';
16
16
 
17
- import { FieldSize } from '@tmagic/design';
18
- import { MSelect, SelectConfig } from '@tmagic/form';
17
+ import { FieldProps, MSelect, SelectConfig } from '@tmagic/form';
19
18
 
20
19
  import { Services } from '../type';
21
20
 
@@ -26,21 +25,15 @@ defineOptions({
26
25
  const emit = defineEmits(['change']);
27
26
 
28
27
  const props = withDefaults(
29
- defineProps<{
30
- config: {
28
+ defineProps<
29
+ FieldProps<{
31
30
  type: 'data-source-select';
32
31
  name: string;
33
32
  text: string;
34
33
  placeholder: string;
35
34
  dataSourceType?: string;
36
- };
37
- model: Record<string, any>;
38
- name: string;
39
- prop: string;
40
- disabled: boolean;
41
- lastValues?: Record<string, any>;
42
- size?: FieldSize;
43
- }>(),
35
+ }>
36
+ >(),
44
37
  {
45
38
  disabled: false,
46
39
  },
@@ -3,18 +3,23 @@
3
3
  <m-form-table
4
4
  v-if="isOldVersion"
5
5
  ref="eventForm"
6
- :size="props.size"
7
- :model="model"
8
6
  name="events"
7
+ :size="size"
8
+ :disabled="disabled"
9
+ :model="model"
9
10
  :config="tableConfig"
10
11
  @change="onChangeHandler"
11
12
  ></m-form-table>
12
13
 
13
14
  <div v-else class="fullWidth">
14
- <TMagicButton class="create-button" type="primary" size="small" @click="addEvent()">添加事件</TMagicButton>
15
+ <TMagicButton class="create-button" type="primary" :size="size" :disabled="disabled" @click="addEvent()"
16
+ >添加事件</TMagicButton
17
+ >
15
18
  <m-form-panel
16
19
  v-for="(cardItem, index) in model[name]"
17
20
  :key="index"
21
+ :disabled="disabled"
22
+ :size="size"
18
23
  :config="actionsConfig"
19
24
  :model="cardItem"
20
25
  @change="onChangeHandler"
@@ -24,9 +29,18 @@
24
29
  class="fullWidth"
25
30
  :config="eventNameConfig"
26
31
  :model="cardItem"
32
+ :disabled="disabled"
33
+ :size="size"
27
34
  @change="onChangeHandler"
28
35
  ></m-form-container>
29
- <TMagicButton style="color: #f56c6c" text :icon="Delete" @click="removeEvent(index)"></TMagicButton>
36
+ <TMagicButton
37
+ style="color: #f56c6c"
38
+ text
39
+ :icon="Delete"
40
+ :disabled="disabled"
41
+ :size="size"
42
+ @click="removeEvent(index)"
43
+ ></TMagicButton>
30
44
  </template>
31
45
  </m-form-panel>
32
46
  </div>
@@ -39,22 +53,16 @@ import { Delete } from '@element-plus/icons-vue';
39
53
  import { has } from 'lodash-es';
40
54
 
41
55
  import { TMagicButton } from '@tmagic/design';
42
- import { FormState } from '@tmagic/form';
56
+ import type { FieldProps, FormState } from '@tmagic/form';
43
57
  import { ActionType } from '@tmagic/schema';
44
58
 
45
- import type { EventSelectConfig, Services } from '@editor/type';
59
+ import type { CodeSelectColConfig, DataSourceMethodSelectConfig, EventSelectConfig, Services } from '@editor/type';
46
60
 
47
61
  defineOptions({
48
62
  name: 'MEditorEventSelect',
49
63
  });
50
64
 
51
- const props = defineProps<{
52
- config: EventSelectConfig;
53
- model: any;
54
- prop: string;
55
- name: string;
56
- size: 'small' | 'default' | 'large';
57
- }>();
65
+ const props = defineProps<FieldProps<EventSelectConfig>>();
58
66
 
59
67
  const emit = defineEmits(['change']);
60
68
 
@@ -81,7 +89,7 @@ const actionTypeConfig = computed(() => {
81
89
  const defaultActionTypeConfig = {
82
90
  name: 'actionType',
83
91
  text: '联动类型',
84
- labelWidth: '70px',
92
+ labelWidth: '80px',
85
93
  type: 'select',
86
94
  defaultValue: ActionType.COMP,
87
95
  options: () => [
@@ -93,8 +101,15 @@ const actionTypeConfig = computed(() => {
93
101
  {
94
102
  text: '代码',
95
103
  label: '代码',
104
+ disabled: !Object.keys(services?.codeBlockService.getCodeDsl() || {}).length,
96
105
  value: ActionType.CODE,
97
106
  },
107
+ {
108
+ text: '数据源',
109
+ label: '数据源',
110
+ disabled: !services?.dataSourceService.get('dataSources')?.filter((ds) => ds.methods?.length).length,
111
+ value: ActionType.DATA_SOURCE,
112
+ },
98
113
  ],
99
114
  };
100
115
  return { ...defaultActionTypeConfig, ...props.config.actionTypeConfig };
@@ -105,7 +120,7 @@ const targetCompConfig = computed(() => {
105
120
  const defaultTargetCompConfig = {
106
121
  name: 'to',
107
122
  text: '联动组件',
108
- labelWidth: '70px',
123
+ labelWidth: '80px',
109
124
  type: 'ui-select',
110
125
  display: (mForm: FormState, { model }: { model: Record<any, any> }) => model.actionType === ActionType.COMP,
111
126
  };
@@ -117,7 +132,7 @@ const compActionConfig = computed(() => {
117
132
  const defaultCompActionConfig = {
118
133
  name: 'method',
119
134
  text: '动作',
120
- labelWidth: '70px',
135
+ labelWidth: '80px',
121
136
  type: 'select',
122
137
  display: (mForm: FormState, { model }: { model: Record<any, any> }) => model.actionType === ActionType.COMP,
123
138
  options: (mForm: FormState, { model }: any) => {
@@ -135,14 +150,27 @@ const compActionConfig = computed(() => {
135
150
 
136
151
  // 代码联动配置
137
152
  const codeActionConfig = computed(() => {
138
- const defaultCodeActionConfig = {
153
+ const defaultCodeActionConfig: CodeSelectColConfig = {
139
154
  type: 'code-select-col',
140
155
  labelWidth: 0,
141
- display: (mForm: FormState, { model }: { model: Record<any, any> }) => model.actionType === ActionType.CODE,
156
+ name: 'codeId',
157
+ disabled: () => !services?.codeBlockService.getEditStatus(),
158
+ display: (mForm, { model }) => model.actionType === ActionType.CODE,
142
159
  };
143
160
  return { ...defaultCodeActionConfig, ...props.config.codeActionConfig };
144
161
  });
145
162
 
163
+ // 数据源联动配置
164
+ const dataSourceActionConfig = computed(() => {
165
+ const defaultDataSourceActionConfig: DataSourceMethodSelectConfig = {
166
+ type: 'data-source-method-select',
167
+ name: 'dataSourceMethod',
168
+ labelWidth: 0,
169
+ display: (mForm, { model }) => model.actionType === ActionType.DATA_SOURCE,
170
+ };
171
+ return { ...defaultDataSourceActionConfig, ...props.config.dataSourceActionConfig };
172
+ });
173
+
146
174
  // 兼容旧的数据格式
147
175
  const tableConfig = computed(() => ({
148
176
  type: 'table',
@@ -188,7 +216,13 @@ const actionsConfig = computed(() => ({
188
216
  name: 'actions',
189
217
  expandAll: true,
190
218
  enableToggleMode: false,
191
- items: [actionTypeConfig.value, targetCompConfig.value, compActionConfig.value, codeActionConfig.value],
219
+ items: [
220
+ actionTypeConfig.value,
221
+ targetCompConfig.value,
222
+ compActionConfig.value,
223
+ codeActionConfig.value,
224
+ dataSourceActionConfig.value,
225
+ ],
192
226
  },
193
227
  ],
194
228
  }));
@@ -21,6 +21,7 @@
21
21
  class="m-fileds-key-value-delete"
22
22
  type="danger"
23
23
  :size="size"
24
+ :disabled="disabled"
24
25
  circle
25
26
  plain
26
27
  :icon="Delete"
@@ -28,7 +29,9 @@
28
29
  ></TMagicButton>
29
30
  </div>
30
31
 
31
- <TMagicButton type="primary" :size="size" plain :icon="Plus" @click="addHandler">添加</TMagicButton>
32
+ <TMagicButton type="primary" :size="size" :disabled="disabled" plain :icon="Plus" @click="addHandler"
33
+ >添加</TMagicButton
34
+ >
32
35
  </div>
33
36
  </template>
34
37
 
@@ -37,25 +40,20 @@ import { ref, watchEffect } from 'vue';
37
40
  import { Delete, Plus } from '@element-plus/icons-vue';
38
41
 
39
42
  import { TMagicButton, TMagicInput } from '@tmagic/design';
43
+ import type { FieldProps } from '@tmagic/form';
40
44
 
41
45
  defineOptions({
42
46
  name: 'MEditorKeyValue',
43
47
  });
44
48
 
45
49
  const props = withDefaults(
46
- defineProps<{
47
- config: {
50
+ defineProps<
51
+ FieldProps<{
48
52
  type: 'key-value';
49
53
  name: string;
50
54
  text: string;
51
- };
52
- model: Record<string, any>;
53
- name: string;
54
- prop: string;
55
- disabled: boolean;
56
- lastValues?: Record<string, any>;
57
- size?: 'large' | 'default' | 'small';
58
- }>(),
55
+ }>
56
+ >(),
59
57
  {
60
58
  disabled: false,
61
59
  },