@tmagic/editor 1.8.0-beta.25 → 1.8.0-beta.26

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 (111) hide show
  1. package/dist/es/Editor.vue_vue_type_script_setup_true_lang.js +10 -16
  2. package/dist/es/components/CodeParams.vue_vue_type_script_setup_true_lang.js +4 -4
  3. package/dist/es/components/CompareForm.vue_vue_type_script_setup_true_lang.js +5 -8
  4. package/dist/es/components/ViewForm.vue_vue_type_script_setup_true_lang.js +3 -5
  5. package/dist/es/fields/Code.vue_vue_type_script_setup_true_lang.js +3 -11
  6. package/dist/es/fields/CodeSelect.vue_vue_type_script_setup_true_lang.js +29 -124
  7. package/dist/es/fields/CodeSelectCol.vue_vue_type_script_setup_true_lang.js +5 -6
  8. package/dist/es/fields/DataSourceFieldSelect/FieldSelect.vue_vue_type_script_setup_true_lang.js +1 -1
  9. package/dist/es/fields/DataSourceFieldSelect/Index.vue_vue_type_script_setup_true_lang.js +4 -5
  10. package/dist/es/fields/DataSourceFields.vue_vue_type_script_setup_true_lang.js +6 -10
  11. package/dist/es/fields/DataSourceMethodSelect.vue_vue_type_script_setup_true_name_true_lang.js +5 -7
  12. package/dist/es/fields/DataSourceMethods.vue_vue_type_script_setup_true_lang.js +1 -4
  13. package/dist/es/fields/DataSourceMocks.vue_vue_type_script_setup_true_lang.js +4 -6
  14. package/dist/es/fields/DataSourceSelect.vue_vue_type_script_setup_true_lang.js +1 -1
  15. package/dist/es/fields/DisplayConds.vue_vue_type_script_setup_true_lang.js +9 -142
  16. package/dist/es/fields/EventSelect.vue_vue_type_script_setup_true_lang.js +51 -326
  17. package/dist/es/fields/KeyValue.vue_vue_type_script_setup_true_lang.js +2 -4
  18. package/dist/es/fields/StyleSetter/components/Border.vue_vue_type_script_setup_true_lang.js +3 -34
  19. package/dist/es/fields/StyleSetter/configs.js +663 -0
  20. package/dist/es/fields/StyleSetter/pro/Background.vue_vue_type_script_setup_true_lang.js +5 -108
  21. package/dist/es/fields/StyleSetter/pro/Border.vue_vue_type_script_setup_true_lang.js +3 -9
  22. package/dist/es/fields/StyleSetter/pro/Font.vue_vue_type_script_setup_true_lang.js +5 -102
  23. package/dist/es/fields/StyleSetter/pro/Layout.vue_vue_type_script_setup_true_lang.js +5 -265
  24. package/dist/es/fields/StyleSetter/pro/Position.vue_vue_type_script_setup_true_lang.js +5 -85
  25. package/dist/es/fields/StyleSetter/pro/Transform.vue_vue_type_script_setup_true_lang.js +3 -22
  26. package/dist/es/fields/configs/codeSelect.js +98 -0
  27. package/dist/es/fields/configs/displayConds.js +158 -0
  28. package/dist/es/fields/configs/eventSelect.js +225 -0
  29. package/dist/es/fields/configs/stickyAddButton.js +20 -0
  30. package/dist/es/fields/headless-validation.js +139 -0
  31. package/dist/es/headless.js +2 -0
  32. package/dist/es/hooks/use-compare-form.js +6 -23
  33. package/dist/es/hooks/use-form-context.js +19 -0
  34. package/dist/es/index.js +2 -1
  35. package/dist/es/initService.js +17 -1
  36. package/dist/es/layouts/history-list/HistoryDiffDialog.vue_vue_type_script_setup_true_lang.js +1 -7
  37. package/dist/es/layouts/history-list/HistoryListPanel.vue_vue_type_script_setup_true_lang.js +1 -11
  38. package/dist/es/layouts/history-list/useHistoryRevert.js +3 -11
  39. package/dist/es/layouts/props-panel/FormPanel.vue_vue_type_script_setup_true_lang.js +10 -23
  40. package/dist/es/layouts/props-panel/PropsPanel.vue_vue_type_script_setup_true_lang.js +3 -13
  41. package/dist/es/layouts/sidebar/code-block/CodeBlockListPanel.vue_vue_type_script_setup_true_lang.js +1 -1
  42. package/dist/es/layouts/sidebar/code-block/useContentMenu.js +1 -1
  43. package/dist/es/layouts/sidebar/data-source/DataSourceListPanel.vue_vue_type_script_setup_true_lang.js +1 -1
  44. package/dist/es/layouts/sidebar/data-source/useContentMenu.js +1 -1
  45. package/dist/es/plugin.js +33 -32
  46. package/dist/es/style.css +116 -60
  47. package/dist/es/utils/data-source/index.js +2 -1
  48. package/dist/es/utils/props.js +1 -4
  49. package/dist/es/utils/type-match-rules.js +2 -2
  50. package/dist/style.css +116 -60
  51. package/dist/themes/magic-admin.css +128 -67
  52. package/dist/tmagic-editor-headless.umd.cjs +10867 -0
  53. package/dist/tmagic-editor.umd.cjs +2123 -2015
  54. package/package.json +12 -7
  55. package/src/Editor.vue +12 -16
  56. package/src/components/CodeParams.vue +10 -4
  57. package/src/components/CompareForm.vue +4 -5
  58. package/src/components/ViewForm.vue +2 -3
  59. package/src/editorProps.ts +1 -2
  60. package/src/fields/Code.vue +2 -10
  61. package/src/fields/CodeSelect.vue +20 -116
  62. package/src/fields/CodeSelectCol.vue +3 -5
  63. package/src/fields/DataSourceFieldSelect/FieldSelect.vue +1 -1
  64. package/src/fields/DataSourceFieldSelect/Index.vue +3 -5
  65. package/src/fields/DataSourceFields.vue +0 -7
  66. package/src/fields/DataSourceMethodSelect.vue +2 -5
  67. package/src/fields/DataSourceMethods.vue +1 -6
  68. package/src/fields/DataSourceMocks.vue +1 -10
  69. package/src/fields/DataSourceSelect.vue +1 -1
  70. package/src/fields/DisplayConds.vue +17 -157
  71. package/src/fields/EventSelect.vue +28 -375
  72. package/src/fields/KeyValue.vue +3 -4
  73. package/src/fields/StyleSetter/components/Border.vue +4 -38
  74. package/src/fields/StyleSetter/configs.ts +690 -0
  75. package/src/fields/StyleSetter/pro/Background.vue +4 -104
  76. package/src/fields/StyleSetter/pro/Border.vue +3 -12
  77. package/src/fields/StyleSetter/pro/Font.vue +4 -123
  78. package/src/fields/StyleSetter/pro/Layout.vue +4 -219
  79. package/src/fields/StyleSetter/pro/Position.vue +6 -110
  80. package/src/fields/StyleSetter/pro/Transform.vue +4 -30
  81. package/src/fields/configs/codeSelect.ts +127 -0
  82. package/src/fields/configs/displayConds.ts +184 -0
  83. package/src/fields/configs/eventSelect.ts +309 -0
  84. package/src/fields/configs/stickyAddButton.ts +31 -0
  85. package/src/fields/headless-validation.ts +177 -0
  86. package/src/headless.ts +33 -0
  87. package/src/hooks/use-compare-form.ts +7 -25
  88. package/src/hooks/use-form-context.ts +40 -0
  89. package/src/index.ts +2 -0
  90. package/src/initService.ts +23 -1
  91. package/src/layouts/history-list/HistoryDiffDialog.vue +0 -10
  92. package/src/layouts/history-list/HistoryListPanel.vue +1 -13
  93. package/src/layouts/history-list/useHistoryRevert.ts +7 -13
  94. package/src/layouts/props-panel/FormPanel.vue +17 -28
  95. package/src/layouts/props-panel/PropsPanel.vue +1 -4
  96. package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +1 -1
  97. package/src/layouts/sidebar/code-block/useContentMenu.ts +1 -1
  98. package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +1 -1
  99. package/src/layouts/sidebar/data-source/useContentMenu.ts +1 -1
  100. package/src/plugin.ts +32 -33
  101. package/src/theme/code-block.scss +0 -37
  102. package/src/theme/display-conds.scss +4 -0
  103. package/src/theme/event.scss +22 -45
  104. package/src/theme/props-panel.scss +17 -3
  105. package/src/theme/themes/magic-admin/index.scss +12 -1
  106. package/src/type.ts +10 -29
  107. package/src/utils/data-source/index.ts +1 -0
  108. package/src/utils/props.ts +1 -4
  109. package/src/utils/type-match-rules.ts +8 -3
  110. package/types/headless.d.ts +18 -0
  111. package/types/index.d.ts +154 -179
