@allbluecn/admin-app 0.2.6 → 0.3.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 (204) hide show
  1. package/package.json +16 -12
  2. package/src/components/admin/admin-user-menu.tsx +2 -4
  3. package/src/components/admin/developer-log.tsx +3 -5
  4. package/src/components/ai-memory/memory-facts-panel.tsx +383 -0
  5. package/src/components/ai-prompts/preview-panel.tsx +165 -0
  6. package/src/components/ai-prompts/prompt-editor.tsx +328 -0
  7. package/src/components/ai-prompts/prompt-table.tsx +141 -0
  8. package/src/components/ai-prompts/prompt-utils.ts +124 -0
  9. package/src/components/ai-prompts/section-editor.tsx +135 -0
  10. package/src/components/ai-prompts/variable-panel.tsx +128 -0
  11. package/src/components/ai-prompts/version-history.tsx +157 -0
  12. package/src/components/ai-provider/provider-form.tsx +6 -10
  13. package/src/components/ai-provider/provider-table.tsx +33 -13
  14. package/src/components/auth/admin-login-form.tsx +1 -1
  15. package/src/components/component/component-form-dialog.tsx +4 -4
  16. package/src/components/component/component-import-dialog.tsx +2 -2
  17. package/src/components/dependency/changelog-dialog.tsx +2 -4
  18. package/src/components/dependency/columns.tsx +4 -8
  19. package/src/components/dependency/dependency-table.tsx +2 -2
  20. package/src/components/dependency/edit-dialog.tsx +7 -11
  21. package/src/components/invitations/invitations-page.tsx +4 -8
  22. package/src/components/knowledge-public/bookmark-form-dialog.tsx +1 -1
  23. package/src/components/knowledge-public/compliance-form-dialog.tsx +1 -1
  24. package/src/components/knowledge-public/legal-form-dialog.tsx +2 -2
  25. package/src/components/layout/sidebar-02/app-sidebar.tsx +17 -9
  26. package/src/components/layout/sidebar-02/nav-main.tsx +6 -14
  27. package/src/components/layout/sidebar-02/nav-notifications.tsx +3 -7
  28. package/src/components/magicui/rainbow-button.tsx +2 -2
  29. package/src/components/market/columns.tsx +2 -4
  30. package/src/components/market/market-app-form.tsx +2 -2
  31. package/src/components/market/market-app-list.tsx +1 -1
  32. package/src/components/oauth-providers/provider-page.tsx +1 -1
  33. package/src/components/ui/alert-dialog.tsx +28 -57
  34. package/src/components/ui/alert.tsx +3 -4
  35. package/src/components/ui/avatar.tsx +5 -28
  36. package/src/components/ui/badge.tsx +19 -34
  37. package/src/components/ui/button.tsx +14 -41
  38. package/src/components/ui/card.tsx +6 -24
  39. package/src/components/ui/checkbox.tsx +4 -26
  40. package/src/components/ui/collapsible.tsx +6 -37
  41. package/src/components/ui/dialog.tsx +30 -60
  42. package/src/components/ui/dropdown-menu.tsx +118 -137
  43. package/src/components/ui/field.tsx +8 -27
  44. package/src/components/ui/input-group.tsx +13 -26
  45. package/src/components/ui/input.tsx +4 -21
  46. package/src/components/ui/label.tsx +3 -27
  47. package/src/components/ui/pagination.tsx +17 -31
  48. package/src/components/ui/select.tsx +101 -76
  49. package/src/components/ui/separator.tsx +4 -27
  50. package/src/components/ui/sheet.tsx +29 -58
  51. package/src/components/ui/sidebar.tsx +119 -117
  52. package/src/components/ui/skeleton.tsx +1 -18
  53. package/src/components/ui/switch.tsx +5 -24
  54. package/src/components/ui/table.tsx +1 -19
  55. package/src/components/ui/textarea.tsx +2 -20
  56. package/src/components/ui/toast.tsx +282 -0
  57. package/src/components/ui/tooltip.tsx +34 -45
  58. package/src/components/user/settings-activity-log.tsx +1 -1
  59. package/src/components/user/user-create-dialog.tsx +2 -2
  60. package/src/components/user/user-filters.tsx +2 -2
  61. package/src/hooks/use-mobile.ts +0 -17
  62. package/src/lib/pacer.ts +21 -0
  63. package/src/lib/utils.ts +1 -23
  64. package/src/paraglide/messages/_index.js +95 -0
  65. package/src/paraglide/messages/admin_ai_memory_action_clearuser1.js +30 -0
  66. package/src/paraglide/messages/admin_ai_memory_action_query.js +30 -0
  67. package/src/paraglide/messages/admin_ai_memory_clear_cancel.js +30 -0
  68. package/src/paraglide/messages/admin_ai_memory_clear_confirm_action.js +30 -0
  69. package/src/paraglide/messages/admin_ai_memory_clear_confirm_description.js +30 -0
  70. package/src/paraglide/messages/admin_ai_memory_clear_confirm_title.js +30 -0
  71. package/src/paraglide/messages/admin_ai_memory_columns_actions.js +30 -0
  72. package/src/paraglide/messages/admin_ai_memory_columns_content.js +30 -0
  73. package/src/paraglide/messages/admin_ai_memory_columns_createdat1.js +30 -0
  74. package/src/paraglide/messages/admin_ai_memory_columns_threadid1.js +30 -0
  75. package/src/paraglide/messages/admin_ai_memory_delete_cancel.js +30 -0
  76. package/src/paraglide/messages/admin_ai_memory_delete_confirm_action.js +30 -0
  77. package/src/paraglide/messages/admin_ai_memory_delete_confirm_description.js +30 -0
  78. package/src/paraglide/messages/admin_ai_memory_delete_confirm_title.js +30 -0
  79. package/src/paraglide/messages/admin_ai_memory_empty.js +30 -0
  80. package/src/paraglide/messages/admin_ai_memory_emptyhint1.js +30 -0
  81. package/src/paraglide/messages/admin_ai_memory_error_nouserid2.js +30 -0
  82. package/src/paraglide/messages/admin_ai_memory_error_query.js +30 -0
  83. package/src/paraglide/messages/admin_ai_memory_error_title.js +30 -0
  84. package/src/paraglide/messages/admin_ai_memory_form_user.js +30 -0
  85. package/src/paraglide/messages/admin_ai_memory_page_description.js +30 -0
  86. package/src/paraglide/messages/admin_ai_memory_page_title.js +30 -0
  87. package/src/paraglide/messages/admin_ai_memory_placeholder_user.js +30 -0
  88. package/src/paraglide/messages/admin_ai_memory_stat_count.js +30 -0
  89. package/src/paraglide/messages/admin_ai_memory_stat_lastwrite1.js +30 -0
  90. package/src/paraglide/messages/admin_ai_memory_toast_cleared.js +30 -0
  91. package/src/paraglide/messages/admin_ai_memory_toast_deleted.js +30 -0
  92. package/src/paraglide/messages/admin_ai_prompts_active.js +30 -0
  93. package/src/paraglide/messages/admin_ai_prompts_back.js +30 -0
  94. package/src/paraglide/messages/admin_ai_prompts_badge_protected.js +30 -0
  95. package/src/paraglide/messages/admin_ai_prompts_cache_hint.js +30 -0
  96. package/src/paraglide/messages/admin_ai_prompts_columns_active.js +30 -0
  97. package/src/paraglide/messages/admin_ai_prompts_columns_key.js +30 -0
  98. package/src/paraglide/messages/admin_ai_prompts_columns_name.js +30 -0
  99. package/src/paraglide/messages/admin_ai_prompts_columns_protected.js +30 -0
  100. package/src/paraglide/messages/admin_ai_prompts_columns_updatedat1.js +30 -0
  101. package/src/paraglide/messages/admin_ai_prompts_columns_version.js +30 -0
  102. package/src/paraglide/messages/admin_ai_prompts_description.js +30 -0
  103. package/src/paraglide/messages/admin_ai_prompts_description_placeholder.js +30 -0
  104. package/src/paraglide/messages/admin_ai_prompts_edit.js +30 -0
  105. package/src/paraglide/messages/admin_ai_prompts_name.js +30 -0
  106. package/src/paraglide/messages/admin_ai_prompts_name_placeholder.js +30 -0
  107. package/src/paraglide/messages/admin_ai_prompts_note_placeholder.js +30 -0
  108. package/src/paraglide/messages/admin_ai_prompts_page_description.js +30 -0
  109. package/src/paraglide/messages/admin_ai_prompts_page_title.js +30 -0
  110. package/src/paraglide/messages/admin_ai_prompts_preview_empty.js +30 -0
  111. package/src/paraglide/messages/admin_ai_prompts_preview_generating.js +30 -0
  112. package/src/paraglide/messages/admin_ai_prompts_preview_hint.js +30 -0
  113. package/src/paraglide/messages/admin_ai_prompts_preview_nocontent1.js +30 -0
  114. package/src/paraglide/messages/admin_ai_prompts_preview_placeholder.js +30 -0
  115. package/src/paraglide/messages/admin_ai_prompts_preview_section.js +30 -0
  116. package/src/paraglide/messages/admin_ai_prompts_preview_title.js +30 -0
  117. package/src/paraglide/messages/admin_ai_prompts_protected_hint.js +30 -0
  118. package/src/paraglide/messages/admin_ai_prompts_rollback.js +30 -0
  119. package/src/paraglide/messages/admin_ai_prompts_rollback_confirm_action.js +30 -0
  120. package/src/paraglide/messages/admin_ai_prompts_rollback_confirm_description.js +30 -0
  121. package/src/paraglide/messages/admin_ai_prompts_rollback_confirm_title.js +30 -0
  122. package/src/paraglide/messages/admin_ai_prompts_save.js +30 -0
  123. package/src/paraglide/messages/admin_ai_prompts_section_add.js +30 -0
  124. package/src/paraglide/messages/admin_ai_prompts_section_id.js +30 -0
  125. package/src/paraglide/messages/admin_ai_prompts_section_movedown1.js +30 -0
  126. package/src/paraglide/messages/admin_ai_prompts_section_moveup1.js +30 -0
  127. package/src/paraglide/messages/admin_ai_prompts_section_order.js +30 -0
  128. package/src/paraglide/messages/admin_ai_prompts_section_remove.js +30 -0
  129. package/src/paraglide/messages/admin_ai_prompts_section_template_placeholder.js +30 -0
  130. package/src/paraglide/messages/admin_ai_prompts_sections_empty.js +30 -0
  131. package/src/paraglide/messages/admin_ai_prompts_sections_hint.js +30 -0
  132. package/src/paraglide/messages/admin_ai_prompts_sections_title.js +30 -0
  133. package/src/paraglide/messages/admin_ai_prompts_toast_activated.js +30 -0
  134. package/src/paraglide/messages/admin_ai_prompts_toast_failed.js +30 -0
  135. package/src/paraglide/messages/admin_ai_prompts_toast_protected_locked.js +30 -0
  136. package/src/paraglide/messages/admin_ai_prompts_toast_rolled_back.js +30 -0
  137. package/src/paraglide/messages/admin_ai_prompts_toast_save_failed.js +30 -0
  138. package/src/paraglide/messages/admin_ai_prompts_toast_saved.js +30 -0
  139. package/src/paraglide/messages/admin_ai_prompts_variable_add.js +30 -0
  140. package/src/paraglide/messages/admin_ai_prompts_variable_declarehint1.js +30 -0
  141. package/src/paraglide/messages/admin_ai_prompts_variable_description_placeholder.js +30 -0
  142. package/src/paraglide/messages/admin_ai_prompts_variable_name_placeholder.js +30 -0
  143. package/src/paraglide/messages/admin_ai_prompts_variable_remove.js +30 -0
  144. package/src/paraglide/messages/admin_ai_prompts_variable_undeclared.js +30 -0
  145. package/src/paraglide/messages/admin_ai_prompts_variables_empty.js +30 -0
  146. package/src/paraglide/messages/admin_ai_prompts_variables_title.js +30 -0
  147. package/src/paraglide/messages/admin_ai_prompts_versions_current.js +30 -0
  148. package/src/paraglide/messages/admin_ai_prompts_versions_empty.js +30 -0
  149. package/src/paraglide/messages/admin_ai_prompts_versions_hint.js +30 -0
  150. package/src/paraglide/messages/admin_ai_prompts_versions_nonote1.js +30 -0
  151. package/src/paraglide/messages/admin_ai_prompts_versions_title.js +30 -0
  152. package/src/paraglide/messages/admin_ai_prompts_versions_unknowncreator1.js +30 -0
  153. package/src/paraglide/messages/admin_ai_table_seedfromseed2.js +30 -0
  154. package/src/paraglide/messages/admin_ai_table_toast_seedcreated1.js +30 -0
  155. package/src/paraglide/messages/admin_ai_table_toast_seedfailed1.js +30 -0
  156. package/src/paraglide/messages/admin_ai_table_toast_seednonew2.js +30 -0
  157. package/src/paraglide/messages/common_monitoring_aiusage_sandbox1.js +30 -0
  158. package/src/paraglide/messages/common_monitoring_aiusage_sandboxvalue2.js +30 -0
  159. package/src/paraglide/messages/common_nav_aiprompts1.js +30 -0
  160. package/src/routeTree.gen.ts +101 -0
  161. package/src/routes/__root.tsx +2 -2
  162. package/src/{components/ui/sonner.tsx → routes/_nav/ai-memory/route.lazy.tsx} +24 -16
  163. package/src/routes/_nav/ai-memory/route.tsx +31 -0
  164. package/src/routes/_nav/ai-prompts/$key/route.lazy.tsx +32 -0
  165. package/src/routes/_nav/ai-prompts/$key/route.tsx +37 -0
  166. package/src/routes/_nav/ai-prompts/index/route.lazy.tsx +47 -0
  167. package/src/routes/_nav/ai-prompts/route.lazy.tsx +26 -0
  168. package/src/routes/_nav/ai-prompts/route.tsx +31 -0
  169. package/src/routes/_nav/compliance/route.lazy.tsx +2 -4
  170. package/src/routes/_nav/components/route.lazy.tsx +1 -1
  171. package/src/routes/_nav/knowledge-public/bookmarks/route.lazy.tsx +1 -1
  172. package/src/routes/_nav/knowledge-public/compliance/route.lazy.tsx +1 -1
  173. package/src/routes/_nav/knowledge-public/legal/route.lazy.tsx +1 -1
  174. package/src/routes/_nav/licenses/$licenseId/route.lazy.tsx +1 -1
  175. package/src/routes/_nav/monitoring/ai-usage/route.lazy.tsx +10 -1
  176. package/src/routes/_nav/monitoring/errors/route.lazy.tsx +1 -1
  177. package/src/routes/_nav/monitoring/health/route.lazy.tsx +1 -1
  178. package/src/routes/_nav/monitoring/logs/route.lazy.tsx +1 -1
  179. package/src/routes/_nav/monitoring/metrics/route.lazy.tsx +1 -1
  180. package/src/routes/_nav/monitoring/sentry/route.lazy.tsx +1 -1
  181. package/src/routes/_nav/permissions/route.lazy.tsx +2 -2
  182. package/src/routes/_nav/sso/route.lazy.tsx +1 -1
  183. package/src/routes/_nav/users/$userId/route.lazy.tsx +3 -3
  184. package/src/routes/setup/route.lazy.tsx +1 -1
  185. package/src/server/__tests__/prompt-defaults.test.ts +139 -0
  186. package/src/server/admin-ai-usage.ts +22 -4
  187. package/src/server/ai-memory/store.ts +103 -0
  188. package/src/server/serverFns/ai-memory/clear.ts +31 -0
  189. package/src/server/serverFns/ai-memory/delete.ts +31 -0
  190. package/src/server/serverFns/ai-memory/list-users.ts +40 -0
  191. package/src/server/serverFns/ai-memory/list.ts +54 -0
  192. package/src/server/serverFns/ai-prompts/activate.ts +53 -0
  193. package/src/server/serverFns/ai-prompts/get.ts +74 -0
  194. package/src/server/serverFns/ai-prompts/list.ts +55 -0
  195. package/src/server/serverFns/ai-prompts/preview.ts +66 -0
  196. package/src/server/serverFns/ai-prompts/prompt-defaults.ts +63 -0
  197. package/src/server/serverFns/ai-prompts/prompt-schemas.ts +47 -0
  198. package/src/server/serverFns/ai-prompts/rollback.ts +86 -0
  199. package/src/server/serverFns/ai-prompts/save.ts +129 -0
  200. package/src/server/serverFns/ai-provider/seed-from-seed.ts +64 -0
  201. package/src/styles/globals.css +92 -77
  202. package/src/components/layout/sidebar-02/logo.tsx +0 -40
  203. package/src/components/layout/sidebar-02/team-switcher.tsx +0 -106
  204. package/src/components/providers/theme-toggle.tsx +0 -59
