@tmagic/editor 1.8.0-beta.2 → 1.8.0-beta.3

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 (45) hide show
  1. package/dist/es/Editor.vue_vue_type_script_setup_true_lang.js +9 -0
  2. package/dist/es/components/CompareForm.vue_vue_type_script_setup_true_lang.js +32 -28
  3. package/dist/es/editorProps.js +2 -0
  4. package/dist/es/fields/CodeLink.vue_vue_type_script_setup_true_lang.js +2 -5
  5. package/dist/es/hooks/use-stage.js +2 -1
  6. package/dist/es/index.js +3 -1
  7. package/dist/es/layouts/CodeEditor.vue_vue_type_script_setup_true_lang.js +2 -5
  8. package/dist/es/layouts/history-list/Bucket.vue_vue_type_script_setup_true_lang.js +33 -14
  9. package/dist/es/layouts/history-list/BucketTab.js +5 -0
  10. package/dist/es/layouts/history-list/{CodeBlockTab.vue_vue_type_script_setup_true_lang.js → BucketTab.vue_vue_type_script_setup_true_lang.js} +27 -16
  11. package/dist/es/layouts/history-list/GroupRow.vue_vue_type_script_setup_true_lang.js +71 -53
  12. package/dist/es/layouts/history-list/HistoryDiffDialog.vue_vue_type_script_setup_true_lang.js +78 -28
  13. package/dist/es/layouts/history-list/HistoryListPanel.vue_vue_type_script_setup_true_lang.js +136 -66
  14. package/dist/es/layouts/history-list/InitialRow.vue_vue_type_script_setup_true_lang.js +15 -9
  15. package/dist/es/layouts/history-list/PageTab.vue_vue_type_script_setup_true_lang.js +12 -6
  16. package/dist/es/layouts/history-list/composables.js +20 -2
  17. package/dist/es/services/history.js +5 -2
  18. package/dist/es/style.css +44 -12
  19. package/dist/style.css +44 -12
  20. package/dist/tmagic-editor.umd.cjs +479 -326
  21. package/package.json +7 -7
  22. package/src/Editor.vue +8 -0
  23. package/src/components/CompareForm.vue +32 -19
  24. package/src/editorProps.ts +7 -0
  25. package/src/fields/CodeLink.vue +2 -5
  26. package/src/hooks/use-stage.ts +1 -0
  27. package/src/index.ts +2 -0
  28. package/src/layouts/CodeEditor.vue +2 -5
  29. package/src/layouts/history-list/Bucket.vue +53 -28
  30. package/src/layouts/history-list/BucketTab.vue +77 -0
  31. package/src/layouts/history-list/GroupRow.vue +95 -60
  32. package/src/layouts/history-list/HistoryDiffDialog.vue +51 -32
  33. package/src/layouts/history-list/HistoryListPanel.vue +161 -52
  34. package/src/layouts/history-list/InitialRow.vue +17 -6
  35. package/src/layouts/history-list/PageTab.vue +20 -6
  36. package/src/layouts/history-list/composables.ts +32 -1
  37. package/src/services/history.ts +3 -0
  38. package/src/theme/history-list-panel.scss +52 -13
  39. package/src/type.ts +90 -0
  40. package/types/index.d.ts +295 -135
  41. package/dist/es/layouts/history-list/CodeBlockTab.js +0 -5
  42. package/dist/es/layouts/history-list/DataSourceTab.js +0 -5
  43. package/dist/es/layouts/history-list/DataSourceTab.vue_vue_type_script_setup_true_lang.js +0 -62
  44. package/src/layouts/history-list/CodeBlockTab.vue +0 -61
  45. package/src/layouts/history-list/DataSourceTab.vue +0 -61
@@ -5191,6 +5191,7 @@
5191
5191
  push(state, pageId) {
5192
5192
  const undoRedo = this.getUndoRedo(pageId);
5193
5193
  if (!undoRedo) return null;
5194
+ if (state.timestamp === void 0) state.timestamp = Date.now();
5194
5195
  undoRedo.pushElement(state);
5195
5196
  if (pageId === void 0 || `${pageId}` === `${this.state.pageId}`) this.emit("change", state);
5196
5197
  return state;
@@ -5211,7 +5212,8 @@
5211
5212
  oldContent: payload.oldContent ? cloneDeep$1(payload.oldContent) : null,
5212
5213
  newContent: payload.newContent ? cloneDeep$1(payload.newContent) : null,
5213
5214
  changeRecords: payload.changeRecords?.length ? cloneDeep$1(payload.changeRecords) : void 0,
5214
- historyDescription: payload.historyDescription
5215
+ historyDescription: payload.historyDescription,
5216
+ timestamp: Date.now()
5215
5217
  };
5216
5218
  this.getCodeBlockUndoRedo(codeBlockId).pushElement(step);
5217
5219
  this.emit("code-block-history-change", codeBlockId, step);
@@ -5228,7 +5230,8 @@
5228
5230
  oldSchema: payload.oldSchema ? cloneDeep$1(payload.oldSchema) : null,
5229
5231
  newSchema: payload.newSchema ? cloneDeep$1(payload.newSchema) : null,
5230
5232
  changeRecords: payload.changeRecords?.length ? cloneDeep$1(payload.changeRecords) : void 0,
5231
- historyDescription: payload.historyDescription
5233
+ historyDescription: payload.historyDescription,
5234
+ timestamp: Date.now()
5232
5235
  };
5233
5236
  this.getDataSourceUndoRedo(dataSourceId).pushElement(step);
5234
5237
  this.emit("data-source-history-change", dataSourceId, step);
@@ -7258,7 +7261,8 @@
7258
7261
  guidesOptions: stageOptions.guidesOptions,
7259
7262
  disabledMultiSelect: stageOptions.disabledMultiSelect,
7260
7263
  alwaysMultiSelect: stageOptions.alwaysMultiSelect,
7261
- disabledRule: stageOptions.disabledRule
7264
+ disabledRule: stageOptions.disabledRule,
7265
+ disabledFlashTip: stageOptions.disabledFlashTip
7262
7266
  });
7263
7267
  (0, vue.watch)(() => editor_default.get("disabledMultiSelect"), (disabledMultiSelect) => {
7264
7268
  if (disabledMultiSelect) stage.disableMultiSelect();
@@ -8355,7 +8359,7 @@
8355
8359
  var SplitView_default = SplitView_vue_vue_type_script_setup_true_lang_default;
8356
8360
  //#endregion
8357
8361
  //#region packages/editor/src/components/Icon.vue?vue&type=script&setup=true&lang.ts
8358
- var _hoisted_1$72 = ["src"];
8362
+ var _hoisted_1$71 = ["src"];
8359
8363
  var Icon_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ (0, vue.defineComponent)({
8360
8364
  name: "MEditorIcon",
8361
8365
  __name: "Icon",
@@ -8373,7 +8377,7 @@
8373
8377
  key: 1,
8374
8378
  class: "magic-editor-icon"
8375
8379
  }, {
8376
- default: (0, vue.withCtx)(() => [(0, vue.createElementVNode)("img", { src: __props.icon }, null, 8, _hoisted_1$72)]),
8380
+ default: (0, vue.withCtx)(() => [(0, vue.createElementVNode)("img", { src: __props.icon }, null, 8, _hoisted_1$71)]),
8377
8381
  _: 1
8378
8382
  })) : typeof __props.icon === "string" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("i", {
8379
8383
  key: 2,
@@ -8393,11 +8397,11 @@
8393
8397
  var Icon_default = Icon_vue_vue_type_script_setup_true_lang_default;
8394
8398
  //#endregion
8395
8399
  //#region packages/editor/src/components/ToolButton.vue?vue&type=script&setup=true&lang.ts
8396
- var _hoisted_1$71 = {
8400
+ var _hoisted_1$70 = {
8397
8401
  key: 1,
8398
8402
  class: "menu-item-text"
8399
8403
  };
8400
- var _hoisted_2$29 = { class: "el-dropdown-link menubar-menu-button" };
8404
+ var _hoisted_2$28 = { class: "el-dropdown-link menubar-menu-button" };
8401
8405
  var ToolButton_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ (0, vue.defineComponent)({
8402
8406
  name: "MEditorToolButton",
8403
8407
  __name: "ToolButton",
@@ -8456,7 +8460,7 @@
8456
8460
  }, [__props.data.type === "divider" ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.unref)(_tmagic_design.TMagicDivider), {
8457
8461
  key: 0,
8458
8462
  direction: __props.data.direction || "vertical"
8459
- }, null, 8, ["direction"])) : __props.data.type === "text" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$71, (0, vue.toDisplayString)(__props.data.text), 1)) : __props.data.type === "button" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 2 }, [__props.data.tooltip ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.unref)(_tmagic_design.TMagicTooltip), {
8463
+ }, null, 8, ["direction"])) : __props.data.type === "text" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$70, (0, vue.toDisplayString)(__props.data.text), 1)) : __props.data.type === "button" ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 2 }, [__props.data.tooltip ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.unref)(_tmagic_design.TMagicTooltip), {
8460
8464
  key: 0,
8461
8465
  effect: "dark",
8462
8466
  placement: "bottom-start",
@@ -8511,7 +8515,7 @@
8511
8515
  }), 128))]),
8512
8516
  _: 1
8513
8517
  })) : (0, vue.createCommentVNode)("v-if", true)]),
8514
- default: (0, vue.withCtx)(() => [(0, vue.createElementVNode)("span", _hoisted_2$29, [(0, vue.createTextVNode)((0, vue.toDisplayString)(__props.data.text), 1), (0, vue.createVNode)((0, vue.unref)(_tmagic_design.TMagicIcon), { class: "el-icon--right" }, {
8518
+ default: (0, vue.withCtx)(() => [(0, vue.createElementVNode)("span", _hoisted_2$28, [(0, vue.createTextVNode)((0, vue.toDisplayString)(__props.data.text), 1), (0, vue.createVNode)((0, vue.unref)(_tmagic_design.TMagicIcon), { class: "el-icon--right" }, {
8515
8519
  default: (0, vue.withCtx)(() => [(0, vue.createVNode)((0, vue.unref)(_element_plus_icons_vue.ArrowDown))]),
8516
8520
  _: 1
8517
8521
  })])]),
@@ -8525,12 +8529,12 @@
8525
8529
  var ToolButton_default = ToolButton_vue_vue_type_script_setup_true_lang_default;
8526
8530
  //#endregion
8527
8531
  //#region packages/editor/src/layouts/page-bar/AddButton.vue?vue&type=script&setup=true&lang.ts
8528
- var _hoisted_1$70 = {
8532
+ var _hoisted_1$69 = {
8529
8533
  key: 0,
8530
8534
  id: "m-editor-page-bar-add-icon",
8531
8535
  class: "m-editor-page-bar-item m-editor-page-bar-item-icon"
8532
8536
  };
8533
- var _hoisted_2$28 = {
8537
+ var _hoisted_2$27 = {
8534
8538
  key: 1,
8535
8539
  style: { "width": "21px" }
8536
8540
  };
@@ -8551,7 +8555,7 @@
8551
8555
  editorService.add(pageConfig);
8552
8556
  };
8553
8557
  return (_ctx, _cache) => {
8554
- return showAddPageButton.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$70, [(0, vue.createVNode)((0, vue.unref)(_tmagic_design.TMagicPopover), { "popper-class": "data-source-list-panel-add-menu" }, {
8558
+ return showAddPageButton.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$69, [(0, vue.createVNode)((0, vue.unref)(_tmagic_design.TMagicPopover), { "popper-class": "data-source-list-panel-add-menu" }, {
8555
8559
  reference: (0, vue.withCtx)(() => [(0, vue.createVNode)(Icon_default, { icon: (0, vue.unref)(_element_plus_icons_vue.Plus) }, null, 8, ["icon"])]),
8556
8560
  default: (0, vue.withCtx)(() => [(0, vue.createVNode)(ToolButton_default, { data: {
8557
8561
  type: "button",
@@ -8567,7 +8571,7 @@
8567
8571
  }
8568
8572
  } }, null, 8, ["data"])]),
8569
8573
  _: 1
8570
- })])) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_2$28));
8574
+ })])) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_2$27));
8571
8575
  };
8572
8576
  }
8573
8577
  });
@@ -8576,11 +8580,11 @@
8576
8580
  var AddButton_default = AddButton_vue_vue_type_script_setup_true_lang_default;
8577
8581
  //#endregion
8578
8582
  //#region packages/editor/src/layouts/page-bar/PageBarScrollContainer.vue?vue&type=script&setup=true&lang.ts