@@ -3,11 +3,11 @@ import { useEditorContentHeight } from "../hooks/use-editor-content-height.js";
3
3
  import { useNextFloatBoxPosition } from "../hooks/use-next-float-box-position.js";
4
4
  import CodeEditor_default from "../layouts/CodeEditor.js";
5
5
  import FloatingBox_default from "../components/FloatingBox.js";
6
- import { FORM_SILENT_MODE_KEY, MFormBox } from "@tmagic/form";
6
+ import { MFormBox } from "@tmagic/form";
7
7
  import { MagicTable } from "@tmagic/table";
8
8
  import { TMagicButton, TMagicSwitch, tMagicMessageBox } from "@tmagic/design";
9
9
  import { getDefaultValueFromFields } from "@tmagic/utils";
10
- import { computed, createBlock, createCommentVNode, createElementBlock, createTextVNode, createVNode, defineComponent, inject, isRef, mergeModels, openBlock, ref, unref, useModel, withCtx } from "vue";
10
+ import { computed, createCommentVNode, createElementBlock, createTextVNode, createVNode, defineComponent, inject, isRef, mergeModels, openBlock, ref, unref, useModel, withCtx } from "vue";
11
11
  //#region packages/editor/src/fields/DataSourceMocks.vue?vue&type=script&setup=true&lang.ts
