@tmagic/editor 1.4.8 → 1.4.10

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 (166) hide show
  1. package/dist/style.css +26 -0
  2. package/dist/tmagic-editor.js +3213 -2820
  3. package/dist/tmagic-editor.umd.cjs +3237 -2839
  4. package/package.json +14 -12
  5. package/src/Editor.vue +212 -0
  6. package/src/components/CodeBlockEditor.vue +268 -0
  7. package/src/components/CodeParams.vue +60 -0
  8. package/src/components/ContentMenu.vue +193 -0
  9. package/src/components/FloatingBox.vue +178 -0
  10. package/src/components/Icon.vue +27 -0
  11. package/src/components/Resizer.vue +23 -0
  12. package/src/components/ScrollBar.vue +151 -0
  13. package/src/components/ScrollViewer.vue +128 -0
  14. package/src/components/SearchInput.vue +37 -0
  15. package/src/components/SplitView.vue +186 -0
  16. package/src/components/ToolButton.vue +138 -0
  17. package/src/components/Tree.vue +71 -0
  18. package/src/components/TreeNode.vue +150 -0
  19. package/src/editorProps.ts +120 -0
  20. package/src/fields/Code.vue +50 -0
  21. package/src/fields/CodeLink.vue +80 -0
  22. package/src/fields/CodeSelect.vue +132 -0
  23. package/src/fields/CodeSelectCol.vue +139 -0
  24. package/src/fields/CondOpSelect.vue +87 -0
  25. package/src/fields/DataSourceFieldSelect/FieldSelect.vue +152 -0
  26. package/src/fields/DataSourceFieldSelect/Index.vue +168 -0
  27. package/src/fields/DataSourceFields.vue +329 -0
  28. package/src/fields/DataSourceInput.vue +339 -0
  29. package/src/fields/DataSourceMethodSelect.vue +153 -0
  30. package/src/fields/DataSourceMethods.vue +104 -0
  31. package/src/fields/DataSourceMocks.vue +255 -0
  32. package/src/fields/DataSourceSelect.vue +98 -0
  33. package/src/fields/DisplayConds.vue +145 -0
  34. package/src/fields/EventSelect.vue +375 -0
  35. package/src/fields/KeyValue.vue +137 -0
  36. package/src/fields/PageFragmentSelect.vue +63 -0
  37. package/src/fields/UISelect.vue +135 -0
  38. package/src/hooks/index.ts +24 -0
  39. package/src/hooks/use-code-block-edit.ts +83 -0
  40. package/src/hooks/use-data-source-edit.ts +46 -0
  41. package/src/hooks/use-data-source-method.ts +100 -0
  42. package/src/hooks/use-editor-content-height.ts +26 -0
  43. package/src/hooks/use-filter.ts +55 -0
  44. package/src/hooks/use-float-box.ts +76 -0
  45. package/src/hooks/use-getso.ts +35 -0
  46. package/src/hooks/use-next-float-box-position.ts +29 -0
  47. package/src/hooks/use-node-status.ts +48 -0
  48. package/src/hooks/use-stage.ts +129 -0
  49. package/src/hooks/use-window-rect.ts +20 -0
  50. package/src/icons/AppManageIcon.vue +15 -0
  51. package/src/icons/CenterIcon.vue +13 -0
  52. package/src/icons/CodeIcon.vue +28 -0
  53. package/src/icons/FolderMinusIcon.vue +22 -0
  54. package/src/icons/PinIcon.vue +25 -0
  55. package/src/icons/PinnedIcon.vue +25 -0
  56. package/src/index.ts +124 -0
  57. package/src/initService.ts +448 -0
  58. package/src/layouts/AddPageBox.vue +55 -0
  59. package/src/layouts/CodeEditor.vue +226 -0
  60. package/src/layouts/Framework.vue +165 -0
  61. package/src/layouts/NavMenu.vue +200 -0
  62. package/src/layouts/PropsPanel.vue +131 -0
  63. package/src/layouts/page-bar/AddButton.vue +48 -0
  64. package/src/layouts/page-bar/PageBar.vue +165 -0
  65. package/src/layouts/page-bar/PageBarScrollContainer.vue +192 -0
  66. package/src/layouts/page-bar/PageList.vue +55 -0
  67. package/src/layouts/page-bar/SwitchTypeButton.vue +45 -0
  68. package/src/layouts/sidebar/ComponentListPanel.vue +134 -0
  69. package/src/layouts/sidebar/Sidebar.vue +278 -0
  70. package/src/layouts/sidebar/code-block/CodeBlockList.vue +160 -0
  71. package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +70 -0
  72. package/src/layouts/sidebar/data-source/DataSourceConfigPanel.vue +84 -0
  73. package/src/layouts/sidebar/data-source/DataSourceList.vue +172 -0
  74. package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +106 -0
  75. package/src/layouts/sidebar/layer/LayerMenu.vue +128 -0
  76. package/src/layouts/sidebar/layer/LayerNodeTool.vue +32 -0
  77. package/src/layouts/sidebar/layer/LayerPanel.vue +119 -0
  78. package/src/layouts/sidebar/layer/use-click.ts +113 -0
  79. package/src/layouts/sidebar/layer/use-drag.ts +167 -0
  80. package/src/layouts/sidebar/layer/use-keybinding.ts +54 -0
  81. package/src/layouts/sidebar/layer/use-node-status.ts +114 -0
  82. package/src/layouts/workspace/Breadcrumb.vue +35 -0
  83. package/src/layouts/workspace/Workspace.vue +46 -0
  84. package/src/layouts/workspace/viewer/NodeListMenu.vue +115 -0
  85. package/src/layouts/workspace/viewer/Stage.vue +246 -0
  86. package/src/layouts/workspace/viewer/StageOverlay.vue +68 -0
  87. package/src/layouts/workspace/viewer/ViewerMenu.vue +145 -0
  88. package/src/services/BaseService.ts +230 -0
  89. package/src/services/codeBlock.ts +327 -0
  90. package/src/services/componentList.ts +58 -0
  91. package/src/services/dataSource.ts +216 -0
  92. package/src/services/dep.ts +152 -0
  93. package/src/services/editor.ts +1135 -0
  94. package/src/services/events.ts +93 -0
  95. package/src/services/history.ts +126 -0
  96. package/src/services/keybinding.ts +220 -0
  97. package/src/services/props.ts +286 -0
  98. package/src/services/stageOverlay.ts +212 -0
  99. package/src/services/storage.ts +155 -0
  100. package/src/services/ui.ts +157 -0
  101. package/src/shims-vue.d.ts +6 -0
  102. package/src/theme/breadcrumb.scss +6 -0
  103. package/src/theme/code-block.scss +6 -0
  104. package/src/theme/code-editor.scss +38 -0
  105. package/src/theme/common/var.scss +14 -0
  106. package/src/theme/component-list-panel.scss +95 -0
  107. package/src/theme/content-menu.scss +76 -0
  108. package/src/theme/data-source-field-select.scss +16 -0
  109. package/src/theme/data-source-field.scss +12 -0
  110. package/src/theme/data-source-fields.scss +13 -0
  111. package/src/theme/data-source-input.scss +18 -0
  112. package/src/theme/data-source-methods.scss +13 -0
  113. package/src/theme/data-source.scss +28 -0
  114. package/src/theme/event.scss +37 -0
  115. package/src/theme/floating-box.scss +32 -0
  116. package/src/theme/framework.scss +69 -0
  117. package/src/theme/icon.scss +12 -0
  118. package/src/theme/index.scss +10 -0
  119. package/src/theme/key-value.scss +20 -0
  120. package/src/theme/layer-panel.scss +26 -0
  121. package/src/theme/layout.scss +9 -0
  122. package/src/theme/nav-menu.scss +78 -0
  123. package/src/theme/page-bar.scss +102 -0
  124. package/src/theme/page-fragment-select.scss +14 -0
  125. package/src/theme/props-panel.scss +55 -0
  126. package/src/theme/resizer.scss +66 -0
  127. package/src/theme/ruler.scss +38 -0
  128. package/src/theme/search-input.scss +14 -0
  129. package/src/theme/sidebar.scss +79 -0
  130. package/src/theme/stage.scss +76 -0
  131. package/src/theme/theme.scss +28 -0
  132. package/src/theme/tree.scss +89 -0
  133. package/src/theme/workspace.scss +9 -0
  134. package/src/type.ts +780 -0
  135. package/src/utils/compose.ts +52 -0
  136. package/src/utils/config.ts +29 -0
  137. package/src/utils/content-menu.ts +95 -0
  138. package/src/utils/data-source/formConfigs/base.ts +30 -0
  139. package/src/utils/data-source/formConfigs/http.ts +60 -0
  140. package/src/utils/data-source/index.ts +249 -0
  141. package/src/utils/editor.ts +313 -0
  142. package/src/utils/idle-task.ts +72 -0
  143. package/src/utils/index.ts +24 -0
  144. package/src/utils/keybinding-config.ts +125 -0
  145. package/src/utils/logger.ts +47 -0
  146. package/src/utils/monaco-editor.ts +8 -0
  147. package/src/utils/operator.ts +106 -0
  148. package/src/utils/props.ts +407 -0
  149. package/src/utils/scroll-viewer.ts +165 -0
  150. package/src/utils/tree.ts +15 -0
  151. package/src/utils/undo-redo.ts +76 -0
  152. package/types/editorProps.d.ts +3 -1
  153. package/types/fields/CondOpSelect.vue.d.ts +17 -0
  154. package/types/fields/DataSourceFieldSelect/FieldSelect.vue.d.ts +36 -0
  155. package/types/fields/{DataSourceFieldSelect.vue.d.ts → DataSourceFieldSelect/Index.vue.d.ts} +1 -1
  156. package/types/fields/DisplayConds.vue.d.ts +32 -0
  157. package/types/index.d.ts +3 -1
  158. package/types/layouts/Framework.vue.d.ts +3 -1
  159. package/types/layouts/PropsPanel.vue.d.ts +21 -21
  160. package/types/layouts/page-bar/PageBar.vue.d.ts +6 -0
  161. package/types/layouts/page-bar/PageBarScrollContainer.vue.d.ts +3 -0
  162. package/types/layouts/page-bar/PageList.vue.d.ts +25 -0
  163. package/types/services/ui.d.ts +1 -0
  164. package/types/type.d.ts +30 -4
  165. package/types/utils/data-source/index.d.ts +1 -0
  166. package/types/utils/props.d.ts +12 -0
