@modern-admin/web 0.5.0 → 0.6.0

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 (391) hide show
  1. package/dist/config/vite.js +20 -0
  2. package/dist/lib/index.js +6 -5
  3. package/dist/lib/index.js.map +1 -1
  4. package/dist/standalone/assets/action-component-host-8DE4kuUJ.js +2 -0
  5. package/dist/standalone/assets/action-component-host-8DE4kuUJ.js.br +0 -0
  6. package/dist/standalone/assets/action-component-host-8DE4kuUJ.js.gz +0 -0
  7. package/dist/standalone/assets/{action-component-host-QVowRL_F.js.map → action-component-host-8DE4kuUJ.js.map} +1 -1
  8. package/dist/standalone/assets/{action-page-CET1s1MA.js → action-page-D6BbXzUo.js} +2 -2
  9. package/dist/standalone/assets/action-page-D6BbXzUo.js.br +0 -0
  10. package/dist/standalone/assets/action-page-D6BbXzUo.js.gz +0 -0
  11. package/dist/standalone/assets/{action-page-CET1s1MA.js.map → action-page-D6BbXzUo.js.map} +1 -1
  12. package/dist/standalone/assets/ai-assistant-widget-BORa8_hT.js +2 -0
  13. package/dist/standalone/assets/ai-assistant-widget-BORa8_hT.js.br +0 -0
  14. package/dist/standalone/assets/ai-assistant-widget-BORa8_hT.js.gz +0 -0
  15. package/dist/standalone/assets/{ai-assistant-widget-pJHSP1PB.js.map → ai-assistant-widget-BORa8_hT.js.map} +1 -1
  16. package/dist/standalone/assets/arrow-left-yVCaEJJu.js +2 -0
  17. package/dist/standalone/assets/{arrow-left-CI9hUPwJ.js.map → arrow-left-yVCaEJJu.js.map} +1 -1
  18. package/dist/standalone/assets/audit-log-page-uHj9GWfi.js +2 -0
  19. package/dist/standalone/assets/audit-log-page-uHj9GWfi.js.br +0 -0
  20. package/dist/standalone/assets/audit-log-page-uHj9GWfi.js.gz +0 -0
  21. package/dist/standalone/assets/{audit-log-page-DoZPtbGo.js.map → audit-log-page-uHj9GWfi.js.map} +1 -1
  22. package/dist/standalone/assets/{badge-8oeWEs3P.js → badge-CdW_Z0lB.js} +2 -2
  23. package/dist/standalone/assets/{badge-8oeWEs3P.js.map → badge-CdW_Z0lB.js.map} +1 -1
  24. package/dist/standalone/assets/{bot-DFDgGfNj.js → bot-CuDPD_ZU.js} +2 -2
  25. package/dist/standalone/assets/{bot-DFDgGfNj.js.map → bot-CuDPD_ZU.js.map} +1 -1
  26. package/dist/standalone/assets/cache-page-CBKj7WFq.js +2 -0
  27. package/dist/standalone/assets/cache-page-CBKj7WFq.js.br +0 -0
  28. package/dist/standalone/assets/cache-page-CBKj7WFq.js.gz +0 -0
  29. package/dist/standalone/assets/{cache-page-CoKusfv-.js.map → cache-page-CBKj7WFq.js.map} +1 -1
  30. package/dist/standalone/assets/calendar-BuLRvNBg.js +2 -0
  31. package/dist/standalone/assets/calendar-BuLRvNBg.js.br +0 -0
  32. package/dist/standalone/assets/calendar-BuLRvNBg.js.gz +0 -0
  33. package/dist/standalone/assets/calendar-BuLRvNBg.js.map +1 -0
  34. package/dist/standalone/assets/card-BYbadRar.js +2 -0
  35. package/dist/standalone/assets/card-BYbadRar.js.br +0 -0
  36. package/dist/standalone/assets/card-BYbadRar.js.gz +0 -0
  37. package/dist/standalone/assets/{card-MNH_XK0V.js.map → card-BYbadRar.js.map} +1 -1
  38. package/dist/standalone/assets/chart-widget-Bfk_mvm2.js +2 -0
  39. package/dist/standalone/assets/chart-widget-Bfk_mvm2.js.br +0 -0
  40. package/dist/standalone/assets/chart-widget-Bfk_mvm2.js.gz +0 -0
  41. package/dist/standalone/assets/{chart-widget-R2NG5T1y.js.map → chart-widget-Bfk_mvm2.js.map} +1 -1
  42. package/dist/standalone/assets/chevrons-up-down-y29_Sm-3.js +2 -0
  43. package/dist/standalone/assets/{chevrons-up-down-BHCs46XQ.js.map → chevrons-up-down-y29_Sm-3.js.map} +1 -1
  44. package/dist/standalone/assets/{circle-alert-0EyKeic4.js → circle-alert-D1sKnXtO.js} +2 -2
  45. package/dist/standalone/assets/{circle-alert-0EyKeic4.js.map → circle-alert-D1sKnXtO.js.map} +1 -1
  46. package/dist/standalone/assets/{clock-OCmX6DtA.js → clock-B9qbSr_k.js} +2 -2
  47. package/dist/standalone/assets/{clock-OCmX6DtA.js.map → clock-B9qbSr_k.js.map} +1 -1
  48. package/dist/standalone/assets/command-BAXXxf0P.js +2 -0
  49. package/dist/standalone/assets/command-BAXXxf0P.js.br +0 -0
  50. package/dist/standalone/assets/command-BAXXxf0P.js.gz +0 -0
  51. package/dist/standalone/assets/command-BAXXxf0P.js.map +1 -0
  52. package/dist/standalone/assets/{copy-BexCWf4U.js → copy-5fb4qj-_.js} +2 -2
  53. package/dist/standalone/assets/{copy-BexCWf4U.js.map → copy-5fb4qj-_.js.map} +1 -1
  54. package/dist/standalone/assets/createLucideIcon-QE2kj6ru.js +2 -0
  55. package/dist/standalone/assets/createLucideIcon-QE2kj6ru.js.br +0 -0
  56. package/dist/standalone/assets/createLucideIcon-QE2kj6ru.js.gz +0 -0
  57. package/dist/standalone/assets/createLucideIcon-QE2kj6ru.js.map +1 -0
  58. package/dist/standalone/assets/date-picker-Bxv-yrWf.js +2 -0
  59. package/dist/standalone/assets/date-picker-Bxv-yrWf.js.br +0 -0
  60. package/dist/standalone/assets/date-picker-Bxv-yrWf.js.gz +0 -0
  61. package/dist/standalone/assets/{date-picker-DQ4XOgO6.js.map → date-picker-Bxv-yrWf.js.map} +1 -1
  62. package/dist/standalone/assets/dist-COXu-_Zv.js +2 -0
  63. package/dist/standalone/assets/dist-COXu-_Zv.js.br +0 -0
  64. package/dist/standalone/assets/dist-COXu-_Zv.js.gz +0 -0
  65. package/dist/standalone/assets/dist-COXu-_Zv.js.map +1 -0
  66. package/dist/standalone/assets/dist-CiXwD0ML.js +2 -0
  67. package/dist/standalone/assets/dist-CiXwD0ML.js.br +0 -0
  68. package/dist/standalone/assets/dist-CiXwD0ML.js.gz +0 -0
  69. package/dist/standalone/assets/dist-CiXwD0ML.js.map +1 -0
  70. package/dist/standalone/assets/dist-DPxQeZn3.js +2 -0
  71. package/dist/standalone/assets/dist-DPxQeZn3.js.br +0 -0
  72. package/dist/standalone/assets/dist-DPxQeZn3.js.gz +0 -0
  73. package/dist/standalone/assets/dist-DPxQeZn3.js.map +1 -0
  74. package/dist/standalone/assets/{edit-page-CVjik6T5.js → edit-page-Dm638D2J.js} +2 -2
  75. package/dist/standalone/assets/edit-page-Dm638D2J.js.br +0 -0
  76. package/dist/standalone/assets/edit-page-Dm638D2J.js.gz +0 -0
  77. package/dist/standalone/assets/{edit-page-CVjik6T5.js.map → edit-page-Dm638D2J.js.map} +1 -1
  78. package/dist/standalone/assets/{ellipsis-lEjcTxo0.js → ellipsis-BRmOlhsy.js} +2 -2
  79. package/dist/standalone/assets/{ellipsis-lEjcTxo0.js.map → ellipsis-BRmOlhsy.js.map} +1 -1
  80. package/dist/standalone/assets/empty-DMs98grx.js +2 -0
  81. package/dist/standalone/assets/empty-DMs98grx.js.br +0 -0
  82. package/dist/standalone/assets/empty-DMs98grx.js.gz +0 -0
  83. package/dist/standalone/assets/empty-DMs98grx.js.map +1 -0
  84. package/dist/standalone/assets/{file-text-CcLZq8HA.js → file-text-MQF--yeB.js} +2 -2
  85. package/dist/standalone/assets/{file-text-CcLZq8HA.js.map → file-text-MQF--yeB.js.map} +1 -1
  86. package/dist/standalone/assets/floating-layer-BcTp2AMB.js +2 -0
  87. package/dist/standalone/assets/floating-layer-BcTp2AMB.js.br +0 -0
  88. package/dist/standalone/assets/floating-layer-BcTp2AMB.js.gz +0 -0
  89. package/dist/standalone/assets/floating-layer-BcTp2AMB.js.map +1 -0
  90. package/dist/standalone/assets/{global-search-dialog-CT30gcRv.js → global-search-dialog-DxwxFDO5.js} +2 -2
  91. package/dist/standalone/assets/global-search-dialog-DxwxFDO5.js.br +0 -0
  92. package/dist/standalone/assets/global-search-dialog-DxwxFDO5.js.gz +0 -0
  93. package/dist/standalone/assets/{global-search-dialog-CT30gcRv.js.map → global-search-dialog-DxwxFDO5.js.map} +1 -1
  94. package/dist/standalone/assets/heavy-fields-LnhreUPp.js +174 -0
  95. package/dist/standalone/assets/heavy-fields-LnhreUPp.js.br +0 -0
  96. package/dist/standalone/assets/heavy-fields-LnhreUPp.js.gz +0 -0
  97. package/dist/standalone/assets/heavy-fields-LnhreUPp.js.map +1 -0
  98. package/dist/standalone/assets/home-page-DiDOzuic.js +61 -0
  99. package/dist/standalone/assets/home-page-DiDOzuic.js.br +0 -0
  100. package/dist/standalone/assets/home-page-DiDOzuic.js.gz +0 -0
  101. package/dist/standalone/assets/home-page-DiDOzuic.js.map +1 -0
  102. package/dist/standalone/assets/{hooks-DHDUQgzs.js → hooks-BiOfAnEq.js} +11 -11
  103. package/dist/standalone/assets/hooks-BiOfAnEq.js.br +0 -0
  104. package/dist/standalone/assets/hooks-BiOfAnEq.js.gz +0 -0
  105. package/dist/standalone/assets/hooks-BiOfAnEq.js.map +1 -0
  106. package/dist/standalone/assets/icon-registry-s31CNk7M.js +2 -0
  107. package/dist/standalone/assets/icon-registry-s31CNk7M.js.br +0 -0
  108. package/dist/standalone/assets/icon-registry-s31CNk7M.js.gz +0 -0
  109. package/dist/standalone/assets/icon-registry-s31CNk7M.js.map +1 -0
  110. package/dist/standalone/assets/index-CASCzvYu.js +15 -0
  111. package/dist/standalone/assets/index-CASCzvYu.js.br +0 -0
  112. package/dist/standalone/assets/index-CASCzvYu.js.gz +0 -0
  113. package/dist/standalone/assets/index-CASCzvYu.js.map +1 -0
  114. package/dist/standalone/assets/index-Cz5ntgJ_.css +2 -0
  115. package/dist/standalone/assets/index-Cz5ntgJ_.css.br +0 -0
  116. package/dist/standalone/assets/index-Cz5ntgJ_.css.gz +0 -0
  117. package/dist/standalone/assets/{info-CGVdWTj1.js → info-ChwYoM77.js} +2 -2
  118. package/dist/standalone/assets/{info-CGVdWTj1.js.map → info-ChwYoM77.js.map} +1 -1
  119. package/dist/standalone/assets/json-editor-BD0UhGOT.js +2 -0
  120. package/dist/standalone/assets/json-editor-BD0UhGOT.js.br +0 -0
  121. package/dist/standalone/assets/json-editor-BD0UhGOT.js.gz +0 -0
  122. package/dist/standalone/assets/json-editor-BD0UhGOT.js.map +1 -0
  123. package/dist/standalone/assets/key-BzJFbNbz.js +2 -0
  124. package/dist/standalone/assets/key-BzJFbNbz.js.map +1 -0
  125. package/dist/standalone/assets/{key-round-CQLp1Ua9.js → key-round-oSqmVdkQ.js} +2 -2
  126. package/dist/standalone/assets/{key-round-CQLp1Ua9.js.map → key-round-oSqmVdkQ.js.map} +1 -1
  127. package/dist/standalone/assets/{minimize-2-Bx2cH_WS.js → minimize-2-iWv98HjE.js} +2 -2
  128. package/dist/standalone/assets/{minimize-2-Bx2cH_WS.js.map → minimize-2-iWv98HjE.js.map} +1 -1
  129. package/dist/standalone/assets/{palette-DVP_4RAn.js → palette-jgTV28yN.js} +2 -2
  130. package/dist/standalone/assets/{palette-DVP_4RAn.js.map → palette-jgTV28yN.js.map} +1 -1
  131. package/dist/standalone/assets/{pencil-BO-k3yTG.js → pencil-kFOObGrY.js} +2 -2
  132. package/dist/standalone/assets/{pencil-BO-k3yTG.js.map → pencil-kFOObGrY.js.map} +1 -1
  133. package/dist/standalone/assets/{pipette-CqHYfQnn.js → pipette-roLBCmPv.js} +2 -2
  134. package/dist/standalone/assets/pipette-roLBCmPv.js.br +0 -0
  135. package/dist/standalone/assets/pipette-roLBCmPv.js.gz +0 -0
  136. package/dist/standalone/assets/{pipette-CqHYfQnn.js.map → pipette-roLBCmPv.js.map} +1 -1
  137. package/dist/standalone/assets/plus-D7PHzena.js +2 -0
  138. package/dist/standalone/assets/{plus-Dk-FzitW.js.map → plus-D7PHzena.js.map} +1 -1
  139. package/dist/standalone/assets/property-renderer-ClrVnSny.js +4 -0
  140. package/dist/standalone/assets/property-renderer-ClrVnSny.js.br +0 -0
  141. package/dist/standalone/assets/property-renderer-ClrVnSny.js.gz +0 -0
  142. package/dist/standalone/assets/property-renderer-ClrVnSny.js.map +1 -0
  143. package/dist/standalone/assets/reference-BMbhUBHD.js +2 -0
  144. package/dist/standalone/assets/reference-BMbhUBHD.js.br +0 -0
  145. package/dist/standalone/assets/reference-BMbhUBHD.js.gz +0 -0
  146. package/dist/standalone/assets/{reference-BDP1QYCg.js.map → reference-BMbhUBHD.js.map} +1 -1
  147. package/dist/standalone/assets/refresh-cw-Cm9YiHGV.js +2 -0
  148. package/dist/standalone/assets/refresh-cw-Cm9YiHGV.js.map +1 -0
  149. package/dist/standalone/assets/revisions-button-Csueldv_.js +2 -0
  150. package/dist/standalone/assets/revisions-button-Csueldv_.js.br +0 -0
  151. package/dist/standalone/assets/revisions-button-Csueldv_.js.gz +0 -0
  152. package/dist/standalone/assets/{revisions-button-CI74_D14.js.map → revisions-button-Csueldv_.js.map} +1 -1
  153. package/dist/standalone/assets/richtext-render-DaiNQPjZ.js +68 -0
  154. package/dist/standalone/assets/richtext-render-DaiNQPjZ.js.br +0 -0
  155. package/dist/standalone/assets/richtext-render-DaiNQPjZ.js.gz +0 -0
  156. package/dist/standalone/assets/richtext-render-DaiNQPjZ.js.map +1 -0
  157. package/dist/standalone/assets/{rotate-ccw-BLr0QLAg.js → rotate-ccw-AB1VcvbK.js} +2 -2
  158. package/dist/standalone/assets/{rotate-ccw-BLr0QLAg.js.map → rotate-ccw-AB1VcvbK.js.map} +1 -1
  159. package/dist/standalone/assets/{save-Cd3oR3Sj.js → save-BkkrgP5Q.js} +2 -2
  160. package/dist/standalone/assets/{save-Cd3oR3Sj.js.map → save-BkkrgP5Q.js.map} +1 -1
  161. package/dist/standalone/assets/schemas-ByMQmMCS.js +65 -0
  162. package/dist/standalone/assets/schemas-ByMQmMCS.js.br +0 -0
  163. package/dist/standalone/assets/schemas-ByMQmMCS.js.gz +0 -0
  164. package/dist/standalone/assets/schemas-ByMQmMCS.js.map +1 -0
  165. package/dist/standalone/assets/select-BOe2daO9.js +2 -0
  166. package/dist/standalone/assets/select-BOe2daO9.js.br +0 -0
  167. package/dist/standalone/assets/select-BOe2daO9.js.gz +0 -0
  168. package/dist/standalone/assets/select-BOe2daO9.js.map +1 -0
  169. package/dist/standalone/assets/{send-D4KHQGYj.js → send-Bzb_4uMT.js} +2 -2
  170. package/dist/standalone/assets/{send-D4KHQGYj.js.map → send-Bzb_4uMT.js.map} +1 -1
  171. package/dist/standalone/assets/settings-page-BmphreWj.js +2 -0
  172. package/dist/standalone/assets/settings-page-BmphreWj.js.br +0 -0
  173. package/dist/standalone/assets/settings-page-BmphreWj.js.gz +0 -0
  174. package/dist/standalone/assets/{settings-page-CdIWVeh0.js.map → settings-page-BmphreWj.js.map} +1 -1
  175. package/dist/standalone/assets/show-page-CDgUXhsx.js +2 -0
  176. package/dist/standalone/assets/show-page-CDgUXhsx.js.br +0 -0
  177. package/dist/standalone/assets/show-page-CDgUXhsx.js.gz +0 -0
  178. package/dist/standalone/assets/{show-page-Dgw-9Pmn.js.map → show-page-CDgUXhsx.js.map} +1 -1
  179. package/dist/standalone/assets/{sparkles-CqF0zjrF.js → sparkles-1tT0H4n4.js} +2 -2
  180. package/dist/standalone/assets/{sparkles-CqF0zjrF.js.map → sparkles-1tT0H4n4.js.map} +1 -1
  181. package/dist/standalone/assets/{square-pen-DGT7ekeJ.js → square-pen-ZvVEwkzw.js} +2 -2
  182. package/dist/standalone/assets/{square-pen-DGT7ekeJ.js.map → square-pen-ZvVEwkzw.js.map} +1 -1
  183. package/dist/standalone/assets/table-RI-lM4fw.js +2 -0
  184. package/dist/standalone/assets/table-RI-lM4fw.js.br +1 -0
  185. package/dist/standalone/assets/table-RI-lM4fw.js.gz +0 -0
  186. package/dist/standalone/assets/{table-DzBSPeVH.js.map → table-RI-lM4fw.js.map} +1 -1
  187. package/dist/standalone/assets/tabs-Bj4gQaH2.js +2 -0
  188. package/dist/standalone/assets/tabs-Bj4gQaH2.js.br +0 -0
  189. package/dist/standalone/assets/tabs-Bj4gQaH2.js.gz +0 -0
  190. package/dist/standalone/assets/tabs-Bj4gQaH2.js.map +1 -0
  191. package/dist/standalone/assets/textarea-C2w7TG3h.js +2 -0
  192. package/dist/standalone/assets/{textarea-T25SXcrC.js.map → textarea-C2w7TG3h.js.map} +1 -1
  193. package/dist/standalone/assets/{trash-2-DhyKQCKv.js → trash-2-BIJVpWxv.js} +2 -2
  194. package/dist/standalone/assets/{trash-2-DhyKQCKv.js.map → trash-2-BIJVpWxv.js.map} +1 -1
  195. package/dist/standalone/assets/{triangle-alert-CyaaNWN8.js → triangle-alert-yljVpQCM.js} +2 -2
  196. package/dist/standalone/assets/{triangle-alert-CyaaNWN8.js.map → triangle-alert-yljVpQCM.js.map} +1 -1
  197. package/dist/standalone/assets/{undo-2-DlSB-5DM.js → undo-2-CnH3ScKE.js} +2 -2
  198. package/dist/standalone/assets/undo-2-CnH3ScKE.js.br +0 -0
  199. package/dist/standalone/assets/undo-2-CnH3ScKE.js.gz +0 -0
  200. package/dist/standalone/assets/{undo-2-DlSB-5DM.js.map → undo-2-CnH3ScKE.js.map} +1 -1
  201. package/dist/standalone/assets/{upload-BVhXhZgn.js → upload-DrfB-4bU.js} +2 -2
  202. package/dist/standalone/assets/upload-DrfB-4bU.js.br +0 -0
  203. package/dist/standalone/assets/upload-DrfB-4bU.js.gz +0 -0
  204. package/dist/standalone/assets/{upload-BVhXhZgn.js.map → upload-DrfB-4bU.js.map} +1 -1
  205. package/dist/standalone/assets/{use-dashboard-charts-aymvhXUB.js → use-dashboard-charts-D7-ctwCE.js} +2 -2
  206. package/dist/standalone/assets/use-dashboard-charts-D7-ctwCE.js.br +0 -0
  207. package/dist/standalone/assets/use-dashboard-charts-D7-ctwCE.js.gz +0 -0
  208. package/dist/standalone/assets/{use-dashboard-charts-aymvhXUB.js.map → use-dashboard-charts-D7-ctwCE.js.map} +1 -1
  209. package/dist/standalone/assets/useQueries-DNUnShBb.js +2 -0
  210. package/dist/standalone/assets/useQueries-DNUnShBb.js.br +0 -0
  211. package/dist/standalone/assets/useQueries-DNUnShBb.js.gz +0 -0
  212. package/dist/standalone/assets/useQueries-DNUnShBb.js.map +1 -0
  213. package/dist/standalone/assets/{user-directory-C33bGZdb.js → user-directory-BvmDzxsG.js} +3 -3
  214. package/dist/standalone/assets/user-directory-BvmDzxsG.js.br +0 -0
  215. package/dist/standalone/assets/user-directory-BvmDzxsG.js.gz +0 -0
  216. package/dist/standalone/assets/{user-directory-C33bGZdb.js.map → user-directory-BvmDzxsG.js.map} +1 -1
  217. package/dist/standalone/assets/{wand-sparkles-DWaFQeYS.js → wand-sparkles-DwseTI5T.js} +2 -2
  218. package/dist/standalone/assets/{wand-sparkles-DWaFQeYS.js.map → wand-sparkles-DwseTI5T.js.map} +1 -1
  219. package/dist/standalone/assets/wizard-create-page-D4a8FnmI.js +2 -0
  220. package/dist/standalone/assets/wizard-create-page-D4a8FnmI.js.br +0 -0
  221. package/dist/standalone/assets/wizard-create-page-D4a8FnmI.js.gz +0 -0
  222. package/dist/standalone/assets/{wizard-create-page-BtfveXmP.js.map → wizard-create-page-D4a8FnmI.js.map} +1 -1
  223. package/dist/standalone/assets/x-c-gfVPJa.js +2 -0
  224. package/dist/standalone/assets/{x-C3kLunD6.js.map → x-c-gfVPJa.js.map} +1 -1
  225. package/dist/standalone/assets/zap-BxPAEPtJ.js +2 -0
  226. package/dist/standalone/assets/zap-BxPAEPtJ.js.map +1 -0
  227. package/dist/standalone/assets/zod-2-ubQvxh.js +2 -0
  228. package/dist/standalone/assets/zod-2-ubQvxh.js.br +0 -0
  229. package/dist/standalone/assets/zod-2-ubQvxh.js.gz +0 -0
  230. package/dist/standalone/assets/zod-2-ubQvxh.js.map +1 -0
  231. package/dist/standalone/index.html +12 -12
  232. package/dist/standalone/index.html.br +0 -0
  233. package/dist/standalone/index.html.gz +0 -0
  234. package/package.json +21 -21
  235. package/src/vite.ts +21 -0
  236. package/dist/standalone/assets/action-component-host-QVowRL_F.js +0 -2
  237. package/dist/standalone/assets/action-component-host-QVowRL_F.js.br +0 -0
  238. package/dist/standalone/assets/action-component-host-QVowRL_F.js.gz +0 -0
  239. package/dist/standalone/assets/action-page-CET1s1MA.js.br +0 -0
  240. package/dist/standalone/assets/action-page-CET1s1MA.js.gz +0 -0
  241. package/dist/standalone/assets/ai-assistant-widget-pJHSP1PB.js +0 -2
  242. package/dist/standalone/assets/ai-assistant-widget-pJHSP1PB.js.br +0 -0
  243. package/dist/standalone/assets/ai-assistant-widget-pJHSP1PB.js.gz +0 -0
  244. package/dist/standalone/assets/arrow-left-CI9hUPwJ.js +0 -2
  245. package/dist/standalone/assets/audit-log-page-DoZPtbGo.js +0 -2
  246. package/dist/standalone/assets/audit-log-page-DoZPtbGo.js.br +0 -0
  247. package/dist/standalone/assets/audit-log-page-DoZPtbGo.js.gz +0 -0
  248. package/dist/standalone/assets/cache-page-CoKusfv-.js +0 -2
  249. package/dist/standalone/assets/cache-page-CoKusfv-.js.br +0 -0
  250. package/dist/standalone/assets/cache-page-CoKusfv-.js.gz +0 -0
  251. package/dist/standalone/assets/calendar-DDv0Qalf.js +0 -2
  252. package/dist/standalone/assets/calendar-DDv0Qalf.js.br +0 -0
  253. package/dist/standalone/assets/calendar-DDv0Qalf.js.gz +0 -0
  254. package/dist/standalone/assets/calendar-DDv0Qalf.js.map +0 -1
  255. package/dist/standalone/assets/card-MNH_XK0V.js +0 -2
  256. package/dist/standalone/assets/card-MNH_XK0V.js.br +0 -0
  257. package/dist/standalone/assets/card-MNH_XK0V.js.gz +0 -0
  258. package/dist/standalone/assets/chart-widget-R2NG5T1y.js +0 -2
  259. package/dist/standalone/assets/chart-widget-R2NG5T1y.js.br +0 -0
  260. package/dist/standalone/assets/chart-widget-R2NG5T1y.js.gz +0 -0
  261. package/dist/standalone/assets/chevrons-up-down-BHCs46XQ.js +0 -2
  262. package/dist/standalone/assets/command-Cw-hTtpk.js +0 -2
  263. package/dist/standalone/assets/command-Cw-hTtpk.js.br +0 -0
  264. package/dist/standalone/assets/command-Cw-hTtpk.js.gz +0 -0
  265. package/dist/standalone/assets/command-Cw-hTtpk.js.map +0 -1
  266. package/dist/standalone/assets/createLucideIcon-CUopU_LC.js +0 -2
  267. package/dist/standalone/assets/createLucideIcon-CUopU_LC.js.br +0 -0
  268. package/dist/standalone/assets/createLucideIcon-CUopU_LC.js.gz +0 -0
  269. package/dist/standalone/assets/createLucideIcon-CUopU_LC.js.map +0 -1
  270. package/dist/standalone/assets/date-picker-DQ4XOgO6.js +0 -2
  271. package/dist/standalone/assets/date-picker-DQ4XOgO6.js.br +0 -0
  272. package/dist/standalone/assets/date-picker-DQ4XOgO6.js.gz +0 -0
  273. package/dist/standalone/assets/dist-CmyV2PEd.js +0 -2
  274. package/dist/standalone/assets/dist-CmyV2PEd.js.br +0 -0
  275. package/dist/standalone/assets/dist-CmyV2PEd.js.gz +0 -0
  276. package/dist/standalone/assets/dist-CmyV2PEd.js.map +0 -1
  277. package/dist/standalone/assets/dist-DI9XNddW.js +0 -2
  278. package/dist/standalone/assets/dist-DI9XNddW.js.br +0 -0
  279. package/dist/standalone/assets/dist-DI9XNddW.js.gz +0 -0
  280. package/dist/standalone/assets/dist-DI9XNddW.js.map +0 -1
  281. package/dist/standalone/assets/dist-jC1pK2zN.js +0 -2
  282. package/dist/standalone/assets/dist-jC1pK2zN.js.br +0 -0
  283. package/dist/standalone/assets/dist-jC1pK2zN.js.gz +0 -0
  284. package/dist/standalone/assets/dist-jC1pK2zN.js.map +0 -1
  285. package/dist/standalone/assets/edit-page-CVjik6T5.js.br +0 -0
  286. package/dist/standalone/assets/edit-page-CVjik6T5.js.gz +0 -0
  287. package/dist/standalone/assets/empty-DcETRWsu.js +0 -2
  288. package/dist/standalone/assets/empty-DcETRWsu.js.br +0 -0
  289. package/dist/standalone/assets/empty-DcETRWsu.js.gz +0 -0
  290. package/dist/standalone/assets/empty-DcETRWsu.js.map +0 -1
  291. package/dist/standalone/assets/floating-layer-DJGCYMex.js +0 -2
  292. package/dist/standalone/assets/floating-layer-DJGCYMex.js.br +0 -0
  293. package/dist/standalone/assets/floating-layer-DJGCYMex.js.gz +0 -0
  294. package/dist/standalone/assets/floating-layer-DJGCYMex.js.map +0 -1
  295. package/dist/standalone/assets/global-search-dialog-CT30gcRv.js.br +0 -0
  296. package/dist/standalone/assets/global-search-dialog-CT30gcRv.js.gz +0 -0
  297. package/dist/standalone/assets/heavy-fields-ByzRCqe0.js +0 -181
  298. package/dist/standalone/assets/heavy-fields-ByzRCqe0.js.br +0 -0
  299. package/dist/standalone/assets/heavy-fields-ByzRCqe0.js.gz +0 -0
  300. package/dist/standalone/assets/heavy-fields-ByzRCqe0.js.map +0 -1
  301. package/dist/standalone/assets/home-page-B3WVGerG.js +0 -3
  302. package/dist/standalone/assets/home-page-B3WVGerG.js.br +0 -0
  303. package/dist/standalone/assets/home-page-B3WVGerG.js.gz +0 -0
  304. package/dist/standalone/assets/home-page-B3WVGerG.js.map +0 -1
  305. package/dist/standalone/assets/hooks-DHDUQgzs.js.br +0 -0
  306. package/dist/standalone/assets/hooks-DHDUQgzs.js.gz +0 -0
  307. package/dist/standalone/assets/hooks-DHDUQgzs.js.map +0 -1
  308. package/dist/standalone/assets/icon-registry-O7MDzgTi.js +0 -2
  309. package/dist/standalone/assets/icon-registry-O7MDzgTi.js.br +0 -0
  310. package/dist/standalone/assets/icon-registry-O7MDzgTi.js.gz +0 -0
  311. package/dist/standalone/assets/icon-registry-O7MDzgTi.js.map +0 -1
  312. package/dist/standalone/assets/index-BvESJd1R.js +0 -15
  313. package/dist/standalone/assets/index-BvESJd1R.js.br +0 -0
  314. package/dist/standalone/assets/index-BvESJd1R.js.gz +0 -0
  315. package/dist/standalone/assets/index-BvESJd1R.js.map +0 -1
  316. package/dist/standalone/assets/index-DSYyF4Ah.css +0 -2
  317. package/dist/standalone/assets/index-DSYyF4Ah.css.br +0 -0
  318. package/dist/standalone/assets/index-DSYyF4Ah.css.gz +0 -0
  319. package/dist/standalone/assets/json-editor-DJ-yNmlx.js +0 -2
  320. package/dist/standalone/assets/json-editor-DJ-yNmlx.js.br +0 -0
  321. package/dist/standalone/assets/json-editor-DJ-yNmlx.js.gz +0 -0
  322. package/dist/standalone/assets/json-editor-DJ-yNmlx.js.map +0 -1
  323. package/dist/standalone/assets/key-lbuX0yk_.js +0 -2
  324. package/dist/standalone/assets/key-lbuX0yk_.js.map +0 -1
  325. package/dist/standalone/assets/pipette-CqHYfQnn.js.br +0 -0
  326. package/dist/standalone/assets/pipette-CqHYfQnn.js.gz +0 -0
  327. package/dist/standalone/assets/plus-Dk-FzitW.js +0 -2
  328. package/dist/standalone/assets/property-renderer-DeykD9hp.js +0 -7
  329. package/dist/standalone/assets/property-renderer-DeykD9hp.js.br +0 -0
  330. package/dist/standalone/assets/property-renderer-DeykD9hp.js.gz +0 -0
  331. package/dist/standalone/assets/property-renderer-DeykD9hp.js.map +0 -1
  332. package/dist/standalone/assets/reference-BDP1QYCg.js +0 -2
  333. package/dist/standalone/assets/reference-BDP1QYCg.js.br +0 -0
  334. package/dist/standalone/assets/reference-BDP1QYCg.js.gz +0 -0
  335. package/dist/standalone/assets/refresh-cw-DHvUQTMb.js +0 -2
  336. package/dist/standalone/assets/refresh-cw-DHvUQTMb.js.map +0 -1
  337. package/dist/standalone/assets/revisions-button-CI74_D14.js +0 -2
  338. package/dist/standalone/assets/revisions-button-CI74_D14.js.br +0 -0
  339. package/dist/standalone/assets/revisions-button-CI74_D14.js.gz +0 -0
  340. package/dist/standalone/assets/richtext-render-BHGG3eKV.js +0 -67
  341. package/dist/standalone/assets/richtext-render-BHGG3eKV.js.br +0 -0
  342. package/dist/standalone/assets/richtext-render-BHGG3eKV.js.gz +0 -0
  343. package/dist/standalone/assets/richtext-render-BHGG3eKV.js.map +0 -1
  344. package/dist/standalone/assets/schemas-twnCb1uT.js +0 -65
  345. package/dist/standalone/assets/schemas-twnCb1uT.js.br +0 -0
  346. package/dist/standalone/assets/schemas-twnCb1uT.js.gz +0 -0
  347. package/dist/standalone/assets/schemas-twnCb1uT.js.map +0 -1
  348. package/dist/standalone/assets/select-BR1RMqsn.js +0 -2
  349. package/dist/standalone/assets/select-BR1RMqsn.js.br +0 -0
  350. package/dist/standalone/assets/select-BR1RMqsn.js.gz +0 -0
  351. package/dist/standalone/assets/select-BR1RMqsn.js.map +0 -1
  352. package/dist/standalone/assets/settings-page-CdIWVeh0.js +0 -2
  353. package/dist/standalone/assets/settings-page-CdIWVeh0.js.br +0 -0
  354. package/dist/standalone/assets/settings-page-CdIWVeh0.js.gz +0 -0
  355. package/dist/standalone/assets/show-page-Dgw-9Pmn.js +0 -2
  356. package/dist/standalone/assets/show-page-Dgw-9Pmn.js.br +0 -0
  357. package/dist/standalone/assets/show-page-Dgw-9Pmn.js.gz +0 -0
  358. package/dist/standalone/assets/table-DzBSPeVH.js +0 -2
  359. package/dist/standalone/assets/table-DzBSPeVH.js.br +0 -0
  360. package/dist/standalone/assets/table-DzBSPeVH.js.gz +0 -0
  361. package/dist/standalone/assets/tabs-Dr7UA219.js +0 -2
  362. package/dist/standalone/assets/tabs-Dr7UA219.js.br +0 -0
  363. package/dist/standalone/assets/tabs-Dr7UA219.js.gz +0 -0
  364. package/dist/standalone/assets/tabs-Dr7UA219.js.map +0 -1
  365. package/dist/standalone/assets/textarea-T25SXcrC.js +0 -2
  366. package/dist/standalone/assets/undo-2-DlSB-5DM.js.br +0 -0
  367. package/dist/standalone/assets/undo-2-DlSB-5DM.js.gz +0 -0
  368. package/dist/standalone/assets/upload-BVhXhZgn.js.br +0 -0
  369. package/dist/standalone/assets/upload-BVhXhZgn.js.gz +0 -0
  370. package/dist/standalone/assets/use-dashboard-charts-aymvhXUB.js.br +0 -0
  371. package/dist/standalone/assets/use-dashboard-charts-aymvhXUB.js.gz +0 -0
  372. package/dist/standalone/assets/useQueries-Dch5Ggjr.js +0 -2
  373. package/dist/standalone/assets/useQueries-Dch5Ggjr.js.br +0 -0
  374. package/dist/standalone/assets/useQueries-Dch5Ggjr.js.gz +0 -0
  375. package/dist/standalone/assets/useQueries-Dch5Ggjr.js.map +0 -1
  376. package/dist/standalone/assets/user-directory-C33bGZdb.js.br +0 -0
  377. package/dist/standalone/assets/user-directory-C33bGZdb.js.gz +0 -0
  378. package/dist/standalone/assets/value-format-CLzWct9Y.js +0 -60
  379. package/dist/standalone/assets/value-format-CLzWct9Y.js.br +0 -0
  380. package/dist/standalone/assets/value-format-CLzWct9Y.js.gz +0 -0
  381. package/dist/standalone/assets/value-format-CLzWct9Y.js.map +0 -1
  382. package/dist/standalone/assets/wizard-create-page-BtfveXmP.js +0 -2
  383. package/dist/standalone/assets/wizard-create-page-BtfveXmP.js.br +0 -0
  384. package/dist/standalone/assets/wizard-create-page-BtfveXmP.js.gz +0 -0
  385. package/dist/standalone/assets/x-C3kLunD6.js +0 -2
  386. package/dist/standalone/assets/zap-b3saQVKc.js +0 -2
  387. package/dist/standalone/assets/zap-b3saQVKc.js.map +0 -1
  388. package/dist/standalone/assets/zod-N7mHo7BX.js +0 -2
  389. package/dist/standalone/assets/zod-N7mHo7BX.js.br +0 -0
  390. package/dist/standalone/assets/zod-N7mHo7BX.js.gz +0 -0
  391. package/dist/standalone/assets/zod-N7mHo7BX.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"settings-page-CdIWVeh0.js","names":[],"sources":["../../../../react/src/pages/settings-shared.tsx","../../../../react/src/pages/ai-assistant-settings-section.tsx","../../../../react/src/pages/settings-page.tsx"],"sourcesContent":["// Shared layout primitives for the Settings hub. Every section in\n// `settings-page.tsx` (API keys, webhooks, AI assistant, ...) should use\n// these so the look, spacing, and mobile behavior stays uniform.\n\nimport * as React from 'react'\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Empty,\n EmptyDescription,\n EmptyHeader,\n EmptyMedia,\n EmptyTitle,\n cn,\n} from '@modern-admin/ui'\n\ntype IconComponent = React.ComponentType<{ className?: string }>\n\ninterface SettingsCardProps {\n icon: IconComponent\n title: React.ReactNode\n description?: React.ReactNode\n action?: React.ReactNode\n /** Removes default padding/header so the card body can fill edge-to-edge. */\n bodyClassName?: string\n children: React.ReactNode\n}\n\n/**\n * Unified card wrapper for a settings section. Header collapses\n * vertically on mobile and lays the action button to the right on `sm+`.\n * `CardContent` gets `min-w-0` so tables/grids inside can shrink and\n * scroll horizontally instead of forcing the parent grid wider.\n */\nexport function SettingsCard({\n icon: Icon,\n title,\n description,\n action,\n bodyClassName,\n children,\n}: SettingsCardProps): React.ReactElement {\n return (\n <Card>\n <CardHeader\n className={cn(\n 'flex-col items-start gap-2',\n action && 'sm:flex-row sm:items-center sm:justify-between',\n )}\n >\n <div className=\"flex min-w-0 flex-col gap-1.5\">\n <CardTitle className=\"flex items-center gap-2\">\n <Icon className=\"size-5\" />\n {title}\n </CardTitle>\n {description ? <CardDescription>{description}</CardDescription> : null}\n </div>\n {action}\n </CardHeader>\n <CardContent className={cn('min-w-0', bodyClassName)}>{children}</CardContent>\n </Card>\n )\n}\n\n/**\n * Horizontal-scroll wrapper for tables inside `SettingsCard`. On mobile\n * the content extends to the card edges (`-mx-6`) so the user sees the\n * left edge of the table flush with the card; from `sm+` the negative\n * margin is removed.\n */\nexport function SettingsTableScroll({ children }: { children: React.ReactNode }): React.ReactElement {\n return <div className=\"-mx-6 overflow-x-auto sm:mx-0\">{children}</div>\n}\n\ninterface SettingsEmptyProps {\n icon: IconComponent\n title: React.ReactNode\n description?: React.ReactNode\n}\n\nexport function SettingsEmpty({ icon: Icon, title, description }: SettingsEmptyProps): React.ReactElement {\n return (\n <Empty className=\"border-0\">\n <EmptyHeader>\n <EmptyMedia>\n <Icon />\n </EmptyMedia>\n <EmptyTitle>{title}</EmptyTitle>\n {description ? <EmptyDescription>{description}</EmptyDescription> : null}\n </EmptyHeader>\n </Empty>\n )\n}\n\ninterface SettingsListStateProps {\n isLoading: boolean\n error: unknown\n isEmpty: boolean\n loadingLabel: React.ReactNode\n empty: SettingsEmptyProps\n children: React.ReactNode\n}\n\n/**\n * Renders one of: loading row, destructive error banner, empty state, or\n * the actual list `children`. Keeps every section's \"list with status\"\n * surface identical.\n */\nexport function SettingsListState({\n isLoading,\n error,\n isEmpty,\n loadingLabel,\n empty,\n children,\n}: SettingsListStateProps): React.ReactElement {\n if (isLoading) {\n return <div className=\"py-8 text-center text-sm text-muted-foreground\">{loadingLabel}</div>\n }\n if (error) {\n return (\n <div className=\"rounded-md border border-destructive/50 bg-destructive/10 p-4 text-sm text-destructive\">\n {error instanceof Error ? error.message : String(error)}\n </div>\n )\n }\n if (isEmpty) {\n return <SettingsEmpty {...empty} />\n }\n return <>{children}</>\n}\n","import * as React from 'react'\nimport { useMutation, useQuery } from '@tanstack/react-query'\nimport { Badge, Button, Input, Label, Switch, Textarea } from '@modern-admin/ui'\nimport { Bot, KeyRound, Save } from 'lucide-react'\nimport { useAdminClient } from '../provider.js'\nimport { useNotify } from '../notify.js'\nimport { useI18n } from '../i18n.js'\nimport type { AiAssistantSettings } from '../client.js'\nimport { SettingsCard } from './settings-shared.js'\n\nexport function AiAssistantSettingsSection(): React.ReactElement {\n const client = useAdminClient()\n const notify = useNotify()\n const { t } = useI18n()\n const settings = useQuery({\n queryKey: ['modern-admin', 'ai-assistant', 'settings'],\n queryFn: () => client.getAiAssistantSettings(),\n })\n const [form, setForm] = React.useState({\n enabled: true,\n model: 'google/gemini-3.1-flash-lite-preview',\n apiKey: '',\n systemPrompt: '',\n })\n\n React.useEffect(() => {\n if (!settings.data) return\n setForm({\n enabled: settings.data.enabled,\n model: settings.data.model,\n apiKey: '',\n systemPrompt: settings.data.systemPrompt,\n })\n }, [settings.data])\n\n const save = useMutation({\n mutationFn: async (): Promise<AiAssistantSettings> =>\n client.updateAiAssistantSettings({\n enabled: form.enabled,\n model: form.model,\n ...(form.apiKey.trim() ? { apiKey: form.apiKey.trim() } : {}),\n systemPrompt: form.systemPrompt,\n }),\n onSuccess: () => {\n settings.refetch()\n setForm((prev) => ({ ...prev, apiKey: '' }))\n notify.success({ message: t('aiAssistant:settings.saved') })\n },\n onError: (err) => {\n notify.error({ message: err instanceof Error ? err.message : String(err) })\n },\n })\n\n if (settings.isLoading) {\n return <div className=\"py-8 text-sm text-muted-foreground\">{t('common:loading')}</div>\n }\n\n if (settings.error) {\n return (\n <div className=\"rounded-md border border-destructive/50 bg-destructive/10 p-4 text-sm text-destructive\">\n {settings.error instanceof Error ? settings.error.message : String(settings.error)}\n </div>\n )\n }\n\n const data = settings.data\n if (!data) {\n return <div className=\"py-8 text-sm text-muted-foreground\">{t('aiAssistant:settings.empty')}</div>\n }\n\n return (\n <div className=\"flex flex-col gap-4\">\n <SettingsCard\n icon={Bot}\n title={t('aiAssistant:settings.title')}\n description={t('aiAssistant:settings.description')}\n bodyClassName=\"space-y-4\"\n >\n <div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant={data.enabled ? 'secondary' : 'outline'}>\n {data.enabled ? t('aiAssistant:settings.enabled') : t('aiAssistant:settings.disabled')}\n </Badge>\n <Badge variant={data.configured ? 'secondary' : 'outline'}>\n {data.configured ? t('aiAssistant:settings.configured') : t('aiAssistant:settings.apiKeyRequired')}\n </Badge>\n <Badge variant=\"outline\">{t('aiAssistant:settings.readOnly')}</Badge>\n <Badge variant=\"outline\">{t('aiAssistant:settings.provider', { provider: data.provider })}</Badge>\n </div>\n\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"flex items-center justify-between rounded-lg border border-border p-3\">\n <div className=\"space-y-1\">\n <Label htmlFor=\"ai-assistant-enabled\">{t('aiAssistant:settings.enableLabel')}</Label>\n <p className=\"text-xs text-muted-foreground\">\n {t('aiAssistant:settings.enableHint')}\n </p>\n </div>\n <Switch\n id=\"ai-assistant-enabled\"\n checked={form.enabled}\n disabled={!data.canManage || save.isPending}\n onCheckedChange={(enabled) => setForm((prev) => ({ ...prev, enabled }))}\n />\n </div>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"ai-assistant-model\">{t('aiAssistant:settings.modelLabel')}</Label>\n <Input\n id=\"ai-assistant-model\"\n value={form.model}\n disabled={!data.canManage || save.isPending}\n onChange={(e) => setForm((prev) => ({ ...prev, model: e.target.value }))}\n placeholder=\"google/gemini-3.1-flash-lite-preview\"\n />\n </div>\n </div>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"ai-assistant-api-key\" className=\"flex items-center gap-2\">\n <KeyRound className=\"size-4\"/>\n {t('aiAssistant:settings.apiKeyLabel')}\n </Label>\n <Input\n id=\"ai-assistant-api-key\"\n type=\"password\"\n value={form.apiKey}\n disabled={!data.canManage || save.isPending}\n onChange={(e) => setForm((prev) => ({ ...prev, apiKey: e.target.value }))}\n placeholder={data.maskedApiKey ?? 'sk-or-v1-...'}\n />\n <p className=\"text-xs text-muted-foreground\">\n {t('aiAssistant:settings.apiKeyHint')}\n </p>\n </div>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"ai-assistant-system-prompt\">{t('aiAssistant:settings.systemPromptLabel')}</Label>\n <Textarea\n id=\"ai-assistant-system-prompt\"\n value={form.systemPrompt}\n disabled={!data.canManage || save.isPending}\n onChange={(e) => setForm((prev) => ({ ...prev, systemPrompt: e.target.value }))}\n rows={8}\n placeholder={t('aiAssistant:settings.systemPromptPlaceholder')}\n />\n </div>\n\n <div className=\"flex items-center justify-between gap-3 rounded-lg border border-border p-3 text-sm\">\n <div>\n <div className=\"font-medium\">{t('aiAssistant:settings.accessTitle')}</div>\n <div className=\"text-muted-foreground\">\n {t('aiAssistant:settings.accessDescription')}\n </div>\n </div>\n <Badge variant=\"outline\">{t('aiAssistant:settings.futureToolsReady')}</Badge>\n </div>\n\n <div className=\"flex justify-end\">\n <Button onClick={() => save.mutate()} disabled={!data.canManage || save.isPending || !form.model.trim()}>\n <Save className=\"size-4\"/>\n {save.isPending ? t('aiAssistant:settings.saving') : t('aiAssistant:settings.save')}\n </Button>\n </div>\n </SettingsCard>\n </div>\n )\n}\n","// Admin Settings hub. Reachable from the user/profile dropdown menu and\n// rendered by the router for `/settings/<section>`. Currently three\n// sections: `api-keys`, `webhooks`, `ai-assistant`; the layout is built so\n// adding more sections is just a new entry in `SECTIONS` + a switch case.\n\nimport * as React from 'react'\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'\nimport {\n Badge,\n Button,\n Checkbox,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n InfoTooltip,\n Input,\n JsonEditor,\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Switch,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n cn,\n} from '@modern-admin/ui'\nimport {\n AlertTriangle,\n Bot,\n Check,\n Copy,\n Edit,\n Eye,\n EyeOff,\n KeyRound,\n Plus,\n Settings as SettingsIcon,\n Trash2,\n X,\n} from 'lucide-react'\nimport { useAdminClient } from '../provider.js'\nimport { useFeatures, useResources } from '../hooks.js'\nimport { useI18n } from '../i18n.js'\nimport { Link, useNavigate } from '../router.js'\nimport { useNotify } from '../notify.js'\nimport { useDialogs } from '../dialogs.js'\nimport type { ApiKeyRecord, WebhookInput, WebhookRecord } from '../client.js'\nimport type { ResourceJSON } from '../types.js'\nimport { getSettingsSectionExtensions } from '../extension-registry.js'\nimport { AiAssistantSettingsSection } from './ai-assistant-settings-section.js'\nimport { SettingsCard, SettingsListState, SettingsTableScroll } from './settings-shared.js'\n\nconst KEY_LIST = ['modern-admin', 'api-keys'] as const\nconst KEY_WEBHOOKS = ['modern-admin', 'webhooks'] as const\n\ntype BuiltInSectionKey = 'api-keys' | 'ai-assistant' | 'webhooks'\n\ninterface SectionDef {\n key: string\n labelKey: string\n icon: React.ComponentType<{ className?: string }>\n /** When `true`, the section is supplied by an extension (no built-in renderer). */\n isExtension?: boolean\n}\n\nconst BUILT_IN_SECTIONS: SectionDef[] = [\n { key: 'api-keys', labelKey: 'settings:apiKeys.title', icon: KeyRound },\n { key: 'webhooks', labelKey: 'settings:webhooks.title', icon: SettingsIcon },\n { key: 'ai-assistant', labelKey: 'aiAssistant:title', icon: Bot },\n]\n\nexport function SettingsPage({ section }: { section?: string }): React.ReactElement {\n const { t } = useI18n()\n const navigate = useNavigate()\n const features = useFeatures()\n // Only surface built-in sections whose backend subsystem is wired.\n // Extension sections are always shown when registered.\n const SECTIONS = React.useMemo<SectionDef[]>(\n () => [\n ...BUILT_IN_SECTIONS.filter((s) =>\n s.key === 'api-keys' ? features.apiKeys\n : s.key === 'webhooks' ? features.webhooks\n : s.key === 'ai-assistant' ? features.aiAssistant\n : true,\n ),\n ...getSettingsSectionExtensions().map((ext) => ({\n key: ext.key,\n labelKey: ext.labelKey,\n icon: ext.icon,\n isExtension: true as const,\n })),\n ],\n\n [features.apiKeys, features.webhooks, features.aiAssistant],\n )\n // Resolve the requested section. If the URL is bogus or the section is\n // disabled, fall back to the first enabled section.\n const builtInKeys: BuiltInSectionKey[] = ['api-keys', 'webhooks', 'ai-assistant']\n const isBuiltIn = (k: string): k is BuiltInSectionKey =>\n (builtInKeys as string[]).includes(k)\n const requested: string | null = section ?? null\n const active: string | null =\n requested && SECTIONS.some((s) => s.key === requested)\n ? requested\n : (SECTIONS[0]?.key ?? null)\n if (active === null) {\n // Defensive: the user menu hides Settings entirely when no section is\n // available, so users normally won't land here. Direct navigation to\n // /settings without any configured section ends up showing this.\n return (\n <div className=\"rounded-md border border-dashed bg-card p-8 text-center text-sm text-muted-foreground\">\n {t('settings:noSectionsConfigured')}\n </div>\n )\n }\n return (\n // `minmax(0,1fr)` (not bare `1fr`) lets the content column shrink below\n // its intrinsic min-width — otherwise wide tables push the whole grid\n // past the viewport at ~`lg` widths (~1000–1100px).\n <div className=\"flex flex-col gap-4 lg:grid lg:grid-cols-[14rem_minmax(0,1fr)]\">\n {/* Mobile: dropdown selector (handles many sections gracefully) */}\n <div className=\"lg:hidden\">\n <Select value={active ?? ''} onValueChange={(v) => navigate({ name: 'settings', section: v })}>\n <SelectTrigger className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {SECTIONS.map(({ key, labelKey, icon: Icon }) => (\n <SelectItem key={key} value={key}>\n <span className=\"flex items-center gap-2\">\n <Icon className=\"size-4\" />\n <span>{t(labelKey)}</span>\n </span>\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n {/* Desktop: sidebar nav */}\n <aside className=\"hidden lg:block\">\n <nav className=\"flex flex-col gap-1\">\n {SECTIONS.map(({ key, labelKey, icon: Icon }) => (\n <Link\n key={key}\n to={{ name: 'settings', section: key }}\n className={cn(\n 'flex items-center gap-2 rounded-md px-3 py-2 text-sm hover:bg-accent',\n active === key && 'bg-accent font-medium',\n )}\n >\n <Icon className=\"size-4\" />\n <span>{t(labelKey)}</span>\n </Link>\n ))}\n </nav>\n </aside>\n <section className=\"min-w-0\">\n {active && isBuiltIn(active) && active === 'api-keys' && <ApiKeysSection />}\n {active && isBuiltIn(active) && active === 'webhooks' && <WebhooksSection />}\n {active && isBuiltIn(active) && active === 'ai-assistant' && <AiAssistantSettingsSection />}\n {active && !isBuiltIn(active) && (() => {\n const extSection = getSettingsSectionExtensions().find((e) => e.key === active)\n return extSection ? <extSection.component /> : null\n })()}\n </section>\n </div>\n )\n}\n\n// ─── API Keys section ─────────────────────────────────────────────────────────\n\nfunction ApiKeysSection(): React.ReactElement {\n const { t } = useI18n()\n const client = useAdminClient()\n const qc = useQueryClient()\n const notify = useNotify()\n const dialogs = useDialogs()\n const resources = useResources()\n const [editorOpen, setEditorOpen] = React.useState(false)\n const [editing, setEditing] = React.useState<ApiKeyRecord | null>(null)\n const [createdSecret, setCreatedSecret] = React.useState<{ key: string; record: ApiKeyRecord } | null>(null)\n\n const list = useQuery({\n queryKey: KEY_LIST,\n queryFn: () => client.listApiKeys(),\n })\n\n const deleteMut = useMutation({\n mutationFn: (id: string) => client.deleteApiKey(id),\n onSuccess: () => {\n qc.invalidateQueries({ queryKey: KEY_LIST })\n notify.success({ key: 'settings:apiKeys.notice.revoked' })\n },\n onError: (err) => notify.error({ message: err instanceof Error ? err.message : String(err) }),\n })\n\n const toggleEnabledMut = useMutation({\n mutationFn: (vars: { id: string; enabled: boolean }) =>\n client.updateApiKey(vars.id, { enabled: vars.enabled }),\n onSuccess: () => qc.invalidateQueries({ queryKey: KEY_LIST }),\n onError: (err) => notify.error({ message: err instanceof Error ? err.message : String(err) }),\n })\n\n const onCreate = (): void => {\n setEditing(null)\n setEditorOpen(true)\n }\n\n const onEdit = (key: ApiKeyRecord): void => {\n setEditing(key)\n setEditorOpen(true)\n }\n\n const onRevoke = async (key: ApiKeyRecord): Promise<void> => {\n const ok = await dialogs.confirm({\n title: t('settings:apiKeys.confirmRevoke.title'),\n description: t('settings:apiKeys.confirmRevoke.description', { name: key.name ?? key.id }),\n confirmLabel: t('settings:apiKeys.actions.revoke'),\n destructive: true,\n })\n if (ok) deleteMut.mutate(key.id)\n }\n\n const keys = list.data?.keys ?? []\n\n return (\n <div className=\"flex flex-col gap-4\">\n <SettingsCard\n icon={KeyRound}\n title={t('settings:apiKeys.title')}\n description={t('settings:apiKeys.description')}\n action={\n <Button onClick={onCreate} size=\"sm\">\n <Plus className=\"size-4\" />\n <span>{t('settings:apiKeys.actions.create')}</span>\n </Button>\n }\n >\n <SettingsListState\n isLoading={list.isLoading}\n error={list.error}\n isEmpty={keys.length === 0}\n loadingLabel={t('common:loading')}\n empty={{\n icon: KeyRound,\n title: t('settings:apiKeys.empty.title'),\n description: t('settings:apiKeys.empty.description'),\n }}\n >\n <SettingsTableScroll>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{t('settings:apiKeys.columns.name')}</TableHead>\n <TableHead className=\"hidden sm:table-cell\">{t('settings:apiKeys.columns.start')}</TableHead>\n <TableHead className=\"hidden md:table-cell\">{t('settings:apiKeys.columns.permissions')}</TableHead>\n <TableHead className=\"hidden md:table-cell\">{t('settings:apiKeys.columns.expiresAt')}</TableHead>\n <TableHead>{t('settings:apiKeys.columns.enabled')}</TableHead>\n <TableHead className=\"text-right\">{t('settings:apiKeys.columns.actions')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {keys.map((k) => (\n <TableRow key={k.id}>\n <TableCell className=\"font-medium\">\n <div className=\"flex flex-col\">\n <span>{k.name ?? k.id}</span>\n {k.lastRequest && (\n <span className=\"text-xs text-muted-foreground\">\n {t('settings:apiKeys.lastUsed', { date: formatDate(k.lastRequest) })}\n </span>\n )}\n </div>\n </TableCell>\n <TableCell className=\"hidden font-mono text-xs sm:table-cell\">\n {k.start ? `${k.start}…` : '—'}\n </TableCell>\n <TableCell className=\"hidden md:table-cell\">\n <PermissionsSummary permissions={k.permissions} />\n </TableCell>\n <TableCell className=\"hidden md:table-cell text-xs\">\n {k.expiresAt ? formatDate(k.expiresAt) : t('settings:apiKeys.expiresNever')}\n </TableCell>\n <TableCell>\n <Switch\n checked={k.enabled}\n onCheckedChange={(enabled) => toggleEnabledMut.mutate({ id: k.id, enabled })}\n aria-label={t('settings:apiKeys.columns.enabled')}\n />\n </TableCell>\n <TableCell className=\"text-right\">\n <div className=\"inline-flex gap-1\">\n <Button variant=\"ghost\" size=\"sm\" onClick={() => onEdit(k)} aria-label={t('settings:apiKeys.actions.edit')}>\n <Edit className=\"size-4\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => onRevoke(k)}\n aria-label={t('settings:apiKeys.actions.revoke')}\n disabled={deleteMut.isPending}\n >\n <Trash2 className=\"size-4 text-destructive\" />\n </Button>\n </div>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </SettingsTableScroll>\n </SettingsListState>\n </SettingsCard>\n\n <ApiKeyEditorDialog\n key={editing?.id ?? 'new'}\n open={editorOpen}\n onOpenChange={setEditorOpen}\n editing={editing}\n resources={resources}\n onCreated={(result) => {\n setEditorOpen(false)\n setCreatedSecret(result)\n qc.invalidateQueries({ queryKey: KEY_LIST })\n }}\n onUpdated={() => {\n setEditorOpen(false)\n qc.invalidateQueries({ queryKey: KEY_LIST })\n }}\n />\n\n <CreatedSecretDialog\n secret={createdSecret}\n onClose={() => setCreatedSecret(null)}\n />\n </div>\n )\n}\n\n// ─── Permissions matrix editor ────────────────────────────────────────────────\n\ninterface PermissionsState {\n /** resourceId -> Set<actionName>. `'*'` means all actions of that resource. */\n byResource: Record<string, Set<string>>\n}\n\nconst buildState = (perms: Record<string, string[]>): PermissionsState => ({\n byResource: Object.fromEntries(\n Object.entries(perms).map(([k, v]) => [k, new Set(v)]),\n ),\n})\n\nconst stateToWire = (state: PermissionsState): Record<string, string[]> => {\n const out: Record<string, string[]> = {}\n for (const [k, set] of Object.entries(state.byResource)) {\n if (set.size === 0) continue\n out[k] = Array.from(set)\n }\n return out\n}\n\nfunction PermissionsMatrix({\n resources,\n state,\n onChange,\n}: {\n resources: ResourceJSON[]\n state: PermissionsState\n onChange: (next: PermissionsState) => void\n}): React.ReactElement {\n const { t } = useI18n()\n\n const toggle = (resourceId: string, action: string): void => {\n const set = new Set(state.byResource[resourceId] ?? [])\n if (set.has(action)) set.delete(action)\n else set.add(action)\n onChange({ byResource: { ...state.byResource, [resourceId]: set } })\n }\n\n const toggleAll = (resourceId: string, actions: string[]): void => {\n const current = state.byResource[resourceId] ?? new Set<string>()\n const allSelected = actions.every((a) => current.has(a))\n const next = new Set<string>(allSelected ? [] : actions)\n onChange({ byResource: { ...state.byResource, [resourceId]: next } })\n }\n\n const resourcesWithActions = React.useMemo(\n () => resources.filter((r) => (r.actions ?? []).length > 0),\n [resources],\n )\n\n const allGloballySelected =\n resourcesWithActions.length > 0 &&\n resourcesWithActions.every((r) => {\n const actions = (r.actions ?? []).map((a) => a.name)\n const current = state.byResource[r.id] ?? new Set<string>()\n return actions.every((a) => current.has(a))\n })\n\n const toggleAllResources = (): void => {\n const select = !allGloballySelected\n const next: Record<string, Set<string>> = { ...state.byResource }\n for (const r of resources) {\n const actions = (r.actions ?? []).map((a) => a.name)\n next[r.id] = select ? new Set(actions) : new Set<string>()\n }\n onChange({ byResource: next })\n }\n\n if (resources.length === 0) {\n return (\n <p className=\"text-sm text-muted-foreground\">{t('settings:apiKeys.permissions.noResources')}</p>\n )\n }\n\n return (\n <div className=\"rounded-md border border-border\">\n {resourcesWithActions.length > 0 && (\n <div className=\"flex flex-wrap items-center justify-end gap-2 border-b border-border bg-muted/30 px-3 py-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"h-8\"\n onClick={toggleAllResources}\n >\n {allGloballySelected ? (\n <>\n <X className=\"mr-1.5 size-3.5\" />\n {t('settings:apiKeys.permissions.clearAllResources')}\n </>\n ) : (\n <>\n <Check className=\"mr-1.5 size-3.5\" />\n {t('settings:apiKeys.permissions.selectAllResources')}\n </>\n )}\n </Button>\n </div>\n )}\n <div className=\"max-h-[24rem] overflow-y-auto\">\n <Table>\n <TableHeader className=\"sticky top-0 bg-card\">\n <TableRow>\n <TableHead className=\"w-[14rem]\">{t('settings:apiKeys.permissions.resource')}</TableHead>\n <TableHead>{t('settings:apiKeys.permissions.actions')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {resources.map((r) => {\n const actions = (r.actions ?? []).map((a) => a.name)\n const current = state.byResource[r.id] ?? new Set<string>()\n const allSelected = actions.length > 0 && actions.every((a) => current.has(a))\n return (\n <TableRow key={r.id}>\n <TableCell className=\"align-top\">\n <div className=\"flex flex-col gap-1\">\n <span className=\"font-medium\">{r.name}</span>\n <span className=\"text-xs text-muted-foreground\">{r.id}</span>\n <button\n type=\"button\"\n className=\"mt-1 inline-flex items-center gap-1 self-start text-xs text-primary hover:underline\"\n onClick={() => toggleAll(r.id, actions)}\n >\n {allSelected ? <X className=\"size-3\" /> : <Check className=\"size-3\" />}\n {allSelected\n ? t('settings:apiKeys.permissions.clearAll')\n : t('settings:apiKeys.permissions.selectAll')}\n </button>\n </div>\n </TableCell>\n <TableCell>\n <div className=\"flex flex-wrap gap-2\">\n {actions.map((a) => {\n const checked = current.has(a)\n return (\n <label\n key={a}\n className={cn(\n 'inline-flex cursor-pointer items-center gap-1.5 rounded-md border border-border px-2 py-1 text-xs',\n checked && 'border-primary bg-primary/10 text-primary',\n )}\n >\n <Checkbox\n checked={checked}\n onCheckedChange={() => toggle(r.id, a)}\n className=\"size-3.5\"\n />\n <span>{a}</span>\n </label>\n )\n })}\n </div>\n </TableCell>\n </TableRow>\n )\n })}\n </TableBody>\n </Table>\n </div>\n </div>\n )\n}\n\nfunction PermissionsSummary({ permissions }: { permissions: Record<string, string[]> }): React.ReactElement {\n const { t } = useI18n()\n const entries = Object.entries(permissions)\n if (entries.length === 0) {\n return <Badge variant=\"outline\">{t('settings:apiKeys.permissions.none')}</Badge>\n }\n const totalActions = entries.reduce((sum, [, a]) => sum + a.length, 0)\n return (\n <Badge variant=\"secondary\">\n {t('settings:apiKeys.permissions.summary', { resources: entries.length, actions: totalActions })}\n </Badge>\n )\n}\n\n// ─── Editor dialog ────────────────────────────────────────────────────────────\n\nfunction ApiKeyEditorDialog({\n open,\n onOpenChange,\n editing,\n resources,\n onCreated,\n onUpdated,\n}: {\n open: boolean\n onOpenChange: (open: boolean) => void\n editing: ApiKeyRecord | null\n resources: ResourceJSON[]\n onCreated: (result: { key: string; record: ApiKeyRecord }) => void\n onUpdated: (record: ApiKeyRecord) => void\n}): React.ReactElement {\n const { t } = useI18n()\n const client = useAdminClient()\n const notify = useNotify()\n const isEdit = !!editing\n const [name, setName] = React.useState(editing?.name ?? '')\n const [expiresInDays, setExpiresInDays] = React.useState<string>(() => {\n if (!editing?.expiresAt) return ''\n const ms = new Date(editing.expiresAt).getTime() - Date.now()\n return ms > 0 ? String(Math.max(1, Math.round(ms / (24 * 60 * 60 * 1000)))) : ''\n })\n const [permissions, setPermissions] = React.useState<PermissionsState>(() =>\n buildState(editing?.permissions ?? {}),\n )\n\n const save = useMutation({\n mutationFn: async (): Promise<{ key?: string; record: ApiKeyRecord }> => {\n const wire = stateToWire(permissions)\n if (isEdit && editing) {\n const expiry = expiresInDays.trim() === '' ? null : Number(expiresInDays)\n const res = await client.updateApiKey(editing.id, {\n name: name.trim(),\n permissions: wire,\n expiresInDays: expiry === null ? null : Number.isFinite(expiry) && expiry > 0 ? expiry : undefined,\n })\n return { record: res.record }\n }\n const expiry = expiresInDays.trim() === '' ? null : Number(expiresInDays)\n return client.createApiKey({\n name: name.trim(),\n permissions: wire,\n expiresInDays: expiry === null ? null : Number.isFinite(expiry) && expiry > 0 ? expiry : undefined,\n }) as Promise<{ key: string; record: ApiKeyRecord }>\n },\n onSuccess: (result) => {\n if (isEdit) {\n notify.success({ key: 'settings:apiKeys.notice.updated' })\n onUpdated(result.record)\n } else {\n if (result.key) onCreated({ key: result.key, record: result.record })\n }\n },\n onError: (err) => notify.error({ message: err instanceof Error ? err.message : String(err) }),\n })\n\n // Sync state when dialog re-opens against a different record.\n React.useEffect(() => {\n if (!open) return\n setName(editing?.name ?? '')\n setPermissions(buildState(editing?.permissions ?? {}))\n if (!editing?.expiresAt) setExpiresInDays('')\n else {\n const ms = new Date(editing.expiresAt).getTime() - Date.now()\n setExpiresInDays(ms > 0 ? String(Math.max(1, Math.round(ms / (24 * 60 * 60 * 1000)))) : '')\n }\n }, [open, editing])\n\n const totalSelected = Object.values(permissions.byResource).reduce(\n (sum, set) => sum + (set?.size ?? 0),\n 0,\n )\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-w-3xl\">\n <DialogHeader>\n <DialogTitle>\n {isEdit ? t('settings:apiKeys.editor.titleEdit') : t('settings:apiKeys.editor.titleCreate')}\n </DialogTitle>\n <DialogDescription>{t('settings:apiKeys.editor.description')}</DialogDescription>\n </DialogHeader>\n <form\n className=\"flex flex-col gap-4\"\n onSubmit={(e) => {\n e.preventDefault()\n if (!name.trim()) return\n save.mutate()\n }}\n >\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-1.5\">\n <Label htmlFor=\"api-key-name\">{t('settings:apiKeys.editor.name')}</Label>\n <Input\n id=\"api-key-name\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder={t('settings:apiKeys.editor.namePlaceholder')}\n required\n maxLength={64}\n />\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <Label htmlFor=\"api-key-expires\">{t('settings:apiKeys.editor.expiresInDays')}</Label>\n <Input\n id=\"api-key-expires\"\n type=\"number\"\n min={1}\n max={3650}\n value={expiresInDays}\n onChange={(e) => setExpiresInDays(e.target.value)}\n placeholder={t('settings:apiKeys.editor.expiresPlaceholder')}\n />\n <span className=\"text-xs text-muted-foreground\">\n {t('settings:apiKeys.editor.expiresHint')}\n </span>\n </div>\n </div>\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex items-center justify-between\">\n <Label>{t('settings:apiKeys.editor.permissions')}</Label>\n <span className=\"text-xs text-muted-foreground\">\n {t('settings:apiKeys.editor.selectedActions', { count: totalSelected })}\n </span>\n </div>\n <PermissionsMatrix resources={resources} state={permissions} onChange={setPermissions} />\n </div>\n <DialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => onOpenChange(false)}>\n {t('common:cancel')}\n </Button>\n <Button type=\"submit\" disabled={save.isPending || !name.trim() || totalSelected === 0}>\n {save.isPending ? t('common:saving') : isEdit ? t('common:save') : t('settings:apiKeys.actions.create')}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n )\n}\n\n// ─── Webhooks section ─────────────────────────────────────────────────────────\n\nconst WEBHOOK_EVENTS = ['record.created', 'record.updated', 'record.deleted', '*']\n\nfunction WebhooksSection(): React.ReactElement {\n const { t } = useI18n()\n const client = useAdminClient()\n const qc = useQueryClient()\n const notify = useNotify()\n const dialogs = useDialogs()\n const resources = useResources()\n const [editorOpen, setEditorOpen] = React.useState(false)\n const [editing, setEditing] = React.useState<WebhookRecord | null>(null)\n const [selectedId, setSelectedId] = React.useState<string | null>(null)\n\n const list = useQuery({\n queryKey: KEY_WEBHOOKS,\n queryFn: () => client.listWebhooks(),\n })\n const deliveries = useQuery({\n queryKey: ['modern-admin', 'webhooks', selectedId, 'deliveries'],\n queryFn: () => client.listWebhookDeliveries(selectedId!),\n enabled: !!selectedId,\n })\n const deleteMut = useMutation({\n mutationFn: (id: string) => client.deleteWebhook(id),\n onSuccess: () => {\n qc.invalidateQueries({ queryKey: KEY_WEBHOOKS })\n notify.success({ key: 'settings:webhooks.notice.deleted' })\n },\n onError: (err) => notify.error({ message: err instanceof Error ? err.message : String(err) }),\n })\n const testMut = useMutation({\n mutationFn: (id: string) => client.testWebhook(id),\n onSuccess: () => {\n if (selectedId) qc.invalidateQueries({ queryKey: ['modern-admin', 'webhooks', selectedId, 'deliveries'] })\n notify.success({ key: 'settings:webhooks.notice.testQueued' })\n },\n onError: (err) => notify.error({ message: err instanceof Error ? err.message : String(err) }),\n })\n\n const webhooks = list.data?.webhooks ?? []\n\n const onDelete = async (webhook: WebhookRecord): Promise<void> => {\n const ok = await dialogs.confirm({\n title: t('settings:webhooks.confirmDelete.title'),\n description: t('settings:webhooks.confirmDelete.description', { name: webhook.name }),\n confirmLabel: t('common:delete'),\n destructive: true,\n })\n if (ok) deleteMut.mutate(webhook.id)\n }\n\n return (\n <div className=\"flex flex-col gap-4\">\n <SettingsCard\n icon={SettingsIcon}\n title={t('settings:webhooks.title')}\n description={t('settings:webhooks.description')}\n action={\n <Button size=\"sm\" onClick={() => { setEditing(null); setEditorOpen(true) }}>\n <Plus className=\"size-4\" />\n {t('settings:webhooks.actions.create')}\n </Button>\n }\n >\n <SettingsListState\n isLoading={list.isLoading}\n error={list.error}\n isEmpty={webhooks.length === 0}\n loadingLabel={t('common:loading')}\n empty={{\n icon: SettingsIcon,\n title: t('settings:webhooks.empty.title'),\n description: t('settings:webhooks.empty.description'),\n }}\n >\n <SettingsTableScroll>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{t('settings:webhooks.columns.name')}</TableHead>\n <TableHead>{t('settings:webhooks.columns.resource')}</TableHead>\n <TableHead>{t('settings:webhooks.columns.events')}</TableHead>\n <TableHead>{t('settings:webhooks.columns.enabled')}</TableHead>\n <TableHead className=\"text-right\">{t('settings:webhooks.columns.actions')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {webhooks.map((webhook) => (\n <TableRow key={webhook.id}>\n <TableCell>\n <button\n type=\"button\"\n className=\"text-left font-medium hover:underline\"\n onClick={() => setSelectedId(webhook.id)}\n >\n {webhook.name}\n </button>\n <div className=\"max-w-xs truncate text-xs text-muted-foreground\">{webhook.url}</div>\n </TableCell>\n <TableCell>{resourceName(resources, webhook.resourceId, t('settings:webhooks.editor.allResources'))}</TableCell>\n <TableCell className=\"max-w-xs\">\n <div className=\"flex flex-wrap gap-1\">\n {webhook.events.map((event) => <Badge key={event} variant=\"outline\">{event}</Badge>)}\n </div>\n </TableCell>\n <TableCell>{webhook.enabled ? t('common:yes') : t('common:no')}</TableCell>\n <TableCell className=\"text-right\">\n <div className=\"inline-flex gap-1\">\n <Button variant=\"ghost\" size=\"sm\" onClick={() => testMut.mutate(webhook.id)}>\n {t('settings:webhooks.actions.test')}\n </Button>\n <Button variant=\"ghost\" size=\"sm\" onClick={() => { setEditing(webhook); setEditorOpen(true) }}>\n <Edit className=\"size-4\" />\n </Button>\n <Button variant=\"ghost\" size=\"sm\" onClick={() => void onDelete(webhook)}>\n <Trash2 className=\"size-4 text-destructive\" />\n </Button>\n </div>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </SettingsTableScroll>\n </SettingsListState>\n </SettingsCard>\n\n {selectedId && (\n <SettingsCard icon={SettingsIcon} title={t('settings:webhooks.deliveries.title')}>\n {deliveries.isLoading ? (\n <div className=\"py-4 text-sm text-muted-foreground\">{t('common:loading')}</div>\n ) : (\n <SettingsTableScroll>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{t('settings:webhooks.deliveries.status')}</TableHead>\n <TableHead>{t('settings:webhooks.deliveries.event')}</TableHead>\n <TableHead>{t('settings:webhooks.deliveries.attempt')}</TableHead>\n <TableHead>{t('settings:webhooks.deliveries.response')}</TableHead>\n <TableHead>{t('settings:webhooks.deliveries.createdAt')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {(deliveries.data?.deliveries ?? []).map((delivery) => (\n <TableRow key={delivery.id}>\n <TableCell>{delivery.status}</TableCell>\n <TableCell>{delivery.event}</TableCell>\n <TableCell>{delivery.attempt}</TableCell>\n <TableCell className=\"max-w-sm truncate\">\n {delivery.responseStatus ?? delivery.error ?? delivery.responseBody ?? '—'}\n </TableCell>\n <TableCell>{formatDate(delivery.createdAt)}</TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </SettingsTableScroll>\n )}\n </SettingsCard>\n )}\n\n <WebhookEditorDialog\n key={editing?.id ?? 'new'}\n open={editorOpen}\n onOpenChange={setEditorOpen}\n webhook={editing}\n resources={resources}\n />\n </div>\n )\n}\n\nfunction WebhookEditorDialog({\n open,\n onOpenChange,\n webhook,\n resources,\n}: {\n open: boolean\n onOpenChange(open: boolean): void\n webhook: WebhookRecord | null\n resources: ResourceJSON[]\n}): React.ReactElement {\n const { t } = useI18n()\n const client = useAdminClient()\n const qc = useQueryClient()\n const notify = useNotify()\n const [name, setName] = React.useState(webhook?.name ?? '')\n const [url, setUrl] = React.useState(webhook?.url ?? '')\n const [resourceId, setResourceId] = React.useState(webhook?.resourceId ?? '')\n const [enabled, setEnabled] = React.useState(webhook?.enabled ?? true)\n const [secret, setSecret] = React.useState(webhook?.secret ?? '')\n const [events, setEvents] = React.useState<string[]>(webhook?.events ?? ['record.created', 'record.updated'])\n const [headers, setHeaders] = React.useState<Record<string, unknown>>(webhook?.headers ?? {})\n const [filters, setFilters] = React.useState<Record<string, unknown>>(webhook?.filters ?? {})\n const [payloadFields, setPayloadFields] = React.useState<string[]>(webhook?.payloadFields ?? [])\n const selectedResource = resources.find((r) => r.id === resourceId)\n\n const save = useMutation({\n mutationFn: (payload: WebhookInput) =>\n webhook ? client.updateWebhook(webhook.id, payload) : client.createWebhook(payload),\n onSuccess: () => {\n qc.invalidateQueries({ queryKey: KEY_WEBHOOKS })\n notify.success({ key: 'settings:webhooks.notice.saved' })\n onOpenChange(false)\n },\n onError: (err) => notify.error({ message: err instanceof Error ? err.message : String(err) }),\n })\n\n const toggleEvent = (event: string): void => {\n setEvents((prev) => prev.includes(event) ? prev.filter((e) => e !== event) : [...prev, event])\n }\n\n const onSubmit = (e: React.FormEvent): void => {\n e.preventDefault()\n save.mutate({\n name: name.trim(),\n url: url.trim(),\n events,\n resourceId: resourceId || null,\n enabled,\n ...(secret.trim() ? { secret: secret.trim() } : {}),\n headers: stringRecord(headers),\n filters: stringRecord(filters),\n payloadFields,\n })\n }\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-w-3xl\">\n <DialogHeader>\n <DialogTitle>{webhook ? t('settings:webhooks.editor.titleEdit') : t('settings:webhooks.editor.titleCreate')}</DialogTitle>\n <DialogDescription>{t('settings:webhooks.editor.description')}</DialogDescription>\n </DialogHeader>\n <form className=\"space-y-4\" onSubmit={onSubmit}>\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"space-y-1.5\">\n <Label>{t('settings:webhooks.editor.name')}</Label>\n <Input value={name} onChange={(e) => setName(e.target.value)} required />\n </div>\n <div className=\"space-y-1.5\">\n <Label>{t('settings:webhooks.editor.url')}</Label>\n <Input value={url} onChange={(e) => setUrl(e.target.value)} required type=\"url\" />\n </div>\n <div className=\"space-y-1.5\">\n <Label>{t('settings:webhooks.editor.resource')}</Label>\n <Select\n value={resourceId || '__all__'}\n onValueChange={(v) => { setResourceId(v === '__all__' ? '' : v); setPayloadFields([]) }}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"__all__\">{t('settings:webhooks.editor.allResources')}</SelectItem>\n {resources.map((resource) => (\n <SelectItem key={resource.id} value={resource.id}>\n {resource.name}\n {resource.name !== resource.id && (\n <span className=\"ml-1.5 text-xs text-muted-foreground\">({resource.id})</span>\n )}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-1.5\">\n <div className=\"flex items-center gap-1.5\">\n <Label>{t('settings:webhooks.editor.secret')}</Label>\n <InfoTooltip\n content={t('settings:webhooks.editor.secretHint')}\n ariaLabel={t('settings:webhooks.editor.secret')}\n side=\"right\"\n />\n </div>\n <Input value={secret} onChange={(e) => setSecret(e.target.value)} type=\"password\" />\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <Switch checked={enabled} onCheckedChange={setEnabled} />\n <Label>{t('settings:webhooks.editor.enabled')}</Label>\n </div>\n <div className=\"space-y-2\">\n <Label>{t('settings:webhooks.editor.events')}</Label>\n <div className=\"flex flex-wrap gap-2\">\n {WEBHOOK_EVENTS.map((event) => (\n <label key={event} className=\"flex items-center gap-2 rounded-md border border-border px-3 py-2 text-sm\">\n <Checkbox checked={events.includes(event)} onCheckedChange={() => toggleEvent(event)} />\n {event}\n </label>\n ))}\n </div>\n </div>\n {selectedResource && (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-1.5\">\n <Label>{t('settings:webhooks.editor.payloadFields')}</Label>\n <InfoTooltip\n content={t('settings:webhooks.editor.payloadFieldsHint')}\n ariaLabel={t('settings:webhooks.editor.payloadFields')}\n side=\"right\"\n />\n </div>\n <div className=\"grid gap-2 sm:grid-cols-2\">\n {selectedResource.properties.map((property) => (\n <label key={property.path} className=\"flex items-center gap-2 text-sm\">\n <Checkbox\n checked={payloadFields.includes(property.path)}\n onCheckedChange={() =>\n setPayloadFields((prev) =>\n prev.includes(property.path)\n ? prev.filter((p) => p !== property.path)\n : [...prev, property.path],\n )\n }\n />\n {property.label}\n </label>\n ))}\n </div>\n </div>\n )}\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"space-y-1.5\">\n <div className=\"flex items-center gap-1.5\">\n <Label>{t('settings:webhooks.editor.headers')}</Label>\n <InfoTooltip\n content={t('settings:webhooks.editor.headersHint')}\n ariaLabel={t('settings:webhooks.editor.headers')}\n side=\"top\"\n />\n </div>\n <JsonEditor value={headers} onChange={(next) => setHeaders(toJsonRecord(next))} />\n </div>\n <div className=\"space-y-1.5\">\n <div className=\"flex items-center gap-1.5\">\n <Label>{t('settings:webhooks.editor.filters')}</Label>\n <InfoTooltip\n content={t('settings:webhooks.editor.filtersHint')}\n ariaLabel={t('settings:webhooks.editor.filters')}\n side=\"top\"\n />\n </div>\n <JsonEditor value={filters} onChange={(next) => setFilters(toJsonRecord(next))} />\n </div>\n </div>\n <DialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => onOpenChange(false)}>{t('common:cancel')}</Button>\n <Button type=\"submit\" disabled={save.isPending || !name.trim() || !url.trim() || events.length === 0}>\n {save.isPending ? t('common:saving') : t('common:save')}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n )\n}\n\nconst resourceName = (\n resources: ResourceJSON[],\n id: string | null | undefined,\n fallback: string,\n): string => id ? (resources.find((r) => r.id === id)?.name ?? id) : fallback\n\nconst toJsonRecord = (value: unknown): Record<string, unknown> =>\n value && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : {}\n\nconst stringRecord = (value: Record<string, unknown>): Record<string, string> => {\n const out: Record<string, string> = {}\n for (const [key, item] of Object.entries(value)) {\n if (item != null && item !== '') out[key] = String(item)\n }\n return out\n}\n\n// ─── Created-secret dialog ────────────────────────────────────────────────────\n\nfunction CreatedSecretDialog({\n secret,\n onClose,\n}: {\n secret: { key: string; record: ApiKeyRecord } | null\n onClose: () => void\n}): React.ReactElement {\n const { t } = useI18n()\n const notify = useNotify()\n const [reveal, setReveal] = React.useState(false)\n const [copied, setCopied] = React.useState(false)\n\n React.useEffect(() => {\n if (!secret) {\n setReveal(false)\n setCopied(false)\n }\n }, [secret])\n\n const onCopy = async (): Promise<void> => {\n if (!secret) return\n try {\n await navigator.clipboard.writeText(secret.key)\n setCopied(true)\n notify.success({ key: 'settings:apiKeys.notice.copied' })\n setTimeout(() => setCopied(false), 1500)\n } catch {\n notify.error({ key: 'settings:apiKeys.notice.copyFailed' })\n }\n }\n\n return (\n <Dialog open={!!secret} onOpenChange={(open) => !open && onClose()}>\n <DialogContent className=\"max-w-lg\">\n <DialogHeader>\n <DialogTitle className=\"flex items-center gap-2\">\n <SettingsIcon className=\"size-5\" />\n {t('settings:apiKeys.created.title')}\n </DialogTitle>\n <DialogDescription>{t('settings:apiKeys.created.description')}</DialogDescription>\n </DialogHeader>\n <div className=\"rounded-md border border-amber-300/60 bg-amber-50 p-3 text-sm text-amber-900 dark:border-amber-300/30 dark:bg-amber-950/40 dark:text-amber-200\">\n <div className=\"flex items-start gap-2\">\n <AlertTriangle className=\"mt-0.5 size-4\" />\n <p>{t('settings:apiKeys.created.warning')}</p>\n </div>\n </div>\n <div className=\"flex items-stretch gap-2\">\n <div className=\"relative flex-1\">\n <Input\n readOnly\n type={reveal ? 'text' : 'password'}\n value={secret?.key ?? ''}\n className=\"pr-10 font-mono text-xs\"\n onFocus={(e) => e.currentTarget.select()}\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"absolute right-1 top-1/2 -translate-y-1/2\"\n onClick={() => setReveal((v) => !v)}\n aria-label={reveal ? t('settings:apiKeys.created.hide') : t('settings:apiKeys.created.reveal')}\n >\n {reveal ? <EyeOff className=\"size-4\" /> : <Eye className=\"size-4\" />}\n </Button>\n </div>\n <Button type=\"button\" onClick={onCopy} variant=\"secondary\">\n {copied ? <Check className=\"size-4\" /> : <Copy className=\"size-4\" />}\n <span className=\"hidden sm:inline\">\n {copied ? t('settings:apiKeys.created.copied') : t('settings:apiKeys.created.copy')}\n </span>\n </Button>\n </div>\n <DialogFooter>\n <Button onClick={onClose}>{t('common:done')}</Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n\nconst formatDate = (input: string | Date): string => {\n try {\n return new Date(input).toLocaleString()\n } catch {\n return String(input)\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"settings-page-BmphreWj.js","names":[],"sources":["../../../../react/src/pages/settings-shared.tsx","../../../../react/src/pages/ai-assistant-settings-section.tsx","../../../../react/src/pages/settings-page.tsx"],"sourcesContent":["// Shared layout primitives for the Settings hub. Every section in\n// `settings-page.tsx` (API keys, webhooks, AI assistant, ...) should use\n// these so the look, spacing, and mobile behavior stays uniform.\n\nimport * as React from 'react'\nimport {\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Empty,\n EmptyDescription,\n EmptyHeader,\n EmptyMedia,\n EmptyTitle,\n cn,\n} from '@modern-admin/ui'\n\ntype IconComponent = React.ComponentType<{ className?: string }>\n\ninterface SettingsCardProps {\n icon: IconComponent\n title: React.ReactNode\n description?: React.ReactNode\n action?: React.ReactNode\n /** Removes default padding/header so the card body can fill edge-to-edge. */\n bodyClassName?: string\n children: React.ReactNode\n}\n\n/**\n * Unified card wrapper for a settings section. Header collapses\n * vertically on mobile and lays the action button to the right on `sm+`.\n * `CardContent` gets `min-w-0` so tables/grids inside can shrink and\n * scroll horizontally instead of forcing the parent grid wider.\n */\nexport function SettingsCard({\n icon: Icon,\n title,\n description,\n action,\n bodyClassName,\n children,\n}: SettingsCardProps): React.ReactElement {\n return (\n <Card>\n <CardHeader\n className={cn(\n 'flex-col items-start gap-2',\n action && 'sm:flex-row sm:items-center sm:justify-between',\n )}\n >\n <div className=\"flex min-w-0 flex-col gap-1.5\">\n <CardTitle className=\"flex items-center gap-2\">\n <Icon className=\"size-5\" />\n {title}\n </CardTitle>\n {description ? <CardDescription>{description}</CardDescription> : null}\n </div>\n {action}\n </CardHeader>\n <CardContent className={cn('min-w-0', bodyClassName)}>{children}</CardContent>\n </Card>\n )\n}\n\n/**\n * Horizontal-scroll wrapper for tables inside `SettingsCard`. On mobile\n * the content extends to the card edges (`-mx-6`) so the user sees the\n * left edge of the table flush with the card; from `sm+` the negative\n * margin is removed.\n */\nexport function SettingsTableScroll({ children }: { children: React.ReactNode }): React.ReactElement {\n return <div className=\"-mx-6 overflow-x-auto sm:mx-0\">{children}</div>\n}\n\ninterface SettingsEmptyProps {\n icon: IconComponent\n title: React.ReactNode\n description?: React.ReactNode\n}\n\nexport function SettingsEmpty({ icon: Icon, title, description }: SettingsEmptyProps): React.ReactElement {\n return (\n <Empty className=\"border-0\">\n <EmptyHeader>\n <EmptyMedia>\n <Icon />\n </EmptyMedia>\n <EmptyTitle>{title}</EmptyTitle>\n {description ? <EmptyDescription>{description}</EmptyDescription> : null}\n </EmptyHeader>\n </Empty>\n )\n}\n\ninterface SettingsListStateProps {\n isLoading: boolean\n error: unknown\n isEmpty: boolean\n loadingLabel: React.ReactNode\n empty: SettingsEmptyProps\n children: React.ReactNode\n}\n\n/**\n * Renders one of: loading row, destructive error banner, empty state, or\n * the actual list `children`. Keeps every section's \"list with status\"\n * surface identical.\n */\nexport function SettingsListState({\n isLoading,\n error,\n isEmpty,\n loadingLabel,\n empty,\n children,\n}: SettingsListStateProps): React.ReactElement {\n if (isLoading) {\n return <div className=\"py-8 text-center text-sm text-muted-foreground\">{loadingLabel}</div>\n }\n if (error) {\n return (\n <div className=\"rounded-md border border-destructive/50 bg-destructive/10 p-4 text-sm text-destructive\">\n {error instanceof Error ? error.message : String(error)}\n </div>\n )\n }\n if (isEmpty) {\n return <SettingsEmpty {...empty} />\n }\n return <>{children}</>\n}\n","import * as React from 'react'\nimport { useMutation, useQuery } from '@tanstack/react-query'\nimport { Badge, Button, Input, Label, Switch, Textarea } from '@modern-admin/ui'\nimport { Bot, KeyRound, Save } from 'lucide-react'\nimport { useAdminClient } from '../provider.js'\nimport { useNotify } from '../notify.js'\nimport { useI18n } from '../i18n.js'\nimport type { AiAssistantSettings } from '../client.js'\nimport { SettingsCard } from './settings-shared.js'\n\nexport function AiAssistantSettingsSection(): React.ReactElement {\n const client = useAdminClient()\n const notify = useNotify()\n const { t } = useI18n()\n const settings = useQuery({\n queryKey: ['modern-admin', 'ai-assistant', 'settings'],\n queryFn: () => client.getAiAssistantSettings(),\n })\n const [form, setForm] = React.useState({\n enabled: true,\n model: 'google/gemini-3.1-flash-lite-preview',\n apiKey: '',\n systemPrompt: '',\n })\n\n React.useEffect(() => {\n if (!settings.data) return\n setForm({\n enabled: settings.data.enabled,\n model: settings.data.model,\n apiKey: '',\n systemPrompt: settings.data.systemPrompt,\n })\n }, [settings.data])\n\n const save = useMutation({\n mutationFn: async (): Promise<AiAssistantSettings> =>\n client.updateAiAssistantSettings({\n enabled: form.enabled,\n model: form.model,\n ...(form.apiKey.trim() ? { apiKey: form.apiKey.trim() } : {}),\n systemPrompt: form.systemPrompt,\n }),\n onSuccess: () => {\n settings.refetch()\n setForm((prev) => ({ ...prev, apiKey: '' }))\n notify.success({ message: t('aiAssistant:settings.saved') })\n },\n onError: (err) => {\n notify.error({ message: err instanceof Error ? err.message : String(err) })\n },\n })\n\n if (settings.isLoading) {\n return <div className=\"py-8 text-sm text-muted-foreground\">{t('common:loading')}</div>\n }\n\n if (settings.error) {\n return (\n <div className=\"rounded-md border border-destructive/50 bg-destructive/10 p-4 text-sm text-destructive\">\n {settings.error instanceof Error ? settings.error.message : String(settings.error)}\n </div>\n )\n }\n\n const data = settings.data\n if (!data) {\n return <div className=\"py-8 text-sm text-muted-foreground\">{t('aiAssistant:settings.empty')}</div>\n }\n\n return (\n <div className=\"flex flex-col gap-4\">\n <SettingsCard\n icon={Bot}\n title={t('aiAssistant:settings.title')}\n description={t('aiAssistant:settings.description')}\n bodyClassName=\"space-y-4\"\n >\n <div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant={data.enabled ? 'secondary' : 'outline'}>\n {data.enabled ? t('aiAssistant:settings.enabled') : t('aiAssistant:settings.disabled')}\n </Badge>\n <Badge variant={data.configured ? 'secondary' : 'outline'}>\n {data.configured ? t('aiAssistant:settings.configured') : t('aiAssistant:settings.apiKeyRequired')}\n </Badge>\n <Badge variant=\"outline\">{t('aiAssistant:settings.readOnly')}</Badge>\n <Badge variant=\"outline\">{t('aiAssistant:settings.provider', { provider: data.provider })}</Badge>\n </div>\n\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"flex items-center justify-between rounded-lg border border-border p-3\">\n <div className=\"space-y-1\">\n <Label htmlFor=\"ai-assistant-enabled\">{t('aiAssistant:settings.enableLabel')}</Label>\n <p className=\"text-xs text-muted-foreground\">\n {t('aiAssistant:settings.enableHint')}\n </p>\n </div>\n <Switch\n id=\"ai-assistant-enabled\"\n checked={form.enabled}\n disabled={!data.canManage || save.isPending}\n onCheckedChange={(enabled) => setForm((prev) => ({ ...prev, enabled }))}\n />\n </div>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"ai-assistant-model\">{t('aiAssistant:settings.modelLabel')}</Label>\n <Input\n id=\"ai-assistant-model\"\n value={form.model}\n disabled={!data.canManage || save.isPending}\n onChange={(e) => setForm((prev) => ({ ...prev, model: e.target.value }))}\n placeholder=\"google/gemini-3.1-flash-lite-preview\"\n />\n </div>\n </div>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"ai-assistant-api-key\" className=\"flex items-center gap-2\">\n <KeyRound className=\"size-4\"/>\n {t('aiAssistant:settings.apiKeyLabel')}\n </Label>\n <Input\n id=\"ai-assistant-api-key\"\n type=\"password\"\n value={form.apiKey}\n disabled={!data.canManage || save.isPending}\n onChange={(e) => setForm((prev) => ({ ...prev, apiKey: e.target.value }))}\n placeholder={data.maskedApiKey ?? 'sk-or-v1-...'}\n />\n <p className=\"text-xs text-muted-foreground\">\n {t('aiAssistant:settings.apiKeyHint')}\n </p>\n </div>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"ai-assistant-system-prompt\">{t('aiAssistant:settings.systemPromptLabel')}</Label>\n <Textarea\n id=\"ai-assistant-system-prompt\"\n value={form.systemPrompt}\n disabled={!data.canManage || save.isPending}\n onChange={(e) => setForm((prev) => ({ ...prev, systemPrompt: e.target.value }))}\n rows={8}\n placeholder={t('aiAssistant:settings.systemPromptPlaceholder')}\n />\n </div>\n\n <div className=\"flex items-center justify-between gap-3 rounded-lg border border-border p-3 text-sm\">\n <div>\n <div className=\"font-medium\">{t('aiAssistant:settings.accessTitle')}</div>\n <div className=\"text-muted-foreground\">\n {t('aiAssistant:settings.accessDescription')}\n </div>\n </div>\n <Badge variant=\"outline\">{t('aiAssistant:settings.futureToolsReady')}</Badge>\n </div>\n\n <div className=\"flex justify-end\">\n <Button onClick={() => save.mutate()} disabled={!data.canManage || save.isPending || !form.model.trim()}>\n <Save className=\"size-4\"/>\n {save.isPending ? t('aiAssistant:settings.saving') : t('aiAssistant:settings.save')}\n </Button>\n </div>\n </SettingsCard>\n </div>\n )\n}\n","// Admin Settings hub. Reachable from the user/profile dropdown menu and\n// rendered by the router for `/settings/<section>`. Currently three\n// sections: `api-keys`, `webhooks`, `ai-assistant`; the layout is built so\n// adding more sections is just a new entry in `SECTIONS` + a switch case.\n\nimport * as React from 'react'\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'\nimport {\n Badge,\n Button,\n Checkbox,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n InfoTooltip,\n Input,\n JsonEditor,\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Switch,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n cn,\n} from '@modern-admin/ui'\nimport {\n AlertTriangle,\n Bot,\n Check,\n Copy,\n Edit,\n Eye,\n EyeOff,\n KeyRound,\n Plus,\n Settings as SettingsIcon,\n Trash2,\n X,\n} from 'lucide-react'\nimport { useAdminClient } from '../provider.js'\nimport { useFeatures, useResources } from '../hooks.js'\nimport { useI18n } from '../i18n.js'\nimport { Link, useNavigate } from '../router.js'\nimport { useNotify } from '../notify.js'\nimport { useDialogs } from '../dialogs.js'\nimport type { ApiKeyRecord, WebhookInput, WebhookRecord } from '../client.js'\nimport type { ResourceJSON } from '../types.js'\nimport { getSettingsSectionExtensions } from '../extension-registry.js'\nimport { AiAssistantSettingsSection } from './ai-assistant-settings-section.js'\nimport { SettingsCard, SettingsListState, SettingsTableScroll } from './settings-shared.js'\n\nconst KEY_LIST = ['modern-admin', 'api-keys'] as const\nconst KEY_WEBHOOKS = ['modern-admin', 'webhooks'] as const\n\ntype BuiltInSectionKey = 'api-keys' | 'ai-assistant' | 'webhooks'\n\ninterface SectionDef {\n key: string\n labelKey: string\n icon: React.ComponentType<{ className?: string }>\n /** When `true`, the section is supplied by an extension (no built-in renderer). */\n isExtension?: boolean\n}\n\nconst BUILT_IN_SECTIONS: SectionDef[] = [\n { key: 'api-keys', labelKey: 'settings:apiKeys.title', icon: KeyRound },\n { key: 'webhooks', labelKey: 'settings:webhooks.title', icon: SettingsIcon },\n { key: 'ai-assistant', labelKey: 'aiAssistant:title', icon: Bot },\n]\n\nexport function SettingsPage({ section }: { section?: string }): React.ReactElement {\n const { t } = useI18n()\n const navigate = useNavigate()\n const features = useFeatures()\n // Only surface built-in sections whose backend subsystem is wired.\n // Extension sections are always shown when registered.\n const SECTIONS = React.useMemo<SectionDef[]>(\n () => [\n ...BUILT_IN_SECTIONS.filter((s) =>\n s.key === 'api-keys' ? features.apiKeys\n : s.key === 'webhooks' ? features.webhooks\n : s.key === 'ai-assistant' ? features.aiAssistant\n : true,\n ),\n ...getSettingsSectionExtensions().map((ext) => ({\n key: ext.key,\n labelKey: ext.labelKey,\n icon: ext.icon,\n isExtension: true as const,\n })),\n ],\n\n [features.apiKeys, features.webhooks, features.aiAssistant],\n )\n // Resolve the requested section. If the URL is bogus or the section is\n // disabled, fall back to the first enabled section.\n const builtInKeys: BuiltInSectionKey[] = ['api-keys', 'webhooks', 'ai-assistant']\n const isBuiltIn = (k: string): k is BuiltInSectionKey =>\n (builtInKeys as string[]).includes(k)\n const requested: string | null = section ?? null\n const active: string | null =\n requested && SECTIONS.some((s) => s.key === requested)\n ? requested\n : (SECTIONS[0]?.key ?? null)\n if (active === null) {\n // Defensive: the user menu hides Settings entirely when no section is\n // available, so users normally won't land here. Direct navigation to\n // /settings without any configured section ends up showing this.\n return (\n <div className=\"rounded-md border border-dashed bg-card p-8 text-center text-sm text-muted-foreground\">\n {t('settings:noSectionsConfigured')}\n </div>\n )\n }\n return (\n // `minmax(0,1fr)` (not bare `1fr`) lets the content column shrink below\n // its intrinsic min-width — otherwise wide tables push the whole grid\n // past the viewport at ~`lg` widths (~1000–1100px).\n <div className=\"flex flex-col gap-4 lg:grid lg:grid-cols-[14rem_minmax(0,1fr)]\">\n {/* Mobile: dropdown selector (handles many sections gracefully) */}\n <div className=\"lg:hidden\">\n <Select value={active ?? ''} onValueChange={(v) => navigate({ name: 'settings', section: v })}>\n <SelectTrigger className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {SECTIONS.map(({ key, labelKey, icon: Icon }) => (\n <SelectItem key={key} value={key}>\n <span className=\"flex items-center gap-2\">\n <Icon className=\"size-4\" />\n <span>{t(labelKey)}</span>\n </span>\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n {/* Desktop: sidebar nav */}\n <aside className=\"hidden lg:block\">\n <nav className=\"flex flex-col gap-1\">\n {SECTIONS.map(({ key, labelKey, icon: Icon }) => (\n <Link\n key={key}\n to={{ name: 'settings', section: key }}\n className={cn(\n 'flex items-center gap-2 rounded-md px-3 py-2 text-sm hover:bg-accent',\n active === key && 'bg-accent font-medium',\n )}\n >\n <Icon className=\"size-4\" />\n <span>{t(labelKey)}</span>\n </Link>\n ))}\n </nav>\n </aside>\n <section className=\"min-w-0\">\n {active && isBuiltIn(active) && active === 'api-keys' && <ApiKeysSection />}\n {active && isBuiltIn(active) && active === 'webhooks' && <WebhooksSection />}\n {active && isBuiltIn(active) && active === 'ai-assistant' && <AiAssistantSettingsSection />}\n {active && !isBuiltIn(active) && (() => {\n const extSection = getSettingsSectionExtensions().find((e) => e.key === active)\n return extSection ? <extSection.component /> : null\n })()}\n </section>\n </div>\n )\n}\n\n// ─── API Keys section ─────────────────────────────────────────────────────────\n\nfunction ApiKeysSection(): React.ReactElement {\n const { t } = useI18n()\n const client = useAdminClient()\n const qc = useQueryClient()\n const notify = useNotify()\n const dialogs = useDialogs()\n const resources = useResources()\n const [editorOpen, setEditorOpen] = React.useState(false)\n const [editing, setEditing] = React.useState<ApiKeyRecord | null>(null)\n const [createdSecret, setCreatedSecret] = React.useState<{ key: string; record: ApiKeyRecord } | null>(null)\n\n const list = useQuery({\n queryKey: KEY_LIST,\n queryFn: () => client.listApiKeys(),\n })\n\n const deleteMut = useMutation({\n mutationFn: (id: string) => client.deleteApiKey(id),\n onSuccess: () => {\n qc.invalidateQueries({ queryKey: KEY_LIST })\n notify.success({ key: 'settings:apiKeys.notice.revoked' })\n },\n onError: (err) => notify.error({ message: err instanceof Error ? err.message : String(err) }),\n })\n\n const toggleEnabledMut = useMutation({\n mutationFn: (vars: { id: string; enabled: boolean }) =>\n client.updateApiKey(vars.id, { enabled: vars.enabled }),\n onSuccess: () => qc.invalidateQueries({ queryKey: KEY_LIST }),\n onError: (err) => notify.error({ message: err instanceof Error ? err.message : String(err) }),\n })\n\n const onCreate = (): void => {\n setEditing(null)\n setEditorOpen(true)\n }\n\n const onEdit = (key: ApiKeyRecord): void => {\n setEditing(key)\n setEditorOpen(true)\n }\n\n const onRevoke = async (key: ApiKeyRecord): Promise<void> => {\n const ok = await dialogs.confirm({\n title: t('settings:apiKeys.confirmRevoke.title'),\n description: t('settings:apiKeys.confirmRevoke.description', { name: key.name ?? key.id }),\n confirmLabel: t('settings:apiKeys.actions.revoke'),\n destructive: true,\n })\n if (ok) deleteMut.mutate(key.id)\n }\n\n const keys = list.data?.keys ?? []\n\n return (\n <div className=\"flex flex-col gap-4\">\n <SettingsCard\n icon={KeyRound}\n title={t('settings:apiKeys.title')}\n description={t('settings:apiKeys.description')}\n action={\n <Button onClick={onCreate} size=\"sm\">\n <Plus className=\"size-4\" />\n <span>{t('settings:apiKeys.actions.create')}</span>\n </Button>\n }\n >\n <SettingsListState\n isLoading={list.isLoading}\n error={list.error}\n isEmpty={keys.length === 0}\n loadingLabel={t('common:loading')}\n empty={{\n icon: KeyRound,\n title: t('settings:apiKeys.empty.title'),\n description: t('settings:apiKeys.empty.description'),\n }}\n >\n <SettingsTableScroll>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{t('settings:apiKeys.columns.name')}</TableHead>\n <TableHead className=\"hidden sm:table-cell\">{t('settings:apiKeys.columns.start')}</TableHead>\n <TableHead className=\"hidden md:table-cell\">{t('settings:apiKeys.columns.permissions')}</TableHead>\n <TableHead className=\"hidden md:table-cell\">{t('settings:apiKeys.columns.expiresAt')}</TableHead>\n <TableHead>{t('settings:apiKeys.columns.enabled')}</TableHead>\n <TableHead className=\"text-right\">{t('settings:apiKeys.columns.actions')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {keys.map((k) => (\n <TableRow key={k.id}>\n <TableCell className=\"font-medium\">\n <div className=\"flex flex-col\">\n <span>{k.name ?? k.id}</span>\n {k.lastRequest && (\n <span className=\"text-xs text-muted-foreground\">\n {t('settings:apiKeys.lastUsed', { date: formatDate(k.lastRequest) })}\n </span>\n )}\n </div>\n </TableCell>\n <TableCell className=\"hidden font-mono text-xs sm:table-cell\">\n {k.start ? `${k.start}…` : '—'}\n </TableCell>\n <TableCell className=\"hidden md:table-cell\">\n <PermissionsSummary permissions={k.permissions} />\n </TableCell>\n <TableCell className=\"hidden md:table-cell text-xs\">\n {k.expiresAt ? formatDate(k.expiresAt) : t('settings:apiKeys.expiresNever')}\n </TableCell>\n <TableCell>\n <Switch\n checked={k.enabled}\n onCheckedChange={(enabled) => toggleEnabledMut.mutate({ id: k.id, enabled })}\n aria-label={t('settings:apiKeys.columns.enabled')}\n />\n </TableCell>\n <TableCell className=\"text-right\">\n <div className=\"inline-flex gap-1\">\n <Button variant=\"ghost\" size=\"sm\" onClick={() => onEdit(k)} aria-label={t('settings:apiKeys.actions.edit')}>\n <Edit className=\"size-4\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => onRevoke(k)}\n aria-label={t('settings:apiKeys.actions.revoke')}\n disabled={deleteMut.isPending}\n >\n <Trash2 className=\"size-4 text-destructive\" />\n </Button>\n </div>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </SettingsTableScroll>\n </SettingsListState>\n </SettingsCard>\n\n <ApiKeyEditorDialog\n key={editing?.id ?? 'new'}\n open={editorOpen}\n onOpenChange={setEditorOpen}\n editing={editing}\n resources={resources}\n onCreated={(result) => {\n setEditorOpen(false)\n setCreatedSecret(result)\n qc.invalidateQueries({ queryKey: KEY_LIST })\n }}\n onUpdated={() => {\n setEditorOpen(false)\n qc.invalidateQueries({ queryKey: KEY_LIST })\n }}\n />\n\n <CreatedSecretDialog\n secret={createdSecret}\n onClose={() => setCreatedSecret(null)}\n />\n </div>\n )\n}\n\n// ─── Permissions matrix editor ────────────────────────────────────────────────\n\ninterface PermissionsState {\n /** resourceId -> Set<actionName>. `'*'` means all actions of that resource. */\n byResource: Record<string, Set<string>>\n}\n\nconst buildState = (perms: Record<string, string[]>): PermissionsState => ({\n byResource: Object.fromEntries(\n Object.entries(perms).map(([k, v]) => [k, new Set(v)]),\n ),\n})\n\nconst stateToWire = (state: PermissionsState): Record<string, string[]> => {\n const out: Record<string, string[]> = {}\n for (const [k, set] of Object.entries(state.byResource)) {\n if (set.size === 0) continue\n out[k] = Array.from(set)\n }\n return out\n}\n\nfunction PermissionsMatrix({\n resources,\n state,\n onChange,\n}: {\n resources: ResourceJSON[]\n state: PermissionsState\n onChange: (next: PermissionsState) => void\n}): React.ReactElement {\n const { t } = useI18n()\n\n const toggle = (resourceId: string, action: string): void => {\n const set = new Set(state.byResource[resourceId] ?? [])\n if (set.has(action)) set.delete(action)\n else set.add(action)\n onChange({ byResource: { ...state.byResource, [resourceId]: set } })\n }\n\n const toggleAll = (resourceId: string, actions: string[]): void => {\n const current = state.byResource[resourceId] ?? new Set<string>()\n const allSelected = actions.every((a) => current.has(a))\n const next = new Set<string>(allSelected ? [] : actions)\n onChange({ byResource: { ...state.byResource, [resourceId]: next } })\n }\n\n const resourcesWithActions = React.useMemo(\n () => resources.filter((r) => (r.actions ?? []).length > 0),\n [resources],\n )\n\n const allGloballySelected =\n resourcesWithActions.length > 0 &&\n resourcesWithActions.every((r) => {\n const actions = (r.actions ?? []).map((a) => a.name)\n const current = state.byResource[r.id] ?? new Set<string>()\n return actions.every((a) => current.has(a))\n })\n\n const toggleAllResources = (): void => {\n const select = !allGloballySelected\n const next: Record<string, Set<string>> = { ...state.byResource }\n for (const r of resources) {\n const actions = (r.actions ?? []).map((a) => a.name)\n next[r.id] = select ? new Set(actions) : new Set<string>()\n }\n onChange({ byResource: next })\n }\n\n if (resources.length === 0) {\n return (\n <p className=\"text-sm text-muted-foreground\">{t('settings:apiKeys.permissions.noResources')}</p>\n )\n }\n\n return (\n <div className=\"rounded-md border border-border\">\n {resourcesWithActions.length > 0 && (\n <div className=\"flex flex-wrap items-center justify-end gap-2 border-b border-border bg-muted/30 px-3 py-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"h-8\"\n onClick={toggleAllResources}\n >\n {allGloballySelected ? (\n <>\n <X className=\"mr-1.5 size-3.5\" />\n {t('settings:apiKeys.permissions.clearAllResources')}\n </>\n ) : (\n <>\n <Check className=\"mr-1.5 size-3.5\" />\n {t('settings:apiKeys.permissions.selectAllResources')}\n </>\n )}\n </Button>\n </div>\n )}\n <div className=\"max-h-[24rem] overflow-y-auto\">\n <Table>\n <TableHeader className=\"sticky top-0 bg-card\">\n <TableRow>\n <TableHead className=\"w-[14rem]\">{t('settings:apiKeys.permissions.resource')}</TableHead>\n <TableHead>{t('settings:apiKeys.permissions.actions')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {resources.map((r) => {\n const actions = (r.actions ?? []).map((a) => a.name)\n const current = state.byResource[r.id] ?? new Set<string>()\n const allSelected = actions.length > 0 && actions.every((a) => current.has(a))\n return (\n <TableRow key={r.id}>\n <TableCell className=\"align-top\">\n <div className=\"flex flex-col gap-1\">\n <span className=\"font-medium\">{r.name}</span>\n <span className=\"text-xs text-muted-foreground\">{r.id}</span>\n <button\n type=\"button\"\n className=\"mt-1 inline-flex items-center gap-1 self-start text-xs text-primary hover:underline\"\n onClick={() => toggleAll(r.id, actions)}\n >\n {allSelected ? <X className=\"size-3\" /> : <Check className=\"size-3\" />}\n {allSelected\n ? t('settings:apiKeys.permissions.clearAll')\n : t('settings:apiKeys.permissions.selectAll')}\n </button>\n </div>\n </TableCell>\n <TableCell>\n <div className=\"flex flex-wrap gap-2\">\n {actions.map((a) => {\n const checked = current.has(a)\n return (\n <label\n key={a}\n className={cn(\n 'inline-flex cursor-pointer items-center gap-1.5 rounded-md border border-border px-2 py-1 text-xs',\n checked && 'border-primary bg-primary/10 text-primary',\n )}\n >\n <Checkbox\n checked={checked}\n onCheckedChange={() => toggle(r.id, a)}\n className=\"size-3.5\"\n />\n <span>{a}</span>\n </label>\n )\n })}\n </div>\n </TableCell>\n </TableRow>\n )\n })}\n </TableBody>\n </Table>\n </div>\n </div>\n )\n}\n\nfunction PermissionsSummary({ permissions }: { permissions: Record<string, string[]> }): React.ReactElement {\n const { t } = useI18n()\n const entries = Object.entries(permissions)\n if (entries.length === 0) {\n return <Badge variant=\"outline\">{t('settings:apiKeys.permissions.none')}</Badge>\n }\n const totalActions = entries.reduce((sum, [, a]) => sum + a.length, 0)\n return (\n <Badge variant=\"secondary\">\n {t('settings:apiKeys.permissions.summary', { resources: entries.length, actions: totalActions })}\n </Badge>\n )\n}\n\n// ─── Editor dialog ────────────────────────────────────────────────────────────\n\nfunction ApiKeyEditorDialog({\n open,\n onOpenChange,\n editing,\n resources,\n onCreated,\n onUpdated,\n}: {\n open: boolean\n onOpenChange: (open: boolean) => void\n editing: ApiKeyRecord | null\n resources: ResourceJSON[]\n onCreated: (result: { key: string; record: ApiKeyRecord }) => void\n onUpdated: (record: ApiKeyRecord) => void\n}): React.ReactElement {\n const { t } = useI18n()\n const client = useAdminClient()\n const notify = useNotify()\n const isEdit = !!editing\n const [name, setName] = React.useState(editing?.name ?? '')\n const [expiresInDays, setExpiresInDays] = React.useState<string>(() => {\n if (!editing?.expiresAt) return ''\n const ms = new Date(editing.expiresAt).getTime() - Date.now()\n return ms > 0 ? String(Math.max(1, Math.round(ms / (24 * 60 * 60 * 1000)))) : ''\n })\n const [permissions, setPermissions] = React.useState<PermissionsState>(() =>\n buildState(editing?.permissions ?? {}),\n )\n\n const save = useMutation({\n mutationFn: async (): Promise<{ key?: string; record: ApiKeyRecord }> => {\n const wire = stateToWire(permissions)\n if (isEdit && editing) {\n const expiry = expiresInDays.trim() === '' ? null : Number(expiresInDays)\n const res = await client.updateApiKey(editing.id, {\n name: name.trim(),\n permissions: wire,\n expiresInDays: expiry === null ? null : Number.isFinite(expiry) && expiry > 0 ? expiry : undefined,\n })\n return { record: res.record }\n }\n const expiry = expiresInDays.trim() === '' ? null : Number(expiresInDays)\n return client.createApiKey({\n name: name.trim(),\n permissions: wire,\n expiresInDays: expiry === null ? null : Number.isFinite(expiry) && expiry > 0 ? expiry : undefined,\n }) as Promise<{ key: string; record: ApiKeyRecord }>\n },\n onSuccess: (result) => {\n if (isEdit) {\n notify.success({ key: 'settings:apiKeys.notice.updated' })\n onUpdated(result.record)\n } else {\n if (result.key) onCreated({ key: result.key, record: result.record })\n }\n },\n onError: (err) => notify.error({ message: err instanceof Error ? err.message : String(err) }),\n })\n\n // Sync state when dialog re-opens against a different record.\n React.useEffect(() => {\n if (!open) return\n setName(editing?.name ?? '')\n setPermissions(buildState(editing?.permissions ?? {}))\n if (!editing?.expiresAt) setExpiresInDays('')\n else {\n const ms = new Date(editing.expiresAt).getTime() - Date.now()\n setExpiresInDays(ms > 0 ? String(Math.max(1, Math.round(ms / (24 * 60 * 60 * 1000)))) : '')\n }\n }, [open, editing])\n\n const totalSelected = Object.values(permissions.byResource).reduce(\n (sum, set) => sum + (set?.size ?? 0),\n 0,\n )\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-w-3xl\">\n <DialogHeader>\n <DialogTitle>\n {isEdit ? t('settings:apiKeys.editor.titleEdit') : t('settings:apiKeys.editor.titleCreate')}\n </DialogTitle>\n <DialogDescription>{t('settings:apiKeys.editor.description')}</DialogDescription>\n </DialogHeader>\n <form\n className=\"flex flex-col gap-4\"\n onSubmit={(e) => {\n e.preventDefault()\n if (!name.trim()) return\n save.mutate()\n }}\n >\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"flex flex-col gap-1.5\">\n <Label htmlFor=\"api-key-name\">{t('settings:apiKeys.editor.name')}</Label>\n <Input\n id=\"api-key-name\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder={t('settings:apiKeys.editor.namePlaceholder')}\n required\n maxLength={64}\n />\n </div>\n <div className=\"flex flex-col gap-1.5\">\n <Label htmlFor=\"api-key-expires\">{t('settings:apiKeys.editor.expiresInDays')}</Label>\n <Input\n id=\"api-key-expires\"\n type=\"number\"\n min={1}\n max={3650}\n value={expiresInDays}\n onChange={(e) => setExpiresInDays(e.target.value)}\n placeholder={t('settings:apiKeys.editor.expiresPlaceholder')}\n />\n <span className=\"text-xs text-muted-foreground\">\n {t('settings:apiKeys.editor.expiresHint')}\n </span>\n </div>\n </div>\n <div className=\"flex flex-col gap-2\">\n <div className=\"flex items-center justify-between\">\n <Label>{t('settings:apiKeys.editor.permissions')}</Label>\n <span className=\"text-xs text-muted-foreground\">\n {t('settings:apiKeys.editor.selectedActions', { count: totalSelected })}\n </span>\n </div>\n <PermissionsMatrix resources={resources} state={permissions} onChange={setPermissions} />\n </div>\n <DialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => onOpenChange(false)}>\n {t('common:cancel')}\n </Button>\n <Button type=\"submit\" disabled={save.isPending || !name.trim() || totalSelected === 0}>\n {save.isPending ? t('common:saving') : isEdit ? t('common:save') : t('settings:apiKeys.actions.create')}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n )\n}\n\n// ─── Webhooks section ─────────────────────────────────────────────────────────\n\nconst WEBHOOK_EVENTS = ['record.created', 'record.updated', 'record.deleted', '*']\n\nfunction WebhooksSection(): React.ReactElement {\n const { t } = useI18n()\n const client = useAdminClient()\n const qc = useQueryClient()\n const notify = useNotify()\n const dialogs = useDialogs()\n const resources = useResources()\n const [editorOpen, setEditorOpen] = React.useState(false)\n const [editing, setEditing] = React.useState<WebhookRecord | null>(null)\n const [selectedId, setSelectedId] = React.useState<string | null>(null)\n\n const list = useQuery({\n queryKey: KEY_WEBHOOKS,\n queryFn: () => client.listWebhooks(),\n })\n const deliveries = useQuery({\n queryKey: ['modern-admin', 'webhooks', selectedId, 'deliveries'],\n queryFn: () => client.listWebhookDeliveries(selectedId!),\n enabled: !!selectedId,\n })\n const deleteMut = useMutation({\n mutationFn: (id: string) => client.deleteWebhook(id),\n onSuccess: () => {\n qc.invalidateQueries({ queryKey: KEY_WEBHOOKS })\n notify.success({ key: 'settings:webhooks.notice.deleted' })\n },\n onError: (err) => notify.error({ message: err instanceof Error ? err.message : String(err) }),\n })\n const testMut = useMutation({\n mutationFn: (id: string) => client.testWebhook(id),\n onSuccess: () => {\n if (selectedId) qc.invalidateQueries({ queryKey: ['modern-admin', 'webhooks', selectedId, 'deliveries'] })\n notify.success({ key: 'settings:webhooks.notice.testQueued' })\n },\n onError: (err) => notify.error({ message: err instanceof Error ? err.message : String(err) }),\n })\n\n const webhooks = list.data?.webhooks ?? []\n\n const onDelete = async (webhook: WebhookRecord): Promise<void> => {\n const ok = await dialogs.confirm({\n title: t('settings:webhooks.confirmDelete.title'),\n description: t('settings:webhooks.confirmDelete.description', { name: webhook.name }),\n confirmLabel: t('common:delete'),\n destructive: true,\n })\n if (ok) deleteMut.mutate(webhook.id)\n }\n\n return (\n <div className=\"flex flex-col gap-4\">\n <SettingsCard\n icon={SettingsIcon}\n title={t('settings:webhooks.title')}\n description={t('settings:webhooks.description')}\n action={\n <Button size=\"sm\" onClick={() => { setEditing(null); setEditorOpen(true) }}>\n <Plus className=\"size-4\" />\n {t('settings:webhooks.actions.create')}\n </Button>\n }\n >\n <SettingsListState\n isLoading={list.isLoading}\n error={list.error}\n isEmpty={webhooks.length === 0}\n loadingLabel={t('common:loading')}\n empty={{\n icon: SettingsIcon,\n title: t('settings:webhooks.empty.title'),\n description: t('settings:webhooks.empty.description'),\n }}\n >\n <SettingsTableScroll>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{t('settings:webhooks.columns.name')}</TableHead>\n <TableHead>{t('settings:webhooks.columns.resource')}</TableHead>\n <TableHead>{t('settings:webhooks.columns.events')}</TableHead>\n <TableHead>{t('settings:webhooks.columns.enabled')}</TableHead>\n <TableHead className=\"text-right\">{t('settings:webhooks.columns.actions')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {webhooks.map((webhook) => (\n <TableRow key={webhook.id}>\n <TableCell>\n <button\n type=\"button\"\n className=\"text-left font-medium hover:underline\"\n onClick={() => setSelectedId(webhook.id)}\n >\n {webhook.name}\n </button>\n <div className=\"max-w-xs truncate text-xs text-muted-foreground\">{webhook.url}</div>\n </TableCell>\n <TableCell>{resourceName(resources, webhook.resourceId, t('settings:webhooks.editor.allResources'))}</TableCell>\n <TableCell className=\"max-w-xs\">\n <div className=\"flex flex-wrap gap-1\">\n {webhook.events.map((event) => <Badge key={event} variant=\"outline\">{event}</Badge>)}\n </div>\n </TableCell>\n <TableCell>{webhook.enabled ? t('common:yes') : t('common:no')}</TableCell>\n <TableCell className=\"text-right\">\n <div className=\"inline-flex gap-1\">\n <Button variant=\"ghost\" size=\"sm\" onClick={() => testMut.mutate(webhook.id)}>\n {t('settings:webhooks.actions.test')}\n </Button>\n <Button variant=\"ghost\" size=\"sm\" onClick={() => { setEditing(webhook); setEditorOpen(true) }}>\n <Edit className=\"size-4\" />\n </Button>\n <Button variant=\"ghost\" size=\"sm\" onClick={() => void onDelete(webhook)}>\n <Trash2 className=\"size-4 text-destructive\" />\n </Button>\n </div>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </SettingsTableScroll>\n </SettingsListState>\n </SettingsCard>\n\n {selectedId && (\n <SettingsCard icon={SettingsIcon} title={t('settings:webhooks.deliveries.title')}>\n {deliveries.isLoading ? (\n <div className=\"py-4 text-sm text-muted-foreground\">{t('common:loading')}</div>\n ) : (\n <SettingsTableScroll>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>{t('settings:webhooks.deliveries.status')}</TableHead>\n <TableHead>{t('settings:webhooks.deliveries.event')}</TableHead>\n <TableHead>{t('settings:webhooks.deliveries.attempt')}</TableHead>\n <TableHead>{t('settings:webhooks.deliveries.response')}</TableHead>\n <TableHead>{t('settings:webhooks.deliveries.createdAt')}</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {(deliveries.data?.deliveries ?? []).map((delivery) => (\n <TableRow key={delivery.id}>\n <TableCell>{delivery.status}</TableCell>\n <TableCell>{delivery.event}</TableCell>\n <TableCell>{delivery.attempt}</TableCell>\n <TableCell className=\"max-w-sm truncate\">\n {delivery.responseStatus ?? delivery.error ?? delivery.responseBody ?? '—'}\n </TableCell>\n <TableCell>{formatDate(delivery.createdAt)}</TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </SettingsTableScroll>\n )}\n </SettingsCard>\n )}\n\n <WebhookEditorDialog\n key={editing?.id ?? 'new'}\n open={editorOpen}\n onOpenChange={setEditorOpen}\n webhook={editing}\n resources={resources}\n />\n </div>\n )\n}\n\nfunction WebhookEditorDialog({\n open,\n onOpenChange,\n webhook,\n resources,\n}: {\n open: boolean\n onOpenChange(open: boolean): void\n webhook: WebhookRecord | null\n resources: ResourceJSON[]\n}): React.ReactElement {\n const { t } = useI18n()\n const client = useAdminClient()\n const qc = useQueryClient()\n const notify = useNotify()\n const [name, setName] = React.useState(webhook?.name ?? '')\n const [url, setUrl] = React.useState(webhook?.url ?? '')\n const [resourceId, setResourceId] = React.useState(webhook?.resourceId ?? '')\n const [enabled, setEnabled] = React.useState(webhook?.enabled ?? true)\n const [secret, setSecret] = React.useState(webhook?.secret ?? '')\n const [events, setEvents] = React.useState<string[]>(webhook?.events ?? ['record.created', 'record.updated'])\n const [headers, setHeaders] = React.useState<Record<string, unknown>>(webhook?.headers ?? {})\n const [filters, setFilters] = React.useState<Record<string, unknown>>(webhook?.filters ?? {})\n const [payloadFields, setPayloadFields] = React.useState<string[]>(webhook?.payloadFields ?? [])\n const selectedResource = resources.find((r) => r.id === resourceId)\n\n const save = useMutation({\n mutationFn: (payload: WebhookInput) =>\n webhook ? client.updateWebhook(webhook.id, payload) : client.createWebhook(payload),\n onSuccess: () => {\n qc.invalidateQueries({ queryKey: KEY_WEBHOOKS })\n notify.success({ key: 'settings:webhooks.notice.saved' })\n onOpenChange(false)\n },\n onError: (err) => notify.error({ message: err instanceof Error ? err.message : String(err) }),\n })\n\n const toggleEvent = (event: string): void => {\n setEvents((prev) => prev.includes(event) ? prev.filter((e) => e !== event) : [...prev, event])\n }\n\n const onSubmit = (e: React.FormEvent): void => {\n e.preventDefault()\n save.mutate({\n name: name.trim(),\n url: url.trim(),\n events,\n resourceId: resourceId || null,\n enabled,\n ...(secret.trim() ? { secret: secret.trim() } : {}),\n headers: stringRecord(headers),\n filters: stringRecord(filters),\n payloadFields,\n })\n }\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-w-3xl\">\n <DialogHeader>\n <DialogTitle>{webhook ? t('settings:webhooks.editor.titleEdit') : t('settings:webhooks.editor.titleCreate')}</DialogTitle>\n <DialogDescription>{t('settings:webhooks.editor.description')}</DialogDescription>\n </DialogHeader>\n <form className=\"space-y-4\" onSubmit={onSubmit}>\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"space-y-1.5\">\n <Label>{t('settings:webhooks.editor.name')}</Label>\n <Input value={name} onChange={(e) => setName(e.target.value)} required />\n </div>\n <div className=\"space-y-1.5\">\n <Label>{t('settings:webhooks.editor.url')}</Label>\n <Input value={url} onChange={(e) => setUrl(e.target.value)} required type=\"url\" />\n </div>\n <div className=\"space-y-1.5\">\n <Label>{t('settings:webhooks.editor.resource')}</Label>\n <Select\n value={resourceId || '__all__'}\n onValueChange={(v) => { setResourceId(v === '__all__' ? '' : v); setPayloadFields([]) }}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"__all__\">{t('settings:webhooks.editor.allResources')}</SelectItem>\n {resources.map((resource) => (\n <SelectItem key={resource.id} value={resource.id}>\n {resource.name}\n {resource.name !== resource.id && (\n <span className=\"ml-1.5 text-xs text-muted-foreground\">({resource.id})</span>\n )}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-1.5\">\n <div className=\"flex items-center gap-1.5\">\n <Label>{t('settings:webhooks.editor.secret')}</Label>\n <InfoTooltip\n content={t('settings:webhooks.editor.secretHint')}\n ariaLabel={t('settings:webhooks.editor.secret')}\n side=\"right\"\n />\n </div>\n <Input value={secret} onChange={(e) => setSecret(e.target.value)} type=\"password\" />\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <Switch checked={enabled} onCheckedChange={setEnabled} />\n <Label>{t('settings:webhooks.editor.enabled')}</Label>\n </div>\n <div className=\"space-y-2\">\n <Label>{t('settings:webhooks.editor.events')}</Label>\n <div className=\"flex flex-wrap gap-2\">\n {WEBHOOK_EVENTS.map((event) => (\n <label key={event} className=\"flex items-center gap-2 rounded-md border border-border px-3 py-2 text-sm\">\n <Checkbox checked={events.includes(event)} onCheckedChange={() => toggleEvent(event)} />\n {event}\n </label>\n ))}\n </div>\n </div>\n {selectedResource && (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-1.5\">\n <Label>{t('settings:webhooks.editor.payloadFields')}</Label>\n <InfoTooltip\n content={t('settings:webhooks.editor.payloadFieldsHint')}\n ariaLabel={t('settings:webhooks.editor.payloadFields')}\n side=\"right\"\n />\n </div>\n <div className=\"grid gap-2 sm:grid-cols-2\">\n {selectedResource.properties.map((property) => (\n <label key={property.path} className=\"flex items-center gap-2 text-sm\">\n <Checkbox\n checked={payloadFields.includes(property.path)}\n onCheckedChange={() =>\n setPayloadFields((prev) =>\n prev.includes(property.path)\n ? prev.filter((p) => p !== property.path)\n : [...prev, property.path],\n )\n }\n />\n {property.label}\n </label>\n ))}\n </div>\n </div>\n )}\n <div className=\"grid gap-3 sm:grid-cols-2\">\n <div className=\"space-y-1.5\">\n <div className=\"flex items-center gap-1.5\">\n <Label>{t('settings:webhooks.editor.headers')}</Label>\n <InfoTooltip\n content={t('settings:webhooks.editor.headersHint')}\n ariaLabel={t('settings:webhooks.editor.headers')}\n side=\"top\"\n />\n </div>\n <JsonEditor value={headers} onChange={(next) => setHeaders(toJsonRecord(next))} />\n </div>\n <div className=\"space-y-1.5\">\n <div className=\"flex items-center gap-1.5\">\n <Label>{t('settings:webhooks.editor.filters')}</Label>\n <InfoTooltip\n content={t('settings:webhooks.editor.filtersHint')}\n ariaLabel={t('settings:webhooks.editor.filters')}\n side=\"top\"\n />\n </div>\n <JsonEditor value={filters} onChange={(next) => setFilters(toJsonRecord(next))} />\n </div>\n </div>\n <DialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => onOpenChange(false)}>{t('common:cancel')}</Button>\n <Button type=\"submit\" disabled={save.isPending || !name.trim() || !url.trim() || events.length === 0}>\n {save.isPending ? t('common:saving') : t('common:save')}\n </Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n )\n}\n\nconst resourceName = (\n resources: ResourceJSON[],\n id: string | null | undefined,\n fallback: string,\n): string => id ? (resources.find((r) => r.id === id)?.name ?? id) : fallback\n\nconst toJsonRecord = (value: unknown): Record<string, unknown> =>\n value && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : {}\n\nconst stringRecord = (value: Record<string, unknown>): Record<string, string> => {\n const out: Record<string, string> = {}\n for (const [key, item] of Object.entries(value)) {\n if (item != null && item !== '') out[key] = String(item)\n }\n return out\n}\n\n// ─── Created-secret dialog ────────────────────────────────────────────────────\n\nfunction CreatedSecretDialog({\n secret,\n onClose,\n}: {\n secret: { key: string; record: ApiKeyRecord } | null\n onClose: () => void\n}): React.ReactElement {\n const { t } = useI18n()\n const notify = useNotify()\n const [reveal, setReveal] = React.useState(false)\n const [copied, setCopied] = React.useState(false)\n\n React.useEffect(() => {\n if (!secret) {\n setReveal(false)\n setCopied(false)\n }\n }, [secret])\n\n const onCopy = async (): Promise<void> => {\n if (!secret) return\n try {\n await navigator.clipboard.writeText(secret.key)\n setCopied(true)\n notify.success({ key: 'settings:apiKeys.notice.copied' })\n setTimeout(() => setCopied(false), 1500)\n } catch {\n notify.error({ key: 'settings:apiKeys.notice.copyFailed' })\n }\n }\n\n return (\n <Dialog open={!!secret} onOpenChange={(open) => !open && onClose()}>\n <DialogContent className=\"max-w-lg\">\n <DialogHeader>\n <DialogTitle className=\"flex items-center gap-2\">\n <SettingsIcon className=\"size-5\" />\n {t('settings:apiKeys.created.title')}\n </DialogTitle>\n <DialogDescription>{t('settings:apiKeys.created.description')}</DialogDescription>\n </DialogHeader>\n <div className=\"rounded-md border border-amber-300/60 bg-amber-50 p-3 text-sm text-amber-900 dark:border-amber-300/30 dark:bg-amber-950/40 dark:text-amber-200\">\n <div className=\"flex items-start gap-2\">\n <AlertTriangle className=\"mt-0.5 size-4\" />\n <p>{t('settings:apiKeys.created.warning')}</p>\n </div>\n </div>\n <div className=\"flex items-stretch gap-2\">\n <div className=\"relative flex-1\">\n <Input\n readOnly\n type={reveal ? 'text' : 'password'}\n value={secret?.key ?? ''}\n className=\"pr-10 font-mono text-xs\"\n onFocus={(e) => e.currentTarget.select()}\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"absolute right-1 top-1/2 -translate-y-1/2\"\n onClick={() => setReveal((v) => !v)}\n aria-label={reveal ? t('settings:apiKeys.created.hide') : t('settings:apiKeys.created.reveal')}\n >\n {reveal ? <EyeOff className=\"size-4\" /> : <Eye className=\"size-4\" />}\n </Button>\n </div>\n <Button type=\"button\" onClick={onCopy} variant=\"secondary\">\n {copied ? <Check className=\"size-4\" /> : <Copy className=\"size-4\" />}\n <span className=\"hidden sm:inline\">\n {copied ? t('settings:apiKeys.created.copied') : t('settings:apiKeys.created.copy')}\n </span>\n </Button>\n </div>\n <DialogFooter>\n <Button onClick={onClose}>{t('common:done')}</Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n\nconst formatDate = (input: string | Date): string => {\n try {\n return new Date(input).toLocaleString()\n } catch {\n return String(input)\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{a as e,n as t}from"./createLucideIcon-QE2kj6ru.js";import{C as n}from"./floating-layer-BcTp2AMB.js";import{t as r}from"./trash-2-BIJVpWxv.js";import{t as i}from"./circle-alert-D1sKnXtO.js";import{t as a}from"./pencil-kFOObGrY.js";import{t as o}from"./zap-BxPAEPtJ.js";import{o as s}from"./dist-DPxQeZn3.js";import{E as c,N as l,T as u,b as d,d as f,g as p,l as m,nt as h}from"./hooks-BiOfAnEq.js";import{c as g,l as _,n as v,o as y,r as b,s as x}from"./action-component-host-8DE4kuUJ.js";import{a as S,i as C,n as w,t as T}from"./card-BYbadRar.js";import{i as E,n as D,r as O,t as k}from"./tabs-Bj4gQaH2.js";import{a as A,c as j,l as M,o as N,r as P,s as F,t as I}from"./property-renderer-ClrVnSny.js";import{t as L}from"./revisions-button-Csueldv_.js";import{D as R,E as z,O as B,T as V,i as H,l as U,n as W,o as G,r as K,w as q}from"./index-CASCzvYu.js";var J=e(t(),1),Y=n();function X({parentRecordId:e,related:t,active:n}){let[r,i]=J.useState({perPage:10}),[a,o]=J.useState(n);return J.useEffect(()=>{n&&o(!0)},[n]),a?(0,Y.jsx)(P,{resourceId:t.resourceId,query:r,onQueryChange:i,lockedFilters:{[t.foreignKey]:e},embedPadding:!1,features:{breadcrumbs:!1,title:!1,create:!1,export:!1,card:!1}}):null}function Z({resource:e,recordId:t}){let{t:n}=l(),r=c(),i=e.showRelatedResources!==!1,a=J.useMemo(()=>i?j(e,r):[],[i,e,r]),[o,s]=J.useState(()=>a[0]?`${a[0].resourceId}::${a[0].foreignKey}`:``);if(J.useEffect(()=>{a.length!==0&&(a.some(e=>`${e.resourceId}::${e.foreignKey}`===o)||s(`${a[0].resourceId}::${a[0].foreignKey}`))},[o,a]),a.length===0)return null;let u=e=>e.label??r.find(t=>t.id===e.resourceId)?.name??e.resourceId;return(0,Y.jsxs)(T,{children:[(0,Y.jsx)(C,{children:(0,Y.jsx)(S,{className:`text-base`,children:n(`common:relatedRecords`)})}),(0,Y.jsx)(w,{children:(0,Y.jsxs)(k,{value:o,onValueChange:s,children:[(0,Y.jsx)(O,{className:`w-full justify-start`,children:a.map(e=>{let t=`${e.resourceId}::${e.foreignKey}`;return(0,Y.jsx)(E,{value:t,children:u(e)},t)})}),a.map(e=>{let n=`${e.resourceId}::${e.foreignKey}`;return(0,Y.jsx)(D,{value:n,className:`mt-4`,children:(0,Y.jsx)(X,{parentRecordId:t,related:e,active:o===n})},n)})]})})]})}function Q({error:e,t}){let{status:n,message:r}=h(e),a=t(n===404?`errors:notFound`:n===403?`errors:forbidden`:`errors:server`);return(0,Y.jsxs)(`div`,{className:`flex items-start gap-3 rounded-lg border border-destructive/50 bg-destructive/10 p-4 dark:bg-destructive/15`,children:[(0,Y.jsx)(i,{className:`mt-0.5 size-5 shrink-0 text-destructive`}),(0,Y.jsxs)(`div`,{className:`space-y-1 text-sm`,children:[(0,Y.jsx)(`p`,{className:`font-semibold text-destructive`,children:a}),(0,Y.jsx)(`p`,{className:`text-destructive/90`,children:r})]})]})}function $({resourceId:e,recordId:t}){let n=u(e),i=d(e,t),c=m(e),h=p(e),E=f(),{t:D}=l(),O=G(),k=K(),j=U(),P=N(e),J=i.data?.record,X=x((n?.actions??[]).filter(e=>e.actionType===`record`&&![`show`,`edit`,`delete`].includes(e.name)),J),$=y(`edit`,J),ee=y(`delete`,J);W(`mod+e`,()=>{!i.data||!$||O({name:`edit`,resourceId:e,recordId:t})},{description:D(`common:edit`)});let te=async()=>{await k.confirm({title:D(`common:confirmDelete`),confirmLabel:D(`common:delete`),destructive:!0})&&(await c.mutateAsync(t),O({name:`list`,resourceId:e}))};if(!n)return(0,Y.jsx)(`div`,{className:`p-6`,children:D(`common:loading`)});let ne=V(),re=i.data?.record?.title||t;return(0,Y.jsxs)(`div`,{className:`space-y-2 sm:space-y-4`,children:[(0,Y.jsx)(g,{items:[_(D(`common:home`)),{label:n.name,to:{name:`list`,resourceId:e}},{label:re}]}),(0,Y.jsxs)(T,{children:[(0,Y.jsxs)(C,{className:`flex flex-row items-center justify-between gap-3`,children:[(0,Y.jsxs)(S,{className:`truncate`,children:[n.name,` #`,t]}),i.data&&(0,Y.jsxs)(`div`,{className:`flex shrink-0 flex-wrap gap-2`,children:[E.history&&(0,Y.jsx)(L,{resourceId:e,recordId:t}),$&&(0,Y.jsxs)(z,{children:[(0,Y.jsx)(B,{asChild:!0,children:(0,Y.jsx)(s,{variant:`outline-primary`,size:`sm`,asChild:!0,children:(0,Y.jsxs)(H,{to:{name:`edit`,resourceId:e,recordId:t},"aria-label":D(`common:edit`),children:[(0,Y.jsx)(a,{className:`size-4`}),(0,Y.jsx)(`span`,{className:`hidden sm:inline`,children:D(`common:edit`)})]})})}),(0,Y.jsxs)(R,{className:`flex items-center gap-1.5`,children:[(0,Y.jsx)(`span`,{children:D(`common:edit`)}),(0,Y.jsxs)(`span`,{className:`inline-flex items-center gap-0.5`,children:[(0,Y.jsx)(q,{children:ne}),(0,Y.jsx)(`span`,{className:`text-muted-foreground`,children:`+`}),(0,Y.jsx)(q,{children:`E`})]})]})]}),ee&&(0,Y.jsxs)(s,{variant:`outline-destructive`,size:`sm`,disabled:c.isPending,onClick:()=>void te(),"aria-label":D(`common:delete`),children:[(0,Y.jsx)(r,{className:`size-4`}),(0,Y.jsx)(`span`,{className:`hidden sm:inline`,children:D(`common:delete`)})]}),X.length>0&&(0,Y.jsx)(b,{actions:X,onAction:async e=>{if(A(e)){P(e,{recordId:t});return}await F(e,k)&&h.mutateAsync({recordId:t,actionName:e.name}).then(e=>v(j,e.notice)).catch(e=>j.error({message:e.message}))},t:D,trigger:(0,Y.jsxs)(s,{variant:`outline`,size:`sm`,disabled:h.isPending,"aria-label":D(`common:actions`),children:[(0,Y.jsx)(o,{className:`size-4`}),(0,Y.jsx)(`span`,{className:`hidden sm:inline`,children:D(`common:actions`)})]})})]})]}),(0,Y.jsx)(w,{children:(0,Y.jsxs)(`div`,{className:`space-y-4`,children:[i.isLoading&&(0,Y.jsx)(`p`,{className:`text-muted-foreground`,children:D(`common:loading`)}),i.isError&&(0,Y.jsx)(Q,{error:i.error,t:D}),i.data&&(0,Y.jsx)(`dl`,{className:`[column-fill:_balance] md:columns-2`,children:M(n.properties,`show`,n.propertyOrder?.show).map(e=>(0,Y.jsxs)(`div`,{className:`mb-8 break-inside-avoid`,children:[(0,Y.jsx)(`dt`,{className:`text-xs font-semibold uppercase tracking-wide text-muted-foreground`,children:e.label}),(0,Y.jsx)(`dd`,{className:`mt-1`,children:(0,Y.jsx)(I,{property:e,value:i.data.record.params[e.path],view:`show`,populated:i.data.record.populated})})]},e.path))})]})})]}),i.data&&(0,Y.jsx)(Z,{resource:n,recordId:t})]})}export{$ as ResourceShowPage};
2
+ //# sourceMappingURL=show-page-CDgUXhsx.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"show-page-Dgw-9Pmn.js","names":[],"sources":["../../../../react/src/components/related-records-tabs.tsx","../../../../react/src/pages/show-page.tsx"],"sourcesContent":["// Tabs of records that reference the open record through a foreign key.\n// Each tab embeds the full ResourceListPage filtered by a locked\n// `{ [foreignKey]: parentRecordId }` so it gets the same table, filters,\n// bulk actions, pagination, and row-click behaviour as the main list.\n//\n// Designed to live below the property card on the show page.\n\nimport * as React from 'react'\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@modern-admin/ui'\nimport { useResources } from '../hooks.js'\nimport { useI18n } from '../i18n.js'\nimport { ResourceListPage } from '../pages/list-page.js'\nimport { resolveRelatedResources } from '../relations.js'\nimport type { ListQueryState } from '../router.js'\nimport type { RelatedResource, ResourceJSON } from '../types.js'\n\ninterface RelatedRecordsTabProps {\n parentRecordId: string\n related: RelatedResource\n active: boolean\n}\n\nfunction RelatedRecordsTab({\n parentRecordId,\n related,\n active,\n}: RelatedRecordsTabProps): React.ReactElement | null {\n // Each tab keeps its own page/sort/filter state. Defaults: page 1, perPage 10\n // so embedded tables stay compact compared to the main list (default 20).\n const [query, setQuery] = React.useState<ListQueryState>({ perPage: 10 })\n\n // Lazy-load tab content: only mount the (heavy) ResourceListPage once the\n // user actually visits the tab. Subsequent toggles keep state thanks to\n // Radix's mount-on-activate semantics on TabsContent (we don't force unmount).\n const [hasBeenActive, setHasBeenActive] = React.useState(active)\n React.useEffect(() => {\n if (active) setHasBeenActive(true)\n }, [active])\n\n if (!hasBeenActive) return null\n\n return (\n <ResourceListPage\n resourceId={related.resourceId}\n query={query}\n onQueryChange={setQuery}\n lockedFilters={{ [related.foreignKey]: parentRecordId }}\n // The host `CardContent` already pads the tab body — don't double it,\n // or the table stops spanning the block's full width.\n embedPadding={false}\n features={{\n breadcrumbs: false,\n title: false,\n create: false,\n export: false,\n card: false,\n }}\n />\n )\n}\n\nexport interface RelatedRecordsTabsProps {\n resource: ResourceJSON\n recordId: string\n}\n\nexport function RelatedRecordsTabs({\n resource,\n recordId,\n}: RelatedRecordsTabsProps): React.ReactElement | null {\n const { t } = useI18n()\n const allResources = useResources()\n // Master switch: `showRelatedResources: false` in the resource config hides\n // the whole section regardless of configured/auto-discovered relations.\n const enabled = resource.showRelatedResources !== false\n const tabs = React.useMemo(\n () => (enabled ? resolveRelatedResources(resource, allResources) : []),\n [enabled, resource, allResources],\n )\n // Hooks must run before any early return — call useState unconditionally.\n const [active, setActive] = React.useState<string>(\n () => tabs[0] ? `${tabs[0].resourceId}::${tabs[0].foreignKey}` : '',\n )\n React.useEffect(() => {\n if (tabs.length === 0) return\n if (tabs.some((r) => `${r.resourceId}::${r.foreignKey}` === active)) return\n setActive(`${tabs[0]!.resourceId}::${tabs[0]!.foreignKey}`)\n }, [active, tabs])\n if (tabs.length === 0) return null\n\n const labelFor = (r: RelatedResource): string =>\n r.label ?? allResources.find((x) => x.id === r.resourceId)?.name ?? r.resourceId\n\n return (\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">{t('common:relatedRecords')}</CardTitle>\n </CardHeader>\n <CardContent>\n <Tabs value={active} onValueChange={setActive}>\n <TabsList className=\"w-full justify-start\">\n {tabs.map((r) => {\n const key = `${r.resourceId}::${r.foreignKey}`\n return (\n <TabsTrigger key={key} value={key}>\n {labelFor(r)}\n </TabsTrigger>\n )\n })}\n </TabsList>\n {tabs.map((r) => {\n const key = `${r.resourceId}::${r.foreignKey}`\n return (\n <TabsContent key={key} value={key} className=\"mt-4\">\n <RelatedRecordsTab\n parentRecordId={recordId}\n related={r}\n active={active === key}\n />\n </TabsContent>\n )\n })}\n </Tabs>\n </CardContent>\n </Card>\n )\n}\n","import * as React from 'react'\nimport {\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Kbd,\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n getModKeyLabel,\n} from '@modern-admin/ui'\nimport { AlertCircle, Pencil, Trash2, Zap } from 'lucide-react'\nimport { useDeleteRecord, useFeatures, useInvokeRecordAction, useRecord, useResource } from '../hooks.js'\nimport { confirmGuard } from '../action-guard.js'\nimport { showActionNotice } from '../action-notice.js'\nimport { hasActionComponent, useActionLauncher } from '../action-launcher.js'\nimport { parseApiError } from '../client.js'\nimport { PropertyDisplay } from '../property-renderer.js'\nimport { Link, useNavigate } from '../router.js'\nimport { useI18n } from '../i18n.js'\nimport { useHotkey } from '../use-hotkey.js'\nimport { PageBreadcrumbs, homeCrumb } from '../breadcrumbs.js'\nimport { RelatedRecordsTabs } from '../components/related-records-tabs.js'\nimport { useDialogs } from '../dialogs.js'\nimport { useNotify } from '../notify.js'\nimport { ActionMenu, isActionAllowedForRecord, visibleRecordActions } from '../action-menu.js'\nimport { RevisionsButton } from '../components/revisions-button.js'\nimport { visibleRecordProperties } from '../relations.js'\n\nfunction PageError({\n error,\n t,\n}: {\n error: unknown\n t: (key: string) => string\n}): React.ReactElement {\n const { status, message } = parseApiError(error)\n const title =\n status === 404\n ? t('errors:notFound')\n : status === 403\n ? t('errors:forbidden')\n : t('errors:server')\n return (\n <div className=\"flex items-start gap-3 rounded-lg border border-destructive/50 bg-destructive/10 p-4 dark:bg-destructive/15\">\n <AlertCircle className=\"mt-0.5 size-5 shrink-0 text-destructive\" />\n <div className=\"space-y-1 text-sm\">\n <p className=\"font-semibold text-destructive\">{title}</p>\n <p className=\"text-destructive/90\">{message}</p>\n </div>\n </div>\n )\n}\n\nexport interface ResourceShowPageProps {\n resourceId: string\n recordId: string\n}\n\nexport function ResourceShowPage({\n resourceId,\n recordId,\n}: ResourceShowPageProps): React.ReactElement {\n const resource = useResource(resourceId)\n const record = useRecord(resourceId, recordId)\n const remove = useDeleteRecord(resourceId)\n const invokeRecord = useInvokeRecordAction(resourceId)\n const features = useFeatures()\n const { t } = useI18n()\n const navigate = useNavigate()\n const dialogs = useDialogs()\n const notify = useNotify()\n const openActionComponent = useActionLauncher(resourceId)\n\n // `recordActions` on the loaded record carries the server's per-record\n // `isVisible`/`isAccessible` verdict, which `resource.actions` cannot —\n // it is serialized without any record in context.\n const loadedRecord = record.data?.record\n const customRecordActions = visibleRecordActions(\n (resource?.actions ?? []).filter(\n (a) => a.actionType === 'record' && !['show', 'edit', 'delete'].includes(a.name),\n ),\n loadedRecord,\n )\n const canEdit = isActionAllowedForRecord('edit', loadedRecord)\n const canDelete = isActionAllowedForRecord('delete', loadedRecord)\n\n // ── Keyboard shortcuts ──\n // Ctrl/Cmd+E jumps into edit. Discoverable via the action-button tooltip.\n useHotkey(\n 'mod+e',\n () => {\n if (!record.data || !canEdit) return\n navigate({ name: 'edit', resourceId, recordId })\n },\n { description: t('common:edit') },\n )\n\n const handleDelete = async (): Promise<void> => {\n const ok = await dialogs.confirm({\n title: t('common:confirmDelete'),\n confirmLabel: t('common:delete'),\n destructive: true,\n })\n if (!ok) return\n await remove.mutateAsync(recordId)\n navigate({ name: 'list', resourceId })\n }\n\n if (!resource) return <div className=\"p-6\">{t('common:loading')}</div>\n\n const modLabel = getModKeyLabel()\n const recordLabel = record.data?.record?.title || recordId\n\n return (\n <div className=\"space-y-2 sm:space-y-4\">\n <PageBreadcrumbs\n items={[\n homeCrumb(t('common:home')),\n { label: resource.name, to: { name: 'list', resourceId } },\n { label: recordLabel },\n ]}\n />\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between gap-3\">\n <CardTitle className=\"truncate\">\n {resource.name} #{recordId}\n </CardTitle>\n {record.data && (\n <div className=\"flex shrink-0 flex-wrap gap-2\">\n {features.history && (\n <RevisionsButton resourceId={resourceId} recordId={recordId} />\n )}\n {canEdit && (\n <Tooltip>\n <TooltipTrigger asChild>\n {/* `asChild` + Link-as-Button keeps the rendered DOM a\n * single `<a>` so it picks up the Button's `h-8` from\n * `size=\"sm\"` instead of stacking a Link wrapper that\n * collapses to its anchor default height. */}\n <Button variant=\"outline-primary\" size=\"sm\" asChild>\n <Link to={{ name: 'edit', resourceId, recordId }} aria-label={t('common:edit')}>\n <Pencil className=\"size-4\" />\n <span className=\"hidden sm:inline\">{t('common:edit')}</span>\n </Link>\n </Button>\n </TooltipTrigger>\n <TooltipContent className=\"flex items-center gap-1.5\">\n <span>{t('common:edit')}</span>\n <span className=\"inline-flex items-center gap-0.5\">\n <Kbd>{modLabel}</Kbd>\n <span className=\"text-muted-foreground\">+</span>\n <Kbd>E</Kbd>\n </span>\n </TooltipContent>\n </Tooltip>\n )}\n {canDelete && (\n <Button\n variant=\"outline-destructive\"\n size=\"sm\"\n disabled={remove.isPending}\n onClick={() => void handleDelete()}\n aria-label={t('common:delete')}\n >\n <Trash2 className=\"size-4\" />\n <span className=\"hidden sm:inline\">{t('common:delete')}</span>\n </Button>\n )}\n {customRecordActions.length > 0 && (\n <ActionMenu\n actions={customRecordActions}\n onAction={async (action) => {\n if (hasActionComponent(action)) {\n openActionComponent(action, { recordId })\n return\n }\n if (!await confirmGuard(action, dialogs)) return\n void invokeRecord\n .mutateAsync({ recordId, actionName: action.name })\n .then((res) => showActionNotice(notify, res.notice))\n .catch((err: Error) =>\n notify.error({ message: err.message }),\n )\n }}\n t={t}\n trigger={(\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={invokeRecord.isPending}\n aria-label={t('common:actions')}\n >\n <Zap className=\"size-4\" />\n <span className=\"hidden sm:inline\">{t('common:actions')}</span>\n </Button>\n )}\n />\n )}\n </div>\n )}\n </CardHeader>\n <CardContent>\n <div className=\"space-y-4\">\n {record.isLoading && <p className=\"text-muted-foreground\">{t('common:loading')}</p>}\n {record.isError && <PageError error={record.error} t={t} />}\n {record.data && (\n <dl className=\"[column-fill:_balance] md:columns-2\">\n {visibleRecordProperties(resource.properties, 'show', resource.propertyOrder?.show)\n .map((p) => (\n <div key={p.path} className=\"mb-8 break-inside-avoid\">\n <dt className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n {p.label}\n </dt>\n <dd className=\"mt-1\">\n <PropertyDisplay\n property={p}\n value={record.data!.record.params[p.path]}\n view=\"show\"\n populated={record.data!.record.populated as Record<string, unknown> | undefined}\n />\n </dd>\n </div>\n ))}\n </dl>\n )}\n </div>\n </CardContent>\n </Card>\n {record.data && <RelatedRecordsTabs resource={resource} recordId={recordId} />}\n </div>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"show-page-CDgUXhsx.js","names":[],"sources":["../../../../react/src/components/related-records-tabs.tsx","../../../../react/src/pages/show-page.tsx"],"sourcesContent":["// Tabs of records that reference the open record through a foreign key.\n// Each tab embeds the full ResourceListPage filtered by a locked\n// `{ [foreignKey]: parentRecordId }` so it gets the same table, filters,\n// bulk actions, pagination, and row-click behaviour as the main list.\n//\n// Designed to live below the property card on the show page.\n\nimport * as React from 'react'\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@modern-admin/ui'\nimport { useResources } from '../hooks.js'\nimport { useI18n } from '../i18n.js'\nimport { ResourceListPage } from '../pages/list-page.js'\nimport { resolveRelatedResources } from '../relations.js'\nimport type { ListQueryState } from '../router.js'\nimport type { RelatedResource, ResourceJSON } from '../types.js'\n\ninterface RelatedRecordsTabProps {\n parentRecordId: string\n related: RelatedResource\n active: boolean\n}\n\nfunction RelatedRecordsTab({\n parentRecordId,\n related,\n active,\n}: RelatedRecordsTabProps): React.ReactElement | null {\n // Each tab keeps its own page/sort/filter state. Defaults: page 1, perPage 10\n // so embedded tables stay compact compared to the main list (default 20).\n const [query, setQuery] = React.useState<ListQueryState>({ perPage: 10 })\n\n // Lazy-load tab content: only mount the (heavy) ResourceListPage once the\n // user actually visits the tab. Subsequent toggles keep state thanks to\n // Radix's mount-on-activate semantics on TabsContent (we don't force unmount).\n const [hasBeenActive, setHasBeenActive] = React.useState(active)\n React.useEffect(() => {\n if (active) setHasBeenActive(true)\n }, [active])\n\n if (!hasBeenActive) return null\n\n return (\n <ResourceListPage\n resourceId={related.resourceId}\n query={query}\n onQueryChange={setQuery}\n lockedFilters={{ [related.foreignKey]: parentRecordId }}\n // The host `CardContent` already pads the tab body — don't double it,\n // or the table stops spanning the block's full width.\n embedPadding={false}\n features={{\n breadcrumbs: false,\n title: false,\n create: false,\n export: false,\n card: false,\n }}\n />\n )\n}\n\nexport interface RelatedRecordsTabsProps {\n resource: ResourceJSON\n recordId: string\n}\n\nexport function RelatedRecordsTabs({\n resource,\n recordId,\n}: RelatedRecordsTabsProps): React.ReactElement | null {\n const { t } = useI18n()\n const allResources = useResources()\n // Master switch: `showRelatedResources: false` in the resource config hides\n // the whole section regardless of configured/auto-discovered relations.\n const enabled = resource.showRelatedResources !== false\n const tabs = React.useMemo(\n () => (enabled ? resolveRelatedResources(resource, allResources) : []),\n [enabled, resource, allResources],\n )\n // Hooks must run before any early return — call useState unconditionally.\n const [active, setActive] = React.useState<string>(\n () => tabs[0] ? `${tabs[0].resourceId}::${tabs[0].foreignKey}` : '',\n )\n React.useEffect(() => {\n if (tabs.length === 0) return\n if (tabs.some((r) => `${r.resourceId}::${r.foreignKey}` === active)) return\n setActive(`${tabs[0]!.resourceId}::${tabs[0]!.foreignKey}`)\n }, [active, tabs])\n if (tabs.length === 0) return null\n\n const labelFor = (r: RelatedResource): string =>\n r.label ?? allResources.find((x) => x.id === r.resourceId)?.name ?? r.resourceId\n\n return (\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">{t('common:relatedRecords')}</CardTitle>\n </CardHeader>\n <CardContent>\n <Tabs value={active} onValueChange={setActive}>\n <TabsList className=\"w-full justify-start\">\n {tabs.map((r) => {\n const key = `${r.resourceId}::${r.foreignKey}`\n return (\n <TabsTrigger key={key} value={key}>\n {labelFor(r)}\n </TabsTrigger>\n )\n })}\n </TabsList>\n {tabs.map((r) => {\n const key = `${r.resourceId}::${r.foreignKey}`\n return (\n <TabsContent key={key} value={key} className=\"mt-4\">\n <RelatedRecordsTab\n parentRecordId={recordId}\n related={r}\n active={active === key}\n />\n </TabsContent>\n )\n })}\n </Tabs>\n </CardContent>\n </Card>\n )\n}\n","import * as React from 'react'\nimport {\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Kbd,\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n getModKeyLabel,\n} from '@modern-admin/ui'\nimport { AlertCircle, Pencil, Trash2, Zap } from 'lucide-react'\nimport { useDeleteRecord, useFeatures, useInvokeRecordAction, useRecord, useResource } from '../hooks.js'\nimport { confirmGuard } from '../action-guard.js'\nimport { showActionNotice } from '../action-notice.js'\nimport { hasActionComponent, useActionLauncher } from '../action-launcher.js'\nimport { parseApiError } from '../client.js'\nimport { PropertyDisplay } from '../property-renderer.js'\nimport { Link, useNavigate } from '../router.js'\nimport { useI18n } from '../i18n.js'\nimport { useHotkey } from '../use-hotkey.js'\nimport { PageBreadcrumbs, homeCrumb } from '../breadcrumbs.js'\nimport { RelatedRecordsTabs } from '../components/related-records-tabs.js'\nimport { useDialogs } from '../dialogs.js'\nimport { useNotify } from '../notify.js'\nimport { ActionMenu, isActionAllowedForRecord, visibleRecordActions } from '../action-menu.js'\nimport { RevisionsButton } from '../components/revisions-button.js'\nimport { visibleRecordProperties } from '../relations.js'\n\nfunction PageError({\n error,\n t,\n}: {\n error: unknown\n t: (key: string) => string\n}): React.ReactElement {\n const { status, message } = parseApiError(error)\n const title =\n status === 404\n ? t('errors:notFound')\n : status === 403\n ? t('errors:forbidden')\n : t('errors:server')\n return (\n <div className=\"flex items-start gap-3 rounded-lg border border-destructive/50 bg-destructive/10 p-4 dark:bg-destructive/15\">\n <AlertCircle className=\"mt-0.5 size-5 shrink-0 text-destructive\" />\n <div className=\"space-y-1 text-sm\">\n <p className=\"font-semibold text-destructive\">{title}</p>\n <p className=\"text-destructive/90\">{message}</p>\n </div>\n </div>\n )\n}\n\nexport interface ResourceShowPageProps {\n resourceId: string\n recordId: string\n}\n\nexport function ResourceShowPage({\n resourceId,\n recordId,\n}: ResourceShowPageProps): React.ReactElement {\n const resource = useResource(resourceId)\n const record = useRecord(resourceId, recordId)\n const remove = useDeleteRecord(resourceId)\n const invokeRecord = useInvokeRecordAction(resourceId)\n const features = useFeatures()\n const { t } = useI18n()\n const navigate = useNavigate()\n const dialogs = useDialogs()\n const notify = useNotify()\n const openActionComponent = useActionLauncher(resourceId)\n\n // `recordActions` on the loaded record carries the server's per-record\n // `isVisible`/`isAccessible` verdict, which `resource.actions` cannot —\n // it is serialized without any record in context.\n const loadedRecord = record.data?.record\n const customRecordActions = visibleRecordActions(\n (resource?.actions ?? []).filter(\n (a) => a.actionType === 'record' && !['show', 'edit', 'delete'].includes(a.name),\n ),\n loadedRecord,\n )\n const canEdit = isActionAllowedForRecord('edit', loadedRecord)\n const canDelete = isActionAllowedForRecord('delete', loadedRecord)\n\n // ── Keyboard shortcuts ──\n // Ctrl/Cmd+E jumps into edit. Discoverable via the action-button tooltip.\n useHotkey(\n 'mod+e',\n () => {\n if (!record.data || !canEdit) return\n navigate({ name: 'edit', resourceId, recordId })\n },\n { description: t('common:edit') },\n )\n\n const handleDelete = async (): Promise<void> => {\n const ok = await dialogs.confirm({\n title: t('common:confirmDelete'),\n confirmLabel: t('common:delete'),\n destructive: true,\n })\n if (!ok) return\n await remove.mutateAsync(recordId)\n navigate({ name: 'list', resourceId })\n }\n\n if (!resource) return <div className=\"p-6\">{t('common:loading')}</div>\n\n const modLabel = getModKeyLabel()\n const recordLabel = record.data?.record?.title || recordId\n\n return (\n <div className=\"space-y-2 sm:space-y-4\">\n <PageBreadcrumbs\n items={[\n homeCrumb(t('common:home')),\n { label: resource.name, to: { name: 'list', resourceId } },\n { label: recordLabel },\n ]}\n />\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between gap-3\">\n <CardTitle className=\"truncate\">\n {resource.name} #{recordId}\n </CardTitle>\n {record.data && (\n <div className=\"flex shrink-0 flex-wrap gap-2\">\n {features.history && (\n <RevisionsButton resourceId={resourceId} recordId={recordId} />\n )}\n {canEdit && (\n <Tooltip>\n <TooltipTrigger asChild>\n {/* `asChild` + Link-as-Button keeps the rendered DOM a\n * single `<a>` so it picks up the Button's `h-8` from\n * `size=\"sm\"` instead of stacking a Link wrapper that\n * collapses to its anchor default height. */}\n <Button variant=\"outline-primary\" size=\"sm\" asChild>\n <Link to={{ name: 'edit', resourceId, recordId }} aria-label={t('common:edit')}>\n <Pencil className=\"size-4\" />\n <span className=\"hidden sm:inline\">{t('common:edit')}</span>\n </Link>\n </Button>\n </TooltipTrigger>\n <TooltipContent className=\"flex items-center gap-1.5\">\n <span>{t('common:edit')}</span>\n <span className=\"inline-flex items-center gap-0.5\">\n <Kbd>{modLabel}</Kbd>\n <span className=\"text-muted-foreground\">+</span>\n <Kbd>E</Kbd>\n </span>\n </TooltipContent>\n </Tooltip>\n )}\n {canDelete && (\n <Button\n variant=\"outline-destructive\"\n size=\"sm\"\n disabled={remove.isPending}\n onClick={() => void handleDelete()}\n aria-label={t('common:delete')}\n >\n <Trash2 className=\"size-4\" />\n <span className=\"hidden sm:inline\">{t('common:delete')}</span>\n </Button>\n )}\n {customRecordActions.length > 0 && (\n <ActionMenu\n actions={customRecordActions}\n onAction={async (action) => {\n if (hasActionComponent(action)) {\n openActionComponent(action, { recordId })\n return\n }\n if (!await confirmGuard(action, dialogs)) return\n void invokeRecord\n .mutateAsync({ recordId, actionName: action.name })\n .then((res) => showActionNotice(notify, res.notice))\n .catch((err: Error) =>\n notify.error({ message: err.message }),\n )\n }}\n t={t}\n trigger={(\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={invokeRecord.isPending}\n aria-label={t('common:actions')}\n >\n <Zap className=\"size-4\" />\n <span className=\"hidden sm:inline\">{t('common:actions')}</span>\n </Button>\n )}\n />\n )}\n </div>\n )}\n </CardHeader>\n <CardContent>\n <div className=\"space-y-4\">\n {record.isLoading && <p className=\"text-muted-foreground\">{t('common:loading')}</p>}\n {record.isError && <PageError error={record.error} t={t} />}\n {record.data && (\n <dl className=\"[column-fill:_balance] md:columns-2\">\n {visibleRecordProperties(resource.properties, 'show', resource.propertyOrder?.show)\n .map((p) => (\n <div key={p.path} className=\"mb-8 break-inside-avoid\">\n <dt className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n {p.label}\n </dt>\n <dd className=\"mt-1\">\n <PropertyDisplay\n property={p}\n value={record.data!.record.params[p.path]}\n view=\"show\"\n populated={record.data!.record.populated as Record<string, unknown> | undefined}\n />\n </dd>\n </div>\n ))}\n </dl>\n )}\n </div>\n </CardContent>\n </Card>\n {record.data && <RelatedRecordsTabs resource={resource} recordId={recordId} />}\n </div>\n )\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{t as e}from"./createLucideIcon-CUopU_LC.js";var t=e(`sparkles`,[[`path`,{d:`M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z`,key:`1s2grr`}],[`path`,{d:`M20 2v4`,key:`1rf3ol`}],[`path`,{d:`M22 4h-4`,key:`gwowj6`}],[`circle`,{cx:`4`,cy:`20`,r:`2`,key:`6kqj1y`}]]);export{t};
2
- //# sourceMappingURL=sparkles-CqF0zjrF.js.map
1
+ import{t as e}from"./createLucideIcon-QE2kj6ru.js";var t=e(`sparkles`,[[`path`,{d:`M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z`,key:`1s2grr`}],[`path`,{d:`M20 2v4`,key:`1rf3ol`}],[`path`,{d:`M22 4h-4`,key:`gwowj6`}],[`circle`,{cx:`4`,cy:`20`,r:`2`,key:`6kqj1y`}]]);export{t};
2
+ //# sourceMappingURL=sparkles-1tT0H4n4.js.map