@svadmin/ui 0.29.3 → 0.29.4

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 (444) hide show
  1. package/dist/README.md +18 -0
  2. package/dist/actions.d.ts +35 -0
  3. package/dist/actions.js +84 -0
  4. package/dist/app.css +673 -0
  5. package/dist/component-registry.svelte.d.ts +36 -0
  6. package/dist/component-registry.svelte.js +20 -0
  7. package/dist/components/AICommandBar.svelte +180 -0
  8. package/dist/components/AICommandBar.svelte.d.ts +6 -0
  9. package/dist/components/AboutSettings.svelte +106 -0
  10. package/dist/components/AboutSettings.svelte.d.ts +18 -0
  11. package/dist/components/AdminApp.svelte +199 -0
  12. package/dist/components/AdminApp.svelte.d.ts +26 -0
  13. package/dist/components/AnimatedCounter.svelte +46 -0
  14. package/dist/components/AnimatedCounter.svelte.d.ts +11 -0
  15. package/dist/components/AnomalyBadge.svelte +65 -0
  16. package/dist/components/AnomalyBadge.svelte.d.ts +16 -0
  17. package/dist/components/AppearanceSettings.svelte +183 -0
  18. package/dist/components/AppearanceSettings.svelte.d.ts +3 -0
  19. package/dist/components/AuditLogDrawer.svelte +93 -0
  20. package/dist/components/AuditLogDrawer.svelte.d.ts +8 -0
  21. package/dist/components/AuditLogViewer.svelte +226 -0
  22. package/dist/components/AuditLogViewer.svelte.d.ts +3 -0
  23. package/dist/components/Authenticated.svelte +51 -0
  24. package/dist/components/Authenticated.svelte.d.ts +11 -0
  25. package/dist/components/AutoForm.svelte +242 -0
  26. package/dist/components/AutoForm.svelte.d.ts +20 -0
  27. package/dist/components/AutoSaveIndicator.svelte +35 -0
  28. package/dist/components/AutoSaveIndicator.svelte.d.ts +9 -0
  29. package/dist/components/AutoTable.svelte +839 -0
  30. package/dist/components/AutoTable.svelte.d.ts +44 -0
  31. package/dist/components/Breadcrumbs.svelte +58 -0
  32. package/dist/components/Breadcrumbs.svelte.d.ts +3 -0
  33. package/dist/components/CanAccess.svelte +23 -0
  34. package/dist/components/CanAccess.svelte.d.ts +12 -0
  35. package/dist/components/CatchAllNavigate.svelte +21 -0
  36. package/dist/components/CatchAllNavigate.svelte.d.ts +3 -0
  37. package/dist/components/ChatDialog.svelte +535 -0
  38. package/dist/components/ChatDialog.svelte.d.ts +14 -0
  39. package/dist/components/ComboboxField.svelte +129 -0
  40. package/dist/components/ComboboxField.svelte.d.ts +17 -0
  41. package/dist/components/CommandPalette.svelte +135 -0
  42. package/dist/components/CommandPalette.svelte.d.ts +8 -0
  43. package/dist/components/ConfigErrorScreen.svelte +126 -0
  44. package/dist/components/ConfigErrorScreen.svelte.d.ts +11 -0
  45. package/dist/components/ConfirmDialog.svelte +53 -0
  46. package/dist/components/ConfirmDialog.svelte.d.ts +13 -0
  47. package/dist/components/CopilotPanel.svelte +163 -0
  48. package/dist/components/CopilotPanel.svelte.d.ts +6 -0
  49. package/dist/components/CreatePage.svelte +39 -0
  50. package/dist/components/CreatePage.svelte.d.ts +10 -0
  51. package/dist/components/DevTools.svelte +149 -0
  52. package/dist/components/DevTools.svelte.d.ts +3 -0
  53. package/dist/components/DraggableGrid.svelte +86 -0
  54. package/dist/components/DraggableGrid.svelte.d.ts +17 -0
  55. package/dist/components/DraggableHeader.svelte +112 -0
  56. package/dist/components/DraggableHeader.svelte.d.ts +25 -0
  57. package/dist/components/DrawerForm.svelte +35 -0
  58. package/dist/components/DrawerForm.svelte.d.ts +11 -0
  59. package/dist/components/EditPage.svelte +52 -0
  60. package/dist/components/EditPage.svelte.d.ts +12 -0
  61. package/dist/components/EmptyState.svelte +31 -0
  62. package/dist/components/EmptyState.svelte.d.ts +8 -0
  63. package/dist/components/ErrorBoundary.svelte +49 -0
  64. package/dist/components/ErrorBoundary.svelte.d.ts +12 -0
  65. package/dist/components/ErrorComponent.svelte +36 -0
  66. package/dist/components/ErrorComponent.svelte.d.ts +9 -0
  67. package/dist/components/FieldRenderer.svelte +357 -0
  68. package/dist/components/FieldRenderer.svelte.d.ts +13 -0
  69. package/dist/components/ForgotPasswordPage.svelte +112 -0
  70. package/dist/components/ForgotPasswordPage.svelte.d.ts +6 -0
  71. package/dist/components/Header.svelte +94 -0
  72. package/dist/components/Header.svelte.d.ts +12 -0
  73. package/dist/components/InferencerPanel.svelte +192 -0
  74. package/dist/components/InferencerPanel.svelte.d.ts +3 -0
  75. package/dist/components/InfiniteList.svelte +93 -0
  76. package/dist/components/InfiniteList.svelte.d.ts +20 -0
  77. package/dist/components/InlineEdit.svelte +88 -0
  78. package/dist/components/InlineEdit.svelte.d.ts +12 -0
  79. package/dist/components/InsightCard.svelte +98 -0
  80. package/dist/components/InsightCard.svelte.d.ts +11 -0
  81. package/dist/components/KeyboardShortcuts.svelte +61 -0
  82. package/dist/components/KeyboardShortcuts.svelte.d.ts +6 -0
  83. package/dist/components/Layout.svelte +167 -0
  84. package/dist/components/Layout.svelte.d.ts +11 -0
  85. package/dist/components/ListPage.svelte +71 -0
  86. package/dist/components/ListPage.svelte.d.ts +32 -0
  87. package/dist/components/LiveIndicator.svelte +58 -0
  88. package/dist/components/LiveIndicator.svelte.d.ts +12 -0
  89. package/dist/components/LoginPage.svelte +163 -0
  90. package/dist/components/LoginPage.svelte.d.ts +28 -0
  91. package/dist/components/MarkdownRenderer.svelte +127 -0
  92. package/dist/components/MarkdownRenderer.svelte.d.ts +11 -0
  93. package/dist/components/ModalForm.svelte +38 -0
  94. package/dist/components/ModalForm.svelte.d.ts +10 -0
  95. package/dist/components/NavigateToResource.svelte +20 -0
  96. package/dist/components/NavigateToResource.svelte.d.ts +3 -0
  97. package/dist/components/PageHeader.svelte +39 -0
  98. package/dist/components/PageHeader.svelte.d.ts +11 -0
  99. package/dist/components/PageSkeleton.svelte +71 -0
  100. package/dist/components/PageSkeleton.svelte.d.ts +7 -0
  101. package/dist/components/PasswordInput.svelte +96 -0
  102. package/dist/components/PasswordInput.svelte.d.ts +12 -0
  103. package/dist/components/PermissionMatrix.svelte +185 -0
  104. package/dist/components/PermissionMatrix.svelte.d.ts +19 -0
  105. package/dist/components/ProfilePage.svelte +284 -0
  106. package/dist/components/ProfilePage.svelte.d.ts +3 -0
  107. package/dist/components/RegisterPage.svelte +112 -0
  108. package/dist/components/RegisterPage.svelte.d.ts +7 -0
  109. package/dist/components/RolesSettings.svelte +146 -0
  110. package/dist/components/RolesSettings.svelte.d.ts +3 -0
  111. package/dist/components/SettingsPage.svelte +113 -0
  112. package/dist/components/SettingsPage.svelte.d.ts +3 -0
  113. package/dist/components/ShowPage.svelte +73 -0
  114. package/dist/components/ShowPage.svelte.d.ts +7 -0
  115. package/dist/components/Sidebar.svelte +417 -0
  116. package/dist/components/Sidebar.svelte.d.ts +14 -0
  117. package/dist/components/SidebarItem.svelte +129 -0
  118. package/dist/components/SidebarItem.svelte.d.ts +11 -0
  119. package/dist/components/SmartSuggest.svelte +158 -0
  120. package/dist/components/SmartSuggest.svelte.d.ts +19 -0
  121. package/dist/components/StatsCard.svelte +79 -0
  122. package/dist/components/StatsCard.svelte.d.ts +23 -0
  123. package/dist/components/StepsForm.svelte +192 -0
  124. package/dist/components/StepsForm.svelte.d.ts +13 -0
  125. package/dist/components/TaskQueueDrawer.svelte +158 -0
  126. package/dist/components/TaskQueueDrawer.svelte.d.ts +11 -0
  127. package/dist/components/TenantSwitcher.svelte +84 -0
  128. package/dist/components/TenantSwitcher.svelte.d.ts +12 -0
  129. package/dist/components/ThemedTitle.svelte +32 -0
  130. package/dist/components/ThemedTitle.svelte.d.ts +9 -0
  131. package/dist/components/Toast.svelte +46 -0
  132. package/dist/components/Toast.svelte.d.ts +3 -0
  133. package/dist/components/TooltipButton.svelte +42 -0
  134. package/dist/components/TooltipButton.svelte.d.ts +14 -0
  135. package/dist/components/UndoableNotification.svelte +69 -0
  136. package/dist/components/UndoableNotification.svelte.d.ts +9 -0
  137. package/dist/components/UpdatePasswordPage.svelte +89 -0
  138. package/dist/components/UpdatePasswordPage.svelte.d.ts +6 -0
  139. package/dist/components/VirtualTable.svelte +76 -0
  140. package/dist/components/VirtualTable.svelte.d.ts +27 -0
  141. package/dist/components/VoiceInput.svelte +120 -0
  142. package/dist/components/VoiceInput.svelte.d.ts +15 -0
  143. package/dist/components/buttons/CloneButton.svelte +30 -0
  144. package/dist/components/buttons/CloneButton.svelte.d.ts +13 -0
  145. package/dist/components/buttons/CreateButton.svelte +29 -0
  146. package/dist/components/buttons/CreateButton.svelte.d.ts +12 -0
  147. package/dist/components/buttons/DeleteButton.svelte +59 -0
  148. package/dist/components/buttons/DeleteButton.svelte.d.ts +15 -0
  149. package/dist/components/buttons/EditButton.svelte +30 -0
  150. package/dist/components/buttons/EditButton.svelte.d.ts +13 -0
  151. package/dist/components/buttons/ExportButton.svelte +30 -0
  152. package/dist/components/buttons/ExportButton.svelte.d.ts +12 -0
  153. package/dist/components/buttons/ImportButton.svelte +56 -0
  154. package/dist/components/buttons/ImportButton.svelte.d.ts +19 -0
  155. package/dist/components/buttons/ListButton.svelte +23 -0
  156. package/dist/components/buttons/ListButton.svelte.d.ts +8 -0
  157. package/dist/components/buttons/RefreshButton.svelte +36 -0
  158. package/dist/components/buttons/RefreshButton.svelte.d.ts +8 -0
  159. package/dist/components/buttons/SaveButton.svelte +27 -0
  160. package/dist/components/buttons/SaveButton.svelte.d.ts +9 -0
  161. package/dist/components/buttons/ShowButton.svelte +31 -0
  162. package/dist/components/buttons/ShowButton.svelte.d.ts +13 -0
  163. package/dist/components/buttons/index.d.ts +10 -0
  164. package/dist/components/buttons/index.js +10 -0
  165. package/dist/components/charts/BarChart.svelte +69 -0
  166. package/dist/components/charts/BarChart.svelte.d.ts +15 -0
  167. package/dist/components/charts/LineChart.svelte +115 -0
  168. package/dist/components/charts/LineChart.svelte.d.ts +17 -0
  169. package/dist/components/charts/PieChart.svelte +95 -0
  170. package/dist/components/charts/PieChart.svelte.d.ts +15 -0
  171. package/dist/components/charts/index.d.ts +3 -0
  172. package/dist/components/charts/index.js +3 -0
  173. package/dist/components/fieldComponentMap.d.ts +24 -0
  174. package/dist/components/fieldComponentMap.js +65 -0
  175. package/dist/components/fields/ArrayField.svelte +86 -0
  176. package/dist/components/fields/ArrayField.svelte.d.ts +9 -0
  177. package/dist/components/fields/BooleanField.svelte +13 -0
  178. package/dist/components/fields/BooleanField.svelte.d.ts +8 -0
  179. package/dist/components/fields/DateField.svelte +6 -0
  180. package/dist/components/fields/DateField.svelte.d.ts +8 -0
  181. package/dist/components/fields/EmailField.svelte +9 -0
  182. package/dist/components/fields/EmailField.svelte.d.ts +6 -0
  183. package/dist/components/fields/FileField.svelte +14 -0
  184. package/dist/components/fields/FileField.svelte.d.ts +7 -0
  185. package/dist/components/fields/ImageField.svelte +9 -0
  186. package/dist/components/fields/ImageField.svelte.d.ts +9 -0
  187. package/dist/components/fields/JsonField.svelte +72 -0
  188. package/dist/components/fields/JsonField.svelte.d.ts +6 -0
  189. package/dist/components/fields/MarkdownField.svelte +9 -0
  190. package/dist/components/fields/MarkdownField.svelte.d.ts +6 -0
  191. package/dist/components/fields/MultiSelectField.svelte +21 -0
  192. package/dist/components/fields/MultiSelectField.svelte.d.ts +10 -0
  193. package/dist/components/fields/NumberField.svelte +6 -0
  194. package/dist/components/fields/NumberField.svelte.d.ts +8 -0
  195. package/dist/components/fields/RelationField.svelte +24 -0
  196. package/dist/components/fields/RelationField.svelte.d.ts +8 -0
  197. package/dist/components/fields/RichTextField.svelte +35 -0
  198. package/dist/components/fields/RichTextField.svelte.d.ts +7 -0
  199. package/dist/components/fields/SelectField.svelte +14 -0
  200. package/dist/components/fields/SelectField.svelte.d.ts +10 -0
  201. package/dist/components/fields/TagField.svelte +12 -0
  202. package/dist/components/fields/TagField.svelte.d.ts +6 -0
  203. package/dist/components/fields/TextField.svelte +11 -0
  204. package/dist/components/fields/TextField.svelte.d.ts +7 -0
  205. package/dist/components/fields/UrlField.svelte +14 -0
  206. package/dist/components/fields/UrlField.svelte.d.ts +7 -0
  207. package/dist/components/ui/alert/alert-description.svelte +17 -0
  208. package/dist/components/ui/alert/alert-description.svelte.d.ts +6 -0
  209. package/dist/components/ui/alert/alert-title.svelte +17 -0
  210. package/dist/components/ui/alert/alert-title.svelte.d.ts +6 -0
  211. package/dist/components/ui/alert/alert.svelte +44 -0
  212. package/dist/components/ui/alert/alert.svelte.d.ts +32 -0
  213. package/dist/components/ui/alert/index.d.ts +4 -0
  214. package/dist/components/ui/alert/index.js +5 -0
  215. package/dist/components/ui/alert-dialog/alert-dialog-content.svelte +29 -0
  216. package/dist/components/ui/alert-dialog/alert-dialog-content.svelte.d.ts +10 -0
  217. package/dist/components/ui/alert-dialog/alert-dialog-description.svelte +16 -0
  218. package/dist/components/ui/alert-dialog/alert-dialog-description.svelte.d.ts +7 -0
  219. package/dist/components/ui/alert-dialog/alert-dialog-footer.svelte +11 -0
  220. package/dist/components/ui/alert-dialog/alert-dialog-footer.svelte.d.ts +8 -0
  221. package/dist/components/ui/alert-dialog/alert-dialog-header.svelte +11 -0
  222. package/dist/components/ui/alert-dialog/alert-dialog-header.svelte.d.ts +8 -0
  223. package/dist/components/ui/alert-dialog/alert-dialog-overlay.svelte +16 -0
  224. package/dist/components/ui/alert-dialog/alert-dialog-overlay.svelte.d.ts +7 -0
  225. package/dist/components/ui/alert-dialog/alert-dialog-portal.svelte +6 -0
  226. package/dist/components/ui/alert-dialog/alert-dialog-portal.svelte.d.ts +3 -0
  227. package/dist/components/ui/alert-dialog/alert-dialog-title.svelte +16 -0
  228. package/dist/components/ui/alert-dialog/alert-dialog-title.svelte.d.ts +7 -0
  229. package/dist/components/ui/alert-dialog/index.d.ts +13 -0
  230. package/dist/components/ui/alert-dialog/index.js +13 -0
  231. package/dist/components/ui/avatar/avatar.svelte +63 -0
  232. package/dist/components/ui/avatar/avatar.svelte.d.ts +32 -0
  233. package/dist/components/ui/avatar/index.d.ts +2 -0
  234. package/dist/components/ui/avatar/index.js +2 -0
  235. package/dist/components/ui/badge/badge.svelte +49 -0
  236. package/dist/components/ui/badge/badge.svelte.d.ts +38 -0
  237. package/dist/components/ui/badge/index.d.ts +2 -0
  238. package/dist/components/ui/badge/index.js +3 -0
  239. package/dist/components/ui/breadcrumb/breadcrumb-ellipsis.svelte +18 -0
  240. package/dist/components/ui/breadcrumb/breadcrumb-ellipsis.svelte.d.ts +4 -0
  241. package/dist/components/ui/breadcrumb/breadcrumb-item.svelte +15 -0
  242. package/dist/components/ui/breadcrumb/breadcrumb-item.svelte.d.ts +8 -0
  243. package/dist/components/ui/breadcrumb/breadcrumb-link.svelte +15 -0
  244. package/dist/components/ui/breadcrumb/breadcrumb-link.svelte.d.ts +8 -0
  245. package/dist/components/ui/breadcrumb/breadcrumb-list.svelte +15 -0
  246. package/dist/components/ui/breadcrumb/breadcrumb-list.svelte.d.ts +8 -0
  247. package/dist/components/ui/breadcrumb/breadcrumb-page.svelte +18 -0
  248. package/dist/components/ui/breadcrumb/breadcrumb-page.svelte.d.ts +8 -0
  249. package/dist/components/ui/breadcrumb/breadcrumb-separator.svelte +22 -0
  250. package/dist/components/ui/breadcrumb/breadcrumb-separator.svelte.d.ts +8 -0
  251. package/dist/components/ui/breadcrumb/breadcrumb.svelte +11 -0
  252. package/dist/components/ui/breadcrumb/breadcrumb.svelte.d.ts +8 -0
  253. package/dist/components/ui/breadcrumb/index.d.ts +7 -0
  254. package/dist/components/ui/breadcrumb/index.js +7 -0
  255. package/dist/components/ui/button/button.svelte +90 -0
  256. package/dist/components/ui/button/button.svelte.d.ts +70 -0
  257. package/dist/components/ui/button/index.d.ts +2 -0
  258. package/dist/components/ui/button/index.js +5 -0
  259. package/dist/components/ui/card/card-action.svelte +23 -0
  260. package/dist/components/ui/card/card-action.svelte.d.ts +5 -0
  261. package/dist/components/ui/card/card-content.svelte +20 -0
  262. package/dist/components/ui/card/card-content.svelte.d.ts +5 -0
  263. package/dist/components/ui/card/card-description.svelte +20 -0
  264. package/dist/components/ui/card/card-description.svelte.d.ts +5 -0
  265. package/dist/components/ui/card/card-footer.svelte +20 -0
  266. package/dist/components/ui/card/card-footer.svelte.d.ts +5 -0
  267. package/dist/components/ui/card/card-header.svelte +23 -0
  268. package/dist/components/ui/card/card-header.svelte.d.ts +5 -0
  269. package/dist/components/ui/card/card-title.svelte +15 -0
  270. package/dist/components/ui/card/card-title.svelte.d.ts +5 -0
  271. package/dist/components/ui/card/card.svelte +22 -0
  272. package/dist/components/ui/card/card.svelte.d.ts +8 -0
  273. package/dist/components/ui/card/index.d.ts +8 -0
  274. package/dist/components/ui/card/index.js +10 -0
  275. package/dist/components/ui/checkbox/checkbox.svelte +39 -0
  276. package/dist/components/ui/checkbox/checkbox.svelte.d.ts +4 -0
  277. package/dist/components/ui/checkbox/index.d.ts +2 -0
  278. package/dist/components/ui/checkbox/index.js +4 -0
  279. package/dist/components/ui/collapsible/index.d.ts +5 -0
  280. package/dist/components/ui/collapsible/index.js +5 -0
  281. package/dist/components/ui/command/command-dialog.svelte +31 -0
  282. package/dist/components/ui/command/command-dialog.svelte.d.ts +10 -0
  283. package/dist/components/ui/command/index.d.ts +2 -0
  284. package/dist/components/ui/command/index.js +2 -0
  285. package/dist/components/ui/context-menu/index.d.ts +9 -0
  286. package/dist/components/ui/context-menu/index.js +9 -0
  287. package/dist/components/ui/dialog/dialog-close.svelte +11 -0
  288. package/dist/components/ui/dialog/dialog-close.svelte.d.ts +4 -0
  289. package/dist/components/ui/dialog/dialog-content.svelte +48 -0
  290. package/dist/components/ui/dialog/dialog-content.svelte.d.ts +13 -0
  291. package/dist/components/ui/dialog/dialog-description.svelte +17 -0
  292. package/dist/components/ui/dialog/dialog-description.svelte.d.ts +4 -0
  293. package/dist/components/ui/dialog/dialog-footer.svelte +32 -0
  294. package/dist/components/ui/dialog/dialog-footer.svelte.d.ts +8 -0
  295. package/dist/components/ui/dialog/dialog-header.svelte +20 -0
  296. package/dist/components/ui/dialog/dialog-header.svelte.d.ts +5 -0
  297. package/dist/components/ui/dialog/dialog-overlay.svelte +17 -0
  298. package/dist/components/ui/dialog/dialog-overlay.svelte.d.ts +4 -0
  299. package/dist/components/ui/dialog/dialog-portal.svelte +7 -0
  300. package/dist/components/ui/dialog/dialog-portal.svelte.d.ts +3 -0
  301. package/dist/components/ui/dialog/dialog-title.svelte +17 -0
  302. package/dist/components/ui/dialog/dialog-title.svelte.d.ts +4 -0
  303. package/dist/components/ui/dialog/dialog-trigger.svelte +11 -0
  304. package/dist/components/ui/dialog/dialog-trigger.svelte.d.ts +4 -0
  305. package/dist/components/ui/dialog/dialog.svelte +7 -0
  306. package/dist/components/ui/dialog/dialog.svelte.d.ts +3 -0
  307. package/dist/components/ui/dialog/index.d.ts +11 -0
  308. package/dist/components/ui/dialog/index.js +13 -0
  309. package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte +43 -0
  310. package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte.d.ts +9 -0
  311. package/dist/components/ui/dropdown-menu/dropdown-menu-content.svelte +35 -0
  312. package/dist/components/ui/dropdown-menu/dropdown-menu-content.svelte.d.ts +8 -0
  313. package/dist/components/ui/dropdown-menu/dropdown-menu-item.svelte +36 -0
  314. package/dist/components/ui/dropdown-menu/dropdown-menu-item.svelte.d.ts +9 -0
  315. package/dist/components/ui/dropdown-menu/dropdown-menu-separator.svelte +10 -0
  316. package/dist/components/ui/dropdown-menu/dropdown-menu-separator.svelte.d.ts +6 -0
  317. package/dist/components/ui/dropdown-menu/dropdown-menu-trigger.svelte +27 -0
  318. package/dist/components/ui/dropdown-menu/dropdown-menu-trigger.svelte.d.ts +11 -0
  319. package/dist/components/ui/dropdown-menu/dropdown-menu.svelte +45 -0
  320. package/dist/components/ui/dropdown-menu/dropdown-menu.svelte.d.ts +9 -0
  321. package/dist/components/ui/dropdown-menu/index.d.ts +7 -0
  322. package/dist/components/ui/dropdown-menu/index.js +7 -0
  323. package/dist/components/ui/input/index.d.ts +2 -0
  324. package/dist/components/ui/input/index.js +4 -0
  325. package/dist/components/ui/input/input.svelte +48 -0
  326. package/dist/components/ui/input/input.svelte.d.ts +13 -0
  327. package/dist/components/ui/label/index.d.ts +1 -0
  328. package/dist/components/ui/label/index.js +1 -0
  329. package/dist/components/ui/label/label.svelte +18 -0
  330. package/dist/components/ui/label/label.svelte.d.ts +5 -0
  331. package/dist/components/ui/pagination/index.d.ts +7 -0
  332. package/dist/components/ui/pagination/index.js +7 -0
  333. package/dist/components/ui/pagination/pagination-content.svelte +11 -0
  334. package/dist/components/ui/pagination/pagination-content.svelte.d.ts +8 -0
  335. package/dist/components/ui/pagination/pagination-ellipsis.svelte +12 -0
  336. package/dist/components/ui/pagination/pagination-ellipsis.svelte.d.ts +4 -0
  337. package/dist/components/ui/pagination/pagination-item.svelte +11 -0
  338. package/dist/components/ui/pagination/pagination-item.svelte.d.ts +8 -0
  339. package/dist/components/ui/pagination/pagination-link.svelte +26 -0
  340. package/dist/components/ui/pagination/pagination-link.svelte.d.ts +9 -0
  341. package/dist/components/ui/pagination/pagination-next.svelte +22 -0
  342. package/dist/components/ui/pagination/pagination-next.svelte.d.ts +8 -0
  343. package/dist/components/ui/pagination/pagination-previous.svelte +22 -0
  344. package/dist/components/ui/pagination/pagination-previous.svelte.d.ts +8 -0
  345. package/dist/components/ui/pagination/pagination.svelte +11 -0
  346. package/dist/components/ui/pagination/pagination.svelte.d.ts +8 -0
  347. package/dist/components/ui/popover/index.d.ts +6 -0
  348. package/dist/components/ui/popover/index.js +6 -0
  349. package/dist/components/ui/popover/popover-content.svelte +25 -0
  350. package/dist/components/ui/popover/popover-content.svelte.d.ts +7 -0
  351. package/dist/components/ui/progress/index.d.ts +1 -0
  352. package/dist/components/ui/progress/index.js +1 -0
  353. package/dist/components/ui/progress/progress.svelte +22 -0
  354. package/dist/components/ui/progress/progress.svelte.d.ts +8 -0
  355. package/dist/components/ui/scroll-area/index.d.ts +1 -0
  356. package/dist/components/ui/scroll-area/index.js +1 -0
  357. package/dist/components/ui/scroll-area/scroll-area.svelte +20 -0
  358. package/dist/components/ui/scroll-area/scroll-area.svelte.d.ts +9 -0
  359. package/dist/components/ui/select/index.d.ts +2 -0
  360. package/dist/components/ui/select/index.js +2 -0
  361. package/dist/components/ui/select/select.svelte +36 -0
  362. package/dist/components/ui/select/select.svelte.d.ts +8 -0
  363. package/dist/components/ui/separator/index.d.ts +2 -0
  364. package/dist/components/ui/separator/index.js +4 -0
  365. package/dist/components/ui/separator/separator.svelte +23 -0
  366. package/dist/components/ui/separator/separator.svelte.d.ts +4 -0
  367. package/dist/components/ui/sheet/index.d.ts +7 -0
  368. package/dist/components/ui/sheet/index.js +7 -0
  369. package/dist/components/ui/sheet/sheet-content.svelte +28 -0
  370. package/dist/components/ui/sheet/sheet-content.svelte.d.ts +8 -0
  371. package/dist/components/ui/sheet/sheet-description.svelte +22 -0
  372. package/dist/components/ui/sheet/sheet-description.svelte.d.ts +6 -0
  373. package/dist/components/ui/sheet/sheet-footer.svelte +22 -0
  374. package/dist/components/ui/sheet/sheet-footer.svelte.d.ts +6 -0
  375. package/dist/components/ui/sheet/sheet-header.svelte +22 -0
  376. package/dist/components/ui/sheet/sheet-header.svelte.d.ts +6 -0
  377. package/dist/components/ui/sheet/sheet-title.svelte +22 -0
  378. package/dist/components/ui/sheet/sheet-title.svelte.d.ts +6 -0
  379. package/dist/components/ui/sheet/sheet.svelte +78 -0
  380. package/dist/components/ui/sheet/sheet.svelte.d.ts +10 -0
  381. package/dist/components/ui/skeleton/index.d.ts +2 -0
  382. package/dist/components/ui/skeleton/index.js +2 -0
  383. package/dist/components/ui/skeleton/skeleton.svelte +21 -0
  384. package/dist/components/ui/skeleton/skeleton.svelte.d.ts +8 -0
  385. package/dist/components/ui/switch/index.d.ts +2 -0
  386. package/dist/components/ui/switch/index.js +2 -0
  387. package/dist/components/ui/switch/switch.svelte +49 -0
  388. package/dist/components/ui/switch/switch.svelte.d.ts +10 -0
  389. package/dist/components/ui/table/index.d.ts +9 -0
  390. package/dist/components/ui/table/index.js +11 -0
  391. package/dist/components/ui/table/table-body.svelte +15 -0
  392. package/dist/components/ui/table/table-body.svelte.d.ts +5 -0
  393. package/dist/components/ui/table/table-caption.svelte +20 -0
  394. package/dist/components/ui/table/table-caption.svelte.d.ts +5 -0
  395. package/dist/components/ui/table/table-cell.svelte +15 -0
  396. package/dist/components/ui/table/table-cell.svelte.d.ts +5 -0
  397. package/dist/components/ui/table/table-footer.svelte +20 -0
  398. package/dist/components/ui/table/table-footer.svelte.d.ts +5 -0
  399. package/dist/components/ui/table/table-head.svelte +15 -0
  400. package/dist/components/ui/table/table-head.svelte.d.ts +5 -0
  401. package/dist/components/ui/table/table-header.svelte +20 -0
  402. package/dist/components/ui/table/table-header.svelte.d.ts +5 -0
  403. package/dist/components/ui/table/table-row.svelte +15 -0
  404. package/dist/components/ui/table/table-row.svelte.d.ts +5 -0
  405. package/dist/components/ui/table/table.svelte +17 -0
  406. package/dist/components/ui/table/table.svelte.d.ts +5 -0
  407. package/dist/components/ui/tabs/index.d.ts +5 -0
  408. package/dist/components/ui/tabs/index.js +5 -0
  409. package/dist/components/ui/tabs/tabs-content.svelte +30 -0
  410. package/dist/components/ui/tabs/tabs-content.svelte.d.ts +9 -0
  411. package/dist/components/ui/tabs/tabs-list.svelte +26 -0
  412. package/dist/components/ui/tabs/tabs-list.svelte.d.ts +6 -0
  413. package/dist/components/ui/tabs/tabs-trigger.svelte +37 -0
  414. package/dist/components/ui/tabs/tabs-trigger.svelte.d.ts +9 -0
  415. package/dist/components/ui/tabs/tabs.svelte +27 -0
  416. package/dist/components/ui/tabs/tabs.svelte.d.ts +9 -0
  417. package/dist/components/ui/textarea/index.d.ts +2 -0
  418. package/dist/components/ui/textarea/index.js +2 -0
  419. package/dist/components/ui/textarea/textarea.svelte +24 -0
  420. package/dist/components/ui/textarea/textarea.svelte.d.ts +6 -0
  421. package/dist/components/ui/tooltip/index.d.ts +6 -0
  422. package/dist/components/ui/tooltip/index.js +8 -0
  423. package/dist/components/ui/tooltip/tooltip-content.svelte +52 -0
  424. package/dist/components/ui/tooltip/tooltip-content.svelte.d.ts +11 -0
  425. package/dist/components/ui/tooltip/tooltip-portal.svelte +7 -0
  426. package/dist/components/ui/tooltip/tooltip-portal.svelte.d.ts +4 -0
  427. package/dist/components/ui/tooltip/tooltip-provider.svelte +7 -0
  428. package/dist/components/ui/tooltip/tooltip-provider.svelte.d.ts +4 -0
  429. package/dist/components/ui/tooltip/tooltip-trigger.svelte +7 -0
  430. package/dist/components/ui/tooltip/tooltip-trigger.svelte.d.ts +4 -0
  431. package/dist/components/ui/tooltip/tooltip.svelte +10 -0
  432. package/dist/components/ui/tooltip/tooltip.svelte.d.ts +4 -0
  433. package/dist/editor-config.svelte.d.ts +15 -0
  434. package/dist/editor-config.svelte.js +19 -0
  435. package/dist/index.d.ts +117 -0
  436. package/dist/index.js +127 -0
  437. package/dist/markdown-deps.d.ts +21 -0
  438. package/dist/router-state.svelte.d.ts +5 -0
  439. package/dist/router-state.svelte.js +58 -0
  440. package/dist/types.d.ts +42 -0
  441. package/dist/types.js +1 -0
  442. package/dist/utils.d.ts +16 -0
  443. package/dist/utils.js +5 -0
  444. package/package.json +2 -2
