@tmagic/editor 1.5.2 → 1.5.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.
Files changed (89) hide show
  1. package/dist/style.css +366 -6
  2. package/dist/tmagic-editor.js +1749 -829
  3. package/dist/tmagic-editor.umd.cjs +1764 -843
  4. package/package.json +7 -7
  5. package/src/components/CodeBlockEditor.vue +3 -3
  6. package/src/components/CodeParams.vue +2 -2
  7. package/src/components/ContentMenu.vue +13 -13
  8. package/src/components/FloatingBox.vue +9 -9
  9. package/src/components/Resizer.vue +2 -2
  10. package/src/components/ScrollBar.vue +6 -7
  11. package/src/components/ScrollViewer.vue +6 -6
  12. package/src/components/SplitView.vue +3 -3
  13. package/src/fields/DataSourceInput.vue +3 -3
  14. package/src/fields/DataSourceMethods.vue +4 -4
  15. package/src/fields/DisplayConds.vue +2 -1
  16. package/src/fields/StyleSetter/Index.vue +69 -0
  17. package/src/fields/StyleSetter/components/BackgroundPosition.vue +71 -0
  18. package/src/fields/StyleSetter/components/Border.vue +104 -0
  19. package/src/fields/StyleSetter/components/Box.vue +73 -0
  20. package/src/fields/StyleSetter/components/Position.vue +54 -0
  21. package/src/fields/StyleSetter/icons/background-position/LeftBottom.vue +7 -0
  22. package/src/fields/StyleSetter/icons/background-position/LeftCenter.vue +7 -0
  23. package/src/fields/StyleSetter/icons/background-position/LeftTop.vue +12 -0
  24. package/src/fields/StyleSetter/icons/background-position/index.ts +3 -0
  25. package/src/fields/StyleSetter/icons/background-repeat/NoRepeat.vue +8 -0
  26. package/src/fields/StyleSetter/icons/background-repeat/Repeat.vue +31 -0
  27. package/src/fields/StyleSetter/icons/background-repeat/RepeatX.vue +8 -0
  28. package/src/fields/StyleSetter/icons/background-repeat/RepeatY.vue +8 -0
  29. package/src/fields/StyleSetter/icons/background-repeat/index.ts +4 -0
  30. package/src/fields/StyleSetter/icons/display/Block.vue +7 -0
  31. package/src/fields/StyleSetter/icons/display/Flex.vue +7 -0
  32. package/src/fields/StyleSetter/icons/display/Inline.vue +7 -0
  33. package/src/fields/StyleSetter/icons/display/InlineBlock.vue +7 -0
  34. package/src/fields/StyleSetter/icons/display/None.vue +7 -0
  35. package/src/fields/StyleSetter/icons/display/index.ts +5 -0
  36. package/src/fields/StyleSetter/icons/flex-direction/Column.vue +7 -0
  37. package/src/fields/StyleSetter/icons/flex-direction/ColumnReverse.vue +7 -0
  38. package/src/fields/StyleSetter/icons/flex-direction/Row.vue +7 -0
  39. package/src/fields/StyleSetter/icons/flex-direction/RowReverse.vue +7 -0
  40. package/src/fields/StyleSetter/icons/flex-direction/index.ts +4 -0
  41. package/src/fields/StyleSetter/icons/justify-content/Center.vue +5 -0
  42. package/src/fields/StyleSetter/icons/justify-content/FlexEnd.vue +5 -0
  43. package/src/fields/StyleSetter/icons/justify-content/FlexStart.vue +5 -0
  44. package/src/fields/StyleSetter/icons/justify-content/SpaceAround.vue +7 -0
  45. package/src/fields/StyleSetter/icons/justify-content/SpaceBetween.vue +5 -0
  46. package/src/fields/StyleSetter/icons/justify-content/index.ts +5 -0
  47. package/src/fields/StyleSetter/icons/text-align/Center.vue +7 -0
  48. package/src/fields/StyleSetter/icons/text-align/Left.vue +7 -0
  49. package/src/fields/StyleSetter/icons/text-align/Right.vue +7 -0
  50. package/src/fields/StyleSetter/icons/text-align/index.ts +3 -0
  51. package/src/fields/StyleSetter/pro/Background.vue +78 -0
  52. package/src/fields/StyleSetter/pro/Border.vue +35 -0
  53. package/src/fields/StyleSetter/pro/Font.vue +90 -0
  54. package/src/fields/StyleSetter/pro/Layout.vue +164 -0
  55. package/src/fields/StyleSetter/pro/Position.vue +48 -0
  56. package/src/fields/StyleSetter/pro/index.ts +5 -0
  57. package/src/hooks/use-code-block-edit.ts +5 -5
  58. package/src/index.ts +3 -0
  59. package/src/initService.ts +104 -66
  60. package/src/layouts/CodeEditor.vue +6 -6
  61. package/src/layouts/Framework.vue +5 -5
  62. package/src/layouts/NavMenu.vue +6 -3
  63. package/src/layouts/page-bar/PageBar.vue +13 -13
  64. package/src/layouts/page-bar/PageBarScrollContainer.vue +12 -11
  65. package/src/layouts/props-panel/FormPanel.vue +7 -7
  66. package/src/layouts/props-panel/PropsPanel.vue +36 -4
  67. package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +3 -3
  68. package/src/layouts/sidebar/layer/LayerMenu.vue +2 -2
  69. package/src/layouts/sidebar/layer/LayerPanel.vue +5 -4
  70. package/src/layouts/sidebar/layer/use-click.ts +4 -6
  71. package/src/layouts/workspace/viewer/NodeListMenu.vue +5 -5
  72. package/src/layouts/workspace/viewer/Stage.vue +13 -13
  73. package/src/layouts/workspace/viewer/StageOverlay.vue +2 -2
  74. package/src/layouts/workspace/viewer/ViewerMenu.vue +3 -3
  75. package/src/services/componentList.ts +2 -2
  76. package/src/services/dep.ts +8 -2
  77. package/src/services/editor.ts +2 -2
  78. package/src/services/stageOverlay.ts +2 -2
  79. package/src/services/ui.ts +2 -2
  80. package/src/theme/props-panel.scss +13 -0
  81. package/src/theme/resizer.scss +2 -2
  82. package/src/theme/style-setter/background.scss +113 -0
  83. package/src/theme/style-setter/border.scss +53 -0
  84. package/src/theme/style-setter/index.scss +28 -0
  85. package/src/theme/style-setter/layout.scss +199 -0
  86. package/src/theme/theme.scss +1 -0
  87. package/src/utils/idle-task.ts +26 -10
  88. package/src/utils/props.ts +52 -297
  89. package/types/index.d.ts +432 -170