12
12
  var _hoisted_1 = { class: "m-editor-data-source-fields" };
13
13
  var _hoisted_2 = {
@@ -49,7 +49,6 @@ var DataSourceMocks_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
49
49
  const emit = __emit;
50
50
  const { uiService } = useServices();
51
51
  const mForm = inject("mForm");
52
- const silentMode = inject(FORM_SILENT_MODE_KEY, false);
53
52
  /** 对比模式下隐藏新增/编辑/删除等操作按钮,仅保留只读展示。 */
54
53
  const isCompare = computed(() => Boolean(mForm?.isCompare));
55
54
  const width = useModel(__props, "width");
@@ -235,8 +234,7 @@ var DataSourceMocks_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
235
234
  default: withCtx(() => [..._cache[4] || (_cache[4] = [createTextVNode("添加", -1)])]),
236
235
  _: 1
237
236
  }, 8, ["disabled"])])) : createCommentVNode("v-if", true),
238
- !unref(silentMode) ? (openBlock(), createBlock(FloatingBox_default, {
239
- key: 1,
237
+ createVNode(FloatingBox_default, {
240
238
  "body-style": { padding: "0 16px" },
241
239
  visible: addDialogVisible.value,
242
240
  "onUpdate:visible": _cache[1] || (_cache[1] = ($event) => addDialogVisible.value = $event),
@@ -268,7 +266,7 @@ var DataSourceMocks_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
268
266
  "title",
269
267
  "framework-width",
270
268
  "position"
271
- ])) : createCommentVNode("v-if", true)
269
+ ])
272
270
  ]);
273
271
  };
274
272
  }
@@ -34,7 +34,7 @@ var DataSourceSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
34
34
  const props = __props;
35
35
  const mForm = inject("mForm");
36
36
  const { dataSourceService, uiService } = useServices();
37
- const eventBus = inject("eventBus");
37
+ const eventBus = inject("eventBus", null);
38
38
  const dataSources = computed(() => dataSourceService.get("dataSources"));
39
39
  const notEditable = computed(() => filterFunction(mForm, props.config.notEditable, props));
40
40
  /** 对比模式下隐藏查看/编辑操作按钮,仅保留只读展示。 */
@@ -1,9 +1,8 @@
1
- import { useServices } from "../hooks/use-services.js";
2
- import { getCascaderOptionsFromFields, getFieldType } from "../utils/data-source/index.js";
1
+ import { createDisplayCondsConfig } from "./configs/displayConds.js";
3
2
  import { MGroupList, filterFunction } from "@tmagic/form";
4
- import { removeDataSourceFieldPrefix } from "@tmagic/utils";
5
- import { computed, createBlock, defineComponent, inject, openBlock, unref } from "vue";
3
+ import { computed, createElementBlock, createVNode, defineComponent, inject, openBlock, unref } from "vue";
6
4
  //#region packages/editor/src/fields/DisplayConds.vue?vue&type=script&setup=true&lang.ts
5
+ var _hoisted_1 = { class: "m-fields-display-conds" };
7
6
  var DisplayConds_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
8
7
  name: "m-fields-display-conds",
9
8
  __name: "DisplayConds",
