@alepha/ui 0.18.2 → 0.19.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 (257) hide show
  1. package/dist/admin/{AdminApiKeys-BJhIwfD6.js → AdminApiKeys-Bt1PjO6o.js} +3 -4
  2. package/dist/admin/{AdminApiKeys-BJhIwfD6.js.map → AdminApiKeys-Bt1PjO6o.js.map} +1 -1
  3. package/dist/admin/{AdminAudits-DzD_4cDt.js → AdminAudits-C7c1CN4c.js} +3 -4
  4. package/dist/admin/{AdminAudits-DzD_4cDt.js.map → AdminAudits-C7c1CN4c.js.map} +1 -1
  5. package/dist/admin/{AdminDashboard-C92tIc6x.js → AdminDashboard-C3RXpTp6.js} +3 -4
  6. package/dist/admin/{AdminDashboard-C92tIc6x.js.map → AdminDashboard-C3RXpTp6.js.map} +1 -1
  7. package/dist/admin/{AdminFiles-DLpfhBkf.js → AdminFiles-31ivR6Wq.js} +3 -4
  8. package/dist/admin/{AdminFiles-DLpfhBkf.js.map → AdminFiles-31ivR6Wq.js.map} +1 -1
  9. package/dist/admin/{AdminJobDashboard-KIOkeMgE.js → AdminJobDashboard-BABLe7hL.js} +73 -25
  10. package/dist/admin/AdminJobDashboard-BABLe7hL.js.map +1 -0
  11. package/dist/admin/{AdminJobExecutions-D0Yo_PU0.js → AdminJobExecutions-D-G8RIlr.js} +3 -4
  12. package/dist/admin/{AdminJobExecutions-D0Yo_PU0.js.map → AdminJobExecutions-D-G8RIlr.js.map} +1 -1
  13. package/dist/admin/{AdminJobRegistry-PFajqaGK.js → AdminJobRegistry-oIS3K9NX.js} +3 -4
  14. package/dist/admin/{AdminJobRegistry-PFajqaGK.js.map → AdminJobRegistry-oIS3K9NX.js.map} +1 -1
  15. package/dist/admin/{AdminLayout-B1DXZHDn.js → AdminLayout-BmZ9mtXh.js} +8 -25
  16. package/dist/admin/AdminLayout-BmZ9mtXh.js.map +1 -0
  17. package/dist/admin/AdminNotifications-DHdzksww.js +541 -0
  18. package/dist/admin/AdminNotifications-DHdzksww.js.map +1 -0
  19. package/dist/admin/{AdminParameters-BspPeqp_.js → AdminParameters-CyZQSXnN.js} +118 -112
  20. package/dist/admin/AdminParameters-CyZQSXnN.js.map +1 -0
  21. package/dist/admin/{AdminSessions-BnH5CZQl.js → AdminSessions--xwELDSO.js} +3 -4
  22. package/dist/admin/{AdminSessions-BnH5CZQl.js.map → AdminSessions--xwELDSO.js.map} +1 -1
  23. package/dist/admin/{AdminUserLayout-DUbC6-BI.js → AdminUserLayout-DvBTG5gd.js} +82 -115
  24. package/dist/admin/AdminUserLayout-DvBTG5gd.js.map +1 -0
  25. package/dist/admin/{AdminUserProfile-DuTUnjdG.js → AdminUserProfile-CzsPBl6Z.js} +7 -6
  26. package/dist/admin/AdminUserProfile-CzsPBl6Z.js.map +1 -0
  27. package/dist/admin/{AdminUserSessions-DvZdAGpL.js → AdminUserSessions-C-aUnhVN.js} +3 -4
  28. package/dist/admin/{AdminUserSessions-DvZdAGpL.js.map → AdminUserSessions-C-aUnhVN.js.map} +1 -1
  29. package/dist/admin/{AdminUsers-CR9z0g_5.js → AdminUsers-BYwei5sj.js} +4 -4
  30. package/dist/admin/AdminUsers-BYwei5sj.js.map +1 -0
  31. package/dist/admin/{AuthLayout-DsUfp9RG.js → AuthLayout-CkPGLJku.js} +3 -4
  32. package/dist/admin/{AuthLayout-DsUfp9RG.js.map → AuthLayout-CkPGLJku.js.map} +1 -1
  33. package/dist/{demo/IconGoogle-CSQLPYwX.js → admin/IconGoogle-8Nkx6yax.js} +2 -4
  34. package/dist/admin/{IconGoogle-Ch1m3Uzl.js.map → IconGoogle-8Nkx6yax.js.map} +1 -1
  35. package/dist/admin/Login-DSBqNsZc.js +274 -0
  36. package/dist/admin/Login-DSBqNsZc.js.map +1 -0
  37. package/dist/admin/{Profile-B2EcIDB9.js → Profile-CDRjJo0P.js} +31 -29
  38. package/dist/admin/Profile-CDRjJo0P.js.map +1 -0
  39. package/dist/admin/{Register-Z3fxRbUF.js → Register-4QGFOnfh.js} +201 -146
  40. package/dist/admin/Register-4QGFOnfh.js.map +1 -0
  41. package/dist/admin/{ResetPassword-_Y1qTTKh.js → ResetPassword-Gxc9L_mY.js} +9 -10
  42. package/dist/admin/ResetPassword-Gxc9L_mY.js.map +1 -0
  43. package/dist/admin/{VerifyEmail-Bg22bwcC.js → VerifyEmail-D7G5NnaN.js} +25 -11
  44. package/dist/admin/VerifyEmail-D7G5NnaN.js.map +1 -0
  45. package/dist/admin/adminUserAtom-DCi4wf-v.js +11 -0
  46. package/dist/admin/adminUserAtom-DCi4wf-v.js.map +1 -0
  47. package/dist/admin/{core-BVO_TQxb.js → core-D1AbU50V.js} +662 -570
  48. package/dist/admin/core-D1AbU50V.js.map +1 -0
  49. package/dist/admin/index.d.ts +141 -53
  50. package/dist/admin/index.d.ts.map +1 -1
  51. package/dist/admin/index.js +67 -49
  52. package/dist/admin/index.js.map +1 -1
  53. package/dist/admin/rolldown-runtime-CiIaOW0V.js +13 -0
  54. package/dist/{demo/AuthLayout-DN-ClJQk.js → auth/AuthLayout-CfRKcTqP.js} +3 -4
  55. package/dist/auth/{AuthLayout-C161NeF6.js.map → AuthLayout-CfRKcTqP.js.map} +1 -1
  56. package/dist/{admin/IconGoogle-Ch1m3Uzl.js → auth/IconGoogle-8Nkx6yax.js} +2 -4
  57. package/dist/auth/{IconGoogle-Ch1m3Uzl.js.map → IconGoogle-8Nkx6yax.js.map} +1 -1
  58. package/dist/auth/Login-DJyweoPS.js +274 -0
  59. package/dist/auth/Login-DJyweoPS.js.map +1 -0
  60. package/dist/auth/{Profile-BMpXJ0oi.js → Profile-Cy93pNTw.js} +31 -29
  61. package/dist/auth/Profile-Cy93pNTw.js.map +1 -0
  62. package/dist/auth/{Register-2gx8qll-.js → Register-CSqzzitW.js} +201 -146
  63. package/dist/auth/Register-CSqzzitW.js.map +1 -0
  64. package/dist/{demo/ResetPassword-CAPj8MO3.js → auth/ResetPassword-B61QPlQi.js} +9 -10
  65. package/dist/auth/ResetPassword-B61QPlQi.js.map +1 -0
  66. package/dist/{demo/VerifyEmail-DFmdCdYs.js → auth/VerifyEmail-CqBJ11id.js} +25 -11
  67. package/dist/auth/VerifyEmail-CqBJ11id.js.map +1 -0
  68. package/dist/auth/{core-DyfeVr5c.js → core-C6D3pazL.js} +403 -343
  69. package/dist/auth/core-C6D3pazL.js.map +1 -0
  70. package/dist/auth/index.d.ts +93 -54
  71. package/dist/auth/index.d.ts.map +1 -1
  72. package/dist/auth/index.js +30 -31
  73. package/dist/auth/index.js.map +1 -1
  74. package/dist/auth/rolldown-runtime-CiIaOW0V.js +13 -0
  75. package/dist/core/index.d.ts +123 -62
  76. package/dist/core/index.d.ts.map +1 -1
  77. package/dist/core/index.js +878 -776
  78. package/dist/core/index.js.map +1 -1
  79. package/dist/{auth/AuthLayout-C161NeF6.js → demo/AuthLayout-Dq5tSLSc.js} +3 -4
  80. package/dist/demo/{AuthLayout-DN-ClJQk.js.map → AuthLayout-Dq5tSLSc.js.map} +1 -1
  81. package/dist/demo/DemoButton-_Ws2w-J0.js +181 -0
  82. package/dist/demo/DemoButton-_Ws2w-J0.js.map +1 -0
  83. package/dist/demo/DemoControlSelect-ChP4ZOpQ.js +304 -0
  84. package/dist/demo/DemoControlSelect-ChP4ZOpQ.js.map +1 -0
  85. package/dist/demo/DemoDataTable-Hwf_UUni.js +361 -0
  86. package/dist/demo/DemoDataTable-Hwf_UUni.js.map +1 -0
  87. package/dist/demo/{DemoDialog-DW8QEvD1.js → DemoDialog-B01OMVRd.js} +3 -4
  88. package/dist/demo/{DemoDialog-DW8QEvD1.js.map → DemoDialog-B01OMVRd.js.map} +1 -1
  89. package/dist/demo/{DemoFlex-CAhLUanT.js → DemoFlex-870PEl0V.js} +4 -5
  90. package/dist/demo/{DemoFlex-CAhLUanT.js.map → DemoFlex-870PEl0V.js.map} +1 -1
  91. package/dist/demo/{DemoHeading-yIFmNjHB.js → DemoHeading-C1YR27fz.js} +4 -5
  92. package/dist/demo/{DemoHeading-yIFmNjHB.js.map → DemoHeading-C1YR27fz.js.map} +1 -1
  93. package/dist/demo/{DemoHome-BSGuBHus.js → DemoHome-DRbL2eGf.js} +4 -5
  94. package/dist/demo/{DemoHome-BSGuBHus.js.map → DemoHome-DRbL2eGf.js.map} +1 -1
  95. package/dist/demo/{DemoJsonViewer-DsA2IpgV.js → DemoJsonViewer-DoABiqBW.js} +4 -5
  96. package/dist/demo/{DemoJsonViewer-DsA2IpgV.js.map → DemoJsonViewer-DoABiqBW.js.map} +1 -1
  97. package/dist/demo/{DemoLayout-Cy6xjn6P.js → DemoLayout-CN_PDCX2.js} +16 -8
  98. package/dist/demo/DemoLayout-CN_PDCX2.js.map +1 -0
  99. package/dist/demo/{DemoLogin-vqxgTu4P.js → DemoLogin-B5x-ug3Q.js} +51 -35
  100. package/dist/demo/DemoLogin-B5x-ug3Q.js.map +1 -0
  101. package/dist/demo/{DemoRegister-YHPvPg77.js → DemoRegister-Q6sg2xuV.js} +51 -53
  102. package/dist/demo/DemoRegister-Q6sg2xuV.js.map +1 -0
  103. package/dist/demo/{DemoResetPassword-mOW18Zlm.js → DemoResetPassword-DrqZfmEw.js} +14 -19
  104. package/dist/demo/DemoResetPassword-DrqZfmEw.js.map +1 -0
  105. package/dist/demo/{DemoSidebar-od7aLjP_.js → DemoSidebar-CfKS6w1o.js} +4 -5
  106. package/dist/demo/{DemoSidebar-od7aLjP_.js.map → DemoSidebar-CfKS6w1o.js.map} +1 -1
  107. package/dist/demo/{DemoText-DU3JeRS0.js → DemoText-pT6Gi5b5.js} +4 -5
  108. package/dist/demo/{DemoText-DU3JeRS0.js.map → DemoText-pT6Gi5b5.js.map} +1 -1
  109. package/dist/demo/{DemoToast-CUJEiPRa.js → DemoToast-I13NBzQQ.js} +3 -4
  110. package/dist/demo/{DemoToast-CUJEiPRa.js.map → DemoToast-I13NBzQQ.js.map} +1 -1
  111. package/dist/demo/{DemoTypeForm-C1dNkahD.js → DemoTypeForm-BqzcrtvN.js} +9 -6
  112. package/dist/demo/DemoTypeForm-BqzcrtvN.js.map +1 -0
  113. package/dist/demo/DemoVerifyEmail-HwD8xfQw.js +33 -0
  114. package/dist/demo/DemoVerifyEmail-HwD8xfQw.js.map +1 -0
  115. package/dist/{auth/IconGoogle-Ch1m3Uzl.js → demo/IconGoogle-CwQy4G9y.js} +2 -4
  116. package/dist/demo/{IconGoogle-CSQLPYwX.js.map → IconGoogle-CwQy4G9y.js.map} +1 -1
  117. package/dist/demo/Login-CqG1iJbn.js +274 -0
  118. package/dist/demo/Login-CqG1iJbn.js.map +1 -0
  119. package/dist/demo/{Profile-BE_Y3co2.js → Profile-C0ojJCaG.js} +31 -29
  120. package/dist/demo/Profile-C0ojJCaG.js.map +1 -0
  121. package/dist/demo/{Register-fXHmBpr3.js → Register-KKZwr_lL.js} +201 -146
  122. package/dist/demo/Register-KKZwr_lL.js.map +1 -0
  123. package/dist/{auth/ResetPassword-DBxt9hKk.js → demo/ResetPassword-DMrLFEtr.js} +9 -10
  124. package/dist/demo/ResetPassword-DMrLFEtr.js.map +1 -0
  125. package/dist/demo/{Showcase-BtEU0pY9.js → Showcase-D49Wud2v.js} +65 -68
  126. package/dist/demo/Showcase-D49Wud2v.js.map +1 -0
  127. package/dist/{auth/VerifyEmail-Z80Ubajk.js → demo/VerifyEmail-BFCAFz6T.js} +25 -11
  128. package/dist/demo/VerifyEmail-BFCAFz6T.js.map +1 -0
  129. package/dist/demo/{auth-Djd7SKiw.js → auth-D9qTZzCa.js} +18 -35
  130. package/dist/demo/{auth-Djd7SKiw.js.map → auth-D9qTZzCa.js.map} +1 -1
  131. package/dist/demo/{core-B7LNjM78.js → core-DRtQklr3.js} +752 -647
  132. package/dist/demo/core-DRtQklr3.js.map +1 -0
  133. package/dist/demo/index.d.ts +1 -0
  134. package/dist/demo/index.d.ts.map +1 -1
  135. package/dist/demo/index.js +25 -22
  136. package/dist/demo/index.js.map +1 -1
  137. package/dist/demo/rolldown-runtime-CiIaOW0V.js +13 -0
  138. package/package.json +19 -19
  139. package/src/admin/AdminRouter.tsx +42 -2
  140. package/src/admin/atoms/adminUserAtom.ts +7 -0
  141. package/src/admin/components/AdminLayout.tsx +2 -14
  142. package/src/admin/components/jobs/AdminJobDashboard.tsx +51 -20
  143. package/src/admin/components/notifications/AdminNotifications.tsx +519 -0
  144. package/src/admin/components/parameters/ParameterDetails.tsx +12 -270
  145. package/src/admin/components/parameters/ParameterDetailsConfigForm.tsx +238 -0
  146. package/src/admin/components/parameters/ParameterDetailsLoading.tsx +24 -0
  147. package/src/admin/components/parameters/ParameterHistory.tsx +10 -11
  148. package/src/admin/components/parameters/ParameterTree.tsx +28 -184
  149. package/src/admin/components/parameters/ParameterTreeNode.tsx +151 -0
  150. package/src/admin/components/shared/AdminResourceHeader.tsx +2 -25
  151. package/src/admin/components/shared/AdminResourceHeaderMenuItem.tsx +37 -0
  152. package/src/admin/components/shared/AdminResourceTabs.tsx +2 -26
  153. package/src/admin/components/shared/AdminResourceTabsItem.tsx +36 -0
  154. package/src/admin/components/users/AdminUserLayout.tsx +84 -127
  155. package/src/admin/components/users/AdminUserProfile.tsx +5 -2
  156. package/src/admin/components/users/AdminUsers.tsx +1 -1
  157. package/src/auth/components/Login.tsx +188 -121
  158. package/src/auth/components/Profile.tsx +1 -22
  159. package/src/auth/components/ProfileField.tsx +39 -0
  160. package/src/auth/components/Register.tsx +215 -158
  161. package/src/auth/components/ResetPassword.tsx +7 -11
  162. package/src/auth/components/VerifyEmail.tsx +35 -10
  163. package/src/auth/components/buttons/UserButton.tsx +19 -21
  164. package/src/auth/index.ts +1 -0
  165. package/src/core/components/Flex.tsx +34 -0
  166. package/src/core/components/buttons/ActionButton.tsx +105 -78
  167. package/src/core/components/data/DetailDrawer.tsx +102 -96
  168. package/src/core/components/data/DetailList.tsx +2 -1
  169. package/src/core/components/dialogs/PromptDialog.tsx +1 -1
  170. package/src/core/components/layout/Breadcrumb.tsx +4 -7
  171. package/src/core/components/layout/DashboardShell.tsx +18 -4
  172. package/src/core/components/layout/Sidebar.tsx +16 -241
  173. package/src/core/components/layout/SidebarCollapsedItem.tsx +91 -0
  174. package/src/core/components/layout/SidebarItem.tsx +146 -0
  175. package/src/core/components/layout/index.ts +3 -1
  176. package/src/core/form/components/Control.tsx +31 -29
  177. package/src/core/form/components/ControlArray.tsx +13 -39
  178. package/src/core/form/components/ControlDate.tsx +10 -21
  179. package/src/core/form/components/ControlNumber.tsx +4 -33
  180. package/src/core/form/components/ControlQueryBuilder.tsx +12 -175
  181. package/src/core/form/components/ControlQueryBuilderHelp.tsx +165 -0
  182. package/src/core/form/components/ControlSelect.browser.spec.tsx +343 -0
  183. package/src/core/form/components/ControlSelect.tsx +294 -92
  184. package/src/core/form/components/TypeForm.browser.spec.tsx +3 -3
  185. package/src/core/form/components/TypeForm.tsx +5 -2
  186. package/src/core/form/index.ts +8 -1
  187. package/src/core/form/utils/parseInput.ts +7 -3
  188. package/src/core/index.ts +3 -1
  189. package/src/core/json/components/JsonViewer.tsx +103 -319
  190. package/src/core/json/components/JsonViewerCopyButton.tsx +46 -0
  191. package/src/core/json/components/JsonViewerRowNode.tsx +120 -0
  192. package/src/core/json/components/JsonViewerShared.ts +76 -0
  193. package/src/core/services/DialogService.tsx +2 -2
  194. package/src/core/styles.css +13 -2
  195. package/src/core/table/components/ColumnPicker.tsx +3 -3
  196. package/src/core/table/components/DataTable.tsx +88 -29
  197. package/src/core/table/components/DataTableFilters.tsx +6 -11
  198. package/src/core/table/components/DataTablePagination.tsx +9 -3
  199. package/src/core/table/components/DataTableToolbar.tsx +7 -3
  200. package/src/core/table/components/FilterPicker.tsx +3 -3
  201. package/src/core/table/interfaces/types.ts +29 -0
  202. package/src/core/utils/icons.tsx +2 -2
  203. package/src/demo/DemoRouter.ts +8 -1
  204. package/src/demo/components/DemoLayout.tsx +12 -2
  205. package/src/demo/components/auth/DemoLogin.tsx +35 -28
  206. package/src/demo/components/auth/DemoRegister.tsx +35 -49
  207. package/src/demo/components/auth/DemoResetPassword.tsx +5 -9
  208. package/src/demo/components/auth/DemoVerifyEmail.tsx +7 -6
  209. package/src/demo/components/core/DemoButton.tsx +123 -103
  210. package/src/demo/components/core/DemoControlSelect.tsx +325 -0
  211. package/src/demo/components/core/DemoDataTable.tsx +255 -237
  212. package/src/demo/components/core/DemoTypeForm.tsx +7 -2
  213. package/src/demo/components/shared/MacWindow.tsx +5 -11
  214. package/src/demo/components/shared/Showcase.tsx +28 -42
  215. package/dist/admin/AdminJobDashboard-KIOkeMgE.js.map +0 -1
  216. package/dist/admin/AdminLayout-B1DXZHDn.js.map +0 -1
  217. package/dist/admin/AdminParameters-BspPeqp_.js.map +0 -1
  218. package/dist/admin/AdminUserLayout-DUbC6-BI.js.map +0 -1
  219. package/dist/admin/AdminUserProfile-DuTUnjdG.js.map +0 -1
  220. package/dist/admin/AdminUsers-CR9z0g_5.js.map +0 -1
  221. package/dist/admin/Login-DHbYJKwg.js +0 -219
  222. package/dist/admin/Login-DHbYJKwg.js.map +0 -1
  223. package/dist/admin/Profile-B2EcIDB9.js.map +0 -1
  224. package/dist/admin/Register-Z3fxRbUF.js.map +0 -1
  225. package/dist/admin/ResetPassword-_Y1qTTKh.js.map +0 -1
  226. package/dist/admin/VerifyEmail-Bg22bwcC.js.map +0 -1
  227. package/dist/admin/core-BVO_TQxb.js.map +0 -1
  228. package/dist/admin/rolldown-runtime-CjeV3_4I.js +0 -18
  229. package/dist/auth/Login-C7jIqf00.js +0 -219
  230. package/dist/auth/Login-C7jIqf00.js.map +0 -1
  231. package/dist/auth/Profile-BMpXJ0oi.js.map +0 -1
  232. package/dist/auth/Register-2gx8qll-.js.map +0 -1
  233. package/dist/auth/ResetPassword-DBxt9hKk.js.map +0 -1
  234. package/dist/auth/VerifyEmail-Z80Ubajk.js.map +0 -1
  235. package/dist/auth/core-DyfeVr5c.js.map +0 -1
  236. package/dist/auth/rolldown-runtime-CjeV3_4I.js +0 -18
  237. package/dist/demo/DemoButton-CGUyR9eM.js +0 -178
  238. package/dist/demo/DemoButton-CGUyR9eM.js.map +0 -1
  239. package/dist/demo/DemoDataTable-QFG-xXSx.js +0 -358
  240. package/dist/demo/DemoDataTable-QFG-xXSx.js.map +0 -1
  241. package/dist/demo/DemoLayout-Cy6xjn6P.js.map +0 -1
  242. package/dist/demo/DemoLogin-vqxgTu4P.js.map +0 -1
  243. package/dist/demo/DemoRegister-YHPvPg77.js.map +0 -1
  244. package/dist/demo/DemoResetPassword-mOW18Zlm.js.map +0 -1
  245. package/dist/demo/DemoTypeForm-C1dNkahD.js.map +0 -1
  246. package/dist/demo/DemoVerifyEmail-D9EcXZ38.js +0 -30
  247. package/dist/demo/DemoVerifyEmail-D9EcXZ38.js.map +0 -1
  248. package/dist/demo/Login-CoYf_P_F.js +0 -219
  249. package/dist/demo/Login-CoYf_P_F.js.map +0 -1
  250. package/dist/demo/Profile-BE_Y3co2.js.map +0 -1
  251. package/dist/demo/Register-fXHmBpr3.js.map +0 -1
  252. package/dist/demo/ResetPassword-CAPj8MO3.js.map +0 -1
  253. package/dist/demo/Showcase-BtEU0pY9.js.map +0 -1
  254. package/dist/demo/VerifyEmail-DFmdCdYs.js.map +0 -1
  255. package/dist/demo/core-B7LNjM78.js.map +0 -1
  256. package/dist/demo/rolldown-runtime-CjeV3_4I.js +0 -18
  257. package/src/demo/styles.css +0 -0
