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

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 (43) hide show
  1. package/dist/es/fields/CodeSelectCol.vue_vue_type_script_setup_true_lang.js +5 -4
  2. package/dist/es/fields/CondOpSelect.vue_vue_type_script_setup_true_lang.js +3 -2
  3. package/dist/es/fields/DataSourceFieldSelect/Index.vue_vue_type_script_setup_true_lang.js +8 -5
  4. package/dist/es/fields/DataSourceFields.vue_vue_type_script_setup_true_lang.js +10 -6
  5. package/dist/es/fields/DataSourceMethodSelect.vue_vue_type_script_setup_true_name_true_lang.js +6 -4
  6. package/dist/es/fields/DataSourceMethods.vue_vue_type_script_setup_true_lang.js +4 -1
  7. package/dist/es/fields/DataSourceMocks.vue_vue_type_script_setup_true_lang.js +6 -4
  8. package/dist/es/fields/DisplayConds.vue_vue_type_script_setup_true_lang.js +12 -7
  9. package/dist/es/fields/EventSelect.vue_vue_type_script_setup_true_lang.js +2 -2
  10. package/dist/es/fields/KeyValue.vue_vue_type_script_setup_true_lang.js +4 -2
  11. package/dist/es/fields/StyleSetter/pro/Font.vue_vue_type_script_setup_true_lang.js +2 -2
  12. package/dist/es/hooks/use-compare-form.js +1 -2
  13. package/dist/es/index.js +3 -3
  14. package/dist/es/plugin.js +9 -1
  15. package/dist/es/services/editor.js +43 -37
  16. package/dist/es/services/props.js +1 -1
  17. package/dist/es/style.css +4 -0
  18. package/dist/es/utils/event.js +1 -1
  19. package/dist/es/utils/props.js +1 -29
  20. package/dist/es/utils/type-match-rules.js +21 -20
  21. package/dist/style.css +4 -0
  22. package/dist/themes/magic-admin.css +4 -0
  23. package/dist/tmagic-editor.umd.cjs +412 -398
  24. package/package.json +8 -8
  25. package/src/fields/CodeSelectCol.vue +4 -2
  26. package/src/fields/CondOpSelect.vue +3 -2
  27. package/src/fields/DataSourceFieldSelect/Index.vue +9 -4
  28. package/src/fields/DataSourceFields.vue +6 -0
  29. package/src/fields/DataSourceMethodSelect.vue +4 -1
  30. package/src/fields/DataSourceMethods.vue +11 -2
  31. package/src/fields/DataSourceMocks.vue +10 -1
  32. package/src/fields/DisplayConds.vue +11 -7
  33. package/src/fields/EventSelect.vue +3 -3
  34. package/src/fields/KeyValue.vue +4 -3
  35. package/src/fields/StyleSetter/pro/Font.vue +2 -2
  36. package/src/hooks/use-compare-form.ts +1 -4
  37. package/src/plugin.ts +9 -1
  38. package/src/services/editor.ts +53 -85
  39. package/src/type.ts +23 -0
  40. package/src/utils/event.ts +2 -2
  41. package/src/utils/props.ts +0 -32
  42. package/src/utils/type-match-rules.ts +29 -28
  43. package/types/index.d.ts +39 -61
@@ -5181,311 +5181,10 @@
5181
5181
  };
5182
5182
  }));
5183
5183
  //#endregion