package/package.json CHANGED
@@ -1,9 +1,8 @@
1
1
  {
2
- "version": "1.4.8",
2
+ "version": "1.4.10",
3
3
  "name": "@tmagic/editor",
4
4
  "type": "module",
5
5
  "sideEffects": [
6
- "dist/*",
7
6
  "src/theme/*"
8
7
  ],
9
8
  "main": "dist/tmagic-editor.umd.cjs",
@@ -24,7 +23,8 @@
24
23
  },
25
24
  "files": [
26
25
  "dist",
27
- "types"
26
+ "types",
27
+ "src"
28
28
  ],
29
29
  "license": "Apache-2.0",
30
30
  "engines": {
@@ -54,14 +54,16 @@
54
54
  "lodash-es": "^4.17.21",
55
55
  "moveable": "^0.53.0",
56
56
  "serialize-javascript": "^6.0.0",
57
- "@tmagic/dep": "1.4.8",
58
- "@tmagic/table": "1.4.8"
57
+ "sortablejs": "^1.15.2",
58
+ "@tmagic/dep": "1.4.10",
59
+ "@tmagic/table": "1.4.10"
59
60
  },
60
61
  "devDependencies": {
61
62
  "@types/events": "^3.0.0",
62
63
  "@types/lodash-es": "^4.17.4",
63
64
  "@types/node": "^18.19.0",
64
65
  "@types/serialize-javascript": "^5.0.1",
66
+ "@types/sortablejs": "^1.15.8",
65
67
  "@vitejs/plugin-vue": "^5.0.4",
66
68
  "@vue/compiler-sfc": "^3.4.27",
67
69
  "@vue/test-utils": "^2.4.6",
@@ -74,14 +76,14 @@
74
76
  },