@@ -1,13 +1,8 @@
1
- import { ActionButton, Flex, Text, TypeForm } from "@alepha/ui";
2
- import { Card, Code, Loader } from "@mantine/core";
3
- import { IconClock } from "@tabler/icons-react";
4
- import { jsonSchemaToTypeBox, type TObject, t } from "alepha";
5
- import { useForm } from "alepha/react/form";
6
- import { useI18n } from "alepha/react/i18n";
7
- import { useMemo } from "react";
8
- import { formatJson, type ParameterValue } from "./types.ts";
1
+ import ParameterDetailsConfigForm from "./ParameterDetailsConfigForm.tsx";
2
+ import ParameterDetailsLoading from "./ParameterDetailsLoading.tsx";
3
+ import type { ParameterValue } from "./types.ts";
9
4
 
10
- export interface ParameterDetailsProps {
5
+ interface Props {
11
6
  selectedConfig: string | null;
12
7
  configValue: ParameterValue | null;
13
8
  loading: boolean;
@@ -15,277 +10,24 @@ export interface ParameterDetailsProps {
15
10
  onSave: (values: Record<string, unknown>) => Promise<void>;
16
11
  }
17
12
 
18
- /**
19
- * Loading state.
20
- */
21
- const LoadingState = () => (
22
- <Flex
23
- flex={1}
24
- h="100%"
25
- p="md"
26
- style={{
27
- overflow: "hidden",
28
- minWidth: 0,
29
- display: "flex",
30
- }}
31
- >
32
- <Flex flex={1} justify="center" align="center" h="100%">
33
- <Loader size="sm" />
34
- </Flex>
35
- </Flex>
36
- );
37
-
38
- interface ConfigFormProps {
39
- selectedConfig: string;
40
- configValue: ParameterValue | null;
41
- saving: boolean;
42
- onSave: (values: Record<string, unknown>) => Promise<void>;
43
- }
44
-
45
- /**
46
- * The actual form component - only rendered when a config is selected.
47
- */
48
- const ConfigForm = ({
49
- selectedConfig,
50
- configValue,
51
- saving,
52
- onSave,
53
- }: ConfigFormProps) => {
54
- const { l } = useI18n();
55
-
56
- // Get the current value to display (from saved version or default)
57
- const currentContent = useMemo(() => {
58
- if (configValue?.current?.content) {
59
- return configValue.current.content;
60
- }
61
- if (configValue?.currentValue !== undefined) {
62
- return configValue.currentValue;
63
- }
64
- return null;
65
- }, [configValue]);
66
-
67
- // Convert JSON Schema from API to TypeBox schema
68
- const schemaForForm = useMemo(() => {
69
- if (!configValue?.schema) {
70
- return t.object({});
71
- }
72
- try {
73
- return jsonSchemaToTypeBox(configValue.schema) as TObject;
74
- } catch {
75
- return t.object({});
76
- }
77
- }, [configValue?.schema]);
78
-
79
- const form = useForm(
80
- {
81
- schema: schemaForForm,
82
- initialValues: (currentContent ?? {}) as Record<string, unknown>,
83
- handler: async (values) => {
84
- await onSave(values as Record<string, unknown>);
85
- },
86
- },
87
- [selectedConfig, schemaForForm, currentContent],
88
- );
89
-
90
- // Check if we have a valid schema with properties
91
- const hasValidSchema = useMemo(() => {
92
- const schema = configValue?.schema;
93
- return (
94
- schema &&
95
- typeof schema === "object" &&
96
- "properties" in schema &&
97
- Object.keys(schema.properties as object).length > 0
98
- );
99
- }, [configValue?.schema]);
100
-
101
- // Count the number of fields to determine column layout
102
- const fieldCount = useMemo(() => {
103
- const schema = configValue?.schema;
104
- if (
105
- schema &&
106
- typeof schema === "object" &&
107
- "properties" in schema &&
108
- schema.properties
109
- ) {
110
- return Object.keys(schema.properties as object).length;
111
- }
112
- return 0;
113
- }, [configValue?.schema]);
114
-
115
- // Determine optimal column count based on field count
116
- const columns = useMemo(() => {
117
- if (fieldCount <= 2) return 1;
118
- if (fieldCount <= 6) return 2;
119
- return 3;
120
- }, [fieldCount]);
121
-
122
- return (
123
- <Flex
124
- flex={1}
125
- h="100%"
126
- style={{
127
- overflow: "hidden",
128
- minWidth: 0,
129
- display: "flex",
130
- }}
131
- >
132
- <Flex direction="column" h="100%" w="100%" style={{ minHeight: 0 }}>
133
- {/* Content */}
134
- <Flex
135
- flex={1}
136
- p="md"
137
- className="overflow-auto"
138
- style={{ minHeight: 0 }}
139
- >
140
- {currentContent !== null ? (
141
- <Flex direction="column" gap="lg">
142
- {/* Form or JSON view */}
143
- <Flex>
144
- {hasValidSchema ? (
145
- <TypeForm
146
- form={form}
147
- columns={columns}
148
- skipSubmitButton
149
- fill={false}
150
- />
151
- ) : (
152
- <Flex>
153
- <Text size="xs" c="dimmed" mb={4}>
154
- Current Value
155
- </Text>
156
- <Code block style={{ whiteSpace: "pre-wrap" }}>
157
- {formatJson(currentContent)}
158
- </Code>
159
- </Flex>
160
- )}
161
- </Flex>
162
-
163
- {/* Metadata */}
164
- {configValue?.current?.changeDescription && (
165
- <Flex>
166
- <Text size="xs" c="dimmed" mb={4}>
167
- Change Description
168
- </Text>
169
- <Text size="sm">{configValue.current.changeDescription}</Text>
170
- </Flex>
171
- )}
172
-
173
- {configValue?.current && (
174
- <Flex gap="xl">
175
- <Flex>
176
- <Text size="xs" c="dimmed" mb={2}>
177
- Updated
178
- </Text>
179
- <Text size="sm">
180
- {l(configValue.current.updatedAt, { date: "fromNow" })}
181
- </Text>
182
- </Flex>
183
- {configValue.current.creatorName && (
184
- <Flex>
185
- <Text size="xs" c="dimmed" mb={2}>
186
- Updated By
187
- </Text>
188
- <Text size="sm">{configValue.current.creatorName}</Text>
189
- </Flex>
190
- )}
191
- </Flex>
192
- )}
193
-
194
- {!configValue?.current &&
195
- configValue?.currentValue !== undefined && (
196
- <Text size="xs" c="dimmed">
197
- This configuration is using its default value. No versions
198
- have been saved to the database yet.
199
- </Text>
200
- )}
201
-
202
- {/* Scheduled update preview */}
203
- {configValue?.next && (
204
- <Card withBorder p="sm" bg="var(--mantine-color-blue-light)">
205
- <Flex direction="column" gap="xs">
206
- <Flex gap="xs">
207
- <IconClock
208
- size={14}
209
- color="var(--mantine-color-blue-6)"
210
- />
211
- <Text size="xs" fw={500} c="blue">
212
- Scheduled Update (v{configValue.next.version})
213
- </Text>
214
- </Flex>
215
- <Text size="xs" c="dimmed">
216
- Activates{" "}
217
- {l(configValue.next.activationDate, {
218
- date: "fromNow",
219
- })}
220
- </Text>
221
- <Code block style={{ whiteSpace: "pre-wrap" }} fz="xs">
222
- {formatJson(configValue.next.content)}
223
- </Code>
224
- </Flex>
225
- </Card>
226
- )}
227
- </Flex>
228
- ) : (
229
- <Flex justify="center" align="center" h={200}>
230
- <Text c="dimmed" size="sm">
231
- No current value
232
- </Text>
233
- </Flex>
234
- )}
235
- </Flex>
236
-
237
- {/* Footer with actions */}
238
- {hasValidSchema && currentContent !== null && (
239
- <Flex
240
- p="md"
241
- style={{
242
- flexShrink: 0,
243
- borderTop: "1px solid var(--mantine-color-default-border)",
244
- }}
245
- >
246
- <Flex justify="flex-end" gap="sm">
247
- <ActionButton
248
- variant="subtle"
249
- onClick={() => form.reset({} as any)}
250
- disabled={saving}
251
- >
252
- Reset
253
- </ActionButton>
254
- <ActionButton intent="primary" form={form} loading={saving}>
255
- Save Changes
256
- </ActionButton>
257
- </Flex>
258
- </Flex>
259
- )}
260
- </Flex>
261
- </Flex>
262
- );
263
- };
264
-
265
13
  /**
266
14
  * Parameter details panel.
267
15
  * Shows loading state or the config form.
268
16
  * Note: Empty state is handled by parent (AdminParameters).
269
17
  */
270
- const ParameterDetails = ({
271
- selectedConfig,
272
- configValue,
273
- loading,
274
- saving,
275
- onSave,
276
- }: ParameterDetailsProps) => {
18
+ const ParameterDetails = (props: Props) => {
277
19
  // Loading state
278
- if (loading) {
279
- return <LoadingState />;
20
+ if (props.loading) {
21
+ return <ParameterDetailsLoading />;
280
22
  }
281
23
 
282
24
  // Config form (selectedConfig is guaranteed to be non-null by parent)
283
25
  return (
284
- <ConfigForm
285
- selectedConfig={selectedConfig!}
286
- configValue={configValue}
287
- saving={saving}
288
- onSave={onSave}
26
+ <ParameterDetailsConfigForm
27
+ selectedConfig={props.selectedConfig!}
28
+ configValue={props.configValue}
29
+ saving={props.saving}
30
+ onSave={props.onSave}
289
31
  />
290
32
  );
291
33
  };
@@ -0,0 +1,238 @@
1
+ import { ActionButton, Flex, Text, TypeForm } from "@alepha/ui";
2
+ import { Card, Code } from "@mantine/core";
3
+ import { IconClock } from "@tabler/icons-react";
4
+ import { jsonSchemaToTypeBox, type TObject, t } from "alepha";
5
+ import { useForm } from "alepha/react/form";
6
+ import { useI18n } from "alepha/react/i18n";
7
+ import { useMemo } from "react";
8
+ import { formatJson, type ParameterValue } from "./types.ts";
9
+
10
+ interface Props {
11
+ selectedConfig: string;
12
+ configValue: ParameterValue | null;
13
+ saving: boolean;
14
+ onSave: (values: Record<string, unknown>) => Promise<void>;
15
+ }
16
+
17
+ /**
18
+ * The actual form component - only rendered when a config is selected.
19
+ */
20
+ const ParameterDetailsConfigForm = (props: Props) => {
21
+ const { l } = useI18n();
22
+
23
+ // Get the current value to display (from saved version or default)
24
+ const currentContent = useMemo(() => {
25
+ if (props.configValue?.current?.content) {
26
+ return props.configValue.current.content;
27
+ }
28
+ if (props.configValue?.currentValue !== undefined) {
29
+ return props.configValue.currentValue;
30
+ }
31
+ return null;
32
+ }, [props.configValue]);
33
+
34
+ // Convert JSON Schema from API to TypeBox schema
35
+ const schemaForForm = useMemo(() => {
36
+ if (!props.configValue?.schema) {
37
+ return t.object({});
38
+ }
39
+ try {
40
+ return jsonSchemaToTypeBox(props.configValue.schema) as TObject;
41
+ } catch {
42
+ return t.object({});
43
+ }
44
+ }, [props.configValue?.schema]);
45
+
46
+ const form = useForm(
47
+ {
48
+ schema: schemaForForm,
49
+ initialValues: (currentContent ?? {}) as Record<string, unknown>,
50
+ handler: async (values) => {
51
+ await props.onSave(values as Record<string, unknown>);
52
+ },
53
+ },
54
+ [props.selectedConfig, schemaForForm, currentContent],
55
+ );
56
+
57
+ // Check if we have a valid schema with properties
58
+ const hasValidSchema = useMemo(() => {
59
+ const schema = props.configValue?.schema;
60
+ return (
61
+ schema &&
62
+ typeof schema === "object" &&
63
+ "properties" in schema &&
64
+ Object.keys(schema.properties as object).length > 0
65
+ );
66
+ }, [props.configValue?.schema]);
67
+
68
+ // Count the number of fields to determine column layout
69
+ const fieldCount = useMemo(() => {
70
+ const schema = props.configValue?.schema;
71
+ if (
72
+ schema &&
73
+ typeof schema === "object" &&
74
+ "properties" in schema &&
75
+ schema.properties
76
+ ) {
77
+ return Object.keys(schema.properties as object).length;
78
+ }
79
+ return 0;
80
+ }, [props.configValue?.schema]);
81
+
82
+ // Determine optimal column count based on field count
83
+ const columns = useMemo(() => {
84
+ if (fieldCount <= 2) return 1;
85
+ if (fieldCount <= 6) return 2;
86
+ return 3;
87
+ }, [fieldCount]);
88
+
89
+ return (
90
+ <Flex
91
+ flex={1}
92
+ h="100%"
93
+ style={{
94
+ overflow: "hidden",
95
+ minWidth: 0,
96
+ display: "flex",
97
+ }}
98
+ >
99
+ <Flex direction="column" h="100%" w="100%" style={{ minHeight: 0 }}>
100
+ {/* Content */}
101
+ <Flex
102
+ flex={1}
103
+ p="md"
104
+ className="overflow-auto"
105
+ style={{ minHeight: 0 }}
106
+ >
107
+ {currentContent !== null ? (
108
+ <Flex direction="column" gap="lg">
109
+ {/* Form or JSON view */}
110
+ <Flex>
111
+ {hasValidSchema ? (
112
+ <TypeForm
113
+ form={form}
114
+ columns={columns}
115
+ skipSubmitButton
116
+ fill={false}
117
+ />
118
+ ) : (
119
+ <Flex>
120
+ <Text size="xs" c="dimmed" mb={4}>
121
+ Current Value
122
+ </Text>
123
+ <Code block style={{ whiteSpace: "pre-wrap" }}>
124
+ {formatJson(currentContent)}
125
+ </Code>
126
+ </Flex>
127
+ )}
128
+ </Flex>
129
+
130
+ {/* Metadata */}
131
+ {props.configValue?.current?.changeDescription && (
132
+ <Flex>
133
+ <Text size="xs" c="dimmed" mb={4}>
134
+ Change Description
135
+ </Text>
136
+ <Text size="sm">
137
+ {props.configValue.current.changeDescription}
138
+ </Text>
139
+ </Flex>
140
+ )}
141
+
142
+ {props.configValue?.current && (
143
+ <Flex gap="xl">
144
+ <Flex>
145
+ <Text size="xs" c="dimmed" mb={2}>
146
+ Updated
147
+ </Text>
148
+ <Text size="sm">
149
+ {l(props.configValue.current.updatedAt, {
150
+ date: "fromNow",
151
+ })}
152
+ </Text>
153
+ </Flex>
154
+ {props.configValue.current.creatorName && (
155
+ <Flex>
156
+ <Text size="xs" c="dimmed" mb={2}>
157
+ Updated By
158
+ </Text>
159
+ <Text size="sm">
160
+ {props.configValue.current.creatorName}
161
+ </Text>
162
+ </Flex>
163
+ )}
164
+ </Flex>
165
+ )}
166
+
167
+ {!props.configValue?.current &&
168
+ props.configValue?.currentValue !== undefined && (
169
+ <Text size="xs" c="dimmed">
170
+ This configuration is using its default value. No versions
171
+ have been saved to the database yet.
172
+ </Text>
173
+ )}
174
+
175
+ {/* Scheduled update preview */}
176
+ {props.configValue?.next && (
177
+ <Card withBorder p="sm" bg="var(--mantine-color-blue-light)">
178
+ <Flex direction="column" gap="xs">
179
+ <Flex gap="xs">
180
+ <IconClock
181
+ size={14}
182
+ color="var(--mantine-color-blue-6)"
183
+ />
184
+ <Text size="xs" fw={500} c="blue">
185
+ Scheduled Update (v{props.configValue.next.version})
186
+ </Text>
187
+ </Flex>
188
+ <Text size="xs" c="dimmed">
189
+ Activates{" "}
190
+ {l(props.configValue.next.activationDate, {
191
+ date: "fromNow",
192
+ })}
193
+ </Text>
194
+ <Code block style={{ whiteSpace: "pre-wrap" }} fz="xs">
195
+ {formatJson(props.configValue.next.content)}
196
+ </Code>
197
+ </Flex>
198
+ </Card>
199
+ )}
200
+ </Flex>
201
+ ) : (
202
+ <Flex justify="center" align="center" h={200}>
203
+ <Text c="dimmed" size="sm">
204
+ No current value
205
+ </Text>
206
+ </Flex>
207
+ )}
208
+ </Flex>
209
+
210
+ {/* Footer with actions */}
211
+ {hasValidSchema && currentContent !== null && (
212
+ <Flex
213
+ p="md"
214
+ style={{
215
+ flexShrink: 0,
216
+ borderTop: "1px solid var(--mantine-color-default-border)",
217
+ }}
218
+ >
219
+ <Flex justify="flex-end" gap="sm">
220
+ <ActionButton
221
+ variant="subtle"
222
+ onClick={() => form.reset({} as any)}
223
+ disabled={props.saving}
224
+ >
225
+ Reset
226
+ </ActionButton>
227
+ <ActionButton intent="primary" form={form} loading={props.saving}>
228
+ Save Changes
229
+ </ActionButton>
230
+ </Flex>
231
+ </Flex>
232
+ )}
233
+ </Flex>
234
+ </Flex>
235
+ );
236
+ };
237
+
238
+ export default ParameterDetailsConfigForm;
@@ -0,0 +1,24 @@
1
+ import { Flex } from "@alepha/ui";
2
+ import { Loader } from "@mantine/core";
3
+
4
+ /**
5
+ * Loading state for the parameter details panel.
6
+ */
7
+ const ParameterDetailsLoading = () => (
8
+ <Flex
9
+ flex={1}
10
+ h="100%"
11
+ p="md"
12
+ style={{
13
+ overflow: "hidden",
14
+ minWidth: 0,
15
+ display: "flex",
16
+ }}
17
+ >
18
+ <Flex flex={1} justify="center" align="center" h="100%">
19
+ <Loader size="sm" />
20
+ </Flex>
21
+ </Flex>
22
+ );
23
+
24
+ export default ParameterDetailsLoading;
@@ -5,22 +5,21 @@ import type { ParameterResponse } from "alepha/api/parameters";
5
5
  import { useI18n } from "alepha/react/i18n";
6
6
  import { getStatusColor } from "./types.ts";
7
7
 
8
- export interface ParameterHistoryProps {
8
+ interface Props {
9
9
  selectedConfig: string | null;
10
10
  history: ParameterResponse[];
11
11
  loading: boolean;
12
12
  onRollback: (version: number) => void;
13
13
  }
14
14
 
15
- const ParameterHistory = ({
16
- history,
17
- loading,
18
- onRollback,
19
- }: ParameterHistoryProps) => {
15
+ /**
16
+ * Parameter version history timeline panel.
17
+ */
18
+ const ParameterHistory = (props: Props) => {
20
19
  const { l } = useI18n();
21
20
 
22
21
  const renderContent = () => {
23
- if (loading) {
22
+ if (props.loading) {
24
23
  return (
25
24
  <Flex flex={1} justify="center" align="center">
26
25
  <Loader size="sm" />
@@ -28,7 +27,7 @@ const ParameterHistory = ({
28
27
  );
29
28
  }
30
29
 
31
- if (history.length === 0) {
30
+ if (props.history.length === 0) {
32
31
  return (
33
32
  <Flex flex={1} justify="center" align="center">
34
33
  <Text c="dimmed" size="xs">
@@ -41,11 +40,11 @@ const ParameterHistory = ({
41
40
  return (
42
41
  <ScrollArea flex={1} offsetScrollbars>
43
42
  <Timeline
44
- active={history.findIndex((h) => h.status === "current")}
43
+ active={props.history.findIndex((h) => h.status === "current")}
45
44
  bulletSize={24}
46
45
  lineWidth={2}
47
46
  >
48
- {history.map((version) => (
47
+ {props.history.map((version) => (
49
48
  <Timeline.Item
50
49
  key={version.id}
51
50
  bullet={
@@ -91,7 +90,7 @@ const ParameterHistory = ({
91
90
  <ActionButton
92
91
  size="compact-xs"
93
92
  variant="subtle"
94
- onClick={() => onRollback(version.version)}
93
+ onClick={() => props.onRollback(version.version)}
95
94
  >
96
95
  Rollback to this version
97
96
  </ActionButton>