8579
- var _hoisted_1$69 = {
8583
+ var _hoisted_1$68 = {
8580
8584
  class: "m-editor-page-bar",
8581
8585
  ref: "pageBar"
8582
8586
  };
8583
- var _hoisted_2$27 = {
8587
+ var _hoisted_2$26 = {
8584
8588
  key: 0,
8585
8589
  class: "m-editor-page-bar-items",
8586
8590
  ref: "itemsContainer"
@@ -8670,9 +8674,9 @@
8670
8674
  }
8671
8675
  });
8672
8676
  return (_ctx, _cache) => {
8673
- return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$69, [
8677
+ return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$68, [
8674
8678
  (0, vue.renderSlot)(_ctx.$slots, "prepend"),
8675
- __props.length ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_2$27, [(0, vue.renderSlot)(_ctx.$slots, "default")], 512)) : (0, vue.createCommentVNode)("v-if", true),
8679
+ __props.length ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_2$26, [(0, vue.renderSlot)(_ctx.$slots, "default")], 512)) : (0, vue.createCommentVNode)("v-if", true),
8676
8680
  canScroll.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
8677
8681
  key: 1,
8678
8682
  class: "m-editor-page-bar-item m-editor-page-bar-item-icon m-editor-page-bar-item-left-icon",
@@ -8692,12 +8696,12 @@
8692
8696
  var PageBarScrollContainer_default = PageBarScrollContainer_vue_vue_type_script_setup_true_lang_default;
8693
8697
  //#endregion
8694
8698
  //#region packages/editor/src/layouts/page-bar/PageList.vue?vue&type=script&setup=true&lang.ts
8695
- var _hoisted_1$68 = {
8699
+ var _hoisted_1$67 = {
8696
8700
  key: 0,
8697
8701
  id: "m-editor-page-bar-list-icon",
8698
8702
  class: "m-editor-page-bar-item m-editor-page-bar-item-icon"
8699
8703
  };
8700
- var _hoisted_2$26 = { class: "page-bar-popover-wrapper" };
8704
+ var _hoisted_2$25 = { class: "page-bar-popover-wrapper" };
8701
8705
  var _hoisted_3$10 = { class: "page-bar-popover-inner" };
8702
8706
  var PageList_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ (0, vue.defineComponent)({
8703
8707
  name: "MEditorPageList",
@@ -8711,7 +8715,7 @@
8711
8715
  await editorService.select(id);
8712
8716
  };
8713
8717
  return (_ctx, _cache) => {
8714
- return showPageListButton.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$68, [(0, vue.createVNode)((0, vue.unref)(_tmagic_design.TMagicPopover), {
8718
+ return showPageListButton.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$67, [(0, vue.createVNode)((0, vue.unref)(_tmagic_design.TMagicPopover), {
8715
8719
  "popper-class": "page-bar-popover",
8716
8720
  placement: "top",
8717
8721
  trigger: "hover",
@@ -8722,7 +8726,7 @@
8722
8726
  default: (0, vue.withCtx)(() => [(0, vue.createVNode)((0, vue.unref)(_element_plus_icons_vue.Files))]),
8723
8727
  _: 1
8724
8728
  })]),
8725
- default: (0, vue.withCtx)(() => [(0, vue.createElementVNode)("div", _hoisted_2$26, [(0, vue.createElementVNode)("div", _hoisted_3$10, [(0, vue.renderSlot)(_ctx.$slots, "page-list-popover", { list: __props.list }, () => [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(__props.list, (item, index) => {
8729
+ default: (0, vue.withCtx)(() => [(0, vue.createElementVNode)("div", _hoisted_2$25, [(0, vue.createElementVNode)("div", _hoisted_3$10, [(0, vue.renderSlot)(_ctx.$slots, "page-list-popover", { list: __props.list }, () => [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(__props.list, (item, index) => {
8726
8730
  return (0, vue.openBlock)(), (0, vue.createBlock)(ToolButton_default, {
8727
8731
  data: {
8728
8732
  type: "button",
@@ -8743,7 +8747,7 @@
8743
8747
  var PageList_default = PageList_vue_vue_type_script_setup_true_lang_default;
8744
8748
  //#endregion
8745
8749
  //#region packages/editor/src/layouts/page-bar/Search.vue?vue&type=script&setup=true&lang.ts
8746
- var _hoisted_1$67 = { class: "m-editor-page-bar-item m-editor-page-bar-item-icon m-editor-page-bar-search" };
8750
+ var _hoisted_1$66 = { class: "m-editor-page-bar-item m-editor-page-bar-item-icon m-editor-page-bar-search" };
8747
8751
  var Search_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ (0, vue.defineComponent)({
8748
8752
  __name: "Search",
8749
8753
  props: {
@@ -8776,7 +8780,7 @@
8776
8780
  emit("search", values);
8777
8781
  };
8778
8782
  return (_ctx, _cache) => {
8779
- return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$67, [(0, vue.createVNode)(Icon_default, {
8783
+ return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$66, [(0, vue.createVNode)(Icon_default, {
8780
8784
  icon: (0, vue.unref)(_element_plus_icons_vue.Search),
8781
8785
  onClick: _cache[0] || (_cache[0] = ($event) => visible.value = !visible.value),
8782
8786
  class: (0, vue.normalizeClass)({ "icon-active": visible.value })
@@ -8800,8 +8804,8 @@
8800
8804
  var Search_default = Search_vue_vue_type_script_setup_true_lang_default;
8801
8805
  //#endregion
8802
8806
  //#region packages/editor/src/layouts/page-bar/PageBar.vue?vue&type=script&setup=true&lang.ts
8803
- var _hoisted_1$66 = { class: "m-editor-page-bar-tabs" };
8804
- var _hoisted_2$25 = ["data-page-id", "onClick"];
8807
+ var _hoisted_1$65 = { class: "m-editor-page-bar-tabs" };
8808
+ var _hoisted_2$24 = ["data-page-id", "onClick"];
8805
8809
  var _hoisted_3$9 = { class: "m-editor-page-bar-title" };
8806
8810
  var _hoisted_4$8 = ["title"];
8807
8811
  var PageBar_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ (0, vue.defineComponent)({
@@ -8868,7 +8872,7 @@
8868
8872
  }
8869
8873
  });
8870
8874
  return (_ctx, _cache) => {
8871
- return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$66, [(0, vue.createVNode)(PageBarScrollContainer_default, {
8875
+ return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$65, [(0, vue.createVNode)(PageBarScrollContainer_default, {
8872
8876
  ref: "pageBarScrollContainer",
8873
8877
  "page-bar-sort-options": __props.pageBarSortOptions,
8874
8878
  length: list.value.length
@@ -8915,7 +8919,7 @@
8915
8919
  handler: () => remove(item)
8916
8920
  } }, null, 8, ["data"])])])]),
8917
8921
  _: 2
8918
- }, 1024)], 10, _hoisted_2$25);
8922
+ }, 1024)], 10, _hoisted_2$24);
8919
8923
  }), 128))]),
8920
8924
  _: 3
8921
8925
  }, 8, ["page-bar-sort-options", "length"])]);
@@ -8927,8 +8931,8 @@
8927
8931
  var PageBar_default = PageBar_vue_vue_type_script_setup_true_lang_default;
8928
8932
  //#endregion
8929
8933
  //#region packages/editor/src/layouts/AddPageBox.vue?vue&type=script&setup=true&lang.ts
8930
- var _hoisted_1$65 = { class: "m-editor-empty-panel" };
8931
- var _hoisted_2$24 = { class: "m-editor-empty-content" };
8934
+ var _hoisted_1$64 = { class: "m-editor-empty-panel" };
8935
+ var _hoisted_2$23 = { class: "m-editor-empty-content" };
8932
8936
  var AddPageBox_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ (0, vue.defineComponent)({
8933
8937
  name: "MEditorAddPageBox",
8934
8938
  __name: "AddPageBox",
@@ -8945,7 +8949,7 @@
8945
8949
  });
8946
8950
  };
8947
8951
  return (_ctx, _cache) => {
8948
- return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$65, [(0, vue.createElementVNode)("div", _hoisted_2$24, [(0, vue.createElementVNode)("div", {
8952
+ return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$64, [(0, vue.createElementVNode)("div", _hoisted_2$23, [(0, vue.createElementVNode)("div", {
8949
8953
  class: "m-editor-empty-button",
8950
8954
  onClick: _cache[0] || (_cache[0] = ($event) => clickHandler((0, vue.unref)(_tmagic_core.NodeType).PAGE))
8951
8955
  }, [(0, vue.createElementVNode)("div", null, [(0, vue.createVNode)(Icon_default, { icon: (0, vue.unref)(_element_plus_icons_vue.Plus) }, null, 8, ["icon"])]), _cache[2] || (_cache[2] = (0, vue.createElementVNode)("p", null, "新增页面", -1))]), !__props.disabledPageFragment ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
@@ -8961,8 +8965,8 @@
8961
8965
  var AddPageBox_default = AddPageBox_vue_vue_type_script_setup_true_lang_default;
8962
8966
  //#endregion
8963
8967
  //#region packages/editor/src/layouts/CodeEditor.vue?vue&type=script&setup=true&lang.ts
8964
- var _hoisted_1$64 = { class: "magic-code-editor" };
8965
- var _hoisted_2$23 = {
8968
+ var _hoisted_1$63 = { class: "magic-code-editor" };
8969
+ var _hoisted_2$22 = {
8966
8970
  ref: "codeEditor",
8967
8971
  class: "magic-code-editor-content"
8968
8972
  };
@@ -9048,10 +9052,7 @@
9048
9052
  const toString = (v, language) => {
9049
9053
  let value;
9050
9054
  if (typeof v !== "string") if (language === "json") value = JSON.stringify(v, null, 2);
9051
- else value = (0, serialize_javascript.default)(v, {
9052
- space: 2,
9053
- unsafe: true
9054
- }).replace(/"(\w+)":\s/g, "$1: ");
9055
+ else value = serializeConfig(v);
9055
9056
  else value = v;
9056
9057
  if (language === "javascript" && value.startsWith("{") && value.endsWith("}")) value = `(${value})`;
9057
9058
  return value;
@@ -9202,7 +9203,7 @@
9202
9203
  }
9203
9204
  });
9204
9205
  return (_ctx, _cache) => {
9205
- return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$64, [((0, vue.openBlock)(), (0, vue.createBlock)(vue.Teleport, {
9206
+ return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$63, [((0, vue.openBlock)(), (0, vue.createBlock)(vue.Teleport, {
9206
9207
  to: "body",
9207
9208
  disabled: !fullScreen.value
9208
9209
  }, [(0, vue.createElementVNode)("div", {
@@ -9220,7 +9221,7 @@
9220
9221
  }, {
9221
9222
  default: (0, vue.withCtx)(() => [(0, vue.createVNode)(Icon_default, { icon: (0, vue.unref)(_element_plus_icons_vue.FullScreen) }, null, 8, ["icon"])]),
9222
9223
  _: 1
9223
- })) : (0, vue.createCommentVNode)("v-if", true), (0, vue.createElementVNode)("div", _hoisted_2$23, null, 512)], 6)], 8, ["disabled"]))]);
9224
+ })) : (0, vue.createCommentVNode)("v-if", true), (0, vue.createElementVNode)("div", _hoisted_2$22, null, 512)], 6)], 8, ["disabled"]))]);
9224
9225
  };
9225
9226
  }
9226
9227
  });
@@ -9229,7 +9230,7 @@
9229
9230
  var CodeEditor_default = CodeEditor_vue_vue_type_script_setup_true_lang_default;
9230
9231
  //#endregion
9231
9232
  //#region packages/editor/src/layouts/Framework.vue?vue&type=script&setup=true&lang.ts
9232
- var _hoisted_1$63 = {
9233
+ var _hoisted_1$62 = {
9233
9234
  class: "m-editor",
9234
9235
  ref: "content",
9235
9236
  style: { "min-width": "900px" }
@@ -9293,7 +9294,7 @@
9293
9294
  }
9294
9295
  };
9295
9296
  return (_ctx, _cache) => {
9296
- return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$63, [
9297
+ return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$62, [
9297
9298
  (0, vue.renderSlot)(_ctx.$slots, "header"),
9298
9299
  (0, vue.renderSlot)(_ctx.$slots, "nav"),
9299
9300
  (0, vue.renderSlot)(_ctx.$slots, "content-before"),
@@ -9371,7 +9372,10 @@
9371
9372
  */
9372
9373
  var useHistoryList = () => {
9373
9374
  const { historyService } = useServices();
9374
- /** 折叠状态:key 形如 `pg-${groupIdx}` / `ds-${id}-${groupIdx}` / `cb-${id}-${groupIdx}`。 */
9375
+ /**
9376
+ * 折叠状态:key 形如 `pg-${组内首步 index}` / `ds-${id}-${组内首步 index}` / `cb-${id}-${组内首步 index}`。
9377
+ * 用组内首步的稳定 index(而非展示位置)作为 key,确保历史数据更新后已展开的分组状态保持不变。
9378
+ */
9375
9379
  const expanded = (0, vue.reactive)({});
9376
9380
  const toggleGroup = (key) => {
9377
9381
  expanded[key] = !expanded[key];
@@ -9408,6 +9412,20 @@
9408
9412
  codeBlockGroupsByTarget: (0, vue.computed)(() => groupByTarget(codeBlockGroups.value))
9409
9413
  };
9410
9414
  };
9415
+ /**
9416
+ * 历史面板的时间展示:
9417
+ * - 当天的记录只显示 `HH:mm:ss`;
9418
+ * - 跨天的记录显示 `MM-DD HH:mm:ss`。
9419
+ * 无时间戳(旧数据 / 未写入)时返回空串,UI 据此不渲染时间。
9420
+ */
9421
+ var formatHistoryTime = (timestamp) => {
9422
+ if (!timestamp) return "";
9423
+ return `${(0, _tmagic_form.datetimeFormatter)(new Date(timestamp), "", "YYYY-MM-DD") === (0, _tmagic_form.datetimeFormatter)(/* @__PURE__ */ new Date(), "", "YYYY-MM-DD") ? (0, _tmagic_form.datetimeFormatter)(new Date(timestamp), "", "HH:mm:ss") : (0, _tmagic_form.datetimeFormatter)(new Date(timestamp), "", "MM-DD HH:mm:ss")}`;
9424
+ };
9425
+ /** 完整时间(含年份与秒),用于 title 悬浮提示。无时间戳时返回空串。 */
9426
+ var formatHistoryFullTime = (timestamp) => timestamp ? `${(0, _tmagic_form.datetimeFormatter)(new Date(timestamp), "", "YYYY-MM-DD HH:mm:ss")}` : "";
9427
+ /** 取一组历史步骤里最后一步(最近一次)的时间戳,用于组头部展示。 */
9428
+ var groupTimestamp = (group) => group.steps[group.steps.length - 1]?.step.timestamp;
9411
9429
  var opLabel = (op) => {
9412
9430
  switch (op) {
9413
9431
  case "add": return "新增";
@@ -9512,30 +9530,25 @@
9512
9530
  };
9513
9531
  //#endregion
9514
9532
  //#region packages/editor/src/layouts/history-list/GroupRow.vue?vue&type=script&setup=true&lang.ts
9515
- var _hoisted_1$62 = ["title"];
9516
- var _hoisted_2$22 = ["title"];
9533
+ var _hoisted_1$61 = ["title"];
9534
+ var _hoisted_2$21 = ["title"];
9517
9535
  var _hoisted_3$8 = { class: "m-editor-history-list-item-desc" };
9518
- var _hoisted_4$7 = {
9519
- key: 0,
9520
- class: "m-editor-history-list-item-current"
9521
- };
9536
+ var _hoisted_4$7 = ["title"];
9522
9537
  var _hoisted_5$3 = {
9523
- key: 2,
9538
+ key: 1,
9524
9539
  class: "m-editor-history-list-item-merge"
9525
9540
  };
9526
9541
  var _hoisted_6$3 = {
9527
9542
  key: 0,
9528
9543
  class: "m-editor-history-list-substeps"
9529
9544
  };
9530
- var _hoisted_7 = ["title", "onClick"];
9545
+ var _hoisted_7$1 = ["title"];
9531
9546
  var _hoisted_8 = { class: "m-editor-history-list-item-index" };
9532
9547
  var _hoisted_9 = { class: "m-editor-history-list-substep-desc" };
9533
- var _hoisted_10 = {
9534
- key: 0,
9535
- class: "m-editor-history-list-item-current"
9536
- };
9548
+ var _hoisted_10 = ["title"];
9537
9549
  var _hoisted_11 = ["onClick"];
9538
9550
  var _hoisted_12 = ["onClick"];
9551
+ var _hoisted_13 = ["onClick"];
9539
9552
  var GroupRow_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ (0, vue.defineComponent)({
9540
9553
  name: "MEditorHistoryListGroupRow",
9541
9554
  __name: "GroupRow",
@@ -9545,10 +9558,19 @@
9545
9558
  merged: { type: Boolean },
9546
9559
  opType: {},
9547
9560
  desc: {},
9561
+ time: {},
9562
+ timeTitle: {},
9548
9563
  stepCount: {},
9549
9564
  subSteps: {},
9550
9565
  expanded: { type: Boolean },
9551
- isCurrent: { type: Boolean }
9566
+ isCurrent: {
9567
+ type: Boolean,
9568
+ default: false
9569
+ },
9570
+ gotoEnabled: {
9571
+ type: Boolean,
9572
+ default: true
9573
+ }
9552
9574
  },
9553
9575
  emits: [
9554
9576
  "toggle",
@@ -9559,33 +9581,29 @@
9559
9581
  setup(__props, { emit: __emit }) {
9560
9582
  const props = __props;
9561
9583
  const emit = __emit;
9562
- /** 单步组:头部可点击 goto;合并组:头部可点击切换展开。当前组(isCurrent)的单步组头部不可点击。 */
9563
- const isHeadClickable = (0, vue.computed)(() => {
9564
- if (props.merged) return true;
9565
- return !props.isCurrent;
9566
- });
9584
+ /**
9585
+ * 仅合并组头部可点击(切换展开 / 收起);
9586
+ * 单步组的跳转改由头部的「回退」按钮触发,整行不再可点击。
9587
+ */
9588
+ const isHeadClickable = (0, vue.computed)(() => props.merged);
9567
9589
  const headTitle = (0, vue.computed)(() => {
9568
9590
  if (props.merged) return props.expanded ? "点击收起子步" : "点击展开子步";
9569
9591
  if (props.isCurrent) return "当前所在记录";
9570
- return "点击跳转到该记录";
9592
+ return "";
9571
9593
  });
9572
9594
  /**
9573
- * 头部点击行为分流:
9574
- * - 合并组:仅切换展开 / 收起,不触发 goto;
9575
- * - 单步组:跳转到该唯一步骤;当前组忽略点击。
9595
+ * 头部点击行为:仅合并组切换展开 / 收起;单步组不再响应整行点击。
9576
9596
  */
9577
9597
  const onHeadClick = () => {
9578
- if (props.merged) {
9579
- emit("toggle", props.groupKey);
9580
- return;
9581
- }
9582
- if (props.isCurrent) return;
9583
- if (!props.subSteps.length) return;
9584
- emit("goto", props.subSteps[0].index);
9598
+ if (props.merged) emit("toggle", props.groupKey);
9599
+ };
9600
+ const onGotoClick = (index) => {
9601
+ if (!props.gotoEnabled) return;
9602
+ emit("goto", index);
9585
9603
  };
9586
- const onSubStepClick = (s) => {
9587
- if (s.isCurrent) return;
9588
- emit("goto", s.index);
9604
+ const subStepTitle = (s) => {
9605
+ if (s.isCurrent) return "当前所在记录";
9606
+ return "";
9589
9607
  };
9590
9608
  /** 单步组头部是否展示"查看差异"入口:要求该唯一子步本身可对比。 */
9591
9609
  const headDiffable = (0, vue.computed)(() => !props.merged && Boolean(props.subSteps[0]?.diffable));
@@ -9635,54 +9653,72 @@
9635
9653
  (0, vue.createElementVNode)("span", {
9636
9654
  class: "m-editor-history-list-item-index",
9637
9655
  title: headIndexTitle.value
9638
- }, (0, vue.toDisplayString)(headIndexLabel.value), 9, _hoisted_2$22),
9656
+ }, (0, vue.toDisplayString)(headIndexLabel.value), 9, _hoisted_2$21),
9639
9657
  (0, vue.createElementVNode)("span", { class: (0, vue.normalizeClass)(["m-editor-history-list-item-op", `op-${__props.opType}`]) }, (0, vue.toDisplayString)((0, vue.unref)(opLabel)(__props.opType)), 3),
9640
9658
  (0, vue.createElementVNode)("span", _hoisted_3$8, (0, vue.toDisplayString)(__props.desc), 1),
9641
- __props.isCurrent ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_4$7, "当前")) : (0, vue.createCommentVNode)("v-if", true),
9642
- !__props.merged && headDiffable.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
9643
- key: 1,
9644
- class: "m-editor-history-list-item-diff",
9645
- title: "查看修改差异",
9646
- onClick: _cache[0] || (_cache[0] = (0, vue.withModifiers)(($event) => onDiffClick(__props.subSteps[0].index), ["stop"]))
9647
- }, "查看差异")) : (0, vue.createCommentVNode)("v-if", true),
9659
+ __props.time ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
9660
+ key: 0,
9661
+ class: "m-editor-history-list-item-time",
9662
+ title: __props.timeTitle || __props.time
9663
+ }, (0, vue.toDisplayString)(__props.time), 9, _hoisted_4$7)) : (0, vue.createCommentVNode)("v-if", true),
9648
9664
  __props.merged ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_5$3, "合并 " + (0, vue.toDisplayString)(__props.stepCount) + " 步", 1)) : (0, vue.createCommentVNode)("v-if", true),
9649
9665
  !__props.merged && headRevertable.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
9650
- key: 3,
9666
+ key: 2,
9651
9667
  class: "m-editor-history-list-item-revert",
9652
9668
  title: "将该步骤的修改作为一次新操作反向应用(不影响后续历史)",
9653
- onClick: _cache[1] || (_cache[1] = (0, vue.withModifiers)(($event) => onRevertClick(__props.subSteps[0].index), ["stop"]))
9669
+ onClick: _cache[0] || (_cache[0] = (0, vue.withModifiers)(($event) => onRevertClick(__props.subSteps[0].index), ["stop"]))
9654
9670
  }, "回滚")) : (0, vue.createCommentVNode)("v-if", true),
9655
- __props.merged ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
9671
+ !__props.merged && __props.gotoEnabled && !__props.isCurrent && __props.subSteps.length ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
9672
+ key: 3,
9673
+ class: "m-editor-history-list-item-goto",
9674
+ title: "回到该记录",
9675
+ onClick: _cache[1] || (_cache[1] = (0, vue.withModifiers)(($event) => onGotoClick(__props.subSteps[0].index), ["stop"]))
9676
+ }, "回到")) : (0, vue.createCommentVNode)("v-if", true),
9677
+ !__props.merged && headDiffable.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
9656
9678
  key: 4,
