@tmagic/editor 1.3.1 → 1.3.3

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 (51) hide show
  1. package/dist/style.css +50 -0
  2. package/dist/tmagic-editor.js +578 -574
  3. package/dist/tmagic-editor.js.map +1 -1
  4. package/dist/tmagic-editor.umd.cjs +590 -585
  5. package/dist/tmagic-editor.umd.cjs.map +1 -1
  6. package/package.json +15 -13
  7. package/src/components/CodeBlockEditor.vue +6 -4
  8. package/src/fields/DataSourceSelect.vue +15 -9
  9. package/src/hooks/index.ts +1 -0
  10. package/src/hooks/use-code-block-edit.ts +2 -0
  11. package/src/hooks/use-float-box.ts +153 -0
  12. package/src/index.ts +1 -0
  13. package/src/initService.ts +12 -11
  14. package/src/layouts/Framework.vue +10 -1
  15. package/src/layouts/sidebar/Sidebar.vue +90 -5
  16. package/src/layouts/sidebar/code-block/CodeBlockList.vue +2 -1
  17. package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +11 -10
  18. package/src/layouts/sidebar/data-source/DataSourceConfigPanel.vue +6 -4
  19. package/src/layouts/sidebar/data-source/DataSourceList.vue +9 -8
  20. package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +15 -15
  21. package/src/layouts/sidebar/layer/use-drag.ts +4 -0
  22. package/src/layouts/sidebar/layer/use-node-status.ts +20 -15
  23. package/src/services/dataSource.ts +4 -0
  24. package/src/services/dep.ts +22 -284
  25. package/src/services/ui.ts +15 -0
  26. package/src/theme/code-block.scss +5 -0
  27. package/src/theme/floatbox.scss +48 -0
  28. package/src/theme/sidebar.scss +1 -0
  29. package/src/theme/theme.scss +1 -0
  30. package/src/type.ts +30 -20
  31. package/types/components/CodeBlockEditor.vue.d.ts +3 -0
  32. package/types/fields/DataSourceSelect.vue.d.ts +6 -4
  33. package/types/hooks/index.d.ts +1 -0
  34. package/types/hooks/use-code-block-edit.d.ts +26 -46
  35. package/types/hooks/use-data-source-method.d.ts +26 -46
  36. package/types/hooks/use-float-box.d.ts +15 -0
  37. package/types/index.d.ts +1 -0
  38. package/types/layouts/PropsPanel.vue.d.ts +92 -59
  39. package/types/layouts/sidebar/Sidebar.vue.d.ts +1 -2
  40. package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +1 -1
  41. package/types/layouts/sidebar/code-block/CodeBlockListPanel.vue.d.ts +3 -1
  42. package/types/layouts/sidebar/data-source/DataSourceConfigPanel.vue.d.ts +3 -0
  43. package/types/layouts/sidebar/data-source/DataSourceList.vue.d.ts +1 -1
  44. package/types/layouts/sidebar/data-source/DataSourceListPanel.vue.d.ts +15 -2
  45. package/types/layouts/sidebar/layer/use-click.d.ts +7 -46
  46. package/types/services/dataSource.d.ts +10 -2
  47. package/types/services/dep.d.ts +12 -112
  48. package/types/services/ui.d.ts +8 -0
  49. package/types/type.d.ts +23 -18
  50. package/src/utils/dep.ts +0 -81
  51. package/types/utils/dep.d.ts +0 -6
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.3.1",
2
+ "version": "1.3.3",
3
3
  "name": "@tmagic/editor",
4
4
  "type": "module",
