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

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 (308) hide show
  1. package/dist/es/Editor.vue_vue_type_script_setup_true_lang.js +43 -9
  2. package/dist/es/components/CodeBlockEditor.vue_vue_type_script_setup_true_lang.js +8 -4
  3. package/dist/es/components/CodeParams.vue_vue_type_script_setup_true_lang.js +3 -2
  4. package/dist/es/components/CompareForm.vue_vue_type_script_setup_true_lang.js +22 -98
  5. package/dist/es/components/ContentMenu.vue_vue_type_script_setup_true_lang.js +32 -9
  6. package/dist/es/components/FloatingBox.vue_vue_type_script_setup_true_lang.js +68 -17
  7. package/dist/es/components/Icon.vue_vue_type_script_setup_true_lang.js +1 -1
  8. package/dist/es/components/Resizer.vue_vue_type_script_setup_true_lang.js +1 -1
  9. package/dist/es/components/ScrollBar.js +0 -1
  10. package/dist/es/components/ScrollBar.vue_vue_type_script_setup_true_lang.js +1 -1
  11. package/dist/es/components/ScrollViewer.vue_vue_type_script_setup_true_lang.js +1 -1
  12. package/dist/es/components/SearchInput.vue_vue_type_script_setup_true_lang.js +1 -1
  13. package/dist/es/components/SplitView.vue_vue_type_script_setup_true_lang.js +1 -1
  14. package/dist/es/components/ToolButton.vue_vue_type_script_setup_true_lang.js +7 -7
  15. package/dist/es/components/Tree.vue_vue_type_script_setup_true_lang.js +1 -1
  16. package/dist/es/components/TreeNode.vue_vue_type_script_setup_true_lang.js +1 -1
  17. package/dist/es/components/ViewForm.js +5 -0
  18. package/dist/es/components/ViewForm.vue_vue_type_script_setup_true_lang.js +58 -0
  19. package/dist/es/editorProps.js +9 -1
  20. package/dist/es/fields/Code.vue_vue_type_script_setup_true_lang.js +16 -5
  21. package/dist/es/fields/CodeLink.vue_vue_type_script_setup_true_lang.js +7 -7
  22. package/dist/es/fields/CodeSelect.vue_vue_type_script_setup_true_lang.js +81 -44
  23. package/dist/es/fields/CodeSelectCol.vue_vue_type_script_setup_true_lang.js +10 -3
  24. package/dist/es/fields/CondOpSelect.vue_vue_type_script_setup_true_lang.js +7 -19
  25. package/dist/es/fields/DataSourceFieldSelect/FieldSelect.vue_vue_type_script_setup_true_lang.js +13 -6
  26. package/dist/es/fields/DataSourceFieldSelect/Index.vue_vue_type_script_setup_true_lang.js +11 -8
  27. package/dist/es/fields/DataSourceFields.vue_vue_type_script_setup_true_lang.js +39 -12
  28. package/dist/es/fields/DataSourceInput.vue_vue_type_script_setup_true_lang.js +11 -20
  29. package/dist/es/fields/DataSourceMethodSelect.vue_vue_type_script_setup_true_name_true_lang.js +11 -6
  30. package/dist/es/fields/DataSourceMethods.vue_vue_type_script_setup_true_lang.js +30 -14
  31. package/dist/es/fields/DataSourceMocks.vue_vue_type_script_setup_true_lang.js +11 -4
  32. package/dist/es/fields/DataSourceSelect.vue_vue_type_script_setup_true_lang.js +5 -2
  33. package/dist/es/fields/DisplayConds.vue_vue_type_script_setup_true_lang.js +38 -6
  34. package/dist/es/fields/EventSelect.vue_vue_type_script_setup_true_lang.js +156 -155
  35. package/dist/es/fields/KeyValue.vue_vue_type_script_setup_true_lang.js +5 -2
  36. package/dist/es/fields/PageFragmentSelect.vue_vue_type_script_setup_true_lang.js +5 -2
  37. package/dist/es/fields/StyleSetter/Index.vue_vue_type_script_setup_true_lang.js +8 -10
  38. package/dist/es/fields/StyleSetter/components/BackgroundPosition.vue_vue_type_script_setup_true_lang.js +5 -2
  39. package/dist/es/fields/StyleSetter/components/Border.vue_vue_type_script_setup_true_lang.js +28 -6
  40. package/dist/es/fields/StyleSetter/components/Box.vue_vue_type_script_setup_true_lang.js +1 -1
  41. package/dist/es/fields/StyleSetter/icons/align-items/Center.js +31 -0
  42. package/dist/es/fields/StyleSetter/icons/align-items/FlexEnd.js +31 -0
  43. package/dist/es/fields/StyleSetter/icons/align-items/FlexStart.js +31 -0
  44. package/dist/es/fields/StyleSetter/icons/align-items/SpaceAround.js +50 -0
  45. package/dist/es/fields/StyleSetter/icons/align-items/SpaceBetween.js +50 -0
  46. package/dist/es/fields/StyleSetter/icons/background-repeat/NoRepeat.js +7 -7
  47. package/dist/es/fields/StyleSetter/icons/background-repeat/Repeat.js +6 -3
  48. package/dist/es/fields/StyleSetter/icons/background-repeat/RepeatX.js +29 -6
  49. package/dist/es/fields/StyleSetter/icons/background-repeat/RepeatY.js +32 -6
  50. package/dist/es/fields/StyleSetter/icons/display/Block.js +1 -1
  51. package/dist/es/fields/StyleSetter/icons/display/Flex.js +1 -1
  52. package/dist/es/fields/StyleSetter/icons/display/Inline.js +1 -1
  53. package/dist/es/fields/StyleSetter/icons/display/InlineBlock.js +1 -1
  54. package/dist/es/fields/StyleSetter/icons/display/None.js +1 -1
  55. package/dist/es/fields/StyleSetter/icons/flex-direction/Column.js +11 -3
  56. package/dist/es/fields/StyleSetter/icons/flex-direction/ColumnReverse.js +11 -3
  57. package/dist/es/fields/StyleSetter/icons/flex-direction/Row.js +11 -3
  58. package/dist/es/fields/StyleSetter/icons/flex-direction/RowReverse.js +11 -3
  59. package/dist/es/fields/StyleSetter/icons/justify-content/Center.js +17 -3
  60. package/dist/es/fields/StyleSetter/icons/justify-content/FlexEnd.js +19 -3
  61. package/dist/es/fields/StyleSetter/icons/justify-content/FlexStart.js +19 -3
  62. package/dist/es/fields/StyleSetter/icons/justify-content/SpaceAround.js +37 -3
  63. package/dist/es/fields/StyleSetter/icons/justify-content/SpaceBetween.js +33 -3
  64. package/dist/es/fields/StyleSetter/icons/text-align/Center.js +1 -1
  65. package/dist/es/fields/StyleSetter/icons/text-align/Left.js +1 -1
  66. package/dist/es/fields/StyleSetter/icons/text-align/Right.js +1 -1
  67. package/dist/es/fields/StyleSetter/pro/Background.vue_vue_type_script_setup_true_lang.js +56 -30
  68. package/dist/es/fields/StyleSetter/pro/Border.vue_vue_type_script_setup_true_lang.js +7 -4
  69. package/dist/es/fields/StyleSetter/pro/Font.vue_vue_type_script_setup_true_lang.js +35 -26
  70. package/dist/es/fields/StyleSetter/pro/Layout.vue_vue_type_script_setup_true_lang.js +76 -48
  71. package/dist/es/fields/StyleSetter/pro/Position.vue_vue_type_script_setup_true_lang.js +29 -23
  72. package/dist/es/fields/StyleSetter/pro/Transform.vue_vue_type_script_setup_true_lang.js +7 -4
  73. package/dist/es/fields/UISelect.js +0 -1
  74. package/dist/es/fields/UISelect.vue_vue_type_script_setup_true_lang.js +5 -2
  75. package/dist/es/hooks/use-code-block-edit.js +6 -3
  76. package/dist/es/hooks/use-compare-form.js +119 -0
  77. package/dist/es/hooks/use-data-source-edit.js +5 -2
  78. package/dist/es/hooks/use-stage.js +9 -4
  79. package/dist/es/icons/CenterIcon.vue_vue_type_script_setup_true_lang.js +1 -1
  80. package/dist/es/icons/CodeIcon.vue_vue_type_script_setup_true_lang.js +1 -1
  81. package/dist/es/icons/DatasourceIcon.js +17 -0
  82. package/dist/es/icons/FolderMinusIcon.vue_vue_type_script_setup_true_lang.js +1 -1
  83. package/dist/es/index.js +24 -10
  84. package/dist/es/initService.js +19 -13
  85. package/dist/es/layouts/AddPageBox.vue_vue_type_script_setup_true_lang.js +1 -1
  86. package/dist/es/layouts/CodeEditor.vue_vue_type_script_setup_true_lang.js +24 -12
  87. package/dist/es/layouts/Framework.vue_vue_type_script_setup_true_lang.js +25 -18
  88. package/dist/es/layouts/NavMenu.vue_vue_type_script_setup_true_lang.js +4 -4
  89. package/dist/es/layouts/NavMenuColumn.vue_vue_type_script_setup_true_lang.js +1 -1
  90. package/dist/es/layouts/history-list/Bucket.vue_vue_type_script_setup_true_lang.js +25 -38
  91. package/dist/es/layouts/history-list/BucketTab.js +5 -0
  92. package/dist/es/layouts/history-list/BucketTab.vue_vue_type_script_setup_true_lang.js +62 -0
  93. package/dist/es/layouts/history-list/GroupRow.vue_vue_type_script_setup_true_lang.js +177 -88
  94. package/dist/es/layouts/history-list/HistoryDiffDialog.vue_vue_type_script_setup_true_lang.js +139 -37
  95. package/dist/es/layouts/history-list/HistoryListPanel.vue_vue_type_script_setup_true_lang.js +164 -107
  96. package/dist/es/layouts/history-list/InitialRow.vue_vue_type_script_setup_true_lang.js +44 -9
  97. package/dist/es/layouts/history-list/PageTab.vue_vue_type_script_setup_true_lang.js +49 -53
  98. package/dist/es/layouts/history-list/composables.js +138 -108
  99. package/dist/es/layouts/history-list/useHistoryList.js +56 -0
  100. package/dist/es/layouts/history-list/useHistoryRevert.js +317 -0
  101. package/dist/es/layouts/page-bar/AddButton.vue_vue_type_script_setup_true_lang.js +1 -1
  102. package/dist/es/layouts/page-bar/PageBar.vue_vue_type_script_setup_true_lang.js +5 -3
  103. package/dist/es/layouts/page-bar/PageBarScrollContainer.vue_vue_type_script_setup_true_lang.js +1 -1
  104. package/dist/es/layouts/page-bar/PageList.vue_vue_type_script_setup_true_lang.js +1 -1
  105. package/dist/es/layouts/page-bar/Search.vue_vue_type_script_setup_true_lang.js +2 -2
  106. package/dist/es/layouts/props-panel/FormPanel.vue_vue_type_script_setup_true_lang.js +50 -7
  107. package/dist/es/layouts/props-panel/PropsPanel.vue_vue_type_script_setup_true_lang.js +33 -13
  108. package/dist/es/layouts/props-panel/use-style-panel.js +3 -2
  109. package/dist/es/layouts/sidebar/ComponentListPanel.vue_vue_type_script_setup_true_lang.js +3 -3
  110. package/dist/es/layouts/sidebar/Sidebar.vue_vue_type_script_setup_true_lang.js +26 -38
  111. package/dist/es/layouts/sidebar/code-block/CodeBlockList.vue_vue_type_script_setup_true_lang.js +4 -4
  112. package/dist/es/layouts/sidebar/code-block/CodeBlockListPanel.vue_vue_type_script_setup_true_lang.js +4 -4
  113. package/dist/es/layouts/sidebar/code-block/useContentMenu.js +19 -4
  114. package/dist/es/layouts/sidebar/data-source/DataSourceAddButton.vue_vue_type_script_setup_true_lang.js +1 -1
  115. package/dist/es/layouts/sidebar/data-source/DataSourceConfigPanel.vue_vue_type_script_setup_true_lang.js +23 -6
  116. package/dist/es/layouts/sidebar/data-source/DataSourceList.vue_vue_type_script_setup_true_lang.js +1 -1
  117. package/dist/es/layouts/sidebar/data-source/DataSourceListPanel.vue_vue_type_script_setup_true_lang.js +27 -5
  118. package/dist/es/layouts/sidebar/data-source/useContentMenu.js +19 -4
  119. package/dist/es/layouts/sidebar/layer/LayerMenu.vue_vue_type_script_setup_true_lang.js +8 -8
  120. package/dist/es/layouts/sidebar/layer/LayerNodeContent.js +5 -0
  121. package/dist/es/layouts/sidebar/layer/LayerNodeContent.vue_vue_type_script_setup_true_lang.js +46 -0
  122. package/dist/es/layouts/sidebar/layer/LayerNodeTool.vue_vue_type_script_setup_true_lang.js +2 -2
  123. package/dist/es/layouts/sidebar/layer/LayerPanel.vue_vue_type_script_setup_true_lang.js +3 -2
  124. package/dist/es/layouts/sidebar/layer/use-click.js +3 -3
  125. package/dist/es/layouts/sidebar/layer/use-node-status.js +2 -2
  126. package/dist/es/layouts/workspace/Breadcrumb.vue_vue_type_script_setup_true_lang.js +1 -1
  127. package/dist/es/layouts/workspace/Workspace.vue_vue_type_script_setup_true_lang.js +1 -1
  128. package/dist/es/layouts/workspace/viewer/NodeListMenu.vue_vue_type_script_setup_true_lang.js +9 -3
  129. package/dist/es/layouts/workspace/viewer/Stage.vue_vue_type_script_setup_true_lang.js +2 -2
  130. package/dist/es/layouts/workspace/viewer/StageOverlay.vue_vue_type_script_setup_true_lang.js +1 -1
  131. package/dist/es/layouts/workspace/viewer/ViewerMenu.vue_vue_type_script_setup_true_lang.js +16 -16
  132. package/dist/es/plugin.js +5 -2
  133. package/dist/es/services/codeBlock.js +137 -56
  134. package/dist/es/services/dataSource.js +122 -52
  135. package/dist/es/services/dep.js +162 -41
  136. package/dist/es/services/editor.js +613 -179
  137. package/dist/es/services/events.js +2 -2
  138. package/dist/es/services/history.js +350 -386
  139. package/dist/es/services/keybinding.js +6 -6
  140. package/dist/es/services/props.js +3 -2
  141. package/dist/es/services/storage.js +2 -2
  142. package/dist/es/services/ui.js +10 -2
  143. package/dist/es/style.css +549 -113
  144. package/dist/es/utils/config.js +4 -1
  145. package/dist/es/utils/const.js +2 -2
  146. package/dist/es/utils/content-menu.js +19 -11
  147. package/dist/es/utils/data-source/index.js +34 -11
  148. package/dist/es/utils/dep/collect-worker-client.js +114 -0
  149. package/dist/es/utils/dep/idle-task.js +70 -22
  150. package/dist/es/utils/dep/worker.js +1 -1
  151. package/dist/es/utils/editor.js +103 -49
  152. package/dist/es/utils/event.js +135 -0
  153. package/dist/es/utils/history.js +220 -0
  154. package/dist/es/utils/indexed-db.js +86 -0
  155. package/dist/es/utils/monaco-editor.js +22 -6
  156. package/dist/es/utils/operator.js +2 -2
  157. package/dist/es/utils/props.js +114 -33
  158. package/dist/es/utils/type-match-rules.js +367 -0
  159. package/dist/es/utils/undo-redo.js +60 -1
  160. package/dist/style.css +549 -113
  161. package/dist/themes/magic-admin.css +3028 -0
  162. package/dist/tmagic-editor.umd.cjs +14403 -10121
  163. package/package.json +8 -8
  164. package/src/Editor.vue +43 -2
  165. package/src/components/CodeBlockEditor.vue +3 -0
  166. package/src/components/CompareForm.vue +18 -146
  167. package/src/components/ContentMenu.vue +44 -8
  168. package/src/components/FloatingBox.vue +84 -9
  169. package/src/components/ScrollBar.vue +0 -67
  170. package/src/components/ToolButton.vue +2 -2
  171. package/src/components/ViewForm.vue +55 -0
  172. package/src/editorProps.ts +30 -0
  173. package/src/fields/Code.vue +10 -2
  174. package/src/fields/CodeLink.vue +2 -5
  175. package/src/fields/CodeSelect.vue +54 -40
  176. package/src/fields/CodeSelectCol.vue +8 -1
  177. package/src/fields/CondOpSelect.vue +2 -24
  178. package/src/fields/DataSourceFieldSelect/FieldSelect.vue +16 -2
  179. package/src/fields/DataSourceFieldSelect/Index.vue +14 -5
  180. package/src/fields/DataSourceFields.vue +42 -8
  181. package/src/fields/DataSourceInput.vue +10 -28
  182. package/src/fields/DataSourceMethodSelect.vue +9 -4
  183. package/src/fields/DataSourceMethods.vue +42 -21
  184. package/src/fields/DataSourceMocks.vue +3 -0
  185. package/src/fields/DisplayConds.vue +18 -1
  186. package/src/fields/EventSelect.vue +152 -166
  187. package/src/fields/StyleSetter/Index.vue +3 -12
  188. package/src/fields/StyleSetter/components/Border.vue +15 -6
  189. package/src/fields/StyleSetter/icons/align-items/Center.vue +19 -0
  190. package/src/fields/StyleSetter/icons/align-items/FlexEnd.vue +19 -0
  191. package/src/fields/StyleSetter/icons/align-items/FlexStart.vue +19 -0
  192. package/src/fields/StyleSetter/icons/align-items/SpaceAround.vue +34 -0
  193. package/src/fields/StyleSetter/icons/align-items/SpaceBetween.vue +34 -0
  194. package/src/fields/StyleSetter/icons/align-items/index.ts +5 -0
  195. package/src/fields/StyleSetter/icons/background-repeat/NoRepeat.vue +20 -4
  196. package/src/fields/StyleSetter/icons/background-repeat/Repeat.vue +10 -28
  197. package/src/fields/StyleSetter/icons/background-repeat/RepeatX.vue +4 -5
  198. package/src/fields/StyleSetter/icons/background-repeat/RepeatY.vue +4 -5
  199. package/src/fields/StyleSetter/icons/flex-direction/Column.vue +4 -3
  200. package/src/fields/StyleSetter/icons/flex-direction/ColumnReverse.vue +4 -3
  201. package/src/fields/StyleSetter/icons/flex-direction/Row.vue +4 -3
  202. package/src/fields/StyleSetter/icons/flex-direction/RowReverse.vue +4 -3
  203. package/src/fields/StyleSetter/icons/justify-content/Center.vue +5 -2
  204. package/src/fields/StyleSetter/icons/justify-content/FlexEnd.vue +15 -2
  205. package/src/fields/StyleSetter/icons/justify-content/FlexStart.vue +15 -2
  206. package/src/fields/StyleSetter/icons/justify-content/SpaceAround.vue +28 -3
  207. package/src/fields/StyleSetter/icons/justify-content/SpaceBetween.vue +28 -2
  208. package/src/fields/StyleSetter/pro/Background.vue +99 -55
  209. package/src/fields/StyleSetter/pro/Border.vue +9 -11
  210. package/src/fields/StyleSetter/pro/Font.vue +66 -64
  211. package/src/fields/StyleSetter/pro/Layout.vue +211 -139
  212. package/src/fields/StyleSetter/pro/Position.vue +69 -67
  213. package/src/fields/StyleSetter/pro/Transform.vue +23 -25
  214. package/src/fields/UISelect.vue +0 -12
  215. package/src/hooks/index.ts +1 -0
  216. package/src/hooks/use-code-block-edit.ts +4 -3
  217. package/src/hooks/use-compare-form.ts +187 -0
  218. package/src/hooks/use-data-source-edit.ts +2 -2
  219. package/src/hooks/use-stage.ts +5 -3
  220. package/src/icons/DatasourceIcon.vue +7 -0
  221. package/src/index.ts +12 -0
  222. package/src/initService.ts +26 -16
  223. package/src/layouts/CodeEditor.vue +34 -11
  224. package/src/layouts/Framework.vue +15 -8
  225. package/src/layouts/NavMenu.vue +3 -3
  226. package/src/layouts/history-list/Bucket.vue +33 -41
  227. package/src/layouts/history-list/BucketTab.vue +72 -0
  228. package/src/layouts/history-list/GroupRow.vue +190 -93
  229. package/src/layouts/history-list/HistoryDiffDialog.vue +169 -90
  230. package/src/layouts/history-list/HistoryListPanel.vue +191 -95
  231. package/src/layouts/history-list/InitialRow.vue +38 -8
  232. package/src/layouts/history-list/PageTab.vue +67 -43
  233. package/src/layouts/history-list/composables.ts +239 -125
  234. package/src/layouts/history-list/useHistoryList.ts +60 -0
  235. package/src/layouts/history-list/useHistoryRevert.ts +425 -0
  236. package/src/layouts/page-bar/PageBar.vue +4 -2
  237. package/src/layouts/props-panel/FormPanel.vue +72 -6
  238. package/src/layouts/props-panel/PropsPanel.vue +62 -18
  239. package/src/layouts/props-panel/use-style-panel.ts +4 -3
  240. package/src/layouts/sidebar/ComponentListPanel.vue +10 -6
  241. package/src/layouts/sidebar/Sidebar.vue +13 -6
  242. package/src/layouts/sidebar/code-block/CodeBlockList.vue +5 -5
  243. package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +5 -2
  244. package/src/layouts/sidebar/code-block/useContentMenu.ts +14 -2
  245. package/src/layouts/sidebar/data-source/DataSourceConfigPanel.vue +34 -2
  246. package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +29 -4
  247. package/src/layouts/sidebar/data-source/useContentMenu.ts +14 -2
  248. package/src/layouts/sidebar/layer/LayerMenu.vue +21 -13
  249. package/src/layouts/sidebar/layer/LayerNodeContent.vue +57 -0
  250. package/src/layouts/sidebar/layer/LayerNodeTool.vue +7 -4
  251. package/src/layouts/sidebar/layer/LayerPanel.vue +4 -1
  252. package/src/layouts/sidebar/layer/use-click.ts +3 -3
  253. package/src/layouts/sidebar/layer/use-node-status.ts +2 -2
  254. package/src/layouts/workspace/viewer/NodeListMenu.vue +4 -1
  255. package/src/layouts/workspace/viewer/Stage.vue +1 -1
  256. package/src/layouts/workspace/viewer/ViewerMenu.vue +15 -15
  257. package/src/plugin.ts +6 -3
  258. package/src/services/codeBlock.ts +152 -47
  259. package/src/services/dataSource.ts +120 -41
  260. package/src/services/dep.ts +292 -47
  261. package/src/services/editor.ts +820 -224
  262. package/src/services/events.ts +3 -3
  263. package/src/services/history.ts +449 -412
  264. package/src/services/keybinding.ts +6 -6
  265. package/src/services/ui.ts +33 -5
  266. package/src/theme/code-block.scss +37 -0
  267. package/src/theme/common/var.scss +1 -1
  268. package/src/theme/component-list-panel.scss +2 -2
  269. package/src/theme/data-source-field.scss +4 -0
  270. package/src/theme/display-conds.scss +11 -0
  271. package/src/theme/event.scss +70 -1
  272. package/src/theme/floating-box.scss +9 -1
  273. package/src/theme/framework.scss +4 -1
  274. package/src/theme/history-list-panel.scss +157 -23
  275. package/src/theme/layer-node-content.scss +14 -0
  276. package/src/theme/nav-menu.scss +5 -1
  277. package/src/theme/page-bar.scss +0 -4
  278. package/src/theme/props-panel.scss +5 -4
  279. package/src/theme/scroll-bar.scss +64 -0
  280. package/src/theme/style-setter/border.scss +17 -5
  281. package/src/theme/theme.scss +4 -0
  282. package/src/theme/themes/magic-admin/index.scss +214 -0
  283. package/src/theme/ui-select.scss +9 -0
  284. package/src/type.ts +668 -124
  285. package/src/utils/config.ts +9 -1
  286. package/src/utils/const.ts +3 -2
  287. package/src/utils/content-menu.ts +20 -11
  288. package/src/utils/data-source/index.ts +32 -12
  289. package/src/utils/dep/collect-worker-client.ts +149 -0
  290. package/src/utils/dep/idle-task.ts +104 -35
  291. package/src/utils/dep/worker.ts +113 -9
  292. package/src/utils/editor.ts +166 -60
  293. package/src/utils/event.ts +237 -0
  294. package/src/utils/history.ts +286 -0
  295. package/src/utils/index.ts +4 -0
  296. package/src/utils/indexed-db.ts +122 -0
  297. package/src/utils/monaco-editor.ts +27 -0
  298. package/src/utils/operator.ts +2 -2
  299. package/src/utils/props.ts +114 -11
  300. package/src/utils/type-match-rules.ts +684 -0
  301. package/src/utils/undo-redo.ts +88 -0
  302. package/types/index.d.ts +1990 -517
  303. package/dist/es/layouts/history-list/CodeBlockTab.js +0 -5
  304. package/dist/es/layouts/history-list/CodeBlockTab.vue_vue_type_script_setup_true_lang.js +0 -62
  305. package/dist/es/layouts/history-list/DataSourceTab.js +0 -5
  306. package/dist/es/layouts/history-list/DataSourceTab.vue_vue_type_script_setup_true_lang.js +0 -62
  307. package/src/layouts/history-list/CodeBlockTab.vue +0 -61
  308. package/src/layouts/history-list/DataSourceTab.vue +0 -61