9679
+ class: "m-editor-history-list-item-diff",
9680
+ title: "查看修改差异",
9681
+ onClick: _cache[2] || (_cache[2] = (0, vue.withModifiers)(($event) => onDiffClick(__props.subSteps[0].index), ["stop"]))
9682
+ }, "查看差异")) : (0, vue.createCommentVNode)("v-if", true),
9683
+ __props.merged ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
9684
+ key: 5,
9657
9685
  class: (0, vue.normalizeClass)(["m-editor-history-list-group-toggle", { "is-expanded": __props.expanded }])
9658
9686
  }, "▾", 2)) : (0, vue.createCommentVNode)("v-if", true)
9659
- ], 10, _hoisted_1$62), __props.merged && __props.expanded ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("ul", _hoisted_6$3, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(subStepsDisplay.value, (s) => {
9687
+ ], 10, _hoisted_1$61), __props.merged && __props.expanded ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("ul", _hoisted_6$3, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(subStepsDisplay.value, (s) => {
9660
9688
  return (0, vue.openBlock)(), (0, vue.createElementBlock)("li", {
9661
9689
  key: s.index,
9662
9690
  class: (0, vue.normalizeClass)({
9663
9691
  "is-undone": !s.applied,
9664
- "is-current": s.isCurrent,
9665
- "is-clickable": !s.isCurrent
9692
+ "is-current": s.isCurrent
9666
9693
  }),
9667
- title: s.isCurrent ? "当前所在记录" : "点击跳转到该记录",
9668
- onClick: ($event) => onSubStepClick(s)
9694
+ title: subStepTitle(s)
9669
9695
  }, [
9670
9696
  (0, vue.createElementVNode)("span", _hoisted_8, "#" + (0, vue.toDisplayString)(s.index + 1), 1),
9671
9697
  (0, vue.createElementVNode)("span", _hoisted_9, (0, vue.toDisplayString)(s.desc), 1),
9672
- s.isCurrent ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_10, "当前")) : (0, vue.createCommentVNode)("v-if", true),
9673
- s.diffable ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
9674
- key: 1,
9675
- class: "m-editor-history-list-item-diff",
9676
- title: "查看修改差异",
9677
- onClick: (0, vue.withModifiers)(($event) => onDiffClick(s.index), ["stop"])
9678
- }, "查看差异", 8, _hoisted_11)) : (0, vue.createCommentVNode)("v-if", true),
9698
+ s.time ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
9699
+ key: 0,
9700
+ class: "m-editor-history-list-item-time",
9701
+ title: s.timeTitle || s.time
9702
+ }, (0, vue.toDisplayString)(s.time), 9, _hoisted_10)) : (0, vue.createCommentVNode)("v-if", true),
9679
9703
  s.revertable ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