@@ -0,0 +1,164 @@
1
+ <template>
2
+ <MContainer :config="config" :model="values" @change="change"></MContainer>
3
+ <Box :model="values" @change="change"></Box>
4
+ </template>
5
+
6
+ <script lang="ts" setup>
7
+ import { markRaw } from 'vue';
8
+
9
+ import type { ContainerChangeEventData, FormState } from '@tmagic/form';
10
+ import { MContainer } from '@tmagic/form';
11
+ import type { StyleSchema } from '@tmagic/schema';
12
+
13
+ import Box from '../components/Box.vue';
14
+ import { DisplayBlock, DisplayFlex, DisplayInline, DisplayInlineBlock, DisplayNone } from '../icons/display';
15
+ import {
16
+ FlexDirectionColumn,
17
+ FlexDirectionColumnReverse,
18
+ FlexDirectionRow,
19
+ FlexDirectionRowReverse,
20
+ } from '../icons/flex-direction';
21
+ import {
22
+ JustifyContentCenter,
23
+ JustifyContentFlexEnd,
24
+ JustifyContentFlexStart,
25
+ JustifyContentSpaceAround,
26
+ JustifyContentSpaceBetween,
27
+ } from '../icons/justify-content';
28
+
29
+ defineProps<{
30
+ values: Partial<StyleSchema>;
31
+ }>();
32
+
33
+ const emit = defineEmits<{
34
+ change: [v: string | StyleSchema, eventData: ContainerChangeEventData];
35
+ }>();
36
+
37
+ const config = {
38
+ items: [
39
+ {
40
+ name: 'display',
41
+ text: '模式',
42
+ type: 'radioGroup',
43
+ childType: 'button',
44
+ labelWidth: '68px',
45
+ options: [
46
+ { value: 'inline', icon: markRaw(DisplayInline), tooltip: '内联布局 inline' },
47
+ { value: 'flex', icon: markRaw(DisplayFlex), tooltip: '弹性布局 flex' },
48
+ { value: 'block', icon: markRaw(DisplayBlock), tooltip: '块级布局 block' },
49
+ { value: 'inline-block', icon: markRaw(DisplayInlineBlock), tooltip: '内联块布局 inline-block' },
50
+ { value: 'none', icon: markRaw(DisplayNone), tooltip: '隐藏 none' },
51
+ ],
52
+ },
53
+ {
54
+ name: 'flexDirection',
55
+ text: '主轴方向',
56
+ type: 'radioGroup',
57
+ childType: 'button',
58
+ labelWidth: '68px',
59
+ options: [
60
+ { value: 'row', icon: markRaw(FlexDirectionRow), tooltip: '水平方向 起点在左侧 row' },
61
+ { value: 'row-reverse', icon: markRaw(FlexDirectionRowReverse), tooltip: '水平方向 起点在右侧 row-reverse' },
62
+ { value: 'column', icon: markRaw(FlexDirectionColumn), tooltip: '垂直方向 起点在上沿 column' },
63
+ {
64
+ value: 'column-reverse',
65
+ icon: markRaw(FlexDirectionColumnReverse),
66
+ tooltip: '垂直方向 起点在下沿 column-reverse',
67
+ },
68
+ ],
69
+ display: (mForm: FormState, { model }: { model: Record<any, any> }) => model.display === 'flex',
70
+ },
71
+ {
72
+ name: 'justifyContent',
73
+ text: '主轴对齐',
74
+ type: 'radioGroup',
75
+ childType: 'button',
76
+ labelWidth: '68px',
77
+ options: [
78
+ { value: 'flex-start', icon: markRaw(JustifyContentFlexStart), tooltip: '左对齐 flex-start' },
79
+ { value: 'flex-end', icon: markRaw(JustifyContentFlexEnd), tooltip: '右对齐 flex-end' },
80
+ { value: 'center', icon: markRaw(JustifyContentCenter), tooltip: '居中 center' },
81
+ { value: 'space-between', icon: markRaw(JustifyContentSpaceBetween), tooltip: '两端对齐 space-between' },
82
+ { value: 'space-around', icon: markRaw(JustifyContentSpaceAround), tooltip: '横向平分 space-around' },
83
+ ],
84
+ display: (mForm: FormState, { model }: { model: Record<any, any> }) => model.display === 'flex',
85
+ },
86
+ {
87
+ name: 'alignItems',
88
+ text: '辅轴对齐',
89
+ type: 'radioGroup',
90
+ childType: 'button',
91
+ labelWidth: '68px',
92
+ options: [
93
+ { value: 'flex-start', icon: markRaw(JustifyContentFlexStart), tooltip: '左对齐 flex-start' },
94
+ { value: 'flex-end', icon: markRaw(JustifyContentFlexEnd), tooltip: '右对齐 flex-end' },
95
+ { value: 'center', icon: markRaw(JustifyContentCenter), tooltip: '居中 center' },
96
+ { value: 'space-between', icon: markRaw(JustifyContentSpaceBetween), tooltip: '两端对齐 space-between' },
97
+ { value: 'space-around', icon: markRaw(JustifyContentSpaceAround), tooltip: '横向平分 space-around' },
98
+ ],
99
+ display: (mForm: FormState, { model }: { model: Record<any, any> }) => model.display === 'flex',
100
+ },
101
+ {
102
+ name: 'flexWrap',
103
+ text: '换行',
104
+ type: 'radioGroup',
105
+ childType: 'button',
106
+ labelWidth: '68px',
107
+ options: [
108
+ { value: 'nowrap', text: '不换行', tooltip: '不换行 nowrap' },
109
+ { value: 'wrap', text: '正换行', tooltip: '第一行在上方 wrap' },
110
+ { value: 'wrap-reverse', text: '逆换行', tooltip: '第一行在下方 wrap-reverse' },
111
+ ],
112
+ display: (mForm: FormState, { model }: { model: Record<any, any> }) => model.display === 'flex',
113
+ },
114
+ {
115
+ type: 'row',
116
+ items: [
117
+ {
118
+ name: 'width',
119
+ text: '宽度',
120
+ labelWidth: '68px',
121
+ type: 'data-source-field-select',
122
+ fieldConfig: {
123
+ type: 'text',
124
+ },
125
+ },
126
+ {
127
+ name: 'height',
128
+ text: '宽度',
129
+ labelWidth: '68px',
130
+ type: 'data-source-field-select',
131
+ fieldConfig: {
132
+ type: 'text',
133
+ },
134
+ },
135
+ ],
136
+ },
137
+ {
138
+ type: 'data-source-field-select',
139
+ text: 'overflow',
140
+ name: 'overflow',
141
+ checkStrictly: false,
142
+ dataSourceFieldType: ['string'],
143
+ fieldConfig: {
144
+ type: 'select',
145
+ clearable: true,
146
+ allowCreate: true,
147
+ options: [
148
+ { text: 'visible', value: 'visible' },
149
+ { text: 'hidden', value: 'hidden' },
150
+ { text: 'clip', value: 'clip' },
151
+ { text: 'scroll', value: 'scroll' },
152
+ { text: 'auto', value: 'auto' },
153
+ { text: 'overlay', value: 'overlay' },
154
+ { text: 'initial', value: 'initial' },
155
+ ],
156
+ },
157
+ },
158
+ ],
159
+ };
160
+
161
+ const change = (value: string | StyleSchema, eventData: ContainerChangeEventData) => {
162
+ emit('change', value, eventData);
163
+ };
164
+ </script>
@@ -0,0 +1,48 @@
1
+ <template>
2
+ <MContainer :config="config" :model="values" @change="change"></MContainer>
3
+ <Position v-show="values['position'] !== 'static'" :model="values" @change="change"></Position>
4
+ </template>
5
+
6
+ <script lang="ts" setup>
7
+ import { ContainerChangeEventData, MContainer } from '@tmagic/form';
8
+ import type { StyleSchema } from '@tmagic/schema';
9
+
10
+ import Position from '../components/Position.vue';
11
+
12
+ defineProps<{ values: Partial<StyleSchema> }>();
13
+
14
+ const emit = defineEmits<{
15
+ change: [v: string | StyleSchema, eventData: ContainerChangeEventData];
16
+ }>();
17
+
18
+ const config = {
19
+ items: [
20
+ {
21
+ name: 'position',
22
+ text: '定位',
23
+ labelWidth: '68px',
24
+ type: 'data-source-field-select',
25
+ fieldConfig: {
26
+ type: 'select',
27
+ options: ['static', 'relative', 'absolute', 'fixed', 'sticky'].map((item) => ({
28
+ value: item,
29
+ text: item,
30
+ })),
31
+ },
32
+ },
33
+ {
34
+ labelWidth: '68px',
35
+ name: 'zIndex',
36
+ text: 'zIndex',
37
+ type: 'data-source-field-select',
38
+ fieldConfig: {
39
+ type: 'text',
40
+ },
41
+ },
42
+ ],
43
+ };
44
+
45
+ const change = (value: string | StyleSchema, eventData: ContainerChangeEventData) => {
46
+ emit('change', value, eventData);
47
+ };
48
+ </script>
@@ -0,0 +1,5 @@
1
+ export { default as Background } from './Background.vue';
2
+ export { default as Font } from './Font.vue';
3
+ export { default as Layout } from './Layout.vue';
4
+ export { default as Position } from './Position.vue';
5
+ export { default as Border } from './Border.vue';
@@ -10,7 +10,7 @@ import type { CodeBlockService } from '@editor/services/codeBlock';
10
10
  export const useCodeBlockEdit = (codeBlockService?: CodeBlockService) => {
11
11
  const codeConfig = ref<CodeBlockContent>();
12
12
  const codeId = ref<string>();
13
- const codeBlockEditor = useTemplateRef<InstanceType<typeof CodeBlockEditor>>('codeBlockEditor');
13
+ const codeBlockEditorRef = useTemplateRef<InstanceType<typeof CodeBlockEditor>>('codeBlockEditor');
14
14
 
15
15
  // 新增代码块
16
16
  const createCodeBlock = async () => {
@@ -29,7 +29,7 @@ export const useCodeBlockEdit = (codeBlockService?: CodeBlockService) => {
29
29
 
30
30
  await nextTick();
31
31
 
32
- codeBlockEditor.value?.show();
32
+ codeBlockEditorRef.value?.show();
33
33
  };
34
34
 
35
35
  // 编辑代码块
@@ -54,7 +54,7 @@ export const useCodeBlockEdit = (codeBlockService?: CodeBlockService) => {
54
54
  codeId.value = id;
55
55
 
56
56
  await nextTick();
57
- codeBlockEditor.value?.show();
57
+ codeBlockEditorRef.value?.show();
58
58
  };
59
59
 
60
60
  // 删除代码块
@@ -67,13 +67,13 @@ export const useCodeBlockEdit = (codeBlockService?: CodeBlockService) => {
67
67
 
68
68
  await codeBlockService?.setCodeDslById(codeId.value, values);
69
69
 
70
- codeBlockEditor.value?.hide();
70
+ codeBlockEditorRef.value?.hide();
71
71
  };
72
72
 
73
73
  return {
74
74
  codeId,
75
75
  codeConfig,
76
- codeBlockEditor,
76
+ codeBlockEditor: codeBlockEditorRef,
77
77
 
78
78
  createCodeBlock,
79
79
  editCode,
package/src/index.ts CHANGED
@@ -39,6 +39,7 @@ import DisplayConds from './fields/DisplayConds.vue';
39
39
  import EventSelect from './fields/EventSelect.vue';
40
40
  import KeyValue from './fields/KeyValue.vue';
41
41
  import PageFragmentSelect from './fields/PageFragmentSelect.vue';
42
+ import StyleSetter from './fields/StyleSetter/Index.vue';
42
43
  import uiSelect from './fields/UISelect.vue';
43
44
  import CodeEditor from './layouts/CodeEditor.vue';
44
45
  import { setEditorConfig } from './utils/config';
@@ -106,6 +107,7 @@ export { default as TreeNode } from './components/TreeNode.vue';
106
107
  export { default as PageFragmentSelect } from './fields/PageFragmentSelect.vue';
107
108
  export { default as DisplayConds } from './fields/DisplayConds.vue';
108
109
  export { default as CondOpSelect } from './fields/CondOpSelect.vue';
110
+ export { default as StyleSetter } from './fields/StyleSetter/Index.vue';
109
111
 
110
112
  const defaultInstallOpt: EditorInstallOptions = {
111
113
  // eslint-disable-next-line no-eval
@@ -143,5 +145,6 @@ export default {
143
145
  app.component('m-fields-page-fragment-select', PageFragmentSelect);
144
146
  app.component('m-fields-display-conds', DisplayConds);
145
147
  app.component('m-fields-cond-op-select', CondOpSelect);
148
+ app.component('m-form-style-setter', StyleSetter);
146
149
  },
147
150
  };
@@ -1,6 +1,7 @@
1
1
  import { computed, onBeforeUnmount, reactive, toRaw, watch } from 'vue';
2
2
  import { cloneDeep } from 'lodash-es';
3
3
 
4
+ import type TMagicCore from '@tmagic/core';
4
5
  import type {
5
6
  CodeBlockContent,
6
7
  DataSourceSchema,
@@ -263,67 +264,46 @@ export const initServiceEvents = (
263
264
 
264
265
  if (!node) return;
265
266
 
266
- collectIdle([node], true).then(() => {
267
- afterUpdateNodes([node]);
268
- });
267
+ collectIdle([node], true);
268
+ updateStage([node]);
269
269
  });
270
270
  });
271
271
 
272
- const getApp = () => stage.value?.renderer?.runtime?.getApp?.();
273
-
274
- const updateDataSourceSchema = (nodes: MNode[], deep: boolean) => {
275
- const root = editorService.get('root');
276
- const app = getApp();
277
-
278
- if (root && app?.dsl) {
279
- app.dsl.dataSourceDeps = root.dataSourceDeps;
280
- app.dsl.dataSourceCondDeps = root.dataSourceCondDeps;
281
- app.dsl.dataSources = root.dataSources;
272
+ const getApp = () => {
273
+ const renderer = stage.value?.renderer;
274
+ if (!renderer) {
275
+ return undefined;
282
276
  }
283
277
 
284
- if (root?.dataSources) {
285
- getApp()?.dataSourceManager?.updateSchema(root.dataSources);
278
+ if (renderer.runtime) {
279
+ return renderer.runtime.getApp?.();
286
280
  }
287
281
 
288
- if (!root || !stage.value) return;
282
+ return new Promise<TMagicCore | undefined>((resolve) => {
283
+ const timeout = globalThis.setTimeout(() => {
284
+ resolve(undefined);
285
+ }, 10000);
289
286
 
290
- const allNodes: MNode[] = [];
291
-
292
- if (deep) {
293
- nodes.forEach((node) => {
294
- traverseNode<MNode>(node, (node) => {
295
- if (!allNodes.includes(node)) {
296
- allNodes.push(node);
297
- }
298
- });
299
- });
300
- } else {
301
- allNodes.push(...nodes);
302
- }
303
-
304
- const deps = Object.values(root.dataSourceDeps || {});
305
- deps.forEach((dep) => {
306
- Object.keys(dep).forEach((id) => {
307
- const node = allNodes.find((node) => node.id === id);
308
- node &&
309
- stage.value?.update({
310
- config: cloneDeep(node),
311
- parentId: editorService.getParentById(node.id)?.id,
312
- root: cloneDeep(root),
313
- });
287
+ renderer.on('runtime-ready', () => {
288
+ if (timeout) {
289
+ globalThis.clearTimeout(timeout);
290
+ }
291
+ resolve(renderer.runtime?.getApp?.());
314
292
  });
315
293
  });
316
294
  };
317
295
 
318
- const afterUpdateNodes = (nodes: MNode[]) => {
296
+ const updateDataSourceSchema = async () => {
319
297
  const root = editorService.get('root');
320
- if (!root) return;
321
- for (const node of nodes) {
322
- stage.value?.update({
323
- config: cloneDeep(node),
324
- parentId: editorService.getParentById(node.id)?.id,
325
- root: cloneDeep(root),
326
- });
298
+ const app = await getApp();
299
+
300
+ if (root && app?.dsl) {
301
+ app.dsl.dataSourceDeps = root.dataSourceDeps;
302
+ app.dsl.dataSources = root.dataSources;
303
+ }
304
+
305
+ if (root?.dataSources) {
306
+ app?.dataSourceManager?.updateSchema(root.dataSources);
327
307
  }
328
308
  };
329
309
 
@@ -360,18 +340,72 @@ export const initServiceEvents = (
360
340
  }
361
341
  };
362
342
 
363
- const depCollectedHandler = () => {
343
+ /**
344
+ * 修改dsl后会执行依赖收集并调用此方法
345
+ * 所以这个方法是会被执行两次,当时updateStage应当时一次,所以通过inDeps参数来区分调用时机
346
+ * inDeps为true是则更新依赖收集到的节点,否则则更新没有依赖的节点
347
+ * @param nodes 需要更新的节点
348
+ * @param inDeps 是否依赖收集完成事件中执行的
349
+ * @returns
350
+ */
351
+ const updateStage = (nodes: MNode[], inDeps = false) => {
364
352
  const root = editorService.get('root');
365
353
  if (!root) return;
366
- const app = getApp();
354
+
355
+ const update = (node: MNode) =>
356
+ stage.value?.update({
357
+ config: cloneDeep(node),
358
+ parentId: editorService.getParentById(node.id)?.id,
359
+ root: cloneDeep(root),
360
+ });
361
+
362
+ nodes.forEach((node) => {
363
+ const inDepsNodeId: Id[] = [];
364
+ const deps = Object.values(root.dataSourceDeps || {});
365
+ deps.forEach((dep) => {
366
+ Object.keys(dep).forEach((id) => {
367
+ inDepsNodeId.push(id);
368
+ });
369
+ });
370
+
371
+ if (inDeps) {
372
+ if (inDepsNodeId.includes(node.id)) {
373
+ update(node);
374
+ }
375
+ } else {
376
+ if (!inDepsNodeId.includes(node.id)) {
377
+ update(node);
378
+ }
379
+ }
380
+ });
381
+ };
382
+
383
+ const dsDepCollectedHandler = async (nodes: MNode[], deep: boolean) => {
384
+ const root = editorService.get('root');
385
+ if (!root) return;
386
+ const app = await getApp();
367
387
  if (app?.dsl) {
368
388
  app.dsl.dataSourceDeps = root.dataSourceDeps;
369
389
  }
390
+ if (deep) {
391
+ nodes.forEach((node) => {
392
+ traverseNode<MNode>(
393
+ node,
394
+ (node) => {
395
+ updateStage([node], true);
396
+ },
397
+ [],
398
+ true,
399
+ );
400
+ });
401
+ } else {
402
+ updateStage(nodes, true);
403
+ }
370
404
  };
371
405
 
372
406
  depService.on('add-target', targetAddHandler);
373
407
  depService.on('remove-target', targetRemoveHandler);
374
- depService.on('collected', depCollectedHandler);
408
+ depService.on('ds-collected', dsDepCollectedHandler);
375
409
 
376
410
  const initDataSourceDepTarget = (ds: DataSourceSchema) => {
377
411
  depService.addTarget(createDataSourceTarget(ds, reactive({})));
@@ -396,9 +430,9 @@ export const initServiceEvents = (
396
430
 
397
431
  // 新增节点,收集依赖
398
432
  const nodeAddHandler = (nodes: MNode[]) => {
399
- collectIdle(nodes, true).then(() => {
400
- afterUpdateNodes(nodes);
401
- });
433
+ collectIdle(nodes, true);
434
+
435
+ updateStage(nodes);
402
436
  };
403
437
 
404
438
  // 节点更新,收集依赖
@@ -430,11 +464,10 @@ export const initServiceEvents = (
430
464
  });
431
465
 
432
466
  if (needRecollectNodes.length) {
433
- collectIdle(needRecollectNodes, true).then(() => {
434
- afterUpdateNodes(needRecollectNodes);
435
- });
467
+ collectIdle(needRecollectNodes, true);
468
+ updateStage(needRecollectNodes);
436
469
  } else if (normalNodes.length) {
437
- afterUpdateNodes(normalNodes);
470
+ updateStage(normalNodes);
438
471
  }
439
472
  };
440
473
 
@@ -446,7 +479,7 @@ export const initServiceEvents = (
446
479
  // 由于历史记录变化是更新整个page,所以历史记录变化时,需要重新收集依赖
447
480
  const historyChangeHandler = (page: MPage | MPageFragment) => {
448
481
  collectIdle([page], true).then(() => {
449
- updateDataSourceSchema([page], true);
482
+ updateDataSourceSchema();
450
483
  });
451
484
  };
452
485
 
@@ -472,12 +505,16 @@ export const initServiceEvents = (
472
505
  codeBlockService.on('addOrUpdate', codeBlockAddOrUpdateHandler);
473
506
  codeBlockService.on('remove', codeBlockRemoveHandler);
474
507
 
475
- const dataSourceAddHandler = (config: DataSourceSchema) => {
508
+ const dataSourceAddHandler = async (config: DataSourceSchema) => {
476
509
  initDataSourceDepTarget(config);
477
- getApp()?.dataSourceManager?.addDataSource(config);
510
+ const app = await getApp();
511
+ app?.dataSourceManager?.addDataSource(config);
478
512
  };
479
513
 
480
- const dataSourceUpdateHandler = (config: DataSourceSchema, { changeRecords }: { changeRecords: ChangeRecord[] }) => {
514
+ const dataSourceUpdateHandler = async (
515
+ config: DataSourceSchema,
516
+ { changeRecords }: { changeRecords: ChangeRecord[] },
517
+ ) => {
481
518
  let needRecollectDep = false;
482
519
  for (const changeRecord of changeRecords) {
483
520
  if (!changeRecord.propPath) {
@@ -506,11 +543,12 @@ export const initServiceEvents = (
506
543
  initDataSourceDepTarget(config);
507
544
 
508
545
  collectIdle(root.items, true).then(() => {
509
- updateDataSourceSchema(root?.items || [], true);
546
+ updateDataSourceSchema();
510
547
  });
511
548
  }
512
549
  } else if (root?.dataSources) {
513
- getApp()?.dataSourceManager?.updateSchema(root.dataSources);
550
+ const app = await getApp();
551
+ app?.dataSourceManager?.updateSchema(root.dataSources);
514
552
  }
515
553
  };
516
554
 
@@ -525,7 +563,7 @@ export const initServiceEvents = (
525
563
  const nodeIds = Object.keys(root?.dataSourceDeps?.[id] || {});
526
564
  const nodes = getNodes(nodeIds, root?.items);
527
565
  collectIdle(nodes, false).then(() => {
528
- updateDataSourceSchema(nodes, false);
566
+ updateDataSourceSchema();
529
567
  });
530
568
 
531
569
  removeDataSourceTarget(id);
@@ -538,7 +576,7 @@ export const initServiceEvents = (
538
576
  onBeforeUnmount(() => {
539
577
  depService.off('add-target', targetAddHandler);
540
578
  depService.off('remove-target', targetRemoveHandler);
541
- depService.off('collected', depCollectedHandler);
579
+ depService.off('ds-collected', dsDepCollectedHandler);
542
580
 
543
581
  editorService.off('history-change', historyChangeHandler);
544
582
  editorService.off('root-change', rootChangeHandler);
@@ -93,7 +93,7 @@ let vsDiffEditor: monaco.editor.IStandaloneDiffEditor | null = null;
93
93
 
94
94
  const values = ref('');
95
95
  const loading = ref(false);
96
- const codeEditor = useTemplateRef<HTMLDivElement>('codeEditor');
96
+ const codeEditorEl = useTemplateRef<HTMLDivElement>('codeEditor');
97
97
 
98
98
  const resizeObserver = new globalThis.ResizeObserver(
99
99
  throttle((): void => {
@@ -122,7 +122,7 @@ const getEditorValue = () =>
122
122
  (props.type === 'diff' ? vsDiffEditor?.getModifiedEditor().getValue() : vsEditor?.getValue()) || '';
123
123
 
124
124
  const init = async () => {
125
- if (!codeEditor.value) return;
125
+ if (!codeEditorEl.value) return;
126
126
 
127
127
  const options = {
128
128
  value: values.value,
@@ -132,9 +132,9 @@ const init = async () => {
132
132
  };
133
133
 
134
134
  if (props.type === 'diff') {
135
- vsDiffEditor = monaco.editor.createDiffEditor(codeEditor.value, options);
135
+ vsDiffEditor = monaco.editor.createDiffEditor(codeEditorEl.value, options);
136
136
  } else {
137
- vsEditor = monaco.editor.create(codeEditor.value, options);
137
+ vsEditor = monaco.editor.create(codeEditorEl.value, options);
138
138
  }
139
139
 
140
140
  setEditorValue(props.initValues, props.modifiedValues);
@@ -143,7 +143,7 @@ const init = async () => {
143
143
 
144
144
  emit('initd', vsEditor);
145
145
 
146
- codeEditor.value.addEventListener('keydown', (e) => {
146
+ codeEditorEl.value.addEventListener('keydown', (e) => {
147
147
  if (e.keyCode === 83 && (navigator.platform.match('Mac') ? e.metaKey : e.ctrlKey)) {
148
148
  e.preventDefault();
149
149
  e.stopPropagation();
@@ -163,7 +163,7 @@ const init = async () => {
163
163
  });
164
164
  }
165
165
 
166
- resizeObserver.observe(codeEditor.value);
166
+ resizeObserver.observe(codeEditorEl.value);
167
167
  };
168
168
 
169
169
  watch(
@@ -90,8 +90,8 @@ const DEFAULT_RIGHT_COLUMN_WIDTH = 480;
90
90
  const codeOptions = inject('codeOptions', {});
91
91
  const { editorService, uiService } = inject<Services>('services') || {};
92
92
 
93
- const content = useTemplateRef<HTMLDivElement>('content');
94
- const splitView = useTemplateRef<InstanceType<typeof SplitView>>('splitView');
93
+ const contentEl = useTemplateRef<HTMLDivElement>('content');
94
+ const splitViewRef = useTemplateRef<InstanceType<typeof SplitView>>('splitView');
95
95
 
96
96
  const root = computed(() => editorService?.get('root'));
97
97
  const page = computed(() => editorService?.get('page'));
@@ -115,7 +115,7 @@ const columnWidth = ref<Partial<GetColumnWidth>>({
115
115
  });
116
116
 
117
117
  watch(pageLength, () => {
118
- splitView.value?.updateWidth();
118
+ splitViewRef.value?.updateWidth();
119
119
  });
120
120
 
121
121
  watch(
@@ -146,8 +146,8 @@ const resizerObserver = new ResizeObserver((entries) => {
146
146
  });
147
147
 
148
148
  onMounted(() => {
149
- if (content.value) {
150
- resizerObserver.observe(content.value);
149
+ if (contentEl.value) {
150
+ resizerObserver.observe(contentEl.value);
151
151
  }
152
152
  });
153
153
 
@@ -179,8 +179,10 @@ const buttons = computed(() => {
179
179
  return data;
180
180
  });
181
181
 
182
+ const navMenuEl = useTemplateRef<HTMLDivElement>('navMenu');
183
+
182
184
  const resizeObserver = new ResizeObserver(() => {
183
- const rect = navMenu.value?.getBoundingClientRect();
185
+ const rect = navMenuEl.value?.getBoundingClientRect();
184
186
  if (rect) {
185
187
  uiService?.set('navMenuRect', {
186
188
  left: rect.left,
@@ -190,10 +192,11 @@ const resizeObserver = new ResizeObserver(() => {
190
192
  });
191
193
  }
192
194
  });
193
- const navMenu = useTemplateRef<HTMLDivElement>('navMenu');
195
+
194
196
  onMounted(() => {
195
- navMenu.value && resizeObserver.observe(navMenu.value);
197
+ navMenuEl.value && resizeObserver.observe(navMenuEl.value);
196
198
  });
199
+
197
200
  onBeforeUnmount(() => {
198
201
  resizeObserver.disconnect();
199
202
  });