@@ -29,154 +28,21 @@ var DisplayConds_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
29
28
  setup(__props, { emit: __emit }) {
30
29
  const emit = __emit;
31
30
  const props = __props;
32
- const { dataSourceService } = useServices();
33
31
  const mForm = inject("mForm");
34
32
  const parentFields = computed(() => filterFunction(mForm, props.config.parentFields, props) || []);
35
- const resolveFieldPath = (path) => {
36
- const [id, ...fieldNames] = path;
37
- return {
38
- ds: id ? dataSourceService.getDataSourceById(removeDataSourceFieldPrefix(`${id}`)) : void 0,
39
- fieldNames
40
- };
41
- };
42
- const fieldOnChange = (_formState, v, { model }) => {
43
- const { ds, fieldNames } = resolveFieldPath([...parentFields.value, ...v]);
44
- const type = getFieldType(ds, fieldNames);
45
- if (type === "number") model.value = Number(model.value);
46
- else if (type === "boolean") model.value = Boolean(model.value);
47
- else if (type === "null") model.value = null;
48
- else model.value = `${model.value}`;
49
- return v;
50
- };
51
- const config = computed(() => ({
52
- type: "groupList",
53
- name: props.name,
54
- titlePrefix: props.config.titlePrefix,
55
- expandAll: true,
56
- enableToggleMode: false,
57
- flat: props.config.flat,
58
- items: [{
59
- type: "table",
60
- name: "cond",
61
- operateColWidth: props.config.operateColWidth,
62
- enableToggleMode: false,
63
- fixed: props.config.fixed,
64
- flat: props.config.flat,
65
- items: [
66
- parentFields.value.length ? {
67
- type: "cascader",
68
- options: () => {
69
- const { ds, fieldNames } = resolveFieldPath(parentFields.value);
70
- if (!ds) return [];
71
- let fields = ds.fields || [];
72
- fieldNames.forEach((key) => {
73
- fields = fields.find((f) => f.name === key)?.fields || [];
74
- });
75
- return getCascaderOptionsFromFields(fields, [
76
- "string",
77
- "number",
78
- "boolean",
79
- "any"
80
- ]);
81
- },
82
- name: "field",
83
- value: "key",
84
- label: "字段",
85
- checkStrictly: false,
86
- onChange: fieldOnChange,
87
- defaultValue: () => [],
88
- rules: [{
89
- required: true,
90
- trigger: "blur",
91
- message: "请选择字段"
92
- }, {
93
- typeMatch: true,
94
- trigger: "change"
95
- }]
96
- } : {
97
- type: "data-source-field-select",
98
- name: "field",
99
- value: "key",
100
- label: "字段",
101
- checkStrictly: false,
102
- dataSourceFieldType: [
103
- "string",
104
- "number",
105
- "boolean",
106
- "any"
107
- ],
108
- onChange: fieldOnChange,
109
- defaultValue: () => [],
110
- rules: [{
111
- required: true,
112
- trigger: "blur",
113
- message: "请选择字段"
114
- }, {
115
- typeMatch: true,
116
- trigger: "change"
117
- }]
118
- },
119
- {
120
- type: "cond-op-select",
121
- parentFields: parentFields.value,
122
- label: "条件",
123
- width: 140,
124
- name: "op",
125
- rules: [{
126
- required: true,
127
- trigger: "blur",
128
- message: "请选择条件"
129
- }, {
130
- typeMatch: true,
131
- trigger: "change"
132
- }]
133
- },
134
- {
135
- label: "值",
136
- width: 160,
137
- items: [{
138
- name: "value",
139
- type: (_mForm, { model }) => {
140
- const { ds, fieldNames } = resolveFieldPath([...parentFields.value, ...model.field || []]);
141
- const type = getFieldType(ds, fieldNames);
142
- if (type === "number") return "number";
143
- if (type === "boolean") return "select";
144
- if (type === "null") return "display";
145
- return "text";
146
- },
147
- options: [{
148
- text: "true",
149
- value: true
150
- }, {
151
- text: "false",
152
- value: false
153
- }],
154
- display: (_mForm, { model }) => !["between", "not_between"].includes(model.op),
155
- displayText: (_mForm, { model }) => {
156
- if (model.value === null) return "null";
157
- return model.value;
158
- }
159
- }, {
160
- name: "range",
161
- type: "number-range",
162
- display: (vm, { model }) => ["between", "not_between"].includes(model.op)
163
- }]
164
- }
165
- ]
166
- }]
167
- }));
33
+ const config = computed(() => createDisplayCondsConfig(props.config, props.name, parentFields.value));
34
+ const isCompareMode = computed(() => Boolean(props.isCompare && props.lastValues));
168
35
  const changeHandler = (v, eventData) => {
169
- if (!Array.isArray(props.model[props.name])) props.model[props.name] = [];
170
36
  emit("change", v, eventData);
171
37
  };
172
38
  return (_ctx, _cache) => {
173
- return openBlock(), createBlock(unref(MGroupList), {
174
- style: { "width": "100%" },
39
+ return openBlock(), createElementBlock("div", _hoisted_1, [createVNode(unref(MGroupList), {
175
40
  config: config.value,
176
41
  name: __props.name,
177
42
  disabled: __props.disabled,
178
43
  model: __props.model,
179
44
  "last-values": __props.lastValues,
45
+ "is-compare": isCompareMode.value,
180
46
  prop: __props.prop,
181
47
  size: __props.size,
182
48
  onChange: changeHandler
@@ -186,9 +52,10 @@ var DisplayConds_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ def
186
52
  "disabled",
187
53
  "model",
188
54
  "last-values",
55
+ "is-compare",
189
56
  "prop",
190
57
  "size"
191
- ]);
58
+ ])]);
192
59
  };
193
60
  }
194
61
  });
