@gadmin2n/schematics 0.0.68 → 0.0.70

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 (223) hide show
  1. package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/canvas.prisma +45 -0
  2. package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/example.prisma +24 -23
  3. package/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/system.prisma +93 -90
  4. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Audit.ts +70 -0
  5. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Event.ts +3 -3
  6. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Page.ts +70 -0
  7. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/PageResource.ts +70 -0
  8. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/Resource.ts +70 -0
  9. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/RolePages.ts +70 -0
  10. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/RoleResource.ts +70 -0
  11. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/SavedQuery.ts +70 -0
  12. package/dist/lib/application/files/gadmin2-game-angle-demo/config/ui/User.ts +70 -0
  13. package/dist/lib/application/files/gadmin2-game-angle-demo/readme.md +95 -2
  14. package/dist/lib/application/files/gadmin2-game-angle-demo/server/.eslintrc.js +4 -2
  15. package/dist/lib/application/files/gadmin2-game-angle-demo/server/.prettierignore +7 -1
  16. package/dist/lib/application/files/gadmin2-game-angle-demo/server/config/index.ts +1 -3
  17. package/dist/lib/application/files/gadmin2-game-angle-demo/server/gadmin-cli.json +2 -2
  18. package/dist/lib/application/files/gadmin2-game-angle-demo/server/package.json +6 -5
  19. package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/lib/page-helpers.ts +157 -0
  20. package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/page-manage.ts +290 -0
  21. package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/permission-manage.ts +184 -0
  22. package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/prismaModels.ts +143 -0
  23. package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/sync-resources.ts +100 -0
  24. package/dist/lib/application/files/gadmin2-game-angle-demo/server/scripts/syncDataMngtPages.ts +119 -0
  25. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/index.ts +1 -3
  26. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/permissions.ts +109 -143
  27. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/main.ts +5 -2
  28. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/canvas/canvas.controller.spec.ts +20 -0
  29. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/canvas/canvas.controller.ts +81 -0
  30. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/canvas/canvas.dto.ts +49 -0
  31. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/canvas/canvas.module.ts +11 -0
  32. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/canvas/canvas.service.spec.ts +334 -0
  33. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/canvas/canvas.service.ts +249 -0
  34. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/index.ts +2 -1
  35. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/page/page.service.ts +2 -2
  36. package/dist/lib/application/files/gadmin2-game-angle-demo/server/src/modules/role/role.service.ts +17 -4
  37. package/dist/lib/application/files/gadmin2-game-angle-demo/server/yarn.lock +7737 -0
  38. package/dist/lib/application/files/gadmin2-game-angle-demo/web/.env +1 -0
  39. package/dist/lib/application/files/gadmin2-game-angle-demo/web/.eslintrc.json +38 -0
  40. package/dist/lib/application/files/gadmin2-game-angle-demo/web/.prettierignore +2 -0
  41. package/dist/lib/application/files/gadmin2-game-angle-demo/web/dev-shell-entry.html +49 -0
  42. package/dist/lib/application/files/gadmin2-game-angle-demo/web/package.json +13 -2
  43. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/App.tsx +137 -111
  44. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/auditLogProvider.ts +46 -44
  45. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/authProvider.ts +32 -12
  46. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/BulkActions.tsx +74 -23
  47. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/ListPageHeader.tsx +9 -9
  48. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/RowActions.tsx +57 -31
  49. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/SearchBar.tsx +53 -24
  50. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/SqlModal.tsx +148 -72
  51. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/agentPanel/AgentContext.tsx +190 -16
  52. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/agentPanel/ElementInspector.tsx +914 -63
  53. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/agentPanel/agentAttributes.ts +17 -8
  54. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/agentPanel/index.ts +0 -10
  55. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/agentPanel/inspectorActions.ts +969 -46
  56. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/agentPanel/pagePathUtils.ts +66 -0
  57. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/agentPanel/promptGenerator.ts +85 -25
  58. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/agentPanel/propPatcher.ts +84 -0
  59. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/auditLog/components/eventList/index.tsx +16 -20
  60. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/auditLog/components/index.ts +4 -4
  61. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/auditLog/components/logButton/index.tsx +13 -13
  62. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/auditLog/components/logList/index.tsx +15 -16
  63. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/auditLog/components/modalDiffViewer/index.tsx +15 -15
  64. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/auditLog/index.tsx +2 -2
  65. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/BarChart/index.tsx +896 -0
  66. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/ChartSwitcher/index.tsx +219 -0
  67. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/ChartViewer/index.tsx +159 -0
  68. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/Filter/index.tsx +192 -0
  69. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/LineChart/index.tsx +1034 -0
  70. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/NumCard/NumCard.module.css +8 -0
  71. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/NumCard/index.tsx +509 -0
  72. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/NumLineCard/index.tsx +66 -0
  73. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/PieChart/index.tsx +552 -0
  74. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/RadarChart/index.tsx +263 -0
  75. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/Section/index.tsx +35 -0
  76. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/Table/index.tsx +207 -0
  77. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/TreemapChart/index.tsx +382 -0
  78. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/WorldMap/index.tsx +135 -0
  79. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/chart-constants.ts +53 -0
  80. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/icon/InfoIcon.tsx +8 -0
  81. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/icon/index.ts +1 -0
  82. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/map/config.ts +31 -0
  83. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/map/nameMap.json +9 -0
  84. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/map/world.geo.json +39349 -0
  85. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/canvas/metric-info-tooltip/index.tsx +19 -0
  86. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/contexts/business/index.tsx +12 -12
  87. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/contexts/color-mode/index.tsx +22 -26
  88. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/custom-avatar.tsx +13 -9
  89. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/index.ts +4 -4
  90. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/header.tsx +22 -37
  91. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/index.ts +4 -4
  92. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/layout.tsx +10 -10
  93. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/logo.tsx +1 -1
  94. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/sider.tsx +113 -65
  95. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/title.tsx +14 -14
  96. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/offLayoutArea/index.tsx +1 -1
  97. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/pagination-total.tsx +2 -2
  98. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/tags/index.ts +1 -1
  99. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/tags/role-tag.tsx +21 -21
  100. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/text.tsx +17 -13
  101. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/http.ts +26 -5
  102. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/routeRegistry.tsx +221 -51
  103. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/constants/layout.ts +3 -3
  104. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/AddDataModal.tsx +199 -0
  105. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/AddPageModal.tsx +335 -0
  106. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/DeleteDataConfirm.tsx +56 -0
  107. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/DevShell.tsx +401 -0
  108. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/EditDataModal.tsx +129 -0
  109. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/SkillMenu.tsx +202 -0
  110. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/UndoConfirm.tsx +36 -0
  111. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/index.tsx +8 -0
  112. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/dev-shell/style.css +835 -0
  113. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/enums/audit-log.enum.ts +8 -8
  114. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/enums/index.ts +1 -1
  115. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/form.tsx +120 -70
  116. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/get-name-initials.ts +3 -3
  117. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/get-random-color.ts +11 -11
  118. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/http.ts +16 -19
  119. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/index.tsx +1 -1
  120. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/list.tsx +99 -73
  121. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/login.ts +22 -27
  122. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/page-tree.ts +74 -0
  123. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/show.tsx +95 -51
  124. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/utils.tsx +7 -3
  125. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/types.ts +15 -15
  126. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useBatchDelete.ts +10 -10
  127. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useBatchOperations.ts +8 -7
  128. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useBatchOperationsCore.ts +10 -10
  129. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useBatchUpdate.ts +10 -10
  130. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useDynamicResources.tsx +36 -27
  131. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useECharts.tsx +144 -0
  132. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useFetchData.ts +4 -4
  133. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useListPageState.ts +34 -34
  134. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useRoles.ts +8 -4
  135. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useRowSelection.ts +1 -1
  136. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useUserPageAccess.ts +55 -41
  137. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/i18n.ts +8 -8
  138. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/index.tsx +9 -2
  139. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/en/common.json +193 -0
  140. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/common.json +194 -0
  141. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/plugins/devShellPlugin.ts +81 -0
  142. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/components/action-cell.tsx +37 -37
  143. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/create.tsx +23 -31
  144. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/edit.tsx +34 -35
  145. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/index.ts +1 -1
  146. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/index.tsx +4 -6
  147. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/list.tsx +41 -34
  148. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/show.tsx +33 -20
  149. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasCell.tsx +87 -0
  150. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasEditPage.tsx +192 -0
  151. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasListPage.tsx +409 -0
  152. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasPage.tsx +1372 -0
  153. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CanvasToolbar.tsx +384 -0
  154. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/CodeFloatWindow.tsx +476 -0
  155. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/ComponentThumbnail.tsx +135 -0
  156. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/IsolatedLivePreview.tsx +101 -0
  157. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/LivePreview.tsx +236 -0
  158. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/PublishModal.tsx +200 -0
  159. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasApi.ts +92 -0
  160. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasConfigRegistry.tsx +25 -0
  161. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasContextMenuRegistry.tsx +875 -0
  162. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasDefaults.ts +126 -0
  163. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/canvasI18n.ts +11 -0
  164. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/BarChartDataSourceModal.tsx +115 -0
  165. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/ChartViewerConfigModal.tsx +217 -0
  166. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/LineChartDataSourceModal.tsx +153 -0
  167. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/NumCardDataSourceModal.tsx +211 -0
  168. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/PromptModal.tsx +90 -0
  169. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/RadarChartDataSourceModal.tsx +87 -0
  170. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/components/TableDataSourceModal.tsx +204 -0
  171. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/demos.ts +1153 -0
  172. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/index.tsx +2 -0
  173. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/sectionCompactor.ts +45 -0
  174. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas/types.ts +45 -0
  175. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/canvas-page/index.tsx +108 -0
  176. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/game/create.tsx +105 -0
  177. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/game/edit.tsx +121 -0
  178. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/game/index.tsx +4 -0
  179. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/game/list.tsx +237 -0
  180. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/game/show.tsx +74 -0
  181. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/Components/AssignRolesModal.tsx +29 -20
  182. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/Components/CreatePageModal.tsx +3 -3
  183. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/Components/EditPageModal.tsx +7 -3
  184. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/Components/PageDetailDrawer.tsx +58 -23
  185. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/Components/PageFormModal.tsx +206 -122
  186. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/hooks/usePageManagement.ts +8 -4
  187. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/index.ts +1 -1
  188. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/list.tsx +345 -190
  189. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/types.ts +1 -1
  190. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/permissionReadme/index.tsx +341 -340
  191. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/Components/CreateModal.tsx +2 -2
  192. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/Components/EditModal.tsx +2 -2
  193. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/Components/ResourceDetailDrawer.tsx +41 -24
  194. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/Components/modal.tsx +64 -36
  195. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/index.ts +2 -2
  196. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/list.tsx +78 -40
  197. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/Components/CreateModal.tsx +3 -3
  198. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/Components/EditModal.tsx +4 -4
  199. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/Components/RoleDetailDrawer.tsx +19 -9
  200. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/Components/modal.tsx +45 -47
  201. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/hooks/useRolePage.ts +4 -4
  202. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/index.ts +1 -1
  203. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/list.tsx +121 -147
  204. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/types.ts +1 -1
  205. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/components/create-modal.tsx +2 -2
  206. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/components/edit-modal.tsx +2 -2
  207. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/components/form-modal.tsx +25 -19
  208. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/components/index.ts +5 -5
  209. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/components/role-tag.tsx +10 -10
  210. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/components/show-drawer.tsx +31 -26
  211. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/index.ts +1 -1
  212. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/list.tsx +76 -71
  213. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/setupTests.ts +1 -1
  214. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/types/audit-log.ts +1 -1
  215. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/types/index.ts +3 -3
  216. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/types/role.ts +1 -1
  217. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/types/user.ts +1 -1
  218. package/dist/lib/application/files/gadmin2-game-angle-demo/web/vite.config.ts +42 -25
  219. package/dist/lib/application/files/gadmin2-game-angle-demo/web/yarn.lock +1193 -32
  220. package/package.json +1 -1
  221. package/dist/lib/application/files/gadmin2-game-angle-demo/server/seed/seedDataMngtPages.ts +0 -258
  222. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/agentPanel/AgentPanel.tsx +0 -497
  223. package/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/agentPanel/skills.ts +0 -464
