@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
@@ -9,7 +9,7 @@
9
9
  :values="values"
10
10
  :disabledShowSrc="disabledShowSrc"
11
11
  :extendState="extendState"
12
- @submit="submit"
12
+ @submit="(v, eventData, error) => submit(v, eventData, error, 'props')"
13
13
  @submit-error="errorHandler"
14
14
  @form-error="errorHandler"
15
15
  @mounted="mountedHandler"
@@ -27,7 +27,7 @@
27
27
  :values="values"
28
28
  :disabledShowSrc="disabledShowSrc"
29
29
  :extendState="extendState"
30
- @submit="submit"
30
+ @submit="(v, eventData, error) => submit(v, eventData, error, 'style')"
31
31
  @submit-error="errorHandler"
32
32
  @form-error="errorHandler"
33
33
  >
@@ -55,7 +55,7 @@
55
55
  </template>
56
56
 
57
57
  <script lang="ts" setup>
58
- import { computed, onBeforeUnmount, onMounted, ref, useTemplateRef, watch, watchEffect } from 'vue';
58
+ import { computed, inject, onBeforeUnmount, onMounted, ref, useTemplateRef, watch, watchEffect } from 'vue';
59
59
  import { Close, Sugar } from '@element-plus/icons-vue';
60
60
  import type { OnDrag } from 'gesto';
61
61
 
@@ -66,9 +66,10 @@ import { setValueByKeyPath } from '@tmagic/utils';
66
66
 
67
67
  import MIcon from '@editor/components/Icon.vue';
68
68
  import Resizer from '@editor/components/Resizer.vue';
69
+ import { ENABLE_PROPS_FORM_VALIDATE } from '@editor/editorProps';
69
70
  import { useServices } from '@editor/hooks/use-services';
70
71
  import { Protocol } from '@editor/services/storage';
71
- import type { PropsPanelSlots } from '@editor/type';
72
+ import type { NodeInvalidSource, PropsPanelSlots } from '@editor/type';
72
73
  import { styleTabConfig } from '@editor/utils';
73
74
  import { PROPS_PANEL_WIDTH_STORAGE_KEY } from '@editor/utils/const';
74
75
 
@@ -95,6 +96,8 @@ const emit = defineEmits<{
95
96
 
96
97
  const { editorService, uiService, propsService, storageService } = useServices();
97
98
 
99
+ const enablePropsFormValidate = inject(ENABLE_PROPS_FORM_VALIDATE, false);
100
+
98
101
  const values = ref<FormValue>({});
99
102
  // ts类型应该是FormConfig, 但是打包时会出错,所以暂时用any
100
103
  const curFormConfig = ref<any>([]);
@@ -108,14 +111,31 @@ const styleFormConfig = [
108
111
  },
109
112
  ];
110
113
 
114
+ // 用单调递增序号标记每次 init 调用,只让"最新一次"的 await 结果落到 ref 上。
115
+ // 避免节点快速切换时多个 init 并发 + 解析顺序错乱导致 stale config 覆盖最新选中节点,
116
+ // 以及组件已卸载 / FormPanel 正在 remount 的中间态下写 ref 触发 Vue setRef 把 __vnode
117
+ // 设到 null 上的报错(TypeError: Cannot set properties of null (setting '__vnode'))。
118
+ let initSeq = 0;
119
+ let mounted = true;
120
+
111
121
  const init = async () => {
122
+ initSeq += 1;
123
+ const seq = initSeq;
124
+
112
125
  if (!node.value) {
126
+ if (seq !== initSeq || !mounted) return;
113
127
  curFormConfig.value = [];
114
128
  return;
115
129
  }
116
130
 
117
131
  const type = node.value.type || (node.value.items ? 'container' : 'text');
118
- curFormConfig.value = await propsService.getPropsConfig(type, { node: node.value });
132
+ const config = await propsService.getPropsConfig(type, { node: node.value });
133
+
134
+ // 期间被新一次 init 取代 / 组件已卸载,丢弃本次结果
135
+ if (seq !== initSeq || !mounted) return;
136
+ if (!node.value) return;
137
+
138
+ curFormConfig.value = config;
119
139
  values.value = node.value;
120
140
  };