@@ -1,19 +1,13 @@
1
- import { useServices } from "../hooks/use-services.js";
2
- import { getCompActionAllowedValues, getCompActionOptions, getEventNameAllowedValues, getEventNameOptions, normalizeCompActionValue } from "../utils/event.js";
3
- import { MContainer, MPanel, MTable, defineFormItem } from "@tmagic/form";
4
- import { TMagicButton } from "@tmagic/design";
5
- import { ActionType } from "@tmagic/core";
6
- import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, openBlock, renderList, unref, withCtx } from "vue";
7
- import { has } from "lodash-es";
8
- import { Delete, Plus } from "@element-plus/icons-vue";
1
+ import { createEventNameConfig, createEventSelectConfig, createLegacyTableConfig, isLegacyEventValue } from "./configs/eventSelect.js";
2
+ import { MContainer, MGroupList, MTable } from "@tmagic/form";
3
+ import { computed, createBlock, createElementBlock, createElementVNode, createVNode, defineComponent, openBlock, unref, withCtx } from "vue";
9
4
  //#region packages/editor/src/fields/EventSelect.vue?vue&type=script&setup=true&lang.ts
10
5
  var _hoisted_1 = { class: "m-fields-event-select" };
11
6
  var _hoisted_2 = {
12
7
  key: 1,
13
8
  class: "fullWidth event-select-container"
14
9
  };
15
- var _hoisted_3 = { class: "event-select-header" };
16
- var _hoisted_4 = { class: "event-item-header" };
10
+ var _hoisted_3 = { class: "event-item-header" };
17
11
  var EventSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
18
12
  name: "MFieldsEventSelect",
19
13
  __name: "EventSelect",
