@svadmin/ui 0.68.1 → 0.69.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 (315) hide show
  1. package/README.md +52 -0
  2. package/dist/app.css +7627 -853
  3. package/dist/app.theme.css +7676 -850
  4. package/dist/components/AboutSettings.svelte +8 -8
  5. package/dist/components/ActivityFeed.svelte +25 -40
  6. package/dist/components/AdminApp.svelte +14 -14
  7. package/dist/components/AnomalyBadge.svelte +6 -5
  8. package/dist/components/ApiSettings.svelte +8 -8
  9. package/dist/components/AppearanceSettings.svelte +13 -13
  10. package/dist/components/ApprovalActionCard.svelte +35 -35
  11. package/dist/components/AuditLogDrawer.svelte +17 -17
  12. package/dist/components/AuditLogViewer.svelte +42 -42
  13. package/dist/components/AuthPageShell.svelte +11 -11
  14. package/dist/components/AutoForm.svelte +28 -28
  15. package/dist/components/AutoSaveIndicator.svelte +8 -8
  16. package/dist/components/AutoTable.svelte +141 -141
  17. package/dist/components/BatchActionBar.svelte +15 -15
  18. package/dist/components/Breadcrumbs.svelte +4 -4
  19. package/dist/components/CancelTaskButton.svelte +2 -2
  20. package/dist/components/CanvasAnnotation.svelte +27 -27
  21. package/dist/components/Cascader.svelte +20 -20
  22. package/dist/components/CatchAllNavigate.svelte +2 -2
  23. package/dist/components/ColumnHeaderFilter.svelte +21 -21
  24. package/dist/components/ColumnSettings.svelte +20 -20
  25. package/dist/components/ComboboxField.svelte +17 -17
  26. package/dist/components/CommandPalette.svelte +23 -23
  27. package/dist/components/ConfigErrorScreen.svelte +27 -27
  28. package/dist/components/ConfirmDialog.svelte +1 -1
  29. package/dist/components/CreateInferencer.svelte +1 -1
  30. package/dist/components/CreatePage.svelte +1 -1
  31. package/dist/components/DecisionTable.svelte +39 -39
  32. package/dist/components/DetailDrawer.svelte +9 -9
  33. package/dist/components/DevTools.svelte +96 -96
  34. package/dist/components/DraggableGrid.svelte +6 -6
  35. package/dist/components/DraggableHeader.svelte +1 -1
  36. package/dist/components/DraggableRowTable.svelte +13 -13
  37. package/dist/components/DrawerForm.svelte +10 -10
  38. package/dist/components/DynamicFormList.svelte +19 -19
  39. package/dist/components/EditInferencer.svelte +3 -3
  40. package/dist/components/EditInferencer.svelte.d.ts +1 -1
  41. package/dist/components/EditPage.svelte +1 -1
  42. package/dist/components/EditableTable.svelte +30 -30
  43. package/dist/components/EmptyState.svelte +6 -6
  44. package/dist/components/ErrorBoundary.svelte +8 -8
  45. package/dist/components/ErrorComponent.svelte +5 -5
  46. package/dist/components/FieldRenderer.svelte +30 -30
  47. package/dist/components/FilterBuilder.svelte +31 -31
  48. package/dist/components/FilterDropdown.svelte +26 -26
  49. package/dist/components/ForgotPasswordPage.svelte +14 -14
  50. package/dist/components/GanttChart.svelte +30 -30
  51. package/dist/components/Header.svelte +13 -13
  52. package/dist/components/ImageCropper.svelte +21 -21
  53. package/dist/components/ImportWizard.svelte +49 -49
  54. package/dist/components/InferencerPanel.svelte +35 -35
  55. package/dist/components/InfiniteList.svelte +8 -8
  56. package/dist/components/InlineEdit.svelte +5 -5
  57. package/dist/components/IntegrationsSettings.svelte +5 -5
  58. package/dist/components/JsonSchemaForm.svelte +18 -18
  59. package/dist/components/KanbanBoard.svelte +30 -30
  60. package/dist/components/KeyboardShortcuts.svelte +8 -8
  61. package/dist/components/Layout.svelte +22 -22
  62. package/dist/components/LazyPage.svelte +4 -4
  63. package/dist/components/ListInferencer.svelte +2 -2
  64. package/dist/components/ListPage.svelte +1 -1
  65. package/dist/components/LiveIndicator.svelte +11 -11
  66. package/dist/components/LoginPage.svelte +27 -27
  67. package/dist/components/MasterDetailView.svelte +24 -24
  68. package/dist/components/MediaLibraryModal.svelte +37 -37
  69. package/dist/components/MentionsInput.svelte +11 -11
  70. package/dist/components/MetricStrip.svelte +18 -58
  71. package/dist/components/ModalForm.svelte +8 -8
  72. package/dist/components/MultiTabKeepAlive.svelte +14 -14
  73. package/dist/components/NavigateToResource.svelte +3 -3
  74. package/dist/components/NotificationsSettings.svelte +4 -4
  75. package/dist/components/OfflineSyncBanner.svelte +28 -28
  76. package/dist/components/PageHeader.svelte +12 -13
  77. package/dist/components/PageSkeleton.svelte +26 -26
  78. package/dist/components/PasswordInput.svelte +11 -11
  79. package/dist/components/PdfDocumentViewer.svelte +45 -45
  80. package/dist/components/PermissionMatrix.svelte +48 -48
  81. package/dist/components/PivotTable.svelte +21 -21
  82. package/dist/components/PresenceAvatarGroup.svelte +11 -11
  83. package/dist/components/PrintableBill.svelte +43 -43
  84. package/dist/components/ProfilePage.svelte +34 -34
  85. package/dist/components/RecordDetailDrawer.svelte +15 -15
  86. package/dist/components/RegisterPage.svelte +9 -9
  87. package/dist/components/ResourceInferencer.svelte +3 -3
  88. package/dist/components/ResourceOperationsPage.svelte +44 -44
  89. package/dist/components/RetryTaskButton.svelte +2 -2
  90. package/dist/components/RolesSettings.svelte +4 -4
  91. package/dist/components/RowActions.svelte +10 -10
  92. package/dist/components/SecuritySettings.svelte +8 -8
  93. package/dist/components/SensitiveDataMask.svelte +8 -8
  94. package/dist/components/SettingsPage.svelte +17 -17
  95. package/dist/components/ShowInferencer.svelte +3 -3
  96. package/dist/components/ShowInferencer.svelte.d.ts +1 -1
  97. package/dist/components/ShowPage.svelte +24 -24
  98. package/dist/components/Sidebar.svelte +63 -63
  99. package/dist/components/SidebarItem.svelte +35 -35
  100. package/dist/components/SignaturePad.svelte +16 -16
  101. package/dist/components/SplitPaneLayout.svelte +10 -10
  102. package/dist/components/SpreadsheetView.svelte +35 -35
  103. package/dist/components/StatsCard.svelte +12 -25
  104. package/dist/components/StepForm.svelte +23 -23
  105. package/dist/components/StepsForm.svelte +17 -17
  106. package/dist/components/SvadminLogo.svelte +1 -1
  107. package/dist/components/SystemPageShell.svelte +6 -6
  108. package/dist/components/TableSummary.svelte +8 -8
  109. package/dist/components/TaskDetails.svelte +29 -29
  110. package/dist/components/TaskList.svelte +17 -17
  111. package/dist/components/TaskProgressBar.svelte +4 -4
  112. package/dist/components/TaskQueueDrawer.svelte +44 -44
  113. package/dist/components/TaskStatusBadge.svelte +5 -5
  114. package/dist/components/TenantSwitcher.svelte +17 -17
  115. package/dist/components/ThemedTitle.svelte +4 -4
  116. package/dist/components/Toast.svelte +2 -2
  117. package/dist/components/Transfer.svelte +40 -40
  118. package/dist/components/TreeSelect.svelte +32 -32
  119. package/dist/components/TreeTable.svelte +28 -28
  120. package/dist/components/TwoFactorAuthPage.svelte +15 -15
  121. package/dist/components/UndoableNotification.svelte +10 -10
  122. package/dist/components/UpdatePasswordPage.svelte +6 -6
  123. package/dist/components/VersionDiffViewer.svelte +38 -38
  124. package/dist/components/VirtualTable.svelte +9 -9
  125. package/dist/components/Watermark.svelte +2 -2
  126. package/dist/components/account/CompanyProfilePage.svelte +4 -4
  127. package/dist/components/account/GetStartedPage.svelte +19 -19
  128. package/dist/components/account/ImportMembersPage.svelte +42 -42
  129. package/dist/components/account/MembersStarterPage.svelte +18 -18
  130. package/dist/components/account/SecurityLogPage.svelte +1 -1
  131. package/dist/components/account/SettingsEnterprisePage.svelte +7 -7
  132. package/dist/components/account/SettingsPlainPage.svelte +3 -3
  133. package/dist/components/account/SettingsSidebarPage.svelte +5 -5
  134. package/dist/components/account/TeamMembersPage.svelte +2 -2
  135. package/dist/components/account/UserProfilePage.svelte +3 -3
  136. package/dist/components/buttons/CloneButton.svelte +2 -2
  137. package/dist/components/buttons/CreateButton.svelte +2 -2
  138. package/dist/components/buttons/DeleteButton.svelte +4 -4
  139. package/dist/components/buttons/EditButton.svelte +2 -2
  140. package/dist/components/buttons/ExportButton.svelte +2 -2
  141. package/dist/components/buttons/ImportButton.svelte +3 -3
  142. package/dist/components/buttons/ListButton.svelte +2 -2
  143. package/dist/components/buttons/RefreshButton.svelte +2 -2
  144. package/dist/components/buttons/SaveButton.svelte +3 -3
  145. package/dist/components/buttons/ShowButton.svelte +2 -2
  146. package/dist/components/charts/BarChart.svelte +3 -3
  147. package/dist/components/charts/LineChart.svelte +3 -3
  148. package/dist/components/charts/PieChart.svelte +7 -7
  149. package/dist/components/content/ApiKeyList.svelte +12 -12
  150. package/dist/components/content/AuditTimeline.svelte +18 -18
  151. package/dist/components/content/ContentPageHeader.svelte +9 -9
  152. package/dist/components/content/ContentPageShell.svelte +2 -2
  153. package/dist/components/content/DataState.svelte +8 -8
  154. package/dist/components/content/DescriptionList.svelte +25 -25
  155. package/dist/components/content/FeedbackNotice.svelte +11 -11
  156. package/dist/components/content/FileList.svelte +2 -2
  157. package/dist/components/content/FilterToolbar.svelte +15 -15
  158. package/dist/components/content/ImportDropzone.svelte +6 -6
  159. package/dist/components/content/IntegrationCard.svelte +4 -4
  160. package/dist/components/content/MediaThumbnail.svelte +16 -16
  161. package/dist/components/content/MemberList.svelte +2 -2
  162. package/dist/components/content/MetricBlock.svelte +7 -7
  163. package/dist/components/content/NetworkTable.svelte +1 -1
  164. package/dist/components/content/NetworkUserCard.svelte +12 -12
  165. package/dist/components/content/OtpInput.svelte +2 -2
  166. package/dist/components/content/PageToolbar.svelte +3 -3
  167. package/dist/components/content/ProjectCard.svelte +11 -11
  168. package/dist/components/content/SectionHeader.svelte +5 -5
  169. package/dist/components/content/SecurityEventTable.svelte +2 -2
  170. package/dist/components/content/SettingsFieldRow.svelte +5 -5
  171. package/dist/components/content/SettingsGroup.svelte +7 -7
  172. package/dist/components/content/StatusBadge.svelte +6 -6
  173. package/dist/components/content/StatusTabs.svelte +28 -28
  174. package/dist/components/content/SystemErrorState.svelte +2 -2
  175. package/dist/components/content/TeamCard.svelte +6 -6
  176. package/dist/components/content/TwoFactorStepper.svelte +3 -3
  177. package/dist/components/content/WorkspaceActionBar.svelte +12 -12
  178. package/dist/components/content/WorkspaceInspector.svelte +11 -11
  179. package/dist/components/content/WorkspaceLayout.svelte +5 -5
  180. package/dist/components/content/WorkspaceSplitPane.svelte +4 -4
  181. package/dist/components/content/WorkspaceStageStepper.svelte +16 -16
  182. package/dist/components/content/WorkspaceTabBar.svelte +16 -16
  183. package/dist/components/fields/ArrayField.svelte +12 -12
  184. package/dist/components/fields/AvatarField.svelte +15 -15
  185. package/dist/components/fields/BooleanField.svelte +14 -14
  186. package/dist/components/fields/CodeField.svelte +10 -10
  187. package/dist/components/fields/CopyField.svelte +6 -6
  188. package/dist/components/fields/CurrencyField.svelte +6 -6
  189. package/dist/components/fields/DateField.svelte +1 -1
  190. package/dist/components/fields/DateRangeField.svelte +2 -2
  191. package/dist/components/fields/EmailField.svelte +2 -2
  192. package/dist/components/fields/FileField.svelte +3 -3
  193. package/dist/components/fields/ImageField.svelte +1 -1
  194. package/dist/components/fields/JsonField.svelte +11 -11
  195. package/dist/components/fields/MarkdownField.svelte +2 -2
  196. package/dist/components/fields/MultiSelectField.svelte +3 -3
  197. package/dist/components/fields/NumberField.svelte +1 -1
  198. package/dist/components/fields/PercentField.svelte +9 -9
  199. package/dist/components/fields/PhoneField.svelte +8 -8
  200. package/dist/components/fields/RatingField.svelte +10 -10
  201. package/dist/components/fields/RelationField.svelte +3 -3
  202. package/dist/components/fields/RichTextField.svelte +4 -4
  203. package/dist/components/fields/TagField.svelte +11 -11
  204. package/dist/components/fields/TextField.svelte +2 -2
  205. package/dist/components/fields/UrlField.svelte +3 -3
  206. package/dist/components/network/TeamCrewTablePage.svelte +2 -2
  207. package/dist/components/network/UserCardsNFTPage.svelte +1 -1
  208. package/dist/components/profile/ActivityTimeline.svelte +8 -8
  209. package/dist/components/profile/ProfileCard.svelte +47 -47
  210. package/dist/components/profile/ProfileVariantSections.svelte +158 -158
  211. package/dist/components/profile/ProjectsGrid.svelte +6 -6
  212. package/dist/components/profile/PublicProfilePage.svelte +6 -6
  213. package/dist/components/profile/TeamsShowcase.svelte +3 -3
  214. package/dist/components/ui/alert/alert-description.svelte +1 -1
  215. package/dist/components/ui/alert/alert-title.svelte +1 -1
  216. package/dist/components/ui/alert/alert-variants.d.ts +7 -0
  217. package/dist/components/ui/alert/alert-variants.js +2 -0
  218. package/dist/components/ui/alert/alert.svelte +4 -15
  219. package/dist/components/ui/alert/alert.svelte.d.ts +7 -24
  220. package/dist/components/ui/alert-dialog/alert-dialog-content.svelte +2 -2
  221. package/dist/components/ui/alert-dialog/alert-dialog-description.svelte +1 -1
  222. package/dist/components/ui/alert-dialog/alert-dialog-footer.svelte +1 -1
  223. package/dist/components/ui/alert-dialog/alert-dialog-header.svelte +1 -1
  224. package/dist/components/ui/alert-dialog/alert-dialog-overlay.svelte +1 -1
  225. package/dist/components/ui/alert-dialog/alert-dialog-title.svelte +1 -1
  226. package/dist/components/ui/avatar/avatar-variants.d.ts +7 -0
  227. package/dist/components/ui/avatar/avatar-variants.js +2 -0
  228. package/dist/components/ui/avatar/avatar.svelte +11 -20
  229. package/dist/components/ui/avatar/avatar.svelte.d.ts +12 -28
  230. package/dist/components/ui/badge/badge-variants.d.ts +7 -0
  231. package/dist/components/ui/badge/badge-variants.js +2 -0
  232. package/dist/components/ui/badge/badge.svelte +4 -24
  233. package/dist/components/ui/badge/badge.svelte.d.ts +7 -45
  234. package/dist/components/ui/breadcrumb/breadcrumb-ellipsis.svelte +3 -3
  235. package/dist/components/ui/breadcrumb/breadcrumb-item.svelte +1 -1
  236. package/dist/components/ui/breadcrumb/breadcrumb-link.svelte +1 -1
  237. package/dist/components/ui/breadcrumb/breadcrumb-list.svelte +1 -1
  238. package/dist/components/ui/breadcrumb/breadcrumb-page.svelte +1 -1
  239. package/dist/components/ui/breadcrumb/breadcrumb-separator.svelte +2 -2
  240. package/dist/components/ui/button/button-variants.d.ts +9 -0
  241. package/dist/components/ui/button/button-variants.js +3 -0
  242. package/dist/components/ui/button/button.svelte +12 -31
  243. package/dist/components/ui/button/button.svelte.d.ts +9 -61
  244. package/dist/components/ui/card/card-action.svelte +1 -4
  245. package/dist/components/ui/card/card-content.svelte +1 -1
  246. package/dist/components/ui/card/card-description.svelte +1 -1
  247. package/dist/components/ui/card/card-footer.svelte +1 -1
  248. package/dist/components/ui/card/card-header.svelte +1 -4
  249. package/dist/components/ui/card/card-title.svelte +1 -1
  250. package/dist/components/ui/card/card.svelte +1 -1
  251. package/dist/components/ui/checkbox/checkbox.svelte +2 -5
  252. package/dist/components/ui/command/command-dialog.svelte +3 -3
  253. package/dist/components/ui/command/command-empty.svelte +1 -1
  254. package/dist/components/ui/command/command-group.svelte +2 -2
  255. package/dist/components/ui/command/command-input.svelte +1 -4
  256. package/dist/components/ui/command/command-item.svelte +1 -4
  257. package/dist/components/ui/command/command-list.svelte +1 -1
  258. package/dist/components/ui/command/command-separator.svelte +1 -1
  259. package/dist/components/ui/command/command.svelte +1 -4
  260. package/dist/components/ui/dialog/dialog-content.svelte +3 -3
  261. package/dist/components/ui/dialog/dialog-description.svelte +1 -1
  262. package/dist/components/ui/dialog/dialog-footer.svelte +1 -1
  263. package/dist/components/ui/dialog/dialog-header.svelte +1 -1
  264. package/dist/components/ui/dialog/dialog-overlay.svelte +1 -1
  265. package/dist/components/ui/dialog/dialog-title.svelte +1 -1
  266. package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte +2 -5
  267. package/dist/components/ui/dropdown-menu/dropdown-menu-content.svelte +1 -6
  268. package/dist/components/ui/dropdown-menu/dropdown-menu-item.svelte +3 -9
  269. package/dist/components/ui/dropdown-menu/dropdown-menu-separator.svelte +1 -1
  270. package/dist/components/ui/dropdown-menu/dropdown-menu.svelte +1 -1
  271. package/dist/components/ui/input/input.svelte +3 -2
  272. package/dist/components/ui/label/label.svelte +1 -4
  273. package/dist/components/ui/navigation-menu/navigation-menu-content.svelte +1 -5
  274. package/dist/components/ui/navigation-menu/navigation-menu-indicator.svelte +2 -5
  275. package/dist/components/ui/navigation-menu/navigation-menu-item.svelte +1 -1
  276. package/dist/components/ui/navigation-menu/navigation-menu-link.svelte +1 -4
  277. package/dist/components/ui/navigation-menu/navigation-menu-list.svelte +1 -1
  278. package/dist/components/ui/navigation-menu/navigation-menu-trigger.svelte +2 -5
  279. package/dist/components/ui/navigation-menu/navigation-menu-viewport.svelte +2 -5
  280. package/dist/components/ui/navigation-menu/navigation-menu.svelte +1 -1
  281. package/dist/components/ui/pagination/pagination-content.svelte +1 -1
  282. package/dist/components/ui/pagination/pagination-ellipsis.svelte +3 -3
  283. package/dist/components/ui/pagination/pagination-link.svelte +3 -0
  284. package/dist/components/ui/pagination/pagination-next.svelte +5 -2
  285. package/dist/components/ui/pagination/pagination-previous.svelte +5 -2
  286. package/dist/components/ui/pagination/pagination.svelte +1 -1
  287. package/dist/components/ui/popover/popover-content.svelte +1 -4
  288. package/dist/components/ui/progress/progress.svelte +2 -2
  289. package/dist/components/ui/scroll-area/scroll-area.svelte +3 -4
  290. package/dist/components/ui/select/select.svelte +1 -2
  291. package/dist/components/ui/separator/separator.svelte +1 -6
  292. package/dist/components/ui/sheet/sheet-content.svelte +1 -4
  293. package/dist/components/ui/sheet/sheet-description.svelte +1 -1
  294. package/dist/components/ui/sheet/sheet-footer.svelte +1 -1
  295. package/dist/components/ui/sheet/sheet-header.svelte +1 -1
  296. package/dist/components/ui/sheet/sheet-title.svelte +1 -1
  297. package/dist/components/ui/sheet/sheet.svelte +5 -10
  298. package/dist/components/ui/skeleton/skeleton.svelte +1 -1
  299. package/dist/components/ui/switch/switch.svelte +2 -9
  300. package/dist/components/ui/table/table-caption.svelte +1 -1
  301. package/dist/components/ui/table/table-cell.svelte +8 -11
  302. package/dist/components/ui/table/table-footer.svelte +1 -1
  303. package/dist/components/ui/table/table-head.svelte +1 -11
  304. package/dist/components/ui/table/table-header.svelte +1 -1
  305. package/dist/components/ui/table/table-row.svelte +2 -2
  306. package/dist/components/ui/table/table-row.svelte.d.ts +1 -1
  307. package/dist/components/ui/table/table.svelte +2 -2
  308. package/dist/components/ui/tabs/tabs-content.svelte +1 -1
  309. package/dist/components/ui/tabs/tabs-list.svelte +1 -4
  310. package/dist/components/ui/tabs/tabs-trigger.svelte +1 -7
  311. package/dist/components/ui/tabs/tabs.svelte +1 -1
  312. package/dist/components/ui/textarea/textarea.svelte +1 -4
  313. package/dist/components/ui/tooltip/tooltip-content.svelte +1 -1
  314. package/dist/page-chrome.css +228 -0
  315. package/package.json +12 -7