5184
- //#region packages/editor/src/utils/props.ts
5185
- var arrayOptions, eqOptions, numberOptions, booleanOptions, getCondOpOptionsByFieldType, styleTabConfig, eventTabConfig, advancedTabConfig, displayTabConfig, fillConfig, removeStyleDisplayConfig;
5186
- var init_props = __esmMin((() => {
5187
- arrayOptions = [{
5188
- text: "包含",
5189
- value: "include"
5190
- }, {
5191
- text: "不包含",
5192
- value: "not_include"
5193
- }];
5194
- eqOptions = [{
5195
- text: "等于",
5196
- value: "="
5197
- }, {
5198
- text: "不等于",
5199
- value: "!="
5200
- }];
5201
- numberOptions = [
5202
- {
5203
- text: "大于",
5204
- value: ">"
5205
- },
5206
- {
5207
- text: "大于等于",
5208
- value: ">="
5209
- },
5210
- {
5211
- text: "小于",
5212
- value: "<"
5213
- },
5214
- {
5215
- text: "小于等于",
5216
- value: "<="
5217
- },
5218
- {
5219
- text: "在范围内",
5220
- value: "between"
5221
- },
5222
- {
5223
- text: "不在范围内",
5224
- value: "not_between"
5225
- }
5226
- ];
5227
- booleanOptions = [{
5228
- text: "是",
5229
- value: "is"
5230
- }, {
5231
- text: "不是",
5232
- value: "not"
5233
- }];
5234
- getCondOpOptionsByFieldType = (type) => {
5235
- if (type === "array") return arrayOptions;
5236
- if (type === "boolean" || type === "null") return booleanOptions;
5237
- if (type === "number") return [...eqOptions, ...numberOptions];
5238
- if (type === "string") return [...arrayOptions, ...eqOptions];
5239
- return [
5240
- ...arrayOptions,
5241
- ...eqOptions,
5242
- ...numberOptions
5243
- ];
5244
- };
5245
- styleTabConfig = {
5246
- title: "样式",
5247
- lazy: true,
5248
- display: ({ services }) => !(services?.uiService?.get("showStylePanel") ?? true),
5249
- items: [{
5250
- name: "style",
5251
- labelWidth: "100px",
5252
- type: "style-setter",
5253
- items: [{ names: [
5254
- "display",
5255
- "flexDirection",
5256
- "justifyContent",
5257
- "alignItems",
5258
- "flexWrap",
5259
- "marginTop",
5260
- "marginRight",
5261
- "marginBottom",
5262
- "marginLeft",
5263
- "paddingTop",
5264
- "paddingRight",
5265
- "paddingBottom",
5266
- "paddingLeft",
5267
- "width",
5268
- "height",
5269
- "overflow",
5270
- "fontSize",
5271
- "lineHeight",
5272
- "fontWeight",
5273
- "color",
5274
- "textAlign",
5275
- "backgroundColor",
5276
- "backgroundImage",
5277
- "backgroundSize",
5278
- "backgroundPosition",
5279
- "backgroundRepeat",
5280
- "position",
5281
- "zIndex",
5282
- "top",
5283
- "right",
5284
- "bottom",
5285
- "left",
5286
- "borderRadius",
5287
- "borderTopWidth",
5288
- "borderTopStyle",
5289
- "borderTopColor",
5290
- "borderRightColor",
5291
- "borderRightWidth",
5292
- "borderRightStyle",
5293
- "borderRightColor",
5294
- "borderBottomWidth",
5295
- "borderBottomStyle",
5296
- "borderBottomColor",
5297
- "borderLeftStyle",
5298
- "borderLeftWidth",
5299
- "borderLeftColor",
5300
- "borderWidth",
5301
- "borderStyle",
5302
- "borderColor",
5303
- "opacity"
5304
- ] }, {
5305
- name: "transform",
5306
- defaultValue: () => ({})
5307
- }]
5308
- }]
5309
- };
5310
- eventTabConfig = {
5311
- title: "事件",
5312
- lazy: true,
5313
- items: [{
5314
- name: "events",
5315
- src: "component",
5316
- labelWidth: "100px",
5317
- type: "event-select",
5318
- rules: [{ typeMatch: true }]
5319
- }]
5320
- };
5321
- advancedTabConfig = {
5322
- title: "高级",
5323
- lazy: true,
5324
- items: [
5325
- {
5326
- name: _tmagic_core.NODE_DISABLE_CODE_BLOCK_KEY,
5327
- text: "禁用代码块",
5328
- type: "switch",
5329
- labelPosition: "left",
5330
- defaultValue: false,
5331
- extra: "开启后,配置的代码块将不会被执行"
5332
- },
5333
- {
5334
- name: _tmagic_core.NODE_DISABLE_DATA_SOURCE_KEY,
5335
- text: "禁用数据源",
5336
- type: "switch",
5337
- labelPosition: "left",
5338
- defaultValue: false,
5339
- extra: "开启后,组件内配置的数据源相关配置将不会被编译,显隐条件将失效"
5340
- },
5341
- {
5342
- name: "created",
5343
- text: "Created",
5344
- labelPosition: "top",
5345
- type: "code-select",
5346
- titleExtra: "组件初始化时执行",
5347
- rules: [{
5348
- typeMatch: true,
5349
- trigger: "change"
5350
- }, { validator: ({ value, callback }) => {
5351
- if (value && value.hookType !== _tmagic_core.HookType.CODE) return callback("hookType 必须是 code");
5352
- callback();
5353
- } }]
5354
- },
5355
- {
5356
- name: "mounted",
5357
- text: "Mounted",
5358
- labelPosition: "top",
5359
- type: "code-select",
5360
- titleExtra: "组件挂载到dom时执行",
5361
- rules: [{
5362
- typeMatch: true,
5363
- trigger: "change"
5364
- }, { validator: ({ value, callback }) => {
5365
- if (value && value.hookType !== _tmagic_core.HookType.CODE) return callback("hookType 必须是 code");
5366
- callback();
5367
- } }]
5368
- },
5369
- {
5370
- name: "display",
5371
- text: "Display",
5372
- titleExtra: "控制组件是否渲染,关系的代码块返回值为false时不渲染",
5373
- labelPosition: "top",
5374
- type: "code-select",
5375
- rules: [{
5376
- typeMatch: true,
5377
- trigger: "change"
5378
- }, { validator: ({ value, callback }) => {
5379
- if (value && value.hookType !== _tmagic_core.HookType.CODE) return callback("hookType 必须是 code");
5380
- callback();
5381
- } }]
5382
- }
5383
- ]
5384
- };
5385
- displayTabConfig = {
5386
- title: "显示条件",
5387
- display: (_state, { model }) => model.type !== "page",
5388
- items: [
5389
- {
5390
- name: _tmagic_core.NODE_CONDS_RESULT_KEY,
5391
- type: "select",
5392
- text: "条件成立时",
5393
- defaultValue: false,
5394
- options: [{
5395
- text: "显示",
5396
- value: false
5397
- }, {
5398
- text: "隐藏",
5399
- value: true
5400
- }],
5401
- extra: (_state, { model }) => `条件成立时${model[_tmagic_core.NODE_CONDS_RESULT_KEY] ? "隐藏" : "显示"},不成立时${model[_tmagic_core.NODE_CONDS_RESULT_KEY] ? "显示" : "隐藏"};<br />同一条件组内的所有条件配置同时成立时表示该条件组成立,任意一个条件组成立时表示条件成立(条件组内为且的关系,条件组间为或的关系);<br />条件为空时表示成立;`
5402
- },
5403
- {
5404
- text: "条件组配置",
5405
- static: true,
5406
- className: "display-conds-title"
5407
- },
5408
- {
5409
- type: "display-conds",
5410
- name: _tmagic_core.NODE_CONDS_KEY,
5411
- titlePrefix: "条件组",
5412
- fixed: "right",
5413
- operateColWidth: 112,
5414
- defaultValue: [],
5415
- rules: [{ typeMatch: true }]
5416
- }
5417
- ]
5418
- };
5419
- fillConfig = (config = [], { labelWidth = "80px", disabledDataSource = false, disabledCodeBlock = false } = {}) => {
5420
- const propsConfig = [];
5421
- if (!config.find((item) => "name" in item && item.name === "type")) propsConfig.push({
5422
- text: "type",
5423
- name: "type",
5424
- type: "hidden"
5425
- });
5426
- if (!config.find((item) => "name" in item && item.name === "id")) propsConfig.push({
5427
- name: "id",
5428
- text: "ID",
5429
- type: "text",
5430
- static: true,
5431
- append: {
5432
- type: "icon",
5433
- text: "https://vip.image.video.qpic.cn/vupload/20260615/36cf7e1781493669935.svg",
5434
- extra: "复制",
5435
- handler: (vm, { model }) => {
5436
- navigator.clipboard.writeText(`${model.id}`).then(() => {
5437
- _tmagic_design.tMagicMessage.success("已复制");
5438
- }).catch(() => {
5439
- _tmagic_design.tMagicMessage.error("复制失败");
5440
- });
5441
- }
5442
- }
5443
- });
5444
- if (!config.find((item) => "name" in item && item.name === "name")) propsConfig.push({
5445
- name: "name",
5446
- text: "组件名称"
5447
- });
5448
- const noCodeAdvancedTabItems = advancedTabConfig.items.filter((item) => "type" in item && item.type !== "code-select");
5449
- if (noCodeAdvancedTabItems.length > 0 && disabledCodeBlock) advancedTabConfig.items = noCodeAdvancedTabItems;
5450
- const tabConfig = {
5451
- type: "tab",
5452
- labelWidth,
5453
- className: "magic-right-panel-tabs-top",
5454
- items: [
5455
- {
5456
- title: "属性",
5457
- items: [...propsConfig, ...config]
5458
- },
5459
- { ...styleTabConfig },
5460
- { ...eventTabConfig }
5461
- ]
5462
- };
5463
- if (!disabledCodeBlock) tabConfig.items.push({ ...advancedTabConfig });
5464
- else if (noCodeAdvancedTabItems.length > 0) tabConfig.items.push({ ...advancedTabConfig });
5465
- if (!disabledDataSource) tabConfig.items.push({ ...displayTabConfig });
5466
- return [tabConfig];
5467
- };
5468
- removeStyleDisplayConfig = (formConfig) => formConfig.map((item) => {
5469
- if (!("type" in item)) return item;
5470
- if (item?.type !== "tab" || !Array.isArray(item.items)) return item;
5471
- return {
5472
- ...item,
5473
- items: item.items.map((tabPane) => {
5474
- if (tabPane?.title !== "样式" || !Array.isArray(tabPane.items)) return tabPane;
5475
- return {
5476
- ...tabPane,
5477
- display: true
5478
- };
5479
- })
5480
- };
5481
- });
5482
- }));
5483
- //#endregion
5484
5184
  //#region packages/editor/src/hooks/use-compare-form.ts
5485
5185
  var useCompareForm;
