@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
@@ -22,6 +22,7 @@
22
22
 
23
23
  <script lang="ts" setup>
24
24
  import { computed, onMounted, onUnmounted, ref } from 'vue';
25
+ import { OnDrag } from 'gesto';
25
26
 
26
27
  import Resizer from './Resizer.vue';
27
28
 
@@ -111,7 +112,7 @@ onUnmounted(() => {
111
112
 
112
113
  const center = ref(0);
113
114
 
114
- const changeLeft = (deltaX: number) => {
115
+ const changeLeft = ({ deltaX }: OnDrag) => {
115
116
  if (typeof props.left === 'undefined') return;
116
117
  let left = Math.max(props.left + deltaX, props.minLeft) || 0;
117
118
  emit('update:left', left);
@@ -131,7 +132,7 @@ const changeLeft = (deltaX: number) => {
131
132
  });
132
133
  };
133
134
 
134
- const changeRight = (deltaX: number) => {
135
+ const changeRight = ({ deltaX }: OnDrag) => {
135
136
  if (typeof props.right === 'undefined') return;
136
137
  let right = Math.max(props.right - deltaX, props.minRight) || 0;
137
138
  emit('update:right', right);
@@ -1,8 +1,8 @@
1
1
  import type { PropType } from 'vue';
2
2
 
3
3
  import type { EventOption } from '@tmagic/core';
4
- import type { FormConfig } from '@tmagic/form';
5
- import type { MApp, MNode } from '@tmagic/schema';
4
+ import type { FormConfig, FormState } from '@tmagic/form';
5
+ import type { DataSourceSchema, MApp, MNode } from '@tmagic/schema';
6
6
  import StageCore, {
7
7
  CONTAINER_HIGHLIGHT_CLASS_NAME,
8
8
  ContainerHighlightType,
@@ -11,7 +11,15 @@ import StageCore, {
11
11
  UpdateDragEl,
12
12
  } from '@tmagic/stage';
13
13
 
14
- import type { ComponentGroup, MenuBarData, MenuButton, MenuComponent, SideBarData, StageRect } from './type';
14
+ import type {
15
+ ComponentGroup,
16
+ DatasourceTypeOption,
17
+ MenuBarData,
18
+ MenuButton,
19
+ MenuComponent,
20
+ SideBarData,
21
+ StageRect,
22
+ } from './type';
15
23
 
16
24
  export default {
17
25
  /** 页面初始值 */
@@ -27,6 +35,12 @@ export default {
27
35
  default: () => [],
28
36
  },
29
37
 
38
+ /** 左侧面板中的组件列表 */
39
+ datasourceList: {
40
+ type: Array as PropType<DatasourceTypeOption[]>,
41
+ default: () => [],
42
+ },
43
+
30
44
  /** 左侧面板配置 */
31
45
  sidebar: {
32
46
  type: Object as PropType<SideBarData>,
@@ -69,7 +83,7 @@ export default {
69
83
 
70
84
  /** 添加组件时的默认值 */
71
85
  propsValues: {
72
- type: Object as PropType<Record<string, MNode>>,
86
+ type: Object as PropType<Record<string, Partial<MNode>>>,
73
87
  default: () => ({}),
74
88
  },
75
89
 
@@ -79,7 +93,14 @@ export default {
79
93
  default: () => ({}),
80
94
  },
81
95
 
82
- dataScourceConfigs: {
96
+ /** 添加数据源时的默认值 */
97
+ datasourceValues: {
98
+ type: Object as PropType<Record<string, Partial<DataSourceSchema>>>,
99
+ default: () => ({}),
100
+ },
101
+
102
+ /** 数据源的属性配置表单的dsl */
103
+ datasourceConfigs: {
83
104
  type: Object as PropType<Record<string, FormConfig>>,
84
105
  default: () => ({}),
85
106
  },
@@ -137,4 +158,8 @@ export default {
137
158
  disabledDragStart: {
138
159
  type: Boolean,
139
160
  },
161
+
162
+ extendFormState: {
163
+ type: Function as PropType<(state: FormState) => Record<string, any> | Promise<Record<string, any>>>,
164
+ },
140
165
  };
@@ -1,15 +1,20 @@
1
1
  <template>
2
- <magic-code-editor
3
- :style="`height: ${height}`"
2
+ <MagicCodeEditor
3
+ :height="config.height"
4
4
  :init-values="model[name]"
5
- :language="language"
6
- :options="config.options"
5
+ :language="config.language"
6
+ :options="{
7
+ ...config.options,
8
+ readOnly: disabled,
9
+ }"
7
10
  @save="save"
8
- ></magic-code-editor>
11
+ ></MagicCodeEditor>
9
12
  </template>
10
13
 
11
14
  <script lang="ts" setup>
12
- import { computed } from 'vue';
15
+ import type { FieldProps } from '@tmagic/form';
16
+
17
+ import MagicCodeEditor from '@editor/layouts/CodeEditor.vue';
13
18
 
14
19
  defineOptions({
15
20
  name: 'MEditorCode',
@@ -17,19 +22,18 @@ defineOptions({
17
22
 
18
23
  const emit = defineEmits(['change']);
19
24
 
20
- const props = defineProps<{
21
- model: any;
22
- name: string;
23
- config: {
24
- language?: string;
25
- options?: Object;
26
- height?: string;
27
- };
28
- prop: string;
29
- }>();
30
-
31
- const language = computed(() => props.config.language || 'javascript');
32
- const height = computed(() => props.config.height || `${document.body.clientHeight - 168}px`);
25
+ const props = withDefaults(
26
+ defineProps<
27
+ FieldProps<{
28
+ language?: string;
29
+ options?: Object;
30
+ height?: string;
31
+ }>
32
+ >(),
33
+ {
34
+ disabled: false,
35
+ },
36
+ );
33
37
 
34
38
  const save = (v: string) => {
35
39
  props.model[props.name] = v;
@@ -6,24 +6,23 @@
6
6
  import { computed, reactive, watch } from 'vue';
7
7
  import serialize from 'serialize-javascript';
8
8
 
9
+ import type { FieldProps } from '@tmagic/form';
10
+
9
11
  import { getConfig } from '@editor/utils/config';
10
12
 
11
13
  defineOptions({
12
14
  name: 'MEditorCodeLink',
13
15
  });
14
16
 
15
- const props = defineProps<{
16
- config: {
17
+ const props = defineProps<
18
+ FieldProps<{
17
19
  type: 'code-link';
18
20
  name: string;
19
21
  text?: string;
20
22
  formTitle?: string;
21
23
  codeOptions?: Object;
22
- };
23
- model: any;
24
- name: string;
25
- prop: string;
26
- }>();
24
+ }>
25
+ >();
27
26
 
28
27
  const emit = defineEmits(['change']);
29
28
 
@@ -7,28 +7,29 @@
7
7
  </template>
8
8
 
9
9
  <script lang="ts" setup>
10
- import { computed, watch } from 'vue';
10
+ import { computed, inject, watch } from 'vue';
11
11
  import { isEmpty } from 'lodash-es';
12
12
 
13
13
  import { TMagicCard } from '@tmagic/design';
14
+ import type { FieldProps } from '@tmagic/form';
14
15
  import { HookType } from '@tmagic/schema';
15
16
 
17
+ import type { Services } from '@editor/type';
18
+
16
19
  defineOptions({
17
20
  name: 'MEditorCodeSelect',
18
21
  });
19
22
 
20
23
  const emit = defineEmits(['change']);
21
24
 
25
+ const services = inject<Services>('services');
26
+
22
27
  const props = withDefaults(
23
- defineProps<{
24
- config: {
28
+ defineProps<
29
+ FieldProps<{
25
30
  className?: string;
26
- };
27
- model: any;
28
- prop: string;
29
- name: string;
30
- size: 'small' | 'default' | 'large';
31
- }>(),
31
+ }>
32
+ >(),
32
33
  {},
33
34
  );
34
35
 
@@ -41,7 +42,9 @@ const codeConfig = computed(() => ({
41
42
  items: [
42
43
  {
43
44
  type: 'code-select-col',
45
+ name: 'codeId',
44
46
  labelWidth: 0,
47
+ disabled: () => !services?.codeBlockService.getEditStatus(),
45
48
  },
46
49
  ],
47
50
  }));
@@ -9,10 +9,26 @@
9
9
  @change="onParamsChangeHandler"
10
10
  ></m-form-container>
11
11
  <!-- 查看/编辑按钮 -->
12
- <Icon class="icon" :icon="editable ? Edit : View" @click="editCode"></Icon>
12
+ <Icon v-if="model[name]" class="icon" :icon="!disabled ? Edit : View" @click="editCode(model[name])"></Icon>
13
13
  </div>
14
+
14
15
  <!-- 参数填写框 -->
15
- <m-form-container :config="codeParamsConfig" :model="model" @change="onParamsChangeHandler"></m-form-container>
16
+ <CodeParams
17
+ v-if="paramsConfig.length"
18
+ name="params"
19
+ :model="model"
20
+ :size="size"
21
+ :params-config="paramsConfig"
22
+ @change="onParamsChangeHandler"
23
+ ></CodeParams>
24
+
25
+ <CodeBlockEditor
26
+ ref="codeBlockEditor"
27
+ v-if="codeConfig"
28
+ :disabled="disabled"
29
+ :content="codeConfig"
30
+ @submit="submitCodeBlockHandler"
31
+ ></CodeBlockEditor>
16
32
  </div>
17
33
  </template>
18
34
 
@@ -21,45 +37,61 @@ import { computed, inject, ref, watch } from 'vue';
21
37
  import { Edit, View } from '@element-plus/icons-vue';
22
38
  import { isEmpty, map } from 'lodash-es';
23
39
 
24
- import { createValues, FieldsetConfig, FormState } from '@tmagic/form';
25
- import { Id } from '@tmagic/schema';
40
+ import { createValues, FieldProps } from '@tmagic/form';
41
+ import type { Id } from '@tmagic/schema';
26
42
 
43
+ import CodeBlockEditor from '@editor/components/CodeBlockEditor.vue';
44
+ import CodeParams from '@editor/components/CodeParams.vue';
27
45
  import Icon from '@editor/components/Icon.vue';
28
- import type { CodeParamStatement, Services } from '@editor/type';
46
+ import { useCodeBlockEdit } from '@editor/hooks/use-code-block-edit';
47
+ import type { CodeParamStatement, CodeSelectColConfig, Services } from '@editor/type';
29
48
 
30
49
  defineOptions({
31
50
  name: 'MEditorCodeSelectCol',
32
51
  });
33
52
 
34
53
  const services = inject<Services>('services');
35
- const mForm = inject<FormState>('mForm');
36
54
  const emit = defineEmits(['change']);
37
55
 
38
- const props = withDefaults(
39
- defineProps<{
40
- config: any;
41
- model: any;
42
- prop: string;
43
- name: string;
44
- size: 'small' | 'default' | 'large';
45
- }>(),
46
- {},
47
- );
48
- const codeDsl = computed(() => services?.codeBlockService.getCodeDsl());
49
- const editable = computed(() => services?.codeBlockService.getEditStatus());
50
- const codeParamsConfig = ref<FieldsetConfig>({
51
- type: 'fieldset',
52
- items: [],
53
- legend: '参数',
54
- labelWidth: '70px',
55
- name: 'params',
56
- display: false,
56
+ const props = withDefaults(defineProps<FieldProps<CodeSelectColConfig>>(), {
57
+ disabled: false,
57
58
  });
59
+
60
+ /**
61
+ * 根据代码块id获取代码块参数配置
62
+ * @param codeId 代码块ID
63
+ */
64
+ const getParamItemsConfig = (codeId?: Id): CodeParamStatement[] => {
65
+ if (!codeDsl.value || !codeId) return [];
66
+
67
+ const paramStatements = codeDsl.value[codeId]?.params;
68
+
69
+ if (isEmpty(paramStatements)) return [];
70
+
71
+ return paramStatements.map((paramState: CodeParamStatement) => ({
72
+ labelWidth: '100px',
73
+ text: paramState.name,
74
+ ...paramState,
75
+ }));
76
+ };
77
+
78
+ const codeDsl = computed(() => services?.codeBlockService.getCodeDsl());
79
+ const paramsConfig = ref<CodeParamStatement[]>(getParamItemsConfig(props.model[props.name]));
80
+
81
+ watch(
82
+ () => props.model[props.name],
83
+ (v, preV) => {
84
+ if (v !== preV) {
85
+ paramsConfig.value = getParamItemsConfig(v);
86
+ }
87
+ },
88
+ );
89
+
58
90
  const selectConfig = {
59
91
  type: 'select',
60
92
  text: '代码块',
61
- name: 'codeId',
62
- labelWidth: '70px',
93
+ name: props.name,
94
+ labelWidth: '80px',
63
95
  options: () => {
64
96
  if (codeDsl.value) {
65
97
  return map(codeDsl.value, (value, key) => ({
@@ -72,68 +104,25 @@ const selectConfig = {
72
104
  },
73
105
  onChange: (formState: any, codeId: Id, { model }: any) => {
74
106
  // 通过下拉框选择的codeId变化后修正model的值,避免写入其他codeId的params
75
- model.params = {};
76
- },
77
- };
107
+ paramsConfig.value = getParamItemsConfig(codeId);
78
108
 
79
- /**
80
- * 根据代码块id获取代码块参数配置
81
- * @param codeId 代码块ID
82
- */
83
- const getParamItemsConfig = (codeId: Id): CodeParamStatement[] => {
84
- if (!codeDsl.value) return [];
85
- const paramStatements = codeDsl.value[codeId]?.params;
86
- if (isEmpty(paramStatements)) return [];
87
- return paramStatements.map((paramState: CodeParamStatement) => ({
88
- labelWidth: '100px',
89
- text: paramState.name,
90
- ...paramState,
91
- }));
92
- };
109
+ if (paramsConfig.value.length) {
110
+ model.params = createValues(formState, paramsConfig.value, {}, model.params);
111
+ } else {
112
+ model.params = {};
113
+ }
93
114
 
94
- /**
95
- * 根据代码块id获取参数fieldset表单配置
96
- * @param codeId 代码块ID
97
- */
98
- const getCodeParamsConfig = (codeId: Id) => {
99
- const paramsConfig = getParamItemsConfig(codeId);
100
- // 如果参数没有填值,则使用createValues补全空值
101
- if (!props.model.params || isEmpty(props.model.params)) {
102
- props.model.params = {};
103
- createValues(mForm, paramsConfig, {}, props.model.params);
104
- }
105
- codeParamsConfig.value = {
106
- type: 'fieldset',
107
- items: paramsConfig,
108
- legend: '参数',
109
- labelWidth: '70px',
110
- name: 'params',
111
- display: !isEmpty(paramsConfig),
112
- };
115
+ return codeId;
116
+ },
113
117
  };
114
118
 
115
119
  /**
116
120
  * 参数值修改更新
117
121
  */
118
- const onParamsChangeHandler = () => {
122
+ const onParamsChangeHandler = (value: any) => {
123
+ props.model.params = value.params;
119
124
  emit('change', props.model);
120
125
  };
121
126
 
122
- // 监听代码块顺序变化以及下拉选择的变化,并更新参数配置
123
- // TODO onchange在watch之前触发
124
- watch(
125
- () => props.model.codeId,
126
- (codeId: Id) => {
127
- if (!codeId) return;
128
- getCodeParamsConfig(codeId);
129
- },
130
- {
131
- immediate: true,
132
- },
133
- );
134
-
135
- // 打开代码编辑框
136
- const editCode = () => {
137
- services?.codeBlockService.setCodeEditorContent(true, props.model.codeId);
138
- };
127
+ const { codeBlockEditor, codeConfig, editCode, submitCodeBlockHandler } = useCodeBlockEdit(services?.codeBlockService);
139
128
  </script>
@@ -0,0 +1,47 @@
1
+ <template>
2
+ <m-form-container
3
+ :config="{
4
+ ...config,
5
+ ...cascaderConfig,
6
+ }"
7
+ :model="model"
8
+ @change="onChangeHandler"
9
+ ></m-form-container>
10
+ </template>
11
+
12
+ <script setup lang="ts">
13
+ import { computed, inject } from 'vue';
14
+
15
+ import type { FieldProps } from '@tmagic/form';
16
+
17
+ import type { DataSourceFieldSelectConfig, Services } from '@editor/type';
18
+
19
+ const services = inject<Services>('services');
20
+ const emit = defineEmits(['change']);
21
+
22
+ const props = withDefaults(defineProps<FieldProps<DataSourceFieldSelectConfig>>(), {
23
+ disabled: false,
24
+ });
25
+
26
+ const dataSources = computed(() => services?.dataSourceService.get('dataSources'));
27
+
28
+ const cascaderConfig = {
29
+ type: 'cascader',
30
+ name: props.name,
31
+ options: () =>
32
+ dataSources.value
33
+ ?.filter((ds) => ds.fields?.length)
34
+ ?.map((ds) => ({
35
+ label: ds.title || ds.id,
36
+ value: ds.id,
37
+ children: ds.fields?.map((field) => ({
38
+ label: field.title,
39
+ value: field.name,
40
+ })),
41
+ })) || [],
42
+ };
43
+
44
+ const onChangeHandler = (value: any) => {
45
+ emit('change', value);
46
+ };
47
+ </script>
@@ -1,43 +1,44 @@
1
1
  <template>
2
2
  <div class="m-editor-data-source-fields">
3
- <MagicTable :data="model[name]" :columns="filedColumns"></MagicTable>
3
+ <MagicTable :data="model[name]" :columns="fieldColumns"></MagicTable>
4
4
 
5
5
  <div class="m-editor-data-source-fields-footer">
6
6
  <TMagicButton size="small" type="primary" :disabled="disabled" plain @click="newHandler()">添加</TMagicButton>
7
7
  </div>
8
8
 
9
- <MFormDialog
9
+ <MFormDrawer
10
10
  ref="addDialog"
11
+ label-width="80px"
11
12
  :title="filedTitle"
12
13
  :config="dataSourceFieldsConfig"
13
14
  :values="fieldValues"
14
15
  :parentValues="model[name]"
16
+ :disabled="disabled"
17
+ :width="width"
15
18
  @submit="fieldChange"
16
- ></MFormDialog>
19
+ ></MFormDrawer>
17
20
  </div>
18
21
  </template>
19
22
 
20
23
  <script setup lang="ts">
21
- import { ref } from 'vue';
24
+ import { computed, inject, ref } from 'vue';
22
25
 
23
26
  import { TMagicButton, tMagicMessageBox } from '@tmagic/design';
24
- import { FormConfig, FormState, MFormDialog } from '@tmagic/form';
27
+ import { type FieldProps, type FormConfig, type FormState, MFormDrawer } from '@tmagic/form';
25
28
  import { MagicTable } from '@tmagic/table';
26
29
 
30
+ import type { Services } from '@editor/type';
31
+
27
32
  defineOptions({
28
33
  name: 'MEditorDataSourceFields',
29
34
  });
30
35
 
31
36
  const props = withDefaults(
32
- defineProps<{
33
- config: {
37
+ defineProps<
38
+ FieldProps<{
34
39
  type: 'data-source-fields';
35
- };
36
- model: any;
37
- prop: string;
38
- disabled: boolean;
39
- name: string;
40
- }>(),
40
+ }>
41
+ >(),
41
42
  {
42
43
  disabled: false,
43
44
  },
@@ -45,32 +46,33 @@ const props = withDefaults(
45
46
 
46
47
  const emit = defineEmits(['change']);
47
48
 
48
- const addDialog = ref<InstanceType<typeof MFormDialog>>();
49
+ const services = inject<Services>('services');
50
+
51
+ const addDialog = ref<InstanceType<typeof MFormDrawer>>();
49
52
  const fieldValues = ref<Record<string, any>>({});
50
53
  const filedTitle = ref('');
51
54
 
55
+ const width = computed(() => globalThis.document.body.clientWidth - (services?.uiService.get('columnWidth').left || 0));
56
+
52
57
  const newHandler = () => {
53
- if (!addDialog.value) return;
54
58
  fieldValues.value = {};
55
59
  filedTitle.value = '新增属性';
56
- addDialog.value.dialogVisible = true;
60
+ addDialog.value?.show();
57
61
  };
58
62
 
59
63
  const fieldChange = ({ index, ...value }: Record<string, any>) => {
60
- if (!addDialog.value) return;
61
-
62
64
  if (index > -1) {
63
65
  props.model[props.name][index] = value;
64
66
  } else {
65
67
  props.model[props.name].push(value);
66
68
  }
67
69
 
68
- addDialog.value.dialogVisible = false;
70
+ addDialog.value?.hide();
69
71
 
70
72
  emit('change', props.model[props.name]);
71
73
  };
72
74
 
73
- const filedColumns = [
75
+ const fieldColumns = [
74
76
  {
75
77
  label: '属性名称',
76
78
  prop: 'title',
@@ -83,6 +85,10 @@ const filedColumns = [
83
85
  label: '属性描述',
84
86
  prop: 'desc',
85
87
  },
88
+ {
89
+ label: '默认值',
90
+ prop: 'defaultValue',
91
+ },
86
92
  {
87
93
  label: '操作',
88
94
  fixed: 'right',
@@ -90,13 +96,12 @@ const filedColumns = [
90
96
  {
91
97
  text: '编辑',
92
98
  handler: (row: Record<string, any>, index: number) => {
93
- if (!addDialog.value) return;
94
99
  fieldValues.value = {
95
100
  ...row,
96
101
  index,
97
102
  };
98
103
  filedTitle.value = `编辑${row.title}`;
99
- addDialog.value.dialogVisible = true;
104
+ addDialog.value?.show();
100
105
  },
101
106
  },
102
107
  {
@@ -161,10 +166,21 @@ const dataSourceFieldsConfig: FormConfig = [
161
166
  {
162
167
  name: 'description',
163
168
  text: '描述',
169
+ type: 'textarea',
164
170
  },
165
171
  {
166
172
  name: 'defaultValue',
167
173
  text: '默认值',
174
+ type: (mForm: FormState | undefined, { model }: any) => {
175
+ if (model.type === 'number') return 'number';
176
+ if (model.type === 'boolean') return 'select';
177
+
178
+ return 'string';
179
+ },
180
+ options: [
181
+ { text: 'true', value: true },
182
+ { text: 'false', value: false },
183
+ ],
168
184
  },
169
185
  {
170
186
  name: 'enable',