75
77
  "peerDependencies": {
76
78
  "monaco-editor": "^0.48.0",
77
- "vue": "^3.4.27",
78
79
  "typescript": "*",
79
- "@tmagic/core": "1.4.8",
80
- "@tmagic/design": "1.4.8",
81
- "@tmagic/form": "1.4.8",
82
- "@tmagic/stage": "1.4.8",
83
- "@tmagic/schema": "1.4.8",
84
- "@tmagic/utils": "1.4.8"
80
+ "vue": "^3.4.27",
81
+ "@tmagic/core": "1.4.10",
82
+ "@tmagic/design": "1.4.10",
83
+ "@tmagic/schema": "1.4.10",
84
+ "@tmagic/form": "1.4.10",
85
+ "@tmagic/stage": "1.4.10",
86
+ "@tmagic/utils": "1.4.10"
85
87
  },
86
88
  "peerDependenciesMeta": {
87
89
  "typescript": {
package/src/Editor.vue ADDED
@@ -0,0 +1,212 @@
1
+ <template>
2
+ <Framework :disabled-page-fragment="disabledPageFragment" :page-bar-sort-options="pageBarSortOptions">
3
+ <template #header>
4
+ <slot name="header"></slot>
5
+ </template>
6
+
7
+ <template #nav>
8
+ <slot name="nav" :editorService="editorService"><TMagicNavMenu :data="menu"></TMagicNavMenu></slot>
9
+ </template>
10
+
11
+ <template #content-before>
12
+ <slot name="content-before"></slot>
13
+ </template>
14
+
15
+ <template #src-code><slot name="src-code" :editorService="editorService"></slot></template>
16
+
17
+ <template #sidebar>
18
+ <slot name="sidebar" :editorService="editorService">
19
+ <Sidebar :data="sidebar" :layer-content-menu="layerContentMenu" :custom-content-menu="customContentMenu">
20
+ <template #layer-panel-header>
21
+ <slot name="layer-panel-header"></slot>
22
+ </template>
23
+
24
+ <template #layer-node-content="{ data }">
25
+ <slot name="layer-node-content" :data="data"></slot>
26
+ </template>
27
+
28
+ <template #layer-node-label="{ data }">
29
+ <slot name="layer-node-label" :data="data"></slot>
30
+ </template>
31
+
32
+ <template #layer-node-tool="{ data }">
33
+ <slot name="layer-node-tool" :data="data"></slot>
34
+ </template>
35
+
36
+ <template #component-list-panel-header>
37
+ <slot name="component-list-panel-header"></slot>
38
+ </template>
39
+
40
+ <template #component-list-item="{ component }">
41
+ <slot name="component-list-item" :component="component"></slot>
42
+ </template>
43
+
44
+ <template #code-block-panel-header>
45
+ <slot name="code-block-panel-header"></slot>
46
+ </template>
47
+
48
+ <template #code-block-panel-tool="{ id, data }">
49
+ <slot name="code-block-panel-tool" :id="id" :data="data"></slot>
50
+ </template>
51
+
52
+ <template #code-block-panel-search>
53
+ <slot name="code-block-panel-search"></slot>
54
+ </template>
55
+
56
+ <template #data-source-panel-tool="{ data }">
57
+ <slot name="data-source-panel-tool" :data="data"></slot>
58
+ </template>
59
+
60
+ <template #data-source-panel-search>
61
+ <slot name="data-source-panel-search"></slot>
62
+ </template>
63
+ </Sidebar>
64
+ </slot>
65
+ </template>
66
+
67
+ <template #workspace>
68
+ <slot name="workspace" :editorService="editorService">
69
+ <Workspace
70
+ :disabled-stage-overlay="disabledStageOverlay"
71
+ :stage-content-menu="stageContentMenu"
72
+ :custom-content-menu="customContentMenu"
73
+ >
74
+ <template #stage><slot name="stage"></slot></template>
75
+ <template #workspace-content><slot name="workspace-content" :editorService="editorService"></slot></template>
76
+ </Workspace>
77
+ </slot>
78
+ </template>
79
+
80
+ <template #props-panel>
81
+ <slot name="props-panel">
82
+ <PropsPanel
83
+ :extend-state="extendFormState"
84
+ :disabled-show-src="disabledShowSrc"
85
+ @mounted="(instance: any) => $emit('props-panel-mounted', instance)"
86
+ @form-error="(e: any) => $emit('props-form-error', e)"
87
+ @submit-error="(e: any) => $emit('props-submit-error', e)"
88
+ >
89
+ <template #props-panel-header>
90
+ <slot name="props-panel-header"></slot>
91
+ </template>
92
+ </PropsPanel>
93
+ </slot>
94
+ </template>
95
+
96
+ <template #empty><slot name="empty" :editorService="editorService"></slot></template>
97
+
98
+ <template #content-after>
99
+ <slot name="content-after"></slot>
100
+ </template>
101
+
102
+ <template #footer>
103
+ <slot name="footer"></slot>
104
+ </template>
105
+
106
+ <template #page-bar><slot name="page-bar"></slot></template>
107
+ <template #page-bar-title="{ page }"><slot name="page-bar-title" :page="page"></slot></template>
108
+ <template #page-bar-popover="{ page }"><slot name="page-bar-popover" :page="page"></slot></template>
109
+ <template #page-list-popover="{ list }"><slot name="page-list-popover" :list="list"></slot></template>
110
+ </Framework>
111
+ </template>
112
+
113
+ <script lang="ts" setup>
114
+ import { EventEmitter } from 'events';
115
+
116
+ import { provide } from 'vue';
117
+
118
+ import type { MApp } from '@tmagic/schema';
119
+
120
+ import Framework from './layouts/Framework.vue';
121
+ import TMagicNavMenu from './layouts/NavMenu.vue';
122
+ import PropsPanel from './layouts/PropsPanel.vue';
123
+ import Sidebar from './layouts/sidebar/Sidebar.vue';
124
+ import Workspace from './layouts/workspace/Workspace.vue';
125
+ import codeBlockService from './services/codeBlock';
126
+ import componentListService from './services/componentList';
127
+ import dataSourceService from './services/dataSource';
128
+ import depService from './services/dep';
129
+ import editorService, { type EditorService } from './services/editor';
130
+ import eventsService from './services/events';
131
+ import historyService from './services/history';
132
+ import keybindingService from './services/keybinding';
133
+ import propsService from './services/props';
134
+ import stageOverlayService from './services/stageOverlay';
135
+ import storageService from './services/storage';
136
+ import uiService from './services/ui';
137
+ import keybindingConfig from './utils/keybinding-config';
138
+ import { defaultEditorProps, EditorProps } from './editorProps';
139
+ import { initServiceEvents, initServiceState } from './initService';
140
+ import type { EventBus, FrameworkSlots, PropsPanelSlots, Services, SidebarSlots, WorkspaceSlots } from './type';
141
+
142
+ defineSlots<
143
+ FrameworkSlots &
144
+ WorkspaceSlots &
145
+ SidebarSlots &
146
+ PropsPanelSlots & {
147
+ workspace(props: { editorService: EditorService }): any;
148
+ 'workspace-content'(props: { editorService: EditorService }): any;
149
+ }
150
+ >();
151
+
152
+ defineOptions({
153
+ name: 'MEditor',
154
+ });
155
+
156
+ const emit = defineEmits<{
157
+ 'props-panel-mounted': [instance: InstanceType<typeof PropsPanel>];
158
+ 'update:modelValue': [value: MApp | null];
159
+ 'props-form-error': [e: any];
160
+ 'props-submit-error': [e: any];
161
+ }>();
162
+
163
+ const props = withDefaults(defineProps<EditorProps>(), defaultEditorProps);
164
+
165
+ const services: Services = {
166
+ componentListService,
167
+ eventsService,
168
+ historyService,
169
+ propsService,
170
+ editorService,
171
+ uiService,
172
+ storageService,
173
+ codeBlockService,
174
+ depService,
175
+ dataSourceService,
176
+ keybindingService,
177
+ stageOverlayService,
178
+ };
179
+
180
+ initServiceEvents(props, emit, services);
181
+ initServiceState(props, services);
182
+ keybindingService.register(keybindingConfig);
183
+ keybindingService.registerEl('global');
184
+
185
+ const stageOptions = {
186
+ runtimeUrl: props.runtimeUrl,
187
+ autoScrollIntoView: props.autoScrollIntoView,
188
+ render: props.render,
189
+ moveableOptions: props.moveableOptions,
190
+ canSelect: props.canSelect,
191
+ updateDragEl: props.updateDragEl,
192
+ isContainer: props.isContainer,
193
+ containerHighlightClassName: props.containerHighlightClassName,
194
+ containerHighlightDuration: props.containerHighlightDuration,
195
+ containerHighlightType: props.containerHighlightType,
196
+ disabledDragStart: props.disabledDragStart,
197
+ renderType: props.renderType,
198
+ guidesOptions: props.guidesOptions,
199
+ disabledMultiSelect: props.disabledMultiSelect,
200
+ };
201
+
202
+ stageOverlayService.set('stageOptions', stageOptions);
203
+
204
+ provide('services', services);
205
+
206
+ provide('codeOptions', props.codeOptions);
207
+ provide('stageOptions', stageOptions);
208
+
209
+ provide<EventBus>('eventBus', new EventEmitter());
210
+
211
+ defineExpose(services);
212
+ </script>
@@ -0,0 +1,268 @@
1
+ <template>
2
+ <!-- 代码块编辑区 -->
3
+ <FloatingBox
4
+ v-model:visible="boxVisible"
5
+ v-model:width="width"
6
+ v-model:height="codeBlockEditorHeight"
7
+ :title="content.name ? `${disabled ? '查看' : '编辑'}${content.name}` : '新增代码'"
8
+ :position="boxPosition"
9
+ :before-close="beforeClose"
10
+ >
11
+ <template #body>
12
+ <MFormBox
13
+ class="m-editor-code-block-editor"
14
+ ref="formBox"
15
+ label-width="80px"
16
+ :close-on-press-escape="false"
17
+ :title="content.name"
18
+ :config="functionConfig"
19
+ :values="content"
20
+ :disabled="disabled"
21
+ style="height: 100%"
22
+ @change="changeHandler"
23
+ @submit="submitForm"
24
+ @error="errorHandler"
25
+ @closed="closedHandler"
26
+ >
27
+ <template #left>
28
+ <TMagicButton v-if="!disabled" type="primary" link @click="difVisible = true">查看修改</TMagicButton>
29
+ </template>
30
+ </MFormBox>
31
+ </template>
32
+ </FloatingBox>
33
+
34
+ <Teleport to="body">
35
+ <TMagicDialog title="查看修改" v-model="difVisible" fullscreen>
36
+ <div style="display: flex; margin-bottom: 10px">
37
+ <div style="flex: 1"><TMagicTag size="small" type="info">修改前</TMagicTag></div>
38
+ <div style="flex: 1"><TMagicTag size="small" type="success">修改后</TMagicTag></div>
39
+ </div>
40
+
41
+ <CodeEditor
42
+ v-if="difVisible"
43
+ ref="magicVsEditor"
44
+ type="diff"
45
+ language="json"
46
+ :initValues="content.content"
47
+ :modifiedValues="formBox?.form?.values.content"
48
+ :style="`height: ${windowRect.height - 150}px`"
49
+ ></CodeEditor>
50
+
51
+ <template #footer>
52
+ <span class="dialog-footer">
53
+ <TMagicButton size="small" @click="difVisible = false">取消</TMagicButton>
54
+ <TMagicButton size="small" type="primary" @click="diffChange">确定</TMagicButton>
55
+ </span>
56
+ </template>
57
+ </TMagicDialog>
58
+ </Teleport>
59
+ </template>
60
+
61
+ <script lang="ts" setup>
62
+ import { computed, inject, Ref, ref } from 'vue';
63
+
64
+ import { TMagicButton, TMagicDialog, tMagicMessage, tMagicMessageBox, TMagicTag } from '@tmagic/design';
65
+ import { ColumnConfig, FormConfig, FormState, MFormBox } from '@tmagic/form';
66
+ import type { CodeBlockContent } from '@tmagic/schema';
67
+
68
+ import FloatingBox from '@editor/components/FloatingBox.vue';
69
+ import { useEditorContentHeight } from '@editor/hooks/use-editor-content-height';
70
+ import { useNextFloatBoxPosition } from '@editor/hooks/use-next-float-box-position';
71
+ import { useWindowRect } from '@editor/hooks/use-window-rect';
72
+ import CodeEditor from '@editor/layouts/CodeEditor.vue';
73
+ import type { Services } from '@editor/type';
74
+ import { getConfig } from '@editor/utils/config';
75
+
76
+ defineOptions({
77
+ name: 'MEditorCodeBlockEditor',
78
+ });
79
+
80
+ const width = defineModel<number>('width', { default: 670 });
81
+ const boxVisible = defineModel<boolean>('visible', { default: false });
82
+
83
+ const props = defineProps<{
84
+ content: CodeBlockContent;
85
+ disabled?: boolean;
86
+ isDataSource?: boolean;
87
+ dataSourceType?: string;
88
+ }>();
89
+
90
+ const emit = defineEmits<{
91
+ submit: [values: CodeBlockContent];
92
+ }>();
93
+
94
+ const services = inject<Services>('services');
95
+
96
+ const { height: codeBlockEditorHeight } = useEditorContentHeight();
97
+
98
+ const difVisible = ref(false);
99
+ const { rect: windowRect } = useWindowRect();
100
+
101
+ const magicVsEditor = ref<InstanceType<typeof CodeEditor>>();
102
+
103
+ const diffChange = () => {
104
+ if (!magicVsEditor.value || !formBox.value?.form) {
105
+ return;
106
+ }
107
+
108
+ formBox.value.form.values.content = magicVsEditor.value.getEditorValue();
109
+
110
+ difVisible.value = false;
111
+ };
112
+
113
+ const defaultParamColConfig: ColumnConfig = {
114
+ type: 'row',
115
+ label: '参数类型',
116
+ items: [
117
+ {
118
+ text: '参数类型',
119
+ labelWidth: '70px',
120
+ type: 'select',
121
+ name: 'type',
122
+ options: [
123
+ {
124
+ text: '数字',
125
+ label: '数字',
126
+ value: 'number',
127
+ },
128
+ {
129
+ text: '字符串',
130
+ label: '字符串',
131
+ value: 'text',
132
+ },
133
+ {
134
+ text: '组件',
135
+ label: '组件',
136
+ value: 'ui-select',
137
+ },
138
+ ],
139
+ },
140
+ ],
141
+ };
142
+
143
+ const functionConfig = computed<FormConfig>(() => [
144
+ {
145
+ text: '名称',
146
+ name: 'name',
147
+ rules: [{ required: true, message: '请输入名称', trigger: 'blur' }],
148
+ },
149
+ {
150
+ text: '描述',
151
+ name: 'desc',
152
+ },
153
+ {
154
+ text: '执行时机',
155
+ name: 'timing',
156
+ type: 'select',
157
+ options: () => {
158
+ const options = [
159
+ { text: '初始化前', value: 'beforeInit' },
160
+ { text: '初始化后', value: 'afterInit' },
161
+ ];
162
+ if (props.dataSourceType !== 'base') {
163
+ options.push({ text: '请求前', value: 'beforeRequest' });
164
+ options.push({ text: '请求后', value: 'afterRequest' });
165
+ }
166
+ return options;
167
+ },
168
+ display: () => props.isDataSource,
169
+ },
170
+ {
171
+ type: 'table',
172
+ border: true,
173
+ text: '参数',
174
+ enableFullscreen: false,
175
+ enableToggleMode: false,
176
+ name: 'params',
177
+ dropSort: false,
178
+ items: [
179
+ {
180
+ type: 'text',
181
+ label: '参数名',
182
+ name: 'name',
183
+ },
184
+ {
185
+ type: 'text',
186
+ label: '描述',
187
+ name: 'extra',
188
+ },
189
+ services?.codeBlockService.getParamsColConfig() || defaultParamColConfig,
190
+ ],
191
+ },
192
+ {
193
+ name: 'content',
194
+ type: 'vs-code',
195
+ options: inject('codeOptions', {}),
196
+ height: '500px',
197
+ onChange: (formState: FormState | undefined, code: string) => {
198
+ try {
199
+ // 检测js代码是否存在语法错误
200
+ getConfig('parseDSL')(code);
201
+
202
+ return code;
203
+ } catch (error: any) {
204
+ tMagicMessage.error(error.message);
205
+
206
+ throw error;
207
+ }
208
+ },
209
+ },
210
+ ]);
211
+
212
+ const submitForm = (values: CodeBlockContent) => {
213
+ changedValue.value = undefined;
214
+ emit('submit', values);
215
+ };
216
+
217
+ const errorHandler = (error: any) => {
218
+ tMagicMessage.error(error.message);
219
+ };
220
+
221
+ const formBox = ref<InstanceType<typeof MFormBox>>();
222
+
223
+ const changedValue = ref<CodeBlockContent>();
224
+ const changeHandler = (values: CodeBlockContent) => {
225
+ changedValue.value = values;
226
+ };
227
+
228
+ const beforeClose = (done: (cancel?: boolean) => void) => {
229
+ if (!changedValue.value) {
230
+ done();
231
+ return;
232
+ }
233
+ tMagicMessageBox
234
+ .confirm('当前代码块已修改,是否保存?', '提示', {
235
+ confirmButtonText: '保存并关闭',
236
+ cancelButtonText: '不保存并关闭',
237
+ type: 'warning',
238
+ distinguishCancelAndClose: true,
239
+ })
240
+ .then(() => {
241
+ changedValue.value && submitForm(changedValue.value);
242
+ done();
243
+ })
244
+ .catch((action: string) => {
245
+ if (action === 'cancel') {
246
+ }
247
+ done(action === 'cancel');
248
+ });
249
+ };
250
+
251
+ const closedHandler = () => {
252
+ changedValue.value = undefined;
253
+ };
254
+
255
+ const parentFloating = inject<Ref<HTMLDivElement | null>>('parentFloating', ref(null));
256
+ const { boxPosition, calcBoxPosition } = useNextFloatBoxPosition(services?.uiService, parentFloating);
257
+
258
+ defineExpose({
259
+ async show() {
260
+ calcBoxPosition();
261
+ boxVisible.value = true;
262
+ },
263
+
264
+ async hide() {
265
+ boxVisible.value = false;
266
+ },
267
+ });
268
+ </script>
@@ -0,0 +1,60 @@
1
+ <template>
2
+ <MForm
3
+ ref="form"
4
+ :config="codeParamsConfig"
5
+ :init-values="model"
6
+ :disabled="disabled"
7
+ :size="size"
8
+ :watch-props="false"
9
+ @change="onParamsChangeHandler"
10
+ ></MForm>
11
+ </template>
12
+
13
+ <script lang="ts" setup>
14
+ import { computed, ref } from 'vue';
15
+
16
+ import { FormConfig, MForm } from '@tmagic/form';
17
+
18
+ import type { CodeParamStatement } from '@editor/type';
19
+ import { error } from '@editor/utils';
20
+
21
+ defineOptions({
22
+ name: 'MEditorCodeParams',
23
+ });
24
+
25
+ const props = defineProps<{
26
+ model: any;
27
+ size?: 'small' | 'default' | 'large';
28
+ disabled?: boolean;
29
+ name: string;
30
+ paramsConfig: CodeParamStatement[];
31
+ }>();
32
+
33
+ const emit = defineEmits(['change']);
34
+
35
+ const form = ref<InstanceType<typeof MForm>>();
36
+
37
+ const getFormConfig = (items: FormConfig = []) => [
38
+ {
39
+ type: 'fieldset',
40
+ items,
41
+ legend: '参数',
42
+ labelWidth: '70px',
43
+ name: props.name,
44
+ },
45
+ ];
46
+
47
+ const codeParamsConfig = computed(() => getFormConfig(props.paramsConfig));
48
+
49
+ /**
50
+ * 参数值修改更新
51
+ */
52
+ const onParamsChangeHandler = async () => {
53
+ try {
54
+ const value = await form.value?.submitForm(true);
55
+ emit('change', value);
56
+ } catch (e) {
57
+ error(e);
58
+ }
59
+ };
60
+ </script>