@tmagic/editor 1.3.0-alpha.2 → 1.3.0-alpha.21

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 (167) hide show
  1. package/dist/style.css +91 -120
  2. package/dist/tmagic-editor.js +4609 -3257
  3. package/dist/tmagic-editor.js.map +1 -1
  4. package/dist/tmagic-editor.umd.cjs +5708 -4337
  5. package/dist/tmagic-editor.umd.cjs.map +1 -1
  6. package/package.json +21 -22
  7. package/src/Editor.vue +29 -7
  8. package/src/components/CodeBlockEditor.vue +170 -0
  9. package/src/components/CodeParams.vue +60 -0
  10. package/src/components/ContentMenu.vue +30 -11
  11. package/src/components/Icon.vue +5 -1
  12. package/src/components/Resizer.vue +45 -0
  13. package/src/components/ScrollBar.vue +5 -1
  14. package/src/components/ScrollViewer.vue +5 -1
  15. package/src/components/SearchInput.vue +4 -0
  16. package/src/components/{Layout.vue → SplitView.vue} +8 -4
  17. package/src/components/ToolButton.vue +5 -1
  18. package/src/editorProps.ts +35 -4
  19. package/src/fields/Code.vue +28 -20
  20. package/src/fields/CodeLink.vue +15 -10
  21. package/src/fields/CodeSelect.vue +19 -10
  22. package/src/fields/CodeSelectCol.vue +67 -83
  23. package/src/fields/DataSourceFieldSelect.vue +47 -0
  24. package/src/fields/DataSourceFields.vue +24 -21
  25. package/src/fields/DataSourceInput.vue +318 -0
  26. package/src/fields/DataSourceMethodSelect.vue +136 -0
  27. package/src/fields/DataSourceMethods.vue +103 -0
  28. package/src/fields/DataSourceSelect.vue +68 -0
  29. package/src/fields/EventSelect.vue +62 -22
  30. package/src/fields/KeyValue.vue +13 -11
  31. package/src/fields/UISelect.vue +59 -15
  32. package/src/hooks/index.ts +21 -0
  33. package/src/hooks/use-code-block-edit.ts +84 -0
  34. package/src/hooks/use-data-source-method.ts +100 -0
  35. package/src/{utils/stage.ts → hooks/use-stage.ts} +4 -7
  36. package/src/icons/AppManageIcon.vue +5 -1
  37. package/src/icons/CenterIcon.vue +13 -0
  38. package/src/icons/CodeIcon.vue +5 -3
  39. package/src/index.ts +24 -3
  40. package/src/initService.ts +75 -16
  41. package/src/layouts/AddPageBox.vue +5 -1
  42. package/src/layouts/CodeEditor.vue +66 -11
  43. package/src/layouts/Framework.vue +32 -28
  44. package/src/layouts/NavMenu.vue +5 -1
  45. package/src/layouts/PropsPanel.vue +14 -4
  46. package/src/layouts/sidebar/ComponentListPanel.vue +11 -10
  47. package/src/layouts/sidebar/LayerMenu.vue +13 -25
  48. package/src/layouts/sidebar/LayerNode.vue +40 -0
  49. package/src/layouts/sidebar/LayerPanel.vue +71 -28
  50. package/src/layouts/sidebar/Sidebar.vue +13 -17
  51. package/src/layouts/sidebar/code-block/CodeBlockList.vue +84 -118
  52. package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +63 -0
  53. package/src/layouts/sidebar/data-source/DataSourceConfigPanel.vue +39 -34
  54. package/src/layouts/sidebar/data-source/DataSourceList.vue +145 -0
  55. package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +17 -65
  56. package/src/layouts/workspace/Breadcrumb.vue +5 -1
  57. package/src/layouts/workspace/PageBar.vue +5 -1
  58. package/src/layouts/workspace/PageBarScrollContainer.vue +5 -1
  59. package/src/layouts/workspace/Stage.vue +30 -8
  60. package/src/layouts/workspace/ViewerMenu.vue +15 -36
  61. package/src/layouts/workspace/Workspace.vue +9 -134
  62. package/src/services/codeBlock.ts +20 -72
  63. package/src/services/dataSource.ts +17 -2
  64. package/src/services/dep.ts +23 -20
  65. package/src/services/editor.ts +3 -3
  66. package/src/services/keybinding.ts +185 -0
  67. package/src/services/props.ts +2 -2
  68. package/src/services/storage.ts +3 -2
  69. package/src/theme/code-block.scss +5 -117
  70. package/src/theme/code-editor.scss +27 -2
  71. package/src/theme/content-menu.scss +1 -1
  72. package/src/theme/data-source-input.scss +18 -0
  73. package/src/theme/data-source-methods.scss +13 -0
  74. package/src/theme/event.scss +15 -12
  75. package/src/theme/framework.scss +0 -3
  76. package/src/theme/layer-panel.scss +6 -0
  77. package/src/theme/layout.scss +4 -0
  78. package/src/theme/resizer.scss +25 -10
  79. package/src/theme/stage.scss +4 -0
  80. package/src/theme/theme.scss +2 -0
  81. package/src/type.ts +105 -7
  82. package/src/utils/config.ts +1 -1
  83. package/src/utils/content-menu.ts +92 -0
  84. package/src/utils/data-source/formConfigs/base.ts +35 -30
  85. package/src/utils/data-source/index.ts +75 -6
  86. package/src/utils/dep.ts +39 -7
  87. package/src/utils/index.ts +1 -1
  88. package/src/utils/keybinding-config.ts +120 -0
  89. package/src/utils/props.ts +298 -155
  90. package/src/utils/undo-redo.ts +1 -1
  91. package/types/Editor.vue.d.ts +37 -4
  92. package/types/components/CodeBlockEditor.vue.d.ts +23 -0
  93. package/types/components/CodeParams.vue.d.ts +26 -0
  94. package/types/components/ContentMenu.vue.d.ts +8 -3
  95. package/types/components/Icon.vue.d.ts +2 -2
  96. package/types/{layouts → components}/Resizer.vue.d.ts +2 -2
  97. package/types/components/ScrollBar.vue.d.ts +1 -1
  98. package/types/components/ScrollViewer.vue.d.ts +8 -5
  99. package/types/components/SearchInput.vue.d.ts +1 -1
  100. package/types/components/{Layout.vue.d.ts → SplitView.vue.d.ts} +9 -6
  101. package/types/components/ToolButton.vue.d.ts +10 -7
  102. package/types/editorProps.d.ts +23 -4
  103. package/types/fields/Code.vue.d.ts +23 -18
  104. package/types/fields/CodeLink.vue.d.ts +13 -22
  105. package/types/fields/CodeSelect.vue.d.ts +12 -20
  106. package/types/fields/CodeSelectCol.vue.d.ts +14 -15
  107. package/types/fields/DataSourceFieldSelect.vue.d.ts +29 -0
  108. package/types/fields/DataSourceFields.vue.d.ts +13 -21
  109. package/types/fields/DataSourceInput.vue.d.ts +34 -0
  110. package/types/fields/DataSourceMethodSelect.vue.d.ts +29 -0
  111. package/types/fields/DataSourceMethods.vue.d.ts +32 -0
  112. package/types/fields/DataSourceSelect.vue.d.ts +40 -0
  113. package/types/fields/EventSelect.vue.d.ts +3 -14
  114. package/types/fields/KeyValue.vue.d.ts +15 -27
  115. package/types/fields/UISelect.vue.d.ts +3 -12
  116. package/types/hooks/index.d.ts +3 -0
  117. package/types/hooks/use-code-block-edit.d.ts +125 -0
  118. package/types/hooks/use-data-source-method.d.ts +123 -0
  119. package/types/icons/AppManageIcon.vue.d.ts +1 -1
  120. package/types/icons/CenterIcon.vue.d.ts +2 -0
  121. package/types/icons/CodeIcon.vue.d.ts +1 -1
  122. package/types/index.d.ts +12 -2
  123. package/types/initService.d.ts +2 -2
  124. package/types/layouts/AddPageBox.vue.d.ts +1 -1
  125. package/types/layouts/CodeEditor.vue.d.ts +18 -10
  126. package/types/layouts/Framework.vue.d.ts +11 -32
  127. package/types/layouts/NavMenu.vue.d.ts +7 -4
  128. package/types/layouts/PropsPanel.vue.d.ts +276 -4
  129. package/types/layouts/sidebar/ComponentListPanel.vue.d.ts +4 -4
  130. package/types/layouts/sidebar/LayerMenu.vue.d.ts +2 -2
  131. package/types/layouts/sidebar/LayerNode.vue.d.ts +16 -0
  132. package/types/layouts/sidebar/LayerPanel.vue.d.ts +5 -5
  133. package/types/layouts/sidebar/Sidebar.vue.d.ts +16 -16
  134. package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +7 -12
  135. package/types/layouts/sidebar/code-block/CodeBlockListPanel.vue.d.ts +28 -0
  136. package/types/layouts/sidebar/data-source/DataSourceConfigPanel.vue.d.ts +4 -2
  137. package/types/layouts/sidebar/data-source/DataSourceList.vue.d.ts +14 -0
  138. package/types/layouts/sidebar/data-source/DataSourceListPanel.vue.d.ts +1 -11
  139. package/types/layouts/workspace/Breadcrumb.vue.d.ts +1 -1
  140. package/types/layouts/workspace/PageBar.vue.d.ts +5 -5
  141. package/types/layouts/workspace/PageBarScrollContainer.vue.d.ts +2 -2
  142. package/types/layouts/workspace/Stage.vue.d.ts +2 -2
  143. package/types/layouts/workspace/ViewerMenu.vue.d.ts +7 -4
  144. package/types/layouts/workspace/Workspace.vue.d.ts +9 -9
  145. package/types/services/codeBlock.d.ts +6 -37
  146. package/types/services/dataSource.d.ts +7 -1
  147. package/types/services/dep.d.ts +12 -21
  148. package/types/services/editor.d.ts +1 -1
  149. package/types/services/keybinding.d.ts +20 -0
  150. package/types/services/props.d.ts +10 -115
  151. package/types/type.d.ts +97 -7
  152. package/types/utils/config.d.ts +1 -1
  153. package/types/utils/content-menu.d.ts +7 -0
  154. package/types/utils/data-source/formConfigs/base.d.ts +2 -2
  155. package/types/utils/data-source/index.d.ts +7 -1
  156. package/types/utils/dep.d.ts +4 -2
  157. package/types/utils/index.d.ts +1 -1
  158. package/types/utils/keybinding-config.d.ts +3 -0
  159. package/types/utils/props.d.ts +13 -102
  160. package/src/components/CodeDraftEditor.vue +0 -144
  161. package/src/components/FunctionEditor.vue +0 -190
  162. package/src/layouts/Resizer.vue +0 -32
  163. package/src/layouts/sidebar/code-block/CodeBlockEditor.vue +0 -96
  164. package/types/components/CodeDraftEditor.vue.d.ts +0 -58
  165. package/types/components/FunctionEditor.vue.d.ts +0 -192
  166. package/types/layouts/sidebar/code-block/CodeBlockEditor.vue.d.ts +0 -25
  167. /package/types/{utils/stage.d.ts → hooks/use-stage.d.ts} +0 -0
