@tmagic/editor 1.8.0-manmanyu.26 → 1.8.0-manmanyu.28

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 (101) hide show
  1. package/dist/es/Editor.vue_vue_type_script_setup_true_lang.js +9 -4
  2. package/dist/es/components/CodeBlockEditor.vue_vue_type_script_setup_true_lang.js +1 -1
  3. package/dist/es/components/CodeParams.vue_vue_type_script_setup_true_lang.js +2 -1
  4. package/dist/es/components/CompareForm.vue_vue_type_script_setup_true_lang.js +13 -121
  5. package/dist/es/components/FloatingBox.vue_vue_type_script_setup_true_lang.js +4 -1
  6. package/dist/es/components/ScrollBar.js +0 -1
  7. package/dist/es/components/ViewForm.js +5 -0
  8. package/dist/es/components/ViewForm.vue_vue_type_script_setup_true_lang.js +58 -0
  9. package/dist/es/editorProps.js +6 -1
  10. package/dist/es/fields/CodeSelect.vue_vue_type_script_setup_true_lang.js +14 -1
  11. package/dist/es/fields/CondOpSelect.vue_vue_type_script_setup_true_lang.js +2 -17
  12. package/dist/es/fields/DataSourceFieldSelect/FieldSelect.vue_vue_type_script_setup_true_lang.js +2 -1
  13. package/dist/es/fields/DataSourceInput.vue_vue_type_script_setup_true_lang.js +5 -17
  14. package/dist/es/fields/DisplayConds.vue_vue_type_script_setup_true_lang.js +29 -3
  15. package/dist/es/fields/EventSelect.vue_vue_type_script_setup_true_lang.js +50 -88
  16. package/dist/es/fields/StyleSetter/Index.vue_vue_type_script_setup_true_lang.js +2 -5
  17. package/dist/es/fields/StyleSetter/pro/Background.vue_vue_type_script_setup_true_lang.js +78 -22
  18. package/dist/es/fields/StyleSetter/pro/Border.vue_vue_type_script_setup_true_lang.js +6 -3
  19. package/dist/es/fields/StyleSetter/pro/Font.vue_vue_type_script_setup_true_lang.js +28 -22
  20. package/dist/es/fields/StyleSetter/pro/Layout.vue_vue_type_script_setup_true_lang.js +28 -22
  21. package/dist/es/fields/StyleSetter/pro/Position.vue_vue_type_script_setup_true_lang.js +28 -22
  22. package/dist/es/fields/StyleSetter/pro/Transform.vue_vue_type_script_setup_true_lang.js +6 -3
  23. package/dist/es/fields/UISelect.js +0 -1
  24. package/dist/es/hooks/use-compare-form.js +119 -0
  25. package/dist/es/index.js +13 -8
  26. package/dist/es/layouts/CodeEditor.vue_vue_type_script_setup_true_lang.js +21 -6
  27. package/dist/es/layouts/Framework.vue_vue_type_script_setup_true_lang.js +3 -3
  28. package/dist/es/layouts/history-list/composables.js +1 -1
  29. package/dist/es/layouts/props-panel/FormPanel.vue_vue_type_script_setup_true_lang.js +44 -5
  30. package/dist/es/layouts/props-panel/PropsPanel.vue_vue_type_script_setup_true_lang.js +15 -8
  31. package/dist/es/layouts/sidebar/Sidebar.vue_vue_type_script_setup_true_lang.js +12 -31
  32. package/dist/es/layouts/sidebar/code-block/CodeBlockListPanel.vue_vue_type_script_setup_true_lang.js +2 -2
  33. package/dist/es/layouts/sidebar/code-block/useContentMenu.js +18 -3
  34. package/dist/es/layouts/sidebar/data-source/DataSourceListPanel.vue_vue_type_script_setup_true_lang.js +2 -2
  35. package/dist/es/layouts/sidebar/data-source/useContentMenu.js +18 -3
  36. package/dist/es/layouts/sidebar/layer/LayerNodeContent.js +5 -0
  37. package/dist/es/layouts/sidebar/layer/LayerNodeContent.vue_vue_type_script_setup_true_lang.js +46 -0
  38. package/dist/es/layouts/sidebar/layer/LayerPanel.vue_vue_type_script_setup_true_lang.js +2 -1
  39. package/dist/es/plugin.js +3 -1
  40. package/dist/es/services/codeBlock.js +1 -1
  41. package/dist/es/services/editor.js +104 -5
  42. package/dist/es/services/history.js +1 -1
  43. package/dist/es/services/props.js +3 -2
  44. package/dist/es/services/storage.js +2 -2
  45. package/dist/es/services/ui.js +4 -2
  46. package/dist/es/style.css +94 -54
  47. package/dist/es/utils/data-source/index.js +30 -11
  48. package/dist/es/utils/event.js +123 -0
  49. package/dist/es/utils/monaco-editor.js +22 -6
  50. package/dist/es/utils/props.js +119 -8
  51. package/dist/es/utils/type-match-rules.js +360 -0
  52. package/dist/style.css +94 -54
  53. package/dist/themes/magic-admin.css +93 -2
  54. package/dist/tmagic-editor.umd.cjs +16961 -15824
  55. package/package.json +8 -8
  56. package/src/Editor.vue +12 -1
  57. package/src/components/CompareForm.vue +15 -202
  58. package/src/components/ScrollBar.vue +0 -67
  59. package/src/components/ViewForm.vue +55 -0
  60. package/src/editorProps.ts +16 -8
  61. package/src/fields/CodeSelect.vue +4 -0
  62. package/src/fields/CondOpSelect.vue +2 -24
  63. package/src/fields/DataSourceInput.vue +7 -25
  64. package/src/fields/DisplayConds.vue +14 -0
  65. package/src/fields/EventSelect.vue +84 -129
  66. package/src/fields/StyleSetter/Index.vue +2 -8
  67. package/src/fields/StyleSetter/pro/Background.vue +118 -58
  68. package/src/fields/StyleSetter/pro/Border.vue +9 -11
  69. package/src/fields/StyleSetter/pro/Font.vue +66 -64
  70. package/src/fields/StyleSetter/pro/Layout.vue +199 -197
  71. package/src/fields/StyleSetter/pro/Position.vue +69 -67
  72. package/src/fields/StyleSetter/pro/Transform.vue +23 -25
  73. package/src/fields/UISelect.vue +0 -12
  74. package/src/hooks/index.ts +1 -0
  75. package/src/hooks/use-compare-form.ts +187 -0
  76. package/src/index.ts +2 -0
  77. package/src/layouts/CodeEditor.vue +32 -6
  78. package/src/layouts/props-panel/FormPanel.vue +66 -5
  79. package/src/layouts/props-panel/PropsPanel.vue +20 -6
  80. package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +4 -1
  81. package/src/layouts/sidebar/code-block/useContentMenu.ts +13 -1
  82. package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +2 -2
  83. package/src/layouts/sidebar/data-source/useContentMenu.ts +13 -1
  84. package/src/layouts/sidebar/layer/LayerNodeContent.vue +57 -0
  85. package/src/layouts/sidebar/layer/LayerPanel.vue +4 -1
  86. package/src/plugin.ts +3 -1
  87. package/src/services/editor.ts +168 -3
  88. package/src/services/ui.ts +20 -14
  89. package/src/theme/event.scss +8 -0
  90. package/src/theme/layer-node-content.scss +14 -0
  91. package/src/theme/scroll-bar.scss +64 -0
  92. package/src/theme/theme.scss +3 -0
  93. package/src/theme/ui-select.scss +9 -0
  94. package/src/type.ts +93 -2
  95. package/src/utils/data-source/index.ts +30 -12
  96. package/src/utils/event.ts +224 -0
  97. package/src/utils/index.ts +2 -0
  98. package/src/utils/monaco-editor.ts +27 -0
  99. package/src/utils/props.ts +189 -2
  100. package/src/utils/type-match-rules.ts +678 -0
  101. package/types/index.d.ts +540 -223