9680
- key: 2,
9704
+ key: 1,
9681
9705
  class: "m-editor-history-list-item-revert",
9682
9706
  title: "将该步骤的修改作为一次新操作反向应用(不影响后续历史)",
9683
9707
  onClick: (0, vue.withModifiers)(($event) => onRevertClick(s.index), ["stop"])
9684
- }, "回滚", 8, _hoisted_12)) : (0, vue.createCommentVNode)("v-if", true)
9685
- ], 10, _hoisted_7);
9708
+ }, "回滚", 8, _hoisted_11)) : (0, vue.createCommentVNode)("v-if", true),
9709
+ __props.gotoEnabled && !s.isCurrent ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
9710
+ key: 2,
9711
+ class: "m-editor-history-list-item-goto",
9712
+ title: "回到该记录",
9713
+ onClick: (0, vue.withModifiers)(($event) => onGotoClick(s.index), ["stop"])
9714
+ }, "回到", 8, _hoisted_12)) : (0, vue.createCommentVNode)("v-if", true),
9715
+ s.diffable ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
9716
+ key: 3,
9717
+ class: "m-editor-history-list-item-diff",
9718
+ title: "查看修改差异",
9719
+ onClick: (0, vue.withModifiers)(($event) => onDiffClick(s.index), ["stop"])
9720
+ }, "查看差异", 8, _hoisted_13)) : (0, vue.createCommentVNode)("v-if", true)
9721
+ ], 10, _hoisted_7$1);
9686
9722
  }), 128))])) : (0, vue.createCommentVNode)("v-if", true)], 2);
9687
9723
  };
9688
9724
  }
@@ -9692,15 +9728,17 @@
9692
9728
  var GroupRow_default = GroupRow_vue_vue_type_script_setup_true_lang_default;
9693
9729
  //#endregion
9694
9730
  //#region packages/editor/src/layouts/history-list/InitialRow.vue?vue&type=script&setup=true&lang.ts
9695
- var _hoisted_1$61 = ["title"];
9696
- var _hoisted_2$21 = {
9697
- key: 0,
9698
- class: "m-editor-history-list-item-current"
9699
- };
9731
+ var _hoisted_1$60 = ["title"];
9700
9732
  var InitialRow_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ (0, vue.defineComponent)({
9701
9733
  name: "MEditorHistoryListInitialRow",
9702
9734
  __name: "InitialRow",
9703
- props: { isCurrent: { type: Boolean } },
9735
+ props: {
9736
+ isCurrent: { type: Boolean },
9737
+ gotoEnabled: {
9738
+ type: Boolean,
9739
+ default: true
9740
+ }
9741
+ },
9704
9742
  emits: ["goto-initial"],
9705
9743
  setup(__props, { emit: __emit }) {
9706
9744
  /**
@@ -9722,8 +9760,7 @@
9722
9760
  "is-current": __props.isCurrent,
9723
9761
  "is-clickable": !__props.isCurrent
9724
9762
  }]),
9725
- title: __props.isCurrent ? "当前已回到未修改的初始状态" : "点击回到未修改的初始状态",
9726
- onClick
9763
+ title: __props.isCurrent ? "当前已回到未修改的初始状态" : "点击回到未修改的初始状态"
9727
9764
  }, [
9728
9765
  _cache[0] || (_cache[0] = (0, vue.createElementVNode)("span", {
9729
9766
  class: "m-editor-history-list-item-index",
@@ -9731,8 +9768,13 @@
9731
9768
  }, "#0", -1)),
9732
9769
  _cache[1] || (_cache[1] = (0, vue.createElementVNode)("span", { class: "m-editor-history-list-item-op op-initial" }, "初始", -1)),
9733
9770
  _cache[2] || (_cache[2] = (0, vue.createElementVNode)("span", { class: "m-editor-history-list-item-desc" }, "未修改的初始状态", -1)),
9734
- __props.isCurrent ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_2$21, "当前")) : (0, vue.createCommentVNode)("v-if", true)
9735
- ], 10, _hoisted_1$61);
9771
+ __props.gotoEnabled && !__props.isCurrent ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", {
9772
+ key: 0,
9773
+ class: "m-editor-history-list-item-goto",
9774
+ title: "回到该记录",
9775
+ onClick: (0, vue.withModifiers)(onClick, ["stop"])
9776
+ }, "回到")) : (0, vue.createCommentVNode)("v-if", true)
9777
+ ], 10, _hoisted_1$60);
9736
9778
  };
9737
9779
  }
9738
9780
  });
@@ -9741,7 +9783,7 @@
9741
9783
  var InitialRow_default = InitialRow_vue_vue_type_script_setup_true_lang_default;
9742
9784
  //#endregion
9743
9785
  //#region packages/editor/src/layouts/history-list/Bucket.vue?vue&type=script&setup=true&lang.ts
9744
- var _hoisted_1$60 = { class: "m-editor-history-list-bucket" };
9786
+ var _hoisted_1$59 = { class: "m-editor-history-list-bucket" };
9745
9787
  var _hoisted_2$20 = { class: "m-editor-history-list-bucket-title" };
9746
9788
  var _hoisted_3$7 = { class: "m-editor-history-list-bucket-count" };
9747
9789
  var _hoisted_4$6 = { class: "m-editor-history-list-ul" };
@@ -9752,11 +9794,19 @@
9752
9794
  title: {},
9753
9795
  bucketId: {},
9754
9796
  prefix: {},
9797
+ showInitial: {
9798
+ type: Boolean,
9799
+ default: true
9800
+ },
9755
9801
  groups: {},
9756
- describeGroup: { type: Function },
9757
- describeStep: { type: Function },
9758
- isStepDiffable: { type: Function },
9759
- expanded: {}
9802
+ describeGroup: {},
9803
+ describeStep: {},
9804
+ isStepDiffable: {},
9805
+ expanded: {},
9806
+ gotoEnabled: {
9807
+ type: Boolean,
9808
+ default: true
9809
+ }
9760
9810
  },
9761
9811
  emits: [
9762
9812
  "toggle",
@@ -9770,19 +9820,21 @@
9770
9820
  /** 该 bucket 是否处于初始状态(栈 cursor=0),等价于全部 group 都未 applied。 */
9771
9821
  const isInitial = (0, vue.computed)(() => props.groups.length > 0 && props.groups.every((g) => !g.applied));
9772
9822
  return (_ctx, _cache) => {
9773
- return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$60, [(0, vue.createElementVNode)("div", _hoisted_2$20, [
9823
+ return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$59, [(0, vue.createElementVNode)("div", _hoisted_2$20, [
9774
9824
  (0, vue.createElementVNode)("span", null, (0, vue.toDisplayString)(__props.title), 1),
9775
9825
  (0, vue.createElementVNode)("code", null, (0, vue.toDisplayString)(String(__props.bucketId)), 1),
9776
9826
  (0, vue.createElementVNode)("span", _hoisted_3$7, (0, vue.toDisplayString)(__props.groups.length) + " 组", 1)
9777
9827
  ]), (0, vue.createElementVNode)("ul", _hoisted_4$6, [
9778
- ((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(__props.groups, (group, gIdx) => {
9828
+ ((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(__props.groups, (group) => {
9779
9829
  return (0, vue.openBlock)(), (0, vue.createBlock)(GroupRow_default, {
9780
- key: `${__props.prefix}-${__props.bucketId}-${gIdx}`,
9781
- "group-key": `${__props.prefix}-${__props.bucketId}-${gIdx}`,
9830
+ key: `${__props.prefix}-${__props.bucketId}-${group.steps[0]?.index}`,
9831
+ "group-key": `${__props.prefix}-${__props.bucketId}-${group.steps[0]?.index}`,
9782
9832
  applied: group.applied,
9783
9833
  merged: group.steps.length > 1,
9784
9834
  "op-type": group.opType,
9785
9835
  desc: __props.describeGroup(group),
9836
+ time: (0, vue.unref)(formatHistoryTime)((0, vue.unref)(groupTimestamp)(group)),
9837
+ "time-title": (0, vue.unref)(formatHistoryFullTime)((0, vue.unref)(groupTimestamp)(group)),
9786
9838
  "step-count": group.steps.length,
9787
9839
  "sub-steps": group.steps.map((s) => ({
9788
9840
  index: s.index,
@@ -9790,10 +9842,13 @@
9790
9842
  isCurrent: s.isCurrent,
9791
9843
  desc: __props.describeStep(s.step),
9792
9844
  diffable: __props.isStepDiffable ? __props.isStepDiffable(s.step) : false,
9793
- revertable: s.applied
9845
+ revertable: s.applied,
9846
+ time: (0, vue.unref)(formatHistoryTime)(s.step.timestamp),
9847
+ timeTitle: (0, vue.unref)(formatHistoryFullTime)(s.step.timestamp)
9794
9848
  })),
9795
9849
  "is-current": group.isCurrent,
9796
- expanded: !!__props.expanded[`${__props.prefix}-${__props.bucketId}-${gIdx}`],
9850
+ expanded: !!__props.expanded[`${__props.prefix}-${__props.bucketId}-${group.steps[0]?.index}`],
9851
+ "goto-enabled": __props.gotoEnabled,
9797
9852
  onToggle: _cache[0] || (_cache[0] = (key) => _ctx.$emit("toggle", key)),
9798
9853
  onGoto: _cache[1] || (_cache[1] = (index) => _ctx.$emit("goto", __props.bucketId, index)),
9799
9854
  onDiffStep: _cache[2] || (_cache[2] = (index) => _ctx.$emit("diff-step", __props.bucketId, index)),
@@ -9804,17 +9859,22 @@
9804
9859
  "merged",
9805
9860
  "op-type",
9806
9861
  "desc",
9862
+ "time",
9863
+ "time-title",
9807
9864
  "step-count",
9808
9865
  "sub-steps",
9809
9866
  "is-current",
9810
- "expanded"
9867
+ "expanded",
9868
+ "goto-enabled"
9811
9869
  ]);
9812
9870
  }), 128)),
9813
- (0, vue.createCommentVNode)("\n 初始状态项:永远位于该 bucket 列表底部(同样按倒序展示,最底部 = 最早状态)。\n 当 bucket 内所有 group 都未 applied 时即为当前位置。\n "),
9814
- (0, vue.createVNode)(InitialRow_default, {
9871
+ (0, vue.createCommentVNode)("\n 初始状态项:永远位于该 bucket 列表底部(同样按倒序展示,最底部 = 最早状态)。\n 当 bucket 内所有 group 都未 applied 时即为当前位置。\n showInitial=false 时不展示(用于没有\"撤销到初始状态\"语义的自定义历史,如业务模块历史)。\n "),
9872
+ __props.showInitial !== false ? ((0, vue.openBlock)(), (0, vue.createBlock)(InitialRow_default, {
9873
+ key: 0,
9815
9874
  "is-current": isInitial.value,
9875
+ "goto-enabled": __props.gotoEnabled,
9816
9876
  onGotoInitial: _cache[4] || (_cache[4] = ($event) => _ctx.$emit("goto-initial", __props.bucketId))
9817
- }, null, 8, ["is-current"])
9877
+ }, null, 8, ["is-current", "goto-enabled"])) : (0, vue.createCommentVNode)("v-if", true)
9818
9878
  ])]);
9819
9879
  };
9820
9880
  }
@@ -9823,77 +9883,26 @@
9823
9883
  //#region packages/editor/src/layouts/history-list/Bucket.vue
9824
9884
  var Bucket_default = Bucket_vue_vue_type_script_setup_true_lang_default;
9825
9885
  //#endregion
9826
- //#region packages/editor/src/layouts/history-list/CodeBlockTab.vue?vue&type=script&setup=true&lang.ts
9827
- var _hoisted_1$59 = {
9828
- key: 0,
9829
- class: "m-editor-history-list-empty"
9830
- };
9831
- var CodeBlockTab_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ (0, vue.defineComponent)({
9832
- name: "MEditorHistoryListCodeBlockTab",
9833
- __name: "CodeBlockTab",
9834
- props: {
9835
- buckets: {},
9836
- expanded: {}
9837
- },
9838
- emits: [
9839
- "toggle",
9840
- "goto",
9841
- "goto-initial",
9842
- "diff-step",
9843
- "revert-step"
9844
- ],
9845
- setup(__props) {
9846
- /** 仅 update(前后 content 都存在)时可查看差异。 */
9847
- const isCodeBlockStepDiffable = (step) => Boolean(step.oldContent && step.newContent);
9848
- return (_ctx, _cache) => {
9849
- return !__props.buckets.length ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$59, "暂无操作记录")) : ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.unref)(_tmagic_design.TMagicScrollbar), {
9850
- key: 1,
9851
- "max-height": "360px"
9852
- }, {
9853
- default: (0, vue.withCtx)(() => [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(__props.buckets, (bucket) => {
9854
- return (0, vue.openBlock)(), (0, vue.createBlock)(Bucket_default, {
9855
- key: `cb-${bucket.id}`,
9856
- title: "代码块",
9857
- "bucket-id": bucket.id,
9858
- prefix: "cb",
9859
- groups: bucket.groups,
9860
- "describe-group": (0, vue.unref)(describeCodeBlockGroup),
9861
- "describe-step": (0, vue.unref)(describeCodeBlockStep),
9862
- "is-step-diffable": isCodeBlockStepDiffable,
9863
- expanded: __props.expanded,
9864
- onToggle: _cache[0] || (_cache[0] = (key) => _ctx.$emit("toggle", key)),
9865
- onGoto: _cache[1] || (_cache[1] = (id, index) => _ctx.$emit("goto", id, index)),
9866
- onGotoInitial: _cache[2] || (_cache[2] = (id) => _ctx.$emit("goto-initial", id)),
9867
- onDiffStep: _cache[3] || (_cache[3] = (id, index) => _ctx.$emit("diff-step", id, index)),
9868
- onRevertStep: _cache[4] || (_cache[4] = (id, index) => _ctx.$emit("revert-step", id, index))
9869
- }, null, 8, [
9870
- "bucket-id",
9871
- "groups",
9872
- "describe-group",
9873
- "describe-step",
9874
- "expanded"
9875
- ]);
9876
- }), 128))]),
9877
- _: 1
9878
- }));
9879
- };
9880
- }
9881
- });
9882
- //#endregion
9883
- //#region packages/editor/src/layouts/history-list/CodeBlockTab.vue
9884
- var CodeBlockTab_default = CodeBlockTab_vue_vue_type_script_setup_true_lang_default;
9885
- //#endregion
9886
- //#region packages/editor/src/layouts/history-list/DataSourceTab.vue?vue&type=script&setup=true&lang.ts
9886
+ //#region packages/editor/src/layouts/history-list/BucketTab.vue?vue&type=script&setup=true&lang.ts
9887
9887
  var _hoisted_1$58 = {
9888
9888
  key: 0,
9889
9889
  class: "m-editor-history-list-empty"
9890
9890
  };
9891
- var DataSourceTab_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ (0, vue.defineComponent)({
9892
- name: "MEditorHistoryListDataSourceTab",
9893
- __name: "DataSourceTab",
9891
+ var BucketTab_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ (0, vue.defineComponent)({
9892
+ name: "MEditorHistoryListBucketTab",
9893
+ __name: "BucketTab",
9894
9894
  props: {
9895
+ title: {},
9896
+ prefix: {},
9895
9897
  buckets: {},
9896
- expanded: {}
9898
+ describeGroup: {},
9899
+ describeStep: {},
9900
+ isStepDiffable: {},
9901
+ expanded: {},
9902
+ gotoEnabled: {
9903
+ type: Boolean,
9904
+ default: true
9905
+ }
9897
9906
  },
9898
9907
  emits: [
9899
9908
  "toggle",
@@ -9903,8 +9912,6 @@
9903
9912
  "revert-step"
9904
9913
  ],
9905
9914
  setup(__props) {
9906
- /** 仅 update(前后 schema 都存在)时可查看差异。 */
9907
- const isDataSourceStepDiffable = (step) => Boolean(step.oldSchema && step.newSchema);
9908
9915
  return (_ctx, _cache) => {
9909
9916
  return !__props.buckets.length ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$58, "暂无操作记录")) : ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.unref)(_tmagic_design.TMagicScrollbar), {
9910
9917
  key: 1,
@@ -9912,26 +9919,31 @@
9912
9919
  }, {
9913
9920
  default: (0, vue.withCtx)(() => [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(__props.buckets, (bucket) => {
9914
9921
  return (0, vue.openBlock)(), (0, vue.createBlock)(Bucket_default, {
9915
- key: `ds-${bucket.id}`,
9916
- title: "数据源",
9922
+ key: `${__props.prefix}-${bucket.id}`,
9923
+ title: __props.title,
9917
9924
  "bucket-id": bucket.id,
9918
- prefix: "ds",
9925
+ prefix: __props.prefix,
9919
9926
  groups: bucket.groups,
9920
- "describe-group": (0, vue.unref)(describeDataSourceGroup),
9921
- "describe-step": (0, vue.unref)(describeDataSourceStep),
9922
- "is-step-diffable": isDataSourceStepDiffable,
9927
+ "describe-group": __props.describeGroup,
9928
+ "describe-step": __props.describeStep,
9929
+ "is-step-diffable": __props.isStepDiffable,
9923
9930
  expanded: __props.expanded,
9931
+ "goto-enabled": __props.gotoEnabled,
9924
9932
  onToggle: _cache[0] || (_cache[0] = (key) => _ctx.$emit("toggle", key)),
9925
9933
  onGoto: _cache[1] || (_cache[1] = (id, index) => _ctx.$emit("goto", id, index)),
9926
9934
  onGotoInitial: _cache[2] || (_cache[2] = (id) => _ctx.$emit("goto-initial", id)),
9927
9935
  onDiffStep: _cache[3] || (_cache[3] = (id, index) => _ctx.$emit("diff-step", id, index)),
9928
9936
  onRevertStep: _cache[4] || (_cache[4] = (id, index) => _ctx.$emit("revert-step", id, index))
9929
9937
  }, null, 8, [
9938
+ "title",
9930
9939
  "bucket-id",
9940
+ "prefix",
9931
9941
  "groups",
9932
9942
  "describe-group",
9933
9943
  "describe-step",
9934
- "expanded"
9944
+ "is-step-diffable",
9945
+ "expanded",
9946
+ "goto-enabled"
9935
9947
  ]);
9936
9948
  }), 128))]),
9937
9949
  _: 1
@@ -9940,8 +9952,8 @@
9940
9952
  }
9941
9953
  });