@@ -3,18 +3,23 @@
3
3
  <m-form-table
4
4
  v-if="isOldVersion"
5
5
  ref="eventForm"
6
- :size="props.size"
7
- :model="model"
8
6
  name="events"
7
+ :size="size"
8
+ :disabled="disabled"
9
+ :model="model"
9
10
  :config="tableConfig"
10
11
  @change="onChangeHandler"
11
12
  ></m-form-table>
12
13
 
13
14
  <div v-else class="fullWidth">
14
- <TMagicButton class="create-button" type="primary" size="small" @click="addEvent()">添加事件</TMagicButton>
15
+ <TMagicButton class="create-button" type="primary" :size="size" :disabled="disabled" @click="addEvent()"
16
+ >添加事件</TMagicButton
17
+ >
15
18
  <m-form-panel
16
19
  v-for="(cardItem, index) in model[name]"
17
20
  :key="index"
21
+ :disabled="disabled"
22
+ :size="size"
18
23
  :config="actionsConfig"
19
24
  :model="cardItem"
20
25
  @change="onChangeHandler"
@@ -24,37 +29,45 @@
24
29
  class="fullWidth"
25
30
  :config="eventNameConfig"
26
31
  :model="cardItem"
32
+ :disabled="disabled"
33
+ :size="size"
27
34
  @change="onChangeHandler"