@@ -3,20 +3,20 @@ import history_default from "./services/history.js";
3
3
  import storage_default from "./services/storage.js";
4
4
  import editor_default from "./services/editor.js";
5
5
  import ui_default from "./services/ui.js";
6
+ import codeBlock_default from "./services/codeBlock.js";
7
+ import dataSource_default from "./services/dataSource.js";
8
+ import events_default from "./services/events.js";
6
9
  import Framework_default from "./layouts/Framework.js";
7
10
  import NavMenu_default from "./layouts/NavMenu.js";
11
+ import { ENABLE_PROPS_FORM_VALIDATE, defaultEditorProps } from "./editorProps.js";
8
12
  import PropsPanel_default from "./layouts/props-panel/PropsPanel.js";
9
13
  import keybinding_config_default from "./utils/keybinding-config.js";
10
14
  import Sidebar_default from "./layouts/sidebar/Sidebar.js";
11
15
  import Workspace_default from "./layouts/workspace/Workspace.js";
12
- import codeBlock_default from "./services/codeBlock.js";
13
16
  import componentList_default from "./services/componentList.js";
14
- import dataSource_default from "./services/dataSource.js";
15
17
  import dep_default from "./services/dep.js";
16
- import events_default from "./services/events.js";
17
18
  import keybinding_default from "./services/keybinding.js";