5486
5186
  var init_use_compare_form = __esmMin((() => {
5487
5187
  init_code_block();
5488
- init_props();
5489
5188
  useCompareForm = (props) => {
5490
5189
  (0, vue.provide)("services", props.services);
5491
5190
  const config = (0, vue.ref)([]);
@@ -5529,7 +5228,7 @@
5529
5228
  switch (props.category) {
5530
5229
  case "node":
5531
5230
  if (!props.type) return [];
5532
- return removeStyleDisplayConfig(await props.services.propsService.getPropsConfig(props.type, { node: props.value }));
5231
+ return props.services.propsService.getPropsConfig(props.type, { node: props.value });
5533
5232
  case "data-source": return props.services.dataSourceService.getFormConfig(props.type || "base").map((item) => "type" in item && item.type === "tab" ? {
5534
5233
  ...item,
5535
5234
  active: "fields"
@@ -5701,9 +5400,294 @@
5701
5400
  }
5702
5401
  };
5703
5402
  //#endregion
5403
+ //#region packages/editor/src/utils/props.ts
5404
+ var arrayOptions = [{
5405
+ text: "包含",
5406
+ value: "include"
5407
+ }, {
5408
+ text: "不包含",
5409
+ value: "not_include"
5410
+ }];
5411
+ var eqOptions = [{
5412
+ text: "等于",
5413
+ value: "="
5414
+ }, {
5415
+ text: "不等于",
5416
+ value: "!="
5417
+ }];
5418
+ var numberOptions = [
5419
+ {
5420
+ text: "大于",
5421
+ value: ">"
5422
+ },
5423
+ {
5424
+ text: "大于等于",
5425
+ value: ">="
5426
+ },
5427
+ {
5428
+ text: "小于",
5429
+ value: "<"
5430
+ },
5431
+ {
5432
+ text: "小于等于",
5433
+ value: "<="
5434
+ },
5435
+ {
5436
+ text: "在范围内",
5437
+ value: "between"
5438
+ },
5439
+ {
5440
+ text: "不在范围内",
5441
+ value: "not_between"
5442
+ }
5443
+ ];
5444
+ var booleanOptions = [{
5445
+ text: "是",
5446
+ value: "is"
5447
+ }, {
5448
+ text: "不是",
5449
+ value: "not"
5450
+ }];
5451
+ /** 按字段类型返回条件运算符选项(UI 与 typeMatch 校验共用) */
5452
+ var getCondOpOptionsByFieldType = (type) => {
5453
+ if (type === "array") return arrayOptions;
5454
+ if (type === "boolean" || type === "null") return booleanOptions;
5455
+ if (type === "number") return [...eqOptions, ...numberOptions];
5456
+ if (type === "string") return [...arrayOptions, ...eqOptions];
5457
+ return [
5458
+ ...arrayOptions,
5459
+ ...eqOptions,
5460
+ ...numberOptions
5461
+ ];
5462
+ };
5463
+ var styleTabConfig = {
5464
+ title: "样式",
5465
+ display: ({ services }) => !(services?.uiService?.get("showStylePanel") ?? true),
5466
+ items: [{
5467
+ name: "style",
5468
+ labelWidth: "100px",
5469
+ type: "style-setter",
5470
+ items: [{ names: [
5471
+ "display",
5472
+ "flexDirection",
5473
+ "justifyContent",
5474
+ "alignItems",
5475
+ "flexWrap",
5476
+ "marginTop",
5477
+ "marginRight",
5478
+ "marginBottom",
5479
+ "marginLeft",
5480
+ "paddingTop",
5481
+ "paddingRight",
5482
+ "paddingBottom",
5483
+ "paddingLeft",
5484
+ "width",
5485
+ "height",
5486
+ "overflow",
5487
+ "fontSize",
5488
+ "lineHeight",
5489
+ "fontWeight",
5490
+ "color",
5491
+ "textAlign",
5492
+ "backgroundColor",
5493
+ "backgroundImage",
5494
+ "backgroundSize",
5495
+ "backgroundPosition",
5496
+ "backgroundRepeat",
5497
+ "position",
5498
+ "zIndex",
5499
+ "top",
5500
+ "right",
5501
+ "bottom",
5502
+ "left",
5503
+ "borderRadius",
5504
+ "borderTopWidth",
5505
+ "borderTopStyle",
5506
+ "borderTopColor",
5507
+ "borderRightColor",
5508
+ "borderRightWidth",
5509
+ "borderRightStyle",
5510
+ "borderRightColor",
5511
+ "borderBottomWidth",
5512
+ "borderBottomStyle",
5513
+ "borderBottomColor",
5514
+ "borderLeftStyle",
5515
+ "borderLeftWidth",
5516
+ "borderLeftColor",
5517
+ "borderWidth",
5518
+ "borderStyle",
5519
+ "borderColor",
5520
+ "opacity"
5521
+ ] }, {
5522
+ name: "transform",
5523
+ defaultValue: () => ({})
5524
+ }]
5525
+ }]
5526
+ };
5527
+ var eventTabConfig = {
5528
+ title: "事件",
5529
+ items: [{
5530
+ name: "events",
5531
+ src: "component",
5532
+ labelWidth: "100px",
5533
+ type: "event-select",
5534
+ rules: [{ typeMatch: true }]
5535
+ }]
5536
+ };
5537
+ var advancedTabConfig = {
5538
+ title: "高级",
5539
+ items: [
5540
+ {
5541
+ name: _tmagic_core.NODE_DISABLE_CODE_BLOCK_KEY,
5542
+ text: "禁用代码块",
5543
+ type: "switch",
5544
+ labelPosition: "left",
5545
+ defaultValue: false,
5546
+ extra: "开启后,配置的代码块将不会被执行"
5547
+ },
5548
+ {
5549
+ name: _tmagic_core.NODE_DISABLE_DATA_SOURCE_KEY,
5550
+ text: "禁用数据源",
5551
+ type: "switch",
5552
+ labelPosition: "left",
5553
+ defaultValue: false,
5554
+ extra: "开启后,组件内配置的数据源相关配置将不会被编译,显隐条件将失效"
5555
+ },
5556
+ {
5557
+ name: "created",
5558
+ text: "Created",
5559
+ labelPosition: "top",
5560
+ type: "code-select",
5561
+ titleExtra: "组件初始化时执行",
5562
+ rules: [{
5563
+ typeMatch: true,
5564
+ trigger: "change"
5565
+ }, { validator: ({ value, callback }) => {
5566
+ if (value && value.hookType !== _tmagic_core.HookType.CODE) return callback("hookType 必须是 code");
5567
+ callback();
5568
+ } }]
5569
+ },
5570
+ {
5571
+ name: "mounted",
5572
+ text: "Mounted",
5573
+ labelPosition: "top",
5574
+ type: "code-select",
5575
+ titleExtra: "组件挂载到dom时执行",
5576
+ rules: [{
5577
+ typeMatch: true,
5578
+ trigger: "change"
5579
+ }, { validator: ({ value, callback }) => {
5580
+ if (value && value.hookType !== _tmagic_core.HookType.CODE) return callback("hookType 必须是 code");
5581
+ callback();
5582
+ } }]
5583
+ },
5584
+ {
5585
+ name: "display",
5586
+ text: "Display",
5587
+ titleExtra: "控制组件是否渲染,关系的代码块返回值为false时不渲染",
5588
+ labelPosition: "top",
5589
+ type: "code-select",
5590
+ rules: [{
5591
+ typeMatch: true,
5592
+ trigger: "change"
5593
+ }, { validator: ({ value, callback }) => {
5594
+ if (value && value.hookType !== _tmagic_core.HookType.CODE) return callback("hookType 必须是 code");
5595
+ callback();
5596
+ } }]
5597
+ }
5598
+ ]
5599
+ };
5600
+ var displayTabConfig = {
5601
+ title: "显示条件",
5602
+ display: (_state, { model }) => model.type !== "page",
5603
+ items: [
5604
+ {
5605
+ name: _tmagic_core.NODE_CONDS_RESULT_KEY,
5606
+ type: "select",
5607
+ text: "条件成立时",
5608
+ defaultValue: false,
5609
+ options: [{
5610
+ text: "显示",
5611
+ value: false
5612
+ }, {
5613
+ text: "隐藏",
5614
+ value: true
5615
+ }],
5616
+ extra: (_state, { model }) => `条件成立时${model[_tmagic_core.NODE_CONDS_RESULT_KEY] ? "隐藏" : "显示"},不成立时${model[_tmagic_core.NODE_CONDS_RESULT_KEY] ? "显示" : "隐藏"};<br />同一条件组内的所有条件配置同时成立时表示该条件组成立,任意一个条件组成立时表示条件成立(条件组内为且的关系,条件组间为或的关系);<br />条件为空时表示成立;`
5617
+ },
5618
+ {
5619
+ text: "条件组配置",
5620
+ static: true,
5621
+ className: "display-conds-title"
5622
+ },
5623
+ {
5624
+ type: "display-conds",
5625
+ name: _tmagic_core.NODE_CONDS_KEY,
5626
+ titlePrefix: "条件组",
5627
+ fixed: "right",
5628
+ operateColWidth: 112,
5629
+ defaultValue: [],
5630
+ rules: [{ typeMatch: true }]
5631
+ }
5632
+ ]
5633
+ };
5634
+ /**
5635
+ * 统一为组件属性表单加上事件、高级、样式配置
5636
+ * @param config 组件属性配置
5637
+ * @returns Object
5638
+ */
5639
+ var fillConfig = (config = [], { labelWidth = "80px", disabledDataSource = false, disabledCodeBlock = false } = {}) => {
5640
+ const propsConfig = [];
5641
+ if (!config.find((item) => "name" in item && item.name === "type")) propsConfig.push({
5642
+ text: "type",
5643
+ name: "type",
5644
+ type: "hidden"
5645
+ });
5646
+ if (!config.find((item) => "name" in item && item.name === "id")) propsConfig.push({
5647
+ name: "id",
5648
+ text: "ID",
5649
+ type: "text",
5650
+ static: true,
5651
+ append: {
5652
+ type: "icon",
5653
+ text: "https://vip.image.video.qpic.cn/vupload/20260615/36cf7e1781493669935.svg",
5654
+ extra: "复制",
5655
+ handler: (vm, { model }) => {
5656
+ navigator.clipboard.writeText(`${model.id}`).then(() => {
5657
+ _tmagic_design.tMagicMessage.success("已复制");
5658
+ }).catch(() => {
5659
+ _tmagic_design.tMagicMessage.error("复制失败");
5660
+ });
5661
+ }
5662
+ }
5663
+ });
5664
+ if (!config.find((item) => "name" in item && item.name === "name")) propsConfig.push({
5665
+ name: "name",
5666
+ text: "组件名称"
5667
+ });
5668
+ const noCodeAdvancedTabItems = advancedTabConfig.items.filter((item) => "type" in item && item.type !== "code-select");
5669
+ if (noCodeAdvancedTabItems.length > 0 && disabledCodeBlock) advancedTabConfig.items = noCodeAdvancedTabItems;
5670
+ const tabConfig = {
5671
+ type: "tab",
5672
+ labelWidth,
5673
+ className: "magic-right-panel-tabs-top",
5674
+ items: [
5675
+ {
5676
+ title: "属性",
5677
+ items: [...propsConfig, ...config]
5678
+ },
5679
+ { ...styleTabConfig },
5680
+ { ...eventTabConfig }
5681
+ ]
5682
+ };
5683
+ if (!disabledCodeBlock) tabConfig.items.push({ ...advancedTabConfig });
5684
+ else if (noCodeAdvancedTabItems.length > 0) tabConfig.items.push({ ...advancedTabConfig });
5685
+ if (!disabledDataSource) tabConfig.items.push({ ...displayTabConfig });
5686
+ return [tabConfig];
5687
+ };
5688
+ //#endregion
5704
5689
  //#region packages/editor/src/services/props.ts
5705
5690
  init_lodash();
5706
- init_props();
5707
5691
  var canUsePluginMethods$8 = {
5708
5692
  async: [
5709
5693
  "setPropsConfig",
@@ -7363,6 +7347,8 @@
7363
7347
  init_lodash();
7364
7348
  init_type();
7365
7349
  init_editor();
7350
+ /** 历史插回时把记录的下标收敛到 [0, length],越界(含未记录)一律追加到末尾 */
7351
+ var clampIndex = (index, length) => typeof index === "number" && index >= 0 && index <= length ? index : length;
7366
7352
  /**
7367
7353
  * 把「变更前后节点快照」列表归一成 update 类型的 {@link StepDiffItem} 列表,供 {@link StepValue.diff} 使用。
7368
7354
  * `changeRecords` 来自 form 端的 propPath/value 列表,撤销/重做时只对这些 propPath 做局部更新;
@@ -7402,6 +7388,11 @@
7402
7388
  * 普通操作不会读取它,调用前由 *AndGetHistoryId 重置为 null。
7403
7389
  */
7404
7390
  lastPushedHistoryId = null;
7391
+ /**
7392
+ * 上一次 doAdd 的插入记忆:nodeId 为插入的节点,selectedId 为当时的选中节点。
7393
+ * 仅在选中节点未变化时复用(连续 add / doNotSelect / 批量粘贴),选中变化后自动失效,无需手动清理。
7394
+ */
7395
+ lastAdded = null;
7405
7396
  constructor() {
7406
7397
  super(canUsePluginMethods.async.map((methodName) => ({
7407
7398
  name: methodName,
@@ -7597,24 +7588,29 @@
7597
7588
  this.set("stage", null);
7598
7589
  this.set("highlightNode", null);
7599
7590
  }
7600
- async doAdd(node, parent) {
7591
+ async doAdd(node, parent, _options = {}) {
7601
7592
  const root = this.get("root");
7602
7593
  if (!root) throw new Error("root为空");
7603
7594
  const curNode = this.get("node");
7604
7595
  const stage = this.get("stage");
7605
7596
  if (!curNode) throw new Error("当前选中节点为空");
7606
7597
  if ((parent.type === _tmagic_core.NodeType.ROOT || curNode?.type === _tmagic_core.NodeType.ROOT) && !(0, _tmagic_utils.isPageOrFragment)(node)) throw new Error("app下不能添加组件");
7607
- if (parent.id !== curNode.id && !(0, _tmagic_utils.isPageOrFragment)(node)) {
7608
- const index = parent.items.indexOf(curNode);
7609
- parent.items?.splice(index + 1, 0, node);
7610
- } else parent.items?.push(node);
7598
+ const anchorId = this.lastAdded?.selectedId === curNode.id ? this.lastAdded.nodeId : curNode.id;
7599
+ const anchorIndex = (0, _tmagic_utils.isPageOrFragment)(node) ? -1 : Math.max(getNodeIndex(anchorId, parent), getNodeIndex(curNode.id, parent));
7600
+ const insertIndex = anchorIndex < 0 ? parent.items.length : anchorIndex + 1;
7601
+ parent.items.splice(insertIndex, 0, node);
7602
+ this.lastAdded = {
7603
+ selectedId: curNode.id,
7604
+ nodeId: node.id
7605
+ };
7611
7606
  const layout = await this.getLayout((0, vue.toRaw)(parent), node);
7612
7607
  node.style = getInitPositionStyle(node.style, layout);
7613
7608
  await stage?.add({
7614
7609
  config: cloneDeep$1(node),
7615
7610
  parent: cloneDeep$1(parent),
7616
7611
  parentId: parent.id,
7617
- root: cloneDeep$1(root)
7612
+ root: cloneDeep$1(root),
7613
+ index: insertIndex
7618
7614
  });
7619
7615
  const newStyle = fixNodePosition(node, parent, stage);
7620
7616
  if (newStyle && (newStyle.top !== node.style.top || newStyle.left !== node.style.left)) {
@@ -7632,14 +7628,12 @@
7632
7628
  * 向指点容器添加组件节点
7633
7629
  * @param addConfig 将要添加的组件节点配置
7634
7630
  * @param parent 要添加到的容器组件节点配置,如果不设置,默认为当前选中的组件的父节点
7635
- * @param options 可选配置
7636
- * @param options.doNotSelect 添加后是否不更新当前选中节点(默认 false,添加后会选中新增的节点)
7637
- * @param options.doNotSwitchPage 添加后是否不切换当前页面(默认 false;新增页面 / 跨页新增时为 true 会跳过会引发页面切换的选中操作)
7638
- * @param options.doNotPushHistory 是否不写入历史记录(默认 false)
7631
+ * @param options 可选配置,见 {@link DslOpOptions}
7639
7632
  * @returns 添加后的节点
7640
7633
  */
7641
- async add(addNode, parent, { doNotSelect = false, doNotSwitchPage = false, doNotPushHistory = false, historyDescription, historySource } = {}) {
7634
+ async add(addNode, parent, options = {}) {
7642
7635
  this.captureSelectionBeforeOp();
7636
+ const { doNotSelect = false, doNotSwitchPage = false, doNotPushHistory = false, historyDescription, historySource } = options;
7643
7637
  const stage = this.get("stage");
7644
7638
  const addNodes = [];
7645
7639
  if (!Array.isArray(addNode)) {
@@ -7647,13 +7641,13 @@
7647
7641
  if (!type) throw new Error("组件类型不能为空");
7648
7642
  addNodes.push({ ...(0, vue.toRaw)(await props_default.getPropsValue(type, config)) });
7649
7643
  } else addNodes.push(...addNode);
7650
- const newNodes = await Promise.all(addNodes.map((node) => {
7644
+ const newNodes = [];
7645
+ for (const node of addNodes) {
7651
7646
  const root = this.get("root");
7652
- if ((0, _tmagic_utils.isPageOrFragment)(node) && root) return this.doAdd(node, root);
7653
- const parentNode = parent ?? getAddParent(node);
7647
+ const parentNode = (0, _tmagic_utils.isPageOrFragment)(node) && root ? root : parent ?? getAddParent(node);
7654
7648
  if (!parentNode) throw new Error("未找到父元素");
7655
- return this.doAdd(node, parentNode);
7656
- }));
7649
+ newNodes.push(await this.doAdd(node, parentNode, options));
7650
+ }
7657
7651
  if (newNodes.length > 1) {
7658
7652
  const wouldSwitchPage = newNodes.some((n) => this.isOnDifferentPage(n));
7659
7653
  if (!doNotSelect && !(doNotSwitchPage && wouldSwitchPage)) {
@@ -7769,7 +7763,8 @@
7769
7763
  * @param options.doNotSwitchPage 删除后是否不切换当前页面(默认 false;删除页面 / 页面片段时为 true 会跳过自动切换到首个剩余页面)
7770
7764
  * @param options.doNotPushHistory 是否不写入历史记录(默认 false)
7771
7765
  */
7772
- async remove(nodeOrNodeList, { doNotSelect = false, doNotSwitchPage = false, doNotPushHistory = false, historyDescription, historySource } = {}) {
7766
+ async remove(nodeOrNodeList, options = {}) {
7767
+ const { doNotPushHistory = false, historyDescription, historySource } = options;
7773
7768
  this.captureSelectionBeforeOp();
7774
7769
  const nodes = Array.isArray(nodeOrNodeList) ? nodeOrNodeList : [nodeOrNodeList];
7775
7770
  const changeItems = nodes.map((node) => ({
@@ -7793,10 +7788,7 @@
7793
7788
  });
7794
7789
  }
7795
7790
  }
7796
- await Promise.all(nodes.map((node) => this.doRemove(node, {
7797
- doNotSelect,
7798
- doNotSwitchPage
7799
- })));
7791
+ await Promise.all(nodes.map((node) => this.doRemove(node, options)));
7800
7792
  this.removeInvalidNodesBySubtree(nodes);
7801
7793
  if (removedItems.length > 0 && pageForOp) if (!doNotPushHistory) this.pushOpHistory("remove", {
7802
7794
  diff: removedItems,
@@ -7818,7 +7810,8 @@
7818
7810
  remove: removedPages
7819
7811
  });
7820
7812
  }
7821
- async doUpdate(config, { changeRecords = [], historySource, replace = false } = {}) {
7813
+ async doUpdate(config, data = {}) {
7814
+ const { changeRecords = [], historySource, replace = false } = data;
7822
7815
  if (!this.get("root")) throw new Error("root为空");
7823
7816
  if (!config?.id) throw new Error("没有配置或者配置缺少id值");
7824
7817
  const info = this.getNodeInfo(config.id, false);
@@ -7867,24 +7860,18 @@
7867
7860
  * 更新节点
7868
7861
  * update后会触发依赖收集,收集完后会掉stage.update方法
7869
7862
  * @param config 新的节点配置,配置中需要有id信息
7870
- * @param data 额外数据
7871
- * @param data.changeRecords 单节点 form 端变更记录(多节点场景下被忽略,使用 changeRecordList)
7872
- * @param data.changeRecordList 多节点 form 端变更记录列表,按 config 数组同序对应每个节点;优先级高于 changeRecords
7873
- * @param data.doNotPushHistory 是否不写入历史记录(默认 false)
7874
- * @param data.historyDescription 入栈时附带的人类可读描述,用于历史面板展示(不影响 undo/redo 行为)
7875
- * @param data.replace 是否整节点替换:为 true 时跳过 mergeWith / toggleFixedPosition / setChildrenLayout,直接用传入配置覆盖(默认 false)
7863
+ * @param data 额外数据,见 {@link UpdateOptions}
7876
7864
  * @returns 更新后的节点配置
7877
7865
  */
7878
7866
  async update(config, data = {}) {
7879
7867
  this.captureSelectionBeforeOp();
7880
- const { doNotPushHistory = false, changeRecordList, changeRecords, historyDescription, historySource, replace = false, invalidInfo } = data;
7868
+ const { doNotPushHistory = false, changeRecordList, changeRecords, historyDescription, historySource, invalidInfo } = data;
7881
7869
  const nodes = Array.isArray(config) ? config : [config];
7882
7870
  const updateData = await Promise.all(nodes.map((node, index) => {
7883
7871
  const recordsForNode = changeRecordList ? changeRecordList[index] ?? [] : changeRecords ?? [];
7884
7872
  return this.doUpdate(node, {
7885
- changeRecords: recordsForNode,
7886
- historySource,
7887
- replace
7873
+ ...data,
7874
+ changeRecords: recordsForNode
7888
7875
  });
7889
7876
  }));
7890
7877
  this.applyInvalidInfo(config, invalidInfo);
@@ -8727,14 +8714,15 @@
8727
8714
  const parent = this.getNodeById(parentId, false);
8728
8715
  if (parent?.items) {
8729
8716
  const addedNode = cloneDeep$1(newSchema);
8730
- if (typeof index === "number" && index >= 0 && index < parent.items.length) parent.items.splice(index, 0, addedNode);
8731
- else parent.items.push(addedNode);
8717
+ const insertIndex = clampIndex(index, parent.items.length);
8718
+ parent.items.splice(insertIndex, 0, addedNode);
8732
8719
  addedNodes.push(addedNode);
8733
8720
  await stage?.add({
8734
8721
  config: cloneDeep$1(newSchema),
8735
8722
  parent: cloneDeep$1(parent),
8736
8723
  parentId: parent.id,
8737
- root: cloneDeep$1(root)
8724
+ root: cloneDeep$1(root),
8725
+ index: insertIndex
8738
8726
  });
8739
8727
  }
8740
8728
  }
@@ -8752,13 +8740,15 @@
8752
8740
  const parent = this.getNodeById(parentId, false);
8753
8741
  if (parent?.items) {
8754
8742
  const addedNode = cloneDeep$1(oldSchema);
8755
- parent.items.splice(index ?? parent.items.length, 0, addedNode);
8743
+ const insertIndex = clampIndex(index, parent.items.length);
8744
+ parent.items.splice(insertIndex, 0, addedNode);
8756
8745
  addedNodes.push(addedNode);
8757
8746
  await stage?.add({
8758
8747
  config: cloneDeep$1(oldSchema),
8759
8748
  parent: cloneDeep$1(parent),
8760
8749
  parentId,
8761
- root: cloneDeep$1(root)
8750
+ root: cloneDeep$1(root),
8751
+ index: insertIndex
8762
8752
  });
8763
8753
  }
8764
8754
  }
@@ -10833,7 +10823,6 @@
10833
10823
  //#endregion
10834
10824
  //#region packages/editor/src/utils/type-match-rules.ts
10835
10825
  init_use_compare_form();
10836
- init_props();
10837
10826
  /** 复用 form 的可选项建议文案;额外过滤 null / 空串,避免业务侧无效枚举污染提示。 */
10838
10827
  var listSuggestion = (values) => (0, _tmagic_form.optionSuggestion)(values.filter((item) => item !== null && item !== ""));
10839
10828
  /**
@@ -10978,24 +10967,20 @@
10978
10967
  };
10979
10968
  var validateDataSourceFieldPath = (path, options = {}) => {
10980
10969
  if (!getDataSources().length) return;
10981
- let dsId = options.dataSourceId;
10982
- let fieldNames = path;
10983
- if (!dsId) {
10984
- if (!path.length) return defaultMessage(options.message, "值不在可选项中", dataSourceIdSuggestion());
10985
- const rawDsId = path[0];
10986
- dsId = options.valueMode === "key" || !`${rawDsId}`.startsWith(_tmagic_utils.DATA_SOURCE_FIELDS_SELECT_VALUE_PREFIX) ? `${rawDsId}` : (0, _tmagic_utils.removeDataSourceFieldPrefix)(`${rawDsId}`);
10987
- fieldNames = path.slice(1);
10988
- }
10970
+ const dsId = options.dataSourceId;
10971
+ if (!dsId) return defaultMessage(options.message, "数据源不存在", dataSourceIdSuggestion());
10989
10972
  const ds = findDataSource(`${dsId}`);
10990
10973
  if (!ds) return defaultMessage(options.message, `数据源(${dsId})不存在`, dataSourceIdSuggestion());
10991
- if (!fieldNames.length) return;
10992
- const { field, ok, fields, failedName } = resolveFieldByPath(ds.fields, fieldNames);
10974
+ if (!path.length) return;
10975
+ const { field, ok, fields, failedName } = resolveFieldByPath(ds.fields, path);
10993
10976
  if (!ok) return defaultMessage(options.message, `数据源字段(${failedName})不存在`, listSuggestion(fields.map((item) => item.name)));
10994
10977
  const allowedTypes = options.dataSourceFieldType || ["any"];
10995
10978
  if (!allowedTypes.length || allowedTypes.includes("any")) return;
10996
10979
  const leafType = field?.type || "any";
10997
- if (leafType === "any" || allowedTypes.includes(leafType)) return;
10998
- return defaultMessage(options.message, "值不在可选项中", dataSourceIdSuggestion());
10980
+ if (leafType !== "any" && !allowedTypes.includes(leafType)) {
10981
+ const fieldName = field?.name || path[path.length - 1];
10982
+ return defaultMessage(options.message, `请选择类型为${allowedTypes.join("或")}的字段,字段(${fieldName})的类型为${leafType}`);
10983
+ }
10999
10984
  };
11000
10985
  var validateDataSourceMethodTuple = (value, message) => {
11001
10986
  if (!Array.isArray(value) || value.length !== 2 || value.some((item) => typeof item !== "string")) return defaultMessage(message, `${value}类型应为长度为 2 的字符串数组`, methodTupleSuggestion());
@@ -11041,7 +11026,7 @@
11041
11026
  const parentFields = props.config?.parentFields || [];
11042
11027
  const fieldPath = Array.isArray(props.model?.field) ? props.model.field : [];
11043
11028
  const [id, ...fieldNames] = [...parentFields, ...fieldPath];
11044
- const allowed = getCondOpsByFieldType(getFieldType(id ? findDataSource(`${id}`) : void 0, fieldNames));
11029
+ const allowed = getCondOpsByFieldType(getFieldType(id ? findDataSource((0, _tmagic_utils.removeDataSourceFieldPrefix)(`${id}`)) : void 0, fieldNames));
11045
11030
  if (!allowed.has(value)) return defaultMessage(message, `${value} 不在可选项中`, listSuggestion([...allowed]));
11046
11031
  };
11047
11032
  var validateCodeSelectCol = (value, { message }) => {
@@ -11076,7 +11061,7 @@
11076
11061
  /**
11077
11062
  * data-source-field-select 的 typeMatch 校验逻辑,可供自定义 rules.validator 复用。
11078
11063
  */
11079
- var validateDataSourceFieldSelectValue = (value, context, options) => {
11064
+ var validateDataSourceFieldSelect = (value, context, options) => {
11080
11065
  const { mForm, message, props } = context;
11081
11066
  const config = props.config || {};
11082
11067
  if (!isDataSourceFieldPathValue(value, config)) {
@@ -11090,14 +11075,18 @@
11090
11075
  }, message);
11091
11076
  }
11092
11077
  if (!Array.isArray(value) || value.some((item) => typeof item !== "string")) return defaultMessage(message, `${value}类型应为字符串数组`, dataSourceFieldPathSuggestion());
11093
- return validateDataSourceFieldPath(value, {
11094
- dataSourceId: config.dataSourceId,
11095
- valueMode: config.value,
11078
+ let dataSourceId = config.dataSourceId ? `${config.dataSourceId}` : void 0;
11079
+ let fieldNames = value;
11080
+ if (!dataSourceId) {
11081
+ dataSourceId = value.length ? (0, _tmagic_utils.removeDataSourceFieldPrefix)(value[0]) : void 0;
11082
+ fieldNames = value.slice(1);
11083
+ }
11084
+ return validateDataSourceFieldPath(fieldNames, {
11085
+ dataSourceId,
11096
11086
  dataSourceFieldType: config.dataSourceFieldType,
11097
11087
  message
11098
11088
  });
11099
11089
  };
11100
- var validateDataSourceFieldSelect = (value, context) => validateDataSourceFieldSelectValue(value, context);
11101
11090
  var validateDataSourceSelect = (value, { message, props }) => {
11102
11091
  const config = props.config || {};
11103
11092
  const dataSources = getDataSources();
@@ -11167,7 +11156,8 @@
11167
11156
  "ui-select": validateUiSelect,
11168
11157
  "data-source-input": validateDataSourceInput,
11169
11158
  "data-source-method-select": validateDataSourceMethodSelect,
11170
- "data-source-field-select": validateDataSourceFieldSelect,
11159
+ /** 注册进 typeMatch 规则表的入口,收窄为 TypeMatchValidator,避免调用方误传第三个参数 */
11160
+ "data-source-field-select": (value, context) => validateDataSourceFieldSelect(value, context),
11171
11161
  "data-source-select": validateDataSourceSelect,
11172
11162
  "code-select": validateCodeSelect,
11173
11163
  "data-source-fields": validateDataSourceFields,
@@ -11253,7 +11243,7 @@
11253
11243
  var getEventNameOptions = (src, formValue = {}) => {
11254
11244
  if (!formValue.type) return [];
11255
11245
  if (src === "component") {
11256
- const sourceNode = editor_default.getNodeById(formValue.id);
11246
+ const sourceNode = editor_default.getNodeById(formValue.id) || formValue;
11257
11247
  let events = events_default.getEvent(formValue.type, { node: sourceNode }) || [];
11258
11248
  if (formValue.type === "page-fragment-container" && formValue.pageFragmentId) {
11259
11249
  const pageFragment = editor_default.get("root")?.items?.find((page) => page.id === formValue.pageFragmentId);
@@ -15083,7 +15073,6 @@
15083
15073
  //#endregion
15084
15074
  //#region packages/editor/src/layouts/props-panel/PropsPanel.vue?vue&type=script&setup=true&lang.ts
15085
15075
  init_Icon();
15086
- init_props();
15087
15076
  var _hoisted_1$58 = {
15088
15077
  ref: "propsPanel",
15089
15078
  class: "m-editor-props-panel"
@@ -20997,6 +20986,7 @@
20997
20986
  emits: ["change"],
20998
20987
  setup(__props, { emit: __emit }) {
20999
20988
  const mForm = (0, vue.inject)("mForm");
20989
+ const silentMode = (0, vue.inject)(_tmagic_form.FORM_SILENT_MODE_KEY, false);
21000
20990
  const { codeBlockService, uiService } = useServices();
21001
20991
  const eventBus = (0, vue.inject)("eventBus");
21002
20992
  const emit = __emit;
@@ -21093,7 +21083,7 @@
21093
21083
  "last-values",
21094
21084
  "size",
21095
21085
  "prop"
21096
- ])) : ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.unref)(_tmagic_form.MSelect), {
21086
+ ])) : !(0, vue.unref)(silentMode) ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.unref)(_tmagic_form.MSelect), {
21097
21087
  key: 1,
21098
21088
  class: "select",
21099
21089
  config: selectConfig,
@@ -21107,9 +21097,9 @@
21107
21097
  "model",
21108
21098
  "size",
21109
21099
  "prop"
21110
- ])),
21100
+ ])) : (0, vue.createCommentVNode)("v-if", true),
21111
21101
  (0, vue.createCommentVNode)(" 查看/编辑按钮:对比模式为只读,不展示 "),
21112
- !isCompareMode.value && __props.model[__props.name] && hasCodeBlockSidePanel.value ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.unref)(_tmagic_design.TMagicButton), {
21102
+ !isCompareMode.value && !(0, vue.unref)(silentMode) && __props.model[__props.name] && hasCodeBlockSidePanel.value ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.unref)(_tmagic_design.TMagicButton), {
21113
21103
  key: 2,
21114
21104
  class: "m-fields-select-action-button",
21115
21105
  size: __props.size,
@@ -21196,6 +21186,7 @@
21196
21186
  const emit = __emit;
21197
21187
  const { uiService } = useServices();
21198
21188
  const mForm = (0, vue.inject)("mForm");
21189
+ const silentMode = (0, vue.inject)(_tmagic_form.FORM_SILENT_MODE_KEY, false);
21199
21190
  /** 对比模式下隐藏新增/编辑/删除等操作按钮,仅保留只读展示。 */
21200
21191
  const isCompare = (0, vue.computed)(() => Boolean(mForm?.isCompare));
21201
21192
  const fieldValues = (0, vue.ref)({});
@@ -21462,6 +21453,7 @@
21462
21453
  const editingFieldPath = (0, vue.inject)("editingDataSourceFieldPath", (0, vue.computed)(() => []));
21463
21454
  (0, vue.provide)("editingDataSourceFieldPath", (0, vue.computed)(() => editingFieldPath.value.slice(1)));
21464
21455
  (0, vue.onMounted)(() => {
21456
+ if (silentMode) return;
21465
21457
  const path = editingFieldPath.value;
21466
21458
  if (!path.length) return;
21467
21459
  const fields = props.model[props.name] || [];
@@ -21494,7 +21486,8 @@
21494
21486
  default: (0, vue.withCtx)(() => [..._cache[9] || (_cache[9] = [(0, vue.createTextVNode)("添加", -1)])]),
21495
21487
  _: 1
21496
21488
  }, 8, ["disabled"])])) : (0, vue.createCommentVNode)("v-if", true),
21497
- (0, vue.createVNode)(FloatingBox_default, {
21489
+ !(0, vue.unref)(silentMode) ? ((0, vue.openBlock)(), (0, vue.createBlock)(FloatingBox_default, {
21490
+ key: 1,
21498
21491
  "body-style": { padding: "0 16px" },
21499
21492
  visible: addDialogVisible.value,
21500
21493
  "onUpdate:visible": _cache[2] || (_cache[2] = ($event) => addDialogVisible.value = $event),
@@ -21528,8 +21521,9 @@
21528
21521
  "title",
21529
21522
  "framework-width",
21530
21523
  "position"
21531
- ]),
21532
- (0, vue.createVNode)(FloatingBox_default, {
21524
+ ])) : (0, vue.createCommentVNode)("v-if", true),
21525
+ !(0, vue.unref)(silentMode) ? ((0, vue.openBlock)(), (0, vue.createBlock)(FloatingBox_default, {
21526
+ key: 2,
21533
21527
  "body-style": { padding: "0 16px" },
21534
21528
  visible: addFromJsonDialogVisible.value,
21535
21529
  "onUpdate:visible": _cache[5] || (_cache[5] = ($event) => addFromJsonDialogVisible.value = $event),
@@ -21554,7 +21548,7 @@
21554
21548
  "height",
21555
21549
  "framework-width",
21556
21550
  "position"
21557
- ])
21551
+ ])) : (0, vue.createCommentVNode)("v-if", true)
21558
21552
  ]);
21559
21553
  };
21560
21554
  }
@@ -21605,6 +21599,7 @@
21605
21599
  const emit = __emit;
21606
21600
  const { uiService } = useServices();
21607
21601
  const mForm = (0, vue.inject)("mForm");
21602
+ const silentMode = (0, vue.inject)(_tmagic_form.FORM_SILENT_MODE_KEY, false);
21608
21603
  /** 对比模式下隐藏新增/编辑/删除等操作按钮,仅保留只读展示。 */
21609
21604
  const isCompare = (0, vue.computed)(() => Boolean(mForm?.isCompare));
21610
21605
  const width = (0, vue.useModel)(__props, "width");
@@ -21789,7 +21784,8 @@
21789
21784
  default: (0, vue.withCtx)(() => [..._cache[4] || (_cache[4] = [(0, vue.createTextVNode)("添加", -1)])]),
21790
21785
  _: 1
21791
21786
  }, 8, ["disabled"])])) : (0, vue.createCommentVNode)("v-if", true),
21792
- (0, vue.createVNode)(FloatingBox_default, {
21787
+ !(0, vue.unref)(silentMode) ? ((0, vue.openBlock)(), (0, vue.createBlock)(FloatingBox_default, {
21788
+ key: 1,
21793
21789
  "body-style": { padding: "0 16px" },
21794
21790
  visible: addDialogVisible.value,
21795
21791
  "onUpdate:visible": _cache[1] || (_cache[1] = ($event) => addDialogVisible.value = $event),
@@ -21821,7 +21817,7 @@
21821
21817
  "title",
21822
21818
  "framework-width",
21823
21819
  "position"
21824
- ])
21820
+ ])) : (0, vue.createCommentVNode)("v-if", true)
21825
21821
  ]);