5
5
  "sideEffects": [
@@ -47,13 +47,14 @@
47
47
  "dependencies": {
48
48
  "@babel/core": "^7.18.0",
49
49
  "@element-plus/icons-vue": "^2.0.9",
50
- "@tmagic/core": "1.3.1",
51
- "@tmagic/design": "1.3.1",
52
- "@tmagic/form": "1.3.1",
53
- "@tmagic/schema": "1.3.1",
54
- "@tmagic/stage": "1.3.1",
55
- "@tmagic/table": "1.3.1",
56
- "@tmagic/utils": "1.3.1",
50
+ "@tmagic/core": "1.3.3",
51
+ "@tmagic/dep": "1.3.3",
52
+ "@tmagic/design": "1.3.3",
53
+ "@tmagic/form": "1.3.3",
54
+ "@tmagic/schema": "1.3.3",
55
+ "@tmagic/stage": "1.3.3",
56
+ "@tmagic/table": "1.3.3",
57
+ "@tmagic/utils": "1.3.3",
57
58
  "buffer": "^6.0.3",
58
59
  "color": "^3.1.3",
59
60
  "events": "^3.3.0",
@@ -61,14 +62,15 @@
61
62
  "keycon": "^1.4.0",
62
63
  "lodash-es": "^4.17.21",
63
64
  "monaco-editor": "^0.41.0",
65
+ "moveable": "^0.51.1",
64
66
  "serialize-javascript": "^6.0.0",
65
- "vue": "^3.3.4"
67
+ "vue": "^3.3.8"
66
68
  },
67
69
  "peerDependencies": {
68
- "@tmagic/design": "1.3.1",
69
- "@tmagic/form": "1.3.1",
70
+ "@tmagic/design": "1.3.3",
71
+ "@tmagic/form": "1.3.3",
70
72
  "monaco-editor": "^0.41.0",
71
- "vue": "^3.3.4"
73
+ "vue": "^3.3.8"
72
74
  },
73
75
  "devDependencies": {
74
76
  "@types/events": "^3.0.0",
@@ -76,7 +78,7 @@
76
78
  "@types/node": "^15.12.4",
77
79
  "@types/serialize-javascript": "^5.0.1",
78
80
  "@vitejs/plugin-vue": "^4.2.3",
79
- "@vue/compiler-sfc": "^3.3.4",
81
+ "@vue/compiler-sfc": "^3.3.8",
80
82
  "@vue/test-utils": "^2.3.2",
81
83
  "rimraf": "^3.0.2",
82
84
  "sass": "^1.35.1",
@@ -1,5 +1,6 @@
1
1
  <template>
2
- <MFormDrawer
2
+ <component
3
+ :is="slideType === 'box' ? MFormBox : MFormDrawer"
3
4
  class="m-editor-code-block-editor"
4
5
  ref="fomDrawer"
5
6
  label-width="80px"
@@ -19,7 +20,7 @@
19
20
  <template #left>
20
21
  <TMagicButton type="primary" text @click="difVisible = true">查看修改</TMagicButton>
21
22
  </template>
22
- </MFormDrawer>
23
+ </component>
23
24
 
24
25
  <TMagicDialog v-model="difVisible" title="查看修改" fullscreen>
25
26
  <div style="display: flex; margin-bottom: 10px">
@@ -50,11 +51,11 @@
50
51
  import { computed, inject, onUnmounted, ref } from 'vue';
51
52
 
52
53
  import { TMagicButton, TMagicDialog, tMagicMessage, tMagicMessageBox, TMagicTag } from '@tmagic/design';
53
- import { ColumnConfig, FormConfig, FormState, MFormDrawer } from '@tmagic/form';
54
+ import { ColumnConfig, FormConfig, FormState, MFormBox, MFormDrawer } from '@tmagic/form';
54
55
  import type { CodeBlockContent } from '@tmagic/schema';
55
56
 
56
57
  import CodeEditor from '@editor/layouts/CodeEditor.vue';
57
- import type { Services } from '@editor/type';
58
+ import type { Services, SlideType } from '@editor/type';
58
59
  import { getConfig } from '@editor/utils/config';
59
60
 
60
61
  defineOptions({
@@ -66,6 +67,7 @@ const props = defineProps<{
66
67
  disabled?: boolean;
67
68
  isDataSource?: boolean;
68
69
  dataSourceType?: string;
70
+ slideType?: SlideType;
69
71
  }>();
70
72
 
71
73
  const emit = defineEmits<{
@@ -29,9 +29,10 @@ const props = withDefaults(
29
29
  FieldProps<{
30
30
  type: 'data-source-select';
31
31
  name: string;
32
- text: string;
33
- placeholder: string;
32
+ text?: string;
33
+ placeholder?: string;
34
34
  dataSourceType?: string;
35
+ value?: 'id' | 'value';
35
36
  }>
36
37
  >(),
37
38
  {
@@ -44,19 +45,24 @@ const { dataSourceService } = inject<Services>('services') || {};
44
45
  const dataSources = computed(() => dataSourceService?.get('dataSources') || []);
45
46
 
46
47
  const selectConfig = computed<SelectConfig>(() => {
47
- const { type, dataSourceType, ...config } = props.config;
48
+ const { type, dataSourceType, value, ...config } = props.config;
49
+
50
+ const valueIsId = props.config.value === 'id';
51
+
48
52
  return {
49
53
  ...config,
50
54
  type: 'select',
51
55
  valueKey: 'dataSourceId',
52
56
  options: dataSources.value
53
- .filter((ds) => !dataSourceType || ds.type === dataSourceType)
57
+ .filter((ds) => !props.config.dataSourceType || ds.type === props.config.dataSourceType)
54
58
  .map((ds) => ({
55
- value: {
56
- isBindDataSource: true,
57
- dataSourceType: ds.type,
58
- dataSourceId: ds.id,
59
- },
59
+ value: valueIsId
60
+ ? ds.id
61
+ : {
62
+ isBindDataSource: true,
63
+ dataSourceType: ds.type,
64
+ dataSourceId: ds.id,
65
+ },
60
66
  text: ds.title || ds.id,
61
67
  })),
62
68
  };
@@ -19,3 +19,4 @@
19
19
  export * from './use-code-block-edit';
20
20
  export * from './use-data-source-method';
21
21
  export * from './use-stage';
22
+ export * from './use-float-box';
@@ -68,6 +68,8 @@ export const useCodeBlockEdit = (codeBlockService?: CodeBlockService) => {
68
68
 
69
69
  await codeBlockService?.setCodeDslById(codeId.value, values);
70
70
 
71
+ tMagicMessage.success('代码块保存成功');
72
+
71
73
  codeBlockEditor.value?.hide();
72
74
  };
73
75
 
@@ -0,0 +1,153 @@
1
+ import { computed, ComputedRef, inject, nextTick, ref, watch } from 'vue';
2
+ import Moveable from 'moveable';
3
+
4
+ import { type Services } from '@editor/type';
5
+
6
+ export const useFloatBox = (slideKeys: ComputedRef<string[]>) => {
7
+ const services = inject<Services>('services');
8
+ const moveable = ref<Moveable>();
9
+ const floatBox = ref<HTMLElement[]>();
10
+
11
+ const floatBoxStates = computed(() => services?.uiService.get('floatBox'));
12
+
13
+ const curKey = ref('');
14
+ const target = computed(() =>
15
+ floatBox.value
16
+ ? floatBox.value.find((item) => item.classList.contains(`m-editor-float-box-${curKey.value}`))
17
+ : undefined,
18
+ );
19
+
20
+ const showingBoxKeys = computed(() =>
21
+ [...(floatBoxStates.value?.keys() ?? [])].filter((key) => floatBoxStates.value?.get(key)?.status),
22
+ );
23
+
24
+ const isDraging = ref(false);
25
+
26
+ const showFloatBox = async (key: string) => {
27
+ const curBoxStatus = floatBoxStates.value?.get(curKey.value)?.status;
28
+ if (curKey.value === key && curBoxStatus) return;
29
+ curKey.value = key;
30
+ setSlideState(key, {
31
+ zIndex: getMaxZIndex() + 1,
32
+ status: true,
33
+ });
34
+
35
+ await nextTick();
36
+ if (moveable.value) {
37
+ moveable.value.target = target.value;
38
+ moveable.value.dragTarget = getDragTarget();
39
+ moveable.value.updateRect();
40
+ } else {
41
+ initFloatBoxMoveable();
42
+ }
43
+ };
44
+
45
+ const setSlideState = (key: string, data: Record<string, string | number | boolean>) => {
46
+ const slideState = floatBoxStates.value?.get(key);
47
+ if (!slideState) return;
48
+ floatBoxStates.value?.set(key, {
49
+ ...slideState,
50
+ ...data,
51
+ });
52
+ };
53
+
54
+ const getDragTarget = (key?: string) => `.m-editor-float-box-header-${key ?? curKey.value}`;
55
+
56
+ const closeFloatBox = (key: string) => {
57
+ setSlideState(key, {
58
+ status: false,
59
+ });
60
+
61
+ // 如果只有一个,关掉后需要销毁moveable实例
62
+ if (!floatBoxStates.value?.values) return;
63
+ const keys = [...floatBoxStates.value?.keys()];
64
+ const values = [...floatBoxStates.value?.values()];
65
+ const lastFloatBoxLen = values.filter((state) => state.status).length;
66
+ if (lastFloatBoxLen === 0) {
67
+ moveable.value?.destroy();
68
+ moveable.value = undefined;
69
+ return;
70
+ }
71
+
72
+ // 如果关掉的 box 是最大的,需要选中下面的一层
73
+ if (key === curKey.value) {
74
+ // 查找显示的最大 zIndex 对应的 index
75
+ const zIndexList = values.filter((item) => item.status).map((item) => item.zIndex);
76
+ const maxZIndex = Math.max(...zIndexList);
77
+ const key = keys.find((key) => floatBoxStates.value?.get(key)?.zIndex === maxZIndex);
78
+ if (!key) return;
79
+ showFloatBox(key);
80
+ }
81
+ };
82
+
83
+ const getMaxZIndex = () => {
84
+ if (!floatBoxStates.value?.values()) return 0;
85
+ const list = [...floatBoxStates.value?.values()].map((state) => state.zIndex);
86
+ return Math.max(...list) ?? 0;
87
+ };
88
+
89
+ const initFloatBoxMoveable = () => {
90
+ const dragTarget = getDragTarget();
91
+ moveable.value = new Moveable(document.body, {
92
+ target: target.value,
93
+ draggable: true,
94
+ resizable: true,
95
+ edge: true,
96
+ keepRatio: false,
97
+ origin: false,
98
+ snappable: true,
99
+ dragTarget,
100
+ dragTargetSelf: false,
101
+ linePadding: 10,
102
+ controlPadding: 10,
103
+ elementGuidelines: [...(floatBoxStates.value?.keys() ?? [])].map((key) => getDragTarget(key)),
104
+ bounds: { left: 0, top: 0, right: 0, bottom: 0, position: 'css' },
105
+ });
106
+ moveable.value.on('drag', (e) => {
107
+ e.target.style.transform = e.transform;
108
+ });
109
+ moveable.value.on('resize', (e) => {
110
+ e.target.style.width = `${e.width}px`;
111
+ e.target.style.height = `${e.height}px`;
112
+ e.target.style.transform = e.drag.transform;
113
+ });
114
+ };
115
+
116
+ const dragendHandler = (key: string, e: DragEvent) => {
117
+ setSlideState(key, {
118
+ left: e.clientX,
119
+ top: e.clientY,
120
+ });
121
+ showFloatBox(key);
122
+ isDraging.value = false;
123
+ };
124
+
125
+ document.body.addEventListener('dragover', (e: DragEvent) => {
126
+ if (!isDraging.value) return;
127
+ e.preventDefault();
128
+ });
129
+
130
+ const dragstartHandler = () => (isDraging.value = true);
131
+
132
+ // 监听 slide 长度变化,更新 ui serice map
133
+ watch(
134
+ () => slideKeys.value,
135
+ () => {
136
+ services?.uiService.setFloatBox(slideKeys.value);
137
+ },
138
+ {
139
+ deep: true,
140
+ immediate: true,
141
+ },
142
+ );
143
+
144
+ return {
145
+ showFloatBox,
146
+ closeFloatBox,
147
+ dragstartHandler,
148
+ dragendHandler,
149
+ floatBoxStates,
150
+ floatBox,
151
+ showingBoxKeys,
152
+ };
153
+ };
package/src/index.ts CHANGED
@@ -40,6 +40,7 @@ import './theme/index.scss';
40
40
 
41
41
  export type { OnDrag } from 'gesto';
42
42
 
43
+ export { DepTargetType } from '@tmagic/dep';
43
44
  export type { MoveableOptions } from '@tmagic/stage';
44
45
  export * from './type';
45
46
  export * from './hooks';
@@ -1,20 +1,21 @@
1
- import { onUnmounted, toRaw, watch } from 'vue';
1
+ import { onUnmounted, reactive, toRaw, watch } from 'vue';
2
2
  import { cloneDeep } from 'lodash-es';
3
3
 
4
4
  import type { EventOption } from '@tmagic/core';
5
- import type { CodeBlockContent, DataSourceSchema, Id, MApp, MNode, MPage } from '@tmagic/schema';
6
- import { getNodes } from '@tmagic/utils';
7
-
8
- import PropsPanel from './layouts/PropsPanel.vue';
9
- import type { Target } from './services/dep';
5
+ import type { Target } from '@tmagic/dep';
10
6
  import {
11
7
  createCodeBlockTarget,
12
8
  createDataSourceCondTarget,
13
9
  createDataSourceMethodTarget,
14
10
  createDataSourceTarget,
15
- } from './utils/dep';
11
+ DepTargetType,
12
+ } from '@tmagic/dep';
13
+ import type { CodeBlockContent, DataSourceSchema, Id, MApp, MNode, MPage } from '@tmagic/schema';
14
+ import { getNodes } from '@tmagic/utils';
15
+
16
+ import PropsPanel from './layouts/PropsPanel.vue';
16
17
  import { EditorProps } from './editorProps';
17
- import { DepTargetType, Services } from './type';
18
+ import { Services } from './type';
18
19
 
19
20
  export declare type LooseRequired<T> = {
20
21
  [P in string & keyof T]: T[P];
@@ -270,9 +271,9 @@ export const initServiceEvents = (
270
271
  depService.on('collected', collectedHandler);
271
272
 
272
273
  const initDataSourceDepTarget = (ds: DataSourceSchema) => {
273
- depService.addTarget(createDataSourceTarget(ds.id));
274
- depService.addTarget(createDataSourceMethodTarget(ds.id));
275
- depService.addTarget(createDataSourceCondTarget(ds.id));
274
+ depService.addTarget(createDataSourceTarget(ds, reactive({})));
275
+ depService.addTarget(createDataSourceMethodTarget(ds, reactive({})));
276
+ depService.addTarget(createDataSourceCondTarget(ds, reactive({})));
276
277
  };
277
278
 
278
279
  const rootChangeHandler = async (value: MApp | null, preValue?: MApp | null) => {
@@ -82,8 +82,10 @@ const showSrc = computed(() => uiService?.get('showSrc'));
82
82
  const LEFT_COLUMN_WIDTH_STORAGE_KEY = '$MagicEditorLeftColumnWidthData';
83
83
  const RIGHT_COLUMN_WIDTH_STORAGE_KEY = '$MagicEditorRightColumnWidthData';
84
84
 
85
- const leftColumnWidthCacheData =
85
+ const getLeftColumnWidthCacheData = () =>
86
86
  Number(globalThis.localStorage.getItem(LEFT_COLUMN_WIDTH_STORAGE_KEY)) || DEFAULT_LEFT_COLUMN_WIDTH;
87
+
88
+ const leftColumnWidthCacheData = getLeftColumnWidthCacheData();
87
89
  const RightColumnWidthCacheData =
88
90
  Number(globalThis.localStorage.getItem(RIGHT_COLUMN_WIDTH_STORAGE_KEY)) || DEFAULT_RIGHT_COLUMN_WIDTH;
89
91
 
@@ -118,6 +120,13 @@ watch(
118
120
  },
119
121
  );
120
122
 
123
+ watch(
124
+ () => uiService?.get('hideSlideBar'),
125
+ (hideSlideBar) => {
126
+ columnWidth.value.left = hideSlideBar ? 0 : getLeftColumnWidthCacheData();
127
+ },
128
+ );
129
+
121
130
  const columnWidthChange = (columnW: GetColumnWidth) => {
122
131
  columnWidth.value.left = columnW.left;
123
132
  columnWidth.value.center = columnW.center;
@@ -7,6 +7,10 @@
7
7
  :key="config.$key ?? index"
8
8
  :class="{ 'is-active': activeTabName === config.text }"
9
9
  @click="activeTabName = config.text || `${index}`"
10
+ draggable="true"
11
+ @dragstart="dragstartHandler"
12
+ @dragend="dragendHandler(config.$key, $event)"
13
+ v-show="!floatBoxStates?.get(config.$key)?.status"
10
14
  >
11
15
  <MIcon v-if="config.icon" :icon="config.icon"></MIcon>
12
16
  <div v-if="config.text" class="magic-editor-tab-panel-title">{{ config.text }}</div>
@@ -18,7 +22,12 @@
18
22
  :key="config.$key ?? index"
19
23
  v-show="activeTabName === config.text"
20
24
  >
21
- <component v-if="config" :is="config.component" v-bind="config.props || {}" v-on="config?.listeners || {}">
25
+ <component
26
+ v-if="config && !floatBoxStates?.get(config.$key)?.status"
27
+ :is="config.component"
28
+ v-bind="config.props || {}"
29
+ v-on="config?.listeners || {}"
30
+ >
22
31
  <template
23
32
  #component-list-panel-header
24
33
  v-if="config.$key === 'component-list' || config.slots?.componentListPanelHeader"
@@ -80,15 +89,56 @@
80
89
  </component>
81
90
  </div>
82
91
  </div>
92
+
93
+ <Teleport to="body">
94
+ <div class="m-editor-float-box-list">
95
+ <div
96
+ v-for="(config, index) in sideBarItems"
97
+ :key="config.$key ?? index"
98
+ ref="floatBox"
99
+ :class="['m-editor-float-box', `m-editor-float-box-${config.$key}`]"
100
+ :style="{
101
+ left: `${floatBoxStates?.get(config.$key)?.left}px`,
102
+ top: `${floatBoxStates?.get(config.$key)?.top}px`,
103
+ zIndex: floatBoxStates?.get(config.$key)?.zIndex,
104
+ }"
105
+ v-show="floatBoxStates?.get(config.$key)?.status"
106
+ >
107
+ <div
108
+ :class="['m-editor-float-box-header', `m-editor-float-box-header-${config.$key}`]"
109
+ @click="showFloatBox(config.$key)"
110
+ >
111
+ <div>{{ config.text }}</div>
112
+ <MIcon class="m-editor-float-box-close" :icon="Close" @click.stop="closeFloatBox(config.$key)"></MIcon>
113
+ </div>
114
+ <div class="m-editor-float-box-body">
115
+ <component
116
+ v-if="config && floatBoxStates?.get(config.$key)?.status"
117
+ :is="config.boxComponentConfig?.component || config.component"
118
+ v-bind="config.boxComponentConfig?.props || config.props || {}"
119
+ v-on="config?.listeners || {}"
120
+ />
121
+ </div>
122
+ </div>
123
+ </div>
124
+ </Teleport>
83
125
  </template>
84
126
 
85
127
  <script setup lang="ts">
86
- import { computed, ref, watch } from 'vue';
87
- import { Coin, EditPen, Goods, List } from '@element-plus/icons-vue';
128
+ import { computed, inject, ref, watch } from 'vue';
129
+ import { Close, Coin, EditPen, Goods, List } from '@element-plus/icons-vue';
88
130
 
89
131
  import MIcon from '@editor/components/Icon.vue';
90
- import type { MenuButton, MenuComponent, SidebarSlots, SideComponent, SideItem } from '@editor/type';
91
- import { SideBarData } from '@editor/type';
132
+ import { useFloatBox } from '@editor/hooks/use-float-box';
133
+ import type {
134
+ MenuButton,
135
+ MenuComponent,
136
+ Services,
137
+ SideBarData,
138
+ SidebarSlots,
139
+ SideComponent,
140
+ SideItem,
141
+ } from '@editor/type';
92
142
 
93
143
  import CodeBlockListPanel from './code-block/CodeBlockListPanel.vue';
94
144
  import DataSourceListPanel from './data-source/DataSourceListPanel.vue';
@@ -111,6 +161,8 @@ const props = withDefaults(
111
161
  },
112
162
  );
113
163
 
164
+ const services = inject<Services>('services');
165
+
114
166
  const activeTabName = ref(props.data?.status);
115
167
 
116
168
  const getItemConfig = (data: SideItem): SideComponent => {
@@ -141,6 +193,11 @@ const getItemConfig = (data: SideItem): SideComponent => {
141
193
  text: '代码编辑',
142
194
  component: CodeBlockListPanel,
143
195
  slots: {},
196
+ boxComponentConfig: {
197
+ props: {
198
+ slideType: 'box',
199
+ },
200
+ },
144
201
  },
145
202
  'data-source': {
146
203
  $key: 'data-source',
@@ -149,6 +206,11 @@ const getItemConfig = (data: SideItem): SideComponent => {
149
206
  text: '数据源',
150
207
  component: DataSourceListPanel,
151
208
  slots: {},
209
+ boxComponentConfig: {
210
+ props: {
211
+ slideType: 'box',
212
+ },
213
+ },
152
214
  },
153
215
  };
154
216
 
@@ -164,6 +226,29 @@ watch(
164
226
  },
165
227
  );
166
228
 
229
+ const slideKeys = computed(() => sideBarItems.value.map((sideBarItem) => sideBarItem.$key));
230
+
231
+ const { showFloatBox, closeFloatBox, dragstartHandler, dragendHandler, floatBoxStates, floatBox, showingBoxKeys } =
232
+ useFloatBox(slideKeys);
233
+
234
+ watch(
235
+ () => showingBoxKeys.value.length,
236
+ () => {
237
+ const isActiveTabShow = showingBoxKeys.value.some(
238
+ (key) => activeTabName.value === sideBarItems.value.find((v) => v.$key === key)?.text,
239
+ );
240
+ if (!isActiveTabShow && activeTabName.value) return;
241
+ const nextSlideBarItem = sideBarItems.value.find((sideBarItem) => !showingBoxKeys.value.includes(sideBarItem.$key));
242
+ if (!nextSlideBarItem) {
243
+ activeTabName.value = '';
244
+ services?.uiService.set('hideSlideBar', true);
245
+ return;
246
+ }
247
+ services?.uiService.set('hideSlideBar', false);
248
+ activeTabName.value = nextSlideBarItem?.text;
249
+ },
250
+ );
251
+
167
252
  defineExpose({
168
253
  activeTabName,
169
254
  });
@@ -44,13 +44,14 @@
44
44
  import { computed, inject, ref } from 'vue';
45
45
  import { Close, Edit, View } from '@element-plus/icons-vue';
46
46
 
47
+ import { DepTargetType } from '@tmagic/dep';
47
48
  import { tMagicMessage, tMagicMessageBox, TMagicTooltip, TMagicTree } from '@tmagic/design';
48
49
  import type { Id } from '@tmagic/schema';
49
50
 
50
51
  import Icon from '@editor/components/Icon.vue';
51
52
  import AppManageIcon from '@editor/icons/AppManageIcon.vue';
52
53
  import CodeIcon from '@editor/icons/CodeIcon.vue';
53
- import { CodeBlockListSlots, CodeDeleteErrorType, CodeDslItem, DepTargetType, Services } from '@editor/type';
54
+ import { type CodeBlockListSlots, CodeDeleteErrorType, type CodeDslItem, type Services } from '@editor/type';
54
55
 
55
56
  defineSlots<CodeBlockListSlots>();
56
57
 
@@ -16,16 +16,16 @@
16
16
  <slot name="code-block-panel-tool" :id="id" :data="data"></slot>
17
17
  </template>
18
18
  </CodeBlockList>
19
-
20
- <!-- 代码块编辑区 -->
21
- <CodeBlockEditor
22
- v-if="codeConfig"
23
- ref="codeBlockEditor"
24
- :disabled="!editable"
25
- :content="codeConfig"
26
- @submit="submitCodeBlockHandler"
27
- ></CodeBlockEditor>
28
19
  </TMagicScrollbar>
20
+ <!-- 代码块编辑区 -->
21
+ <CodeBlockEditor
22
+ v-if="codeConfig"
23
+ ref="codeBlockEditor"
24
+ :disabled="!editable"
25
+ :content="codeConfig"
26
+ :slideType="slideType"
27
+ @submit="submitCodeBlockHandler"
28
+ ></CodeBlockEditor>
29
29
  </template>
30
30
 
31
31
  <script setup lang="ts">
@@ -37,7 +37,7 @@ import type { Id } from '@tmagic/schema';
37
37
  import CodeBlockEditor from '@editor/components/CodeBlockEditor.vue';
38
38
  import SearchInput from '@editor/components/SearchInput.vue';
39
39
  import { useCodeBlockEdit } from '@editor/hooks/use-code-block-edit';
40
- import type { CodeBlockListPanelSlots, CodeDeleteErrorType, Services } from '@editor/type';
40
+ import type { CodeBlockListPanelSlots, CodeDeleteErrorType, Services, SlideType } from '@editor/type';
41
41
 
42
42
  import CodeBlockList from './CodeBlockList.vue';
43
43
 
@@ -49,6 +49,7 @@ defineOptions({
49
49
 
50
50
  defineProps<{
51
51
  customError?: (id: Id, errorType: CodeDeleteErrorType) => any;
52
+ slideType?: SlideType;
52
53
  }>();
53
54
 
54
55
  const { codeBlockService } = inject<Services>('services') || {};
@@ -1,5 +1,6 @@
1
1
  <template>
2
- <MFormDrawer
2
+ <component
3
+ :is="slideType === 'box' ? MFormBox : MFormDrawer"
3
4
  ref="fomDrawer"
4
5
  label-width="80px"
5
6
  :close-on-press-escape="false"
@@ -10,17 +11,17 @@
10
11
  :disabled="disabled"
11
12
  @submit="submitHandler"
12
13
  @error="errorHandler"
13
- ></MFormDrawer>
14
+ ></component>
14
15
  </template>
15
16
 
16
17
  <script setup lang="ts">
17
18
  import { computed, inject, ref, watchEffect } from 'vue';
18
19
 
19
20
  import { tMagicMessage } from '@tmagic/design';
20
- import { FormConfig, MFormDrawer } from '@tmagic/form';
21
+ import { FormConfig, MFormBox, MFormDrawer } from '@tmagic/form';
21
22
  import { DataSourceSchema } from '@tmagic/schema';
22
23
 
23
- import type { Services } from '@editor/type';
24
+ import type { Services, SlideType } from '@editor/type';
24
25
 
25
26
  defineOptions({
26
27
  name: 'MEditorDataSourceConfigPanel',
@@ -30,6 +31,7 @@ const props = defineProps<{
30
31
  title?: string;
31
32
  values: any;
32
33
  disabled: boolean;
34
+ slideType?: SlideType;
33
35
  }>();
34
36
 
35
37
  const emit = defineEmits(['submit']);