9942
9954
  //#endregion
9943
- //#region packages/editor/src/layouts/history-list/DataSourceTab.vue
9944
- var DataSourceTab_default = DataSourceTab_vue_vue_type_script_setup_true_lang_default;
9955
+ //#region packages/editor/src/layouts/history-list/BucketTab.vue
9956
+ var BucketTab_default = BucketTab_vue_vue_type_script_setup_true_lang_default;
9945
9957
  //#endregion
9946
9958
  //#region packages/editor/src/components/CompareForm.vue?vue&type=script&setup=true&lang.ts
9947
9959
  var CompareForm_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ (0, vue.defineComponent)({
@@ -9955,15 +9967,10 @@
9955
9967
  dataSourceType: {},
9956
9968
  labelWidth: { default: "120px" },
9957
9969
  height: {},
9958
- extendState: {}
9970
+ extendState: {},
9971
+ loadConfig: {}
9959
9972
  },
9960
9973
  setup(__props, { expose: __expose }) {
9961
- /**
9962
- * 对比类型:
9963
- * - node: 节点组件,按 `type` 从 propsService 获取属性表单配置
9964
- * - data-source: 数据源,按 `type`(base/http/...) 从 dataSourceService 获取数据源表单配置
9965
- * - code-block: 数据源代码块,使用内置的代码块表单配置
9966
- */
9967
9974
  const props = __props;
9968
9975
  const { propsService, dataSourceService, codeBlockService, editorService } = useServices();
9969
9976
  const services = useServices();
@@ -10023,34 +10030,43 @@
10023
10030
  }
10024
10031
  return !isEqual(curValue, lastValue);
10025
10032
  };
10026
- const loadConfig = async () => {
10033
+ /**
10034
+ * 内置的默认 FormConfig 加载逻辑:按 `category` 从对应 service / 工具取配置。
10035
+ * 作为 ctx.defaultLoadConfig 透传给自定义 `loadConfig`,方便复用与二次加工。
10036
+ */
10037
+ const defaultLoadConfig = async () => {
10027
10038
  switch (props.category) {
10028
10039
  case "node":
10029
- if (!props.type) {
10030
- config.value = [];
10031
- return;
10032
- }
10033
- config.value = await propsService.getPropsConfig(props.type);
10034
- break;
10035
- case "data-source":
10036
- config.value = dataSourceService.getFormConfig(props.type || "base");
10037
- break;
10038
- case "code-block":
10039
- config.value = getCodeBlockFormConfig({
10040
- paramColConfig: codeBlockService.getParamsColConfig(),
10041
- isDataSource: () => Boolean(props.dataSourceType),
10042
- dataSourceType: () => props.dataSourceType,
10043
- codeOptions,
10044
- editable: false
10045
- });
10046
- break;
10047
- default: config.value = [];
10040
+ if (!props.type) return [];
10041
+ return await propsService.getPropsConfig(props.type);
10042
+ case "data-source": return dataSourceService.getFormConfig(props.type || "base");
10043
+ case "code-block": return getCodeBlockFormConfig({
10044
+ paramColConfig: codeBlockService.getParamsColConfig(),
10045
+ isDataSource: () => Boolean(props.dataSourceType),
10046
+ dataSourceType: () => props.dataSourceType,
10047
+ codeOptions,
10048
+ editable: false
10049
+ });
10050
+ default: return [];
10048
10051
  }
10049
10052
  };
10053
+ const loadConfig = async () => {
10054
+ if (props.loadConfig) {
10055
+ config.value = await props.loadConfig({
10056
+ category: props.category,
10057
+ type: props.type,
10058
+ dataSourceType: props.dataSourceType,
10059
+ defaultLoadConfig
10060
+ });
10061
+ return;
10062
+ }
10063
+ config.value = await defaultLoadConfig();
10064
+ };
10050
10065
  (0, vue.watch)([
10051
10066
  () => props.category,
10052
10067
  () => props.type,
10053
- () => props.dataSourceType
10068
+ () => props.dataSourceType,
10069
+ () => props.loadConfig
10054
10070
  ], () => {
10055
10071
  loadConfig();
10056
10072
  }, { immediate: true });
@@ -10111,20 +10127,37 @@
10111
10127
  key: 0,
10112
10128
  class: "m-editor-history-diff-dialog-body"
10113
10129
  };