@@ -0,0 +1,284 @@
1
+ <script lang="ts">
2
+ import { useGetIdentity, useUpdatePassword, getAuthProvider } from '@svadmin/core';
3
+ import { t } from '@svadmin/core/i18n';
4
+ import { Button } from './ui/button/index.js';
5
+ import { Label } from './ui/label/index.js';
6
+ import { Input } from './ui/input/index.js';
7
+ import * as Card from './ui/card/index.js';
8
+ import * as Alert from './ui/alert/index.js';
9
+ import PasswordInput from './PasswordInput.svelte';
10
+ import { User, Mail, Lock, Loader2, AlertCircle, CheckCircle, Camera } from '@lucide/svelte';
11
+
12
+ const identity = useGetIdentity();
13
+ const updatePw = useUpdatePassword();
14
+
15
+ // Check if auth provider supports updateProfile
16
+ let authProvider: ReturnType<typeof getAuthProvider> | null = null;
17
+ try { authProvider = getAuthProvider(); } catch { /* no auth */ }
18
+ const canUpdateProfile = !!authProvider?.updateProfile;
19
+
20
+ // Profile edit state
21
+ let editingProfile = $state(false);
22
+ let editName = $state('');
23
+ let profileSaving = $state(false);
24
+ let profileSuccess = $state(false);
25
+ let profileError = $state('');
26
+
27
+ function startEditProfile() {
28
+ editName = identity.data?.name ?? '';
29
+ editingProfile = true;
30
+ profileSuccess = false;
31
+ profileError = '';
32
+ }
33
+
34
+ async function saveProfile() {
35
+ if (!authProvider?.updateProfile) return;
36
+ profileSaving = true;
37
+ profileError = '';
38
+ try {
39
+ const result = await authProvider.updateProfile({ name: editName });
40
+ if (result.success) {
41
+ profileSuccess = true;
42
+ editingProfile = false;
43
+ identity.refetch();
44
+ } else {
45
+ profileError = result.error?.message ?? t('common.operationFailed');
46
+ }
47
+ } catch (e) {
48
+ profileError = (e as Error).message;
49
+ } finally {
50
+ profileSaving = false;
51
+ }
52
+ }
53
+
54
+ // Avatar upload
55
+ let avatarUploading = $state(false);
56
+ let fileInput = $state<HTMLInputElement>(null!);
57
+
58
+ async function handleAvatarChange(e: Event) {
59
+ const file = (e.target as HTMLInputElement).files?.[0];
60
+ if (!file || !authProvider?.updateProfile) return;
61
+ avatarUploading = true;
62
+ try {
63
+ const result = await authProvider.updateProfile({ avatar: file });
64
+ if (result.success) identity.refetch();
65
+ } finally {
66
+ avatarUploading = false;
67
+ }
68
+ }
69
+
70
+ // Password change form
71
+ let currentPassword = $state('');
72
+ let newPassword = $state('');
73
+ let confirmPassword = $state('');
74
+ let pwError = $state('');
75
+ let pwSuccess = $state(false);
76
+
77
+ async function handlePasswordChange(e: SubmitEvent) {
78
+ e.preventDefault();
79
+ pwError = '';
80
+ pwSuccess = false;
81
+
82
+ if (!newPassword) { pwError = t('auth.passwordRequired'); return; }
83
+ if (newPassword !== confirmPassword) { pwError = t('auth.passwordMismatch'); return; }
84
+
85
+ const result = await updatePw.mutate({
86
+ password: newPassword,
87
+ currentPassword,
88
+ confirmPassword,
89
+ });
90
+ if (result.success) {
91
+ pwSuccess = true;
92
+ currentPassword = '';
93
+ newPassword = '';
94
+ confirmPassword = '';
95
+ } else {
96
+ pwError = result.error?.message ?? t('common.operationFailed');
97
+ }
98
+ }
99
+
100
+ // Avatar initials
101
+ const initials = $derived(
102
+ identity.data?.name
103
+ ? identity.data.name.split(' ').map((n: string) => n[0]).join('').toUpperCase().slice(0, 2)
104
+ : '?'
105
+ );
106
+ </script>
107
+
108
+ <div class="space-y-6">
109
+ <div>
110
+ <h2 class="text-xl font-semibold text-foreground">{t('profile.title')}</h2>
111
+ </div>
112
+
113
+ <!-- Profile Info -->
114
+ <Card.Card>
115
+ <Card.CardHeader>
116
+ <Card.CardTitle class="flex items-center gap-2 text-base">
117
+ <User class="h-4 w-4 text-muted-foreground" />
118
+ {t('profile.title')}
119
+ </Card.CardTitle>
120
+ </Card.CardHeader>
121
+ <Card.CardContent>
122
+ {#if identity.isLoading}
123
+ <div class="flex items-center gap-2 text-muted-foreground">
124
+ <Loader2 class="h-4 w-4 animate-spin" />
125
+ {t('common.loading')}
126
+ </div>
127
+ {:else if identity.data}
128
+ {#if profileSuccess}
129
+ <Alert.Root class="border-success/30 bg-success/5 text-success mb-4">
130
+ <CheckCircle class="h-4 w-4" />
131
+ <Alert.Description>{t('common.updateSuccess')}</Alert.Description>
132
+ </Alert.Root>
133
+ {/if}
134
+
135
+ <div class="flex items-start gap-6">
136
+ <!-- Avatar -->
137
+ <div class="shrink-0 relative group">
138
+ {#if identity.data.avatar}
139
+ <img
140
+ src={identity.data.avatar}
141
+ alt={identity.data.name ?? ''}
142
+ class="h-20 w-20 rounded-lg object-cover ring-2 ring-primary/20"
143
+ />
144
+ {:else}
145
+ <div class="h-20 w-20 rounded-lg bg-primary/10 text-primary flex items-center justify-center text-2xl font-bold">
146
+ {initials}
147
+ </div>
148
+ {/if}
149
+ {#if canUpdateProfile}
150
+ <button
151
+ class="absolute inset-0 rounded-lg bg-black/50 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity cursor-pointer"
152
+ onclick={() => fileInput.click()}
153
+ disabled={avatarUploading}
154
+ >
155
+ {#if avatarUploading}
156
+ <Loader2 class="h-5 w-5 text-white animate-spin" />
157
+ {:else}
158
+ <Camera class="h-5 w-5 text-white" />
159
+ {/if}
160
+ </button>
161
+ <input
162
+ bind:this={fileInput}
163
+ type="file"
164
+ accept="image/*"
165
+ class="hidden"
166
+ onchange={handleAvatarChange}
167
+ />
168
+ {/if}
169
+ </div>
170
+
171
+ <!-- Info -->
172
+ <div class="space-y-3 flex-1 min-w-0">
173
+ {#if editingProfile}
174
+ <div class="space-y-3 max-w-sm">
175
+ <div>
176
+ <Label for="edit-name" class="text-xs text-muted-foreground">{t('profile.name')}</Label>
177
+ <Input id="edit-name" bind:value={editName} class="mt-1" />
178
+ </div>
179
+ {#if profileError}
180
+ <p class="text-xs text-destructive">{profileError}</p>
181
+ {/if}
182
+ <div class="flex gap-2">
183
+ <Button size="sm" onclick={saveProfile} disabled={profileSaving}>
184
+ {#if profileSaving}<Loader2 class="h-3 w-3 animate-spin mr-1" />{/if}
185
+ {t('common.save')}
186
+ </Button>
187
+ <Button size="sm" variant="outline" onclick={() => { editingProfile = false; }}>
188
+ {t('common.cancel')}
189
+ </Button>
190
+ </div>
191
+ </div>
192
+ {:else}
193
+ <div>
194
+ <Label class="text-xs text-muted-foreground">{t('profile.name')}</Label>
195
+ <p class="text-lg font-semibold truncate">{identity.data.name ?? '—'}</p>
196
+ </div>
197
+
198
+ {#if identity.data.email || identity.data.username}
199
+ <div class="flex items-center gap-2 text-sm text-muted-foreground">
200
+ {#if identity.data.email}
201
+ <Mail class="h-4 w-4 shrink-0" />
202
+ {:else}
203
+ <User class="h-4 w-4 shrink-0" />
204
+ {/if}
205
+ <span class="truncate">{identity.data.email || identity.data.username}</span>
206
+ </div>
207
+ {/if}
208
+
209
+ {#if identity.data.id}
210
+ <div class="text-xs text-muted-foreground/60 font-mono">
211
+ ID: {identity.data.id}
212
+ </div>
213
+ {/if}
214
+
215
+ {#if canUpdateProfile}
216
+ <Button size="sm" variant="outline" onclick={startEditProfile}>
217
+ {t('common.edit')}
218
+ </Button>
219
+ {/if}
220
+ {/if}
221
+ </div>
222
+ </div>
223
+ {:else}
224
+ <p class="text-sm text-muted-foreground">{t('profile.notAvailable')}</p>
225
+ {/if}
226
+ </Card.CardContent>
227
+ </Card.Card>
228
+
229
+ <!-- Change Password -->
230
+ <Card.Card>
231
+ <Card.CardHeader>
232
+ <Card.CardTitle class="flex items-center gap-2 text-base">
233
+ <Lock class="h-4 w-4 text-muted-foreground" />
234
+ {t('profile.changePassword')}
235
+ </Card.CardTitle>
236
+ </Card.CardHeader>
237
+ <Card.CardContent>
238
+ <form onsubmit={handlePasswordChange} class="space-y-4 max-w-sm">
239
+ {#if pwError}
240
+ <Alert.Root variant="destructive">
241
+ <AlertCircle class="h-4 w-4" />
242
+ <Alert.Description>{pwError}</Alert.Description>
243
+ </Alert.Root>
244
+ {/if}
245
+
246
+ {#if pwSuccess}
247
+ <Alert.Root class="border-success/30 bg-success/5 text-success">
248
+ <CheckCircle class="h-4 w-4" />
249
+ <Alert.Description>{t('profile.passwordChanged')}</Alert.Description>
250
+ </Alert.Root>
251
+ {/if}
252
+
253
+ <PasswordInput
254
+ id="current-password"
255
+ label={t('profile.currentPassword')}
256
+ bind:value={currentPassword}
257
+ autocomplete="current-password"
258
+ />
259
+
260
+ <PasswordInput
261
+ id="new-password"
262
+ label={t('auth.password')}
263
+ bind:value={newPassword}
264
+ autocomplete="new-password"
265
+ showStrength
266
+ />
267
+
268
+ <PasswordInput
269
+ id="confirm-new-password"
270
+ label={t('auth.confirmPassword')}
271
+ bind:value={confirmPassword}
272
+ autocomplete="new-password"
273
+ />
274
+
275
+ <Button type="submit" disabled={updatePw.isLoading}>
276
+ {#if updatePw.isLoading}
277
+ <Loader2 class="h-4 w-4 animate-spin mr-2" />
278
+ {/if}
279
+ {t('profile.updatePassword')}
280
+ </Button>
281
+ </form>
282
+ </Card.CardContent>
283
+ </Card.Card>
284
+ </div>
@@ -0,0 +1,3 @@
1
+ declare const ProfilePage: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type ProfilePage = ReturnType<typeof ProfilePage>;
3
+ export default ProfilePage;
@@ -0,0 +1,112 @@
1
+ <script lang="ts">
2
+ import { useRegister } from '@svadmin/core';
3
+ import { t } from '@svadmin/core/i18n';
4
+ import { navigate } from '@svadmin/core/router';
5
+ import { Button } from './ui/button/index.js';
6
+ import { Input } from './ui/input/index.js';
7
+ import { Label } from './ui/label/index.js';
8
+ import * as Card from './ui/card/index.js';
9
+ import * as Alert from './ui/alert/index.js';
10
+ import PasswordInput from './PasswordInput.svelte';
11
+ import { UserPlus, User, Loader2, AlertCircle } from '@lucide/svelte';
12
+
13
+ let { title = 'Admin', onSuccess } = $props<{
14
+ title?: string;
15
+ onSuccess?: () => void;
16
+ }>();
17
+
18
+ const register = useRegister();
19
+
20
+ let identifier = $state('');
21
+ let password = $state('');
22
+ let confirmPassword = $state('');
23
+ let error = $state('');
24
+
25
+ async function handleSubmit(e: SubmitEvent) {
26
+ e.preventDefault();
27
+ error = '';
28
+
29
+ if (!identifier) { error = t('auth.usernameOrEmailRequired'); return; }
30
+ if (!password) { error = t('auth.passwordRequired'); return; }
31
+ if (password !== confirmPassword) { error = t('auth.passwordMismatch'); return; }
32
+
33
+ const result = await register.mutate({ email: identifier, username: identifier, password });
34
+ if (result.success) {
35
+ onSuccess?.();
36
+ } else {
37
+ error = result.error?.message ?? t('common.operationFailed');
38
+ }
39
+ }
40
+ </script>
41
+
42
+ <div class="min-h-screen flex items-center justify-center bg-background p-4">
43
+ <div class="w-full max-w-[380px]">
44
+ <Card.Card>
45
+ <Card.CardHeader class="text-center pb-2">
46
+ <div class="inline-flex items-center justify-center w-10 h-10 rounded-lg bg-primary/10 text-primary mx-auto mb-3">
47
+ <UserPlus class="h-5 w-5" />
48
+ </div>
49
+ <Card.CardTitle class="text-xl">{t('auth.createAccount')}</Card.CardTitle>
50
+ <p class="text-sm text-muted-foreground">{t('auth.createAccountMessage')}</p>
51
+ </Card.CardHeader>
52
+ <Card.CardContent>
53
+ <form onsubmit={handleSubmit} class="space-y-4">
54
+ {#if error}
55
+ <Alert.Root variant="destructive">
56
+ <AlertCircle class="h-4 w-4" />
57
+ <Alert.Description>{error}</Alert.Description>
58
+ </Alert.Root>
59
+ {/if}
60
+
61
+ <div class="space-y-2">
62
+ <Label for="register-identifier">{t('auth.usernameOrEmail')}</Label>
63
+ <div class="relative">
64
+ <User class="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground pointer-events-none z-[1]" />
65
+ <Input
66
+ id="register-identifier"
67
+ type="text"
68
+ placeholder={t('auth.identifierPlaceholder')}
69
+ bind:value={identifier}
70
+ class="pl-9"
71
+ autocomplete="username"
72
+ />
73
+ </div>
74
+ </div>
75
+
76
+ <PasswordInput
77
+ id="register-password"
78
+ label={t('auth.password')}
79
+ bind:value={password}
80
+ autocomplete="new-password"
81
+ showStrength
82
+ />
83
+
84
+ <PasswordInput
85
+ id="register-confirm"
86
+ label={t('auth.confirmPassword')}
87
+ bind:value={confirmPassword}
88
+ autocomplete="new-password"
89
+ />
90
+
91
+ <Button type="submit" class="w-full" disabled={register.isLoading}>
92
+ {#if register.isLoading}
93
+ <Loader2 class="h-4 w-4 animate-spin mr-2" />
94
+ {/if}
95
+ {t('auth.registerButton')}
96
+ </Button>
97
+ </form>
98
+
99
+ <div class="flex items-center justify-center gap-1 mt-5 pt-5 border-t">
100
+ <span class="text-sm text-muted-foreground">{t('auth.hasAccount')}</span>
101
+ <Button variant="link" class="text-sm h-auto p-0 font-medium" onclick={() => navigate('/login')}>
102
+ {t('auth.login')}
103
+ </Button>
104
+ </div>
105
+ </Card.CardContent>
106
+ </Card.Card>
107
+
108
+ <p class="text-xs text-muted-foreground mt-4 text-center opacity-60">
109
+ Powered by {title}
110
+ </p>
111
+ </div>
112
+ </div>
@@ -0,0 +1,7 @@
1
+ type $$ComponentProps = {
2
+ title?: string;
3
+ onSuccess?: () => void;
4
+ };
5
+ declare const RegisterPage: import("svelte").Component<$$ComponentProps, {}, "">;
6
+ type RegisterPage = ReturnType<typeof RegisterPage>;
7
+ export default RegisterPage;
@@ -0,0 +1,146 @@
1
+ <script lang="ts">
2
+ import { t } from '@svadmin/core/i18n';
3
+ import { getAuthProvider, getResources } from '@svadmin/core';
4
+ import type { Role } from '@svadmin/core';
5
+ import PermissionMatrix from './PermissionMatrix.svelte';
6
+ import type { RoleInfo, ResourceInfo, ActionInfo } from '../types.js';
7
+ import { toast } from '@svadmin/core/toast';
8
+ import { AlertCircle } from '@lucide/svelte';
9
+
10
+ const authProvider = getAuthProvider();
11
+ const rawResources = getResources();
12
+
13
+ let roles = $state<RoleInfo[]>([]);
14
+ let selectedRoleCode = $state<string>('');
15
+
16
+ // Matrix format: { "roleId": { "resourceName": ["action1", "action2"] } }
17
+ let permissionsCache = $state<Record<string, Record<string, string[]>>>({});
18
+
19
+ let loadingRoles = $state(true);
20
+ let loadingPermissions = $state(false);
21
+ let saving = $state(false);
22
+ let error = $state<string | null>(null);
23
+
24
+ // Convert system resources to MatrixResource format
25
+ let matrixResources = $derived<ResourceInfo[]>(
26
+ rawResources.map(r => ({
27
+ code: r.name,
28
+ name: r.label || r.name,
29
+ }))
30
+ );
31
+
32
+ let matrixActions = $state<ActionInfo[]>([
33
+ { code: 'create', name: t('common.create') ?? 'Create' },
34
+ { code: 'read', name: t('common.detail') ?? 'Read' },
35
+ { code: 'update', name: t('common.edit') ?? 'Update' },
36
+ { code: 'delete', name: t('common.delete') ?? 'Delete' },
37
+ ]);
38
+
39
+ async function loadRoles() {
40
+ if (!authProvider?.getRoles) {
41
+ error = t('settings.rbacNotSupported') ?? 'RBAC not supported by AuthProvider';
42
+ loadingRoles = false;
43
+ return;
44
+ }
45
+ try {
46
+ const fetchedRoles = await authProvider.getRoles();
47
+ roles = fetchedRoles.map(r => ({ code: r.id, ...r }));
48
+ if (roles.length > 0 && !selectedRoleCode) {
49
+ selectedRoleCode = roles[0].code;
50
+ }
51
+ } catch (e) {
52
+ error = (e as Error).message;
53
+ } finally {
54
+ loadingRoles = false;
55
+ }
56
+ }
57
+
58
+ async function loadPermissionsForRole(roleId: string) {
59
+ if (!authProvider?.getRolePermissions || permissionsCache[roleId]) return;
60
+
61
+ loadingPermissions = true;
62
+ try {
63
+ const perms = await authProvider.getRolePermissions(roleId);
64
+ permissionsCache[roleId] = perms;
65
+ } catch (e) {
66
+ toast.error((e as Error).message);
67
+ } finally {
68
+ loadingPermissions = false;
69
+ }
70
+ }
71
+
72
+ // Load permissions whenever the selected role changes
73
+ $effect(() => {
74
+ if (selectedRoleCode && !permissionsCache[selectedRoleCode] && !loadingPermissions) {
75
+ loadPermissionsForRole(selectedRoleCode);
76
+ }
77
+ });
78
+
79
+ $effect(() => {
80
+ loadRoles();
81
+ });
82
+
83
+ // isGranted logic
84
+ function checkGrant(roleCode: string, resourceCode: string, actionCode: string) {
85
+ const rolePerms = permissionsCache[roleCode];
86
+ if (!rolePerms) return false;
87
+ return rolePerms[resourceCode]?.includes(actionCode) ?? false;
88
+ }
89
+
90
+ async function handleToggle(roleCode: string, resourceCode: string, actionCode: string, grant: boolean) {
91
+ if (!authProvider?.updateRolePermissions) return;
92
+
93
+ // Copy state
94
+ const currentRolePerms = { ...(permissionsCache[roleCode] || {}) };
95
+ const currentResPerms = [...(currentRolePerms[resourceCode] || [])];
96
+
97
+ // Optimistic update
98
+ if (grant) {
99
+ if (!currentResPerms.includes(actionCode)) currentResPerms.push(actionCode);
100
+ } else {
101
+ const idx = currentResPerms.indexOf(actionCode);
102
+ if (idx > -1) currentResPerms.splice(idx, 1);
103
+ }
104
+
105
+ currentRolePerms[resourceCode] = currentResPerms;
106
+ permissionsCache[roleCode] = currentRolePerms;
107
+
108
+ saving = true;
109
+ try {
110
+ // Send the entire role's permissions back (as defined by our AuthProvider interface)
111
+ const result = await authProvider.updateRolePermissions(roleCode, currentRolePerms);
112
+ if (result.success) {
113
+ // Success silently
114
+ } else {
115
+ throw new Error(result.error?.message ?? t('common.operationFailed'));
116
+ }
117
+ } catch (e) {
118
+ toast.error((e as Error).message);
119
+ // Rollback on fail
120
+ delete permissionsCache[roleCode];
121
+ loadPermissionsForRole(roleCode);
122
+ } finally {
123
+ saving = false;
124
+ }
125
+ }
126
+ </script>
127
+
128
+ {#if error}
129
+ <div class="h-full flex items-center justify-center">
130
+ <div class="max-w-md p-6 border border-destructive/20 bg-destructive/10 text-destructive rounded-lg flex flex-col items-center gap-3 text-center">
131
+ <AlertCircle class="h-8 w-8" />
132
+ <h3 class="font-bold text-lg">{t('common.error') ?? 'Error'}</h3>
133
+ <p>{error}</p>
134
+ </div>
135
+ </div>
136
+ {:else}
137
+ <PermissionMatrix
138
+ {roles}
139
+ resources={matrixResources}
140
+ actions={matrixActions}
141
+ isGranted={checkGrant}
142
+ bind:selectedRole={selectedRoleCode}
143
+ loading={loadingRoles || loadingPermissions || saving}
144
+ onToggle={handleToggle}
145
+ />
146
+ {/if}
@@ -0,0 +1,3 @@
1
+ declare const RolesSettings: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type RolesSettings = ReturnType<typeof RolesSettings>;
3
+ export default RolesSettings;
@@ -0,0 +1,113 @@
1
+ <script lang="ts">
2
+ import { t } from '@svadmin/core/i18n';
3
+ import { navigate } from '@svadmin/core/router';
4
+ import { currentPath } from '@svadmin/core/router';
5
+ import { User, Palette, Info, Shield, FileSearch } from '@lucide/svelte';
6
+ import ProfilePage from './ProfilePage.svelte';
7
+ import AppearanceSettings from './AppearanceSettings.svelte';
8
+ import AboutSettings from './AboutSettings.svelte';
9
+ import RolesSettings from './RolesSettings.svelte';
10
+ import AuditLogViewer from './AuditLogViewer.svelte';
11
+
12
+ const sections = [
13
+ {
14
+ group: 'settings.general',
15
+ items: [
16
+ { key: 'profile', path: '/settings/profile', icon: User, label: 'settings.profile' },
17
+ { key: 'appearance', path: '/settings/appearance', icon: Palette, label: 'settings.appearance' },
18
+ ],
19
+ },
20
+ {
21
+ group: 'settings.system',
22
+ items: [
23
+ { key: 'roles', path: '/settings/roles', icon: Shield, label: 'settings.rolesAndPermissions' },
24
+ { key: 'audit', path: '/settings/audit', icon: FileSearch, label: 'settings.auditLogs' },
25
+ { key: 'about', path: '/settings/about', icon: Info, label: 'settings.about' },
26
+ ],
27
+ },
28
+ ];
29
+
30
+ let activeKey = $derived.by(() => {
31
+ const path = currentPath();
32
+ if (path.includes('/settings/appearance')) return 'appearance';
33
+ if (path.includes('/settings/roles')) return 'roles';
34
+ if (path.includes('/settings/audit')) return 'audit';
35
+ if (path.includes('/settings/about')) return 'about';
36
+ return 'profile';
37
+ });
38
+
39
+ // Default redirect to profile
40
+ $effect(() => {
41
+ const path = currentPath();
42
+ if (path === '/settings') {
43
+ navigate('/settings/profile');
44
+ }
45
+ });
46
+ </script>
47
+
48
+ <div class="flex flex-col lg:flex-row gap-0 min-h-full">
49
+ <!-- Left sidebar navigation -->
50
+ <nav class="w-full lg:w-56 shrink-0 bg-muted/10 shadow-[inset_0_-1px_0_rgba(0,0,0,0.05)] lg:shadow-[inset_-1px_0_0_rgba(0,0,0,0.05)] dark:shadow-[inset_-1px_0_0_rgba(255,255,255,0.05)]">
51
+ <!-- Mobile: horizontal scroll tabs -->
52
+ <div class="flex lg:hidden overflow-x-auto px-4 py-2 gap-1">
53
+ {#each sections as section}
54
+ {#each section.items as item}
55
+ {@const active = activeKey === item.key}
56
+ <button
57
+ class="flex items-center gap-2 px-3 py-2 text-sm font-medium rounded-md whitespace-nowrap transition-colors
58
+ {active ? 'bg-background text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground hover:bg-background/50'}"
59
+ onclick={() => navigate(item.path)}
60
+ >
61
+ <item.icon class="h-4 w-4" />
62
+ {t(item.label)}
63
+ </button>
64
+ {/each}
65
+ {/each}
66
+ </div>
67
+
68
+ <!-- Desktop: vertical nav with groups -->
69
+ <div class="hidden lg:block py-6 px-3 space-y-6">
70
+ <div class="px-3">
71
+ <h2 class="text-lg font-semibold text-foreground">{t('settings.title')}</h2>
72
+ <p class="text-xs text-muted-foreground mt-1">{t('settings.settingsDescription')}</p>
73
+ </div>
74
+ {#each sections as section}
75
+ <div>
76
+ <h3 class="px-3 mb-1 text-[11px] font-semibold uppercase tracking-wider text-muted-foreground/60">
77
+ {t(section.group)}
78
+ </h3>
79
+ <div class="space-y-0.5">
80
+ {#each section.items as item}
81
+ {@const active = activeKey === item.key}
82
+ <button
83
+ class="flex w-full items-center gap-3 rounded-lg px-3 py-2 text-sm transition-all
84
+ {active
85
+ ? 'bg-primary/10 text-primary font-medium'
86
+ : 'text-muted-foreground hover:bg-accent hover:text-accent-foreground'}"
87
+ onclick={() => navigate(item.path)}
88
+ >
89
+ <item.icon class="h-4 w-4 shrink-0" />
90
+ {t(item.label)}
91
+ </button>
92
+ {/each}
93
+ </div>
94
+ </div>
95
+ {/each}
96
+ </div>
97
+ </nav>
98
+
99
+ <!-- Right content area -->
100
+ <div class="flex-1 p-6 lg:p-8 {activeKey === 'roles' || activeKey === 'audit' ? 'max-w-6xl' : 'max-w-3xl'}">
101
+ {#if activeKey === 'profile'}
102
+ <ProfilePage />
103
+ {:else if activeKey === 'appearance'}
104
+ <AppearanceSettings />
105
+ {:else if activeKey === 'roles'}
106
+ <RolesSettings />
107
+ {:else if activeKey === 'audit'}
108
+ <AuditLogViewer />
109
+ {:else if activeKey === 'about'}
110
+ <AboutSettings />
111
+ {/if}
112
+ </div>
113
+ </div>
@@ -0,0 +1,3 @@
1
+ declare const SettingsPage: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type SettingsPage = ReturnType<typeof SettingsPage>;
3
+ export default SettingsPage;