21826
21822
  };
21827
21823
  }
@@ -21863,6 +21859,7 @@
21863
21859
  const props = __props;
21864
21860
  const emit = __emit;
21865
21861
  const mForm = (0, vue.inject)("mForm");
21862
+ const silentMode = (0, vue.inject)(_tmagic_form.FORM_SILENT_MODE_KEY, false);
21866
21863
  /** 对比模式下隐藏新增/编辑/删除等操作按钮,仅保留只读展示。 */
21867
21864
  const isCompare = (0, vue.computed)(() => Boolean(mForm?.isCompare));
21868
21865
  const codeConfig = (0, vue.ref)();
@@ -21956,6 +21953,7 @@
21956
21953
  /** 由 DataSourceConfigPanel 注入:打开数据源详情后需要直接打开的方法名 */
21957
21954
  const editingMethodName = (0, vue.inject)("editingDataSourceMethodName", (0, vue.computed)(() => ""));
21958
21955
  (0, vue.onMounted)(() => {
21956
+ if (silentMode) return;
21959
21957
  const methodName = editingMethodName.value;
21960
21958
  if (!methodName) return;
21961
21959
  const methods = props.model[props.name] || [];
@@ -21980,7 +21978,7 @@
21980
21978
  default: (0, vue.withCtx)(() => [..._cache[0] || (_cache[0] = [(0, vue.createTextVNode)("添加", -1)])]),
21981
21979
  _: 1
21982
21980
  }, 8, ["disabled"])])) : (0, vue.createCommentVNode)("v-if", true),
