@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
@@ -1,5 +1,12 @@
1
+ import {
2
+ CheckCircleOutlined,
3
+ EditOutlined,
4
+ ExclamationCircleOutlined,
5
+ FormOutlined,
6
+ } from '@ant-design/icons';
7
+ import { Dropdown, Input, message, Modal, Select, theme } from 'antd';
8
+ import { modelsMap } from 'generated/models.index';
1
9
  import React, { useCallback, useEffect, useRef, useState } from 'react';
2
- import { Dropdown, Input, Modal } from 'antd';
3
10
  import { useAgent } from './AgentContext';
4
11
  import { AgentType } from './agentAttributes';
5
12
  import {
@@ -7,17 +14,607 @@ import {
7
14
  InspectedElementInfo,
8
15
  InspectorAction,
9
16
  } from './inspectorActions';
17
+ import { generatePrompt } from './promptGenerator';
18
+ import {
19
+ patchBooleanProp,
20
+ patchEnumProp,
21
+ patchStringProp,
22
+ readBooleanProp,
23
+ } from './propPatcher';
10
24
 
11
25
  const TYPE_LABELS: Record<AgentType, string> = {
12
- 'table-column': '表格列',
26
+ 'list-column': '表格列',
13
27
  'form-field': '表单字段',
14
28
  'show-field': '详情字段',
15
- 'search-bar': '搜索栏',
29
+ 'list-search-bar': '搜索栏',
16
30
  'list-header': '列表头部',
17
- 'row-actions': '行操作',
18
- 'bulk-actions': '批量操作',
31
+ 'list-row-actions': '行操作',
32
+ 'list-bulk-actions': '批量操作',
33
+ 'canvas-component': '画布组件',
34
+ 'show-header': '详情页工具栏',
35
+ 'app-header': 'App 顶部导航',
36
+ 'app-title': 'Logo 和标题',
19
37
  };
20
38
 
39
+ /** Get all field names for a resource from the generated models map. */
40
+ function getModelFields(resource: string): { name: string; type: string }[] {
41
+ // modelsMap keys are PascalCase (e.g. "Event"), resource is camelCase (e.g. "event")
42
+ const key = resource.charAt(0).toUpperCase() + resource.slice(1);
43
+ const entry = (modelsMap as Record<string, { model: Record<string, any> }>)[
44
+ key
45
+ ];
46
+ if (!entry?.model) return [];
47
+ return Object.values(entry.model).map((f) => ({
48
+ name: f.name as string,
49
+ type: f.type as string,
50
+ }));
51
+ }
52
+
53
+ /** Collect fields already rendered on the current page. */
54
+ function getVisibleFields(type: AgentType): string[] {
55
+ const selector =
56
+ type === 'list-column'
57
+ ? '[data-agent-type="list-column"][data-agent-field]'
58
+ : type === 'form-field'
59
+ ? '[data-agent-type="form-field"][data-agent-field]'
60
+ : '[data-agent-type="show-field"][data-agent-field]';
61
+ return Array.from(document.querySelectorAll<HTMLElement>(selector))
62
+ .map((el) => el.dataset.agentField!)
63
+ .filter(Boolean);
64
+ }
65
+
66
+ /** Returns fields that exist in the model but are not currently displayed. */
67
+ function getHiddenFields(
68
+ resource: string,
69
+ type: AgentType,
70
+ ): { name: string; type: string }[] {
71
+ const visible = new Set(getVisibleFields(type));
72
+ return getModelFields(resource).filter((f) => !visible.has(f.name));
73
+ }
74
+
75
+ /** Confirm modal shown after user picks a field from the sub-menu. */
76
+ interface FieldConfirmModalProps {
77
+ open: boolean;
78
+ actionLabel: string;
79
+ fieldName: string;
80
+ onOk: () => void;
81
+ onCancel: () => void;
82
+ }
83
+
84
+ const FieldConfirmModal: React.FC<FieldConfirmModalProps> = ({
85
+ open,
86
+ actionLabel,
87
+ fieldName,
88
+ onOk,
89
+ onCancel,
90
+ }) => {
91
+ const { token } = theme.useToken();
92
+ return (
93
+ <Modal
94
+ title={
95
+ <span style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
96
+ <span
97
+ style={{
98
+ display: 'inline-flex',
99
+ alignItems: 'center',
100
+ justifyContent: 'center',
101
+ width: 28,
102
+ height: 28,
103
+ borderRadius: '50%',
104
+ background: token.colorSuccessBg,
105
+ color: token.colorSuccess,
106
+ fontSize: 14,
107
+ flexShrink: 0,
108
+ }}
109
+ >
110
+ <CheckCircleOutlined />
111
+ </span>
112
+ <span style={{ fontWeight: 600, fontSize: 15 }}>确认操作</span>
113
+ </span>
114
+ }
115
+ open={open}
116
+ onOk={onOk}
117
+ onCancel={onCancel}
118
+ okText="确认"
119
+ cancelText="取消"
120
+ zIndex={10010}
121
+ width={400}
122
+ styles={{
123
+ header: {
124
+ padding: '16px 20px 12px',
125
+ borderBottom: `1px solid ${token.colorBorderSecondary}`,
126
+ marginBottom: 0,
127
+ },
128
+ body: { padding: '16px 20px 8px' },
129
+ footer: { padding: '12px 20px 16px' },
130
+ }}
131
+ okButtonProps={{ style: { borderRadius: 6 } }}
132
+ cancelButtonProps={{ style: { borderRadius: 6 } }}
133
+ >
134
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
135
+ <div
136
+ style={{
137
+ padding: '8px 12px',
138
+ background: token.colorFillQuaternary,
139
+ borderRadius: token.borderRadiusLG,
140
+ border: `1px solid ${token.colorBorderSecondary}`,
141
+ }}
142
+ >
143
+ <div
144
+ style={{
145
+ fontSize: 11,
146
+ fontWeight: 500,
147
+ color: token.colorTextTertiary,
148
+ letterSpacing: '0.02em',
149
+ textTransform: 'uppercase',
150
+ marginBottom: 4,
151
+ }}
152
+ >
153
+ 操作
154
+ </div>
155
+ <div style={{ fontSize: 13, color: token.colorText }}>
156
+ {actionLabel}
157
+ </div>
158
+ </div>
159
+ <div
160
+ style={{
161
+ padding: '8px 12px',
162
+ background: token.colorPrimaryBg,
163
+ borderRadius: token.borderRadiusLG,
164
+ border: `1px solid ${token.colorPrimaryBorder}`,
165
+ }}
166
+ >
167
+ <div
168
+ style={{
169
+ fontSize: 11,
170
+ fontWeight: 500,
171
+ color: token.colorTextTertiary,
172
+ letterSpacing: '0.02em',
173
+ textTransform: 'uppercase',
174
+ marginBottom: 4,
175
+ }}
176
+ >
177
+ 选中字段
178
+ </div>
179
+ <div
180
+ style={{
181
+ fontSize: 14,
182
+ fontWeight: 600,
183
+ color: token.colorPrimary,
184
+ fontFamily: 'monospace',
185
+ }}
186
+ >
187
+ {fieldName}
188
+ </div>
189
+ </div>
190
+ </div>
191
+ </Modal>
192
+ );
193
+ };
194
+
195
+ interface ConfirmModalProps {
196
+ open: boolean;
197
+ action: InspectorAction | null;
198
+ onOk: () => void;
199
+ onCancel: () => void;
200
+ }
201
+
202
+ const ConfirmModal: React.FC<ConfirmModalProps> = ({
203
+ open,
204
+ action,
205
+ onOk,
206
+ onCancel,
207
+ }) => {
208
+ const { token } = theme.useToken();
209
+ return (
210
+ <Modal
211
+ title={
212
+ <span style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
213
+ <ExclamationCircleOutlined style={{ color: token.colorWarning }} />
214
+ <span style={{ fontWeight: 600, fontSize: 15 }}>{action?.label}</span>
215
+ </span>
216
+ }
217
+ open={open}
218
+ onOk={onOk}
219
+ onCancel={onCancel}
220
+ okText="确认"
221
+ cancelText="取消"
222
+ zIndex={10010}
223
+ width={360}
224
+ styles={{
225
+ header: { borderBottom: 'none', paddingBottom: 8 },
226
+ body: { padding: '4px 20px 8px' },
227
+ footer: { borderTop: 'none' },
228
+ }}
229
+ >
230
+ {action?.confirmDescription && (
231
+ <p
232
+ style={{
233
+ margin: 0,
234
+ fontSize: 13,
235
+ color: token.colorTextSecondary,
236
+ lineHeight: '1.6',
237
+ }}
238
+ >
239
+ {action.confirmDescription}
240
+ </p>
241
+ )}
242
+ </Modal>
243
+ );
244
+ };
245
+
246
+ interface FreeInputModalProps {
247
+ open: boolean;
248
+ mode: 'freeInput' | 'requiresInput';
249
+ action: InspectorAction | null;
250
+ value: string;
251
+ onChange: (v: string) => void;
252
+ onOk: () => void;
253
+ onCancel: () => void;
254
+ }
255
+
256
+ const FreeInputModal: React.FC<FreeInputModalProps> = ({
257
+ open,
258
+ mode,
259
+ action,
260
+ value,
261
+ onChange,
262
+ onOk,
263
+ onCancel,
264
+ }) => {
265
+ const { token } = theme.useToken();
266
+ const isRequiresInput = mode === 'requiresInput';
267
+ const Icon = isRequiresInput ? EditOutlined : FormOutlined;
268
+ const actionLabel = action?.label;
269
+
270
+ return (
271
+ <Modal
272
+ title={
273
+ <span style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
274
+ <span
275
+ style={{
276
+ display: 'inline-flex',
277
+ alignItems: 'center',
278
+ justifyContent: 'center',
279
+ width: 28,
280
+ height: 28,
281
+ borderRadius: '50%',
282
+ background: isRequiresInput
283
+ ? token.colorPrimaryBg
284
+ : token.colorInfoBg,
285
+ color: isRequiresInput ? token.colorPrimary : token.colorInfo,
286
+ fontSize: 14,
287
+ flexShrink: 0,
288
+ }}
289
+ >
290
+ <Icon />
291
+ </span>
292
+ <span style={{ fontWeight: 600, fontSize: 15 }}>
293
+ {isRequiresInput ? '补充说明' : '输入自定义需求'}
294
+ </span>
295
+ </span>
296
+ }
297
+ open={open}
298
+ onOk={onOk}
299
+ onCancel={onCancel}
300
+ okText="确认发送"
301
+ cancelText="取消"
302
+ zIndex={10010}
303
+ width={480}
304
+ styles={{
305
+ header: {
306
+ padding: '16px 20px 12px',
307
+ borderBottom: `1px solid ${token.colorBorderSecondary}`,
308
+ marginBottom: 0,
309
+ },
310
+ body: { padding: '16px 20px 8px' },
311
+ footer: { padding: '12px 20px 16px' },
312
+ }}
313
+ okButtonProps={{
314
+ style: { borderRadius: 6 },
315
+ disabled: mode === 'requiresInput' && !value.trim(),
316
+ }}
317
+ cancelButtonProps={{ style: { borderRadius: 6 } }}
318
+ >
319
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
320
+ {/* 操作上下文提示区 */}
321
+ {actionLabel && (
322
+ <div
323
+ style={{
324
+ display: 'flex',
325
+ alignItems: 'flex-start',
326
+ gap: 8,
327
+ padding: '8px 12px',
328
+ background: token.colorFillQuaternary,
329
+ borderRadius: token.borderRadiusLG,
330
+ border: `1px solid ${token.colorBorderSecondary}`,
331
+ }}
332
+ >
333
+ <span
334
+ style={{
335
+ fontSize: 11,
336
+ fontWeight: 500,
337
+ color: token.colorTextTertiary,
338
+ whiteSpace: 'nowrap',
339
+ marginTop: 1,
340
+ letterSpacing: '0.02em',
341
+ textTransform: 'uppercase',
342
+ }}
343
+ >
344
+ 当前操作
345
+ </span>
346
+ <span
347
+ style={{
348
+ fontSize: 13,
349
+ color: token.colorTextSecondary,
350
+ fontWeight: 500,
351
+ lineHeight: '20px',
352
+ }}
353
+ >
354
+ {actionLabel}
355
+ </span>
356
+ </div>
357
+ )}
358
+
359
+ {/* 说明文字 */}
360
+ <p
361
+ style={{
362
+ margin: 0,
363
+ fontSize: 13,
364
+ color: token.colorTextTertiary,
365
+ lineHeight: '20px',
366
+ }}
367
+ >
368
+ {isRequiresInput
369
+ ? '请补充具体要求,AI 将在执行操作时参考你的说明。'
370
+ : '请描述你希望 AI 执行的自定义操作。'}
371
+ </p>
372
+
373
+ {/* TextArea */}
374
+ <Input.TextArea
375
+ autoFocus
376
+ rows={4}
377
+ value={value}
378
+ onChange={(e) => onChange(e.target.value)}
379
+ placeholder={
380
+ isRequiresInput
381
+ ? action?.inputPlaceholder || '请补充具体要求...'
382
+ : '请描述你想要的自定义操作...'
383
+ }
384
+ style={{
385
+ borderRadius: token.borderRadiusLG,
386
+ fontSize: 13,
387
+ lineHeight: '1.6',
388
+ resize: 'none',
389
+ }}
390
+ styles={{ textarea: { padding: '10px 12px' } }}
391
+ onPressEnter={(e) => {
392
+ if (e.metaKey || e.ctrlKey) {
393
+ if (mode === 'requiresInput' && !value.trim()) return;
394
+ onOk();
395
+ }
396
+ }}
397
+ />
398
+
399
+ {/* 快捷键提示 */}
400
+ <p
401
+ style={{
402
+ margin: 0,
403
+ fontSize: 12,
404
+ color: token.colorTextQuaternary,
405
+ textAlign: 'right',
406
+ }}
407
+ >
408
+ 按 ⌘ Enter 快速确认
409
+ </p>
410
+ </div>
411
+ </Modal>
412
+ );
413
+ };
414
+
415
+ // ── QuickSelectModal ───────────────────────────────────────────────────────────────────
416
+
417
+ interface QuickSelectModalProps {
418
+ open: boolean;
419
+ action: InspectorAction | null;
420
+ onOk: (value: string) => void;
421
+ onCancel: () => void;
422
+ }
423
+
424
+ const QuickSelectModal: React.FC<QuickSelectModalProps> = ({
425
+ open,
426
+ action,
427
+ onOk,
428
+ onCancel,
429
+ }) => {
430
+ const { token } = theme.useToken();
431
+ const [value, setValue] = useState<string>('');
432
+
433
+ useEffect(() => {
434
+ if (open) setValue('');
435
+ }, [open]);
436
+
437
+ return (
438
+ <Modal
439
+ title={
440
+ <span style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
441
+ <span style={{ fontWeight: 600, fontSize: 15 }}>
442
+ {action?.label ?? '选择'}
443
+ </span>
444
+ </span>
445
+ }
446
+ open={open}
447
+ onOk={() => value && onOk(value)}
448
+ onCancel={onCancel}
449
+ okText="确认"
450
+ cancelText="取消"
451
+ okButtonProps={{
452
+ disabled: !value,
453
+ style: { borderRadius: token.borderRadius },
454
+ }}
455
+ cancelButtonProps={{ style: { borderRadius: token.borderRadius } }}
456
+ zIndex={10010}
457
+ width={400}
458
+ styles={{
459
+ body: { padding: '16px 20px 8px' },
460
+ footer: { padding: '12px 20px 16px' },
461
+ }}
462
+ >
463
+ <Select
464
+ autoFocus
465
+ style={{ width: '100%' }}
466
+ placeholder="请选择..."
467
+ value={value || undefined}
468
+ onChange={setValue}
469
+ options={action?.quickSelectOptions?.map((o) => ({
470
+ label: o.label,
471
+ value: o.value,
472
+ }))}
473
+ size="large"
474
+ />
475
+ </Modal>
476
+ );
477
+ };
478
+
479
+ // ── QuickInputModal ───────────────────────────────────────────────────────────────────
480
+
481
+ interface QuickInputModalProps {
482
+ open: boolean;
483
+ action: InspectorAction | null;
484
+ onOk: (value: string) => void;
485
+ onCancel: () => void;
486
+ }
487
+
488
+ const QuickInputModal: React.FC<QuickInputModalProps> = ({
489
+ open,
490
+ action,
491
+ onOk,
492
+ onCancel,
493
+ }) => {
494
+ const { token } = theme.useToken();
495
+ const [value, setValue] = useState('');
496
+
497
+ useEffect(() => {
498
+ if (open) setValue('');
499
+ }, [open]);
500
+
501
+ return (
502
+ <Modal
503
+ title={
504
+ <span style={{ fontWeight: 600, fontSize: 15 }}>
505
+ {action?.label ?? '修改'}
506
+ </span>
507
+ }
508
+ open={open}
509
+ onOk={() => onOk(value.trim())}
510
+ onCancel={onCancel}
511
+ okText="确认"
512
+ cancelText="取消"
513
+ okButtonProps={{ style: { borderRadius: token.borderRadius } }}
514
+ cancelButtonProps={{ style: { borderRadius: token.borderRadius } }}
515
+ zIndex={10010}
516
+ width={400}
517
+ styles={{
518
+ body: { padding: '16px 20px 8px' },
519
+ footer: { padding: '12px 20px 16px' },
520
+ }}
521
+ >
522
+ <Input
523
+ autoFocus
524
+ size="large"
525
+ value={value}
526
+ onChange={(e) => setValue(e.target.value)}
527
+ placeholder={action?.quickInputPlaceholder ?? '输入新值'}
528
+ onPressEnter={() => onOk(value.trim())}
529
+ />
530
+ </Modal>
531
+ );
532
+ };
533
+
534
+ function buildMenuItems(
535
+ actions: InspectorAction[],
536
+ handleAction: (a: InspectorAction) => void,
537
+ hiddenFields: { name: string; type: string }[],
538
+ onFieldPick: (action: InspectorAction, field: string) => void,
539
+ ): any[] {
540
+ return actions.map((action) => {
541
+ if (action.fieldSubMenu) {
542
+ const fieldChildren =
543
+ hiddenFields.length > 0
544
+ ? [
545
+ {
546
+ key: `${action.label}::__header`,
547
+ label: (
548
+ <span
549
+ style={{
550
+ fontSize: 11,
551
+ color: '#8c8c8c',
552
+ fontWeight: 500,
553
+ letterSpacing: '0.02em',
554
+ }}
555
+ >
556
+ 选择需要添加的字段
557
+ </span>
558
+ ),
559
+ disabled: true,
560
+ },
561
+ ...hiddenFields.map((f) => ({
562
+ key: `${action.label}::${f.name}`,
563
+ label: (
564
+ <span
565
+ style={{
566
+ display: 'flex',
567
+ alignItems: 'center',
568
+ justifyContent: 'space-between',
569
+ gap: 12,
570
+ }}
571
+ >
572
+ <span>{f.name}</span>
573
+ <span
574
+ style={{
575
+ fontSize: 11,
576
+ color: '#1677ff',
577
+ background: '#e6f4ff',
578
+ padding: '1px 6px',
579
+ borderRadius: 4,
580
+ fontFamily: 'monospace',
581
+ flexShrink: 0,
582
+ }}
583
+ >
584
+ {f.type}
585
+ </span>
586
+ </span>
587
+ ),
588
+ onClick: () => onFieldPick(action, f.name),
589
+ })),
590
+ ]
591
+ : [{ key: '__empty', label: '(无可添加字段)', disabled: true }];
592
+ return {
593
+ key: action.label,
594
+ label: action.label,
595
+ children: fieldChildren,
596
+ };
597
+ }
598
+ if (action.children && action.children.length > 0) {
599
+ return {
600
+ key: action.label,
601
+ label: action.label,
602
+ children: buildMenuItems(
603
+ action.children,
604
+ handleAction,
605
+ hiddenFields,
606
+ onFieldPick,
607
+ ),
608
+ };
609
+ }
610
+ return {
611
+ key: action.label,
612
+ label: action.label,
613
+ onClick: () => handleAction(action),
614
+ };
615
+ });
616
+ }
617
+
21
618
  function findAgentElement(x: number, y: number): HTMLElement | null {
22
619
  const elements = document.elementsFromPoint(x, y);
23
620
  for (const el of elements) {
@@ -53,28 +650,40 @@ export const ElementInspector: React.FC = () => {
53
650
  const [menuOpen, setMenuOpen] = useState(false);
54
651
  const [freeInputVisible, setFreeInputVisible] = useState(false);
55
652
  const [freeInputValue, setFreeInputValue] = useState('');
653
+ const [freeInputMode, setFreeInputMode] = useState<
654
+ 'freeInput' | 'requiresInput'
655
+ >('freeInput');
56
656
  const pendingActionRef = useRef<InspectorAction | null>(null);
657
+ const pendingMenuInfoRef = useRef<InspectedElementInfo | null>(null);
658
+
659
+ // requiresConfirm state
660
+ const [confirmVisible, setConfirmVisible] = useState(false);
661
+
662
+ // Field sub-menu state
663
+ const [fieldConfirmVisible, setFieldConfirmVisible] = useState(false);
664
+ const [fieldConfirmField, setFieldConfirmField] = useState('');
665
+ const pendingFieldActionRef = useRef<InspectorAction | null>(null);
57
666
 
58
667
  const inspecting = agent?.inspecting ?? false;
59
668
 
60
- const handleMouseMove = useCallback(
61
- (e: MouseEvent) => {
62
- const el = findAgentElement(e.clientX, e.clientY);
63
- if (el) {
64
- const rect = el.getBoundingClientRect();
65
- setHighlight(rect);
66
- const type = el.dataset.agentType as AgentType;
67
- const field = el.dataset.agentField;
68
- setLabel(
69
- `${TYPE_LABELS[type] || type}${field ? ': ' + field : ''}`,
70
- );
71
- } else {
72
- setHighlight(null);
73
- setLabel('');
74
- }
75
- },
76
- [],
77
- );
669
+ // Fetch hidden fields when menu opens
670
+ const hiddenFields = menuOpen
671
+ ? getHiddenFields(menuInfo?.resource ?? '', menuInfo?.type ?? 'list-column')
672
+ : [];
673
+
674
+ const handleMouseMove = useCallback((e: MouseEvent) => {
675
+ const el = findAgentElement(e.clientX, e.clientY);
676
+ if (el) {
677
+ const rect = el.getBoundingClientRect();
678
+ setHighlight(rect);
679
+ const type = el.dataset.agentType as AgentType;
680
+ const field = el.dataset.agentField;
681
+ setLabel(`${TYPE_LABELS[type] || type}${field ? ': ' + field : ''}`);
682
+ } else {
683
+ setHighlight(null);
684
+ setLabel('');
685
+ }
686
+ }, []);
78
687
 
79
688
  const handleClick = useCallback(
80
689
  (e: MouseEvent) => {
@@ -85,7 +694,6 @@ export const ElementInspector: React.FC = () => {
85
694
 
86
695
  const rect = el.getBoundingClientRect();
87
696
  const info = parseElementInfo(el, e.clientX, e.clientY);
88
- agent?.stopInspecting();
89
697
  // keep highlight visible while menu is open
90
698
  setHighlight(rect);
91
699
  setMenuRect(rect);
@@ -106,7 +714,7 @@ export const ElementInspector: React.FC = () => {
106
714
  );
107
715
 
108
716
  useEffect(() => {
109
- if (!inspecting) return;
717
+ if (!inspecting || menuOpen) return;
110
718
  document.addEventListener('mousemove', handleMouseMove, true);
111
719
  document.addEventListener('click', handleClick, true);
112
720
  document.addEventListener('keydown', handleKeyDown, true);
@@ -115,78 +723,311 @@ export const ElementInspector: React.FC = () => {
115
723
  document.removeEventListener('click', handleClick, true);
116
724
  document.removeEventListener('keydown', handleKeyDown, true);
117
725
  };
118
- }, [inspecting, handleMouseMove, handleClick, handleKeyDown]);
726
+ }, [inspecting, menuOpen, handleMouseMove, handleClick, handleKeyDown]);
727
+
728
+ // Clear transient UI state when inspect mode is stopped externally
729
+ // (e.g. dev-shell toggle button calls agent.stopInspecting() directly,
730
+ // bypassing all the individual event handlers that normally reset state).
731
+ useEffect(() => {
732
+ if (!inspecting) {
733
+ setHighlight(null);
734
+ setLabel('');
735
+ setMenuOpen(false);
736
+ setMenuInfo(null);
737
+ setMenuRect(null);
738
+ }
739
+ }, [inspecting]);
119
740
 
120
741
  const applyAction = useCallback(
121
742
  (action: InspectorAction, prompt?: string) => {
122
- if (!agent || !menuInfo) return;
123
- agent.setSelectedSkillId(action.skillId);
124
- agent.setSelectedSubSkillId(action.subSkillId);
125
- agent.setUserPrompt(prompt || action.promptTemplate || '');
126
- agent.setInspectedElement(menuInfo);
127
- agent.open();
743
+ if (!agent) return;
744
+ const resolvedMenuInfo = pendingMenuInfoRef.current || menuInfo;
745
+ if (!resolvedMenuInfo) return;
746
+ const userPrompt = prompt || action.promptTemplate || '';
747
+ const finalPrompt = generatePrompt({
748
+ skill: action.skill,
749
+ pageInfo: agent.pageInfo,
750
+ userPrompt,
751
+ inspectedElement: resolvedMenuInfo,
752
+ });
753
+ agent.setSelectedSkillId(action.skill);
754
+ agent.setSelectedSubSkillId(null);
755
+ agent.setUserPrompt(userPrompt);
756
+ agent.setInspectedElement(resolvedMenuInfo);
757
+ agent.sendPrompt(finalPrompt);
758
+ agent.stopInspecting();
759
+ setMenuOpen(false);
760
+ setMenuInfo(null);
761
+ setMenuRect(null);
762
+ setHighlight(null);
763
+ pendingMenuInfoRef.current = null;
764
+ },
765
+ [agent, menuInfo],
766
+ );
767
+
768
+ // 快捷操作:直接替换 code 中的 prop,通过 canvas-patch 推送
769
+ const applyPatch = useCallback(
770
+ async (newCode: string) => {
771
+ const resolvedMenuInfo = pendingMenuInfoRef.current || menuInfo;
772
+ if (!resolvedMenuInfo) return;
773
+ const itemId = resolvedMenuInfo.meta?.canvasItemId;
774
+ if (!itemId) {
775
+ message.error('找不到 Canvas Item ID');
776
+ return;
777
+ }
778
+ try {
779
+ const res = await fetch('/canvas-patch', {
780
+ method: 'POST',
781
+ headers: { 'Content-Type': 'application/json' },
782
+ body: JSON.stringify({ itemId, code: newCode }),
783
+ });
784
+ if (!res.ok) throw new Error('请求失败');
785
+ } catch {
786
+ message.error('画布更新失败,请确认 dev server 是否运行');
787
+ }
788
+ agent?.stopInspecting();
128
789
  setMenuOpen(false);
129
790
  setMenuInfo(null);
130
791
  setMenuRect(null);
131
792
  setHighlight(null);
793
+ pendingMenuInfoRef.current = null;
794
+ pendingActionRef.current = null;
132
795
  },
133
796
  [agent, menuInfo],
134
797
  );
135
798
 
136
799
  const handleMenuAction = useCallback(
137
800
  (action: InspectorAction) => {
801
+ // quickToggle: 直接切换 boolean prop,无需弹框
802
+ if (action.quickToggle && action.propName) {
803
+ const currentCode = menuInfo?.meta?.code ?? '';
804
+ pendingMenuInfoRef.current = menuInfo;
805
+ const currentVal = readBooleanProp(
806
+ currentCode,
807
+ action.propName,
808
+ action.defaultValue ?? true,
809
+ );
810
+ const newCode = patchBooleanProp(
811
+ currentCode,
812
+ action.propName,
813
+ !currentVal,
814
+ );
815
+ setMenuOpen(false);
816
+ applyPatch(newCode);
817
+ return;
818
+ }
819
+
820
+ // quickSelect: 弹出下拉选择框
821
+ if (action.quickSelect) {
822
+ pendingActionRef.current = action;
823
+ pendingMenuInfoRef.current = menuInfo;
824
+ setMenuOpen(false);
825
+ setQuickSelectVisible(true);
826
+ return;
827
+ }
828
+
829
+ // quickInput: 弹出输入框
830
+ if (action.quickInput) {
831
+ pendingActionRef.current = action;
832
+ pendingMenuInfoRef.current = menuInfo;
833
+ setMenuOpen(false);
834
+ setQuickInputVisible(true);
835
+ return;
836
+ }
837
+
838
+ // openDialog: 弹出自由对话框(复用 freeInput 逻辑)
839
+ if (action.openDialog) {
840
+ pendingActionRef.current = { ...action, freeInput: true, skill: null };
841
+ pendingMenuInfoRef.current = menuInfo;
842
+ setFreeInputValue('');
843
+ setFreeInputMode('freeInput');
844
+ setFreeInputVisible(true);
845
+ setMenuOpen(false);
846
+ return;
847
+ }
848
+
138
849
  if (action.freeInput) {
139
850
  pendingActionRef.current = action;
851
+ pendingMenuInfoRef.current = menuInfo;
852
+ setFreeInputValue('');
853
+ setFreeInputMode('freeInput');
854
+ setFreeInputVisible(true);
855
+ setMenuOpen(false);
856
+ return;
857
+ }
858
+ if (action.requiresInput) {
859
+ pendingActionRef.current = action;
860
+ pendingMenuInfoRef.current = menuInfo;
140
861
  setFreeInputValue('');
862
+ setFreeInputMode('requiresInput');
141
863
  setFreeInputVisible(true);
142
864
  setMenuOpen(false);
143
865
  return;
144
866
  }
867
+ if (action.requiresConfirm) {
868
+ pendingActionRef.current = action;
869
+ pendingMenuInfoRef.current = menuInfo;
870
+ setConfirmVisible(true);
871
+ setMenuOpen(false);
872
+ return;
873
+ }
145
874
  applyAction(action);
146
875
  },
147
- [applyAction],
876
+ [applyAction, menuInfo],
877
+ );
878
+
879
+ const handleConfirmOk = useCallback(() => {
880
+ const action = pendingActionRef.current;
881
+ if (action) applyAction(action);
882
+ setConfirmVisible(false);
883
+ pendingActionRef.current = null;
884
+ }, [applyAction]);
885
+
886
+ const handleConfirmCancel = useCallback(() => {
887
+ agent?.stopInspecting();
888
+ setConfirmVisible(false);
889
+ pendingActionRef.current = null;
890
+ pendingMenuInfoRef.current = null;
891
+ setMenuInfo(null);
892
+ setMenuRect(null);
893
+ setHighlight(null);
894
+ }, [agent]);
895
+
896
+ const handleFieldPick = useCallback(
897
+ (action: InspectorAction, field: string) => {
898
+ pendingFieldActionRef.current = action;
899
+ pendingMenuInfoRef.current = menuInfo;
900
+ setFieldConfirmField(field);
901
+ setFieldConfirmVisible(true);
902
+ setMenuOpen(false);
903
+ },
904
+ [menuInfo],
148
905
  );
149
906
 
907
+ const handleFieldConfirmOk = useCallback(() => {
908
+ const action = pendingFieldActionRef.current;
909
+ if (action) {
910
+ const prompt = `${action.promptTemplate}:${fieldConfirmField}`;
911
+ applyAction(action, prompt);
912
+ }
913
+ setFieldConfirmVisible(false);
914
+ pendingFieldActionRef.current = null;
915
+ }, [applyAction, fieldConfirmField]);
916
+
917
+ const handleFieldConfirmCancel = useCallback(() => {
918
+ agent?.stopInspecting();
919
+ setFieldConfirmVisible(false);
920
+ pendingFieldActionRef.current = null;
921
+ pendingMenuInfoRef.current = null;
922
+ setMenuInfo(null);
923
+ setMenuRect(null);
924
+ setHighlight(null);
925
+ }, [agent]);
926
+
150
927
  const handleFreeInputOk = useCallback(() => {
151
928
  const action = pendingActionRef.current;
152
929
  if (action) {
153
- applyAction(action, freeInputValue);
930
+ if (freeInputMode === 'requiresInput') {
931
+ const userInput = freeInputValue.trim();
932
+ const parts = [action.promptTemplate || ''];
933
+ const prefix =
934
+ 'promptPrefix' in action
935
+ ? action.promptPrefix
936
+ : action.promptSuffix
937
+ ? ''
938
+ : '修改为:';
939
+ if (userInput)
940
+ parts.push(prefix ? `${prefix}\n${userInput}` : userInput);
941
+ if (action.promptSuffix) parts.push(action.promptSuffix);
942
+ const combined = parts.filter(Boolean).join('\n\n');
943
+ applyAction(action, combined);
944
+ } else {
945
+ applyAction(action, freeInputValue);
946
+ }
154
947
  }
155
948
  setFreeInputVisible(false);
156
949
  pendingActionRef.current = null;
157
- }, [applyAction, freeInputValue]);
950
+ }, [applyAction, freeInputValue, freeInputMode]);
158
951
 
159
952
  const handleFreeInputCancel = useCallback(() => {
953
+ agent?.stopInspecting();
160
954
  setFreeInputVisible(false);
161
955
  pendingActionRef.current = null;
956
+ pendingMenuInfoRef.current = null;
162
957
  setMenuInfo(null);
163
958
  setMenuRect(null);
164
959
  setHighlight(null);
165
- }, []);
960
+ }, [agent]);
166
961
 
167
- const handleMenuOpenChange = useCallback((open: boolean) => {
168
- if (!open) {
169
- setMenuOpen(false);
170
- setMenuInfo(null);
171
- setMenuRect(null);
172
- setHighlight(null);
173
- }
174
- }, []);
962
+ const handleQuickSelectOk = useCallback(
963
+ (value: string) => {
964
+ const action = pendingActionRef.current;
965
+ const currentCode = pendingMenuInfoRef.current?.meta?.code ?? '';
966
+ if (action?.propName) {
967
+ const newCode = patchEnumProp(currentCode, action.propName, value);
968
+ applyPatch(newCode);
969
+ }
970
+ setQuickSelectVisible(false);
971
+ },
972
+ [applyPatch],
973
+ );
974
+
975
+ const handleQuickSelectCancel = useCallback(() => {
976
+ setQuickSelectVisible(false);
977
+ pendingActionRef.current = null;
978
+ pendingMenuInfoRef.current = null;
979
+ agent?.stopInspecting();
980
+ setHighlight(null);
981
+ }, [agent]);
982
+
983
+ const handleQuickInputOk = useCallback(
984
+ (value: string) => {
985
+ const action = pendingActionRef.current;
986
+ const currentCode = pendingMenuInfoRef.current?.meta?.code ?? '';
987
+ if (action?.propName) {
988
+ const newCode = patchStringProp(currentCode, action.propName, value);
989
+ applyPatch(newCode);
990
+ }
991
+ setQuickInputVisible(false);
992
+ },
993
+ [applyPatch],
994
+ );
995
+ const handleQuickInputCancel = useCallback(() => {
996
+ setQuickInputVisible(false);
997
+ pendingActionRef.current = null;
998
+ pendingMenuInfoRef.current = null;
999
+ agent?.stopInspecting();
1000
+ setHighlight(null);
1001
+ }, [agent]);
1002
+
1003
+ const handleMenuOpenChange = useCallback(
1004
+ (open: boolean) => {
1005
+ if (!open) {
1006
+ agent?.stopInspecting();
1007
+ setMenuOpen(false);
1008
+ setMenuInfo(null);
1009
+ setMenuRect(null);
1010
+ setHighlight(null);
1011
+ }
1012
+ },
1013
+ [agent],
1014
+ );
175
1015
 
176
1016
  if (!agent) return null;
177
1017
 
178
1018
  const actions = menuInfo ? getInspectorActions(menuInfo) : [];
179
1019
 
180
- const menuItems = actions.map((action) => ({
181
- key: action.label,
182
- label: action.label,
183
- onClick: () => handleMenuAction(action),
184
- }));
1020
+ const menuItems = buildMenuItems(
1021
+ actions,
1022
+ handleMenuAction,
1023
+ hiddenFields,
1024
+ handleFieldPick,
1025
+ );
185
1026
 
186
1027
  return (
187
1028
  <>
188
1029
  {/* Overlay — captures mouse events during inspect mode */}
189
- {inspecting && (
1030
+ {inspecting && !menuOpen && (
190
1031
  <div
191
1032
  style={{
192
1033
  position: 'fixed',
@@ -259,22 +1100,32 @@ export const ElementInspector: React.FC = () => {
259
1100
  </Dropdown>
260
1101
 
261
1102
  {/* Free input modal */}
262
- <Modal
263
- title="输入自定义需求"
1103
+ <FreeInputModal
264
1104
  open={freeInputVisible}
1105
+ mode={freeInputMode}
1106
+ action={pendingActionRef.current}
1107
+ value={freeInputValue}
1108
+ onChange={setFreeInputValue}
265
1109
  onOk={handleFreeInputOk}
266
1110
  onCancel={handleFreeInputCancel}
267
- okText="确定"
268
- cancelText="取消"
269
- zIndex={10010}
270
- >
271
- <Input.TextArea
272
- rows={3}
273
- value={freeInputValue}
274
- onChange={(e) => setFreeInputValue(e.target.value)}
275
- placeholder="请描述你想要的自定义操作..."
276
- />
277
- </Modal>
1111
+ />
1112
+
1113
+ {/* requiresConfirm modal */}
1114
+ <ConfirmModal
1115
+ open={confirmVisible}
1116
+ action={pendingActionRef.current}
1117
+ onOk={handleConfirmOk}
1118
+ onCancel={handleConfirmCancel}
1119
+ />
1120
+
1121
+ {/* Field sub-menu confirm modal */}
1122
+ <FieldConfirmModal
1123
+ open={fieldConfirmVisible}
1124
+ actionLabel={pendingFieldActionRef.current?.label ?? ''}
1125
+ fieldName={fieldConfirmField}
1126
+ onOk={handleFieldConfirmOk}
1127
+ onCancel={handleFieldConfirmCancel}
1128
+ />
278
1129
  </>
279
1130
  );
280
1131
  };