28
35
  ></m-form-container>
29
- <TMagicButton style="color: #f56c6c" text :icon="Delete" @click="removeEvent(index)"></TMagicButton>
36
+ <TMagicButton
37
+ style="color: #f56c6c"
38
+ text
39
+ :icon="Delete"
40
+ :disabled="disabled"
41
+ :size="size"
42
+ @click="removeEvent(index)"
43
+ ></TMagicButton>
30
44
  </template>
31
45
  </m-form-panel>
32
46
  </div>
33
47
  </div>
34
48
  </template>
35
49
 
36
- <script lang="ts" setup name="MEditorEventSelect">
37
- import { computed, defineProps, inject } from 'vue';
50
+ <script lang="ts" setup>
51
+ import { computed, inject } from 'vue';
38
52
  import { Delete } from '@element-plus/icons-vue';
39
53
  import { has } from 'lodash-es';
40
54
 
41
55
  import { TMagicButton } from '@tmagic/design';
42
- import { FormState } from '@tmagic/form';
56
+ import type { FieldProps, FormState } from '@tmagic/form';
43
57
  import { ActionType } from '@tmagic/schema';
44
58
 
45
- import type { EventSelectConfig, Services } from '@editor/type';
59
+ import type { CodeSelectColConfig, DataSourceMethodSelectConfig, EventSelectConfig, Services } from '@editor/type';
46
60
 
47
- const services = inject<Services>('services');
61
+ defineOptions({
62
+ name: 'MEditorEventSelect',
63
+ });
64
+
65
+ const props = defineProps<FieldProps<EventSelectConfig>>();
48
66
 
49
- const props = defineProps<{
50
- config: EventSelectConfig;
51
- model: any;
52
- prop: string;
53
- name: string;
54
- size: 'small' | 'default' | 'large';
55
- }>();
56
67
  const emit = defineEmits(['change']);
57
68
 
69
+ const services = inject<Services>('services');
70
+
58
71
  // 事件名称下拉框表单配置