10114
- var _hoisted_2$19 = { class: "m-editor-history-diff-dialog-header" };
10115
- var _hoisted_3$6 = { class: "m-editor-history-diff-dialog-target" };
10116
- var _hoisted_4$5 = { class: "m-editor-history-diff-dialog-controls" };
10117
- var _hoisted_5$2 = { class: "m-editor-history-diff-dialog-legend" };
10118
- var _hoisted_6$2 = {
10130
+ var _hoisted_2$19 = {
10131
+ key: 0,
10132
+ class: "m-editor-history-diff-dialog-notice"
10133
+ };
10134
+ var _hoisted_3$6 = { class: "m-editor-history-diff-dialog-header" };
10135
+ var _hoisted_4$5 = { class: "m-editor-history-diff-dialog-target" };
10136
+ var _hoisted_5$2 = { class: "m-editor-history-diff-dialog-controls" };
10137
+ var _hoisted_6$2 = { class: "m-editor-history-diff-dialog-legend" };
10138
+ var _hoisted_7 = {
10119
10139
  key: 0,
10120
10140
  class: "m-editor-history-diff-dialog-tip"
10121
10141
  };
10122
10142
  var HistoryDiffDialog_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ (0, vue.defineComponent)({
10123
10143
  name: "MEditorHistoryDiffDialog",
10124
10144
  __name: "HistoryDiffDialog",
10125
- props: { extendState: { type: Function } },
10126
- setup(__props, { expose: __expose }) {
10127
- /** 差异对话框的入参 */
10145
+ props: {
10146
+ extendState: {},
10147
+ loadConfig: {},
10148
+ width: { default: "900px" },
10149
+ onConfirm: {},
10150
+ selfDiffFieldTypes: {}
10151
+ },
10152
+ emits: ["close"],
10153
+ setup(__props, { expose: __expose, emit: __emit }) {
10154
+ const props = __props;
10155
+ const emit = __emit;
10156
+ /**
10157
+ * 差异对比模式:
10158
+ * - before:该步骤修改前 vs 该步骤修改后(默认行为,体现这一步带来的变化)
10159
+ * - current:该步骤修改后 vs 当前最新值(用于查看「该步骤之后是否还被改过」)
10160
+ */
10128
10161
  const visible = (0, vue.ref)(false);
10129
10162
  const payload = (0, vue.ref)(null);
10130
10163
  const mode = (0, vue.ref)("before");
@@ -10146,6 +10179,7 @@
10146
10179
  scrollBeyondLastLine: false,
10147
10180
  hideUnchangedRegions: { enabled: true }
10148
10181
  };
10182
+ const dialogTitle = (0, vue.computed)(() => props.onConfirm ? "确认回滚" : "查看修改差异");
10149
10183
  const hasCurrent = (0, vue.computed)(() => payload.value?.currentValue !== void 0 && payload.value?.currentValue !== null);
10150
10184
  /** 左侧(旧/参照)值 */
10151
10185
  const leftValue = (0, vue.computed)(() => {
@@ -10166,6 +10200,11 @@
10166
10200
  if (mode.value !== "current" || !payload.value) return false;
10167
10201
  return isEqual(payload.value.value, payload.value.currentValue);
10168
10202
  });
10203
+ const onConfirmClick = () => {
10204
+ const cb = props.onConfirm;
10205
+ cb?.();
10206
+ visible.value = false;
10207
+ };
10169
10208
  const targetText = (0, vue.computed)(() => {
10170
10209
  if (!payload.value) return "";
10171
10210
  const prefix = {
@@ -10189,6 +10228,9 @@
10189
10228
  (0, vue.watch)(visible, (v) => {
10190
10229
  if (!v) payload.value = null;
10191
10230
  });
10231
+ const onClose = () => {
10232
+ emit("close");
10233
+ };
10192
10234
  __expose({
10193
10235
  open,
10194
10236
  close
@@ -10196,33 +10238,49 @@
10196
10238
  return (_ctx, _cache) => {
10197
10239
  return (0, vue.openBlock)(), (0, vue.createBlock)(vue.Teleport, { to: "body" }, [(0, vue.createVNode)((0, vue.unref)(_tmagic_design.TMagicDialog), {
10198
10240
  modelValue: visible.value,
10199
- "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => visible.value = $event),
10241
+ "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => visible.value = $event),
10200
10242
  class: "m-editor-history-diff-dialog",
10201
- title: "查看修改差异",
10202
- width: "900px",
10243
+ title: dialogTitle.value,
10203
10244
  top: "5vh",
10204
10245
  "destroy-on-close": "",
10205
- "append-to-body": ""
10246
+ "append-to-body": "",
10247
+ width: __props.width,
10248
+ onClose
10206
10249
  }, {
10207
- footer: (0, vue.withCtx)(() => [(0, vue.createVNode)((0, vue.unref)(_tmagic_design.TMagicButton), {
10250
+ footer: (0, vue.withCtx)(() => [__props.onConfirm ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 0 }, [(0, vue.createVNode)((0, vue.unref)(_tmagic_design.TMagicButton), {
10208
10251
  size: "small",
10209
10252
  onClick: _cache[2] || (_cache[2] = ($event) => visible.value = false)
10210
10253
  }, {
10211
- default: (0, vue.withCtx)(() => [..._cache[9] || (_cache[9] = [(0, vue.createTextVNode)("关闭", -1)])]),
10254
+ default: (0, vue.withCtx)(() => [..._cache[10] || (_cache[10] = [(0, vue.createTextVNode)("取消", -1)])]),
10212
10255
  _: 1
10213
- })]),
10256
+ }), (0, vue.createVNode)((0, vue.unref)(_tmagic_design.TMagicButton), {
10257
+ size: "small",
10258
+ type: "primary",
10259
+ onClick: onConfirmClick
10260
+ }, {
10261
+ default: (0, vue.withCtx)(() => [..._cache[11] || (_cache[11] = [(0, vue.createTextVNode)("确定回滚", -1)])]),
10262
+ _: 1
10263
+ })], 64)) : ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.unref)(_tmagic_design.TMagicButton), {
10264
+ key: 1,
10265
+ size: "small",
10266
+ onClick: _cache[3] || (_cache[3] = ($event) => visible.value = false)
10267
+ }, {
10268
+ default: (0, vue.withCtx)(() => [..._cache[12] || (_cache[12] = [(0, vue.createTextVNode)("关闭", -1)])]),
10269
+ _: 1
10270
+ }))]),
10214
10271
  default: (0, vue.withCtx)(() => [payload.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$57, [
10215
- (0, vue.createElementVNode)("div", _hoisted_2$19, [(0, vue.createElementVNode)("span", _hoisted_3$6, (0, vue.toDisplayString)(targetText.value), 1), (0, vue.createElementVNode)("div", _hoisted_4$5, [(0, vue.createVNode)((0, vue.unref)(_tmagic_design.TMagicRadioGroup), {
10272
+ __props.onConfirm ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_2$19, "仅回滚有差异的字段")) : (0, vue.createCommentVNode)("v-if", true),
10273
+ (0, vue.createElementVNode)("div", _hoisted_3$6, [(0, vue.createElementVNode)("span", _hoisted_4$5, (0, vue.toDisplayString)(targetText.value), 1), (0, vue.createElementVNode)("div", _hoisted_5$2, [(0, vue.createVNode)((0, vue.unref)(_tmagic_design.TMagicRadioGroup), {
10216
10274
  modelValue: viewMode.value,
10217
10275
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => viewMode.value = $event),
10218
10276
  size: "small",
10219
10277
  class: "m-editor-history-diff-dialog-view"
10220
10278
  }, {
10221
10279
  default: (0, vue.withCtx)(() => [(0, vue.createVNode)((0, vue.unref)(_tmagic_design.TMagicRadioButton), { value: "form" }, {
10222
- default: (0, vue.withCtx)(() => [..._cache[4] || (_cache[4] = [(0, vue.createTextVNode)("表单对比", -1)])]),
10280
+ default: (0, vue.withCtx)(() => [..._cache[5] || (_cache[5] = [(0, vue.createTextVNode)("表单对比", -1)])]),
10223
10281
  _: 1
10224
10282
  }), (0, vue.createVNode)((0, vue.unref)(_tmagic_design.TMagicRadioButton), { value: "code" }, {
10225
- default: (0, vue.withCtx)(() => [..._cache[5] || (_cache[5] = [(0, vue.createTextVNode)("源码对比", -1)])]),
10283
+ default: (0, vue.withCtx)(() => [..._cache[6] || (_cache[6] = [(0, vue.createTextVNode)("源码对比", -1)])]),
10226
10284
  _: 1
10227
10285
  })]),
10228
10286
  _: 1
@@ -10233,18 +10291,18 @@
10233
10291
  class: "m-editor-history-diff-dialog-mode"
10234
10292
  }, {
10235
10293
  default: (0, vue.withCtx)(() => [(0, vue.createVNode)((0, vue.unref)(_tmagic_design.TMagicRadioButton), { value: "before" }, {
10236
- default: (0, vue.withCtx)(() => [..._cache[6] || (_cache[6] = [(0, vue.createTextVNode)("与修改前对比", -1)])]),
10294
+ default: (0, vue.withCtx)(() => [..._cache[7] || (_cache[7] = [(0, vue.createTextVNode)("与修改前对比", -1)])]),
10237
10295
  _: 1
10238
10296
  }), (0, vue.createVNode)((0, vue.unref)(_tmagic_design.TMagicRadioButton), {
10239
10297
  value: "current",
10240
10298
  disabled: !hasCurrent.value
10241
10299
  }, {
10242
- default: (0, vue.withCtx)(() => [..._cache[7] || (_cache[7] = [(0, vue.createTextVNode)("与当前对比", -1)])]),
10300
+ default: (0, vue.withCtx)(() => [..._cache[8] || (_cache[8] = [(0, vue.createTextVNode)("与当前对比", -1)])]),
10243
10301
  _: 1
10244
10302
  }, 8, ["disabled"])]),
10245
10303
  _: 1
10246
10304
  }, 8, ["modelValue"])])]),
10247
- (0, vue.createElementVNode)("div", _hoisted_5$2, [
10305
+ (0, vue.createElementVNode)("div", _hoisted_6$2, [
10248
10306
  (0, vue.createVNode)((0, vue.unref)(_tmagic_design.TMagicTag), {
10249
10307
  size: "small",
10250
10308
  type: "danger"
@@ -10252,7 +10310,7 @@
10252
10310
  default: (0, vue.withCtx)(() => [(0, vue.createTextVNode)((0, vue.toDisplayString)(leftLabel.value), 1)]),
10253
10311
  _: 1
10254
10312
  }),
10255
- _cache[8] || (_cache[8] = (0, vue.createElementVNode)("span", { class: "m-editor-history-diff-dialog-arrow" }, "→", -1)),
10313
+ _cache[9] || (_cache[9] = (0, vue.createElementVNode)("span", { class: "m-editor-history-diff-dialog-arrow" }, "→", -1)),
10256
10314
  (0, vue.createVNode)((0, vue.unref)(_tmagic_design.TMagicTag), {
10257
10315
  size: "small",
10258
10316
  type: "success"
@@ -10260,16 +10318,18 @@
10260
10318
  default: (0, vue.withCtx)(() => [(0, vue.createTextVNode)((0, vue.toDisplayString)(rightLabel.value), 1)]),
10261
10319
  _: 1
10262
10320
  }),
10263
- mode.value === "current" && isSameAsCurrent.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_6$2, " 当前值与该步修改后一致,无差异 ")) : (0, vue.createCommentVNode)("v-if", true)
10321
+ mode.value === "current" && isSameAsCurrent.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_7, " 当前值与该步修改后一致,无差异 ")) : (0, vue.createCommentVNode)("v-if", true)
10264
10322
  ]),
10265
10323
  viewMode.value === "form" ? ((0, vue.openBlock)(), (0, vue.createBlock)(CompareForm_default, {
10266
- key: 0,
10324
+ key: 1,
10267
10325
  category: payload.value.category,
10268
10326
  type: payload.value.type,
10269
10327
  "data-source-type": payload.value.dataSourceType,
10270
10328
  value: rightValue.value,
10271
10329
  "last-value": leftValue.value,
10272
10330
  "extend-state": __props.extendState,
10331
+ "load-config": __props.loadConfig,
10332
+ "self-diff-field-types": __props.selfDiffFieldTypes,
10273
10333
  height: "70vh"
10274
10334
  }, null, 8, [
10275
10335
  "category",
@@ -10277,9 +10337,11 @@
10277
10337
  "data-source-type",
10278
10338
  "value",
10279
10339
  "last-value",
10280
- "extend-state"
10340
+ "extend-state",
10341
+ "load-config",
10342
+ "self-diff-field-types"
10281
10343
  ])) : ((0, vue.openBlock)(), (0, vue.createBlock)(CodeEditor_default, {
10282
- key: 1,
10344
+ key: 2,
10283
10345
  type: "diff",
10284
10346
  language: "json",
10285
10347
  "init-values": leftValue.value,
@@ -10290,7 +10352,11 @@
10290
10352
  }, null, 8, ["init-values", "modified-values"]))
10291
10353
  ])) : (0, vue.createCommentVNode)("v-if", true)]),
10292
10354
  _: 1
10293
- }, 8, ["modelValue"])]);
10355
+ }, 8, [
10356
+ "modelValue",
10357
+ "title",
10358
+ "width"
10359
+ ])]);
10294
10360
  };
10295
10361
  }
10296
10362
  });
@@ -10344,14 +10410,16 @@
10344
10410
  "max-height": "360px"