@@ -12,8 +12,8 @@
12
12
  const version = '__SVADMIN_VERSION__';
13
13
  </script>
14
14
 
15
- <div class="space-y-6">
16
- <div><h2 class="text-xl font-semibold text-foreground">{i18n.t('settings.about')}</h2></div>
15
+ <div class="svadmin-u-b3542e058833">
16
+ <div><h2 class="svadmin-u-d5c9b0001e7e svadmin-u-e83a7042bc91 svadmin-u-d4108abe6359">{i18n.t('settings.about')}</h2></div>
17
17
  <SettingsGroup title="svadmin" description={i18n.t('settings.currentEnvironment')} bodyClass="space-y-6">
18
18
  <DescriptionList columns={2} items={[
19
19
  { label: i18n.t('settings.version'), value: version },
@@ -21,13 +21,13 @@
21
21
  { label: i18n.t('settings.themeMode'), value: getResolvedTheme() },
22
22
  { label: i18n.t('settings.colorAccent'), value: getColorTheme() },
23
23
  ]} />
24
- <div class="border-t border-border pt-5">
25
- <h3 class="text-sm font-medium text-foreground">{i18n.t('settings.registeredResources')}</h3>
26
- <div class="mt-3 flex flex-wrap gap-2">{#each resources as resource (resource.name)}<Badge variant="outline" class="font-mono text-xs">{resource.name}</Badge>{:else}<span class="text-sm text-muted-foreground">—</span>{/each}</div>
24
+ <div class="svadmin-u-b950dda299d3 svadmin-u-18049387f0af svadmin-u-52be28846b5f">
25
+ <h3 class="svadmin-u-fc7473ca09eb svadmin-u-2689f3958069 svadmin-u-d4108abe6359">{i18n.t('settings.registeredResources')}</h3>
26
+ <div class="svadmin-u-eccd13ef4f2f svadmin-u-60fbb7713999 svadmin-u-1eb5c6df38c1 svadmin-u-77a2a20e90d4">{#each resources as resource (resource.name)}<Badge variant="outline" class="svadmin-u-0e65706bcccd svadmin-u-359090c2d529">{resource.name}</Badge>{:else}<span class="svadmin-u-fc7473ca09eb svadmin-u-bfa603190748">—</span>{/each}</div>
27
27
  </div>
28
- <div class="border-t border-border pt-5">
29
- <h3 class="text-sm font-medium text-foreground">{i18n.t('settings.dataProvider')}</h3>
30
- <div class="mt-3 flex flex-wrap gap-2">{#each providerNames as name (name)}<Badge variant="outline" class="font-mono text-xs">{name}</Badge>{:else}<span class="text-sm text-muted-foreground">—</span>{/each}</div>
28
+ <div class="svadmin-u-b950dda299d3 svadmin-u-18049387f0af svadmin-u-52be28846b5f">
29
+ <h3 class="svadmin-u-fc7473ca09eb svadmin-u-2689f3958069 svadmin-u-d4108abe6359">{i18n.t('settings.dataProvider')}</h3>
30
+ <div class="svadmin-u-eccd13ef4f2f svadmin-u-60fbb7713999 svadmin-u-1eb5c6df38c1 svadmin-u-77a2a20e90d4">{#each providerNames as name (name)}<Badge variant="outline" class="svadmin-u-0e65706bcccd svadmin-u-359090c2d529">{name}</Badge>{:else}<span class="svadmin-u-fc7473ca09eb svadmin-u-bfa603190748">—</span>{/each}</div>
31
31
  </div>
32
32
  </SettingsGroup>
33
33
  </div>
@@ -44,60 +44,45 @@
44
44
  isSending = false;
45
45
  }
46
46
  }
47
-
48
- function getStatusBadge(status?: ActivityItem['status']) {
49
- switch (status) {
50
- case 'success':
51
- return 'bg-success/15 text-success border-success/20';
52
- case 'warning':
53
- return 'bg-warning/15 text-warning-foreground border-warning/20';
54
- case 'destructive':
55
- return 'bg-destructive/15 text-destructive border-destructive/20';
56
- default:
57
- return 'bg-primary/10 text-primary border-primary/20';
58
- }
59
- }
60
47
  </script>
61
48
 
62
- <div class={cn('space-y-4 rounded-xl border border-border bg-card p-4 shadow-xs text-xs', className)}>
63
- <div class="flex items-center justify-between pb-2 border-b border-border/60">
64
- <h4 class="font-semibold text-foreground flex items-center gap-1.5">
65
- <MessageSquare class="h-4 w-4 text-primary" />
49
+ <div class={cn('svadmin-activity-feed', className)}>
50
+ <div class="svadmin-activity-feed__header">
51
+ <h4 class="svadmin-activity-feed__title">
52
+ <MessageSquare class="svadmin-activity-feed__icon" />
66
53
  Activity & Timeline Stream
67
54
  </h4>
68
- <span class="text-muted-foreground text-[11px]">{activities.length} event{activities.length === 1 ? '' : 's'}</span>
55
+ <span class="svadmin-activity-feed__count">{activities.length} event{activities.length === 1 ? '' : 's'}</span>
69
56
  </div>
70
57
 
71
- <!-- Timeline Stream -->
72
- <div class="relative space-y-4 pl-4 before:absolute before:left-1.5 before:top-2 before:bottom-2 before:w-0.5 before:bg-border/60">
58
+ <div class="svadmin-activity-feed__timeline">
73
59
  {#each activities as act (act.id)}
74
- <div class="relative flex items-start gap-3 group">
75
- <!-- Bullet dot -->
76
- <div class="absolute -left-4 top-1 h-3 w-3 rounded-full border-2 border-card bg-primary ring-2 ring-primary/20"></div>
60
+ <div class="svadmin-activity-feed__item">
61
+ <div class="svadmin-activity-feed__dot"></div>
77
62
 
78
- <div class="flex-1 space-y-1.5">
79
- <div class="flex flex-wrap items-center justify-between gap-1">
80
- <div class="flex items-center gap-1.5">
81
- <span class="font-semibold text-foreground">{act.user?.name ?? 'System'}</span>
82
- <span class="text-muted-foreground">{act.action}</span>
63
+ <div class="svadmin-activity-feed__body">
64
+ <div class="svadmin-activity-feed__meta">
65
+ <div class="svadmin-activity-feed__summary">
66
+ <span class="svadmin-activity-feed__user">{act.user?.name ?? 'System'}</span>
67
+ <span class="svadmin-activity-feed__action">{act.action}</span>
83
68
  {#if act.target}
84
- <strong class="text-foreground">{act.target}</strong>
69
+ <strong class="svadmin-activity-feed__target">{act.target}</strong>
85
70
  {/if}
86
71
  {#if act.status}
87
- <Badge variant="outline" class={cn('text-[10px] px-1 py-0', getStatusBadge(act.status))}>
72
+ <Badge variant="outline" data-status={act.status}>
88
73
  {act.status}
89
74
  </Badge>
90
75
  {/if}
91
76
  </div>
92
77
 
93
- <div class="flex items-center gap-1 text-[11px] text-muted-foreground">
94
- <Clock class="h-3 w-3" />
78
+ <div class="svadmin-activity-feed__timestamp">
79
+ <Clock class="svadmin-activity-feed__timestamp-icon" />
95
80
  <span>{act.timestamp}</span>
96
81
  </div>
97
82
  </div>
98
83
 
99
84
  {#if act.comment}
100
- <div class="rounded-lg bg-muted/40 p-2.5 text-foreground border border-border/40 font-normal">
85
+ <div class="svadmin-activity-feed__comment">
101
86
  {act.comment}
102
87
  </div>
103
88
  {/if}
@@ -106,7 +91,7 @@
106
91
  {/each}
107
92
 
108
93
  {#if activities.length === 0}
109
- <div class="py-6 text-center text-muted-foreground">
94
+ <div class="svadmin-activity-feed__empty">
110
95
  No recent activities
111
96
  </div>
112
97
  {/if}
@@ -114,18 +99,18 @@
114
99
 
115
100
  <!-- Add Comment Box -->
116
101
  {#if allowComment && onaddcomment}
117
- <div class="pt-3 border-t border-border/60 space-y-2">
102
+ <div class="svadmin-activity-feed__composer">
118
103
  <textarea
119
104
  bind:value={newComment}
120
105
  placeholder="Add an internal comment or update note..."
121
- class="w-full h-16 rounded-md border border-input bg-background p-2 text-xs focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
106
+ class="svadmin-activity-feed__textarea"
122
107
  ></textarea>
123
- <div class="flex justify-end">
124
- <Button size="sm" class="h-7 text-xs gap-1" disabled={isSending || !newComment.trim()} onclick={handleSend}>
108
+ <div class="svadmin-activity-feed__send">
109
+ <Button size="sm" class="svadmin-activity-feed__send-button" disabled={isSending || !newComment.trim()} onclick={handleSend}>
125
110
  {#if isSending}
126
- <Loader2 class="h-3.5 w-3.5 animate-spin" />
111
+ <Loader2 class="svadmin-activity-feed__send-icon svadmin-activity-feed__send-icon--loading" />
127
112
  {:else}
128
- <Send class="h-3.5 w-3.5" />
113
+ <Send class="svadmin-activity-feed__send-icon" />
129
114
  {/if}
130
115
  Send Comment
131
116
  </Button>
@@ -517,10 +517,10 @@
517
517
  {#if !resolvedDataProvider}
518
518
  <ConfigErrorScreen title="{title} — DataProvider is required" />
519
519
  {:else if !authChecked || authProviderPending}
520
- <div class="flex h-screen items-center justify-center">
521
- <div class="space-y-4 text-center">
522
- <div class="h-8 w-8 animate-spin rounded-full border-4 border-muted border-t-primary mx-auto"></div>
523
- <p class="text-sm text-muted-foreground">Loading...</p>
520
+ <div class="svadmin-u-60fbb7713999 svadmin-u-ef114b5f5ad1 svadmin-u-3960ffc248d9 svadmin-u-86843cf1e227">
521
+ <div class="svadmin-u-3e7ce58d64fa svadmin-u-ca6bf63030aa">
522
+ <div class="svadmin-u-ed8a5df7b2fb svadmin-u-2bbcfc3b5179 svadmin-u-afbdd13a380e svadmin-u-ac204c108886 svadmin-u-b485ae1c3b47 svadmin-u-da2c5d419684 svadmin-u-8a5560925d62 svadmin-u-0e12dc7de920"></div>
523
+ <p class="svadmin-u-fc7473ca09eb svadmin-u-bfa603190748">Loading...</p>
524
524
  </div>
525
525
  </div>
526
526
  {:else if route === '/login' && loginPage}
@@ -552,12 +552,12 @@
552
552
  </SystemPageShell>
553
553
  {:else if isAuthenticated || !resolvedAuthProvider}
554
554
  <Layout {title} {menu} {siteUrl} routeMode={resolvedRouteMode} {aiAssistant}>
555
- <div class="relative min-h-40" aria-busy={authRechecking}>
555
+ <div class="svadmin-u-d89972fe17d6 svadmin-u-8a7a926578c8" aria-busy={authRechecking}>
556
556
  {#if authRechecking}
557
- <div class="absolute inset-0 z-10 flex min-h-40 items-center justify-center bg-background/80" role="status" aria-live="polite">
558
- <div class="space-y-3 text-center">
559
- <div class="h-6 w-6 animate-spin rounded-full border-4 border-muted border-t-primary mx-auto"></div>
560
- <p class="text-sm text-muted-foreground">Loading...</p>
557
+ <div class="svadmin-u-da4dbfbc4fdc svadmin-u-7b7df0449b80 svadmin-u-236812d64c82 svadmin-u-60fbb7713999 svadmin-u-8a7a926578c8 svadmin-u-3960ffc248d9 svadmin-u-86843cf1e227 svadmin-u-d542b60b5312" role="status" aria-live="polite">
558
+ <div class="svadmin-u-6ed543e2fbbb svadmin-u-ca6bf63030aa">
559
+ <div class="svadmin-u-f6fe902450dc svadmin-u-7ec10f86d9b1 svadmin-u-afbdd13a380e svadmin-u-ac204c108886 svadmin-u-b485ae1c3b47 svadmin-u-da2c5d419684 svadmin-u-8a5560925d62 svadmin-u-0e12dc7de920"></div>
560
+ <p class="svadmin-u-fc7473ca09eb svadmin-u-bfa603190748">Loading...</p>
561
561
  </div>
562
562
  </div>
563
563
  {:else}
@@ -605,9 +605,9 @@
605
605
  {#if dashboard}
606
606
  {@render dashboard()}
607
607
  {:else}
608
- <div class="space-y-4">
609
- <h1 class="text-xl font-semibold text-foreground">{translation.t('common.welcome', { title })}</h1>
610
- <p class="text-muted-foreground">{translation.t('common.dashboardHint')}</p>
608
+ <div class="svadmin-u-3e7ce58d64fa">
609
+ <h1 class="svadmin-u-d5c9b0001e7e svadmin-u-e83a7042bc91 svadmin-u-d4108abe6359">{translation.t('common.welcome', { title })}</h1>
610
+ <p class="svadmin-u-bfa603190748">{translation.t('common.dashboardHint')}</p>
611
611
  </div>
612
612
  {/if}
613
613
  {:else if (renderedRoute === '/:resource' || renderedRoute === '/:parent/:parentId/:resource') && renderedHasRouteResource}
@@ -655,8 +655,8 @@
655
655
  </div>
656
656
  </Layout>
657
657
  {:else}
658
- <div class="flex h-screen items-center justify-center">
659
- <p class="text-muted-foreground">{translation.t('common.redirecting')}</p>
658
+ <div class="svadmin-u-60fbb7713999 svadmin-u-ef114b5f5ad1 svadmin-u-3960ffc248d9 svadmin-u-86843cf1e227">
659
+ <p class="svadmin-u-bfa603190748">{translation.t('common.redirecting')}</p>
660
660
  </div>
661
661
  {/if}
662
662
  <Toast />
@@ -47,7 +47,7 @@
47
47
  </script>
48
48
 
49
49
  {#if !isAnomaly}
50
- <span class="text-muted-foreground text-sm font-medium tabular-nums {className}">
50
+ <span class="svadmin-anomaly-badge__value {className}">
51
51
  {formatter(value)}
52
52
  </span>
53
53
  {:else}
@@ -55,17 +55,18 @@
55
55
  tooltip={`Baseline: ${formatter(baseline)} (${diff > 0 ? '+' : '-'}${percentLabel})`}
56
56
  variant="ghost"
57
57
  size="sm"
58
- class="p-0 h-auto hover:bg-transparent"
58
+ class="svadmin-anomaly-badge__trigger"
59
59
  aria-label={anomalyAriaLabel}
60
60
  >
61
61
  <Badge
62
62
  variant={isGood ? 'default' : 'destructive'}
63
- class="flex items-center gap-1 font-mono text-xs tabular-nums px-1.5 py-0 {isGood ? 'bg-success hover:bg-success/90 text-success-foreground' : ''} {className}"
63
+ class="svadmin-anomaly-badge {className}"
64
+ data-good={isGood === true ? 'true' : 'false'}
64
65
  >
65
66
  {#if diff > 0}
66
- <TrendingUp class="h-3 w-3" aria-hidden="true" />
67
+ <TrendingUp class="svadmin-anomaly-badge__icon" aria-hidden="true" />
67
68
  {:else}
68
- <TrendingDown class="h-3 w-3" aria-hidden="true" />
69
+ <TrendingDown class="svadmin-anomaly-badge__icon" aria-hidden="true" />
69
70
  {/if}
70
71
  {formatter(value)}
71
72
  </Badge>
@@ -160,26 +160,26 @@
160
160
  <WorkspaceLayout secondaryWidth="21rem">
161
161
  {#snippet summary()}
162
162
  {#if generatedSecret}
163
- <section class="rounded-lg border border-primary/20 bg-primary/5 p-4" role="status" aria-live="polite">
164
- <div class="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between"><div class="flex min-w-0 items-start gap-3"><ShieldCheck class="mt-0.5 size-5 shrink-0 text-primary" /><div class="min-w-0"><h2 class="text-sm font-semibold text-foreground">{i18n.t('api.successTitle')}</h2><p class="mt-1 text-sm text-muted-foreground">{i18n.t('api.successHint')}</p></div></div><Button variant="ghost" size="sm" onclick={() => { generatedSecret = ''; copied = false; }}>{i18n.t('common.close')}</Button></div>
165
- <div class="mt-4 flex min-w-0 items-center gap-2"><Input readonly value={generatedSecret} class="min-w-0 font-mono text-xs" aria-label={i18n.t('api.successTitle')} /><Button size="icon" onclick={copySecret} aria-label={i18n.t('common.copy')}>{#if copied}<Check class="size-4" />{:else}<Copy class="size-4" />{/if}</Button></div>
163
+ <section class="svadmin-u-5f22e64f2282 svadmin-u-ca6bcd4b6f3f svadmin-u-a6afccfc915b svadmin-u-989c466fdbe7 svadmin-u-8e63407b5ceb" role="status" aria-live="polite">
164
+ <div class="svadmin-u-60fbb7713999 svadmin-u-8dddea0773ed svadmin-u-0c3bc98565dd svadmin-u-020ba687fa12 svadmin-u-9f76a62f4f44 svadmin-u-3b9871a0bf93"><div class="svadmin-u-60fbb7713999 svadmin-u-7e0b7cdf1a94 svadmin-u-60541e1e26f8 svadmin-u-1004c0c3954c"><ShieldCheck class="svadmin-u-15e1b1f444fe svadmin-u-add63bc6753d svadmin-u-012fbd121f37 svadmin-u-20aaf08a7ed1" /><div class="svadmin-u-7e0b7cdf1a94"><h2 class="svadmin-u-fc7473ca09eb svadmin-u-e83a7042bc91 svadmin-u-d4108abe6359">{i18n.t('api.successTitle')}</h2><p class="svadmin-u-b6b02c0ebef6 svadmin-u-fc7473ca09eb svadmin-u-bfa603190748">{i18n.t('api.successHint')}</p></div></div><Button variant="ghost" size="sm" onclick={() => { generatedSecret = ''; copied = false; }}>{i18n.t('common.close')}</Button></div>
165
+ <div class="svadmin-u-0ab8667228fd svadmin-u-60fbb7713999 svadmin-u-7e0b7cdf1a94 svadmin-u-3960ffc248d9 svadmin-u-77a2a20e90d4"><Input readonly value={generatedSecret} class="svadmin-u-7e0b7cdf1a94 svadmin-u-0e65706bcccd svadmin-u-359090c2d529" aria-label={i18n.t('api.successTitle')} /><Button size="icon" onclick={copySecret} aria-label={i18n.t('common.copy')}>{#if copied}<Check class="svadmin-u-f7b5fa971871" />{:else}<Copy class="svadmin-u-f7b5fa971871" />{/if}</Button></div>
166
166
  </section>
167
167
  {/if}
168
168
  {/snippet}
169
169
  {#snippet primary()}
170
- <div class="space-y-6">
170
+ <div class="svadmin-u-b3542e058833">
171
171
  <SettingsGroup title={i18n.t('api.activeKeysTitle')} description={i18n.t('api.activeKeysDesc')} bodyClass="p-0">
172
- {#if loading}<DataState state="loading" />{:else if error}<DataState state="error" description={error} retry={loadCredentials} />{:else}<ApiKeyList class="rounded-none border-0" keys={keys.map((key) => ({ id: key.id, name: key.name, prefix: key.prefix, createdAt: new Date(key.createdAt).toLocaleString(), lastUsedAt: key.lastUsedAt ? new Date(key.lastUsedAt).toLocaleString() : undefined, permissions: key.permissions }))} stateTitle={i18n.t('api.noKeys')} stateDescription={credentialProvider ? i18n.t('api.generateDesc') : (isZh ? '配置 CredentialProvider 后可管理真实凭据。' : 'Configure CredentialProvider to manage real credentials.')} onrevoke={credentialProvider ? (key) => revokeKey(key.id) : undefined} />{/if}
172
+ {#if loading}<DataState state="loading" />{:else if error}<DataState state="error" description={error} retry={loadCredentials} />{:else}<ApiKeyList class="svadmin-u-0c5e9137c7de svadmin-u-119b2aa0b8f6" keys={keys.map((key) => ({ id: key.id, name: key.name, prefix: key.prefix, createdAt: new Date(key.createdAt).toLocaleString(), lastUsedAt: key.lastUsedAt ? new Date(key.lastUsedAt).toLocaleString() : undefined, permissions: key.permissions }))} stateTitle={i18n.t('api.noKeys')} stateDescription={credentialProvider ? i18n.t('api.generateDesc') : (isZh ? '配置 CredentialProvider 后可管理真实凭据。' : 'Configure CredentialProvider to manage real credentials.')} onrevoke={credentialProvider ? (key) => revokeKey(key.id) : undefined} />{/if}
173
173
  </SettingsGroup>
174
174
  <SettingsGroup title={i18n.t('api.webhooks')} description={i18n.t('api.webhooksDesc')} bodyClass="space-y-5">
175
- <form class="grid min-w-0 gap-4 md:grid-cols-2" onsubmit={handleAddWebhook}><div class="space-y-2"><Label for="webhook-name">{i18n.t('api.webhookName')}</Label><Input id="webhook-name" bind:value={newWebhookName} placeholder="Order Events" disabled={!credentialProvider || submitting} /></div><div class="space-y-2 md:col-span-2"><Label for="webhook-url">{i18n.t('api.webhookUrl')}</Label><Input id="webhook-url" type="url" bind:value={newWebhookUrl} placeholder="https://api.example.com/hooks" disabled={!credentialProvider || submitting} /></div><div class="space-y-2"><Label for="webhook-event">{i18n.t('api.eventType')}</Label><select id="webhook-event" bind:value={newWebhookEvent} disabled={!credentialProvider || submitting} class="flex h-9 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:opacity-50"><option value="resource.created">resource.created</option><option value="resource.updated">resource.updated</option><option value="resource.deleted">resource.deleted</option><option value="auth.login">auth.login</option></select></div><div class="flex items-end"><Button type="submit" class="w-full" disabled={!credentialProvider || submitting || !newWebhookName.trim() || !newWebhookUrl.trim()}><Plus class="size-4" />{i18n.t('api.addWebhook')}</Button></div></form>
176
- {#if webhooks.length === 0}<DataState state="empty" title={i18n.t('api.noWebhooks')} description={credentialProvider ? i18n.t('api.webhooksDesc') : (isZh ? '配置 CredentialProvider 后可管理真实 Webhook。' : 'Configure CredentialProvider to manage real webhooks.')} />{:else}<div class="divide-y divide-border border-t border-border">{#each webhooks as hook (hook.id)}<div class="flex flex-col gap-3 py-4 sm:flex-row sm:items-center sm:justify-between"><div class="min-w-0"><p class="text-sm font-medium text-foreground">{hook.name}</p><p class="truncate font-mono text-xs text-muted-foreground">{hook.url}</p></div><div class="flex items-center justify-between gap-3 sm:justify-end"><span class="rounded bg-muted px-2 py-1 font-mono text-xs text-muted-foreground">{hook.eventType}</span><Button variant="ghost" size="icon-sm" onclick={() => deleteWebhook(hook.id)} aria-label={i18n.t('common.delete') + ' ' + hook.name}><Trash2 class="size-4" /></Button></div></div>{/each}</div>{/if}
175
+ <form class="svadmin-u-f3c543ad5fe9 svadmin-u-7e0b7cdf1a94 svadmin-u-0c3bc98565dd svadmin-u-e4d6f343b9ff" onsubmit={handleAddWebhook}><div class="svadmin-u-6f7e013d6499"><Label for="webhook-name">{i18n.t('api.webhookName')}</Label><Input id="webhook-name" bind:value={newWebhookName} placeholder="Order Events" disabled={!credentialProvider || submitting} /></div><div class="svadmin-u-6f7e013d6499 svadmin-u-eea04c60c0ca"><Label for="webhook-url">{i18n.t('api.webhookUrl')}</Label><Input id="webhook-url" type="url" bind:value={newWebhookUrl} placeholder="https://api.example.com/hooks" disabled={!credentialProvider || submitting} /></div><div class="svadmin-u-6f7e013d6499"><Label for="webhook-event">{i18n.t('api.eventType')}</Label><select id="webhook-event" bind:value={newWebhookEvent} disabled={!credentialProvider || submitting} class="svadmin-u-60fbb7713999 svadmin-u-e7a768f922d2 svadmin-u-6da6a3c3f741 svadmin-u-421ac2be5045 svadmin-u-ca6bcd4b6f3f svadmin-u-e5795dad4d22 svadmin-u-e6f9e383a762 svadmin-u-0e17f2bd9074 svadmin-u-03b4dd7f172b svadmin-u-fc7473ca09eb svadmin-u-582e6ef4b245 svadmin-u-55d048ebfb1c svadmin-u-608dd26cd5ba svadmin-u-80b9d0ae125f svadmin-u-6b22a22a9752 svadmin-u-b29d8adbad2e"><option value="resource.created">resource.created</option><option value="resource.updated">resource.updated</option><option value="resource.deleted">resource.deleted</option><option value="auth.login">auth.login</option></select></div><div class="svadmin-u-60fbb7713999 svadmin-u-6f27f4f79e55"><Button type="submit" class="svadmin-u-6da6a3c3f741" disabled={!credentialProvider || submitting || !newWebhookName.trim() || !newWebhookUrl.trim()}><Plus class="svadmin-u-f7b5fa971871" />{i18n.t('api.addWebhook')}</Button></div></form>
176
+ {#if webhooks.length === 0}<DataState state="empty" title={i18n.t('api.noWebhooks')} description={credentialProvider ? i18n.t('api.webhooksDesc') : (isZh ? '配置 CredentialProvider 后可管理真实 Webhook。' : 'Configure CredentialProvider to manage real webhooks.')} />{:else}<div class="svadmin-u-fa6acbf81d74 svadmin-u-e783642739e3 svadmin-u-b950dda299d3 svadmin-u-18049387f0af">{#each webhooks as hook (hook.id)}<div class="svadmin-u-60fbb7713999 svadmin-u-8dddea0773ed svadmin-u-1004c0c3954c svadmin-u-cb11fec3bb46 svadmin-u-020ba687fa12 svadmin-u-9f76a62f4f44 svadmin-u-3b9871a0bf93"><div class="svadmin-u-7e0b7cdf1a94"><p class="svadmin-u-fc7473ca09eb svadmin-u-2689f3958069 svadmin-u-d4108abe6359">{hook.name}</p><p class="svadmin-u-f283ea9bea0e svadmin-u-0e65706bcccd svadmin-u-359090c2d529 svadmin-u-bfa603190748">{hook.url}</p></div><div class="svadmin-u-60fbb7713999 svadmin-u-3960ffc248d9 svadmin-u-8ef2268efbbc svadmin-u-1004c0c3954c svadmin-u-1f51d781e606"><span class="svadmin-u-07389a777c1f svadmin-u-2ef11f1cb219 svadmin-u-d5eab218aa34 svadmin-u-660d2effb880 svadmin-u-0e65706bcccd svadmin-u-359090c2d529 svadmin-u-bfa603190748">{hook.eventType}</span><Button variant="ghost" size="icon-sm" onclick={() => deleteWebhook(hook.id)} aria-label={i18n.t('common.delete') + ' ' + hook.name}><Trash2 class="svadmin-u-f7b5fa971871" /></Button></div></div>{/each}</div>{/if}
177
177
  </SettingsGroup>
178
178
  </div>
179
179
  {/snippet}
180
180
  {#snippet secondary()}
181
181
  <SettingsGroup title={i18n.t('api.generateTitle')} description={i18n.t('api.generateDesc')}>
182
- <form onsubmit={handleGenerateKey} class="space-y-5"><div class="space-y-2"><Label for="api-key-name">{i18n.t('api.keyName')}</Label><Input id="api-key-name" placeholder="CI deployment token" bind:value={newKeyName} required disabled={!credentialProvider || submitting} /></div><fieldset class="space-y-3" disabled={!credentialProvider || submitting}><legend class="text-sm font-medium text-foreground">{i18n.t('api.permissions')}</legend>{#each Object.keys(newKeyPermissions) as permission (permission)}<div class="flex items-center gap-2"><Checkbox id={`perm-${permission}`} bind:checked={newKeyPermissions[permission as keyof typeof newKeyPermissions]} /><Label for={`perm-${permission}`} class="cursor-pointer text-sm font-normal">{permission}</Label></div>{/each}</fieldset><Button type="submit" class="w-full" disabled={!credentialProvider || submitting || !newKeyName.trim()}>{i18n.t('api.generateButton')}</Button></form>
182
+ <form onsubmit={handleGenerateKey} class="svadmin-u-b43b4c086d9a"><div class="svadmin-u-6f7e013d6499"><Label for="api-key-name">{i18n.t('api.keyName')}</Label><Input id="api-key-name" placeholder="CI deployment token" bind:value={newKeyName} required disabled={!credentialProvider || submitting} /></div><fieldset class="svadmin-u-6ed543e2fbbb" disabled={!credentialProvider || submitting}><legend class="svadmin-u-fc7473ca09eb svadmin-u-2689f3958069 svadmin-u-d4108abe6359">{i18n.t('api.permissions')}</legend>{#each Object.keys(newKeyPermissions) as permission (permission)}<div class="svadmin-u-60fbb7713999 svadmin-u-3960ffc248d9 svadmin-u-77a2a20e90d4"><Checkbox id={`perm-${permission}`} bind:checked={newKeyPermissions[permission as keyof typeof newKeyPermissions]} /><Label for={`perm-${permission}`} class="svadmin-u-34516836730d svadmin-u-fc7473ca09eb svadmin-u-8ecebc9f80e6">{permission}</Label></div>{/each}</fieldset><Button type="submit" class="svadmin-u-6da6a3c3f741" disabled={!credentialProvider || submitting || !newKeyName.trim()}>{i18n.t('api.generateButton')}</Button></form>
183
183
  </SettingsGroup>
184
184
  {/snippet}
185
185
  </WorkspaceLayout>
@@ -26,33 +26,33 @@
26
26
  function setPageSize(size: number) { pageSize = size; if (typeof window !== 'undefined') localStorage.setItem(PAGE_SIZE_KEY, String(size)); }
27
27
  </script>
28
28
 
29
- <div class="space-y-6">
30
- <div><h2 class="text-xl font-semibold text-foreground">{i18n.t('settings.appearance')}</h2><p class="mt-1 text-sm text-muted-foreground">{i18n.t('settings.settingsDescription')}</p></div>
29
+ <div class="svadmin-u-b3542e058833">
30
+ <div><h2 class="svadmin-u-d5c9b0001e7e svadmin-u-e83a7042bc91 svadmin-u-d4108abe6359">{i18n.t('settings.appearance')}</h2><p class="svadmin-u-b6b02c0ebef6 svadmin-u-fc7473ca09eb svadmin-u-bfa603190748">{i18n.t('settings.settingsDescription')}</p></div>
31
31
  <SettingsGroup title={i18n.t('settings.themeMode')}>
32
- <div class="grid grid-cols-3 gap-3">
32
+ <div class="svadmin-u-f3c543ad5fe9 svadmin-u-be2e831be5dd svadmin-u-1004c0c3954c">
33
33
  {#each themeOptions as option (option.value)}
34
34
  {@const active = currentTheme === option.value}
35
- <button class="relative flex min-w-0 flex-col items-center gap-2 rounded-lg border p-4 transition-colors {active ? 'border-primary bg-primary/5' : 'border-border hover:bg-accent/50'}" onclick={() => setTheme(option.value)} aria-pressed={active}>
36
- {#if active}<Check class="absolute right-2 top-2 size-3.5 text-primary" />{/if}
37
- <span class="flex size-10 items-center justify-center rounded-md {active ? 'bg-primary/10 text-primary' : 'bg-muted text-muted-foreground'}"><option.icon class="size-5" /></span>
38
- <span class="truncate text-xs font-medium {active ? 'text-primary' : 'text-muted-foreground'}">{i18n.t(option.label)}</span>
35
+ <button class="svadmin-u-d89972fe17d6 svadmin-u-60fbb7713999 svadmin-u-7e0b7cdf1a94 svadmin-u-8dddea0773ed svadmin-u-3960ffc248d9 svadmin-u-77a2a20e90d4 svadmin-u-5f22e64f2282 svadmin-u-ca6bcd4b6f3f svadmin-u-8e63407b5ceb svadmin-u-ceb69a6b0e5f {active ? 'svadmin-u-6cbc84dd9e1a svadmin-u-989c466fdbe7' : 'svadmin-u-18049387f0af svadmin-u-c7824f6076ea'}" onclick={() => setTheme(option.value)} aria-pressed={active}>
36
+ {#if active}<Check class="svadmin-u-da4dbfbc4fdc svadmin-u-7b2d63937d23 svadmin-u-9a2db8f949b6 svadmin-u-783b0d9d1e2c svadmin-u-20aaf08a7ed1" />{/if}
37
+ <span class="svadmin-u-60fbb7713999 svadmin-u-7bbb00f9ba7a svadmin-u-3960ffc248d9 svadmin-u-86843cf1e227 svadmin-u-421ac2be5045 {active ? 'svadmin-u-375dc44df6e9 svadmin-u-20aaf08a7ed1' : 'svadmin-u-2ef11f1cb219 svadmin-u-bfa603190748'}"><option.icon class="svadmin-u-add63bc6753d" /></span>
38
+ <span class="svadmin-u-f283ea9bea0e svadmin-u-359090c2d529 svadmin-u-2689f3958069 {active ? 'svadmin-u-20aaf08a7ed1' : 'svadmin-u-bfa603190748'}">{i18n.t(option.label)}</span>
39
39
  </button>
40
40
  {/each}
41
41
  </div>
42
42
  </SettingsGroup>
43
43
  <SettingsGroup title={i18n.t('settings.colorAccent')}>
44
- <div class="flex flex-wrap gap-3">
44
+ <div class="svadmin-u-60fbb7713999 svadmin-u-1eb5c6df38c1 svadmin-u-1004c0c3954c">
45
45
  {#each presets as preset (preset.name)}
46
46
  {@const active = currentColor === preset.name}
47
- <button class="relative size-9 rounded-full border border-border transition-opacity {active ? 'ring-2 ring-primary ring-offset-2 ring-offset-background' : 'opacity-70 hover:opacity-100'}" style="background-color: {preset.color}" onclick={() => setColorTheme(preset.name as Parameters<typeof setColorTheme>[0])} aria-label={preset.label} aria-pressed={active}>{#if active}<Check class="absolute inset-0 m-auto size-4 text-white drop-shadow-sm" />{/if}</button>
47
+ <button class="svadmin-u-d89972fe17d6 svadmin-u-665f07fe73cc svadmin-u-ac204c108886 svadmin-u-ca6bcd4b6f3f svadmin-u-18049387f0af svadmin-u-67d6184a0024 {active ? 'svadmin-u-16b1efa5875e svadmin-u-fd1dda07320a svadmin-u-0c15f6cff5a0 svadmin-u-582e6ef4b245' : 'svadmin-u-0c67ca474a69 svadmin-u-5da1d5250e75'}" style="background-color: {preset.color}" onclick={() => setColorTheme(preset.name as Parameters<typeof setColorTheme>[0])} aria-label={preset.label} aria-pressed={active}>{#if active}<Check class="svadmin-u-da4dbfbc4fdc svadmin-u-7b7df0449b80 svadmin-u-e12dfd448aa6 svadmin-u-f7b5fa971871 svadmin-u-72a4c7cdeef7 drop-shadow-sm" />{/if}</button>
48
48
  {/each}
49
49
  </div>
50
50
  </SettingsGroup>
51
51
  <SettingsGroup title={i18n.t('settings.interface')}>
52
- <div class="divide-y divide-border">
53
- <SettingsFieldRow label={i18n.t('settings.language')} description={localeNames[currentLocale] ?? currentLocale}>{#snippet control()}<select class="h-9 max-w-44 rounded-md border border-input bg-background px-3 text-sm ring-offset-background focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2" value={currentLocale} onchange={(event) => i18n.setLocale((event.target as HTMLSelectElement).value)}>{#each availableLocales as locale (locale)}<option value={locale}>{localeNames[locale] ?? locale}</option>{/each}</select>{/snippet}</SettingsFieldRow>
54
- <SettingsFieldRow label={i18n.t('settings.sidebarDensity')}>{#snippet control()}<div class="flex overflow-hidden rounded-md border border-input"><button class="px-3 py-1.5 text-xs font-medium {density === 'compact' ? 'bg-primary text-primary-foreground' : 'bg-background text-muted-foreground hover:bg-accent'}" onclick={() => setDensity('compact')}>{i18n.t('settings.compact')}</button><button class="px-3 py-1.5 text-xs font-medium {density === 'standard' ? 'bg-primary text-primary-foreground' : 'bg-background text-muted-foreground hover:bg-accent'}" onclick={() => setDensity('standard')}>{i18n.t('settings.standard')}</button></div>{/snippet}</SettingsFieldRow>
55
- <SettingsFieldRow label={i18n.t('settings.defaultPageSize')}>{#snippet control()}<div class="flex overflow-hidden rounded-md border border-input">{#each pageSizeOptions as size (size)}<button class="px-3 py-1.5 font-mono text-xs font-medium {pageSize === size ? 'bg-primary text-primary-foreground' : 'bg-background text-muted-foreground hover:bg-accent'}" onclick={() => setPageSize(size)}>{size}</button>{/each}</div>{/snippet}</SettingsFieldRow>
52
+ <div class="svadmin-u-fa6acbf81d74 svadmin-u-e783642739e3">
53
+ <SettingsFieldRow label={i18n.t('settings.language')} description={localeNames[currentLocale] ?? currentLocale}>{#snippet control()}<select class="svadmin-u-e7a768f922d2 svadmin-u-3713c4c7843d svadmin-u-421ac2be5045 svadmin-u-ca6bcd4b6f3f svadmin-u-e5795dad4d22 svadmin-u-e6f9e383a762 svadmin-u-0e17f2bd9074 svadmin-u-fc7473ca09eb svadmin-u-582e6ef4b245 svadmin-u-55d048ebfb1c svadmin-u-608dd26cd5ba svadmin-u-80b9d0ae125f svadmin-u-6b22a22a9752" value={currentLocale} onchange={(event) => i18n.setLocale((event.target as HTMLSelectElement).value)}>{#each availableLocales as locale (locale)}<option value={locale}>{localeNames[locale] ?? locale}</option>{/each}</select>{/snippet}</SettingsFieldRow>
54
+ <SettingsFieldRow label={i18n.t('settings.sidebarDensity')}>{#snippet control()}<div class="svadmin-u-60fbb7713999 svadmin-u-2cd02d11d1af svadmin-u-421ac2be5045 svadmin-u-ca6bcd4b6f3f svadmin-u-e5795dad4d22"><button class="svadmin-u-0e17f2bd9074 svadmin-u-ec0091ee009b svadmin-u-359090c2d529 svadmin-u-2689f3958069 {density === 'compact' ? 'svadmin-u-75b1bec3ea0e svadmin-u-30ca335ae9c2' : 'svadmin-u-e6f9e383a762 svadmin-u-bfa603190748 svadmin-u-0557b88819cd'}" onclick={() => setDensity('compact')}>{i18n.t('settings.compact')}</button><button class="svadmin-u-0e17f2bd9074 svadmin-u-ec0091ee009b svadmin-u-359090c2d529 svadmin-u-2689f3958069 {density === 'standard' ? 'svadmin-u-75b1bec3ea0e svadmin-u-30ca335ae9c2' : 'svadmin-u-e6f9e383a762 svadmin-u-bfa603190748 svadmin-u-0557b88819cd'}" onclick={() => setDensity('standard')}>{i18n.t('settings.standard')}</button></div>{/snippet}</SettingsFieldRow>
55
+ <SettingsFieldRow label={i18n.t('settings.defaultPageSize')}>{#snippet control()}<div class="svadmin-u-60fbb7713999 svadmin-u-2cd02d11d1af svadmin-u-421ac2be5045 svadmin-u-ca6bcd4b6f3f svadmin-u-e5795dad4d22">{#each pageSizeOptions as size (size)}<button class="svadmin-u-0e17f2bd9074 svadmin-u-ec0091ee009b svadmin-u-0e65706bcccd svadmin-u-359090c2d529 svadmin-u-2689f3958069 {pageSize === size ? 'svadmin-u-75b1bec3ea0e svadmin-u-30ca335ae9c2' : 'svadmin-u-e6f9e383a762 svadmin-u-bfa603190748 svadmin-u-0557b88819cd'}" onclick={() => setPageSize(size)}>{size}</button>{/each}</div>{/snippet}</SettingsFieldRow>
56
56
  </div>
57
57
  </SettingsGroup>
58
58
  </div>
@@ -51,13 +51,13 @@
51
51
  const statusConfig = $derived.by(() => {
52
52
  switch (status) {
53
53
  case 'approved':
54
- return { label: 'Approved', badge: 'bg-success/15 text-success border-success/20', icon: CheckCircle2 };
54
+ return { label: 'Approved', icon: CheckCircle2 };
55
55
  case 'rejected':
56
- return { label: 'Rejected', badge: 'bg-destructive/15 text-destructive border-destructive/20', icon: XCircle };
56
+ return { label: 'Rejected', icon: XCircle };
57
57
  case 'recalled':
58
- return { label: 'Recalled', badge: 'bg-muted text-muted-foreground border-border', icon: Undo2 };
58
+ return { label: 'Recalled', icon: Undo2 };
59
59
  default:
60
- return { label: 'Pending Approval', badge: 'bg-warning/15 text-warning-foreground border-warning/20', icon: Clock };
60
+ return { label: 'Pending Approval', icon: Clock };
61
61
  }
62
62
  });
63
63
 
@@ -97,19 +97,19 @@
97
97
  }
98
98
  </script>
99
99
 
100
- <div class={cn('rounded-xl border border-border bg-card p-4 shadow-xs space-y-3', className)}>
101
- <div class="flex flex-wrap items-center justify-between gap-2 pb-3 border-b border-border/50">
102
- <div class="space-y-0.5">
103
- <div class="flex items-center gap-2">
104
- <h4 class="text-sm font-semibold text-foreground">{title}</h4>
105
- <Badge variant="outline" class={cn('gap-1 text-[11px] font-medium', statusConfig.badge)}>
106
- <statusConfig.icon class="h-3 w-3" />
100
+ <div class={cn('svadmin-approval-card', className)} data-status={status}>
101
+ <div class="svadmin-approval-card__header">
102
+ <div class="svadmin-approval-card__heading">
103
+ <div class="svadmin-approval-card__title-row">
104
+ <h4 class="svadmin-approval-card__title">{title}</h4>
105
+ <Badge variant="outline" data-status={status}>
106
+ <statusConfig.icon class="svadmin-approval-card__status-icon" />
107
107
  {statusConfig.label}
108
108
  </Badge>
109
109
  </div>
110
110
  {#if applicant}
111
- <p class="text-xs text-muted-foreground">
112
- Submitted by <strong class="text-foreground">{applicant.name}</strong>
111
+ <p class="svadmin-approval-card__applicant">
112
+ Submitted by <strong>{applicant.name}</strong>
113
113
  {#if applicant.department} ({applicant.department}){/if}
114
114
  {#if applicant.time} · {applicant.time}{/if}
115
115
  </p>
@@ -117,16 +117,16 @@
117
117
  </div>
118
118
 
119
119
  {#if status === 'pending'}
120
- <div class="flex items-center gap-1.5">
120
+ <div class="svadmin-approval-card__actions">
121
121
  {#if ontransfer}
122
122
  <Button
123
123
  variant="outline"
124
124
  size="sm"
125
- class="h-8 text-xs gap-1 text-muted-foreground"
125
+ class="svadmin-approval-card__action"
126
126
  {disabled}
127
127
  onclick={() => { transferDialogOpen = true; }}
128
128
  >
129
- <ArrowRightLeft class="h-3.5 w-3.5" />
129
+ <ArrowRightLeft class="svadmin-approval-card__action-icon" />
130
130
  Transfer
131
131
  </Button>
132
132
  {/if}
@@ -135,11 +135,11 @@
135
135
  <Button
136
136
  variant="outline"
137
137
  size="sm"
138
- class="h-8 text-xs gap-1 border-destructive/30 text-destructive hover:bg-destructive/10"
138
+ class="svadmin-approval-card__action svadmin-approval-card__action--reject"
139
139
  {disabled}
140
140
  onclick={() => { rejectDialogOpen = true; }}
141
141
  >
142
- <X class="h-3.5 w-3.5" />
142
+ <X class="svadmin-approval-card__action-icon" />
143
143
  Reject
144
144
  </Button>
145
145
  {/if}
@@ -147,11 +147,11 @@
147
147
  {#if onapprove}
148
148
  <Button
149
149
  size="sm"
150
- class="h-8 text-xs gap-1 bg-success hover:bg-success/90 text-success-foreground"
150
+ class="svadmin-approval-card__action svadmin-approval-card__action--approve"
151
151
  {disabled}
152
152
  onclick={() => { approveDialogOpen = true; }}
153
153
  >
154
- <Check class="h-3.5 w-3.5" />
154
+ <Check class="svadmin-approval-card__action-icon" />
155
155
  Approve
156
156
  </Button>
157
157
  {/if}
@@ -160,7 +160,7 @@
160
160
  </div>
161
161
 
162
162
  {#if children}
163
- <div class="text-xs text-foreground space-y-2">
163
+ <div class="svadmin-approval-card__content">
164
164
  {@render children()}
165
165
  </div>
166
166
  {/if}
@@ -169,22 +169,22 @@
169
169
  <!-- Approve Dialog -->
170
170
  {#if approveDialogOpen}
171
171
  <Dialog.Dialog bind:open={approveDialogOpen}>
172
- <Dialog.DialogContent class="sm:max-w-md">
172
+ <Dialog.DialogContent class="svadmin-approval-card__dialog">
173
173
  <Dialog.DialogHeader>
174
174
  <Dialog.DialogTitle>Confirm Approval</Dialog.DialogTitle>
175
175
  </Dialog.DialogHeader>
176
- <div class="space-y-3 py-2 text-xs">
177
- <label class="block font-medium text-foreground" for="approve_comment_input">Optional Approval Comment</label>
176
+ <div class="svadmin-approval-card__dialog-form">
177
+ <label class="svadmin-approval-card__dialog-label" for="approve_comment_input">Optional Approval Comment</label>
178
178
  <textarea
179
179
  id="approve_comment_input"
180
180
  bind:value={approveComment}
181
181
  placeholder="e.g. Verified and approved"
182
- class="w-full h-20 rounded-md border border-input bg-background p-2 text-xs focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
182
+ class="svadmin-approval-card__textarea"
183
183
  ></textarea>
184
184
  </div>
185
185
  <Dialog.DialogFooter>
186
186
  <Button variant="outline" size="sm" onclick={() => { approveDialogOpen = false; }}>Cancel</Button>
187
- <Button size="sm" class="bg-success hover:bg-success/90 text-success-foreground" disabled={isSubmitting} onclick={handleApprove}>
187
+ <Button size="sm" class="svadmin-approval-card__confirm svadmin-approval-card__confirm--approve" disabled={isSubmitting} onclick={handleApprove}>
188
188
  Confirm Approval
189
189
  </Button>
190
190
  </Dialog.DialogFooter>
@@ -195,17 +195,17 @@
195
195
  <!-- Reject Dialog -->
196
196
  {#if rejectDialogOpen}
197
197
  <Dialog.Dialog bind:open={rejectDialogOpen}>
198
- <Dialog.DialogContent class="sm:max-w-md">
198
+ <Dialog.DialogContent class="svadmin-approval-card__dialog">
199
199
  <Dialog.DialogHeader>
200
- <Dialog.DialogTitle class="text-destructive">Reject Request</Dialog.DialogTitle>
200
+ <Dialog.DialogTitle class="svadmin-approval-card__reject-title">Reject Request</Dialog.DialogTitle>
201
201
  </Dialog.DialogHeader>
202
- <div class="space-y-3 py-2 text-xs">
203
- <label class="block font-medium text-foreground" for="reject_reason_input">Rejection Reason (Required)</label>
202
+ <div class="svadmin-approval-card__dialog-form">
203
+ <label class="svadmin-approval-card__dialog-label" for="reject_reason_input">Rejection Reason (Required)</label>
204
204
  <textarea
205
205
  id="reject_reason_input"
206
206
  bind:value={rejectReason}
207
207
  placeholder="Please explain why this request is being rejected..."
208
- class="w-full h-20 rounded-md border border-destructive/40 bg-background p-2 text-xs focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-destructive"
208
+ class="svadmin-approval-card__textarea svadmin-approval-card__textarea--reject"
209
209
  required
210
210
  ></textarea>
211
211
  </div>
@@ -222,18 +222,18 @@
222
222
  <!-- Transfer Dialog -->
223
223
  {#if transferDialogOpen}
224
224
  <Dialog.Dialog bind:open={transferDialogOpen}>
225
- <Dialog.DialogContent class="sm:max-w-md">
225
+ <Dialog.DialogContent class="svadmin-approval-card__dialog">
226
226
  <Dialog.DialogHeader>
227
227
  <Dialog.DialogTitle>Transfer Approval</Dialog.DialogTitle>
228
228
  </Dialog.DialogHeader>
229
- <div class="space-y-3 py-2 text-xs">
230
- <label class="block font-medium text-foreground" for="transfer_target_input">Target Approver Email / Username</label>
229
+ <div class="svadmin-approval-card__dialog-form">
230
+ <label class="svadmin-approval-card__dialog-label" for="transfer_target_input">Target Approver Email / Username</label>
231
231
  <input
232
232
  id="transfer_target_input"
233
233
  type="text"
234
234
  bind:value={transferTarget}
235
235
  placeholder="e.g. manager@example.com"
236
- class="w-full h-8 rounded-md border border-input bg-background px-2 text-xs focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
236
+ class="svadmin-approval-card__input"
237
237
  required
238
238
  />
239
239
  </div>