@tmagic/editor 1.3.0-beta.7 → 1.3.0

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.0-beta.7",
2
+ "version": "1.3.0",
3
3
  "name": "@tmagic/editor",
4
4
  "type": "module",
5
5
  "sideEffects": [
@@ -47,13 +47,13 @@
47
47
  "dependencies": {
48
48
  "@babel/core": "^7.18.0",
49
49
  "@element-plus/icons-vue": "^2.0.9",
50
- "@tmagic/core": "1.3.0-beta.7",
51
- "@tmagic/design": "1.3.0-beta.7",
52
- "@tmagic/form": "1.3.0-beta.7",
53
- "@tmagic/schema": "1.3.0-beta.7",
54
- "@tmagic/stage": "1.3.0-beta.7",
55
- "@tmagic/table": "1.3.0-beta.7",
56
- "@tmagic/utils": "1.3.0-beta.7",
50
+ "@tmagic/core": "1.3.0",
51
+ "@tmagic/design": "1.3.0",
52
+ "@tmagic/form": "1.3.0",
53
+ "@tmagic/schema": "1.3.0",
54
+ "@tmagic/stage": "1.3.0",
55
+ "@tmagic/table": "1.3.0",
56
+ "@tmagic/utils": "1.3.0",
57
57
  "buffer": "^6.0.3",
58
58
  "color": "^3.1.3",
59
59
  "events": "^3.3.0",
@@ -65,8 +65,8 @@
65
65
  "vue": "^3.3.4"
66
66
  },
67
67
  "peerDependencies": {
68
- "@tmagic/design": "1.3.0-beta.7",
69
- "@tmagic/form": "1.3.0-beta.7",
68
+ "@tmagic/design": "1.3.0",
69
+ "@tmagic/form": "1.3.0",
70
70
  "monaco-editor": "^0.41.0",
71
71
  "vue": "^3.3.4"
72
72
  },
@@ -126,17 +126,13 @@ const setPosition = (e: { clientY: number; clientX: number }) => {
126
126
  };
127
127
  };
128
128
 