@@ -36,244 +30,21 @@ var EventSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defi
36
30
  setup(__props, { emit: __emit }) {
37
31
  const props = __props;
38
32
  const emit = __emit;
39
- const { editorService, dataSourceService, eventsService, codeBlockService, propsService } = useServices();
40
- const eventNameConfig = computed(() => {
41
- return {
42
- name: "name",
43
- text: "事件类型",
44
- type: (mForm, { formValue }) => {
45
- if (props.config.src !== "component" || formValue.type === "page-fragment-container" && formValue.pageFragmentId) return "cascader";
46
- return "select";
47
- },
48
- labelWidth: "70px",
49
- checkStrictly: () => props.config.src !== "component",
50
- valueSeparator: ".",
51
- options: (_mForm, { formValue }) => getEventNameOptions(props.config.src, formValue),
52
- rules: [{
53
- validator: ({ value, callback }, { formValue }) => {
54
- const allowedNames = getEventNameAllowedValues(props.config, formValue);
55
- if (allowedNames && allowedNames.size > 0 && value && !allowedNames.has(value)) return callback(`事件名(${value})不存在`);
56
- callback();
57
- },
58
- trigger: "blur"
59
- }],
60
- ...props.config.eventNameConfig
61
- };
62
- });
63
- const actionTypeOptions = computed(() => {
64
- const o = [{
65
- text: "组件",
66
- label: "组件",
67
- value: ActionType.COMP
68
- }];
69
- if (!propsService.getDisabledCodeBlock()) o.push({
70
- text: "代码",
71
- label: "代码",
72
- disabled: !Object.keys(codeBlockService.getCodeDsl() || {}).length,
73
- value: ActionType.CODE
74
- });
75
- if (!propsService.getDisabledDataSource()) o.push({
76
- text: "数据源",
77
- label: "数据源",
78
- value: ActionType.DATA_SOURCE
79
- });
80
- return o;
81
- });
82
- const actionTypeConfig = computed(() => {
83
- return {
84
- name: "actionType",
85
- text: "联动类型",
86
- type: "select",
87
- labelPosition: "left",
88
- defaultValue: ActionType.COMP,
89
- options: actionTypeOptions.value,
90
- rules: [{
91
- required: true,
92
- message: "联动类型不能为空"
93
- }, {
94
- typeMatch: true,
95
- trigger: "blur"
96
- }],
97
- onChange: (_mForm, _v, { setModel }) => {
98
- setModel("to", "");
99
- setModel("method", "");
100
- setModel("codeId", "");
101
- setModel("dataSourceMethod", []);
102
- },
103
- ...props.config.actionTypeConfig
104
- };
105
- });
106
- const targetCompConfig = computed(() => {
107
- return {
108
- name: "to",
109
- text: "联动组件",
110
- type: "ui-select",
111
- labelPosition: "left",
112
- display: (_mForm, { model }) => model.actionType === ActionType.COMP,
113
- onChange: (_mForm, _v, { setModel }) => {
114
- setModel("method", "");
115
- },
116
- rules: [{
117
- typeMatch: true,
118
- trigger: "blur"
119
- }],
120
- ...props.config.targetCompConfig
121
- };
122
- });
123
- const compActionConfig = computed(() => {
124
- return {
125
- name: "method",
126
- text: "动作",
127
- labelPosition: "left",
128
- type: (mForm, { model }) => {
129
- const to = editorService.getNodeById(model.to);
130
- if (to && to.type === "page-fragment-container" && to.pageFragmentId) return "cascader";
131
- return "select";
132
- },
133
- checkStrictly: () => props.config.src !== "component",
134
- display: (mForm, { model }) => model.actionType === ActionType.COMP,
135
- options: (_mForm, { model }) => getCompActionOptions(model.to),
136
- rules: [{
137
- trigger: "blur",
138
- validator: ({ value, callback }, { model }) => {
139
- const allowedMethods = getCompActionAllowedValues(props.config, model);
140
- const normalized = normalizeCompActionValue(value);
141
- if (allowedMethods && allowedMethods.size > 0 && normalized && !allowedMethods.has(normalized)) return callback(`动作名(${normalized})不存在`);
142
- callback();
143
- }
144
- }],
145
- ...props.config.compActionConfig
146
- };
147
- });
148
- const codeActionConfig = computed(() => {
149
- return {
150
- type: "code-select-col",
151
- text: "代码块",
152
- name: "codeId",
153
- notEditable: () => !codeBlockService.getEditStatus(),
154
- display: (mForm, { model }) => model.actionType === ActionType.CODE,
155
- ...props.config.codeActionConfig
156
- };
157
- });
158
- const dataSourceActionConfig = computed(() => {
159
- return {
160
- type: "data-source-method-select",
161
- text: "数据源方法",
162
- name: "dataSourceMethod",
163
- notEditable: () => !dataSourceService.get("editable"),
164
- display: (mForm, { model }) => model.actionType === ActionType.DATA_SOURCE,
165
- ...props.config.dataSourceActionConfig
166
- };
167
- });
168
- const tableConfig = computed(() => defineFormItem({
169
- type: "table",
170
- name: "events",
171
- items: [
172
- {
173
- name: "name",
174
- label: "事件名",
175
- type: eventNameConfig.value.type,
176
- options: (mForm, { formValue }) => eventsService.getEvent(formValue.type, { node: editorService.getNodeById(formValue.id) }).map((option) => ({
177
- text: option.label,
178
- value: option.value
179
- }))
180
- },
181
- {
182
- name: "to",
183
- label: "联动组件",
184
- type: "ui-select"
185
- },
186
- {
187
- name: "method",
188
- label: "动作",
189
- type: compActionConfig.value.type,
190
- options: (mForm, { model, formValue }) => {
191
- const node = editorService.getNodeById(model.to) || formValue;
192
- if (!node?.type) return [];
193
- return eventsService.getMethod(node.type, {
194
- targetId: model.to,
195
- node
196
- }).map((option) => ({
197
- text: option.label,
198
- value: option.value
199
- }));
200
- }
201
- }
202
- ]
203
- }));
204
- const actionsConfig = computed(() => defineFormItem({
205
- type: "panel",
206
- labelPosition: "left",
207
- items: [{
208
- type: "group-list",
209
- name: "actions",
210
- expandAll: true,
211
- enableToggleMode: false,
212
- titlePrefix: "动作",
213
- labelPosition: "left",
214
- items: [
215
- actionTypeConfig.value,
216
- targetCompConfig.value,
217
- compActionConfig.value,
218
- codeActionConfig.value,
219
- dataSourceActionConfig.value
220
- ]
221
- }]
222
- }));
223
- const isOldVersion = computed(() => {
224
- if (props.model[props.name].length === 0) return false;
225
- return !has(props.model[props.name][0], "actions");
226
- });
33
+ const tableConfig = computed(() => createLegacyTableConfig(props.config));
34
+ const eventNameConfig = computed(() => createEventNameConfig(props.config));
35
+ const eventConfig = computed(() => createEventSelectConfig(props.config, props.name));
36
+ const isOldVersion = computed(() => isLegacyEventValue(props.model[props.name]));
227
37
  /**
228
38
  * 对比模式判定:
229
39
  *
230
- * event-select 内部由「事件列表 + 嵌套子表单」组成,属于复合字段。父级 `MFormContainer` 已将其
231
- * 归入「自接管对比字段」(见 Container.vue 的 `SELF_DIFF_FIELD_TYPES`),即对比时只渲染一次本组件,
232
- * 并把当前值 `model` 与历史值 `lastValues` 一并传入,由本组件把 `is-compare`/`lastValues` 透传给
233
- * 内部的 MPanel / MFormContainer,逐项(事件名、动作)展示前后差异。
40
+ * event-select 内部是事件列表 group-list。父级 `MFormContainer` 已将其归入「自接管对比字段」
41
+ * (见 Container.vue 的 `SELF_DIFF_FIELD_TYPES`),对比时只渲染一次本组件,并把 `is-compare` /
42
+ * `lastValues` 透传给内部 MGroupList title slot 里的事件名表单。
234
43
  *
235
44
  * 仅当存在历史值时才启用对比,避免 lastValues 缺失时退化为「全部新增」的空对比。
236
45
  */
237
46
  const isCompareMode = computed(() => Boolean(props.isCompare && props.lastValues));
238
- /**
239
- * 待渲染的事件卡片列表。
240
- *
241
- * - 非对比模式:直接映射当前事件列表,`lastCardItem` 为空;
242
- * - 对比模式:按索引对齐当前值与历史值,取两者长度的最大值,使得「新增」(仅当前有)与
243
- * 「删除」(仅历史有)的事件都能被渲染出来;缺失的一侧用空对象兜底,从而让子级正确高亮差异。
244
- */
245
- const displayList = computed(() => {
246
- const current = props.model[props.name] || [];
247
- if (!isCompareMode.value) return current.map((cardItem, index) => ({
248
- cardItem,
249
- lastCardItem: void 0,
250
- index
251
- }));
252
- const last = props.lastValues?.[props.name] || [];
253
- const length = Math.max(current.length, last.length);
254
- return Array.from({ length }, (_, index) => ({
255
- cardItem: current[index] ?? {},
256
- lastCardItem: last[index] ?? {},
257
- index
258
- }));
259
- });
260
- const addEvent = () => {
261
- const defaultEvent = {
262
- name: "",
263
- actions: []
264
- };
265
- if (!props.model[props.name]) props.model[props.name] = [];
266
- emit("change", defaultEvent, { modifyKey: props.model[props.name].length });
267
- };
268
- const removeEvent = (index) => {
269
- if (!props.name) return;
270
- props.model[props.name].splice(index, 1);
271
- emit("change", props.model[props.name]);
272
- };
273
- const eventNameChangeHandler = (v, eventData) => {
274
- emit("change", props.model[props.name], eventData);
275
- };
276
- const onChangeHandler = (v, eventData) => emit("change", props.model[props.name], eventData);
47
+ const onChangeHandler = (_v, eventData) => emit("change", props.model[props.name], eventData);
277
48
  return (_ctx, _cache) => {
278
49
  return openBlock(), createElementBlock("div", _hoisted_1, [isOldVersion.value ? (openBlock(), createBlock(unref(MTable), {
279
50
  key: 0,
@@ -292,93 +63,47 @@ var EventSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defi
292
63
  "last-values",
293
64
  "is-compare",
294
65
  "config"
295
- ])) : (openBlock(), createElementBlock("div", _hoisted_2, [
296
- createElementVNode("div", _hoisted_3, [_cache[3] || (_cache[3] = createElementVNode("div", { class: "event-select-title" }, "事件配置", -1)), !isCompareMode.value && displayList.value.length > 0 ? (openBlock(), createBlock(unref(TMagicButton), {
297
- key: 0,
298
- class: "create-button",
299
- text: "",
300
- type: "primary",
301
- icon: unref(Plus),
302
- size: __props.size,
66
+ ])) : (openBlock(), createElementBlock("div", _hoisted_2, [_cache[0] || (_cache[0] = createElementVNode("div", { class: "event-select-header" }, [createElementVNode("div", { class: "event-select-title" }, "事件配置")], -1)), createVNode(unref(MGroupList), {
67
+ config: eventConfig.value,
68
+ name: __props.name,
69
+ disabled: __props.disabled,
70
+ model: __props.model,
71
+ "last-values": __props.lastValues,
72
+ "is-compare": isCompareMode.value,
73
+ prop: __props.prop,
74
+ size: __props.size,
75
+ onChange: onChangeHandler
76
+ }, {
77
+ title: withCtx(({ model: itemModel, lastValues: itemLastValues, prop: itemProp }) => [createElementVNode("div", _hoisted_3, [createVNode(unref(MContainer), {
78
+ class: "fullWidth",
79
+ config: eventNameConfig.value,
80
+ model: itemModel,
81
+ "last-values": itemLastValues,
82
+ "is-compare": isCompareMode.value,
303
83
  disabled: __props.disabled,
304
- onClick: _cache[0] || (_cache[0] = ($event) => addEvent())
305
- }, {
306
- default: withCtx(() => [..._cache[2] || (_cache[2] = [createTextVNode("添加事件", -1)])]),
307
- _: 1
308
- }, 8, [
309
- "icon",
84
+ size: __props.size,
85
+ prop: itemProp,
86
+ onChange: onChangeHandler
87
+ }, null, 8, [
88
+ "config",
89
+ "model",
90
+ "last-values",
91
+ "is-compare",
92
+ "disabled",
310
93
  "size",
311
- "disabled"
312
- ])) : createCommentVNode("v-if", true)]),
313
- (openBlock(true), createElementBlock(Fragment, null, renderList(displayList.value, (entry) => {
314
- return openBlock(), createBlock(unref(MPanel), {
315
- key: entry.index,
316
- disabled: __props.disabled,
317
- size: __props.size,
318
- prop: `${__props.prop}.${entry.index}`,
319
- config: actionsConfig.value,
320
- model: entry.cardItem,
321
- "last-values": entry.lastCardItem,
322
- "is-compare": isCompareMode.value,
323
- "hide-expand": false,
324
- "label-width": __props.config.labelWidth || "100px",
325
- onChange: onChangeHandler
326
- }, {
327
- header: withCtx(() => [createElementVNode("div", _hoisted_4, [createVNode(unref(MContainer), {
328
- class: "fullWidth",
329
- config: eventNameConfig.value,
330
- model: entry.cardItem,
331
- "last-values": entry.lastCardItem,
332
- "is-compare": isCompareMode.value,
333
- disabled: __props.disabled,
334
- size: __props.size,
335
- prop: `${__props.prop}.${entry.index}`,
336
- onChange: eventNameChangeHandler
337
- }, null, 8, [
338
- "config",
339
- "model",
340
- "last-values",
341
- "is-compare",
342
- "disabled",
343
- "size",
344
- "prop"
345
- ]), !isCompareMode.value ? (openBlock(), createBlock(unref(TMagicButton), {
346
- key: 0,
347
- class: "event-item-delete-button",
348
- link: "",
349
- icon: unref(Delete),
350
- disabled: __props.disabled,
351
- size: __props.size,
352
- onClick: ($event) => removeEvent(Number(entry.index))
353
- }, null, 8, [
354
- "icon",
355
- "disabled",
356
- "size",
357
- "onClick"
358
- ])) : createCommentVNode("v-if", true)])]),
359
- _: 2
360
- }, 1032, [
361
- "disabled",
362
- "size",
363
- "prop",
364
- "config",
365
- "model",
366
- "last-values",
367
- "is-compare",
368
- "label-width"
369
- ]);
370
- }), 128)),
371
- !isCompareMode.value ? (openBlock(), createBlock(unref(TMagicButton), {
372
- key: 0,
373
- class: "create-button fullWidth",
374
- icon: unref(Plus),
375
- disabled: __props.disabled,
376
- onClick: _cache[1] || (_cache[1] = ($event) => addEvent())
377
- }, {
378
- default: withCtx(() => [..._cache[4] || (_cache[4] = [createTextVNode("添加事件", -1)])]),
379
- _: 1
380
- }, 8, ["icon", "disabled"])) : createCommentVNode("v-if", true)
381
- ]))]);
94
+ "prop"
95
+ ])])]),
96
+ _: 1
97
+ }, 8, [
98
+ "config",
99
+ "name",
100
+ "disabled",
101
+ "model",
102
+ "last-values",
103
+ "is-compare",
104
+ "prop",
105
+ "size"
106
+ ])]))]);
382
107
  };