@@ -0,0 +1,476 @@
1
+ import React, { useState, useCallback, useRef, useEffect } from 'react';
2
+ import Editor, { type OnMount } from '@monaco-editor/react';
3
+ import { Button, Tooltip, Tabs } from 'antd';
4
+ import { CloseOutlined, CopyOutlined, CheckOutlined } from '@ant-design/icons';
5
+ import type { PropDoc, ComponentVariant } from './types';
6
+
7
+ type IStandaloneCodeEditor = Parameters<OnMount>[0];
8
+
9
+ // ─── Theme (reuse from ComponentCanvas) ──────────────────────────────────
10
+
11
+ const C = {
12
+ bg: '#ffffff',
13
+ editorBg: '#fafafa',
14
+ editorBorder: '#e5e5e5',
15
+ importBg: '#f0f4ff',
16
+ importBorder: '#dce6fd',
17
+ importText: '#3451b2',
18
+ text: '#1a1a1a',
19
+ textMuted: '#999',
20
+ accent: '#087ea4',
21
+ };
22
+
23
+ // ─── PropTable (simplified inline version) ───────────────────────────────────
24
+
25
+ const PropTable: React.FC<{ props: PropDoc[]; height: number }> = ({
26
+ props,
27
+ height,
28
+ }) => (
29
+ <div
30
+ style={{
31
+ height,
32
+ overflow: 'auto',
33
+ borderTop: `1px solid ${C.editorBorder}`,
34
+ }}
35
+ >
36
+ <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12 }}>
37
+ <thead>
38
+ <tr style={{ background: '#fafafa', position: 'sticky', top: 0 }}>
39
+ {['Prop', 'Type', 'Default', 'Description'].map((h) => (
40
+ <th
41
+ key={h}
42
+ style={{
43
+ padding: '6px 8px',
44
+ textAlign: 'left',
45
+ borderBottom: `1px solid ${C.editorBorder}`,
46
+ fontWeight: 600,
47
+ color: C.text,
48
+ }}
49
+ >
50
+ {h}
51
+ </th>
52
+ ))}
53
+ </tr>
54
+ </thead>
55
+ <tbody>
56
+ {props.map((p) => (
57
+ <tr key={p.name} style={{ borderBottom: `1px solid #f0f0f0` }}>
58
+ <td
59
+ style={{
60
+ padding: '5px 8px',
61
+ fontFamily: 'monospace',
62
+ color: C.accent,
63
+ fontWeight: 600,
64
+ }}
65
+ >
66
+ {p.name}
67
+ {p.required && <span style={{ color: '#f5222d' }}> *</span>}
68
+ </td>
69
+ <td
70
+ style={{
71
+ padding: '5px 8px',
72
+ fontFamily: 'monospace',
73
+ color: '#666',
74
+ fontSize: 11,
75
+ }}
76
+ >
77
+ {p.type}
78
+ </td>
79
+ <td style={{ padding: '5px 8px', color: '#999', fontSize: 11 }}>
80
+ {p.default ?? '—'}
81
+ </td>
82
+ <td style={{ padding: '5px 8px', color: '#444' }}>{p.desc}</td>
83
+ </tr>
84
+ ))}
85
+ </tbody>
86
+ </table>
87
+ </div>
88
+ );
89
+
90
+ // ─── CopyButton ──────────────────────────────────────────────────────────────
91
+
92
+ const CopyButton: React.FC<{ text: string }> = ({ text }) => {
93
+ const [copied, setCopied] = useState(false);
94
+ return (
95
+ <Tooltip title={copied ? '已复制' : '复制代码'}>
96
+ <Button
97
+ size="small"
98
+ type="text"
99
+ icon={
100
+ copied ? (
101
+ <CheckOutlined style={{ color: '#52c41a' }} />
102
+ ) : (
103
+ <CopyOutlined />
104
+ )
105
+ }
106
+ onClick={() => {
107
+ navigator.clipboard.writeText(text);
108
+ setCopied(true);
109
+ setTimeout(() => setCopied(false), 1500);
110
+ }}
111
+ style={{ fontSize: 12, color: C.textMuted }}
112
+ />
113
+ </Tooltip>
114
+ );
115
+ };
116
+
117
+ // ─── CodeFloatWindow ─────────────────────────────────────────────────────────
118
+
119
+ interface CodeFloatWindowProps {
120
+ componentType: string;
121
+ imports: string;
122
+ code: string;
123
+ props: PropDoc[];
124
+ variants: ComponentVariant[];
125
+ onChange: (code: string) => void;
126
+ onClose: () => void;
127
+ }
128
+
129
+ const MIN_W = 320;
130
+ const MIN_H = 240;
131
+
132
+ type ResizeEdge = 'n' | 's' | 'e' | 'w' | 'ne' | 'nw' | 'se' | 'sw';
133
+
134
+ const EDGE_CURSORS: Record<ResizeEdge, string> = {
135
+ n: 'n-resize',
136
+ s: 's-resize',
137
+ e: 'e-resize',
138
+ w: 'w-resize',
139
+ ne: 'ne-resize',
140
+ nw: 'nw-resize',
141
+ se: 'se-resize',
142
+ sw: 'sw-resize',
143
+ };
144
+
145
+ const CodeFloatWindow: React.FC<CodeFloatWindowProps> = ({
146
+ componentType,
147
+ imports,
148
+ code,
149
+ props,
150
+ variants,
151
+ onChange,
152
+ onClose,
153
+ }) => {
154
+ const [pos, setPos] = useState({ x: 200, y: 100 });
155
+ const [size, setSize] = useState({ w: 520, h: 500 });
156
+ const [propsHeight, setPropsHeight] = useState(160);
157
+ const dragging = useRef(false);
158
+ const dragStart = useRef({ x: 0, y: 0, px: 0, py: 0 });
159
+ const editorRef = useRef<IStandaloneCodeEditor | null>(null);
160
+
161
+ // 拖动标题栏
162
+ const handleTitleMouseDown = useCallback(
163
+ (e: React.MouseEvent) => {
164
+ e.preventDefault();
165
+ dragging.current = true;
166
+ dragStart.current = { x: e.clientX, y: e.clientY, px: pos.x, py: pos.y };
167
+
168
+ const onMove = (ev: MouseEvent) => {
169
+ if (!dragging.current) return;
170
+ setPos({
171
+ x: dragStart.current.px + (ev.clientX - dragStart.current.x),
172
+ y: dragStart.current.py + (ev.clientY - dragStart.current.y),
173
+ });
174
+ };
175
+ const onUp = () => {
176
+ dragging.current = false;
177
+ window.removeEventListener('mousemove', onMove);
178
+ window.removeEventListener('mouseup', onUp);
179
+ };
180
+ window.addEventListener('mousemove', onMove);
181
+ window.addEventListener('mouseup', onUp);
182
+ },
183
+ [pos],
184
+ );
185
+
186
+ // 拖拽边缘 resize
187
+ const handleEdgeMouseDown = useCallback(
188
+ (e: React.MouseEvent, edge: ResizeEdge) => {
189
+ e.preventDefault();
190
+ e.stopPropagation();
191
+ const startX = e.clientX;
192
+ const startY = e.clientY;
193
+ const startW = size.w;
194
+ const startH = size.h;
195
+ const startPx = pos.x;
196
+ const startPy = pos.y;
197
+
198
+ const onMove = (ev: MouseEvent) => {
199
+ const dx = ev.clientX - startX;
200
+ const dy = ev.clientY - startY;
201
+
202
+ setSize((prev) => {
203
+ let w = prev.w;
204
+ let h = prev.h;
205
+ if (edge.includes('e')) w = Math.max(MIN_W, startW + dx);
206
+ if (edge.includes('w')) w = Math.max(MIN_W, startW - dx);
207
+ if (edge.includes('s')) h = Math.max(MIN_H, startH + dy);
208
+ if (edge.includes('n')) h = Math.max(MIN_H, startH - dy);
209
+ return { w, h };
210
+ });
211
+
212
+ setPos((prev) => {
213
+ let x = prev.x;
214
+ let y = prev.y;
215
+ if (edge.includes('w')) x = startPx + Math.min(dx, startW - MIN_W);
216
+ if (edge.includes('n')) y = startPy + Math.min(dy, startH - MIN_H);
217
+ return { x, y };
218
+ });
219
+ };
220
+
221
+ const onUp = () => {
222
+ window.removeEventListener('mousemove', onMove);
223
+ window.removeEventListener('mouseup', onUp);
224
+ };
225
+ window.addEventListener('mousemove', onMove);
226
+ window.addEventListener('mouseup', onUp);
227
+ },
228
+ [size, pos],
229
+ );
230
+
231
+ // 同步外部 code 变化到 editor
232
+ useEffect(() => {
233
+ const editor = editorRef.current;
234
+ if (!editor) return;
235
+ const model = editor.getModel();
236
+ if (model && model.getValue() !== code) {
237
+ editor.executeEdits('external', [
238
+ {
239
+ range: model.getFullModelRange(),
240
+ text: code,
241
+ forceMoveMarkers: true,
242
+ },
243
+ ]);
244
+ }
245
+ }, [code]);
246
+
247
+ const handleMount: OnMount = useCallback((editor) => {
248
+ editorRef.current = editor;
249
+ }, []);
250
+
251
+ // Props 区域 resize
252
+ const handlePropsResize = useCallback(
253
+ (startY: number) => {
254
+ const startH = propsHeight;
255
+ const onMove = (e: MouseEvent) => {
256
+ const delta = e.clientY - startY;
257
+ setPropsHeight(Math.max(60, Math.min(size.h * 0.6, startH - delta)));
258
+ };
259
+ const onUp = () => {
260
+ window.removeEventListener('mousemove', onMove);
261
+ window.removeEventListener('mouseup', onUp);
262
+ };
263
+ window.addEventListener('mousemove', onMove);
264
+ window.addEventListener('mouseup', onUp);
265
+ },
266
+ [propsHeight, size.h],
267
+ );
268
+
269
+ const HANDLE = 6; // resize handle 宽度 px
270
+
271
+ return (
272
+ <div
273
+ style={{
274
+ position: 'fixed',
275
+ left: pos.x,
276
+ top: pos.y,
277
+ width: size.w,
278
+ height: size.h,
279
+ background: C.bg,
280
+ border: `1px solid ${C.editorBorder}`,
281
+ borderRadius: 8,
282
+ boxShadow: '0 8px 24px rgba(0,0,0,0.12)',
283
+ display: 'flex',
284
+ flexDirection: 'column',
285
+ zIndex: 1000,
286
+ overflow: 'hidden',
287
+ }}
288
+ >
289
+ {/* ── Resize handles (8 directions) ── */}
290
+ {(['n', 's', 'e', 'w', 'ne', 'nw', 'se', 'sw'] as ResizeEdge[]).map(
291
+ (edge) => {
292
+ const isN = edge.includes('n');
293
+ const isS = edge.includes('s');
294
+ const isE = edge.includes('e');
295
+ const isW = edge.includes('w');
296
+ const isCorner = edge.length === 2;
297
+ const cornerSize = HANDLE * 3;
298
+ return (
299
+ <div
300
+ key={edge}
301
+ onMouseDown={(e) => handleEdgeMouseDown(e, edge)}
302
+ style={{
303
+ position: 'absolute',
304
+ cursor: EDGE_CURSORS[edge],
305
+ zIndex: 10,
306
+ // edges
307
+ top: isCorner
308
+ ? isN
309
+ ? 0
310
+ : undefined
311
+ : isN
312
+ ? 0
313
+ : isS
314
+ ? undefined
315
+ : HANDLE,
316
+ bottom: isCorner
317
+ ? isS
318
+ ? 0
319
+ : undefined
320
+ : isS
321
+ ? 0
322
+ : isN
323
+ ? undefined
324
+ : HANDLE,
325
+ left: isCorner
326
+ ? isW
327
+ ? 0
328
+ : undefined
329
+ : isW
330
+ ? 0
331
+ : isE
332
+ ? undefined
333
+ : HANDLE,
334
+ right: isCorner
335
+ ? isE
336
+ ? 0
337
+ : undefined
338
+ : isE
339
+ ? 0
340
+ : isW
341
+ ? undefined
342
+ : HANDLE,
343
+ width: isCorner ? cornerSize : isE || isW ? HANDLE : undefined,
344
+ height: isCorner ? cornerSize : isN || isS ? HANDLE : undefined,
345
+ }}
346
+ />
347
+ );
348
+ },
349
+ )}
350
+ {/* 标题栏 */}
351
+ <div
352
+ onMouseDown={handleTitleMouseDown}
353
+ style={{
354
+ height: 36,
355
+ padding: '0 12px',
356
+ background: '#f7f7f7',
357
+ borderBottom: `1px solid ${C.editorBorder}`,
358
+ display: 'flex',
359
+ alignItems: 'center',
360
+ justifyContent: 'space-between',
361
+ cursor: 'move',
362
+ flexShrink: 0,
363
+ userSelect: 'none',
364
+ }}
365
+ >
366
+ <span style={{ fontSize: 13, fontWeight: 600, color: C.accent }}>
367
+ {componentType}
368
+ </span>
369
+ <div style={{ display: 'flex', gap: 4, alignItems: 'center' }}>
370
+ <CopyButton text={`${imports}\n\n${code}`} />
371
+ <Button
372
+ size="small"
373
+ type="text"
374
+ icon={<CloseOutlined />}
375
+ onClick={onClose}
376
+ style={{ color: C.textMuted }}
377
+ />
378
+ </div>
379
+ </div>
380
+
381
+ {/* Variant 切换 */}
382
+ {variants.length > 1 && (
383
+ <div
384
+ style={{
385
+ padding: '0 12px',
386
+ borderBottom: `1px solid ${C.editorBorder}`,
387
+ flexShrink: 0,
388
+ background: C.bg,
389
+ }}
390
+ >
391
+ <Tabs
392
+ size="small"
393
+ style={{ marginBottom: 0 }}
394
+ items={variants.map((v) => ({
395
+ key: v.name,
396
+ label: <span style={{ fontSize: 12 }}>{v.label}</span>,
397
+ }))}
398
+ onChange={(key) => {
399
+ const variant = variants.find((v) => v.name === key);
400
+ if (variant) onChange(variant.code);
401
+ }}
402
+ />
403
+ </div>
404
+ )}
405
+
406
+ {/* Imports(只读) */}
407
+ <div
408
+ style={{
409
+ background: C.importBg,
410
+ borderBottom: `1px solid ${C.importBorder}`,
411
+ padding: '6px 12px',
412
+ flexShrink: 0,
413
+ }}
414
+ >
415
+ <pre
416
+ style={{
417
+ margin: 0,
418
+ fontSize: 12,
419
+ color: C.importText,
420
+ fontFamily: "'Fira Mono', monospace",
421
+ lineHeight: 1.5,
422
+ whiteSpace: 'pre-wrap',
423
+ }}
424
+ >
425
+ {imports}
426
+ </pre>
427
+ </div>
428
+
429
+ {/* Monaco 编辑器 */}
430
+ <div style={{ flex: 1, minHeight: 0, overflow: 'hidden' }}>
431
+ <Editor
432
+ defaultLanguage="tsx"
433
+ value={code}
434
+ onChange={(val) => onChange(val ?? '')}
435
+ onMount={handleMount}
436
+ theme="vs"
437
+ options={{
438
+ minimap: { enabled: false },
439
+ fontSize: 13,
440
+ fontFamily: "'Fira Mono', monospace",
441
+ lineNumbers: 'on',
442
+ lineNumbersMinChars: 3,
443
+ scrollBeyondLastLine: false,
444
+ automaticLayout: true,
445
+ tabSize: 2,
446
+ renderLineHighlight: 'gutter',
447
+ }}
448
+ />
449
+ </div>
450
+
451
+ {/* Resize handle */}
452
+ <div
453
+ onMouseDown={(e) => {
454
+ e.preventDefault();
455
+ handlePropsResize(e.clientY);
456
+ }}
457
+ style={{
458
+ height: 4,
459
+ flexShrink: 0,
460
+ cursor: 'row-resize',
461
+ background: C.editorBorder,
462
+ transition: 'background 0.15s',
463
+ }}
464
+ onMouseEnter={(e) => (e.currentTarget.style.background = C.accent)}
465
+ onMouseLeave={(e) =>
466
+ (e.currentTarget.style.background = C.editorBorder)
467
+ }
468
+ />
469
+
470
+ {/* Props 表 */}
471
+ {props.length > 0 && <PropTable props={props} height={propsHeight} />}
472
+ </div>
473
+ );
474
+ };
475
+
476
+ export default CodeFloatWindow;
@@ -0,0 +1,135 @@
1
+ import React, { useEffect, useRef, memo } from 'react';
2
+ import { createRoot } from 'react-dom/client';
3
+ import type { Root } from 'react-dom/client';
4
+ import LivePreview from './LivePreview';
5
+ import { CANVAS_DEFAULTS } from './canvasDefaults';
6
+
7
+ // ─── Grid constants (same as CanvasPage) ─────────────────────────────────────
8
+ const GRID_COLS = 48;
9
+ const ROW_HEIGHT = 10;
10
+ const MARGIN = 8;
11
+ // Reference container width for computing pixel ratio (typical canvas width)
12
+ const CANVAS_REF_WIDTH = 1200;
13
+ const COL_WIDTH = (CANVAS_REF_WIDTH - MARGIN * (GRID_COLS + 1)) / GRID_COLS;
14
+
15
+ /** Compute real pixel height for h grid rows */
16
+ function gridH(h: number): number {
17
+ return h * ROW_HEIGHT + (h - 1) * MARGIN;
18
+ }
19
+ /** Compute real pixel width for w grid columns */
20
+ function gridW(w: number): number {
21
+ return w * COL_WIDTH + (w - 1) * MARGIN;
22
+ }
23
+
24
+ interface Props {
25
+ componentType: string;
26
+ code?: string;
27
+ width?: number;
28
+ }
29
+
30
+ const ComponentThumbnail: React.FC<Props> = memo(
31
+ ({ componentType, code: codeProp, width = 140 }) => {
32
+ const def = CANVAS_DEFAULTS[componentType];
33
+ const containerRef = useRef<HTMLDivElement>(null);
34
+ const rootRef = useRef<Root | null>(null);
35
+ const slotRef = useRef<HTMLDivElement | null>(null);
36
+
37
+ if (!def) return null;
38
+
39
+ const layout = def.layout;
40
+ const rawCode = codeProp ?? def.variants[0]?.code ?? def.code ?? '';
41
+
42
+ // Thumbnail frame: fixed width, height from real pixel ratio
43
+ const thumbW = width;
44
+ const pxW = gridW(layout.w);
45
+ const pxH = gridH(layout.h);
46
+ const thumbH = thumbW * (pxH / pxW);
47
+
48
+ // Virtual canvas: use real pixel dimensions as render size
49
+ const renderW = Math.round(pxW);
50
+ const renderH = Math.round(pxH);
51
+ const scale = thumbW / renderW;
52
+
53
+ // Replace existing height in code to match ratio; don't inject if none exists
54
+ const code = replaceExistingHeight(rawCode, renderH);
55
+
56
+ useEffect(() => {
57
+ const container = containerRef.current;
58
+ if (!container || !code) return;
59
+
60
+ cleanup();
61
+
62
+ const slot = document.createElement('div');
63
+ Object.assign(slot.style, {
64
+ position: 'absolute',
65
+ top: '0',
66
+ left: '0',
67
+ width: `${renderW}px`,
68
+ height: `${renderH}px`,
69
+ overflow: 'hidden',
70
+ transform: `scale(${scale})`,
71
+ transformOrigin: 'top left',
72
+ pointerEvents: 'none',
73
+ });
74
+
75
+ container.appendChild(slot);
76
+ slotRef.current = slot;
77
+
78
+ const root = createRoot(slot);
79
+ rootRef.current = root;
80
+ root.render(<LivePreview code={code} />);
81
+
82
+ return cleanup;
83
+
84
+ function cleanup() {
85
+ const r = rootRef.current;
86
+ const s = slotRef.current;
87
+ rootRef.current = null;
88
+ slotRef.current = null;
89
+ if (r) {
90
+ setTimeout(() => {
91
+ try {
92
+ r.unmount();
93
+ } catch {}
94
+ }, 0);
95
+ }
96
+ if (s && s.parentNode) {
97
+ s.parentNode.removeChild(s);
98
+ }
99
+ }
100
+ // eslint-disable-next-line react-hooks/exhaustive-deps
101
+ }, [code, renderW, renderH, scale]);
102
+
103
+ return (
104
+ <div
105
+ ref={containerRef}
106
+ style={{
107
+ width: thumbW,
108
+ height: thumbH,
109
+ overflow: 'hidden',
110
+ position: 'relative',
111
+ flexShrink: 0,
112
+ }}
113
+ />
114
+ );
115
+ },
116
+ );
117
+
118
+ ComponentThumbnail.displayName = 'ComponentThumbnail';
119
+ export default ComponentThumbnail;
120
+
121
+ // ─── Helper ──────────────────────────────────────────────────────────────────
122
+
123
+ /**
124
+ * If code already contains a height value, replace it with the correct ratio-based height.
125
+ * If no height exists, leave code untouched.
126
+ */
127
+ function replaceExistingHeight(code: string, h: number): string {
128
+ if (/height\s*=\s*\{[\s\d]+\}/.test(code)) {
129
+ return code.replace(/height\s*=\s*\{[\s\d]+\}/, `height={${h}}`);
130
+ }
131
+ if (/height\s*:\s*\d+/.test(code)) {
132
+ return code.replace(/height\s*:\s*\d+/, `height: ${h}`);
133
+ }
134
+ return code;
135
+ }
@@ -0,0 +1,101 @@
1
+ /**
2
+ * IsolatedLivePreview
3
+ *
4
+ * Renders LivePreview in a completely separate React root so that:
5
+ * 1. antd v6 Spin (rc-motion ClassComponent) setState callbacks, which throw under
6
+ * React 19's commitCallbacks, are silenced per-root via onUncaughtError / onCaughtError
7
+ * and never propagate to the main app's defaultOnUncaughtError.
8
+ * 2. Any other runtime errors inside the preview are contained.
9
+ *
10
+ * The host div is a plain flex container; the inner root owns its own DOM node.
11
+ *
12
+ * Lifecycle notes:
13
+ * - On mount: create DOM node + createRoot, render LivePreview.
14
+ * - On `code` change (useEffect dep): unmount old root asynchronously,
15
+ * create a fresh root synchronously. This avoids the "synchronously unmount
16
+ * a root while React is already rendering" error in React 19 Strict Mode.
17
+ * - On unmount: deferred unmount + remove of the inner div.
18
+ */
19
+ import React, { useEffect, useRef } from 'react';
20
+ import { createRoot } from 'react-dom/client';
21
+ import type { Root } from 'react-dom/client';
22
+ import LivePreview from './LivePreview';
23
+
24
+ interface IsolatedLivePreviewProps {
25
+ code: string;
26
+ style?: React.CSSProperties;
27
+ }
28
+
29
+ const IsolatedLivePreview: React.FC<IsolatedLivePreviewProps> = ({
30
+ code,
31
+ style,
32
+ }) => {
33
+ const hostRef = useRef<HTMLDivElement>(null);
34
+ const rootRef = useRef<Root | null>(null);
35
+ const innerRef = useRef<HTMLDivElement | null>(null);
36
+
37
+ useEffect(() => {
38
+ const host = hostRef.current;
39
+ if (!host) return;
40
+
41
+ // ── Tear down any previous root (deferred so we never call unmount
42
+ // synchronously during React's commit phase).
43
+ const prevRoot = rootRef.current;
44
+ const prevInner = innerRef.current;
45
+ rootRef.current = null;
46
+ innerRef.current = null;
47
+
48
+ if (prevRoot || prevInner) {
49
+ setTimeout(() => {
50
+ try {
51
+ prevRoot?.unmount();
52
+ } catch {
53
+ /* ignore */
54
+ }
55
+ try {
56
+ prevInner?.remove();
57
+ } catch {
58
+ /* ignore */
59
+ }
60
+ }, 0);
61
+ }
62
+
63
+ // ── Create fresh inner div + root
64
+ const inner = document.createElement('div');
65
+ inner.style.cssText = 'width:100%;height:100%';
66
+ host.appendChild(inner);
67
+ innerRef.current = inner;
68
+
69
+ const root = createRoot(inner);
70
+ rootRef.current = root;
71
+ root.render(<LivePreview code={code} />);
72
+
73
+ return () => {
74
+ // Cleanup on unmount or before next effect run
75
+ const r = rootRef.current;
76
+ const d = innerRef.current;
77
+ rootRef.current = null;
78
+ innerRef.current = null;
79
+ setTimeout(() => {
80
+ try {
81
+ r?.unmount();
82
+ } catch {
83
+ /* ignore */
84
+ }
85
+ try {
86
+ d?.remove();
87
+ } catch {
88
+ /* ignore */
89
+ }
90
+ }, 0);
91
+ };
92
+ // Re-run when code changes so the preview always reflects the latest code.
93
+ // eslint-disable-next-line react-hooks/exhaustive-deps
94
+ }, [code]);
95
+
96
+ return (
97
+ <div ref={hostRef} style={{ width: '100%', height: '100%', ...style }} />
98
+ );
99
+ };
100
+
101
+ export default IsolatedLivePreview;