@@ -16,6 +16,8 @@ import { Route as NavRouteRouteImport } from './routes/_nav/route'
16
16
  import { Route as LoginRouteRouteImport } from './routes/login/route'
17
17
  import { Route as SentryTunnelRouteImport } from './routes/sentry-tunnel'
18
18
  import { Route as SetupRouteRouteImport } from './routes/setup/route'
19
+ import { Route as NavAiMemoryRouteRouteImport } from './routes/_nav/ai-memory/route'
20
+ import { Route as NavAiPromptsRouteRouteImport } from './routes/_nav/ai-prompts/route'
19
21
  import { Route as NavAiProvidersRouteRouteImport } from './routes/_nav/ai-providers/route'
20
22
  import { Route as NavAppsRouteRouteImport } from './routes/_nav/apps/route'
21
23
  import { Route as NavAuditRouteRouteImport } from './routes/_nav/audit/route'
@@ -36,6 +38,7 @@ import { Route as NavSettingsRouteRouteImport } from './routes/_nav/settings/rou
36
38
  import { Route as NavSsoRouteRouteImport } from './routes/_nav/sso/route'
37
39
  import { Route as NavUsersRouteRouteImport } from './routes/_nav/users/route'
38
40
  import { Route as ApiSentryTestRouteImport } from './routes/api.sentry-test'