@@ -55,7 +55,7 @@ export const initServiceState = (
55
55
  watch(
56
56
  () => props.modelValue,
57
57
  (modelValue) => {
58
- editorService.set('root', modelValue || null);
58
+ editorService.set('root', modelValue || null, { historySource: 'initial' });
59
59
  },
60
60
  {
61
61
  immediate: true,
@@ -333,11 +333,11 @@ export const initServiceEvents = (
333
333
  Promise.all(
334
334
  nodes.map((node) => {
335
335
  if (node.type === NodeType.ROOT) {
336
- return Promise.resolve();
336
+ return Promise.resolve(true);
337
337
  }
338
338
  return depService.collectIdle([node], { pageId: getPageIdByNode(node) }, deep, type);
339
339
  }),
340
- );
340
+ ).then((results) => results.every(Boolean));
341
341
 
342
342
  watch(
343
343
  () => editorService.get('stage'),
@@ -351,7 +351,7 @@ export const initServiceEvents = (
351
351
 
352
352
  if (!node) return;
353
353
 
354
- await collectIdle([node], true, DepTargetType.DATA_SOURCE);
354
+ if (!(await collectIdle([node], true, DepTargetType.DATA_SOURCE))) return;
355
355
  updateStageNode(node);
356
356
  });
357
357
  },
@@ -494,8 +494,10 @@ export const initServiceEvents = (
494
494
 
495
495
  // 新增节点,收集依赖
496
496
  const nodeAddHandler = (nodes: MComponent[]) => {
497
- collectIdle(nodes, true).then(() => {
498
- updateStageNodes(nodes);
497
+ collectIdle(nodes, true).then((completed) => {
498
+ if (completed) {
499
+ updateStageNodes(nodes);
500
+ }
499
501
  });
500
502
  };
501
503
 
@@ -549,8 +551,8 @@ export const initServiceEvents = (
549
551
  if (needRecollectNodes.length) {
550
552
  // 有数据源依赖,需要等依赖重新收集完才更新stage
551
553
  const handler = async () => {
552
- await collectIdle(needRecollectNodes, true, DepTargetType.DATA_SOURCE);
553
- await collectIdle(needRecollectNodes, true, DepTargetType.DATA_SOURCE_COND);
554
+ if (!(await collectIdle(needRecollectNodes, true, DepTargetType.DATA_SOURCE))) return;
555
+ if (!(await collectIdle(needRecollectNodes, true, DepTargetType.DATA_SOURCE_COND))) return;
554
556
  updateStageNodes(needRecollectNodes);
555
557
  };
556
558
  handler();
@@ -572,8 +574,10 @@ export const initServiceEvents = (
572
574
 
573
575
  // 历史记录变化时,需要重新收集依赖
574
576
  const historyChangeHandler = (page: MPage | MPageFragment) => {
575
- collectIdle([page], true).then(() => {
576
- updateStageNode(page);
577
+ collectIdle([page], true).then((completed) => {
578
+ if (completed) {
579
+ updateStageNode(page);
580
+ }
577
581
  });
578
582
  };
579
583
 
@@ -654,7 +658,7 @@ export const initServiceEvents = (
654
658
  if (Array.isArray(root?.items)) {
655
659
  depService.clearIdleTasks();
656
660
 
657
- let collectIdlePromises: Promise<void[]>[] = [];
661
+ let collectIdlePromises: Promise<boolean>[] = [];
658
662
  if (isModifyField) {
659
663
  depService.removeTarget(config.id, DepTargetType.DATA_SOURCE);
660
664
  depService.removeTarget(config.id, DepTargetType.DATA_SOURCE_COND);
@@ -679,10 +683,15 @@ export const initServiceEvents = (
679
683
 
680
684
  collectIdlePromises = [collectIdle(root.items, true, DepTargetType.DATA_SOURCE_METHOD)];
681
685
  }
682
- Promise.all(collectIdlePromises)
683
- .then(() => updateDataSourceSchema())
684
- .then(() => updateDsData())
685
- .then(() => updateStageNodes(root.items));
686
+ const handler = async () => {
687
+ const results = await Promise.all(collectIdlePromises);
688
+ if (!results.every(Boolean)) return;
689
+
690
+ updateDataSourceSchema();
691
+ await updateDsData();
692
+ updateStageNodes(root.items);
693
+ };
694
+ handler();
686
695
  }
687
696
  } else if (root?.dataSources) {
688
697
  updateDsData();
@@ -706,11 +715,12 @@ export const initServiceEvents = (
706
715
  const nodeIds = Object.keys(root.dataSourceDeps?.[id] || {});
707
716
  const nodes = getNodes(nodeIds, root.items);
708
717
 
709
- await Promise.all([
718
+ const results = await Promise.all([
710
719
  collectIdle(nodes, false, DepTargetType.DATA_SOURCE),
711
720
  collectIdle(nodes, false, DepTargetType.DATA_SOURCE_COND),
712
721
  collectIdle(nodes, false, DepTargetType.DATA_SOURCE_METHOD),
713
722
  ]);
723
+ if (!results.every(Boolean)) return;
714
724
 
715
725
  updateDataSourceSchema();
716
726
 
@@ -21,12 +21,12 @@ import { computed, nextTick, onBeforeUnmount, onMounted, onUnmounted, ref, useTe
21
21
  import { FullScreen } from '@element-plus/icons-vue';
22
22
  import { throttle } from 'lodash-es';
23
23
  import type * as Monaco from 'monaco-editor';
24
- import serialize from 'serialize-javascript';
25
24
 
26
25
  import { TMagicButton } from '@tmagic/design';
27
26
 
28
27
  import MIcon from '@editor/components/Icon.vue';
29
28
  import { getEditorConfig } from '@editor/utils/config';
29
+ import { serializeConfig } from '@editor/utils/editor';
30
30
  import loadMonaco from '@editor/utils/monaco-editor';
31
31
 
32
32
  defineOptions({
@@ -163,10 +163,7 @@ const toString = (v: string | any, language: string): string => {
163
163
  if (language === 'json') {
164
164
  value = JSON.stringify(v, null, 2);
165
165
  } else {
166
- value = serialize(v, {
167
- space: 2,
168
- unsafe: true,
169
- }).replace(/"(\w+)":\s/g, '$1: ');
166
+ value = serializeConfig(v);
170
167
  }
171
168
  } else {
172
169
  value = v;
@@ -197,6 +194,9 @@ const values = ref('');
197
194
  const loading = ref(false);
198
195
  const codeEditorEl = useTemplateRef<HTMLDivElement>('codeEditor');
199
196
 
197
+ // 组件是否已卸载,避免异步初始化过程中组件被销毁后继续创建编辑器
198
+ let destroyed = false;
199
+
200
200
  const resizeObserver = new globalThis.ResizeObserver(
201
201
  throttle((): void => {
202
202
  vsEditor?.layout();
@@ -257,11 +257,18 @@ const handleKeyDown = (e: KeyboardEvent) => {
257
257
  }
258
258
  };
259
259
 
260
+ // 判断容器是否仍然有效:组件未卸载、ref 存在且已挂载到文档树中
261
+ // Monaco 在创建编辑器时会向上遍历 parentNode 判断是否处于 shadow DOM,
262
+ // 若容器为 null 或已从文档树脱离,将抛出 "Cannot read properties of null (reading 'parentNode')"
263
+ const isEditorElValid = () => !destroyed && !!codeEditorEl.value && codeEditorEl.value.isConnected;
264
+
260
265
  const init = async () => {
261
- if (!codeEditorEl.value) return;
266
+ if (!isEditorElValid()) return;
262
267
 
263
- if (codeEditorEl.value.clientHeight === 0) {
268
+ if (codeEditorEl.value!.clientHeight === 0) {
264
269
  await nextTick();
270
+ // await 期间组件可能已被卸载或容器被移除
271
+ if (!isEditorElValid()) return;
265
272
  }
266
273
 
267
274
  // 重置缓存的额外高度,因为编辑器重新初始化
@@ -269,6 +276,11 @@ const init = async () => {
269
276
 
270
277
  monaco = await loadMonaco();
271
278
 
279
+ // 加载 monaco 是异步过程,期间组件可能已被卸载或容器被移除
280
+ if (!isEditorElValid()) return;
281
+
282
+ const editorEl = codeEditorEl.value!;
283
+
272
284
  const options = {
273
285
  value: values.value,
274
286
  language: props.language,
@@ -278,7 +290,7 @@ const init = async () => {
278
290
  };
279
291
 
280
292
  if (props.type === 'diff') {
281
- vsDiffEditor = await getEditorConfig('customCreateMonacoDiffEditor')(monaco!, codeEditorEl.value, options);
293
+ vsDiffEditor = await getEditorConfig('customCreateMonacoDiffEditor')(monaco!, editorEl, options);
282
294
 
283
295
  // 监听diff编辑器内容变化
284
296
  vsDiffEditor.getModifiedEditor().onDidChangeModelContent(() => {
@@ -288,7 +300,7 @@ const init = async () => {
288
300
  }
289
301
  });
290
302
  } else {
291
- vsEditor = await getEditorConfig('customCreateMonacoEditor')(monaco!, codeEditorEl.value, options);
303
+ vsEditor = await getEditorConfig('customCreateMonacoEditor')(monaco!, editorEl, options);
292
304
 
293
305
  // 监听编辑器内容变化
294
306
  vsEditor.onDidChangeModelContent(() => {
@@ -299,10 +311,19 @@ const init = async () => {
299
311
  });
300
312
  }
301
313
 
314
+ // 编辑器创建可能是异步的,创建完成后若组件已卸载则立即销毁,避免内存泄漏
315
+ if (destroyed) {
316
+ vsEditor?.dispose();
317
+ vsDiffEditor?.dispose();
318
+ vsEditor = null;
319
+ vsDiffEditor = null;
320
+ return;
321
+ }
322
+
302
323
  setEditorValue(props.initValues, props.modifiedValues);
303
324
 
304
325
  emit('initd', vsEditor);
305
- codeEditorEl.value.addEventListener('keydown', handleKeyDown);
326
+ editorEl.addEventListener('keydown', handleKeyDown);
306
327
 
307
328
  if (props.type !== 'diff' && props.autoSave) {
308
329
  vsEditor?.onDidBlurEditorWidget(() => {
@@ -314,7 +335,7 @@ const init = async () => {
314
335
  });
315
336
  }
316
337
 
317
- resizeObserver.observe(codeEditorEl.value);
338
+ resizeObserver.observe(editorEl);
318
339
  };
319
340
 
320
341
  watch(
@@ -365,6 +386,8 @@ onMounted(async () => {
365
386
  });
366
387
 
367
388
  onBeforeUnmount(() => {
389
+ destroyed = true;
390
+
368
391
  resizeObserver.disconnect();
369
392
 
370
393
  vsEditor?.dispose();
@@ -1,5 +1,9 @@
1
1
  <template>
2
- <div class="m-editor" ref="content" style="min-width: 900px">
2
+ <div
3
+ ref="content"
4
+ :class="['m-editor', theme ? `m-editor--${theme}` : '', theme ? `m-theme--${theme}` : '']"
5
+ style="min-width: 900px"
6
+ >
3
7
  <slot name="header"></slot>
4
8
 
5
9
  <slot name="nav"></slot>
@@ -25,9 +29,9 @@
25
29
  right-class="m-editor-framework-right"
26
30
  :left="hideSidebar ? undefined : columnWidth.left"
27
31
  :right="columnWidth.right"
28
- :min-left="hideSidebar ? 0 : MIN_LEFT_COLUMN_WIDTH"
29
- :min-right="MIN_RIGHT_COLUMN_WIDTH"
30
- :min-center="MIN_CENTER_COLUMN_WIDTH"
32
+ :min-left="hideSidebar ? 0 : minLeftColumnWidth"
33
+ :min-right="minRightColumnWidth"
34
+ :min-center="minCenterColumnWidth"
31
35
  :width="frameworkRect.width"
32
36
  @change="columnWidthChange"
33
37
  >
@@ -78,9 +82,6 @@ import { getEditorConfig } from '@editor/utils/config';
78
82
  import {
79
83
  DEFAULT_LEFT_COLUMN_WIDTH,
80
84
  LEFT_COLUMN_WIDTH_STORAGE_KEY,
81
- MIN_CENTER_COLUMN_WIDTH,
82
- MIN_LEFT_COLUMN_WIDTH,
83
- MIN_RIGHT_COLUMN_WIDTH,
84
85
  RIGHT_COLUMN_WIDTH_STORAGE_KEY,
85
86
  } from '@editor/utils/const';
86
87
 
@@ -100,6 +101,8 @@ const props = defineProps<{
100
101
  pageFilterFunction?: (_page: MPage | MPageFragment, _keyword: string) => boolean;
101
102
  /** 是否隐藏左侧面板 */
102
103
  hideSidebar?: boolean;
104
+ /** 主题名称,会在根节点追加 `m-editor--<theme>` 修饰类 */
105
+ theme?: string;
103
106
  }>();
104
107
 
105
108
  const codeOptions = inject('codeOptions', {});
@@ -116,6 +119,10 @@ const showSrc = computed(() => uiService.get('showSrc'));
116
119
 
117
120
  const columnWidth = computed(() => uiService.get('columnWidth'));
118
121
 
122
+ const minLeftColumnWidth = computed(() => uiService.get('minLeftColumnWidth'));
123
+ const minCenterColumnWidth = computed(() => uiService.get('minCenterColumnWidth'));
124
+ const minRightColumnWidth = computed(() => uiService.get('minRightColumnWidth'));
125
+
119
126
  watch(pageLength, () => {
120
127
  splitViewRef.value?.updateWidth();
121
128
  });
@@ -168,7 +175,7 @@ onBeforeUnmount(() => {
168
175
  const saveCode = (value: string) => {
169
176
  try {
170
177
  const parseDSL = getEditorConfig('parseDSL');
171
- editorService.set('root', parseDSL(value));
178
+ editorService.set('root', parseDSL(value), { historySource: 'root-code' });
172
179
  } catch (e: any) {
173
180
  console.error(e);
174
181
  }
@@ -80,7 +80,7 @@ const getConfig = (item: MenuItem): (MenuButton | MenuComponent)[] => {
80
80
  disabled: () => editorService.get('node')?.type === NodeType.PAGE,
81
81
  handler: () => {
82
82
  const node = editorService.get('node');
83
- node && editorService.remove(node);
83
+ node && editorService.remove(node, { historySource: 'toolbar' });
84
84
  },
85
85
  });
86
86
  break;
@@ -90,7 +90,7 @@ const getConfig = (item: MenuItem): (MenuButton | MenuComponent)[] => {
90
90
  className: 'undo',
91
91
  icon: markRaw(Back),
92
92
  tooltip: `后退(${ctrl}+z)`,
93
- disabled: () => !historyService.state.canUndo,
93
+ disabled: () => !historyService.canUndo('page', editorService.get('page')?.id),
94
94
  handler: () => editorService.undo(),
95
95
  });
96
96
  break;
@@ -100,7 +100,7 @@ const getConfig = (item: MenuItem): (MenuButton | MenuComponent)[] => {
100
100
  className: 'redo',
101
101
  icon: markRaw(Right),
102
102
  tooltip: `前进(${ctrl}+Shift+z)`,
103
- disabled: () => !historyService.state.canRedo,
103
+ disabled: () => !historyService.canRedo('page', editorService.get('page')?.id),
104
104
  handler: () => editorService.redo(),
105
105
  });
106
106
  break;
@@ -1,33 +1,18 @@
1
1
  <template>
2
2
  <div class="m-editor-history-list-bucket">
3
3
  <div class="m-editor-history-list-bucket-title">
4
- <span>{{ title }}</span>
4
+ <span>{{ config.title }}</span>
5
5
  <code>{{ String(bucketId) }}</code>
6
6
  <span class="m-editor-history-list-bucket-count">{{ groups.length }} 组</span>
7
7
  </div>
8
8
 
9
9
  <ul class="m-editor-history-list-ul">
10
10
  <GroupRow
11
- v-for="(group, gIdx) in groups"
12
- :key="`${prefix}-${bucketId}-${gIdx}`"
13
- :group-key="`${prefix}-${bucketId}-${gIdx}`"
14
- :applied="group.applied"
15
- :merged="group.steps.length > 1"
16
- :op-type="group.opType"
17
- :desc="describeGroup(group)"
18
- :step-count="group.steps.length"
19
- :sub-steps="
20
- group.steps.map((s: any) => ({
21
- index: s.index,
22
- applied: s.applied,
23
- isCurrent: s.isCurrent,
24
- desc: describeStep(s.step),
25
- diffable: isStepDiffable ? isStepDiffable(s.step) : false,
26
- revertable: s.applied,
27
- }))
28
- "
29
- :is-current="group.isCurrent"
30
- :expanded="!!expanded[`${prefix}-${bucketId}-${gIdx}`]"
11
+ v-for="group in groups"
12
+ :key="rowKey(group)"
13
+ :group="toRow(group)"
14
+ :expanded="isHistoryGroupExpanded(expanded, rowKey(group))"
15
+ :goto-enabled="config.gotoEnabled"
31
16
  @toggle="(key: string) => $emit('toggle', key)"
32
17
  @goto="(index: number) => $emit('goto', bucketId, index)"
33
18
  @diff-step="(index: number) => $emit('diff-step', bucketId, index)"
@@ -36,17 +21,25 @@
36
21
  <!--
37
22
  初始状态项:永远位于该 bucket 列表底部(同样按倒序展示,最底部 = 最早状态)。
38
23
  当 bucket 内所有 group 都未 applied 时即为当前位置。
24
+ config.showInitial=false 时不展示(用于没有"撤销到初始状态"语义的自定义历史,如业务模块历史)。
39
25
  -->
40
- <InitialRow :is-current="isInitial" @goto-initial="$emit('goto-initial', bucketId)" />
26
+ <InitialRow
27
+ v-if="config.showInitial !== false"
28
+ :is-current="isInitial"
29
+ :goto-enabled="config.gotoEnabled"
30
+ @goto-initial="$emit('goto-initial', bucketId)"
31
+ />
41
32
  </ul>
42
33
  </div>
43
34
  </template>
44
35
 
45
- <script lang="ts" setup>
36
+ <script lang="ts" setup generic="T extends BaseStepValue = BaseStepValue">
46
37
  import { computed } from 'vue';
47
38
 
48
- import type { HistoryOpType } from '@editor/type';
39
+ import type { BaseStepValue, HistoryBucketConfig } from '@editor/type';
49
40
 
41
+ import type { HistoryBucketGroup, HistoryRowGroup } from './composables';
42
+ import { isHistoryGroupExpanded, toRowGroup } from './composables';
50
43
  import GroupRow from './GroupRow.vue';
51
44
  import InitialRow from './InitialRow.vue';
52
45
 
@@ -55,26 +48,16 @@ defineOptions({
55
48
  });
56
49
 
57
50
  const props = defineProps<{
58
- /** Bucket 标题,例如 "数据源" / "代码块",渲染在 bucket 头部。 */
59
- title: string;
51
+ /**
52
+ * 该类历史的整体渲染配置(title / prefix / describe* / isStep* / showInitial / gotoEnabled)。
53
+ * 由父组件按业务类型注入,组件内部按需读取,避免逐项透传多个 props。
54
+ */
55
+ config: HistoryBucketConfig<T>;
60
56
  /** 当前 bucket 对应的目标 id(dataSource.id 或 codeBlock.id),同时用于组装子项的 key。 */
61
57
  bucketId: string | number;
62
- /** 子项 key 的命名空间前缀:`ds` 表示数据源,`cb` 表示代码块。与上层折叠状态 key 保持一致。 */
63
- prefix: 'ds' | 'cb';
64
58
  /** 当前 bucket 下的所有历史分组,按时间倒序展示(最近的操作在前)。 */
65
- groups: {
66
- applied: boolean;
67
- isCurrent?: boolean;
68
- opType: HistoryOpType;
69
- steps: { index: number; applied: boolean; isCurrent?: boolean; step: any }[];
70
- }[];
71
- /** 组级描述文案生成器,接收一个 group,返回展示文本。由父组件按业务类型注入。 */
72
- describeGroup: (_group: any) => string;
73
- /** 单步描述文案生成器,接收一个 step,返回展示文本。用于合并组展开后的子步列表。 */
74
- describeStep: (_step: any) => string;
75
- /** 判断某个 step 是否可查看差异(前后值都存在)。由父组件按业务类型注入;不传则一律不展示差异入口。 */
76
- isStepDiffable?: (_step: any) => boolean;
77
- /** 共享的折叠状态表(key -> 是否展开),由顶层 panel 统一维护以便跨 tab 复用。 */
59
+ groups: HistoryBucketGroup<T>[];
60
+ /** 共享的折叠状态表(key -> 是否展开,缺省或 true 为展开、false 为收起),由顶层 panel 统一维护以便跨 tab 复用。 */
78
61
  expanded: Record<string, boolean>;
79
62
  }>();
80
63
 
@@ -94,6 +77,15 @@ defineEmits<{
94
77
  (_e: 'revert-step', _bucketId: string | number, _index: number): void;
95
78
  }>();
96
79
 
80
+ /**
81
+ * 子项 / 折叠状态 key:`${prefix}-${bucketId}-${组内首步 index}`。
82
+ * 以稳定的 step 索引(而非展示位置)标识分组,历史数据更新后已展开的分组状态仍能正确保持。
83
+ */
84
+ const rowKey = (group: HistoryBucketGroup<T>) => `${props.config.prefix}-${props.bucketId}-${group.steps[0]?.index}`;
85
+
86
+ /** 把原始分组派生为 GroupRow 直接消费的视图模型。 */
87
+ const toRow = (group: HistoryBucketGroup<T>): HistoryRowGroup => toRowGroup(group, rowKey(group), props.config);
88
+
97
89
  /** 该 bucket 是否处于初始状态(栈 cursor=0),等价于全部 group 都未 applied。 */
98
90
  const isInitial = computed(() => props.groups.length > 0 && props.groups.every((g) => !g.applied));
99
91
  </script>
@@ -0,0 +1,72 @@
1
+ <template>
2
+ <div v-if="!buckets.length" class="m-editor-history-list-empty">暂无操作记录</div>
3
+ <template v-else>
4
+ <div v-if="config.showClear !== false" class="m-editor-history-list-toolbar">
5
+ <span class="m-editor-history-list-clear" :title="`清空${config.title}的历史记录`" @click="$emit('clear')"
6
+ >清空</span
7
+ >
8
+ </div>
9
+ <TMagicScrollbar max-height="360px">
10
+ <Bucket
11
+ v-for="bucket in buckets"
12
+ :key="`${config.prefix}-${bucket.id}`"
13
+ :config="config"
14
+ :bucket-id="bucket.id"
15
+ :groups="bucket.groups"
16
+ :expanded="expanded"
17
+ @toggle="(key: string) => $emit('toggle', key)"
18
+ @goto="(id: string | number, index: number) => $emit('goto', id, index)"
19
+ @goto-initial="(id: string | number) => $emit('goto-initial', id)"
20
+ @diff-step="(id: string | number, index: number) => $emit('diff-step', id, index)"
21
+ @revert-step="(id: string | number, index: number) => $emit('revert-step', id, index)"
22
+ />
23
+ </TMagicScrollbar>
24
+ </template>
25
+ </template>
26
+
27
+ <script lang="ts" setup generic="T extends BaseStepValue = BaseStepValue">
28
+ import { TMagicScrollbar } from '@tmagic/design';
29
+
30
+ import type { BaseStepValue, HistoryBucketConfig } from '@editor/type';
31
+
32
+ import Bucket from './Bucket.vue';
33
+ import type { HistoryBucketGroup } from './composables';
34
+
35
+ defineOptions({
36
+ name: 'MEditorHistoryListBucketTab',
37
+ });
38
+
39
+ defineProps<{
40
+ /**
41
+ * 该类历史的整体渲染配置(title / prefix / describe* / isStep* / showInitial / gotoEnabled / showClear),
42
+ * 由父组件按业务类型注入并整体透传给 Bucket,避免逐项透传多个 props。
43
+ */
44
+ config: HistoryBucketConfig<T>;
45
+ /**
46
+ * 已按目标 id 聚拢成的 bucket 列表,每个 bucket 内部的 groups 已按时间倒序排好。
47
+ * 空数组时显示空态。
48
+ */
49
+ buckets: { id: string | number; groups: HistoryBucketGroup<T>[] }[];
50
+ /**
51
+ * 共享的折叠状态表(key -> 是否展开),由顶层 panel 统一维护。
52
+ * key 形如 `${prefix}-${id}-${组内首步 index}`——以稳定的 step 索引而非展示位置标识分组,
53
+ * 这样历史数据更新后已展开的分组状态仍能正确保持。
54
+ */
55
+ expanded: Record<string, boolean>;
56
+ }>();
57
+
58
+ defineEmits<{
59
+ /** 透传子组件 Bucket 的 toggle 事件给上层 panel,由其更新 expanded。 */
60
+ (_e: 'toggle', _key: string): void;
61
+ /** 透传 Bucket 的 goto 事件,携带目标 id 与目标 step 索引。 */
62
+ (_e: 'goto', _targetId: string | number, _index: number): void;
63
+ /** 透传 Bucket 的 goto-initial 事件,携带目标 id(回到该目标未修改时的状态)。 */
64
+ (_e: 'goto-initial', _targetId: string | number): void;
65
+ /** 透传 Bucket 的 diff-step 事件,携带目标 id 与 step 索引。 */
66
+ (_e: 'diff-step', _targetId: string | number, _index: number): void;
67
+ /** 透传 Bucket 的 revert-step 事件,携带目标 id 与 step 索引(类 git revert)。 */
68
+ (_e: 'revert-step', _targetId: string | number, _index: number): void;
69
+ /** 用户点击"清空"按钮,请求清空该类(数据源 / 代码块)的全部历史记录(由上层弹窗二次确认后执行)。 */
70
+ (_e: 'clear'): void;
71
+ }>();
72
+ </script>