21983
- codeConfig.value ? ((0, vue.openBlock)(), (0, vue.createBlock)(CodeBlockEditor_default, {
21981
+ codeConfig.value && !(0, vue.unref)(silentMode) ? ((0, vue.openBlock)(), (0, vue.createBlock)(CodeBlockEditor_default, {
21984
21982
  key: 1,
21985
21983
  ref: "codeBlockEditor",
21986
21984
  disabled: __props.disabled,
@@ -22390,6 +22388,7 @@
22390
22388
  setup(__props, { emit: __emit }) {
22391
22389
  const { dataSourceService, uiService } = useServices();
22392
22390
  const mForm = (0, vue.inject)("mForm");
22391
+ const silentMode = (0, vue.inject)(_tmagic_form.FORM_SILENT_MODE_KEY, false);
22393
22392
  const eventBus = (0, vue.inject)("eventBus");
22394
22393
  const emit = __emit;
22395
22394
  const props = __props;
@@ -22488,7 +22487,8 @@
22488
22487
  eventBus?.emit("edit-data-source-method", id, methodName);
22489
22488
  };
22490
22489
  return (_ctx, _cache) => {
22491
- return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$36, [(0, vue.createElementVNode)("div", _hoisted_2$6, [(0, vue.createVNode)((0, vue.unref)(_tmagic_form.MCascader), {
22490
+ return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$36, [(0, vue.createElementVNode)("div", _hoisted_2$6, [!(0, vue.unref)(silentMode) ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.unref)(_tmagic_form.MCascader), {
22491
+ key: 0,
22492
22492
  class: "select",
22493
22493
  config: cascaderConfig.value,
22494
22494
  model: __props.model,
@@ -22504,8 +22504,8 @@
22504
22504
  "size",
22505
22505
  "disabled",
22506
22506
  "prop"
22507
- ]), __props.model[__props.name] && isCustomMethod.value && dataSourceSidePanel.value && !isCompare.value ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.unref)(_tmagic_design.TMagicTooltip), {
22508
- key: 0,
22507
+ ])) : (0, vue.createCommentVNode)("v-if", true), !(0, vue.unref)(silentMode) && __props.model[__props.name] && isCustomMethod.value && dataSourceSidePanel.value && !isCompare.value ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.unref)(_tmagic_design.TMagicTooltip), {
22508
+ key: 1,
22509
22509
  content: notEditable.value ? "查看" : "编辑"
22510
22510
  }, {
22511
22511
  default: (0, vue.withCtx)(() => [(0, vue.createVNode)((0, vue.unref)(_tmagic_design.TMagicButton), {
@@ -22785,6 +22785,7 @@
22785
22785
  }, { immediate: true });
22786
22786
  const { dataSourceService, propsService } = useServices();
22787
22787
  const mForm = (0, vue.inject)("mForm");
22788
+ const silentMode = (0, vue.inject)(_tmagic_form.FORM_SILENT_MODE_KEY, false);
22788
22789
  const dataSources = (0, vue.computed)(() => dataSourceService.get("dataSources") || []);
22789
22790
  const disabledDataSource = (0, vue.computed)(() => propsService.getDisabledDataSource());
22790
22791
  const type = (0, vue.computed)(() => {
@@ -22804,7 +22805,9 @@
22804
22805
  let value;
22805
22806
  if (typeof props.config.checkStrictly !== "function") value = props.config.checkStrictly;
22806
22807
  else {
22807
- const dsId = (0, _tmagic_utils.removeDataSourceFieldPrefix)(props.model[0]);
22808
+ const fieldValue = props.model[props.name];
22809
+ const rawDsId = props.config.dataSourceId ?? (Array.isArray(fieldValue) ? fieldValue[0] : fieldValue);
22810
+ const dsId = (0, _tmagic_utils.removeDataSourceFieldPrefix)(`${rawDsId}`);
22808
22811
  const dataSource = dataSources.value.find((ds) => ds.id === dsId);
22809
22812
  value = props.config.checkStrictly(mForm, {
22810
22813
  values: mForm?.initValues || {},
@@ -22848,7 +22851,7 @@
22848
22851
  showDataSourceFieldSelect.value = !showDataSourceFieldSelect.value;
22849
22852
  };
22850
22853
  return (_ctx, _cache) => {
22851
- return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", { class: (0, vue.normalizeClass)(["m-fields-data-source-field-select", { [`data-source-field-${type.value}`]: !isSelectValid.value }]) }, [isSelectValid.value ? ((0, vue.openBlock)(), (0, vue.createBlock)(FieldSelect_default, {
22854
+ return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", { class: (0, vue.normalizeClass)(["m-fields-data-source-field-select", { [`data-source-field-${type.value}`]: !isSelectValid.value }]) }, [isSelectValid.value && !(0, vue.unref)(silentMode) ? ((0, vue.openBlock)(), (0, vue.createBlock)(FieldSelect_default, {
22852
22855
  key: 0,
22853
22856
  "model-value": __props.model[__props.name],
22854
22857
  disabled: __props.disabled,
@@ -22866,7 +22869,7 @@
22866
22869
  "checkStrictly",
22867
22870
  "dataSourceFieldType",
22868
22871
  "dataSourceId"
22869
- ])) : ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.resolveDynamicComponent)(tagName.value), {
22872
+ ])) : !(0, vue.unref)(silentMode) ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.resolveDynamicComponent)(tagName.value), {
22870
22873
  key: 1,
22871
22874
  config: __props.config.fieldConfig,
22872
22875
  model: __props.model,
@@ -22888,7 +22891,7 @@
22888
22891
  "init-values",
22889
22892
  "values",
22890
22893
  "prop"
22891
- ])), __props.config.fieldConfig && !disabledDataSource.value && !(0, vue.unref)(mForm)?.isCompare ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.unref)(_tmagic_design.TMagicTooltip), {
22894
+ ])) : (0, vue.createCommentVNode)("v-if", true), !(0, vue.unref)(silentMode) && __props.config.fieldConfig && !disabledDataSource.value && !(0, vue.unref)(mForm)?.isCompare ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.unref)(_tmagic_design.TMagicTooltip), {
22892
22895
  key: 2,
22893
22896
  disabled: showDataSourceFieldSelect.value,
22894
22897
  content: "选择数据源"
@@ -23097,8 +23100,8 @@
23097
23100
  name: "method",
23098
23101
  label: "动作",
23099
23102
  type: compActionConfig.value.type,
23100
- options: (mForm, { model }) => {
23101
- const node = editorService.getNodeById(model.to);
23103
+ options: (mForm, { model, formValue }) => {
23104
+ const node = editorService.getNodeById(model.to) || formValue;
23102
23105
  if (!node?.type) return [];
23103
23106
  return eventsService.getMethod(node.type, {
23104
23107
  targetId: model.to,
@@ -23346,6 +23349,7 @@
23346
23349
  const props = __props;
23347
23350
  const emit = __emit;
23348
23351
  const mForm = (0, vue.inject)("mForm");
23352
+ const silentMode = (0, vue.inject)(_tmagic_form.FORM_SILENT_MODE_KEY, false);
23349
23353
  /** 对比模式下隐藏增删/代码切换等操作按钮,仅保留只读展示。 */
23350
23354
  const isCompare = (0, vue.computed)(() => Boolean(mForm?.isCompare));
23351
23355
  const records = (0, vue.ref)([]);
@@ -23451,7 +23455,7 @@
23451
23455
  "disabled",
23452
23456
  "icon"
23453
23457
  ])) : (0, vue.createCommentVNode)("v-if", true)])) : (0, vue.createCommentVNode)("v-if", true),
23454
- __props.config.advanced && showCode.value ? ((0, vue.openBlock)(), (0, vue.createBlock)(CodeEditor_default, {
23458
+ __props.config.advanced && showCode.value && !(0, vue.unref)(silentMode) ? ((0, vue.openBlock)(), (0, vue.createBlock)(CodeEditor_default, {
23455
23459
  key: 1,
23456
23460
  "editor-custom-type": "m-fields-key-value",
23457
23461
  language: "javascript",
@@ -23464,7 +23468,7 @@
23464
23468
  parse: true,
23465
23469
  onSave: save
23466
23470
  }, null, 8, ["init-values", "options"])) : (0, vue.createCommentVNode)("v-if", true),
23467
- __props.config.advanced && !isCompare.value ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.unref)(_tmagic_design.TMagicButton), {
23471
+ __props.config.advanced && !isCompare.value && !(0, vue.unref)(silentMode) ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.unref)(_tmagic_design.TMagicButton), {
23468
23472
  key: 2,
23469
23473
  size: "default",
23470
23474
  disabled: __props.disabled,
@@ -23649,9 +23653,16 @@
23649
23653
  const { dataSourceService } = useServices();
23650
23654
  const mForm = (0, vue.inject)("mForm");
23651
23655
  const parentFields = (0, vue.computed)(() => (0, _tmagic_form.filterFunction)(mForm, props.config.parentFields, props) || []);
23656
+ const resolveFieldPath = (path) => {
23657
+ const [id, ...fieldNames] = path;
23658
+ return {
23659
+ ds: id ? dataSourceService.getDataSourceById((0, _tmagic_utils.removeDataSourceFieldPrefix)(`${id}`)) : void 0,
23660
+ fieldNames
23661
+ };
23662
+ };
23652
23663
  const fieldOnChange = (_formState, v, { model }) => {
23653
- const [id, ...fieldNames] = [...parentFields.value, ...v];
23654
- const type = getFieldType(dataSourceService.getDataSourceById(id), fieldNames);
23664
+ const { ds, fieldNames } = resolveFieldPath([...parentFields.value, ...v]);
23665
+ const type = getFieldType(ds, fieldNames);
23655
23666
  if (type === "number") model.value = Number(model.value);
23656
23667
  else if (type === "boolean") model.value = Boolean(model.value);
23657
23668
  else if (type === "null") model.value = null;
@@ -23676,11 +23687,10 @@
23676
23687
  parentFields.value.length ? {
23677
23688
  type: "cascader",
23678
23689
  options: () => {
23679
- const [dsId, ...keys] = parentFields.value;
23680
- const ds = dataSourceService.getDataSourceById(dsId);
23690
+ const { ds, fieldNames } = resolveFieldPath(parentFields.value);
23681
23691
  if (!ds) return [];
23682
23692
  let fields = ds.fields || [];
23683
- keys.forEach((key) => {
23693
+ fieldNames.forEach((key) => {
23684
23694
  fields = fields.find((f) => f.name === key)?.fields || [];
23685
23695
  });
23686
23696
  return getCascaderOptionsFromFields(fields, [
@@ -23748,8 +23758,8 @@
23748
23758
  items: [{
23749
23759
  name: "value",
23750
23760
  type: (_mForm, { model }) => {
23751
- const [id, ...fieldNames] = [...parentFields.value, ...model.field];
23752
- const type = getFieldType(dataSourceService.getDataSourceById(id), fieldNames);
23761
+ const { ds, fieldNames } = resolveFieldPath([...parentFields.value, ...model.field || []]);
23762
+ const type = getFieldType(ds, fieldNames);
23753
23763
  if (type === "number") return "number";
23754
23764
  if (type === "boolean") return "select";
23755
23765
  if (type === "null") return "display";
@@ -23808,7 +23818,6 @@
23808
23818
  var DisplayConds_default = DisplayConds_vue_vue_type_script_setup_true_lang_default;
23809
23819
  //#endregion
23810
23820
  //#region packages/editor/src/fields/CondOpSelect.vue?vue&type=script&setup=true&lang.ts
23811
- init_props();
23812
23821
  var CondOpSelect_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ (0, vue.defineComponent)({
23813
23822
  name: "MFieldsCondOpSelect",
23814
23823
  __name: "CondOpSelect",
@@ -23834,9 +23843,8 @@
23834
23843
  const props = __props;
23835
23844
  const optionComponent = (0, _tmagic_design.getDesignConfig)("components")?.option;
23836
23845
  const options = (0, vue.computed)(() => {
23837
- const [id, ...fieldNames] = [...props.config.parentFields || [], ...props.model.field];
23838
- const type = getFieldType(dataSourceService.getDataSourceById(id), fieldNames);
23839
- return getCondOpOptionsByFieldType(type);
23846
+ const [id, ...fieldNames] = [...props.config.parentFields || [], ...props.model.field || []];
23847
+ return getCondOpOptionsByFieldType(getFieldType(id ? dataSourceService.getDataSourceById((0, _tmagic_utils.removeDataSourceFieldPrefix)(id)) : void 0, fieldNames));
23840
23848
  });
23841
23849
  const fieldChangeHandler = (v) => {
23842
23850
  emit("change", v);
@@ -24311,7 +24319,7 @@
24311
24319
  },
24312
24320
  rules: [{ typeMatch: false }, { validator: ({ value, callback }, { config, model, prop }, mForm) => {
24313
24321
  if (value === "" || value === null || value === void 0) return callback();
24314
- const result = validateDataSourceFieldSelectValue(value, {
24322
+ const result = validateDataSourceFieldSelect(value, {
24315
24323
  fieldType: "data-source-field-select",
24316
24324
  mForm,
24317
24325
  props: {
@@ -26084,6 +26092,14 @@
26084
26092
  app.use(_tmagic_form.default, opt || {});
26085
26093
  app.use(_tmagic_table.default);
26086
26094
  (0, _tmagic_form.registerTypeMatchRules)(editorTypeMatchRules);
26095
+ (0, _tmagic_form.registerSilentLeafFieldTypes)([
26096
+ "vs-code",
26097
+ "ui-select",
26098
+ "cond-op-select",
26099
+ "page-fragment-select",
26100
+ "data-source-select",
26101
+ "data-source-input"
26102
+ ]);
26087
26103
  app.config.globalProperties.$TMAGIC_EDITOR = option;
26088
26104
  setEditorConfig(option);
26089
26105
  app.component(`${Editor_default.name || "MEditor"}`, Editor_default);
@@ -26116,7 +26132,6 @@
26116
26132
  init_CompareForm();
26117
26133
  init_type();
26118
26134
  init_code_block();
26119
- init_props();
26120
26135
  init_use_compare_form();
26121
26136
  init_editor();
26122
26137
  init_monaco_editor();
@@ -26299,7 +26314,6 @@
26299
26314
  exports.numberOptions = numberOptions;
26300
26315
  exports.openIndexedDB = openIndexedDB;
26301
26316
  exports.propsService = props_default;
26302
- exports.removeStyleDisplayConfig = removeStyleDisplayConfig;
26303
26317
  exports.resolveFieldByPath = resolveFieldByPath;
26304
26318
  exports.resolveSelectedNode = resolveSelectedNode;
26305
26319
  exports.serializeConfig = serializeConfig;
@@ -26332,7 +26346,7 @@
26332
26346
  exports.useServices = useServices;
26333
26347
  exports.useStage = useStage;
26334
26348
  exports.useWindowRect = useWindowRect;
26335
- exports.validateDataSourceFieldSelectValue = validateDataSourceFieldSelectValue;
26349
+ exports.validateDataSourceFieldSelect = validateDataSourceFieldSelect;
26336
26350
  exports.warn = warn;
26337
26351
  Object.keys(_tmagic_form).forEach(function(k) {
26338
26352
  if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {