@tmagic/editor 1.3.15 → 1.4.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 (121) hide show
  1. package/dist/style.css +17 -3
  2. package/dist/tmagic-editor.js +875 -530
  3. package/dist/tmagic-editor.umd.cjs +891 -545
  4. package/package.json +23 -21
  5. package/src/Editor.vue +8 -0
  6. package/src/components/CodeBlockEditor.vue +50 -24
  7. package/src/components/FloatingBox.vue +53 -12
  8. package/src/fields/Code.vue +12 -10
  9. package/src/fields/CodeLink.vue +9 -9
  10. package/src/fields/CodeSelect.vue +7 -5
  11. package/src/fields/CodeSelectCol.vue +1 -1
  12. package/src/fields/DataSourceFieldSelect.vue +118 -27
  13. package/src/fields/DataSourceFields.vue +10 -3
  14. package/src/fields/DataSourceInput.vue +7 -7
  15. package/src/fields/DataSourceMethodSelect.vue +1 -1
  16. package/src/fields/DataSourceMethods.vue +3 -3
  17. package/src/fields/DataSourceMocks.vue +3 -3
  18. package/src/fields/DataSourceSelect.vue +6 -18
  19. package/src/fields/EventSelect.vue +1 -1
  20. package/src/fields/KeyValue.vue +8 -8
  21. package/src/fields/PageFragmentSelect.vue +1 -1
  22. package/src/fields/UISelect.vue +5 -5
  23. package/src/hooks/use-code-block-edit.ts +0 -1
  24. package/src/index.ts +3 -2
  25. package/src/layouts/NavMenu.vue +21 -2
  26. package/src/layouts/sidebar/Sidebar.vue +16 -1
  27. package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +0 -1
  28. package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +3 -0
  29. package/src/services/BaseService.ts +5 -2
  30. package/src/services/codeBlock.ts +14 -8
  31. package/src/services/dataSource.ts +39 -26
  32. package/src/services/editor.ts +46 -25
  33. package/src/services/events.ts +4 -4
  34. package/src/services/props.ts +44 -35
  35. package/src/services/stageOverlay.ts +14 -7
  36. package/src/services/storage.ts +14 -8
  37. package/src/services/ui.ts +20 -19
  38. package/src/theme/code-editor.scss +6 -0
  39. package/src/theme/component-list-panel.scss +79 -71
  40. package/src/theme/floating-box.scss +2 -0
  41. package/src/theme/layer-panel.scss +1 -0
  42. package/src/theme/sidebar.scss +6 -3
  43. package/src/type.ts +82 -37
  44. package/src/utils/operator.ts +37 -39
  45. package/src/utils/props.ts +174 -37
  46. package/types/components/CodeBlockEditor.vue.d.ts +4 -4
  47. package/types/components/CodeParams.vue.d.ts +5 -5
  48. package/types/components/ContentMenu.vue.d.ts +12 -12
  49. package/types/components/FloatingBox.vue.d.ts +14 -12
  50. package/types/components/Icon.vue.d.ts +3 -3
  51. package/types/components/Resizer.vue.d.ts +3 -3
  52. package/types/components/ScrollBar.vue.d.ts +3 -3
  53. package/types/components/ScrollViewer.vue.d.ts +12 -12
  54. package/types/components/SearchInput.vue.d.ts +1 -1
  55. package/types/components/SplitView.vue.d.ts +11 -11
  56. package/types/components/ToolButton.vue.d.ts +13 -13
  57. package/types/components/Tree.vue.d.ts +24 -14
  58. package/types/components/TreeNode.vue.d.ts +22 -12
  59. package/types/fields/Code.vue.d.ts +14 -14
  60. package/types/fields/CodeLink.vue.d.ts +6 -10
  61. package/types/fields/CodeSelect.vue.d.ts +14 -14
  62. package/types/fields/CodeSelectCol.vue.d.ts +11 -11
  63. package/types/fields/DataSourceFieldSelect.vue.d.ts +11 -11
  64. package/types/fields/DataSourceFields.vue.d.ts +11 -11
  65. package/types/fields/DataSourceInput.vue.d.ts +14 -18
  66. package/types/fields/DataSourceMethodSelect.vue.d.ts +11 -11
  67. package/types/fields/DataSourceMethods.vue.d.ts +11 -11
  68. package/types/fields/DataSourceMocks.vue.d.ts +11 -11
  69. package/types/fields/DataSourceSelect.vue.d.ts +13 -26
  70. package/types/fields/EventSelect.vue.d.ts +3 -3
  71. package/types/fields/KeyValue.vue.d.ts +14 -18
  72. package/types/fields/PageFragmentSelect.vue.d.ts +11 -11
  73. package/types/fields/UISelect.vue.d.ts +8 -4
  74. package/types/hooks/use-code-block-edit.d.ts +51 -89
  75. package/types/hooks/use-data-source-method.d.ts +51 -89
  76. package/types/hooks/use-node-status.d.ts +6 -1
  77. package/types/icons/AppManageIcon.vue.d.ts +1 -1
  78. package/types/icons/CenterIcon.vue.d.ts +1 -1
  79. package/types/icons/CodeIcon.vue.d.ts +1 -1
  80. package/types/icons/FolderMinusIcon.vue.d.ts +1 -1
  81. package/types/icons/PinIcon.vue.d.ts +1 -1
  82. package/types/icons/PinnedIcon.vue.d.ts +1 -1
  83. package/types/index.d.ts +1 -0
  84. package/types/layouts/AddPageBox.vue.d.ts +3 -3
  85. package/types/layouts/CodeEditor.vue.d.ts +12 -12
  86. package/types/layouts/Framework.vue.d.ts +9 -9
  87. package/types/layouts/NavMenu.vue.d.ts +11 -11
  88. package/types/layouts/PropsPanel.vue.d.ts +193 -243
  89. package/types/layouts/page-bar/AddButton.vue.d.ts +3 -3
  90. package/types/layouts/page-bar/PageBar.vue.d.ts +8 -8
  91. package/types/layouts/page-bar/PageBarScrollContainer.vue.d.ts +8 -8
  92. package/types/layouts/page-bar/SwitchTypeButton.vue.d.ts +3 -3
  93. package/types/layouts/sidebar/ComponentListPanel.vue.d.ts +1 -1
  94. package/types/layouts/sidebar/Sidebar.vue.d.ts +12 -12
  95. package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +10 -10
  96. package/types/layouts/sidebar/code-block/CodeBlockListPanel.vue.d.ts +9 -9
  97. package/types/layouts/sidebar/data-source/DataSourceConfigPanel.vue.d.ts +3 -3
  98. package/types/layouts/sidebar/data-source/DataSourceList.vue.d.ts +3 -3
  99. package/types/layouts/sidebar/data-source/DataSourceListPanel.vue.d.ts +9 -9
  100. package/types/layouts/sidebar/layer/LayerMenu.vue.d.ts +11 -11
  101. package/types/layouts/sidebar/layer/LayerNodeTool.vue.d.ts +3 -3
  102. package/types/layouts/sidebar/layer/LayerPanel.vue.d.ts +9 -9
  103. package/types/layouts/sidebar/layer/use-click.d.ts +42 -76
  104. package/types/layouts/sidebar/layer/use-node-status.d.ts +6 -1
  105. package/types/layouts/workspace/Breadcrumb.vue.d.ts +1 -1
  106. package/types/layouts/workspace/Workspace.vue.d.ts +12 -12
  107. package/types/layouts/workspace/viewer/NodeListMenu.vue.d.ts +1 -1
  108. package/types/layouts/workspace/viewer/Stage.vue.d.ts +11 -11
  109. package/types/layouts/workspace/viewer/StageOverlay.vue.d.ts +1 -1
  110. package/types/layouts/workspace/viewer/ViewerMenu.vue.d.ts +12 -12
  111. package/types/services/BaseService.d.ts +5 -2
  112. package/types/services/codeBlock.d.ts +8 -0
  113. package/types/services/dataSource.d.ts +9 -2
  114. package/types/services/editor.d.ts +8 -1
  115. package/types/services/props.d.ts +15 -22
  116. package/types/services/stageOverlay.d.ts +8 -1
  117. package/types/services/storage.d.ts +8 -0
  118. package/types/services/ui.d.ts +15 -9
  119. package/types/type.d.ts +51 -32
  120. package/types/utils/operator.d.ts +1 -1
  121. package/types/utils/props.d.ts +2 -13
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.3.15",
2
+ "version": "1.4.0-beta.1",
3
3
  "name": "@tmagic/editor",
4
4
  "type": "module",
5
5
  "sideEffects": [
@@ -42,14 +42,14 @@
42
42
  "dependencies": {
43
43
  "@babel/core": "^7.18.0",
44
44
  "@element-plus/icons-vue": "^2.3.1",
45
- "@tmagic/core": "1.3.15",
46
- "@tmagic/dep": "1.3.15",
47
- "@tmagic/design": "1.3.15",
48
- "@tmagic/form": "1.3.15",
49
- "@tmagic/schema": "1.3.15",
50
- "@tmagic/stage": "1.3.15",
51
- "@tmagic/table": "1.3.15",
52
- "@tmagic/utils": "1.3.15",
45
+ "@tmagic/core": "1.4.0-beta.1",
46
+ "@tmagic/dep": "1.4.0-beta.1",
47
+ "@tmagic/design": "1.4.0-beta.1",
48
+ "@tmagic/form": "1.4.0-beta.1",
49
+ "@tmagic/schema": "1.4.0-beta.1",
50
+ "@tmagic/stage": "1.4.0-beta.1",
51
+ "@tmagic/table": "1.4.0-beta.1",
52
+ "@tmagic/utils": "1.4.0-beta.1",
53
53
  "buffer": "^6.0.3",
54
54
  "color": "^3.1.3",
55
55
  "emmet-monaco-es": "^5.3.0",
@@ -57,16 +57,16 @@
57
57
  "gesto": "^1.19.1",
58
58
  "keycon": "^1.4.0",
59
59
  "lodash-es": "^4.17.21",
60
- "monaco-editor": "^0.41.0",
60
+ "monaco-editor": "^0.47.0",
61
61
  "moveable": "^0.51.1",
62
62
  "serialize-javascript": "^6.0.0",
63
- "vue": "^3.3.8"
63
+ "vue": "^3.4.21"
64
64
  },
65
65
  "peerDependencies": {
66
- "@tmagic/design": "1.3.15",
67
- "@tmagic/form": "1.3.15",
68
- "monaco-editor": "^0.41.0",
69
- "vue": "^3.3.8"
66
+ "@tmagic/design": "1.4.0-beta.1",
67
+ "@tmagic/form": "1.4.0-beta.1",
68
+ "monaco-editor": "^0.47.0",
69
+ "vue": "^3.4.21"
70
70
  },
71
71
  "devDependencies": {
72
72
  "@types/events": "^3.0.0",
@@ -74,18 +74,20 @@
74
74
  "@types/node": "^18.19.0",
75
75
  "@types/serialize-javascript": "^5.0.1",
76
76
  "@vitejs/plugin-vue": "^4.5.2",
77
- "@vue/compiler-sfc": "^3.3.8",
78
- "@vue/test-utils": "^2.3.2",
77
+ "@vue/compiler-sfc": "^3.4.21",
78
+ "@vue/test-utils": "^2.4.4",
79
79
  "rimraf": "^3.0.2",
80
80
  "sass": "^1.35.1",
81
81
  "tsc-alias": "^1.8.5",
82
- "typescript": "^5.0.4",
83
- "vite": "^5.0.7",
84
- "vue-tsc": "^1.8.25"
82
+ "type-fest": "^4.10.3",
83
+ "typescript": "^5.4.2",
84
+ "vite": "^5.1.6",
85
+ "vue-tsc": "^2.0.6"
85
86
  },
86
87
  "scripts": {
87
88
  "build": "npm run build:type && vite build",
88
89
  "build:type": "npm run clear:type && vue-tsc --declaration --emitDeclarationOnly --project tsconfig.build.json && tsc-alias -p tsconfig.build.json",
89
- "clear:type": "rimraf ./types"
90
+ "clear:type": "rimraf ./types",
91
+ "type:check": "vue-tsc --noEmit"
90
92
  }
91
93
  }