129
- const show = (e?: MouseEvent) => {
129
+ const show = (e?: { clientY: number; clientX: number }) => {
130
130
  // 加settimeout是以为,如果菜单中的按钮监听的是mouseup,那么菜单显示出来时鼠标如果正好在菜单上就会马上触发按钮的mouseup
131
131
  setTimeout(() => {
132
132
  visible.value = true;
133
133
 
134
- if (!e) {
135
- return;
136
- }
137
-
138
134
  nextTick(() => {
139
- setPosition(e);
135
+ e && setPosition(e);
140
136
 
141
137
  emit('show');
142
138
  });
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div ref="el" class="m-editor-layout">
2
+ <div ref="el" class="m-editor-layout" :style="`min-width: ${props.minCenter + props.minLeft + props.minRight}px`">
3
3
  <template v-if="hasLeft && $slots.left">
4
4
  <div class="m-editor-layout-left" :class="leftClass" :style="`width: ${left}px`">
5
5
  <slot name="left"></slot>
@@ -55,14 +55,18 @@ const el = ref<HTMLElement>();
55
55
  const hasLeft = computed(() => typeof props.left !== 'undefined');
56
56
  const hasRight = computed(() => typeof props.right !== 'undefined');
57
57
 
58
- const getCenterWidth = (clientWidth: number, left: number, right: number) => {
58
+ const getCenterWidth = (clientWidth: number, l = 0, r = 0) => {
59
+ let right = r > 0 ? r : 0;
60
+ let left = l > 0 ? l : 0;
59
61
  let center = clientWidth - left - right;
62
+
60
63
  if (center < props.minCenter) {
61
64
  center = props.minCenter;
62
- if (left < right) {
63
- right = clientWidth - left - props.minCenter;
65
+ if (right > center + props.minRight) {
66
+ right = clientWidth - left - center;
64
67
  } else {
65
- left = clientWidth - right - props.minCenter;
68
+ right = props.minRight;
69
+ left = clientWidth - right - center;
66
70
  }
67
71
  }
68
72
  return {
@@ -141,7 +145,7 @@ const changeRight = ({ deltaX }: OnDrag) => {
141
145
  right = props.right;
142
146
  }
143
147
 
144
- const columnWidth = getCenterWidth(clientWidth, props.left || 0, right);
148
+ const columnWidth = getCenterWidth(clientWidth, props.left, right);
145
149
 
146
150
  center.value = columnWidth.center;
147
151
 
@@ -151,4 +155,16 @@ const changeRight = ({ deltaX }: OnDrag) => {
151
155
  right: columnWidth.right,
152
156
  });
153
157
  };
158
+
159
+ defineExpose({
160
+ updateWidth() {
161
+ const columnWidth = getCenterWidth(el.value?.clientWidth || clientWidth, props.left, props.right);
162
+
163
+ emit('change', {
164
+ left: columnWidth.left,
165
+ center: center.value,
166
+ right: columnWidth.right,
167
+ });
168
+ },
169
+ });
154
170
  </script>
@@ -276,26 +276,6 @@ export const initServiceEvents = (
276
276
  };
277
277
 
278
278
  const rootChangeHandler = async (value: MApp | null, preValue?: MApp | null) => {
279
- const nodeId = editorService.get('node')?.id || props.defaultSelected;
280
- let node;
281
- if (nodeId) {
282
- node = editorService.getNodeById(nodeId);
283
- }
284
-
285
- if (node && node !== value) {
286
- await editorService.select(node.id);
287
- } else if (value?.items?.length) {
288
- await editorService.select(value.items[0]);
289
- } else if (value?.id) {
290
- editorService.set('nodes', [value]);
291
- editorService.set('parent', null);
292
- editorService.set('page', null);
293
- }
294
-
295
- if (toRaw(value) !== toRaw(preValue)) {
296
- emit('update:modelValue', value);
297
- }
298
-
299
279
  if (!value) return;
300
280
 
301
281
  value.codeBlocks = value.codeBlocks || {};
@@ -314,12 +294,32 @@ export const initServiceEvents = (
314
294
  initDataSourceDepTarget(ds);
315
295
  });
316
296
 
317
- if (value && Array.isArray(value.items)) {
297
+ if (Array.isArray(value.items)) {
318
298
  depService.collect(value.items, true);
319
299
  } else {
320
300
  depService.clear();
321
301
  delete value.dataSourceDeps;
322
302
  }
303
+
304
+ const nodeId = editorService.get('node')?.id || props.defaultSelected;
305
+ let node;
306
+ if (nodeId) {
307
+ node = editorService.getNodeById(nodeId);
308
+ }
309
+
310
+ if (node && node !== value) {
311
+ await editorService.select(node.id);
312
+ } else if (value.items?.length) {
313
+ await editorService.select(value.items[0]);
314
+ } else if (value.id) {
315
+ editorService.set('nodes', [value]);
316
+ editorService.set('parent', null);
317
+ editorService.set('page', null);
318
+ }
319
+
320
+ if (toRaw(value) !== toRaw(preValue)) {
321
+ emit('update:modelValue', value);
322
+ }
323
323
  };
324
324
 
325
325
  // 新增节点,收集依赖
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="m-editor" ref="content">
2
+ <div class="m-editor" ref="content" style="min-width: 180px">
3
3
  <slot name="header"></slot>
4
4
 
5
5
  <slot name="nav"></slot>
@@ -12,6 +12,7 @@
12
12
 
13
13
  <SplitView
14
14
  v-else
15
+ ref="splitView"
15
16
  class="m-editor-content"
16
17
  left-class="m-editor-framework-left"
17
18
  center-class="m-editor-framework-center"
@@ -20,6 +21,7 @@
20
21
  v-model:right="columnWidth.right"
21
22
  :min-left="65"
22
23
  :min-right="20"
24
+ :min-center="100"
23
25
  @change="columnWidthChange"
24
26
  >
25
27
  <template #left>
@@ -70,6 +72,7 @@ const codeOptions = inject('codeOptions', {});
70
72
  const { editorService, uiService } = inject<Services>('services') || {};
71
73
 
72
74
  const content = ref<HTMLDivElement>();
75
+ const splitView = ref<InstanceType<typeof SplitView>>();
73
76
 
74
77
  const root = computed(() => editorService?.get('root'));
75
78
 
@@ -79,8 +82,10 @@ const showSrc = computed(() => uiService?.get('showSrc'));
79
82
  const LEFT_COLUMN_WIDTH_STORAGE_KEY = '$MagicEditorLeftColumnWidthData';
80
83
  const RIGHT_COLUMN_WIDTH_STORAGE_KEY = '$MagicEditorRightColumnWidthData';
81
84
 
82
- const leftColumnWidthCacheData = Number(globalThis.localStorage.getItem(LEFT_COLUMN_WIDTH_STORAGE_KEY));
83
- const RightColumnWidthCacheData = Number(globalThis.localStorage.getItem(RIGHT_COLUMN_WIDTH_STORAGE_KEY));
85
+ const leftColumnWidthCacheData =
86
+ Number(globalThis.localStorage.getItem(LEFT_COLUMN_WIDTH_STORAGE_KEY)) || DEFAULT_LEFT_COLUMN_WIDTH;
87
+ const RightColumnWidthCacheData =
88
+ Number(globalThis.localStorage.getItem(RIGHT_COLUMN_WIDTH_STORAGE_KEY)) || DEFAULT_RIGHT_COLUMN_WIDTH;
84
89
 
85
90
  const columnWidth = ref<Partial<GetColumnWidth>>({
86
91
  left: leftColumnWidthCacheData,
@@ -89,24 +94,9 @@ const columnWidth = ref<Partial<GetColumnWidth>>({
89
94
  });
90
95
 
91
96
  watch(
92
- pageLength,
93
- (length) => {
94
- const left = columnWidth.value.left || DEFAULT_LEFT_COLUMN_WIDTH;
95
-
96
- columnWidth.value.left = left;
97
-
98
- const container = content.value || document.body;
99
-
100
- if (length <= 0) {
101
- columnWidth.value.right = undefined;
102
- columnWidth.value.center = container.clientWidth - left;
103
- } else {
104
- const right = columnWidth.value.right || RightColumnWidthCacheData || DEFAULT_RIGHT_COLUMN_WIDTH;
105
- columnWidth.value.right = right;
106
- columnWidth.value.center = container.clientWidth - left - right;
107
- }
108
-
109
- uiService?.set('columnWidth', columnWidth.value as GetColumnWidth);
97
+ [pageLength, splitView],
98
+ () => {
99
+ splitView.value?.updateWidth();
110
100
  },
111
101
  {
112
102
  immediate: true,
@@ -75,6 +75,26 @@ const getNodeTreeConfig = (id: string, dep: Dep[string], type?: string) => ({
75
75
  children: getKeyTreeConfig(dep, type),
76
76
  });
77
77
 
78
+ /**
79
+ * 生成tree中依赖节点的数据
80
+ * @param children 节点
81
+ * @param deps 依赖
82
+ * @param type 依赖类型
83
+ */
84
+ const mergeChildren = (children: any[], deps: Dep, type?: string) => {
85
+ Object.entries(deps).forEach(([id, dep]) => {
86
+ // 已经生成过的节点
87
+ const nodeItem = children.find((item) => item.id === id);
88
+ // 节点存在,则追加依赖的key
89
+ if (nodeItem) {
90
+ nodeItem.children = nodeItem.children.concat(getKeyTreeConfig(dep, type));
91
+ } else {
92
+ // 节点不存在,则生成
93
+ children.push(getNodeTreeConfig(id, dep, type));
94
+ }
95
+ });
96
+ };
97
+
78
98
  const list = computed(() =>
79
99
  dataSources.value.map((ds) => {
80
100
  const dsDeps = dsDep.value[ds.id].deps;
@@ -82,21 +102,10 @@ const list = computed(() =>
82
102
  const dsCondDeps = dsCondDep.value[ds.id].deps;
83
103
 
84
104
  const children: any[] = [];
85
-
86
- const mergeChildren = (deps: Dep, type?: string) => {
87
- Object.entries(deps).forEach(([id, dep]) => {
88
- const nodeItem = children.find((item) => item.id === id);
89
- if (nodeItem) {
90
- nodeItem.children = nodeItem.children.concat(getKeyTreeConfig(dep, type));
91
- } else {
92
- children.push(getNodeTreeConfig(id, dep, type));
93
- }
94
- });
95
- };
96
-
97
- mergeChildren(dsDeps);
98
- mergeChildren(dsMethodDeps, 'method');
99
- mergeChildren(dsCondDeps, 'cond');
105
+ // 数据源依赖分为三种类型:key/node、method、cond,是分开存储,这里将其合并展示
106
+ mergeChildren(children, dsDeps);
107
+ mergeChildren(children, dsMethodDeps, 'method');
108
+ mergeChildren(children, dsCondDeps, 'cond');
100
109
 
101
110
  return {
102
111
  id: ds.id,
@@ -26,11 +26,15 @@ import ContentMenu from '@editor/components/ContentMenu.vue';
26
26
  import type { ComponentItem, MenuButton, Services } from '@editor/type';
27
27
 
28
28
  import NodeListMenuTitle from './NodeListMenuTitle.vue';
29
+
30
+ const PINNED_STATUE_CACHE_KEY = 'tmagic-pinned-node-list-pinned-status';
31
+
29
32
  const props = defineProps<{ isMultiSelect?: boolean }>();
30
33
 
31
34
  const menu = ref<InstanceType<typeof ContentMenu>>();
32
35
  const nodeList = ref<MNode[]>([]);
33
- const pinned = ref(false);
36
+ const pinned = ref(Boolean(globalThis.localStorage.getItem(PINNED_STATUE_CACHE_KEY)));
37
+ const firstShow = ref(true);
34
38
 
35
39
  const services = inject<Services>('services');
36
40
  const editorService = services?.editorService;
@@ -94,7 +98,8 @@ const unWatch = watch(
94
98
  nodeList.value = nodes;
95
99
 
96
100
  if (nodeList.value.length > 1) {
97
- menu.value?.show(pinned.value ? undefined : event);
101
+ menu.value?.show(pinned.value && !firstShow.value ? undefined : event);
102
+ firstShow.value = false;
98
103
  }
99
104
  }, 1500);
100
105
  });
@@ -163,4 +168,8 @@ const dragMenuHandler = ({ deltaY, deltaX }: OnDrag) => {
163
168
  const closeHandler = () => {
164
169
  menu.value?.hide();
165
170
  };
171
+
172
+ watch(pinned, () => {
173
+ globalThis.localStorage.setItem(PINNED_STATUE_CACHE_KEY, pinned.value.toString());
174
+ });
166
175
  </script>
@@ -33,7 +33,7 @@
33
33
  import { computed, inject, markRaw, nextTick, onMounted, onUnmounted, ref, toRaw, watch, watchEffect } from 'vue';
34
34
  import { cloneDeep } from 'lodash-es';
35
35
 
36
- import type { MContainer } from '@tmagic/schema';
36
+ import type { MApp, MContainer } from '@tmagic/schema';
37
37
  import StageCore, { calcValueByFontsize, getOffset, Runtime } from '@tmagic/stage';
38
38
 
39
39
  import ScrollViewer from '@editor/components/ScrollViewer.vue';
@@ -105,12 +105,6 @@ watch(zoom, (zoom) => {
105
105
  stage.setZoom(zoom);
106
106
  });
107
107
 
108
- watch(root, (root) => {
109
- if (runtime && root) {
110
- runtime.updateRootConfig?.(cloneDeep(toRaw(root)));
111
- }
112
- });
113
-
114
108
  watch(page, (page) => {
115
109
  if (runtime && page) {
116
110
  runtime.updatePageId?.(page.id);
@@ -120,6 +114,14 @@ watch(page, (page) => {
120
114
  }
121
115
  });
122
116
 
117
+ const rootChangeHandler = (root: MApp) => {
118
+ if (runtime && root) {
119
+ runtime.updateRootConfig?.(cloneDeep(toRaw(root)));
120
+ }
121
+ };
122
+
123
+ services?.editorService.on('root-change', rootChangeHandler);
124
+
123
125
  const resizeObserver = new ResizeObserver((entries) => {
124
126
  for (const { contentRect } of entries) {
125
127
  services?.uiService.set('stageContainerRect', {
@@ -141,6 +143,7 @@ onUnmounted(() => {
141
143
  resizeObserver.disconnect();
142
144
  services?.editorService.set('stage', null);
143
145
  services?.keybindingService.unregisteEl('stage');
146
+ services?.editorService.off('root-change', rootChangeHandler);
144
147
  });
145
148
 
146
149
  const parseDSL = getConfig('parseDSL');
@@ -299,7 +299,7 @@ export class Watcher extends EventEmitter {
299
299
  const keyIsItems = key === 'items';
300
300
  const fullKey = prop ? `${prop}.${key}` : key;
301
301
 
302
- if (target.isTarget(key, value)) {
302
+ if (target.isTarget(fullKey, value)) {
303
303
  target.updateDep(node, fullKey);
304
304
  this.emit('update-dep', node, fullKey);
305
305
  } else if (!keyIsItems && Array.isArray(value)) {
package/src/utils/dep.ts CHANGED
@@ -58,8 +58,13 @@ export const createDataSourceCondTarget = (id: string) =>
58
58
  new Target({
59
59
  type: DepTargetType.DATA_SOURCE_COND,
60
60
  id,
61
- isTarget: (key: string | number, value: any) =>
62
- Array.isArray(value) && value[0] === id && Boolean(dataSourceService.getDataSourceById(id)),
61
+ isTarget: (key: string | number, value: any) => {
62
+ if (!Array.isArray(value) || value[0] !== id || !`${key}`.startsWith('displayConds')) return false;
63
+
64
+ const ds = dataSourceService.getDataSourceById(id);
65
+
66
+ return Boolean(ds?.fields?.find((field) => field.name === value[1]));
67
+ },
63
68
  });
64
69
 
65
70
  export const createDataSourceMethodTarget = (id: string) =>
@@ -15,7 +15,10 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
15
15
  top: number;
16
16
  }>;
17
17
  hide: () => void;
18
- show: (e?: MouseEvent | undefined) => void;
18
+ show: (e?: {
19
+ clientY: number;
20
+ clientX: number;
21
+ } | undefined) => void;
19
22
  contains: (el: HTMLElement) => any;
20
23
  setPosition: (e: {
21
24
  clientY: number;
@@ -11,7 +11,9 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
11
11
  minLeft: number;
12
12
  minRight: number;
13
13
  minCenter: number;
14
- }>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("change" | "update:left" | "update:right")[], "change" | "update:left" | "update:right", import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
14
+ }>, {
15
+ updateWidth(): void;
16
+ }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("change" | "update:left" | "update:right")[], "change" | "update:left" | "update:right", import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
15
17
  left?: number | undefined;
16
18
  right?: number | undefined;
17
19
  minLeft?: number | undefined;