10345
10411
  }, {
10346
10412
  default: (0, vue.withCtx)(() => [(0, vue.createElementVNode)("ul", _hoisted_2$18, [
10347
- ((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(__props.list, (group, gIdx) => {
10413
+ ((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(__props.list, (group) => {
10348
10414
  return (0, vue.openBlock)(), (0, vue.createBlock)(GroupRow_default, {
10349
- key: `pg-${gIdx}`,
10350
- "group-key": `pg-${gIdx}`,
10415
+ key: `pg-${group.steps[0]?.index}`,
10416
+ "group-key": `pg-${group.steps[0]?.index}`,
10351
10417
  applied: group.applied,
10352
10418
  merged: group.steps.length > 1,
10353
10419
  "op-type": group.opType,
10354
10420
  desc: (0, vue.unref)(describePageGroup)(group),
10421
+ time: (0, vue.unref)(formatHistoryTime)((0, vue.unref)(groupTimestamp)(group)),
10422
+ "time-title": (0, vue.unref)(formatHistoryFullTime)((0, vue.unref)(groupTimestamp)(group)),
10355
10423
  "step-count": group.steps.length,
10356
10424
  "sub-steps": group.steps.map((s) => ({
10357
10425
  index: s.index,
@@ -10359,10 +10427,12 @@
10359
10427
  isCurrent: s.isCurrent,
10360
10428
  desc: (0, vue.unref)(describePageStep)(s.step),
10361
10429
  diffable: isPageStepDiffable(s.step),
10362
- revertable: s.applied
10430
+ revertable: s.applied,
10431
+ time: (0, vue.unref)(formatHistoryTime)(s.step.timestamp),
10432
+ timeTitle: (0, vue.unref)(formatHistoryFullTime)(s.step.timestamp)
10363
10433
  })),
10364
10434
  "is-current": group.isCurrent,
10365
- expanded: !!__props.expanded[`pg-${gIdx}`],
10435
+ expanded: !!__props.expanded[`pg-${group.steps[0]?.index}`],
10366
10436
  onToggle: _cache[0] || (_cache[0] = (key) => _ctx.$emit("toggle", key)),
10367
10437
  onGoto: _cache[1] || (_cache[1] = (index) => _ctx.$emit("goto", index)),
10368
10438
  onDiffStep: _cache[2] || (_cache[2] = (index) => _ctx.$emit("diff-step", index)),
@@ -10373,6 +10443,8 @@
10373
10443
  "merged",
10374
10444
  "op-type",
10375
10445
  "desc",
10446
+ "time",
10447
+ "time-title",
10376
10448
  "step-count",
10377
10449
  "sub-steps",
10378
10450
  "is-current",
@@ -10417,7 +10489,8 @@
10417
10489
  * 此外每条 step 上提供"查看差异"入口(仅在前后值都存在的 update 步骤显示),
10418
10490
  * 点击后弹出 HistoryDiffDialog,使用 CompareForm 组件以表单形式展示新旧值差异。
10419
10491
  *
10420
- * 各 tab 的内容拆分为独立的 SFCPageTab / DataSourceTab / CodeBlockTab),
10492
+ * 各 tab 的内容拆分为独立的 SFC:页面用 PageTab,数据源 / 代码块复用通用的 BucketTab
10493
+ * (通过 title / prefix / describe* / isStepDiffable 注入差异)。
10421
10494
  * 共享的描述生成与折叠状态在 composables.ts 中维护。
10422
10495
  */
10423
10496
  const ClockIcon = (0, vue.markRaw)(_element_plus_icons_vue.Clock);
@@ -10426,7 +10499,23 @@
10426
10499
  /** 面板显隐受控:reference 图标点击切换,右上角关闭按钮置为 false。 */
10427
10500
  const visible = (0, vue.ref)(false);
10428
10501
  const tabPaneComponent = (0, _tmagic_design.getDesignConfig)("components")?.tabPane;
10429
- const { editorService, dataSourceService, codeBlockService, historyService } = useServices();
10502
+ /**
10503
+ * 业务方自定义的扩展 tab,由 Editor 顶层通过 `historyListExtraTabs` 注入。
10504
+ * 追加在内置「页面 / 数据源 / 代码块」三个 tab 之后,未提供时为空数组。
10505
+ */
10506
+ const extraTabs = (0, vue.inject)("historyListExtraTabs", []);
10507
+ /** label 支持字符串或函数,函数形式便于展示动态数量等内容。 */
10508
+ const resolveTabLabel = (tab) => typeof tab.label === "function" ? tab.label() : tab.label;
10509
+ const { editorService, dataSourceService, codeBlockService, historyService, propsService } = useServices();
10510
+ /**
10511
+ * 数据源 / 代码块功能可被业务方通过 `disabledDataSource` / `disabledCodeBlock` 禁用,
10512
+ * 禁用后对应的历史记录 tab 不再展示。若当前激活的 tab 恰好被禁用,则回退到「页面」tab。
10513
+ */
10514
+ const disabledDataSource = (0, vue.computed)(() => propsService.getDisabledDataSource());
10515
+ const disabledCodeBlock = (0, vue.computed)(() => propsService.getDisabledCodeBlock());
10516
+ (0, vue.watch)([disabledDataSource, disabledCodeBlock], ([dsDisabled, cbDisabled]) => {
10517
+ if (activeTab.value === "data-source" && dsDisabled || activeTab.value === "code-block" && cbDisabled) activeTab.value = "page";
10518
+ });
10430
10519
  /**
10431
10520
  * 通过 inject 拿到 Editor 顶层注入的 `extendFormState`,转交给 HistoryDiffDialog
10432
10521
  * 内部的 CompareForm,使差异对比表单的 filterFunction 能拿到完整的业务上下文。
@@ -10434,6 +10523,10 @@
10434
10523
  */
10435
10524
  const extendFormState = (0, vue.inject)("extendFormState", void 0);
10436
10525
  const { expanded, toggleGroup, pageGroups, dataSourceGroups, codeBlockGroups, pageGroupsDisplay, dataSourceGroupsByTarget, codeBlockGroupsByTarget } = useHistoryList();
10526
+ /** 数据源 step 仅 update(前后 schema 都存在)时可查看差异。 */
10527
+ const isDataSourceStepDiffable = (step) => Boolean(step.oldSchema && step.newSchema);
10528
+ /** 代码块 step 仅 update(前后 content 都存在)时可查看差异。 */
10529
+ const isCodeBlockStepDiffable = (step) => Boolean(step.oldContent && step.newContent);
10437
10530
  /** 把"目标 step 索引"翻译成"目标 cursor"(已应用步骤数量)。 */
10438
10531
  const indexToCursor = (index) => index + 1;
10439
10532
  const onPageGoto = (index) => {
@@ -10458,36 +10551,24 @@
10458
10551
  const onCodeBlockGotoInitial = (id) => {
10459
10552
  codeBlockService.goto(id, 0);
10460
10553
  };
10461
- /**
10462
- * 「回滚」入口:把目标历史步骤的修改作为一次新操作反向应用(类 git revert),
10463
- * 不破坏原有栈结构。各 service 内部完成反向 + 入栈,并自带描述用于面板展示。
10464
- */
10465
- const onPageRevert = (index) => {
10466
- editorService.revertPageStep(index);
10467
- };
10468
- const onDataSourceRevert = (id, index) => {
10469
- dataSourceService.revert(id, index);
10470
- };
10471
- const onCodeBlockRevert = (id, index) => {
10472
- codeBlockService.revert(id, index);
10473
- };
10474
10554
  const diffDialogRef = (0, vue.useTemplateRef)("diffDialog");
10475
10555
  /**
10476
- * 页面 step 差异:仅 update 单节点修改可对比,传入旧/新节点。
10556
+ * 构造页面 step 的差异弹窗入参:仅 update 单节点修改可对比,传入旧/新节点。
10477
10557
  * 节点类型 `type` 优先取 newNode.type,再回退 oldNode.type。
10478
10558
  * `currentValue` 取自 editorService 中该节点当前实际值,用于支持「与当前对比」。
10559
+ * 无可对比内容(如多节点 / add / remove)时返回 null。
10479
10560
  */
10480
- const onPageDiff = (index) => {
10561
+ const buildPageDiffPayload = (index) => {
10481
10562
  const groups = historyService.getPageHistoryGroups();
10482
10563
  for (const group of groups) {
10483
10564
  const entry = group.steps.find((s) => s.index === index);
10484
10565
  if (!entry) continue;
10485
10566
  const item = entry.step.updatedItems?.[0];
10486
- if (!item?.oldNode || !item?.newNode) return;
10567
+ if (!item?.oldNode || !item?.newNode) return null;
10487
10568
  const type = item.newNode.type || item.oldNode.type || "";
10488
10569
  const nodeId = item.newNode.id ?? item.oldNode.id;
10489
10570
  const currentNode = nodeId !== void 0 ? editorService.getNodeById(nodeId) : null;
10490
- diffDialogRef.value?.open({
10571
+ return {
10491
10572
  category: "node",
10492
10573
  type,
10493
10574
  lastValue: item.oldNode,
@@ -10495,50 +10576,87 @@
10495
10576
  currentValue: currentNode || null,
10496
10577
  targetLabel: item.newNode.name || item.oldNode.name || type,
10497
10578
  id: nodeId
10498
- });
10499
- return;
10579
+ };
10500
10580
  }
10581
+ return null;
10501
10582
  };
10502
- const onDataSourceDiff = (id, index) => {
10503
- const groups = historyService.getDataSourceHistoryGroups();
10583
+ /**
10584
+ * 在指定分组列表中按 id / index 查找命中的 step,命中后交由 build 构造差异弹窗入参。
10585
+ * 用于统一数据源、代码块两类历史的查找逻辑。
10586
+ */
10587
+ const findGroupStep = (groups, id, index, build) => {
10504
10588
  for (const group of groups) {
10505
10589
  if (group.id !== id) continue;
10506
10590
  const entry = group.steps.find((s) => s.index === index);
10507
10591
  if (!entry) continue;
10508
- const { oldSchema, newSchema } = entry.step;
10509
- if (!oldSchema || !newSchema) return;
10510
- const currentSchema = dataSourceService.getDataSourceById(`${id}`);
10511
- diffDialogRef.value?.open({
10512
- category: "data-source",
10513
- type: newSchema.type || oldSchema.type || "base",
10514
- lastValue: oldSchema,
10515
- value: newSchema,
10516
- currentValue: currentSchema || null,
10517
- targetLabel: newSchema.title || oldSchema.title || `${id}`,
10518
- id
10519
- });
10520
- return;
10592
+ return build(entry.step);
10521
10593
  }
10594
+ return null;
10595
+ };
10596
+ const buildDataSourceDiffPayload = (id, index) => findGroupStep(historyService.getDataSourceHistoryGroups(), id, index, ({ oldSchema, newSchema }) => {
10597
+ if (!oldSchema || !newSchema) return null;
10598
+ const currentSchema = dataSourceService.getDataSourceById(`${id}`);
10599
+ return {
10600
+ category: "data-source",
10601
+ type: newSchema.type || oldSchema.type || "base",
10602
+ lastValue: oldSchema,
10603
+ value: newSchema,
10604
+ currentValue: currentSchema || null,
10605
+ targetLabel: newSchema.title || oldSchema.title || `${id}`,
10606
+ id
10607
+ };
10608
+ });
10609
+ const buildCodeBlockDiffPayload = (id, index) => findGroupStep(historyService.getCodeBlockHistoryGroups(), id, index, ({ oldContent, newContent }) => {
10610
+ if (!oldContent || !newContent) return null;
10611
+ return {
10612
+ category: "code-block",
10613
+ lastValue: oldContent,
10614
+ value: newContent,
10615
+ currentValue: codeBlockService.getCodeContentById(id) || null,
10616
+ targetLabel: newContent.name || oldContent.name || `${id}`,
10617
+ id
10618
+ };
10619
+ });
10620
+ const onPageDiff = (index) => {
10621
+ const payload = buildPageDiffPayload(index);
10622
+ if (payload) diffDialogRef.value?.open(payload);
10623
+ };
10624
+ const onDataSourceDiff = (id, index) => {
10625
+ const payload = buildDataSourceDiffPayload(id, index);
10626
+ if (payload) diffDialogRef.value?.open(payload);
10522
10627
  };
10523
10628
  const onCodeBlockDiff = (id, index) => {
10524
- const groups = historyService.getCodeBlockHistoryGroups();
10525
- for (const group of groups) {
10526
- if (group.id !== id) continue;
10527
- const entry = group.steps.find((s) => s.index === index);
10528
- if (!entry) continue;
10529
- const { oldContent, newContent } = entry.step;
10530
- if (!oldContent || !newContent) return;
10531
- const currentContent = codeBlockService.getCodeContentById(id);
10532
- diffDialogRef.value?.open({
10533
- category: "code-block",
10534
- lastValue: oldContent,
10535
- value: newContent,
10536
- currentValue: currentContent || null,
10537
- targetLabel: newContent.name || oldContent.name || `${id}`,
10538
- id
10539
- });
10540
- return;
10541
- }
10629
+ const payload = buildCodeBlockDiffPayload(id, index);
10630
+ if (payload) diffDialogRef.value?.open(payload);
10631
+ };
10632
+ const onConfirmRevert = (0, vue.shallowRef)();
10633
+ /**
10634
+ * 「回滚」入口:把目标历史步骤的修改作为一次新操作反向应用(类 git revert),
10635
+ * 不破坏原有栈结构。各 service 内部完成反向 + 入栈,并自带描述用于面板展示。
10636
+ *
10637
+ * 交互:先弹出该步骤的差异弹窗供用户确认,点击「确定回滚」后再真正执行回滚;
10638
+ * 对没有可对比内容的步骤(如 add / remove / 多节点更新)则直接回滚。
10639
+ */
10640
+ const onPageRevert = (index) => {
10641
+ const payload = buildPageDiffPayload(index);
10642
+ onConfirmRevert.value = () => editorService.revertPageStep(index);
10643
+ if (payload) diffDialogRef.value?.open({ ...payload });
10644
+ else onConfirmRevert.value();
10645
+ };
10646
+ const onDataSourceRevert = (id, index) => {
10647
+ const payload = buildDataSourceDiffPayload(id, index);
10648
+ onConfirmRevert.value = () => dataSourceService.revert(id, index);
10649
+ if (payload) diffDialogRef.value?.open({ ...payload });
10650
+ else onConfirmRevert.value();
10651
+ };
10652
+ const onCodeBlockRevert = (id, index) => {
10653
+ const payload = buildCodeBlockDiffPayload(id, index);
10654
+ onConfirmRevert.value = () => codeBlockService.revert(id, index);
10655
+ if (payload) diffDialogRef.value?.open({ ...payload });
10656
+ else onConfirmRevert.value();
10657
+ };
10658
+ const onDiffDialogClose = () => {
10659
+ onConfirmRevert.value = void 0;
10542
10660
  };
10543
10661
  return (_ctx, _cache) => {
10544
10662
  return (0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, null, [(0, vue.createVNode)((0, vue.unref)(_tmagic_design.TMagicPopover), {
@@ -10603,13 +10721,18 @@
10603
10721
  ])]),
10604
10722
  _: 1
10605
10723
  }, 16)),
10606
- ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.resolveDynamicComponent)((0, vue.unref)(tabPaneComponent)?.component || "el-tab-pane"), (0, vue.normalizeProps)((0, vue.guardReactiveProps)((0, vue.unref)(tabPaneComponent)?.props({
10724
+ !disabledDataSource.value ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.resolveDynamicComponent)((0, vue.unref)(tabPaneComponent)?.component || "el-tab-pane"), (0, vue.normalizeProps)((0, vue.mergeProps)({ key: 0 }, (0, vue.unref)(tabPaneComponent)?.props({
10607
10725
  name: "data-source",
10608
10726
  label: `数据源 (${(0, vue.unref)(dataSourceGroups).length})`
10609
10727
  }) || {})), {
10610
- default: (0, vue.withCtx)(() => [(0, vue.createVNode)(DataSourceTab_default, {
10728
+ default: (0, vue.withCtx)(() => [(0, vue.createVNode)(BucketTab_default, {
10729
+ title: "数据源",
10730
+ prefix: "ds",
10611
10731
  buckets: (0, vue.unref)(dataSourceGroupsByTarget),
10612
10732
  expanded: (0, vue.unref)(expanded),
10733
+ "describe-group": (0, vue.unref)(describeDataSourceGroup),
10734
+ "describe-step": (0, vue.unref)(describeDataSourceStep),
10735
+ "is-step-diffable": isDataSourceStepDiffable,
10613
10736
  onToggle: (0, vue.unref)(toggleGroup),
10614
10737
  onGoto: onDataSourceGoto,
10615
10738
  onGotoInitial: onDataSourceGotoInitial,
@@ -10618,17 +10741,24 @@
10618
10741
  }, null, 8, [
10619
10742
  "buckets",
10620
10743
  "expanded",
10744
+ "describe-group",
10745
+ "describe-step",
10621
10746
  "onToggle"
10622
10747
  ])]),
10623
10748
  _: 1
10624
- }, 16)),
10625
- ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.resolveDynamicComponent)((0, vue.unref)(tabPaneComponent)?.component || "el-tab-pane"), (0, vue.normalizeProps)((0, vue.guardReactiveProps)((0, vue.unref)(tabPaneComponent)?.props({
10749
+ }, 16)) : (0, vue.createCommentVNode)("v-if", true),
10750
+ !disabledCodeBlock.value ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.resolveDynamicComponent)((0, vue.unref)(tabPaneComponent)?.component || "el-tab-pane"), (0, vue.normalizeProps)((0, vue.mergeProps)({ key: 1 }, (0, vue.unref)(tabPaneComponent)?.props({
10626
10751
  name: "code-block",
10627
10752
  label: `代码块 (${(0, vue.unref)(codeBlockGroups).length})`
10628
10753
  }) || {})), {
10629
- default: (0, vue.withCtx)(() => [(0, vue.createVNode)(CodeBlockTab_default, {
10754
+ default: (0, vue.withCtx)(() => [(0, vue.createVNode)(BucketTab_default, {
10755
+ title: "代码块",
10756
+ prefix: "cb",
10630
10757
  buckets: (0, vue.unref)(codeBlockGroupsByTarget),
10631
10758
  expanded: (0, vue.unref)(expanded),
10759
+ "describe-group": (0, vue.unref)(describeCodeBlockGroup),
10760
+ "describe-step": (0, vue.unref)(describeCodeBlockStep),
10761
+ "is-step-diffable": isCodeBlockStepDiffable,
10632
10762
  onToggle: (0, vue.unref)(toggleGroup),
10633
10763
  onGoto: onCodeBlockGoto,
10634
10764
  onGotoInitial: onCodeBlockGotoInitial,
@@ -10637,18 +10767,31 @@
10637
10767
  }, null, 8, [
10638
10768
  "buckets",
10639
10769
  "expanded",
10770
+ "describe-group",
10771
+ "describe-step",
10640
10772
  "onToggle"
10641
10773
  ])]),
10642
10774
  _: 1
10643
- }, 16))
10775
+ }, 16)) : (0, vue.createCommentVNode)("v-if", true),
10776
+ ((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)((0, vue.unref)(extraTabs), (tab) => {
10777
+ return (0, vue.openBlock)(), (0, vue.createBlock)((0, vue.resolveDynamicComponent)((0, vue.unref)(tabPaneComponent)?.component || "el-tab-pane"), (0, vue.mergeProps)({ key: tab.name }, { ref_for: true }, (0, vue.unref)(tabPaneComponent)?.props({
10778
+ name: tab.name,
10779
+ label: resolveTabLabel(tab)
10780
+ }) || {}), {
10781
+ default: (0, vue.withCtx)(() => [((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.resolveDynamicComponent)(tab.component), (0, vue.mergeProps)({ ref_for: true }, tab.props || {}, (0, vue.toHandlers)(tab.listeners || {})), null, 16))]),
10782
+ _: 2
10783
+ }, 1040);
10784
+ }), 128))
10644
10785
  ]),
10645
10786
  _: 1
10646
10787
  }, 8, ["modelValue"])])]),
10647
10788
  _: 1
10648
10789
  }, 8, ["visible"]), (0, vue.createVNode)(HistoryDiffDialog_default, {
10649
10790
  ref: "diffDialog",
10650
- "extend-state": (0, vue.unref)(extendFormState)
10651
- }, null, 8, ["extend-state"])], 64);
10791
+ "extend-state": (0, vue.unref)(extendFormState),
10792
+ "on-confirm": onConfirmRevert.value,
10793
+ onClose: onDiffDialogClose
10794
+ }, null, 8, ["extend-state", "on-confirm"])], 64);
10652
10795
  };