121
141
 
@@ -123,10 +143,16 @@ watchEffect(init);
123
143
  propsService.on('props-configs-change', init);
124
144
 
125
145
  onBeforeUnmount(() => {
146
+ mounted = false;
126
147
  propsService.off('props-configs-change', init);
127
148
  });
128
149
 
129
- const submit = async (v: MNode, eventData?: ContainerChangeEventData) => {
150
+ const submit = async (
151
+ v: MNode,
152
+ eventData?: ContainerChangeEventData,
153
+ error?: any,
154
+ source: NodeInvalidSource = 'props',
155
+ ) => {
130
156
  try {
131
157
  if (!v.id) {
132
158
  v.id = values.value.id;
@@ -138,20 +164,38 @@ const submit = async (v: MNode, eventData?: ContainerChangeEventData) => {
138
164
  };
139
165
 
140
166
  if (v.style) {
141
- Object.entries(v.style).forEach(([key, value]) => {
142
- if (value !== '' && newValue.style) {
143
- newValue.style[key] = value;
144
- }
145
- });
146
-
147
- eventData?.changeRecords?.forEach((record) => {
148
- if (record.propPath?.startsWith('style') && record.value === '') {
149
- setValueByKeyPath(record.propPath, record.value, newValue);
150
- }
151
- });
167
+ // 空字符串样式值表示「清除该样式」,需保留才能在 doUpdate 的 mergeWith 中覆盖旧值。
168
+ if (eventData) {
169
+ // 表单编辑:先过滤掉空字符串(避免表单默认空值污染 DSL),
170
+ // 再按 changeRecords 恢复被主动清空的字段。
171
+ Object.entries(v.style).forEach(([key, value]) => {
172
+ if (value !== '' && newValue.style) {
173
+ newValue.style[key] = value;
174
+ }
175
+ });
176
+
177
+ eventData.changeRecords?.forEach((record) => {
178
+ if (record.propPath?.startsWith('style') && record.value === '') {
179
+ setValueByKeyPath(record.propPath, record.value, newValue);
180
+ }
181
+ });
182
+ } else {
183
+ // 源码编辑器保存(无 eventData):style 原样保留,其中的空字符串视为用户主动清除该样式。
184
+ newValue.style = { ...v.style };
185
+ }
152
186
  }
153
187
 
154
- editorService.update(newValue, { changeRecords: eventData?.changeRecords });
188
+ // 区分操作途径:表单字段编辑(MForm @change)会带上 eventData(含 changeRecords);
189
+ // 源码编辑器(CodeEditor @save → saveCode)保存时不带 eventData,据此标记为「源码编辑器」。
190
+ const historySource = eventData ? 'props' : 'code';
191
+
192
+ editorService.update(newValue, {
193
+ changeRecords: eventData?.changeRecords,
194
+ historySource,
195
+ // 启用校验联动时,仅校验失败(error 存在)才把错误信息随更新传入 editorService 记录;
196
+ // 其余情况(含表单校验成功、CodeEditor 源码保存)不携带 invalidInfo,由 editorService 在执行 update 时统一清除该节点错误。
197
+ ...(enablePropsFormValidate && error ? { invalidInfo: { id: newValue.id, source, error: error?.message } } : {}),
198
+ });
155
199
  } catch (e: any) {
156
200
  emit('submit-error', e);
157
201
  }
@@ -2,7 +2,7 @@ import { computed, type Ref, watch } from 'vue';
2
2
 
3
3
  import { Protocol } from '@editor/services/storage';
4
4
  import { Services } from '@editor/type';
5
- import { MIN_CENTER_COLUMN_WIDTH, RIGHT_COLUMN_WIDTH_STORAGE_KEY } from '@editor/utils/const';
5
+ import { RIGHT_COLUMN_WIDTH_STORAGE_KEY } from '@editor/utils/const';
6
6
 
7
7
  export const useStylePanel = (
8
8
  { uiService, storageService }: Pick<Services, 'uiService' | 'storageService'>,
@@ -47,8 +47,9 @@ export const useStylePanel = (
47
47
  }
48
48
 
49
49
  if (columnWidth.center < 0) {
50
- columnWidth.right = columnWidth.right + columnWidth.center - MIN_CENTER_COLUMN_WIDTH;
51
- columnWidth.center = MIN_CENTER_COLUMN_WIDTH;
50
+ const minCenterColumnWidth = uiService.get('minCenterColumnWidth');
51
+ columnWidth.right = columnWidth.right + columnWidth.center - minCenterColumnWidth;
52
+ columnWidth.center = minCenterColumnWidth;
52
53
 
53
54
  propsPanelWidth.value = columnWidth.right / 2;
54
55
  }
@@ -94,11 +94,15 @@ let clientX: number;
94
94
  let clientY: number;
95
95
 
96
96
  const appendComponent = ({ text, type, data = {} }: ComponentItem): void => {
97
- editorService.add({
98
- name: text,
99
- type,
100
- ...data,
101
- });
97
+ editorService.add(
98
+ {
99
+ name: text,
100
+ type,
101
+ ...data,
102
+ },
103
+ undefined,
104
+ { historySource: 'component-panel' },
105
+ );
102
106
  };
103
107
 
104
108
  const dragstartHandler = ({ text, type, data = {} }: ComponentItem, e: DragEvent) => {
@@ -141,6 +145,6 @@ const dragHandler = (e: DragEvent) => {
141
145
 
142
146
  if (timeout || !stage.value) return;
143
147
 
144
- timeout = stage.value.delayedMarkContainer(e);
148
+ timeout = stage.value.delayedMarkContainer(e, [], true);
145
149
  };
146
150
  </script>
@@ -132,6 +132,7 @@
132
132
  v-model:height="columnLeftHeight"
133
133
  :width="columnLeftWidth"
134
134
  :title="config.text"
135
+ :framework-width="frameworkWidth"
135
136
  :position="{
136
137
  left: floatBoxStates[config.$key].left,
137
138
  top: floatBoxStates[config.$key].top,
@@ -154,7 +155,7 @@
154
155
 
155
156
  <script setup lang="ts">
156
157
  import { computed, nextTick, ref, watch } from 'vue';
157
- import { Close, Coin, EditPen, Goods, List } from '@element-plus/icons-vue';
158
+ import { Box, Close, Coin, EditPen, Finished } from '@element-plus/icons-vue';
158
159
 
159
160
  import FloatingBox from '@editor/components/FloatingBox.vue';
160
161
  import MIcon from '@editor/components/Icon.vue';
@@ -221,6 +222,7 @@ const taskLength = computed(() => depService.get('taskLength'));
221
222
  const tipsBarVisible = ref(true);
222
223
 
223
224
  const columnLeftWidth = computed(() => uiService.get('columnWidth')[ColumnLayout.LEFT]);
225
+ const frameworkWidth = computed(() => uiService.get('frameworkRect')?.width || 0);
224
226
  const { height: editorContentHeight } = useEditorContentHeight();
225
227
  const columnLeftHeight = ref(0);
226
228
 
@@ -239,22 +241,27 @@ const unWatchEditorContentHeight = watch(
239
241
  },
240
242
  );
241
243
 
242
- const activeTabName = ref(props.data?.status);
244
+ const activeTabName = computed<string>({
245
+ get: () => uiService.get('sideBarActiveTabName'),
246
+ set: (value) => uiService.set('sideBarActiveTabName', value),
247
+ });
248
+
249
+ uiService.set('sideBarActiveTabName', props.data?.status || '');
243
250
 
244
251
  const getItemConfig = (data: SideItem): SideComponent => {
245
252
  const map: Record<string, SideComponent> = {
246
253
  [SideItemKey.COMPONENT_LIST]: {
247
254
  $key: SideItemKey.COMPONENT_LIST,
248
255
  type: 'component',
249
- icon: Goods,
256
+ icon: Box,
250
257
  text: '组件',
251
258
  component: ComponentListPanel,
252
259
  slots: {},
253
260
  },
254
261
  layer: {
255
- $key: 'layer',
262
+ $key: SideItemKey.LAYER,
256
263
  type: 'component',
257
- icon: List,
264
+ icon: Finished,
258
265
  text: '已选组件',
259
266
  props: {
260
267
  layerContentMenu: props.layerContentMenu,
@@ -272,7 +279,7 @@ const getItemConfig = (data: SideItem): SideComponent => {
272
279
  slots: {},
273
280
  },
274
281
  [SideItemKey.CODE_BLOCK]: {
275
- $key: 'code-block',
282
+ $key: SideItemKey.CODE_BLOCK,
276
283
  type: 'component',
277
284
  icon: EditPen,
278
285
  text: '代码编辑',
@@ -24,7 +24,7 @@
24
24
  <Icon :icon="editable ? Edit : View" class="edit-icon" @click.stop="editCode(`${data.key}`)"></Icon>
25
25
  </TMagicTooltip>
26
26
  <TMagicTooltip v-if="data.type === 'code' && editable" effect="dark" content="删除" placement="bottom">
27
- <Icon :icon="Close" class="edit-icon" @click.stop="deleteCode(`${data.key}`)"></Icon>
27
+ <Icon :icon="Close" class="edit-icon" @click.stop="deleteCode(`${data.key}`, { historySource: 'tree' })"></Icon>
28
28
  </TMagicTooltip>
29
29
  <slot name="code-block-panel-tool" :id="data.key" :data="data"></slot>
30
30
  </template>
@@ -44,7 +44,7 @@ import Tree from '@editor/components/Tree.vue';
44
44
  import { useFilter } from '@editor/hooks/use-filter';
45
45
  import { useNodeStatus } from '@editor/hooks/use-node-status';
46
46
  import { useServices } from '@editor/hooks/use-services';
47
- import { type CodeBlockListSlots, CodeDeleteErrorType, type TreeNodeData } from '@editor/type';
47
+ import { type CodeBlockListSlots, CodeDeleteErrorType, HistoryOpSource, type TreeNodeData } from '@editor/type';
48
48
 
49
49
  defineSlots<CodeBlockListSlots>();
50
50
 
@@ -60,7 +60,7 @@ const props = defineProps<{
60
60
 
61
61
  const emit = defineEmits<{
62
62
  edit: [id: string];
63
- remove: [id: string];
63
+ remove: [id: string, { historySource?: HistoryOpSource }];
64
64
  'node-contextmenu': [event: MouseEvent, data: TreeNodeData];
65
65
  }>();
66
66
 
@@ -142,7 +142,7 @@ const editCode = (id: string) => {
142
142
  emit('edit', id);
143
143
  };
144
144
 
145
- const deleteCode = async (id: string) => {
145
+ const deleteCode = async (id: string, { historySource }: { historySource?: HistoryOpSource } = {}) => {
146
146
  const currentCode = codeList.value.find((codeItem) => codeItem.id === id);
147
147
  const existBinds = Boolean(currentCode?.items?.length);
148
148
  const undeleteableList = codeBlockService.getUndeletableList() || [];
@@ -154,7 +154,7 @@ const deleteCode = async (id: string) => {
154
154
  });
155
155
 
156
156
  // 无绑定关系,且不在不可删除列表中
157
- emit('remove', id);
157
+ emit('remove', id, { historySource });
158
158
  } else {
159
159
  if (typeof props.customError === 'function') {
160
160
  props.customError(id, existBinds ? CodeDeleteErrorType.BIND : CodeDeleteErrorType.UNDELETEABLE);
@@ -121,8 +121,11 @@ const {
121
121
  nodeContentMenuHandler,
122
122
  menuData: contentMenuData,
123
123
  contentMenuHideHandler,
124
+ getTarget,
124
125
  } = useContentMenu((id: string) => {
125
- codeBlockListRef.value?.deleteCode(id);
126
+ codeBlockListRef.value?.deleteCode(id, { historySource: 'tree-contextmenu' });
126
127
  });
127
- const menuData = computed<(MenuButton | MenuComponent)[]>(() => props.customContentMenu(contentMenuData, 'code-block'));
128
+ const menuData = computed<(MenuButton | MenuComponent)[]>(() =>
129
+ props.customContentMenu(contentMenuData, 'code-block', getTarget),
130
+ );
128
131
  </script>
@@ -3,13 +3,21 @@ import { CopyDocument, Delete, Edit } from '@element-plus/icons-vue';
3
3
  import { cloneDeep } from 'lodash-es';
4
4
 
5
5
  import ContentMenu from '@editor/components/ContentMenu.vue';
6
- import type { EventBus, MenuButton, MenuComponent, TreeNodeData } from '@editor/type';
6
+ import type { ContentMenuTarget, EventBus, MenuButton, MenuComponent, TreeNodeData } from '@editor/type';
7
7
 
8
8
  export const useContentMenu = (deleteCode: (id: string) => void) => {
9
9
  const eventBus = inject<EventBus>('eventBus');
10
10
  const menuRef = useTemplateRef<InstanceType<typeof ContentMenu>>('menu');
11
11
 
12
12
  let selectId = '';
13
+ let selectData: TreeNodeData | null = null;
14
+
15
+ const getTarget = (): ContentMenuTarget | null => {
16
+ if (!selectId) {
17
+ return null;
18
+ }
19
+ return { id: selectId, data: selectData ?? undefined };
20
+ };
13
21
 
14
22
  const menuData: (MenuButton | MenuComponent)[] = [
15
23
  {
@@ -41,7 +49,7 @@ export const useContentMenu = (deleteCode: (id: string) => void) => {
41
49
 
42
50
  const newCodeId = await codeBlockService.getUniqueId();
43
51
 
44
- codeBlockService.setCodeDslById(newCodeId, cloneDeep(codeBlock));
52
+ codeBlockService.setCodeDslById(newCodeId, cloneDeep(codeBlock), { historySource: 'tree-contextmenu' });
45
53
  },
46
54
  },
47
55
  {
@@ -65,19 +73,23 @@ export const useContentMenu = (deleteCode: (id: string) => void) => {
65
73
  menuRef.value?.show(event);
66
74
  if (data.id) {
67
75
  selectId = `${data.id}`;
76
+ selectData = data;
68
77
  } else {
69
78
  selectId = '';
79
+ selectData = null;
70
80
  }
71
81
  }
72
82
  };
73
83
 
74
84
  const contentMenuHideHandler = () => {
75
85
  selectId = '';
86
+ selectData = null;
76
87
  };
77
88
 
78
89
  return {
79
90
  menuData,
80
91
  nodeContentMenuHandler,
81
92
  contentMenuHideHandler,
93
+ getTarget,
82
94
  };
83
95
  };
@@ -1,9 +1,11 @@
1
1
  <template>
2
2
  <FloatingBox
3
+ :body-style="{ padding: '0 16px' }"
3
4
  v-model:visible="boxVisible"
4
5
  v-model:width="width"
5
6
  v-model:height="editorHeight"
6
7
  :title="title"
8
+ :framework-width="frameworkWidth"
7
9
  :position="boxPosition"
8
10
  >
9
11
  <template #body>
@@ -22,7 +24,7 @@
22
24
  </template>
23
25
 
24
26
  <script setup lang="ts">
25
- import { inject, nextTick, Ref, ref, watch, watchEffect } from 'vue';
27
+ import { computed, inject, nextTick, provide, Ref, ref, watch, watchEffect } from 'vue';
26
28
 
27
29
  import type { DataSourceSchema } from '@tmagic/core';
28
30
  import { tMagicMessage } from '@tmagic/design';
@@ -41,6 +43,10 @@ const props = defineProps<{
41
43
  title?: string;
42
44
  values: any;
43
45
  disabled: boolean;
46
+ /** 打开后需要直接定位并打开的方法名,传入时默认激活「方法定义」tab */
47
+ editMethodName?: string;
48
+ /** 打开后需要直接定位并打开的字段路径,传入时默认激活「数据定义」tab */
49
+ editFieldPath?: string[];
44
50
  }>();
45
51
 
46
52
  const boxVisible = defineModel<boolean>('visible', { default: false });
@@ -61,10 +67,36 @@ const { height: editorHeight } = useEditorContentHeight();
61
67
 
62
68
  const parentFloating = inject<Ref<HTMLDivElement | null>>('parentFloating', ref(null));
63
69
  const { boxPosition, calcBoxPosition } = useNextFloatBoxPosition(uiService, parentFloating);
70
+ const frameworkWidth = computed(() => uiService.get('frameworkRect')?.width || 0);
71
+
72
+ /** 供「方法定义」tab 内的字段消费,用于打开数据源详情后自动打开指定方法 */
73
+ provide(
74
+ 'editingDataSourceMethodName',
75
+ computed(() => props.editMethodName),
76
+ );
77
+
78
+ /** 供「数据定义」tab 内的字段消费,用于打开数据源详情后自动打开指定字段 */
79
+ provide(
80
+ 'editingDataSourceFieldPath',
81
+ computed(() => props.editFieldPath || []),
82
+ );
64
83
 
65
84
  watchEffect(() => {
66
85
  initValues.value = props.values;
67
- dataSourceConfig.value = dataSourceService.getFormConfig(initValues.value.type);
86
+ const config = dataSourceService.getFormConfig(initValues.value.type);
87
+
88
+ // 传入方法名/字段路径时,将外层 tab 容器默认激活到对应 tab(status: methods / fields)
89
+ // 未传入时默认激活「数据定义」tab(fields)
90
+ let activeTab = 'fields';
91
+ if (props.editMethodName) {
92
+ activeTab = 'methods';
93
+ } else if (props.editFieldPath?.length) {
94
+ activeTab = 'fields';
95
+ }
96
+
97
+ dataSourceConfig.value = config.map((item) =>
98
+ (item as { type?: string }).type === 'tab' ? { ...item, active: activeTab } : item,
99
+ );
68
100
  });
69
101
 
70
102
  const submitHandler = (values: any, data: ContainerChangeEventData) => {
@@ -29,6 +29,8 @@
29
29
  :disabled="!editable"
30
30
  :values="dataSourceValues"
31
31
  :title="dialogTitle"
32
+ :edit-method-name="editMethodName"
33
+ :edit-field-path="editFieldPath"
32
34
  @submit="submitDataSourceHandler"
33
35
  @close="editDialogCloseHandler"
34
36
  ></DataSourceConfigPanel>
@@ -45,7 +47,7 @@
45
47
  </template>
46
48
 
47
49
  <script setup lang="ts">
48
- import { computed, inject, useTemplateRef, watch } from 'vue';
50
+ import { computed, inject, ref, useTemplateRef, watch } from 'vue';
49
51
  import { mergeWith } from 'lodash-es';
50
52
 
51
53
  import { tMagicMessageBox, TMagicScrollbar } from '@tmagic/design';
@@ -79,7 +81,16 @@ const { dataSourceService } = useServices();
79
81
  const { editDialog, dataSourceValues, dialogTitle, editable, editHandler, submitDataSourceHandler } =
80
82
  useDataSourceEdit(dataSourceService);
81
83
 
84
+ /** 打开数据源详情时需要直接定位并打开的方法名,为空则正常展示「数据定义」tab */
85
+ const editMethodName = ref('');
86
+
87
+ /** 打开数据源详情时需要直接定位并打开的字段路径,为空则不自动打开字段配置 */
88
+ const editFieldPath = ref<string[]>([]);
89
+
82
90
  const editDialogCloseHandler = () => {
91
+ editMethodName.value = '';
92
+ editFieldPath.value = [];
93
+
83
94
  if (dataSourceListRef.value) {
84
95
  for (const [, status] of dataSourceListRef.value.nodeStatusMap.entries()) {
85
96
  status.selected = false;
@@ -129,7 +140,7 @@ const removeHandler = async (id: string) => {
129
140
  type: 'warning',
130
141
  });
131
142
 
132
- dataSourceService.remove(id);
143
+ dataSourceService.remove(id, { historySource: 'tree-contextmenu' });
133
144
  };
134
145
 
135
146
  const dataSourceListRef = useTemplateRef<InstanceType<typeof DataSourceList>>('dataSourceList');
@@ -139,6 +150,20 @@ const filterTextChangeHandler = (val: string) => {
139
150
  };
140
151
 
141
152
  eventBus?.on('edit-data-source', (id: string) => {
153
+ editMethodName.value = '';
154
+ editFieldPath.value = [];
155
+ editHandler(id);
156
+ });
157
+
158
+ eventBus?.on('edit-data-source-method', (id: string, methodName: string) => {
159
+ editMethodName.value = methodName;
160
+ editFieldPath.value = [];
161
+ editHandler(id);
162
+ });
163
+
164
+ eventBus?.on('edit-data-source-field', (id: string, fieldPath: string[]) => {
165
+ editMethodName.value = '';
166
+ editFieldPath.value = fieldPath;
142
167
  editHandler(id);
143
168
  });
144
169
 
@@ -146,8 +171,8 @@ eventBus?.on('remove-data-source', (id: string) => {
146
171
  removeHandler(id);
147
172
  });
148
173
 
149
- const { nodeContentMenuHandler, menuData: contentMenuData, contentMenuHideHandler } = useContentMenu();
174
+ const { nodeContentMenuHandler, menuData: contentMenuData, contentMenuHideHandler, getTarget } = useContentMenu();
150
175
  const menuData = computed<(MenuButton | MenuComponent)[]>(() =>
151
- props.customContentMenu(contentMenuData, 'data-source'),
176
+ props.customContentMenu(contentMenuData, 'data-source', getTarget),
152
177
  );
153
178
  </script>
@@ -3,13 +3,21 @@ import { CopyDocument, Delete, Edit } from '@element-plus/icons-vue';
3
3
  import { cloneDeep } from 'lodash-es';
4
4
 
5
5
  import ContentMenu from '@editor/components/ContentMenu.vue';
6
- import type { EventBus, MenuButton, MenuComponent, TreeNodeData } from '@editor/type';
6
+ import type { ContentMenuTarget, EventBus, MenuButton, MenuComponent, TreeNodeData } from '@editor/type';
7
7
 
8
8
  export const useContentMenu = () => {
9
9
  const eventBus = inject<EventBus>('eventBus');
10
10
  const menuRef = useTemplateRef<InstanceType<typeof ContentMenu>>('menu');
11
11
 
12
12
  let selectId = '';
13
+ let selectData: TreeNodeData | null = null;
14
+
15
+ const getTarget = (): ContentMenuTarget | null => {
16
+ if (!selectId) {
17
+ return null;
18
+ }
19
+ return { id: selectId, data: selectData ?? undefined };
20
+ };
13
21
 
14
22
  const menuData: (MenuButton | MenuComponent)[] = [
15
23
  {
@@ -39,7 +47,7 @@ export const useContentMenu = () => {
39
47
  return;
40
48
  }
41
49
 
42
- dataSourceService.add(cloneDeep(ds));
50
+ dataSourceService.add(cloneDeep(ds), { historySource: 'tree-contextmenu' });
43
51
  },
44
52
  },
45
53
  {
@@ -63,19 +71,23 @@ export const useContentMenu = () => {
63
71
  menuRef.value?.show(event);
64
72
  if (data.id) {
65
73
  selectId = `${data.id}`;
74
+ selectData = data;
66
75
  } else {
67
76
  selectId = '';
77
+ selectData = null;
68
78
  }
69
79
  }
70
80
  };
71
81
 
72
82
  const contentMenuHideHandler = () => {
73
83
  selectId = '';
84
+ selectData = null;
74
85
  };
75
86
 
76
87
  return {
77
88
  menuData,
78
89
  nodeContentMenuHandler,
79
90
  contentMenuHideHandler,
91
+ getTarget,
80
92
  };
81
93
  };
@@ -6,7 +6,7 @@
6
6
  import { computed, markRaw, useTemplateRef } from 'vue';
7
7
  import { Files, Plus } from '@element-plus/icons-vue';
8
8
 
9
- import { isPage, isPageFragment } from '@tmagic/utils';
9
+ import { isPageOrFragment } from '@tmagic/utils';
10
10
 
11
11
  import ContentMenu from '@editor/components/ContentMenu.vue';
12
12
  import { useServices } from '@editor/hooks/use-services';
@@ -41,11 +41,15 @@ const createMenuItems = (group: ComponentGroup): MenuButton[] =>
41
41
  type: 'button',
42
42
  icon: component.icon,
43
43
  handler: () => {
44
- editorService.add({
45
- name: component.text,
46
- type: component.type,
47
- ...(component.data || {}),
48
- });
44
+ editorService.add(
45
+ {
46
+ name: component.text,
47
+ type: component.type,
48
+ ...(component.data || {}),
49
+ },
50
+ undefined,
51
+ { historySource: 'tree-contextmenu' },
52
+ );
49
53
  },
50
54
  }));
51
55
 
@@ -57,9 +61,13 @@ const getSubMenuData = computed<MenuButton[]>(() => {
57
61
  type: 'button',
58
62
  icon: Files,
59
63
  handler: () => {
60
- editorService.add({
61
- type: 'tab-pane',
62
- });
64
+ editorService.add(
65
+ {
66
+ type: 'tab-pane',
67
+ },
68
+ undefined,
69
+ { historySource: 'tree-contextmenu' },
70
+ );
63
71
  },
64
72
  },
65
73
  ];
@@ -93,7 +101,7 @@ const menuData = computed<(MenuButton | MenuComponent)[]>(() =>
93
101
  type: 'button',
94
102
  text: '全部折叠',
95
103
  icon: FolderMinusIcon,
96
- display: () => isPage(node.value) || isPageFragment(node.value),
104
+ display: () => isPageOrFragment(node.value),
97
105
  handler: () => {
98
106
  emit('collapse-all');
99
107
  },
@@ -106,9 +114,9 @@ const menuData = computed<(MenuButton | MenuComponent)[]>(() =>
106
114
  items: getSubMenuData.value,
107
115
  },
108
116
  useCopyMenu(),
109
- usePasteMenu(),
110
- useDeleteMenu(),
111
- useMoveToMenu(services),
117
+ usePasteMenu('tree-contextmenu'),
118
+ useDeleteMenu('tree-contextmenu'),
119
+ useMoveToMenu(services, 'tree-contextmenu'),
112
120
  ...props.layerContentMenu,
113
121
  ],
114
122
  'layer',