383
108
  }
384
109
  });
@@ -1,6 +1,5 @@
1
1
  import CodeEditor_default from "../layouts/CodeEditor.js";
2
2
  import CodeIcon_default from "../icons/CodeIcon.js";
3
- import { FORM_SILENT_MODE_KEY } from "@tmagic/form";
4
3
  import { TMagicButton, TMagicInput } from "@tmagic/design";
5
4
  import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, inject, openBlock, ref, renderList, unref, watchEffect, withCtx } from "vue";
6
5
  import { Delete, Plus } from "@element-plus/icons-vue";
@@ -33,7 +32,6 @@ var KeyValue_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
33
32
  const props = __props;
34
33
  const emit = __emit;
35
34
  const mForm = inject("mForm");
36
- const silentMode = inject(FORM_SILENT_MODE_KEY, false);
37
35
  /** 对比模式下隐藏增删/代码切换等操作按钮,仅保留只读展示。 */
38
36
  const isCompare = computed(() => Boolean(mForm?.isCompare));
39
37
  const records = ref([]);
@@ -139,7 +137,7 @@ var KeyValue_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
139
137
  "disabled",
140
138
  "icon"
141
139
  ])) : createCommentVNode("v-if", true)])) : createCommentVNode("v-if", true),
142
- __props.config.advanced && showCode.value && !unref(silentMode) ? (openBlock(), createBlock(CodeEditor_default, {
140
+ __props.config.advanced && showCode.value ? (openBlock(), createBlock(CodeEditor_default, {
143
141
  key: 1,
144
142
  "editor-custom-type": "m-fields-key-value",
145
143
  language: "javascript",
@@ -152,7 +150,7 @@ var KeyValue_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
152
150
  parse: true,
153
151
  onSave: save
154
152
  }, null, 8, ["init-values", "options"])) : createCommentVNode("v-if", true),
155
- __props.config.advanced && !isCompare.value && !unref(silentMode) ? (openBlock(), createBlock(unref(TMagicButton), {
153
+ __props.config.advanced && !isCompare.value ? (openBlock(), createBlock(unref(TMagicButton), {
156
154
  key: 2,
157
155
  size: "default",
158
156
  disabled: __props.disabled,