10653
10796
  }
10654
10797
  });
@@ -16518,6 +16661,7 @@
16518
16661
  disabledMultiSelect: false,
16519
16662
  alwaysMultiSelect: false,
16520
16663
  disabledPageFragment: false,
16664
+ disabledFlashTip: false,
16521
16665
  disabledStageOverlay: false,
16522
16666
  containerHighlightClassName: _tmagic_stage.CONTAINER_HIGHLIGHT_CLASS_NAME,
16523
16667
  containerHighlightDuration: 800,
@@ -16527,6 +16671,7 @@
16527
16671
  disabledCodeBlock: false,
16528
16672
  componentGroupList: () => [],
16529
16673
  datasourceList: () => [],
16674
+ historyListExtraTabs: () => [],
16530
16675
  menu: () => ({
16531
16676
  left: [],
16532
16677
  right: []
@@ -16967,6 +17112,7 @@
16967
17112
  disabledMultiSelect: { type: Boolean },
16968
17113
  alwaysMultiSelect: { type: Boolean },
16969
17114
  disabledPageFragment: { type: Boolean },
17115
+ disabledFlashTip: { type: Boolean },
16970
17116
  disabledStageOverlay: { type: Boolean },
16971
17117
  disabledShowSrc: { type: Boolean },
16972
17118
  disabledDataSource: { type: Boolean },
@@ -16983,6 +17129,7 @@
16983
17129
  beforeDblclick: { type: Function },
16984
17130
  beforeLayerNodeDblclick: { type: Function },
16985
17131
  extendFormState: { type: Function },
17132
+ historyListExtraTabs: {},
16986
17133
  pageBarSortOptions: {},
16987
17134
  pageFilterFunction: { type: Function }
16988
17135
  }, defaultEditorProps),
@@ -17032,6 +17179,7 @@
17032
17179
  guidesOptions: props.guidesOptions,
17033
17180
  disabledMultiSelect: props.disabledMultiSelect,
17034
17181
  alwaysMultiSelect: props.alwaysMultiSelect,
17182
+ disabledFlashTip: props.disabledFlashTip,
17035
17183
  beforeDblclick: props.beforeDblclick
17036
17184
  };
17037
17185
  stageOverlay_default.set("stageOptions", stageOptions);
@@ -17044,6 +17192,12 @@
17044
17192
  * 与 PropsPanel 通过 `:extend-state` 显式传入的方式保持等价。
17045
17193
  */
17046
17194
  (0, vue.provide)("extendFormState", props.extendFormState);
17195
+ /**
17196
+ * 把历史记录面板的自定义扩展 tab 提供给深层的 HistoryListPanel(它挂在 NavMenu 中,
17197
+ * 以 markRaw component 形式渲染,无法直接通过 props 透传)。业务方可借此在历史记录
17198
+ * 面板内追加自定义模块的历史 tab。
17199
+ */
17200
+ (0, vue.provide)("historyListExtraTabs", props.historyListExtraTabs);
17047
17201
  (0, vue.provide)("eventBus", new events.EventEmitter());
17048
17202
  const propsPanelMountedHandler = (e) => {
17049
17203
  emit("props-panel-mounted", e);
@@ -21552,10 +21706,7 @@
21552
21706
  });
21553
21707
  const modelValue = (0, vue.reactive)({ form: { [props.name]: "" } });
21554
21708
  (0, vue.watch)(() => props.model[props.name], (value) => {
21555
- modelValue.form = { [props.name]: (0, serialize_javascript.default)(value, {
21556
- space: 2,
21557
- unsafe: true
21558
- }).replace(/"(\w+)":\s/g, "$1: ") };
21709
+ modelValue.form = { [props.name]: serializeConfig(value) };
21559
21710
  }, { immediate: true });
21560
21711
  const changeHandler = (v) => {
21561
21712
  if (!props.name || !props.model) return;
@@ -21814,6 +21965,8 @@
21814
21965
  exports.Fixed2Other = Fixed2Other;
21815
21966
  exports.FloatingBox = FloatingBox_default;
21816
21967
  exports.H_GUIDE_LINE_STORAGE_KEY = H_GUIDE_LINE_STORAGE_KEY;
21968
+ exports.HistoryDiffDialog = HistoryDiffDialog_default;
21969
+ exports.HistoryListBucket = Bucket_default;
21817
21970
  exports.Icon = Icon_default;
21818
21971
  exports.IdleTask = IdleTask;
21819
21972
  exports.KeyBindingCommand = KeyBindingCommand;