59
72
  const eventNameConfig = computed(() => {
60
73
  const defaultEventNameConfig = {
@@ -76,7 +89,7 @@ const actionTypeConfig = computed(() => {
76
89
  const defaultActionTypeConfig = {
77
90
  name: 'actionType',
78
91
  text: '联动类型',
79
- labelWidth: '70px',
92
+ labelWidth: '80px',
80
93
  type: 'select',
81
94
  defaultValue: ActionType.COMP,
82
95
  options: () => [
@@ -88,8 +101,15 @@ const actionTypeConfig = computed(() => {
88
101
  {
89
102
  text: '代码',
90
103
  label: '代码',
104
+ disabled: !Object.keys(services?.codeBlockService.getCodeDsl() || {}).length,
91
105
  value: ActionType.CODE,
92
106
  },
107
+ {
108
+ text: '数据源',
109
+ label: '数据源',
110
+ disabled: !services?.dataSourceService.get('dataSources')?.filter((ds) => ds.methods?.length).length,
111
+ value: ActionType.DATA_SOURCE,
112
+ },
93
113
  ],
94
114
  };
95
115
  return { ...defaultActionTypeConfig, ...props.config.actionTypeConfig };
@@ -100,7 +120,7 @@ const targetCompConfig = computed(() => {
100
120
  const defaultTargetCompConfig = {
101
121
  name: 'to',
102
122
  text: '联动组件',
103
- labelWidth: '70px',
123
+ labelWidth: '80px',
104
124
  type: 'ui-select',
105
125
  display: (mForm: FormState, { model }: { model: Record<any, any> }) => model.actionType === ActionType.COMP,
106
126
  };
@@ -112,7 +132,7 @@ const compActionConfig = computed(() => {
112
132
  const defaultCompActionConfig = {
113
133
  name: 'method',
114
134
  text: '动作',
115
- labelWidth: '70px',
135
+ labelWidth: '80px',
116
136
  type: 'select',
117
137
  display: (mForm: FormState, { model }: { model: Record<any, any> }) => model.actionType === ActionType.COMP,
118
138
  options: (mForm: FormState, { model }: any) => {
@@ -130,14 +150,27 @@ const compActionConfig = computed(() => {
130
150
 
131
151
  // 代码联动配置
132
152
  const codeActionConfig = computed(() => {
133
- const defaultCodeActionConfig = {
153
+ const defaultCodeActionConfig: CodeSelectColConfig = {
134
154
  type: 'code-select-col',
135
155
  labelWidth: 0,
136
- display: (mForm: FormState, { model }: { model: Record<any, any> }) => model.actionType === ActionType.CODE,
156
+ name: 'codeId',
157
+ disabled: () => !services?.codeBlockService.getEditStatus(),
158
+ display: (mForm, { model }) => model.actionType === ActionType.CODE,
137
159
  };
138
160
  return { ...defaultCodeActionConfig, ...props.config.codeActionConfig };
139
161
  });
140
162
 
163
+ // 数据源联动配置
164
+ const dataSourceActionConfig = computed(() => {
165
+ const defaultDataSourceActionConfig: DataSourceMethodSelectConfig = {
166
+ type: 'data-source-method-select',
167
+ name: 'dataSourceMethod',
168
+ labelWidth: 0,
169
+ display: (mForm, { model }) => model.actionType === ActionType.DATA_SOURCE,
170
+ };
171
+ return { ...defaultDataSourceActionConfig, ...props.config.dataSourceActionConfig };
172
+ });
173
+
141
174
  // 兼容旧的数据格式
142
175
  const tableConfig = computed(() => ({
143
176
  type: 'table',
@@ -181,8 +214,15 @@ const actionsConfig = computed(() => ({
181
214
  {
182
215
  type: 'group-list',
183
216
  name: 'actions',
217
+ expandAll: true,
184
218
  enableToggleMode: false,
185
- items: [actionTypeConfig.value, targetCompConfig.value, compActionConfig.value, codeActionConfig.value],
219
+ items: [
220
+ actionTypeConfig.value,
221
+ targetCompConfig.value,
222
+ compActionConfig.value,
223
+ codeActionConfig.value,
224
+ dataSourceActionConfig.value,
225
+ ],
186
226
  },
187
227
  ],
188
228
  }));
@@ -21,6 +21,7 @@
21
21
  class="m-fileds-key-value-delete"
22
22
  type="danger"
23
23
  :size="size"
24
+ :disabled="disabled"
24
25
  circle
25
26
  plain
26
27
  :icon="Delete"
@@ -28,7 +29,9 @@
28
29
  ></TMagicButton>
29
30
  </div>
30
31
 
31
- <TMagicButton type="primary" :size="size" plain :icon="Plus" @click="addHandler">添加</TMagicButton>
32
+ <TMagicButton type="primary" :size="size" :disabled="disabled" plain :icon="Plus" @click="addHandler"
33
+ >添加</TMagicButton
34
+ >
32
35
  </div>
33
36
  </template>
34
37
 
@@ -37,21 +40,20 @@ import { ref, watchEffect } from 'vue';
37
40
  import { Delete, Plus } from '@element-plus/icons-vue';
38
41
 
39
42
  import { TMagicButton, TMagicInput } from '@tmagic/design';
43
+ import type { FieldProps } from '@tmagic/form';
44
+
45
+ defineOptions({
46
+ name: 'MEditorKeyValue',
47
+ });
40
48
 
41
49
  const props = withDefaults(
42
- defineProps<{
43
- config: {
50
+ defineProps<
51
+ FieldProps<{
44
52
  type: 'key-value';
45
53
  name: string;
46
54
  text: string;
47
- };
48
- model: Record<string, any>;
49
- name: string;
50
- prop: string;
51
- disabled: boolean;
52
- lastValues?: Record<string, any>;
53
- size?: 'large' | 'default' | 'small';
54
- }>(),
55
+ }>
56
+ >(),
55
57
  {
56
58
  disabled: false,
57
59
  },
@@ -1,32 +1,61 @@
1
1
  <template>
2
2
  <div class="m-fields-ui-select" v-if="uiSelectMode" @click="cancelHandler">
3
- <TMagicButton type="danger" :icon="Delete" text style="padding: 0">取消</TMagicButton>
3
+ <TMagicButton type="danger" :icon="Delete" :disabled="disabled" :size="size" text style="padding: 0"
4
+ >取消</TMagicButton
5
+ >
4
6
  </div>
5
- <div class="m-fields-ui-select" v-else @click="startSelect" style="display: flex">
6
- <TMagicTooltip v-if="val" content="清除">
7
- <TMagicButton style="padding: 0" type="danger" :icon="Close" text @click.stop="deleteHandler"></TMagicButton>
8
- </TMagicTooltip>
9
- <TMagicTooltip :content="val ? toName + '_' + val : '点击此处选择'">
10
- <TMagicButton text style="padding: 0; margin: 0">{{ val ? toName + '_' + val : '点击此处选择' }}</TMagicButton>
7
+ <div class="m-fields-ui-select" v-else style="display: flex">
8
+ <template v-if="val">
9
+ <TMagicTooltip content="清除" placement="top">
10
+ <TMagicButton
11
+ style="padding: 0"
12
+ type="danger"
13
+ :icon="Close"
14
+ :disabled="disabled"
15
+ :size="size"
16
+ text
17
+ @click.stop="deleteHandler"
18
+ ></TMagicButton>
19
+ </TMagicTooltip>
20
+
21
+ <TMagicTooltip content="点击选中组件" placement="top">
22
+ <TMagicButton
23
+ text
24
+ style="padding: 0; margin: 0"
25
+ :disabled="disabled"
26
+ :size="size"
27
+ @click="selectNode(val)"
28
+ @mouseenter="highlight(val)"
29
+ @mouseleave="unhightlight"
30
+ >{{ `${toName}_${val}` }}</TMagicButton
31
+ >
32
+ </TMagicTooltip>
33
+ </template>
34
+
35
+ <TMagicTooltip v-else content="点击此处选择" placement="top">
36
+ <TMagicButton text style="padding: 0; margin: 0" :disabled="disabled" :size="size" @click="startSelect"
37
+ >点击此处选择</TMagicButton
38
+ >
11
39
  </TMagicTooltip>
12
40
  </div>
13
41
  </template>
14
42
 
15
- <script lang="ts" setup name="MEditorUISelect">
43
+ <script lang="ts" setup>
16
44
  import { computed, inject, ref } from 'vue';
17
45
  import { Close, Delete } from '@element-plus/icons-vue';
46
+ import { throttle } from 'lodash-es';
18
47
 
19
48
  import { TMagicButton, TMagicTooltip } from '@tmagic/design';
20
- import { FormState } from '@tmagic/form';
49
+ import type { FieldProps, FormState } from '@tmagic/form';
50
+ import type { Id } from '@tmagic/schema';
21
51
 
22
52
  import type { Services } from '@editor/type';
23
53
 
24
- const props = defineProps<{
25
- config: any;
26
- model: any;
27
- prop: string;
28
- name: string;
29
- }>();
54
+ defineOptions({
55
+ name: 'MEditorUISelect',
56
+ });
57
+
58
+ const props = defineProps<FieldProps<any>>();
30
59
 
31
60
  const emit = defineEmits(['change']);
32
61
 
@@ -73,6 +102,21 @@ const deleteHandler = () => {
73
102
  mForm?.$emit('field-change', props.prop, '');
74
103
  }
75
104
  };
105
+
106
+ const selectNode = async (id: Id) => {
107
+ await services?.editorService.select(id);
108
+ services?.editorService.get('stage')?.select(id);
109
+ };
110
+
111
+ const highlight = throttle((id: Id) => {
112
+ services?.editorService.highlight(id);
113
+ services?.editorService.get('stage')?.highlight(id);
114
+ }, 150);
115
+
116
+ const unhightlight = () => {
117
+ services?.editorService.set('highlightNode', null);
118
+ services?.editorService.get('stage')?.clearHighlight();
119
+ };
76
120
  </script>
77
121
 
78
122
  <style lang="scss">
@@ -0,0 +1,21 @@
1
+ /*
2
+ * Tencent is pleased to support the open source community by making TMagicEditor available.
3
+ *
4
+ * Copyright (C) 2023 THL A29 Limited, a Tencent company. All rights reserved.
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ export * from './use-code-block-edit';
20
+ export * from './use-data-source-method';
21
+ export * from './use-stage';
@@ -0,0 +1,84 @@
1
+ import { nextTick, ref } from 'vue';
2
+ import { cloneDeep } from 'lodash-es';
3
+
4
+ import { tMagicMessage } from '@tmagic/design';
5
+ import type { CodeBlockContent } from '@tmagic/schema';
6
+
7
+ import CodeBlockEditor from '@editor/components/CodeBlockEditor.vue';
8
+ import type { CodeBlockService } from '@editor/services/codeBlock';
9
+
10
+ export const useCodeBlockEdit = (codeBlockService?: CodeBlockService) => {
11
+ const codeConfig = ref<CodeBlockContent>();
12
+ const codeId = ref<string>();
13
+ const codeBlockEditor = ref<InstanceType<typeof CodeBlockEditor>>();
14
+
15
+ // 新增代码块
16
+ const createCodeBlock = async () => {
17
+ if (!codeBlockService) {
18
+ tMagicMessage.error('新增代码块失败');
19
+ return;
20
+ }
21
+
22
+ codeConfig.value = {
23
+ name: '代码块',
24
+ content: `({app, params}) => {\n // place your code here\n}`,
25
+ params: [],
26
+ };
27
+
28
+ codeId.value = await codeBlockService.getUniqueId();
29
+
30
+ await nextTick();
31
+
32
+ codeBlockEditor.value?.show();
33
+ };
34
+
35
+ // 编辑代码块
36
+ const editCode = async (id: string) => {
37
+ const codeBlock = await codeBlockService?.getCodeContentById(id);
38
+
39
+ if (!codeBlock) {
40
+ tMagicMessage.error('获取代码块内容失败');
41
+ return;
42
+ }
43
+
44
+ let codeContent = codeBlock.content;
45
+
46
+ if (typeof codeContent !== 'string') {
47
+ codeContent = codeContent.toString();
48
+ }
49
+
50
+ codeConfig.value = {
51
+ ...cloneDeep(codeBlock),
52
+ content: codeContent,
53
+ };
54
+ codeId.value = id;
55
+
56
+ await nextTick();
57
+
58
+ codeBlockEditor.value?.show();
59
+ };
60
+
61
+ // 删除代码块
62
+ const deleteCode = async (key: string) => {
63
+ codeBlockService?.deleteCodeDslByIds([key]);
64
+ };
65
+
66
+ const submitCodeBlockHandler = async (values: CodeBlockContent) => {
67
+ if (!codeId.value) return;
68
+
69
+ await codeBlockService?.setCodeDslById(codeId.value, values);
70
+
71
+ codeBlockEditor.value?.hide();
72
+ };
73
+
74
+ return {
75
+ codeId,
76
+ codeConfig,
77
+ codeBlockEditor,
78
+
79
+ createCodeBlock,
80
+ editCode,
81
+ deleteCode,
82
+ submitCodeBlockHandler,
83
+ };
84
+ };
@@ -0,0 +1,100 @@
1
+ import { nextTick, ref } from 'vue';
2
+ import { cloneDeep } from 'lodash-es';
3
+
4
+ import { tMagicMessage } from '@tmagic/design';
5
+ import type { CodeBlockContent, DataSourceSchema } from '@tmagic/schema';
6
+
7
+ import CodeBlockEditor from '@editor/components/CodeBlockEditor.vue';
8
+ import { getConfig } from '@editor/utils/config';
9
+
10
+ export const useDataSourceMethod = () => {
11
+ const codeConfig = ref<CodeBlockContent>();
12
+ const codeBlockEditor = ref<InstanceType<typeof CodeBlockEditor>>();
13
+
14
+ const dataSource = ref<DataSourceSchema>();
15
+ const dataSourceMethod = ref('');
16
+
17
+ return {
18
+ codeConfig,
19
+ codeBlockEditor,
20
+
21
+ createCode: async (model: DataSourceSchema) => {
22
+ codeConfig.value = {
23
+ name: '',
24
+ content: `({ params, dataSource, app }) => {\n // place your code here\n}`,
25
+ params: [],
26
+ };
27
+
28
+ await nextTick();
29
+
30
+ dataSource.value = model;
31
+ dataSourceMethod.value = '';
32
+
33
+ codeBlockEditor.value?.show();
34
+ },
35
+
36
+ editCode: async (model: DataSourceSchema, methodName: string) => {
37
+ const method = model.methods?.find((method) => method.name === methodName);
38
+
39
+ if (!method) {
40
+ tMagicMessage.error('获取数据源方法失败');
41
+ return;
42
+ }
43
+
44
+ let codeContent = method.content;
45
+
46
+ if (typeof codeContent !== 'string') {
47
+ codeContent = codeContent.toString();
48
+ }
49
+
50
+ codeConfig.value = {
51
+ ...cloneDeep(method),
52
+ content: codeContent,
53
+ };
54
+
55
+ await nextTick();
56
+
57
+ dataSource.value = model;
58
+ dataSourceMethod.value = methodName;
59
+
60
+ codeBlockEditor.value?.show();
61
+ },
62
+
63
+ deleteCode: async (model: DataSourceSchema, methodName: string) => {
64
+ if (!model.methods) return;
65
+
66
+ const index = model.methods.findIndex((method) => method.name === methodName);
67
+
68
+ if (index === -1) {
69
+ return;
70
+ }
71
+
72
+ model.methods.splice(index, 1);
73
+ },
74
+
75
+ submitCode: (values: CodeBlockContent) => {
76
+ if (!dataSource.value) return;
77
+
78
+ if (!dataSource.value.methods) {
79
+ dataSource.value.methods = [];
80
+ }
81
+
82
+ if (values.content) {
83
+ // 在保存的时候转换代码内容
84
+ const parseDSL = getConfig('parseDSL');
85
+ if (typeof values.content === 'string') {
86
+ values.content = parseDSL<(...args: any[]) => any>(values.content);
87
+ }
88
+ }
89
+
90
+ if (dataSourceMethod.value) {
91
+ const index = dataSource.value.methods.findIndex((method) => method.name === dataSourceMethod.value);
92
+ dataSource.value.methods.splice(index, 1, values);
93
+ } else {
94
+ dataSource.value.methods.push(values);
95
+ }
96
+
97
+ codeBlockEditor.value?.hide();
98
+ },
99
+ };
100
+ };
@@ -1,12 +1,12 @@
1
1
  import { computed } from 'vue';
2
2
 
3
+ import type { MNode } from '@tmagic/schema';
3
4
  import StageCore, { GuidesType, RemoveEventData, SortEventData, UpdateEventData } from '@tmagic/stage';
4
5
 
5
6
  import editorService from '@editor/services/editor';
6
7
  import uiService from '@editor/services/ui';
7
8
  import { H_GUIDE_LINE_STORAGE_KEY, StageOptions, V_GUIDE_LINE_STORAGE_KEY } from '@editor/type';
8
-
9
- import { getGuideLineFromCache } from './editor';
9
+ import { getGuideLineFromCache } from '@editor/utils/editor';
10
10
 
11
11
  const root = computed(() => editorService.get('root'));
12
12
  const page = computed(() => editorService.get('page'));
@@ -74,11 +74,8 @@ export const useStage = (stageOptions: StageOptions) => {
74
74
  });
75
75
 
76
76
  stage.on('remove', (ev: RemoveEventData) => {
77
- editorService.remove(
78
- ev.data.map(({ el }) => ({
79
- id: el.id,
80
- })),
81
- );
77
+ const nodes = ev.data.map(({ el }) => editorService.getNodeById(el.id));
78
+ editorService.remove(nodes.filter((node) => Boolean(node)) as MNode[]);
82
79
  });
83
80
 
84
81
  stage.on('select-parent', () => {
@@ -8,4 +8,8 @@
8
8
  </svg>
9
9
  </template>
10
10
 
11
- <script lang="ts" setup name="MEditorAppManageIcon"></script>
11
+ <script lang="ts" setup>
12
+ defineOptions({
13
+ name: 'MEditorAppManageIcon',
14
+ });
15
+ </script>
@@ -0,0 +1,13 @@
1
+ <template>
2
+ <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
3
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M2 4H21V6H2V4Z" fill="black" fill-opacity="0.9" />
4
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M5 11H18V13H5V11Z" fill="black" fill-opacity="0.9" />
5
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M2 18H21V20H2V18Z" fill="black" fill-opacity="0.9" />
6
+ </svg>
7
+ </template>
8
+
9
+ <script lang="ts" setup>
10
+ defineOptions({
11
+ name: 'MEditorCenterIcon',
12
+ });
13
+ </script>
@@ -1,7 +1,5 @@
1
1
  <template>
2
- <!-- 代码icon,cdn链接:https://cloudcache.tencent-cloud.com/qcloud/ui/static/government/0d463ed5-6407-4498-8865-3d05b5e70115.svg -->
3
2
  <svg viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
4
- <!-- Generator: Sketch 60.1 (88133) - https://sketch.com -->
5
3
  <defs><rect id="path-1" x="0" y="0" width="32" height="32"></rect></defs>
6
4
  <g id="组件规范" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
7
5
  <g id="03图标" transform="translate(-561.000000, -2356.000000)">
@@ -23,4 +21,8 @@
23
21
  </svg>
24
22
  </template>
25
23
 
26
- <script lang="ts" setup name="MEditorCodeIcon"></script>
24
+ <script lang="ts" setup>
25
+ defineOptions({
26
+ name: 'MEditorCodeIcon',
27
+ });
28
+ </script>
package/src/index.ts CHANGED
@@ -22,6 +22,11 @@ import CodeLink from './fields/CodeLink.vue';
22
22
  import CodeSelect from './fields/CodeSelect.vue';
23
23
  import CodeSelectCol from './fields/CodeSelectCol.vue';
24
24
  import DataSourceFields from './fields/DataSourceFields.vue';
25
+ import DataSourceFieldSelect from './fields/DataSourceFieldSelect.vue';
26
+ import DataSourceInput from './fields/DataSourceInput.vue';
27
+ import DataSourceMethods from './fields/DataSourceMethods.vue';
28
+ import DataSourceMethodSelect from './fields/DataSourceMethodSelect.vue';
29
+ import DataSourceSelect from './fields/DataSourceSelect.vue';
25
30
  import EventSelect from './fields/EventSelect.vue';
26
31
  import KeyValue from './fields/KeyValue.vue';
27
32
  import uiSelect from './fields/UISelect.vue';
@@ -34,6 +39,7 @@ import './theme/index.scss';
34
39
 
35
40
  export type { MoveableOptions } from '@tmagic/stage';
36
41
  export * from './type';
42
+ export * from './hooks';
37
43
  export * from './utils';
38
44
  export { default as TMagicEditor } from './Editor.vue';
39
45
  export { default as TMagicCodeEditor } from './layouts/CodeEditor.vue';
@@ -51,21 +57,31 @@ export { default as LayerPanel } from './layouts/sidebar/LayerPanel.vue';
51
57
  export { default as CodeSelect } from './fields/CodeSelect.vue';
52
58
  export { default as CodeSelectCol } from './fields/CodeSelectCol.vue';
53
59
  export { default as DataSourceFields } from './fields/DataSourceFields.vue';
60
+ export { default as DataSourceMethods } from './fields/DataSourceMethods.vue';
61
+ export { default as DataSourceInput } from './fields/DataSourceInput.vue';
62
+ export { default as DataSourceSelect } from './fields/DataSourceSelect.vue';
63
+ export { default as DataSourceMethodSelect } from './fields/DataSourceMethodSelect.vue';
64
+ export { default as DataSourceFieldSelect } from './fields/DataSourceFieldSelect.vue';
54
65
  export { default as EventSelect } from './fields/EventSelect.vue';
55
66
  export { default as KeyValue } from './fields/KeyValue.vue';
56
67
  export { default as CodeBlockList } from './layouts/sidebar/code-block/CodeBlockList.vue';
68
+ export { default as CodeBlockListPanel } from './layouts/sidebar/code-block/CodeBlockListPanel.vue';
57
69
  export { default as PropsPanel } from './layouts/PropsPanel.vue';
58
70
  export { default as ToolButton } from './components/ToolButton.vue';
59
71
  export { default as ContentMenu } from './components/ContentMenu.vue';
60
72
  export { default as Icon } from './components/Icon.vue';
61
- export { default as LayoutContainer } from './components/Layout.vue';
73
+ export { default as LayoutContainer } from './components/SplitView.vue';
74
+ export { default as SplitView } from './components/SplitView.vue';
75
+ export { default as Resizer } from './components/Resizer.vue';
76
+ export { default as CodeBlockEditor } from './components/CodeBlockEditor.vue';
62
77
 
63
78
  const defaultInstallOpt: InstallOptions = {
64
- // @todo, 自定义图片上传方法等编辑器依赖的外部选项
79
+ // eslint-disable-next-line no-eval
80
+ parseDSL: (dsl: string) => eval(dsl),
65
81
  };
66
82
 
67
83
  export default {
68
- install: (app: App, opt?: InstallOptions): void => {
84
+ install: (app: App, opt?: Partial<InstallOptions>): void => {
69
85
  const option = Object.assign(defaultInstallOpt, opt || {});
70
86
 
71
87
  // eslint-disable-next-line no-param-reassign
@@ -81,5 +97,10 @@ export default {
81
97
  app.component('m-fields-event-select', EventSelect);
82
98
  app.component('m-fields-data-source-fields', DataSourceFields);
83
99
  app.component('m-fields-key-value', KeyValue);
100
+ app.component('m-fields-data-source-input', DataSourceInput);
101
+ app.component('m-fields-data-source-select', DataSourceSelect);
102
+ app.component('m-fields-data-source-methods', DataSourceMethods);
103
+ app.component('m-fields-data-source-method-select', DataSourceMethodSelect);
104
+ app.component('m-fields-data-source-field-select', DataSourceFieldSelect);
84
105
  },
85
106
  };