package/src/Editor.vue CHANGED
@@ -49,9 +49,17 @@
49
49
  <slot name="code-block-panel-tool" :id="id" :data="data"></slot>
50
50
  </template>
51
51
 
52
+ <template #code-block-panel-search>
53
+ <slot name="code-block-panel-search"></slot>
54
+ </template>
55
+
52
56
  <template #data-source-panel-tool="{ data }">
53
57
  <slot name="data-source-panel-tool" :data="data"></slot>
54
58
  </template>
59
+
60
+ <template #data-source-panel-search>
61
+ <slot name="data-source-panel-search"></slot>
62
+ </template>
55
63
  </Sidebar>
56
64
  </slot>
57
65
  </template>
@@ -1,26 +1,33 @@
1
1
  <template>
2
- <component
3
- :is="slideType === 'box' ? MFormBox : MFormDrawer"
4
- class="m-editor-code-block-editor"
5
- ref="fomDrawer"
6
- label-width="80px"
7
- :close-on-press-escape="false"
8
- :title="content.name"
9
- :width="size"
10
- :config="functionConfig"
11
- :values="content"
12
- :disabled="disabled"
13
- :before-close="beforeClose"
14
- @change="changeHandler"
15
- @submit="submitForm"
16
- @error="errorHandler"
17
- @open="openHandler"
18
- @closed="closedHandler"
19
- >
20
- <template #left>
21
- <TMagicButton type="primary" link @click="difVisible = true">查看修改</TMagicButton>
2
+ <!-- 代码块编辑区 -->
3
+ <FloatingBox v-model:visible="boxVisible" title="代码编辑" :position="boxPosition" :before-close="beforeClose">
4
+ <template #body>
5
+ <div ref="floatingBoxBody"></div>
22
6
  </template>