18
19
  import stageOverlay_default from "./services/stageOverlay.js";
19
- import { defaultEditorProps } from "./editorProps.js";
20
20
  import { initServiceEvents, initServiceState } from "./initService.js";
21
21
  import { M_THEME_KEY } from "@tmagic/design";
22
22
  import { computed, createBlock, createVNode, defineComponent, mergeDefaults, openBlock, provide, ref, renderSlot, unref, withCtx } from "vue";
@@ -26,6 +26,7 @@ var Editor_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCom
26
26
  name: "MEditor",
27
27
  __name: "Editor",
28
28
  props: /*@__PURE__*/ mergeDefaults({
29
+ isLargeStageContainer: { type: Boolean },
29
30
  theme: {},
30
31
  modelValue: {},
31
32
  componentGroupList: {},
@@ -58,6 +59,7 @@ var Editor_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCom
58
59
  disabledPageFragment: { type: Boolean },
59
60
  disabledFlashTip: { type: Boolean },
60
61
  disabledStageOverlay: { type: Boolean },
62
+ enablePropsFormValidate: { type: Boolean },
61
63
  disabledShowSrc: { type: Boolean },
62
64
  disabledDataSource: { type: Boolean },
63
65
  disabledCodeBlock: { type: Boolean },
@@ -131,12 +133,15 @@ var Editor_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCom
131
133
  provide("services", services);
132
134
  provide("codeOptions", props.codeOptions);
133
135
  provide("stageOptions", stageOptions);
136
+ /** 是否启用「属性配置表单校验」联动能力,供 PropsPanel / FormPanel 判断校验失败时是否仍更新节点并记录错误 */
137
+ provide(ENABLE_PROPS_FORM_VALIDATE, props.enablePropsFormValidate ?? false);
134
138
  /**
135
139
  * 把顶层 `extendFormState` 提供给非 PropsPanel 链路上的组件使用(例如历史差异对话框 HistoryDiffDialog
136
140
  * 内部的 CompareForm)。这样所有依赖业务上下文的表单 filterFunction 都能拿到一致的扩展状态,
137
141
  * 与 PropsPanel 通过 `:extend-state` 显式传入的方式保持等价。
138
142
  */
139
143
  provide("extendFormState", props.extendFormState);
144
+ provide("isLargeStageContainer", computed(() => props.isLargeStageContainer));
140
145
  /**
141
146
  * 提供 PropsPanel 主属性表单的 formState getter,供历史差异弹窗复用,
142
147
  * 让 CompareForm 与 PropsPanel 的 filterFunction 上下文保持一致。
@@ -1,9 +1,9 @@
1
1
  import { getEditorConfig } from "../utils/config.js";
2
+ import { getCodeBlockFormConfig } from "../utils/code-block.js";
2
3
  import { useServices } from "../hooks/use-services.js";
3
4
  import { useWindowRect } from "../hooks/use-window-rect.js";
4
5
  import { useEditorContentHeight } from "../hooks/use-editor-content-height.js";
5
6
  import { useNextFloatBoxPosition } from "../hooks/use-next-float-box-position.js";
6
- import { getCodeBlockFormConfig } from "../utils/code-block.js";
7
7
  import CodeEditor_default from "../layouts/CodeEditor.js";
8
8
  import FloatingBox_default from "./FloatingBox.js";
9
9
  import { MFormBox } from "@tmagic/form";
@@ -48,7 +48,8 @@ var CodeParams_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
48
48
  */
49
49
  const onParamsChangeHandler = async (v, eventData) => {
50
50
  try {
51
- emit("change", await formRef.value?.submitForm(true), eventData);
51
+ const value = await formRef.value?.submitForm(true);
52
+ emit("change", value, eventData);
52
53
  } catch (e) {
53
54
  error(e);
54
55
  }
@@ -1,7 +1,7 @@
1
- import { getCodeBlockFormConfig } from "../utils/code-block.js";
1
+ import { useCompareForm } from "../hooks/use-compare-form.js";
2
2
  import { MForm } from "@tmagic/form";
3
3
  import { HookType } from "@tmagic/core";
4
- import { computed, createBlock, createCommentVNode, createElementBlock, defineComponent, inject, normalizeStyle, openBlock, provide, ref, unref, useTemplateRef, watch, watchEffect } from "vue";
4
+ import { computed, createBlock, createCommentVNode, createElementBlock, defineComponent, normalizeStyle, openBlock, unref } from "vue";
5
5
  import { isEqual } from "lodash-es";
6
6
  //#region packages/editor/src/components/CompareForm.vue?vue&type=script&setup=true&lang.ts
7
7
  var CompareForm_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
@@ -9,59 +9,27 @@ var CompareForm_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defi
9
9
  __name: "CompareForm",
10
10
  props: {
11
11
  value: {},
12
- lastValue: {},
13
12
  type: {},
14
13
  category: { default: "node" },
15
14
  dataSourceType: {},
16
15
  labelWidth: { default: "120px" },
17
16
  height: {},
18
- extendState: {
19
- type: Function,
20
- default: (state) => state
21
- },
17
+ extendState: {},
22
18
  baseFormState: {},
23
- selfDiffFieldTypes: {},
24
19
  size: {},
25
20
  loadConfig: {},
26
- services: {}
21
+ services: {},
22
+ lastValue: {},
23
+ selfDiffFieldTypes: {}
27
24
  },
28
25
  setup(__props, { expose: __expose }) {
29
26
  const props = __props;
30
- provide("services", props.services);
31
- const config = ref([]);
32
- /** vs-code 编辑器的 monaco 配置项,沿用 Editor 顶层 provide('codeOptions', ...) 的注入。 */
33
- const codeOptions = inject("codeOptions", {});
34
- /** 将代码块的 content 字段统一成字符串,便于在表单/对比中展示 */
35
- const normalizeCodeBlockValue = (v) => {
36
- if (!v) return {};
37
- const next = { ...v };
38
- if (next.content && typeof next.content !== "string") try {
39
- next.content = next.content.toString();
40
- } catch {
41
- next.content = "";
42
- }
43
- return next;
44
- };
45
- const currentValues = computed(() => {
46
- if (props.category === "code-block") return normalizeCodeBlockValue(props.value);
47
- return props.value || {};
48
- });
27
+ const { config, currentValues, wrapperStyle, mergedExtendState, loadConfig, formRef, normalizeCodeBlockValue } = useCompareForm(props);
49
28
  const lastValuesProcessed = computed(() => {
50
29
  if (props.category === "code-block") return normalizeCodeBlockValue(props.lastValue);
51
30
  return props.lastValue || {};
52
31
  });
53
32
  /**
54
- * 外层包裹层的样式:当传入 `height` 时启用固定高度 + 内部滚动,
55
- * 这样滚动条会出现在 CompareForm 内部,避免父容器(如 Dialog)自身也产生滚动。
56
- */
57
- const wrapperStyle = computed(() => {
58
- if (!props.height) return void 0;
59
- return {
60
- height: props.height,
61
- overflow: "auto"
62
- };
63
- });
64
- /**
65
33
  * `code-select` 字段在历史数据中存在两种"语义为空"的形态:
66
34
  * - 字符串 `''`(旧数据 / 用户从未配置过钩子);
67
35
  * - `{ hookType: HookType.CODE, hookData: [] }`(CodeSelect.vue 在挂载时
@@ -84,83 +52,6 @@ var CompareForm_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defi
84
52
  }
85
53
  return !isEqual(curValue, lastValue);
86
54
  };
87
- const removeStyleDisplayConfig = (formConfig) => formConfig.map((item) => {
88
- if (!("type" in item)) return item;
89
- if (item?.type !== "tab" || !Array.isArray(item.items)) return item;
90
- return {
91
- ...item,
92
- items: item.items.map((tabPane) => {
93
- if (tabPane?.title !== "样式" || !Array.isArray(tabPane.items)) return tabPane;
94
- return {
95
- ...tabPane,
96
- display: true
97
- };
98
- })
99
- };
100
- });
101
- const mergedExtendState = (state) => {
102
- return props.extendState(props.baseFormState || state);
103
- };
104
- /**
105
- * 内置的默认 FormConfig 加载逻辑:按 `category` 从对应 service / 工具取配置。
106
- * 作为 ctx.defaultLoadConfig 透传给自定义 `loadConfig`,方便复用与二次加工。
107
- */
108
- const defaultLoadConfig = async () => {
109
- if (!props.services) return [];
110
- switch (props.category) {
111
- case "node":
112
- if (!props.type) return [];
113
- return removeStyleDisplayConfig(await props.services.propsService.getPropsConfig(props.type, { node: props.value }));
114
- case "data-source": return props.services.dataSourceService.getFormConfig(props.type || "base").map((item) => "type" in item && item.type === "tab" ? {
115
- ...item,
116
- active: "fields"
117
- } : item);
118
- case "code-block": return getCodeBlockFormConfig({
119
- paramColConfig: props.services.codeBlockService.getParamsColConfig(),
120
- isDataSource: () => Boolean(props.dataSourceType),
121
- dataSourceType: () => props.dataSourceType,
122
- codeOptions,
123
- editable: false
124
- });
125
- default: return [];
126
- }
127
- };
128
- const loadConfig = async () => {
129
- if (props.loadConfig) {
130
- config.value = await props.loadConfig({
131
- category: props.category,
132
- type: props.type,
133
- dataSourceType: props.dataSourceType,
134
- defaultLoadConfig
135
- });
136
- return;
137
- }
138
- config.value = await defaultLoadConfig();
139
- };
140
- watch([
141
- () => props.category,
142
- () => props.type,
143
- () => props.dataSourceType,
144
- () => props.loadConfig
145
- ], () => {
146
- loadConfig();
147
- }, { immediate: true });
148
- const formRef = useTemplateRef("form");
149
- /**
150
- * 把 services / stage 注入 MForm 的 formState,避免 propsService 注入的表单配置中
151
- * 形如 `display: ({ services }) => services.uiService.get(...)` 的 filterFunction
152
- * 在执行时拿不到 `formState.services` 而报错。
153
- *
154
- * 与 props-panel/FormPanel.vue 中的注入方式保持一致:
155
- * - services:整个 useServices() 返回的服务集合;
156
- * - stage:当前 editorService.get('stage') 的最新值。
157
- */
158
- watchEffect(() => {
159
- if (formRef.value && props.services) {
160
- formRef.value.formState.stage = props.services.editorService.get("stage");
161
- formRef.value.formState.services = props.services;
162
- }
163
- });
164
55
  __expose({
165
56
  form: formRef,
166
57
  config,
@@ -169,18 +60,18 @@ var CompareForm_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defi
169
60
  return (_ctx, _cache) => {
170
61
  return openBlock(), createElementBlock("div", {
171
62
  class: "m-editor-compare-form-wrapper",
172
- style: normalizeStyle(wrapperStyle.value)
173
- }, [config.value.length ? (openBlock(), createBlock(unref(MForm), {
63
+ style: normalizeStyle(unref(wrapperStyle))
64
+ }, [unref(config).length ? (openBlock(), createBlock(unref(MForm), {
174
65
  key: 0,
175
66
  ref: "form",
176
67
  class: "m-editor-compare-form",
177
- config: config.value,
178
- "init-values": currentValues.value,
68
+ config: unref(config),
69
+ "init-values": unref(currentValues),
179
70
  "last-values": lastValuesProcessed.value,
180
71
  "is-compare": true,
181
72
  disabled: true,
182
73
  "label-width": __props.labelWidth,
183
- "extend-state": mergedExtendState,
74
+ "extend-state": unref(mergedExtendState),
184
75
  "show-diff": showDiff,
185
76
  "self-diff-field-types": __props.selfDiffFieldTypes,
186
77
  size: __props.size
@@ -189,6 +80,7 @@ var CompareForm_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defi
189
80
  "init-values",
190
81
  "last-values",
191
82
  "label-width",
83
+ "extend-state",
192
84
  "self-diff-field-types",
193
85
  "size"
194
86
  ])) : createCommentVNode("v-if", true)], 4);
@@ -153,7 +153,10 @@ var FloatingBox_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defi
153
153
  height.value = targetRect.height;
154
154
  initMoveable();
155
155
  }
156
- if (titleEl.value) titleHeight.value = titleEl.value.getBoundingClientRect().height;
156
+ if (titleEl.value) {
157
+ const titleRect = titleEl.value.getBoundingClientRect();
158
+ titleHeight.value = titleRect.height;
159
+ }
157
160
  } else destroyMoveable();
158
161
  }, { immediate: true });
159
162
  onBeforeUnmount(() => {
@@ -1,5 +1,4 @@
1
1
  import ScrollBar_vue_vue_type_script_setup_true_lang_default from "./ScrollBar.vue_vue_type_script_setup_true_lang.js";
2
- /* empty css */
3
2
  //#region packages/editor/src/components/ScrollBar.vue
4
3
  var ScrollBar_default = ScrollBar_vue_vue_type_script_setup_true_lang_default;
5
4
  //#endregion
@@ -0,0 +1,5 @@
1
+ import ViewForm_vue_vue_type_script_setup_true_lang_default from "./ViewForm.vue_vue_type_script_setup_true_lang.js";
2
+ //#region packages/editor/src/components/ViewForm.vue
3
+ var ViewForm_default = ViewForm_vue_vue_type_script_setup_true_lang_default;
4
+ //#endregion
5
+ export { ViewForm_default as default };
@@ -0,0 +1,58 @@
1
+ import { useCompareForm } from "../hooks/use-compare-form.js";
2
+ import { MForm } from "@tmagic/form";
3
+ import { createBlock, createCommentVNode, createElementBlock, defineComponent, normalizeStyle, openBlock, unref } from "vue";
4
+ //#region packages/editor/src/components/ViewForm.vue?vue&type=script&setup=true&lang.ts
5
+ var ViewForm_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
6
+ name: "MEditorViewForm",
7
+ __name: "ViewForm",
8
+ props: {
9
+ value: {},
10
+ type: {},
11
+ category: { default: "node" },
12
+ dataSourceType: {},
13
+ labelWidth: { default: "120px" },
14
+ height: {},
15
+ extendState: {},
16
+ baseFormState: {},
17
+ size: {},
18
+ loadConfig: {},
19
+ services: {},
20
+ disabled: {
21
+ type: Boolean,
22
+ default: true
23
+ }
24
+ },
25
+ setup(__props, { expose: __expose }) {
26
+ const { config, currentValues, wrapperStyle, mergedExtendState, loadConfig, formRef } = useCompareForm(__props);
27
+ __expose({
28
+ form: formRef,
29
+ config,
30
+ reload: loadConfig
31
+ });
32
+ return (_ctx, _cache) => {
33
+ return openBlock(), createElementBlock("div", {
34
+ class: "m-editor-view-form-wrapper",
35
+ style: normalizeStyle(unref(wrapperStyle))
36
+ }, [unref(config).length ? (openBlock(), createBlock(unref(MForm), {
37
+ key: 0,
38
+ ref: "form",
39
+ class: "m-editor-view-form",
40
+ config: unref(config),
41
+ "init-values": unref(currentValues),
42
+ disabled: __props.disabled,
43
+ "label-width": __props.labelWidth,
44
+ "extend-state": unref(mergedExtendState),
45
+ size: __props.size
46
+ }, null, 8, [
47
+ "config",
48
+ "init-values",
49
+ "disabled",
50
+ "label-width",
51
+ "extend-state",
52
+ "size"
53
+ ])) : createCommentVNode("v-if", true)], 4);
54
+ };
55
+ }
56
+ });
57
+ //#endregion
58
+ export { ViewForm_vue_vue_type_script_setup_true_lang_default as default };
@@ -1,6 +1,11 @@
1
1
  import { CONTAINER_HIGHLIGHT_CLASS_NAME, ContainerHighlightType, RenderType } from "@tmagic/stage";
2
2
  import { getIdFromEl } from "@tmagic/utils";
3
3
  //#region packages/editor/src/editorProps.ts
4
+ /**
5
+ * 「属性配置表单校验」联动能力的 provide/inject 注入键。
6
+ * 使用 Symbol 避免与其它字符串键冲突,供 PropsPanel / FormPanel 注入判断校验失败时是否仍更新节点并记录错误。
7
+ */
8
+ var ENABLE_PROPS_FORM_VALIDATE = Symbol("enablePropsFormValidate");
4
9
  var defaultEditorProps = {
5
10
  renderType: RenderType.IFRAME,
6
11
  disabledMultiSelect: false,
@@ -34,4 +39,4 @@ var defaultEditorProps = {
34
39
  customContentMenu: (menus) => menus
35
40
  };
36
41
  //#endregion
37
- export { defaultEditorProps };
42
+ export { ENABLE_PROPS_FORM_VALIDATE, defaultEditorProps };
@@ -49,7 +49,8 @@ var CodeSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
49
49
  codeId: ""
50
50
  };
51
51
  const name = props.config.name || "";
52
- emit("change", defaultCode, { modifyKey: `hookData.${(props.model[name]?.hookData || []).length}` });
52
+ const hookData = props.model[name]?.hookData || [];
53
+ emit("change", defaultCode, { modifyKey: `hookData.${hookData.length}` });
53
54
  };
54
55
  const codeConfig = computed(() => ({
55
56
  type: "group-list",
@@ -77,6 +78,10 @@ var CodeSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
77
78
  type: "select",
78
79
  name: "codeType",
79
80
  labelPosition: "right",
81
+ rules: [{
82
+ typeMatch: true,
83
+ trigger: "change"
84
+ }],
80
85
  options: [{
81
86
  value: HookCodeType.CODE,
82
87
  text: "代码块"
@@ -95,6 +100,10 @@ var CodeSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
95
100
  type: "code-select-col",
96
101
  name: "codeId",
97
102
  text: "代码块",
103
+ rules: [{
104
+ typeMatch: true,
105
+ trigger: "change"
106
+ }],
98
107
  display: (_mForm, { model }) => model.codeType !== HookCodeType.DATA_SOURCE_METHOD,
99
108
  notEditable: () => !codeBlockService.getEditStatus()
100
109
  },
@@ -102,6 +111,10 @@ var CodeSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
102
111
  type: "data-source-method-select",
103
112
  name: "codeId",
104
113
  text: "数据源字段",
114
+ rules: [{
115
+ typeMatch: true,
116
+ trigger: "change"
117
+ }],
105
118
  display: (_mForm, { model }) => model.codeType === HookCodeType.DATA_SOURCE_METHOD,
106
119
  notEditable: () => !dataSourceService.get("editable")
107
120
  }
@@ -1,4 +1,4 @@
1
- import { arrayOptions, eqOptions, numberOptions } from "../utils/props.js";
1
+ import { getCondOpOptionsByFieldType } from "../utils/props.js";
2
2
  import { useServices } from "../hooks/use-services.js";
3
3
  import { getFieldType } from "../utils/data-source/index.js";
4
4
  import { TMagicSelect, getDesignConfig } from "@tmagic/design";
@@ -30,22 +30,7 @@ var CondOpSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
30
30
  const optionComponent = getDesignConfig("components")?.option;
31
31
  const options = computed(() => {
32
32
  const [id, ...fieldNames] = [...props.config.parentFields || [], ...props.model.field];
33
- const type = getFieldType(dataSourceService.getDataSourceById(id), fieldNames);
34
- if (type === "array") return arrayOptions;
35
- if (type === "boolean" || type === "null") return [{
36
- text: "是",
37
- value: "is"
38
- }, {
39
- text: "不是",
40
- value: "not"
41
- }];
42
- if (type === "number") return [...eqOptions, ...numberOptions];
43
- if (type === "string") return [...arrayOptions, ...eqOptions];
44
- return [
45
- ...arrayOptions,
46
- ...eqOptions,
47
- ...numberOptions
48
- ];
33
+ return getCondOpOptionsByFieldType(getFieldType(dataSourceService.getDataSourceById(id), fieldNames));
49
34
  });
50
35
  const fieldChangeHandler = (v) => {
51
36
  emit("change", v);
@@ -49,7 +49,8 @@ var FieldSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defi
49
49
  const selectFieldsId = ref([]);
50
50
  watch(modelValue, (value) => {
51
51
  if (props.dataSourceId) {
52
- selectDataSourceId.value = valueIsKey.value ? props.dataSourceId : `${DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX}${props.dataSourceId}`;
52
+ const dsIdValue = valueIsKey.value ? props.dataSourceId : `${DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX}${props.dataSourceId}`;
53
+ selectDataSourceId.value = dsIdValue;
53
54
  selectFieldsId.value = Array.isArray(value) ? value : [];
54
55
  } else if (Array.isArray(value) && value.length) {
55
56
  const [dsId, ...fields] = value;
@@ -1,8 +1,8 @@
1
1
  import { useServices } from "../hooks/use-services.js";
2
- import { getDisplayField } from "../utils/data-source/index.js";
2
+ import { getDisplayField, resolveFieldByPath } from "../utils/data-source/index.js";
3
3
  import Icon_default from "../components/Icon.js";
4
4
  import { TMagicInput, TMagicTag, getDesignConfig } from "@tmagic/design";
5
- import { getKeysArray, isNumber } from "@tmagic/utils";
5
+ import { getKeysArray } from "@tmagic/utils";
6
6
  import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeProps, nextTick, normalizeClass, openBlock, ref, renderList, resolveDynamicComponent, toDisplayString, unref, useTemplateRef, watch, withCtx } from "vue";
7
7
  import { Coin } from "@element-plus/icons-vue";
8
8
  //#region packages/editor/src/fields/DataSourceInput.vue?vue&type=script&setup=true&lang.ts
@@ -135,23 +135,11 @@ var DataSourceInput_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
135
135
  cb([]);
136
136
  return;
137
137
  }
138
- let fields = ds.fields || [];
139
- let key = keys.shift();
140
- while (key) {
141
- if (isNumber(key)) {
142
- key = keys.shift();
143
- continue;
144
- }
145
- for (const field of fields) if (field.name === key) {
146
- fields = field.fields || [];
147
- key = keys.shift();
148
- break;
149
- }
150
- }
151
- if (curCharIsDot(dotIndex)) result = fields || [];
138
+ const { fields } = resolveFieldByPath(ds.fields, keys, { skipNumberIndices: true });
139
+ if (curCharIsDot(dotIndex)) result = fields;
152
140
  else if (dotIndex > -1) {
153
141
  const queryName = queryString.substring(dotIndex + 1).toLowerCase();
154
- result = fields.filter((field) => field.name?.toLowerCase().includes(queryName) || field.title?.toLowerCase().includes(queryName)) || [];
142
+ result = fields.filter((field) => field.name?.toLowerCase().includes(queryName) || field.title?.toLowerCase().includes(queryName));
155
143
  }
156
144
  cb(result.map((field) => ({
157
145
  value: field.name,
@@ -76,7 +76,16 @@ var DisplayConds_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
76
76
  value: "key",
77
77
  label: "字段",
78
78
  checkStrictly: false,
79
- onChange: fieldOnChange
79
+ onChange: fieldOnChange,
80
+ defaultValue: () => [],
81
+ rules: [{
82
+ required: true,
83
+ trigger: "blur",
84
+ message: "请选择字段"
85
+ }, {
86
+ typeMatch: true,
87
+ trigger: "change"
88
+ }]
80
89
  } : {
81
90
  type: "data-source-field-select",
82
91
  name: "field",
@@ -89,14 +98,31 @@ var DisplayConds_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
89
98
  "boolean",
90
99
  "any"
91
100
  ],
92
- onChange: fieldOnChange
101
+ onChange: fieldOnChange,
102
+ defaultValue: () => [],
103
+ rules: [{
104
+ required: true,
105
+ trigger: "blur",
106
+ message: "请选择字段"
107
+ }, {
108
+ typeMatch: true,
109
+ trigger: "change"
110
+ }]
93
111
  },
94
112
  {
95
113
  type: "cond-op-select",
96
114
  parentFields: parentFields.value,
97
115
  label: "条件",
98
116
  width: 140,
99
- name: "op"
117
+ name: "op",
118
+ rules: [{
119
+ required: true,
120
+ trigger: "blur",
121
+ message: "请选择条件"
122
+ }, {
123
+ typeMatch: true,
124
+ trigger: "change"
125
+ }]
100
126
  },
101
127
  {
102
128
  label: "值",