41
+ import { Route as NavAiPromptsKeyRouteRouteImport } from './routes/_nav/ai-prompts/$key/route'
39
42
  import { Route as NavAiProvidersNewRouteRouteImport } from './routes/_nav/ai-providers/new/route'
40
43
  import { Route as NavBillingInvoicesRouteRouteImport } from './routes/_nav/billing/invoices/route'
41
44
  import { Route as NavBillingSubscriptionsRouteRouteImport } from './routes/_nav/billing/subscriptions/route'
@@ -53,6 +56,8 @@ import { Route as ApiObservabilityHealthRouteImport } from './routes/api/observa
53
56
  import { Route as NavAiProvidersIdEditRouteRouteImport } from './routes/_nav/ai-providers/$id/edit/route'
54
57
  import { Route as NavBillingSubscriptionsSubscriptionIdRouteRouteImport } from './routes/_nav/billing/subscriptions/$subscriptionId/route'
55
58
 
59
+ const NavAiPromptsIndexRouteLazyRouteImport =
60
+ createFileRoute('/_nav/ai-prompts/')()
56
61
  const NavAiProvidersIndexRouteLazyRouteImport = createFileRoute(
57
62
  '/_nav/ai-providers/',
58
63
  )()
@@ -98,6 +103,20 @@ const SetupRouteRoute = SetupRouteRouteImport.update({
98
103
  path: '/setup',
99
104
  getParentRoute: () => rootRouteImport,
100
105
  } as any).lazy(() => import('./routes/setup/route.lazy').then((d) => d.Route))