23
- </component>
7
+ </FloatingBox>
8
+
9
+ <Teleport :to="floatingBoxBody" :disabled="slideType === 'box'" v-if="editVisible">
10
+ <MFormBox
11
+ class="m-editor-code-block-editor"
12
+ ref="fomDrawer"
13
+ label-width="80px"
14
+ :close-on-press-escape="false"
15
+ :title="content.name"
16
+ :width="size"
17
+ :config="functionConfig"
18
+ :values="content"
19
+ :disabled="disabled"
20
+ @change="changeHandler"
21
+ @submit="submitForm"
22
+ @error="errorHandler"
23
+ @open="openHandler"
24
+ @closed="closedHandler"
25
+ >
26
+ <template #left>
27
+ <TMagicButton type="primary" link @click="difVisible = true">查看修改</TMagicButton>
28
+ </template>
29
+ </MFormBox>
30
+ </Teleport>
24
31
 
25
32
  <TMagicDialog v-model="difVisible" title="查看修改" fullscreen>
26
33
  <div style="display: flex; margin-bottom: 10px">
@@ -48,12 +55,13 @@
48
55
  </template>
49
56
 
50
57
  <script lang="ts" setup>
51
- import { computed, inject, onBeforeUnmount, ref } from 'vue';
58
+ import { computed, inject, nextTick, onBeforeUnmount, ref } from 'vue';
52
59
 
53
60
  import { TMagicButton, TMagicDialog, tMagicMessage, tMagicMessageBox, TMagicTag } from '@tmagic/design';
54
61
  import { ColumnConfig, FormConfig, FormState, MFormBox, MFormDrawer } from '@tmagic/form';
55
62
  import type { CodeBlockContent } from '@tmagic/schema';
56
63
 
64
+ import FloatingBox from '@editor/components/FloatingBox.vue';
57
65
  import CodeEditor from '@editor/layouts/CodeEditor.vue';
58
66
  import type { Services, SlideType } from '@editor/type';
59
67
  import { getConfig } from '@editor/utils/config';
@@ -248,7 +256,7 @@ const beforeClose = (done: (cancel?: boolean) => void) => {
248
256
  done();
249
257
  })
250
258
  .catch((action: string) => {
251
- done(action === 'close');
259
+ done(action === 'cancel');
252
260
  });
253
261
  };
254
262
 
@@ -256,8 +264,26 @@ const closedHandler = () => {
256
264
  changedValue.value = undefined;
257
265
  };
258
266
 
