@tmagic/editor 1.3.3 → 1.3.4

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.
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.3.3",
2
+ "version": "1.3.4",
3
3
  "name": "@tmagic/editor",
4
4
  "type": "module",
5
5
  "sideEffects": [
@@ -47,14 +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.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",
50
+ "@tmagic/core": "1.3.4",
51
+ "@tmagic/dep": "1.3.4",
52
+ "@tmagic/design": "1.3.4",
53
+ "@tmagic/form": "1.3.4",
54
+ "@tmagic/schema": "1.3.4",
55
+ "@tmagic/stage": "1.3.4",
56
+ "@tmagic/table": "1.3.4",
57
+ "@tmagic/utils": "1.3.4",
58
58
  "buffer": "^6.0.3",
59
59
  "color": "^3.1.3",
60
60
  "events": "^3.3.0",
@@ -67,8 +67,8 @@
67
67
  "vue": "^3.3.8"
68
68
  },
69
69
  "peerDependencies": {
70
- "@tmagic/design": "1.3.3",
71
- "@tmagic/form": "1.3.3",
70
+ "@tmagic/design": "1.3.4",
71
+ "@tmagic/form": "1.3.4",
72
72
  "monaco-editor": "^0.41.0",
73
73
  "vue": "^3.3.8"
74
74
  },
@@ -25,6 +25,8 @@
25
25
  <script lang="ts" setup>
26
26
  import { computed, onMounted, onUnmounted, ref, watch } from 'vue';
27
27
 
28
+ import { isNumber } from '@tmagic/utils';
29
+
28
30
  import type { ScrollViewerEvent } from '@editor/type';
29
31
  import { ScrollViewer } from '@editor/utils/scroll-viewer';
30
32
 