106
+ const NavAiMemoryRouteRoute = NavAiMemoryRouteRouteImport.update({
107
+ id: '/ai-memory',
108
+ path: '/ai-memory',
109
+ getParentRoute: () => NavRouteRoute,
110
+ } as any).lazy(() =>
111
+ import('./routes/_nav/ai-memory/route.lazy').then((d) => d.Route),
112
+ )
113
+ const NavAiPromptsRouteRoute = NavAiPromptsRouteRouteImport.update({
114
+ id: '/ai-prompts',
115
+ path: '/ai-prompts',
116
+ getParentRoute: () => NavRouteRoute,
117
+ } as any).lazy(() =>
118
+ import('./routes/_nav/ai-prompts/route.lazy').then((d) => d.Route),
119
+ )
101
120
  const NavAiProvidersRouteRoute = NavAiProvidersRouteRouteImport.update({
102
121
  id: '/ai-providers',
103
122
  path: '/ai-providers',
@@ -236,6 +255,21 @@ const ApiSentryTestRoute = ApiSentryTestRouteImport.update({
236
255
  path: '/api/sentry-test',
237
256
  getParentRoute: () => rootRouteImport,
238
257
  } as any)
258
+ const NavAiPromptsIndexRouteLazyRoute =
259
+ NavAiPromptsIndexRouteLazyRouteImport.update({
260
+ id: '/',
261
+ path: '/',
262
+ getParentRoute: () => NavAiPromptsRouteRoute,
263
+ } as any).lazy(() =>
264
+ import('./routes/_nav/ai-prompts/index/route.lazy').then((d) => d.Route),
265
+ )
266
+ const NavAiPromptsKeyRouteRoute = NavAiPromptsKeyRouteRouteImport.update({
267
+ id: '/$key',
268
+ path: '/$key',
269
+ getParentRoute: () => NavAiPromptsRouteRoute,
270
+ } as any).lazy(() =>
271
+ import('./routes/_nav/ai-prompts/$key/route.lazy').then((d) => d.Route),
272
+ )
239
273
  const NavAiProvidersIndexRouteLazyRoute =
240
274
  NavAiProvidersIndexRouteLazyRouteImport.update({
241
275
  id: '/',
@@ -423,6 +457,8 @@ export interface FileRoutesByFullPath {
423
457
  '/login': typeof LoginRouteRoute
424
458
  '/setup': typeof SetupRouteRoute
425
459
  '/sentry-tunnel': typeof SentryTunnelRoute
460
+ '/ai-memory': typeof NavAiMemoryRouteRoute
461
+ '/ai-prompts': typeof NavAiPromptsRouteRouteWithChildren
426
462
  '/ai-providers': typeof NavAiProvidersRouteRouteWithChildren
427
463
  '/apps': typeof NavAppsRouteRoute
428
464
  '/audit': typeof NavAuditRouteRoute
@@ -443,6 +479,7 @@ export interface FileRoutesByFullPath {
443
479
  '/sso': typeof NavSsoRouteRoute
444
480
  '/users': typeof NavUsersRouteRouteWithChildren
445
481
  '/api/sentry-test': typeof ApiSentryTestRoute
482
+ '/ai-prompts/$key': typeof NavAiPromptsKeyRouteRoute
446
483
  '/ai-providers/new': typeof NavAiProvidersNewRouteRoute
447
484
  '/billing/invoices': typeof NavBillingInvoicesRouteRoute
448
485
  '/billing/subscriptions': typeof NavBillingSubscriptionsRouteRouteWithChildren
@@ -457,6 +494,7 @@ export interface FileRoutesByFullPath {
457
494
  '/api/compliance-download/$jobId': typeof ApiComplianceDownloadJobIdRoute
458
495
  '/api/observability/errors': typeof ApiObservabilityErrorsRoute
459
496
  '/api/observability/health': typeof ApiObservabilityHealthRoute
497
+ '/ai-prompts/': typeof NavAiPromptsIndexRouteLazyRoute
460
498
  '/ai-providers/': typeof NavAiProvidersIndexRouteLazyRoute
461
499
  '/licenses/new': typeof NavLicensesNewRouteLazyRoute
462
500
  '/monitoring/errors': typeof NavMonitoringErrorsRouteLazyRoute
@@ -472,6 +510,7 @@ export interface FileRoutesByTo {
472
510
  '/login': typeof LoginRouteRoute
473
511
  '/setup': typeof SetupRouteRoute
474
512
  '/sentry-tunnel': typeof SentryTunnelRoute
513
+ '/ai-memory': typeof NavAiMemoryRouteRoute
475
514
  '/apps': typeof NavAppsRouteRoute
476
515
  '/audit': typeof NavAuditRouteRoute
477
516
  '/billing': typeof NavBillingRouteRouteWithChildren
@@ -491,6 +530,7 @@ export interface FileRoutesByTo {
491
530
  '/sso': typeof NavSsoRouteRoute
492
531
  '/users': typeof NavUsersRouteRouteWithChildren
493
532
  '/api/sentry-test': typeof ApiSentryTestRoute
533
+ '/ai-prompts/$key': typeof NavAiPromptsKeyRouteRoute
494
534
  '/ai-providers/new': typeof NavAiProvidersNewRouteRoute
495
535
  '/billing/invoices': typeof NavBillingInvoicesRouteRoute
496
536
  '/billing/subscriptions': typeof NavBillingSubscriptionsRouteRouteWithChildren
@@ -505,6 +545,7 @@ export interface FileRoutesByTo {
505
545
  '/api/compliance-download/$jobId': typeof ApiComplianceDownloadJobIdRoute
506
546
  '/api/observability/errors': typeof ApiObservabilityErrorsRoute
507
547
  '/api/observability/health': typeof ApiObservabilityHealthRoute
548
+ '/ai-prompts': typeof NavAiPromptsIndexRouteLazyRoute
508
549
  '/ai-providers': typeof NavAiProvidersIndexRouteLazyRoute
509
550
  '/licenses/new': typeof NavLicensesNewRouteLazyRoute
510
551
  '/monitoring/errors': typeof NavMonitoringErrorsRouteLazyRoute
@@ -522,6 +563,8 @@ export interface FileRoutesById {
522
563
  '/login': typeof LoginRouteRoute
523
564
  '/setup': typeof SetupRouteRoute
524
565
  '/sentry-tunnel': typeof SentryTunnelRoute
566
+ '/_nav/ai-memory': typeof NavAiMemoryRouteRoute
567
+ '/_nav/ai-prompts': typeof NavAiPromptsRouteRouteWithChildren
525
568
  '/_nav/ai-providers': typeof NavAiProvidersRouteRouteWithChildren
526
569
  '/_nav/apps': typeof NavAppsRouteRoute
527
570
  '/_nav/audit': typeof NavAuditRouteRoute
@@ -542,6 +585,7 @@ export interface FileRoutesById {
542
585
  '/_nav/sso': typeof NavSsoRouteRoute
543
586
  '/_nav/users': typeof NavUsersRouteRouteWithChildren
544
587
  '/api/sentry-test': typeof ApiSentryTestRoute
588
+ '/_nav/ai-prompts/$key': typeof NavAiPromptsKeyRouteRoute
545
589
  '/_nav/ai-providers/new': typeof NavAiProvidersNewRouteRoute
546
590
  '/_nav/billing/invoices': typeof NavBillingInvoicesRouteRoute
547
591
  '/_nav/billing/subscriptions': typeof NavBillingSubscriptionsRouteRouteWithChildren
@@ -556,6 +600,7 @@ export interface FileRoutesById {
556
600
  '/api/compliance-download/$jobId': typeof ApiComplianceDownloadJobIdRoute
557
601
  '/api/observability/errors': typeof ApiObservabilityErrorsRoute
558
602
  '/api/observability/health': typeof ApiObservabilityHealthRoute
603
+ '/_nav/ai-prompts/': typeof NavAiPromptsIndexRouteLazyRoute
559
604
  '/_nav/ai-providers/': typeof NavAiProvidersIndexRouteLazyRoute
560
605
  '/_nav/licenses/new': typeof NavLicensesNewRouteLazyRoute
561
606
  '/_nav/monitoring/errors': typeof NavMonitoringErrorsRouteLazyRoute
@@ -573,6 +618,8 @@ export interface FileRouteTypes {
573
618
  | '/login'
574
619
  | '/setup'
575
620
  | '/sentry-tunnel'
621
+ | '/ai-memory'
622
+ | '/ai-prompts'
576
623
  | '/ai-providers'
577
624
  | '/apps'
578
625
  | '/audit'
@@ -593,6 +640,7 @@ export interface FileRouteTypes {
593
640
  | '/sso'
594
641
  | '/users'
595
642
  | '/api/sentry-test'
643
+ | '/ai-prompts/$key'
596
644
  | '/ai-providers/new'
597
645
  | '/billing/invoices'
598
646
  | '/billing/subscriptions'
@@ -607,6 +655,7 @@ export interface FileRouteTypes {
607
655
  | '/api/compliance-download/$jobId'
608
656
  | '/api/observability/errors'
609
657
  | '/api/observability/health'
658
+ | '/ai-prompts/'
610
659
  | '/ai-providers/'
611
660
  | '/licenses/new'
612
661
  | '/monitoring/errors'
@@ -622,6 +671,7 @@ export interface FileRouteTypes {
622
671
  | '/login'
623
672
  | '/setup'
624
673
  | '/sentry-tunnel'
674
+ | '/ai-memory'
625
675
  | '/apps'
626
676
  | '/audit'
627
677
  | '/billing'
@@ -641,6 +691,7 @@ export interface FileRouteTypes {
641
691
  | '/sso'
642
692
  | '/users'
643
693
  | '/api/sentry-test'
694
+ | '/ai-prompts/$key'
644
695
  | '/ai-providers/new'
645
696
  | '/billing/invoices'
646
697
  | '/billing/subscriptions'
@@ -655,6 +706,7 @@ export interface FileRouteTypes {
655
706
  | '/api/compliance-download/$jobId'
656
707
  | '/api/observability/errors'
657
708
  | '/api/observability/health'
709
+ | '/ai-prompts'
658
710
  | '/ai-providers'
659
711
  | '/licenses/new'
660
712
  | '/monitoring/errors'
@@ -671,6 +723,8 @@ export interface FileRouteTypes {
671
723
  | '/login'
672
724
  | '/setup'
673
725
  | '/sentry-tunnel'
726
+ | '/_nav/ai-memory'
727
+ | '/_nav/ai-prompts'
674
728
  | '/_nav/ai-providers'
675
729
  | '/_nav/apps'
676
730
  | '/_nav/audit'
@@ -691,6 +745,7 @@ export interface FileRouteTypes {
691
745
  | '/_nav/sso'
692
746
  | '/_nav/users'
693
747
  | '/api/sentry-test'
748
+ | '/_nav/ai-prompts/$key'
694
749
  | '/_nav/ai-providers/new'
695
750
  | '/_nav/billing/invoices'
696
751
  | '/_nav/billing/subscriptions'
@@ -705,6 +760,7 @@ export interface FileRouteTypes {
705
760
  | '/api/compliance-download/$jobId'
706
761
  | '/api/observability/errors'
707
762
  | '/api/observability/health'
763
+ | '/_nav/ai-prompts/'
708
764
  | '/_nav/ai-providers/'
709
765
  | '/_nav/licenses/new'
710
766
  | '/_nav/monitoring/errors'
@@ -766,6 +822,20 @@ declare module '@tanstack/react-router' {
766
822
  preLoaderRoute: typeof SetupRouteRouteImport
767
823
  parentRoute: typeof rootRouteImport
768
824
  }
825
+ '/_nav/ai-memory': {
826
+ id: '/_nav/ai-memory'
827
+ path: '/ai-memory'
828
+ fullPath: '/ai-memory'
829
+ preLoaderRoute: typeof NavAiMemoryRouteRouteImport
830
+ parentRoute: typeof NavRouteRoute
831
+ }
832
+ '/_nav/ai-prompts': {
833
+ id: '/_nav/ai-prompts'
834
+ path: '/ai-prompts'
835
+ fullPath: '/ai-prompts'
836
+ preLoaderRoute: typeof NavAiPromptsRouteRouteImport
837
+ parentRoute: typeof NavRouteRoute
838
+ }
769
839
  '/_nav/ai-providers': {
770
840
  id: '/_nav/ai-providers'
771
841
  path: '/ai-providers'
@@ -906,6 +976,20 @@ declare module '@tanstack/react-router' {
906
976
  preLoaderRoute: typeof ApiSentryTestRouteImport
907
977
  parentRoute: typeof rootRouteImport
908
978
  }
979
+ '/_nav/ai-prompts/': {
980
+ id: '/_nav/ai-prompts/'
981
+ path: '/'
982
+ fullPath: '/ai-prompts/'
983
+ preLoaderRoute: typeof NavAiPromptsIndexRouteLazyRouteImport
984
+ parentRoute: typeof NavAiPromptsRouteRoute
985
+ }
986
+ '/_nav/ai-prompts/$key': {
987
+ id: '/_nav/ai-prompts/$key'
988
+ path: '/$key'
989
+ fullPath: '/ai-prompts/$key'
990
+ preLoaderRoute: typeof NavAiPromptsKeyRouteRouteImport
991
+ parentRoute: typeof NavAiPromptsRouteRoute
992
+ }
909
993
  '/_nav/ai-providers/': {
910
994
  id: '/_nav/ai-providers/'
911
995
  path: '/'
@@ -1070,6 +1154,19 @@ declare module '@tanstack/react-router' {
1070
1154
  }
1071
1155
  }
1072
1156
 
1157
+ interface NavAiPromptsRouteRouteChildren {
1158
+ NavAiPromptsKeyRouteRoute: typeof NavAiPromptsKeyRouteRoute
1159
+ NavAiPromptsIndexRouteLazyRoute: typeof NavAiPromptsIndexRouteLazyRoute
1160
+ }
1161
+
1162
+ const NavAiPromptsRouteRouteChildren: NavAiPromptsRouteRouteChildren = {
1163
+ NavAiPromptsKeyRouteRoute: NavAiPromptsKeyRouteRoute,
1164
+ NavAiPromptsIndexRouteLazyRoute: NavAiPromptsIndexRouteLazyRoute,
1165
+ }
1166
+
1167
+ const NavAiPromptsRouteRouteWithChildren =
1168
+ NavAiPromptsRouteRoute._addFileChildren(NavAiPromptsRouteRouteChildren)
1169
+
1073
1170
  interface NavAiProvidersRouteRouteChildren {
1074
1171
  NavAiProvidersNewRouteRoute: typeof NavAiProvidersNewRouteRoute
1075
1172
  NavAiProvidersIndexRouteLazyRoute: typeof NavAiProvidersIndexRouteLazyRoute
@@ -1164,6 +1261,8 @@ const NavUsersRouteRouteWithChildren = NavUsersRouteRoute._addFileChildren(
1164
1261
  )
1165
1262
 
1166
1263
  interface NavRouteRouteChildren {
1264
+ NavAiMemoryRouteRoute: typeof NavAiMemoryRouteRoute
1265
+ NavAiPromptsRouteRoute: typeof NavAiPromptsRouteRouteWithChildren
1167
1266
  NavAiProvidersRouteRoute: typeof NavAiProvidersRouteRouteWithChildren
1168
1267
  NavAppsRouteRoute: typeof NavAppsRouteRoute
1169
1268
  NavAuditRouteRoute: typeof NavAuditRouteRoute
@@ -1189,6 +1288,8 @@ interface NavRouteRouteChildren {
1189
1288
  }
1190
1289
 
1191
1290
  const NavRouteRouteChildren: NavRouteRouteChildren = {
1291
+ NavAiMemoryRouteRoute: NavAiMemoryRouteRoute,
1292
+ NavAiPromptsRouteRoute: NavAiPromptsRouteRouteWithChildren,
1192
1293
  NavAiProvidersRouteRoute: NavAiProvidersRouteRouteWithChildren,
1193
1294
  NavAppsRouteRoute: NavAppsRouteRoute,
1194
1295
  NavAuditRouteRoute: NavAuditRouteRoute,
@@ -21,7 +21,7 @@ import globalsCss from '../styles/globals.css?url'
21
21
  import type { RouterContext } from '@/lib/router-context'
22
22
  import type { AppLocale } from '@/lib/i18n/config'
23
23
  import { Providers } from '@/providers'
24
- import { Toaster } from '@/components/ui/sonner'
24
+ import { Toaster } from '@/components/ui/toast'
25
25
  import { getSessionFn } from '@/server/serverFns/auth/session'
26
26
  import { getLocaleFn } from '@/server/serverFns/locale'
27
27
  import { reportClientError } from '@/server/serverFns/monitoring/report-error'
@@ -103,7 +103,7 @@ function RootComponent() {
103
103
  <body className="w-full h-full min-h-screen antialiased">
104
104
  <Providers>
105
105
  <Outlet />
106
- <Toaster position="top-center" />
106
+ <Toaster />
107
107
  </Providers>
108
108
  <Scripts />
109
109
  </body>
@@ -15,23 +15,31 @@
15
15
  // You should have received a copy of the GNU Affero General Public License
16
16
  // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
17
 
18
- import { Toaster as Sonner, type ToasterProps, toast } from "sonner"
19
- import { CircleCheckIcon, InfoIcon, TriangleAlertIcon, OctagonXIcon, Loader2Icon } from "lucide-react"
18
+ import { createLazyFileRoute } from "@tanstack/react-router"
19
+
20
+ import { m } from "@/paraglide/messages.js"
21
+ import { MemoryFactsPanel, type MemoryUserOption } from "@/components/ai-memory/memory-facts-panel"
22
+
23
+ export const Route = createLazyFileRoute("/_nav/ai-memory")({
24
+ component: AiMemoryPage,
25
+ })
26
+
27
+ function AiMemoryPage() {
28
+ const ctx = Route.useRouteContext() as {
29
+ memoryUsers?: MemoryUserOption[]
30
+ }
20
31
 
21
- const Toaster = ({ ...props }: ToasterProps) => {
22
32
  return (
23
- <Sonner
24
- className="toaster group"
25
- icons={{
26
- success: <CircleCheckIcon className="size-4 text-emerald-600 dark:text-emerald-500" />,
27
- info: <InfoIcon className="size-4 text-sky-600 dark:text-sky-500" />,
28
- warning: <TriangleAlertIcon className="size-4 text-amber-600 dark:text-amber-500" />,
29
- error: <OctagonXIcon className="size-4 text-red-600 dark:text-red-500" />,
30
- loading: <Loader2Icon className="size-4 animate-spin" />,
31
- }}
32
- {...props}
33
- />
33
+ <div className="p-6">
34
+ <div className="mb-4 space-y-1">
35
+ <h1 className="text-xl font-semibold">
36
+ {m["admin-ai-memory_page_title"]()}
37
+ </h1>
38
+ <p className="text-sm text-muted-foreground">
39
+ {m["admin-ai-memory_page_description"]()}
40
+ </p>
41
+ </div>
42
+ <MemoryFactsPanel users={ctx.memoryUsers ?? []} />
43
+ </div>
34
44
  )
35
45
  }
36
-
37
- export { Toaster, toast }
@@ -0,0 +1,31 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ // AllBlue - 理想之海
3
+ // Copyright (C) 2026 AllBlue Contributors
4
+ //
5
+ // This program is free software: you can redistribute it and/or modify
6
+ // it under the terms of the GNU Affero General Public License as published by
7
+ // the Free Software Foundation, either version 3 of the License, or
8
+ // (at your option) any later version.
9
+ //
10
+ // This program is distributed in the hope that it will be useful,
11
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ // GNU Affero General Public License for more details.
14
+ //
15
+ // You should have received a copy of the GNU Affero General Public License
16
+ // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+
18
+ import { createFileRoute } from "@tanstack/react-router"
19
+ import { listMemoryUsersFn } from "@/server/serverFns/ai-memory/list-users"
20
+
21
+ export const Route = createFileRoute("/_nav/ai-memory")({
22
+ beforeLoad: async () => {
23
+ try {
24
+ const users = await listMemoryUsersFn({ data: {} })
25
+ return { memoryUsers: users }
26
+ } catch (e) {
27
+ console.error("[admin/ai-memory] failed to load", e)
28
+ return { memoryUsers: [] }
29
+ }
30
+ },
31
+ })
@@ -0,0 +1,32 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ // AllBlue - 理想之海
3
+ // Copyright (C) 2026 AllBlue Contributors
4
+ //
5
+ // This program is free software: you can redistribute it and/or modify
6
+ // it under the terms of the GNU Affero General Public License as published by
7
+ // the Free Software Foundation, either version 3 of the License, or
8
+ // (at your option) any later version.
9
+ //
10
+ // This program is distributed in the hope that it will be useful,
11
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ // GNU Affero General Public License for more details.
14
+ //
15
+ // You should have received a copy of the GNU Affero General Public License
16
+ // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+
18
+ import { createLazyFileRoute } from "@tanstack/react-router"
19
+ import { PromptEditor } from "@/components/ai-prompts/prompt-editor"
20
+
21
+ export const Route = createLazyFileRoute("/_nav/ai-prompts/$key")({
22
+ component: PromptEditorPage,
23
+ })
24
+
25
+ function PromptEditorPage() {
26
+ const ctx = Route.useRouteContext() as {
27
+ template?: import("@allbluecn/kernel").SystemPromptTemplateDTO
28
+ versions?: import("@/server/serverFns/ai-prompts/get").PromptVersionSummary[]
29
+ }
30
+ if (!ctx.template) return null
31
+ return <PromptEditor template={ctx.template} versions={ctx.versions ?? []} />
32
+ }
@@ -0,0 +1,37 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ // AllBlue - 理想之海
3
+ // Copyright (C) 2026 AllBlue Contributors
4
+ //
5
+ // This program is free software: you can redistribute it and/or modify
6
+ // it under the terms of the GNU Affero General Public License as published by
7
+ // the Free Software Foundation, either version 3 of the License, or
8
+ // (at your option) any later version.
9
+ //
10
+ // This program is distributed in the hope that it will be useful,
11
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ // GNU Affero General Public License for more details.
14
+ //
15
+ // You should have received a copy of the GNU Affero General Public License
16
+ // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+
18
+ import { createFileRoute, notFound } from "@tanstack/react-router"
19
+ import { z } from "zod"
20
+ import { getPromptTemplateFn } from "@/server/serverFns/ai-prompts/get"
21
+
22
+ export const Route = createFileRoute("/_nav/ai-prompts/$key")({
23
+ params: {
24
+ parse: (raw) => ({ key: z.string().parse(raw.key) }),
25
+ stringify: ({ key }) => ({ key }),
26
+ },
27
+ beforeLoad: async ({ params }) => {
28
+ try {
29
+ const { template, versions } = await getPromptTemplateFn({
30
+ data: { key: params.key },
31
+ })
32
+ return { template, versions }
33
+ } catch {
34
+ throw notFound()
35
+ }
36
+ },
37
+ })
@@ -0,0 +1,47 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ // AllBlue - 理想之海
3
+ // Copyright (C) 2026 AllBlue Contributors
4
+ //
5
+ // This program is free software: you can redistribute it and/or modify
6
+ // it under the terms of the GNU Affero General Public License as published by
7
+ // the Free Software Foundation, either version 3 of the License, or
8
+ // (at your option) any later version.
9
+ //
10
+ // This program is distributed in the hope that it will be useful,
11
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ // GNU Affero General Public License for more details.
14
+ //
15
+ // You should have received a copy of the GNU Affero General Public License
16
+ // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+
18
+ // apps/admin/src/routes/_nav/ai-prompts/index/route.lazy.tsx
19
+ import { createLazyFileRoute } from "@tanstack/react-router"
20
+
21
+ import { m } from "@/paraglide/messages.js"
22
+ import { PromptTable } from "@/components/ai-prompts/prompt-table"
23
+ import type { PromptTemplateRow } from "@/components/ai-prompts/prompt-utils"
24
+
25
+ export const Route = createLazyFileRoute("/_nav/ai-prompts/")({
26
+ component: AiPromptsPage,
27
+ })
28
+
29
+ function AiPromptsPage() {
30
+ const ctx = Route.useRouteContext() as {
31
+ promptTemplates?: PromptTemplateRow[]
32
+ }
33
+
34
+ return (
35
+ <div className="p-6 space-y-4">
36
+ <div className="space-y-1">
37
+ <h1 className="text-xl font-semibold">
38
+ {m["admin-ai_prompts_page_title"]()}
39
+ </h1>
40
+ <p className="text-sm text-muted-foreground">
41
+ {m["admin-ai_prompts_page_description"]()}
42
+ </p>
43
+ </div>
44
+ <PromptTable data={ctx.promptTemplates ?? []} />
45
+ </div>
46
+ )
47
+ }
@@ -0,0 +1,26 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ // AllBlue - 理想之海
3
+ // Copyright (C) 2026 AllBlue Contributors
4
+ //
5
+ // This program is free software: you can redistribute it and/or modify
6
+ // it under the terms of the GNU Affero General Public License as published by
7
+ // the Free Software Foundation, either version 3 of the License, or
8
+ // (at your option) any later version.
9
+ //
10
+ // This program is distributed in the hope that it will be useful,
11
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ // GNU Affero General Public License for more details.
14
+ //
15
+ // You should have received a copy of the GNU Affero General Public License
16
+ // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+
18
+ import { createLazyFileRoute, Outlet } from "@tanstack/react-router"
19
+
20
+ export const Route = createLazyFileRoute("/_nav/ai-prompts")({
21
+ component: AiPromptsLayout,
22
+ })
23
+
24
+ function AiPromptsLayout() {
25
+ return <Outlet />
26
+ }
@@ -0,0 +1,31 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-or-later
2
+ // AllBlue - 理想之海
3
+ // Copyright (C) 2026 AllBlue Contributors
4
+ //
5
+ // This program is free software: you can redistribute it and/or modify
6
+ // it under the terms of the GNU Affero General Public License as published by
7
+ // the Free Software Foundation, either version 3 of the License, or
8
+ // (at your option) any later version.
9
+ //
10
+ // This program is distributed in the hope that it will be useful,
11
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ // GNU Affero General Public License for more details.
14
+ //
15
+ // You should have received a copy of the GNU Affero General Public License
16
+ // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+
18
+ import { createFileRoute } from "@tanstack/react-router"
19
+ import { listPromptTemplatesFn } from "@/server/serverFns/ai-prompts/list"
20
+
21
+ export const Route = createFileRoute("/_nav/ai-prompts")({
22
+ beforeLoad: async () => {
23
+ try {
24
+ const templates = await listPromptTemplatesFn({ data: {} })
25
+ return { promptTemplates: templates }
26
+ } catch (e) {
27
+ console.error("[admin/ai-prompts] failed to load", e)
28
+ return { promptTemplates: [] }
29
+ }
30
+ },
31
+ })
@@ -19,7 +19,7 @@ import { createLazyFileRoute } from '@tanstack/react-router'
19
19
  import { m } from '@/paraglide/messages.js'
20
20
  import { useQuery, useQueryClient } from '@tanstack/react-query'
21
21
  import { useServerFn } from '@tanstack/react-start'
22
- import { toast } from 'sonner'
22
+ import { toast } from '@/components/ui/toast'
23
23
  import type React from 'react'
24
24
  import { listComplianceExportsFn, executeComplianceJobFn } from '@/server/serverFns/compliance'
25
25
  import { Badge } from '@/components/ui/badge'
@@ -160,9 +160,7 @@ function CompliancePage(): React.ReactElement {
160
160
  href={`/api/compliance-download/${item.id}`}
161
161
  download={`allblue-export-${item.id}.json`}
162
162
  >
163
- <Button variant="outline" size="sm" asChild={false}>
164
- <span>{m.enterprise_compliance_export_actions_download()}</span>
165
- </Button>
163
+ <Button render={<span />} variant="outline" size="sm" nativeButton={false}>{m.enterprise_compliance_export_actions_download()}</Button>
166
164
  </a>
167
165
  )}
168
166
  {isExpired(item) && (
@@ -36,7 +36,7 @@ import { ComponentTable, type ComponentItem } from '@/components/component/compo
36
36
  import { ComponentFormDialog } from '@/components/component/component-form-dialog'
37
37
  import { ComponentImportDialog } from '@/components/component/component-import-dialog'
38
38
  import { deleteComponentFn } from '@/server/serverFns/components/mutations'
39
- import { toast } from '@/components/ui/sonner'
39
+ import { toast } from '@/components/ui/toast'
40
40
 
41
41
  const CATEGORY_TABS = [
42
42
  { key: 'all', label: '全部' },
@@ -51,7 +51,7 @@ import {
51
51
  AlertDialogHeader,
52
52
  AlertDialogTitle,
53
53
  } from '@/components/ui/alert-dialog'
54
- import { toast } from '@/components/ui/sonner'
54
+ import { toast } from '@/components/ui/toast'
55
55
  import {
56
56
  BookmarkFormDialog,
57
57
  type BookmarkRow,
@@ -33,7 +33,7 @@ import {
33
33
  AlertDialogHeader,
34
34
  AlertDialogTitle,
35
35
  } from '@/components/ui/alert-dialog'
36
- import { toast } from '@/components/ui/sonner'
36
+ import { toast } from '@/components/ui/toast'
37
37
  import {
38
38
  ComplianceFormDialog,
39
39
  type ComplianceRow,
@@ -33,7 +33,7 @@ import {
33
33
  AlertDialogHeader,
34
34
  AlertDialogTitle,
35
35
  } from '@/components/ui/alert-dialog'
36
- import { toast } from '@/components/ui/sonner'
36
+ import { toast } from '@/components/ui/toast'
37
37
  import { LegalFormDialog, type LegalRow } from '@/components/knowledge-public/legal-form-dialog'
38
38
  import { adminDeleteLegalFn } from '@/server/serverFns/knowledge-public/legal/delete'
39
39
 
@@ -18,7 +18,7 @@
18
18
  import { createLazyFileRoute, Link, useNavigate } from '@tanstack/react-router'
19
19
  import { m } from '@/paraglide/messages.js'
20
20
  import { useServerFn } from '@tanstack/react-start'
21
- import { toast } from 'sonner'
21
+ import { toast } from '@/components/ui/toast'
22
22
  import type React from 'react'
23
23
  import { Button } from '@/components/ui/button'
24
24
  import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'