267
+ const boxVisible = ref<boolean>(false);
268
+ const editVisible = ref<boolean>(false);
269
+ const floatingBoxBody = ref<HTMLDivElement>();
270
+
271
+ const boxPosition = computed(() => {
272
+ const columnWidth = services?.uiService?.get('columnWidth');
273
+ const navMenuRect = services?.uiService?.get('navMenuRect');
274
+ return {
275
+ left: columnWidth?.left ?? 0,
276
+ top: (navMenuRect?.top ?? 0) + (navMenuRect?.height ?? 0),
277
+ };
278
+ });
279
+
259
280
  defineExpose({
260
- show() {
281
+ async show() {
282
+ if (props.slideType !== 'box') {
283
+ boxVisible.value = true;
284
+ }
285
+ await nextTick();
286
+ editVisible.value = true;
261
287
  fomDrawer.value?.show();
262
288
  },
263
289
 
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <Teleport to="body" v-if="visible">
3
- <div ref="target" class="m-editor-float-box" :style="style">
3
+ <div ref="target" class="m-editor-float-box" :style="{ ...style, zIndex: curZIndex }" @mousedown="nextZIndex">
4
4
  <div ref="dragTarget" class="m-editor-float-box-title">
5
5
  <slot name="title">
6
6
  <span>{{ title }}</span>
@@ -17,11 +17,11 @@
17
17
  </template>
18
18
 
19
19
  <script setup lang="ts">
20
- import { computed, nextTick, onBeforeUnmount, ref, watch } from 'vue';
20
+ import { computed, nextTick, onBeforeUnmount, ref, watch, watchEffect } from 'vue';
21
21
  import { Close } from '@element-plus/icons-vue';
22
22
  import VanillaMoveable from 'moveable';
23
23
 
24
- import { TMagicButton } from '@tmagic/design';
24
+ import { TMagicButton, useZIndex } from '@tmagic/design';
25
25
 
26
26
  interface Position {
27
27
  left: number;
@@ -33,12 +33,21 @@ interface Rect {
33
33
  height: number | string;
34
34
  }
35
35
 
36
- const props = withDefaults(defineProps<{ visible: boolean; position?: Position; rect?: Rect; title?: string }>(), {
37
- visible: false,
38
- title: '',
39
- position: () => ({ left: 0, top: 0 }),
40
- rect: () => ({ width: 'auto', height: 'auto' }),
41
- });
36
+ const props = withDefaults(
37
+ defineProps<{
38
+ visible: boolean;
39
+ position?: Position;
40
+ rect?: Rect;
41
+ title?: string;
42
+ beforeClose?: (done: (cancel?: boolean) => void) => void;
43
+ }>(),
44
+ {
45
+ visible: false,
46
+ title: '',
47
+ position: () => ({ left: 0, top: 0 }),
48
+ rect: () => ({ width: 'auto', height: 'auto' }),
49
+ },
50
+ );
42
51
 
43
52
  const emit = defineEmits<{
44
53
  'update:visible': [boolean];
@@ -47,11 +56,26 @@ const emit = defineEmits<{
47
56
  const target = ref<HTMLDivElement>();
48
57
  const dragTarget = ref<HTMLDivElement>();
49
58
 
59
+ const zIndex = useZIndex();
60
+ const curZIndex = ref<number>(zIndex.nextZIndex());
61
+
62
+ const rect = ref({
63
+ width: props.rect.width,
64
+ height: props.rect.height,
65
+ });
66
+
67
+ watchEffect(() => {
68
+ rect.value = {
69
+ width: props.rect.width,
70
+ height: props.rect.height,
71
+ };
72
+ });
73
+
50
74
  const style = computed(() => ({
51
75
  left: `${props.position.left}px`,
52
76
  top: `${props.position.top}px`,
53
- width: typeof props.rect.width === 'string' ? props.rect.width : `${props.rect.width}px`,
54
- height: typeof props.rect.height === 'string' ? props.rect.height : `${props.rect.height}px`,
77
+ width: typeof rect.value.width === 'string' ? rect.value.width : `${rect.value.width}px`,
78
+ height: typeof rect.value.height === 'string' ? rect.value.height : `${rect.value.height}px`,
55
79
  }));
56
80
 
57
81
  let moveable: VanillaMoveable | null = null;
@@ -70,6 +94,7 @@ const initMoveable = () => {
70
94
  dragTargetSelf: false,
71
95
  linePadding: 10,
72
96
  controlPadding: 10,
97
+ bounds: { left: 0, top: 0, right: 0, bottom: 0, position: 'css' },
73
98
  });
74
99
 
75
100
  moveable.on('drag', (e) => {
@@ -77,6 +102,8 @@ const initMoveable = () => {
77
102
  });
78
103
 
79
104
  moveable.on('resize', (e) => {
105
+ rect.value.width = e.width;
106
+ rect.value.height = e.height;
80
107
  e.target.style.width = `${e.width}px`;
81
108
  e.target.style.height = `${e.height}px`;
82
109
  e.target.style.transform = e.drag.transform;
@@ -107,8 +134,22 @@ onBeforeUnmount(() => {
107
134
  destroyMoveable();
108
135
  });
109
136
 
137
+ const hide = (cancel?: boolean) => {
138
+ if (cancel !== false) {
139
+ emit('update:visible', false);
140
+ }
141
+ };
142
+
110
143
  const closeHandler = () => {
111
- emit('update:visible', false);
144
+ if (typeof props.beforeClose === 'function') {
145
+ props.beforeClose(hide);
146
+ } else {
147
+ hide();
148
+ }
149
+ };
150
+
151
+ const nextZIndex = () => {
152
+ curZIndex.value = zIndex.nextZIndex();
112
153
  };
113
154
 
114
155
  defineExpose({
@@ -13,12 +13,12 @@
13
13
  </template>
14
14
 
15
15
  <script lang="ts" setup>
16
- import type { FieldProps } from '@tmagic/form';
16
+ import type { FieldProps, FormItem } from '@tmagic/form';
17
17
 
18
18
  import MagicCodeEditor from '@editor/layouts/CodeEditor.vue';
19
19
 
20
20
  defineOptions({
21
- name: 'MEditorCode',
21
+ name: 'MFieldsVsCode',
22
22
  });
23
23
 
24
24
  const emit = defineEmits<{
@@ -27,14 +27,16 @@ const emit = defineEmits<{
27
27
 
28
28
  const props = withDefaults(
29
29
  defineProps<
30
- FieldProps<{
31
- language?: string;
32
- options?: {
33
- [key: string]: any;
34
- };
35
- height?: string;
36
- parse?: boolean;
37
- }>
30
+ FieldProps<
31
+ {
32
+ language?: string;
33
+ options?: {
34
+ [key: string]: any;
35
+ };
36
+ height?: string;
37
+ parse?: boolean;
38
+ } & FormItem
39
+ >
38
40
  >(),
39
41
  {
40
42
  disabled: false,
@@ -6,22 +6,22 @@
6
6
  import { computed, reactive, watch } from 'vue';
7
7
  import serialize from 'serialize-javascript';
8
8
 
9
- import type { FieldProps } from '@tmagic/form';
9
+ import type { FieldProps, FormItem } from '@tmagic/form';
10
10
 
11
11
  import { getConfig } from '@editor/utils/config';
12
12
 
13
13
  defineOptions({
14
- name: 'MEditorCodeLink',
14
+ name: 'MFieldsCodeLink',
15
15
  });
16
16
 
17
17
  const props = defineProps<
18
- FieldProps<{
19
- type: 'code-link';
20
- name: string;
21
- text?: string;
22
- formTitle?: string;
23
- codeOptions?: Object;
24
- }>
18
+ FieldProps<
19
+ {
20
+ type: 'code-link';
21
+ formTitle?: string;
22
+ codeOptions?: Object;
23
+ } & FormItem
24
+ >
25
25
  >();
26
26
 
27
27
  const emit = defineEmits(['change']);
@@ -11,14 +11,14 @@ 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
+ import type { FieldProps, FormItem } from '@tmagic/form';
15
15
  import { FormState } from '@tmagic/form';
16
16
  import { HookCodeType, HookType } from '@tmagic/schema';
17
17
 
18
18
  import type { Services } from '@editor/type';
19
19
 
20
20
  defineOptions({
21
- name: 'MEditorCodeSelect',
21
+ name: 'MFieldsCodeSelect',
22
22
  });
23
23
 
24
24
  const emit = defineEmits(['change']);
@@ -27,9 +27,11 @@ const services = inject<Services>('services');
27
27
 
28
28
  const props = withDefaults(
29
29
  defineProps<
30
- FieldProps<{
31
- className?: string;
32
- }>
30
+ FieldProps<
31
+ {
32
+ className?: string;
33
+ } & FormItem
34
+ >
33
35
  >(),
34
36
  {},
35
37
  );
@@ -49,7 +49,7 @@ import { useCodeBlockEdit } from '@editor/hooks/use-code-block-edit';
49
49
  import type { CodeParamStatement, CodeSelectColConfig, Services } from '@editor/type';
50
50
 
51
51
  defineOptions({
52
- name: 'MEditorCodeSelectCol',
52
+ name: 'MFieldsCodeSelectCol',
53
53
  });
54
54
 
55
55
  const mForm = inject<FormState | undefined>('mForm');
@@ -1,23 +1,47 @@
1
1
  <template>
2
- <m-form-container
3
- :config="{
4
- ...config,
5
- ...cascaderConfig,
6
- }"
7
- :model="model"
8
- @change="onChangeHandler"
9
- ></m-form-container>
2
+ <div style="width: 100%; display: flex; align-items: center">
3
+ <component
4
+ style="width: 100%"
5
+ :is="tagName"
6
+ :config="showDataSourceFieldSelect || !config.fieldConfig ? cascaderConfig : config.fieldConfig"
7
+ :model="model"
8
+ :name="name"
9
+ :disabled="disabled"
10
+ :size="size"
11
+ :last-values="lastValues"
12
+ :init-values="initValues"
13
+ :values="values"
14
+ :prop="`${prop}${prop ? '.' : ''}${name}`"
15
+ @change="onChangeHandler"
16
+ ></component>
17
+ <TMagicButton
18
+ v-if="config.fieldConfig"
19
+ style="margin-left: 5px"
20
+ link
21
+ :type="showDataSourceFieldSelect ? 'primary' : 'default'"
22
+ :icon="Coin"
23
+ :size="size"
24
+ @click="showDataSourceFieldSelect = !showDataSourceFieldSelect"
25
+ ></TMagicButton>
26
+ </div>
10
27
  </template>
11
28
 
12
29
  <script setup lang="ts">
13
- import { computed, inject } from 'vue';
30
+ import { computed, inject, onMounted, ref, resolveComponent } from 'vue';
31
+ import { Coin } from '@element-plus/icons-vue';
14
32
 
15
- import type { CascaderOption, FieldProps } from '@tmagic/form';
16
- import type { DataSchema } from '@tmagic/schema';
33
+ import { TMagicButton } from '@tmagic/design';
34
+ import type { CascaderConfig, CascaderOption, FieldProps, FormState } from '@tmagic/form';
35
+ import { MCascader } from '@tmagic/form';
36
+ import type { DataSchema, DataSourceFieldType } from '@tmagic/schema';
17
37
  import { DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX } from '@tmagic/utils';
18
38
 
19
39
  import type { DataSourceFieldSelectConfig, Services } from '@editor/type';
20
40
 
41
+ defineOptions({
42
+ name: 'MFieldsDataSourceFieldSelect',
43
+ });
44
+
21
45
  const services = inject<Services>('services');
22
46
  const emit = defineEmits(['change']);
23
47
 
@@ -27,32 +51,99 @@ const props = withDefaults(defineProps<FieldProps<DataSourceFieldSelectConfig>>(
27
51
 
28
52
  const dataSources = computed(() => services?.dataSourceService.get('dataSources'));
29
53
 
30
- const getOptionChildren = (fields: DataSchema[] = []): CascaderOption[] =>
31
- fields.map((field) => ({
32
- label: field.title || field.name,
33
- value: field.name,
34
- children: field.type === 'array' ? [] : getOptionChildren(field.fields),
35
- }));
54
+ const getOptionChildren = (
55
+ fields: DataSchema[] = [],
56
+ dataSourceFieldType: DataSourceFieldType[] = ['any'],
57
+ ): CascaderOption[] => {
58
+ const child: CascaderOption[] = [];
59
+ fields.forEach((field) => {
60
+ if (!dataSourceFieldType.length) {
61
+ dataSourceFieldType.push('any');
62
+ }
63
+
64
+ const children = getOptionChildren(field.fields, dataSourceFieldType);
65
+
66
+ const item = {
67
+ label: field.title || field.name,
68
+ value: field.name,
69
+ children,
70
+ };
71
+
72
+ const fieldType = field.type || 'any';
73
+ if (dataSourceFieldType.includes('any') || dataSourceFieldType.includes(fieldType)) {
74
+ child.push(item);
75
+ return;
76
+ }
77
+
78
+ if (!dataSourceFieldType.includes(fieldType) && fieldType !== 'object') {
79
+ return;
80
+ }
81
+
82
+ if (!children.length && ['object', 'array', 'any'].includes(field.type || '')) {
83
+ return;
84
+ }
85
+
86
+ child.push(item);
87
+ });
88
+ return child;
89
+ };
36
90
 
37
- const cascaderConfig = computed(() => {
91
+ const cascaderConfig = computed<CascaderConfig>(() => {
38
92
  const valueIsKey = props.config.value === 'key';
39
93
 
40
94
  return {
41
95
  type: 'cascader',
42
- name: props.name,
43
- checkStrictly: !valueIsKey,
44
- text: '',
45
- options: () =>
46
- dataSources.value
47
- ?.filter((ds) => ds.fields?.length)
48
- ?.map((ds) => ({
96
+ checkStrictly: props.config.checkStrictly ?? !valueIsKey,
97
+ popperClass: 'm-editor-data-source-field-select-popper',
98
+ options: () => {
99
+ const options =
100
+ dataSources.value?.map((ds) => ({
49
101
  label: ds.title || ds.id,
50
102
  value: valueIsKey ? ds.id : `${DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX}${ds.id}`,
51
- children: getOptionChildren(ds.fields),
52
- })) || [],
103
+ children: getOptionChildren(ds.fields, props.config.dataSourceFieldType),
104
+ })) || [];
105
+ return options.filter((option) => option.children.length);
106
+ },
53
107
  };
54
108
  });
55
109
 
110
+ const showDataSourceFieldSelect = ref(false);
111
+
112
+ onMounted(() => {
113
+ const value = props.model[props.name];
114
+ if (
115
+ Array.isArray(value) &&
116
+ typeof value[0] === 'string' &&
117
+ value[0].startsWith(DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX)
118
+ ) {
119
+ return (showDataSourceFieldSelect.value = true);
120
+ }
121
+ });
122
+
123
+ const mForm = inject<FormState | undefined>('mForm');
124
+
125
+ const type = computed((): string => {
126
+ let type = props.config.fieldConfig?.type;
127
+ if (typeof type === 'function') {
128
+ type = type(mForm, {
129
+ model: props.model,
130
+ });
131
+ }
132
+ if (type === 'form') return '';
133
+ if (type === 'container') return '';
134
+ return type?.replace(/([A-Z])/g, '-$1').toLowerCase() || (props.config.items ? '' : 'text');
135
+ });
136
+
137
+ const tagName = computed(() => {
138
+ if (showDataSourceFieldSelect.value || !props.config.fieldConfig) {
139
+ return MCascader;
140
+ }
141
+
142
+ const component = resolveComponent(`m-${props.config.items ? 'form' : 'fields'}-${type.value}`);
143
+ if (typeof component !== 'string') return component;
144
+ return 'm-fields-text';
145
+ });
146
+
56
147
  const onChangeHandler = (value: any) => {
57
148
  emit('change', value);
58
149
  };
@@ -37,13 +37,13 @@ import { computed, inject, ref } from 'vue';
37
37
  import { TMagicButton, tMagicMessage, tMagicMessageBox } from '@tmagic/design';
38
38
  import { type FieldProps, type FormConfig, type FormState, MFormDrawer } from '@tmagic/form';
39
39
  import type { DataSchema } from '@tmagic/schema';
40
- import { MagicTable } from '@tmagic/table';
40
+ import { type ColumnConfig, MagicTable } from '@tmagic/table';
41
41
  import { getDefaultValueFromFields } from '@tmagic/utils';
42
42
 
43
43
  import type { Services } from '@editor/type';
44
44
 
45
45
  defineOptions({
46
- name: 'MEditorDataSourceFields',
46
+ name: 'MFieldsDataSourceFields',
47
47
  });
48
48
 
49
49
  const props = withDefaults(
@@ -86,7 +86,7 @@ const fieldChange = ({ index, ...value }: Record<string, any>) => {
86
86
  emit('change', props.model[props.name]);
87
87
  };
88
88
 
89
- const fieldColumns = [
89
+ const fieldColumns: ColumnConfig[] = [
90
90
  {
91
91
  label: '属性名称',
92
92
  prop: 'title',
@@ -102,6 +102,13 @@ const fieldColumns = [
102
102
  {
103
103
  label: '默认值',
104
104
  prop: 'defaultValue',
105
+ formatter(item, row) {
106
+ try {
107
+ return JSON.stringify(row.defaultValue);
108
+ } catch (e) {
109
+ return row.defaultValue;
110
+ }
111
+ },
105
112
  },
106
113
  {
107
114
  label: '操作',