@@ -36,8 +38,8 @@ defineOptions({
36
38
 
37
39
  const props = withDefaults(
38
40
  defineProps<{
39
- width?: number;
40
- height?: number;
41
+ width?: number | string;
42
+ height?: number | string;
41
43
  wrapWidth?: number;
42
44
  wrapHeight?: number;
43
45
  zoom?: number;
@@ -63,8 +65,8 @@ const container = ref<HTMLDivElement>();
63
65
  const el = ref<HTMLDivElement>();
64
66
  const style = computed(
65
67
  () => `
66
- width: ${props.width}px;
67
- height: ${props.height}px;
68
+ width: ${isNumber(`${props.width}`) ? `${props.width}px` : props.width};
69
+ height: ${isNumber(`${props.height}`) ? `${props.height}px` : props.height};
68
70
  position: absolute;
69
71
  margin-top: 30px;
70
72
  `,
@@ -38,6 +38,7 @@ 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
40
  import { MagicTable } from '@tmagic/table';
41
+ import { getDefaultValueFromFields } from '@tmagic/utils';
41
42
 
42
43
  import type { Services } from '@editor/type';
43
44
 
@@ -96,7 +97,7 @@ const fieldColumns = [
96
97
  },
97
98
  {
98
99
  label: '属性描述',
99
- prop: 'desc',
100
+ prop: 'description',
100
101
  },
101
102
  {
102
103
  label: '默认值',
@@ -229,6 +230,7 @@ const jsonFromValues = ref({
229
230
  });
230
231
 
231
232
  const newFromJsonHandler = () => {
233
+ jsonFromValues.value.data = getDefaultValueFromFields(props.model[props.name]);
232
234
  addFromJsonDialog.value?.show();
233
235
  };
234
236
 
@@ -243,38 +245,41 @@ const getValueType = (value: any) => {
243
245
  return 'any';
244
246
  };
245
247
 
246
- const getFieldsConfig = (value: any) => {
248
+ const getFieldsConfig = (value: any, fields: DataSchema[] = []) => {
247
249
  if (!value || typeof value !== 'object') throw new Error('数据格式错误');
248
250
 
249
- const fields: DataSchema[] = [];
251
+ const newFields: DataSchema[] = [];
250
252
  Object.entries(value).forEach(([key, value]) => {
251
253
  const type = getValueType(value);
252
254
 
255
+ const oldField = fields.find((field) => field.name === key);
256
+
253
257
  let childFields: DataSchema[] = [];
254
258
  if (Array.isArray(value) && value.length > 0) {
255
- childFields = getFieldsConfig(value[0]);
259
+ childFields = getFieldsConfig(value[0], oldField?.fields);
256
260
  } else if (type === 'object') {
257
- childFields = getFieldsConfig(value);
261
+ childFields = getFieldsConfig(value, oldField?.fields);
258
262
  }
259
263
 
260
- fields.push({
264
+ newFields.push({
261
265
  name: key,
262
- title: key,
266
+ title: oldField?.title || key,
263
267
  type,
268
+ description: oldField?.description || '',
269
+ enable: oldField?.enable ?? true,
264
270
  defaultValue: value,
265
271
  fields: childFields,
266
272
  });
267
273
  });
268
274
 
269
- return fields;
275
+ return newFields;
270
276
  };
271
277
 
272
278
  const addFromJsonFromChange = ({ data }: { data: string }) => {
273
- console.log(data);
274
279
  try {
275
280
  const value = JSON.parse(data);
276
281
 
277
- props.model[props.name] = getFieldsConfig(value);
282
+ props.model[props.name] = getFieldsConfig(value, props.model[props.name]);
278
283
 
279
284
  addFromJsonDialog.value?.hide();
280
285
 
@@ -1,37 +1,60 @@
1
1
  <template>
2
2
  <div class="m-fields-key-value">
3
- <div class="m-fields-key-value-item" v-for="(item, index) in records" :key="index">
4
- <TMagicInput
5
- placeholder="key"
6
- v-model="records[index][0]"
7
- :disabled="disabled"
8
- :size="size"
9
- @change="keyChangeHandler"
10
- ></TMagicInput>
11
- <span class="m-fileds-key-value-delimiter">:</span>
12
- <TMagicInput
13
- placeholder="value"
14
- v-model="records[index][1]"
15
- :disabled="disabled"
16
- :size="size"
17
- @change="valueChangeHandler"
18
- ></TMagicInput>
19
-
20
- <TMagicButton
21
- class="m-fileds-key-value-delete"
22
- type="danger"
23
- :size="size"
24
- :disabled="disabled"
25
- circle
26
- plain
27
- :icon="Delete"
28
- @click="deleteHandler(index)"
29
- ></TMagicButton>
3
+ <div v-if="!showCode">
4
+ <div class="m-fields-key-value-item" v-for="(item, index) in records" :key="index">
5
+ <TMagicInput
6
+ placeholder="key"
7
+ v-model="records[index][0]"
8
+ :disabled="disabled"
9
+ :size="size"
10
+ @change="keyChangeHandler"
11
+ ></TMagicInput>
12
+ <span class="m-fileds-key-value-delimiter">:</span>
13
+ <TMagicInput
14
+ placeholder="value"
15
+ v-model="records[index][1]"
16
+ :disabled="disabled"
17
+ :size="size"
18
+ @change="valueChangeHandler"
19
+ ></TMagicInput>
20
+
21
+ <TMagicButton
22
+ class="m-fileds-key-value-delete"
23
+ type="danger"
24
+ :size="size"
25
+ :disabled="disabled"
26
+ circle
27
+ plain
28
+ :icon="Delete"
29
+ @click="deleteHandler(index)"
30
+ ></TMagicButton>
31
+ </div>
32
+
33
+ <TMagicButton type="primary" :size="size" :disabled="disabled" plain :icon="Plus" @click="addHandler"
34
+ >添加</TMagicButton
35
+ >
30
36
  </div>
31
37
 
32
- <TMagicButton type="primary" :size="size" :disabled="disabled" plain :icon="Plus" @click="addHandler"
33
- >添加</TMagicButton
34
- >
38
+ <MagicCodeEditor
39
+ v-if="config.advanced && showCode"
40
+ height="200px"
41
+ :init-values="model[name]"
42
+ language="json"
43
+ :options="{
44
+ readOnly: disabled,
45
+ }"
46
+ :parse="true"
47
+ @save="save"
48
+ ></MagicCodeEditor>
49
+
50
+ <TMagicButton
51
+ v-if="config.advanced"
52
+ size="default"
53
+ :disabled="disabled"
54
+ text
55
+ :icon="CodeIcon"
56
+ @click="showCode = !showCode"
57
+ ></TMagicButton>
35
58
  </div>
36
59
  </template>
37
60
 
@@ -42,6 +65,9 @@ import { Delete, Plus } from '@element-plus/icons-vue';
42
65
  import { TMagicButton, TMagicInput } from '@tmagic/design';
43
66
  import type { FieldProps } from '@tmagic/form';
44
67
 
68
+ import CodeIcon from '@editor/icons/CodeIcon.vue';
69
+ import MagicCodeEditor from '@editor/layouts/CodeEditor.vue';
70
+
45
71
  defineOptions({
46
72
  name: 'MEditorKeyValue',
47
73
  });
@@ -52,6 +78,7 @@ const props = withDefaults(
52
78
  type: 'key-value';
53
79
  name: string;
54
80
  text: string;
81
+ advanced?: boolean;
55
82
  }>
56
83
  >(),
57
84
  {
@@ -62,9 +89,19 @@ const props = withDefaults(
62
89
  const emit = defineEmits<(e: 'change', value: Record<string, any>) => void>();
63
90
 
64
91
  const records = ref<[string, string][]>([]);
92
+ const showCode = ref(false);
65
93
 
66
94
  watchEffect(() => {
67
- records.value = Object.entries(props.model[props.name] || {});
95
+ const initValues: [string, any][] = Object.entries(props.model[props.name] || {});
96
+
97
+ for (const [, value] of initValues) {
98
+ if (typeof value !== 'string') {
99
+ showCode.value = true;
100
+ break;
101
+ }
102
+ }
103
+
104
+ records.value = initValues;
68
105
  });
69
106
 
70
107
  const getValue = () => {
@@ -93,4 +130,8 @@ const deleteHandler = (index: number) => {
93
130
  records.value.splice(index, 1);
94
131
  emit('change', getValue());
95
132
  };
133
+
134
+ const save = (v: string | any) => {
135
+ emit('change', v);
136
+ };
96
137
  </script>
@@ -191,7 +191,11 @@ const dropHandler = async (e: DragEvent) => {
191
191
  let left = 0;
192
192
  let position = 'relative';
193
193
 
194
- if (layout === Layout.ABSOLUTE) {
194
+ if (style.position === 'fixed') {
195
+ position = 'fixed';
196
+ top = e.clientY - containerRect.top;
197
+ left = e.clientX - containerRect.left;
198
+ } else if (layout === Layout.ABSOLUTE) {
195
199
  position = 'absolute';
196
200
  top = e.clientY - containerRect.top + scrollTop;
197
201
  left = e.clientX - containerRect.left + scrollLeft;
@@ -548,7 +548,9 @@ class Editor extends BaseService {
548
548
 
549
549
  const newNodes = await Promise.all(nodes.map((node) => this.doUpdate(node)));
550
550
 
551
- this.pushHistoryState();
551
+ if (newNodes[0]?.type !== NodeType.ROOT) {
552
+ this.pushHistoryState();
553
+ }
552
554
 
553
555
  this.emit('update', newNodes);
554
556
  return Array.isArray(config) ? newNodes : newNodes[0];
@@ -18,6 +18,8 @@
18
18
 
19
19
  import { reactive } from 'vue';
20
20
 
21
+ import { convertToNumber } from '@tmagic/utils';
22
+
21
23
  import editorService from '@editor/services/editor';
22
24
  import type { StageRect, UiState } from '@editor/type';
23
25
 
@@ -86,9 +88,12 @@ class Ui extends BaseService {
86
88
  const { height, width } = stageContainerRect;
87
89
  if (!width || !height) return 1;
88
90
 
91
+ let stageWidth: number = convertToNumber(stageRect.width, width);
92
+ let stageHeight: number = convertToNumber(stageRect.height, height);
93
+
89
94
  // 30为标尺的大小
90
- const stageWidth = stageRect.width + 30;
91
- const stageHeight = stageRect.height + 30;
95
+ stageWidth = stageWidth + 30;
96
+ stageHeight = stageHeight + 30;
92
97
 
93
98
  if (width > stageWidth && height > stageHeight) {
94
99
  return 1;
@@ -1,3 +1,10 @@
1
+ .m-fields-key-value {
2
+ display: flex;
3
+ justify-items: center;
4
+ align-items: top;
5
+ width: 100%;
6
+ }
7
+
1
8
  .m-fields-key-value-item {
2
9
  display: flex;
3
10
  margin-bottom: 10px;
package/src/type.ts CHANGED
@@ -173,8 +173,8 @@ export interface GetColumnWidth {
173
173
  }
174
174
 
175
175
  export interface StageRect {
176
- width: number;
177
- height: number;
176
+ width: number | string;
177
+ height: number | string;
178
178
  }
179
179
 
180
180
  export interface UiState {
@@ -185,7 +185,10 @@ export interface UiState {
185
185
  /** 画布显示放大倍数,默认为 1 */
186
186
  zoom: number;
187
187
  /** 画布容器的宽高 */
188
- stageContainerRect: StageRect;
188
+ stageContainerRect: {
189
+ width: number;
190
+ height: number;
191
+ };
189
192
  /** 画布顶层div的宽高,可用于改变画布的大小 */
190
193
  stageRect: StageRect;
191
194
  /** 编辑器列布局每一列的宽度,分为左中右三列 */
@@ -46,6 +46,7 @@ export default [
46
46
  name: 'data',
47
47
  type: 'key-value',
48
48
  defaultValue: {},
49
+ advanced: true,
49
50
  text: '请求体',
50
51
  },
51
52
  {
@@ -1,6 +1,6 @@
1
1
  declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
2
- width?: number | undefined;
3
- height?: number | undefined;
2
+ width?: string | number | undefined;
3
+ height?: string | number | undefined;
4
4
  wrapWidth?: number | undefined;
5
5
  wrapHeight?: number | undefined;
6
6
  zoom?: number | undefined;
@@ -21,8 +21,8 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
21
21
  }>, {
22
22
  container: import("vue").Ref<HTMLDivElement | undefined>;
23
23
  }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
24
- width?: number | undefined;
25
- height?: number | undefined;
24
+ width?: string | number | undefined;
25
+ height?: string | number | undefined;
26
26
  wrapWidth?: number | undefined;
27
27
  wrapHeight?: number | undefined;
28
28
  zoom?: number | undefined;
@@ -41,8 +41,8 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
41
41
  height: number;
42
42
  };
43
43
  }>>>, {
44
- width: number;
45
- height: number;
44
+ width: string | number;
45
+ height: string | number;
46
46
  zoom: number;
47
47
  wrapWidth: number;
48
48
  wrapHeight: number;
@@ -3,6 +3,7 @@ declare const _default: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_T
3
3
  type: "key-value";
4
4
  name: string;
5
5
  text: string;
6
+ advanced?: boolean | undefined;
6
7
  }>>, {
7
8
  disabled: boolean;
8
9
  }>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
@@ -11,6 +12,7 @@ declare const _default: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_T
11
12
  type: "key-value";
12
13
  name: string;
13
14
  text: string;
15
+ advanced?: boolean | undefined;
14
16
  }>>, {
15
17
  disabled: boolean;
16
18
  }>>> & {
@@ -12,8 +12,8 @@ declare class Ui extends BaseService {
12
12
  height: number;
13
13
  };
14
14
  stageRect: {
15
- width: number;
16
- height: number;
15
+ width: string | number;
16
+ height: string | number;
17
17
  };
18
18
  columnWidth: {
19
19
  left: number;
package/types/type.d.ts CHANGED
@@ -143,8 +143,8 @@ export interface GetColumnWidth {
143
143
  [ColumnLayout.RIGHT]: number;
144
144
  }
145
145
  export interface StageRect {
146
- width: number;
147
- height: number;
146
+ width: number | string;
147
+ height: number | string;
148
148
  }
149
149
  export interface UiState {
150
150
  /** 当前点击画布是否触发选中,true: 不触发,false: 触发,默认为false */
@@ -154,7 +154,10 @@ export interface UiState {
154
154
  /** 画布显示放大倍数,默认为 1 */
155
155
  zoom: number;
156
156
  /** 画布容器的宽高 */
157
- stageContainerRect: StageRect;
157
+ stageContainerRect: {
158
+ width: number;
159
+ height: number;
160
+ };
158
161
  /** 画布顶层div的宽高,可用于改变画布的大小 */
159
162
  stageRect: StageRect;
160
163
  /** 编辑器列布局每一列的宽度,分为左中右三列 */