@allbluecn/admin-app 0.3.2 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/allblue-ui/package.json +6 -0
  2. package/allblue-ui/src/components/confirm-dialog.tsx +94 -0
  3. package/allblue-ui/src/components/infinite-scroll-sentinel.tsx +37 -0
  4. package/allblue-ui/src/components/notion-avatar.tsx +126 -0
  5. package/allblue-ui/src/components/user-avatar.tsx +82 -0
  6. package/{src/components → allblue-ui/src}/data-table/data-table-pagination.tsx +14 -5
  7. package/{src/components → allblue-ui/src}/data-table/data-table.tsx +1 -1
  8. package/{src/components → allblue-ui/src}/data-table/table-detail-layout.tsx +5 -6
  9. package/allblue-ui/src/hooks/use-load-more.ts +57 -0
  10. package/allblue-ui/src/index.ts +31 -0
  11. package/allblue-ui/src/lib/datetime.ts +226 -0
  12. package/allblue-ui/src/lib/sanitize.ts +18 -0
  13. package/allblue-ui/src/lib/utils.ts +1 -0
  14. package/{src/components → allblue-ui/src}/ui/alert-dialog.tsx +1 -3
  15. package/{src/components → allblue-ui/src}/ui/checkbox.tsx +0 -1
  16. package/{src/components → allblue-ui/src}/ui/dialog.tsx +1 -1
  17. package/{src/components → allblue-ui/src}/ui/dropdown-menu.tsx +0 -2
  18. package/{src/components → allblue-ui/src}/ui/field.tsx +2 -2
  19. package/{src/components → allblue-ui/src}/ui/input-group.tsx +3 -4
  20. package/allblue-ui/src/ui/input.tsx +19 -0
  21. package/{src/components → allblue-ui/src}/ui/pagination.tsx +1 -1
  22. package/{src/components → allblue-ui/src}/ui/select.tsx +0 -2
  23. package/{src/components → allblue-ui/src}/ui/separator.tsx +1 -0
  24. package/{src/components → allblue-ui/src}/ui/sheet.tsx +1 -2
  25. package/{src/components → allblue-ui/src}/ui/sidebar.tsx +7 -7
  26. package/{src/components → allblue-ui/src}/ui/switch.tsx +1 -0
  27. package/{src/components → allblue-ui/src}/ui/table.tsx +0 -2
  28. package/{src/components → allblue-ui/src}/ui/toast.tsx +44 -18
  29. package/{src/components → allblue-ui/src}/ui/tooltip.tsx +1 -0
  30. package/package.json +21 -18
  31. package/src/components/admin/admin-user-menu.tsx +4 -4
  32. package/src/components/admin/developer-log.tsx +16 -32
  33. package/src/components/ai-memory/memory-facts-panel.tsx +30 -70
  34. package/src/components/ai-prompts/preview-panel.tsx +1 -1
  35. package/src/components/ai-prompts/prompt-editor.tsx +8 -9
  36. package/src/components/ai-prompts/prompt-table.tsx +6 -6
  37. package/src/components/ai-prompts/section-editor.tsx +3 -3
  38. package/src/components/ai-prompts/variable-panel.tsx +2 -2
  39. package/src/components/ai-prompts/version-history.tsx +21 -41
  40. package/src/components/ai-provider/model-list-editor.tsx +2 -3
  41. package/src/components/ai-provider/provider-form.tsx +7 -7
  42. package/src/components/ai-provider/provider-table.tsx +17 -40
  43. package/src/components/auth/admin-login-form.tsx +7 -7
  44. package/src/components/auth/icon-input.tsx +2 -2
  45. package/src/components/auth/password-input.tsx +2 -2
  46. package/src/components/component/component-form-dialog.tsx +10 -18
  47. package/src/components/component/component-import-dialog.tsx +6 -6
  48. package/src/components/component/component-preview.tsx +311 -0
  49. package/src/components/component/component-table.tsx +3 -3
  50. package/src/components/dependency/changelog-dialog.tsx +2 -2
  51. package/src/components/dependency/columns.tsx +3 -3
  52. package/src/components/dependency/dependency-table.tsx +7 -7
  53. package/src/components/dependency/edit-dialog.tsx +8 -8
  54. package/src/components/invitations/invitations-page.tsx +26 -49
  55. package/src/components/knowledge-public/bookmark-form-dialog.tsx +6 -6
  56. package/src/components/knowledge-public/compliance-form-dialog.tsx +6 -6
  57. package/src/components/knowledge-public/legal-form-dialog.tsx +7 -7
  58. package/src/components/layout/sidebar-02/app-sidebar.tsx +1 -2
  59. package/src/components/layout/sidebar-02/index.tsx +1 -1
  60. package/src/components/layout/sidebar-02/nav-main.tsx +2 -3
  61. package/src/components/layout/sidebar-02/nav-notifications.tsx +3 -3
  62. package/src/components/market/columns.tsx +4 -4
  63. package/src/components/market/market-app-form.tsx +6 -7
  64. package/src/components/market/market-app-list.tsx +14 -29
  65. package/src/components/monitoring/error-list.tsx +2 -2
  66. package/src/components/monitoring/metrics-stats.tsx +1 -1
  67. package/src/components/monitoring/request-log-table.tsx +2 -2
  68. package/src/components/oauth-providers/provider-page.tsx +20 -38
  69. package/src/components/permissions/assign-dialog.tsx +135 -0
  70. package/src/components/permissions/create-role-dialog.tsx +135 -0
  71. package/src/components/permissions/types.ts +49 -0
  72. package/src/components/user/columns.tsx +6 -6
  73. package/src/components/user/settings-activity-log.tsx +7 -7
  74. package/src/components/user/settings-profile/avatar-uploader.tsx +118 -0
  75. package/src/components/user/settings-profile/social-links.tsx +63 -0
  76. package/src/components/user/settings-profile.tsx +26 -125
  77. package/src/components/user/user-create-dialog.tsx +6 -6
  78. package/src/components/user/user-detail/error-boundary.tsx +19 -0
  79. package/src/components/user/user-detail/user-detail-dialogs.tsx +203 -0
  80. package/src/components/user/user-filters.tsx +4 -4
  81. package/src/lib/auth/page-gate.ts +28 -0
  82. package/src/lib/auth.config.ts +25 -9
  83. package/src/lib/i18n/detect.ts +1 -1
  84. package/src/lib/loader-serial.ts +14 -0
  85. package/src/providers/index.tsx +1 -1
  86. package/src/routeTree.gen.ts +67 -78
  87. package/src/routes/__root.tsx +4 -4
  88. package/src/routes/_nav/audit/route.lazy.tsx +1 -2
  89. package/src/routes/_nav/compliance/route.lazy.tsx +5 -3
  90. package/src/routes/_nav/components/route.lazy.tsx +14 -34
  91. package/src/routes/_nav/knowledge-public/bookmarks/route.lazy.tsx +18 -38
  92. package/src/routes/_nav/knowledge-public/compliance/route.lazy.tsx +18 -38
  93. package/src/routes/_nav/knowledge-public/legal/route.lazy.tsx +6 -6
  94. package/src/routes/_nav/licenses/$licenseId/route.lazy.tsx +3 -3
  95. package/src/routes/_nav/licenses/new/route.lazy.tsx +5 -5
  96. package/src/routes/_nav/licenses/route.lazy.tsx +1 -1
  97. package/src/routes/_nav/monitoring/ai-usage/route.lazy.tsx +2 -2
  98. package/src/routes/_nav/monitoring/errors/route.lazy.tsx +10 -10
  99. package/src/routes/_nav/monitoring/errors/route.tsx +7 -0
  100. package/src/routes/_nav/monitoring/health/route.lazy.tsx +13 -15
  101. package/src/routes/_nav/monitoring/health/route.tsx +14 -0
  102. package/src/routes/_nav/monitoring/logs/route.lazy.tsx +24 -9
  103. package/src/routes/_nav/monitoring/logs/route.tsx +13 -0
  104. package/src/routes/_nav/monitoring/metrics/route.lazy.tsx +12 -14
  105. package/src/routes/_nav/monitoring/metrics/route.tsx +7 -0
  106. package/src/routes/_nav/monitoring/overview/route.lazy.tsx +14 -13
  107. package/src/routes/_nav/monitoring/overview/route.tsx +17 -0
  108. package/src/routes/_nav/monitoring/route.lazy.tsx +6 -6
  109. package/src/routes/_nav/monitoring/sentry/route.lazy.tsx +2 -2
  110. package/src/routes/_nav/permissions/route.lazy.tsx +21 -311
  111. package/src/routes/_nav/permissions/route.tsx +1 -1
  112. package/src/routes/_nav/route.tsx +5 -13
  113. package/src/routes/_nav/sso/route.lazy.tsx +2 -3
  114. package/src/routes/_nav/users/$userId/route.lazy.tsx +91 -156
  115. package/src/routes/_nav/users/-components/users-table.tsx +1 -1
  116. package/src/routes/_nav/users/route.lazy.tsx +1 -1
  117. package/src/routes/login/route.lazy.tsx +1 -1
  118. package/src/routes/setup/route.lazy.tsx +2 -2
  119. package/src/server/__tests__/admin-billing.test.ts +191 -16
  120. package/src/server/__tests__/compliance.test.ts +44 -7
  121. package/src/server/__tests__/permissions.test.ts +10 -5
  122. package/src/server/__tests__/prompt-defaults.test.ts +3 -3
  123. package/src/server/admin-ai-alerts.ts +2 -1
  124. package/src/server/admin-ai-usage.ts +2 -1
  125. package/src/server/ai-memory/store.ts +6 -2
  126. package/src/server/{serverFns/ai-prompts → ai-prompts}/prompt-defaults.ts +5 -3
  127. package/src/server/{serverFns/dependency → dependency}/helpers.ts +4 -3
  128. package/src/server/knowledge-public/github-sync.ts +2 -1
  129. package/src/server/license-issue.ts +2 -1
  130. package/src/server/middlewares/auth-rate-limit.ts +117 -0
  131. package/src/server/observability/health-check.ts +4 -1
  132. package/src/server/observability/metrics.ts +17 -15
  133. package/src/server/observability/request-middleware.ts +2 -1
  134. package/src/server/observability/timing.ts +14 -16
  135. package/src/server/serverFns/admin-billing.ts +107 -12
  136. package/src/server/serverFns/ai-memory/list-users.ts +2 -1
  137. package/src/server/serverFns/ai-prompts/activate.ts +2 -1
  138. package/src/server/serverFns/ai-prompts/get.ts +3 -2
  139. package/src/server/serverFns/ai-prompts/list.ts +3 -2
  140. package/src/server/serverFns/ai-prompts/rollback.ts +3 -1
  141. package/src/server/serverFns/ai-prompts/save.ts +5 -3
  142. package/src/server/serverFns/ai-provider/create.ts +4 -1
  143. package/src/server/serverFns/ai-provider/delete.ts +4 -1
  144. package/src/server/serverFns/ai-provider/get.ts +4 -1
  145. package/src/server/serverFns/ai-provider/list.ts +28 -1
  146. package/src/server/serverFns/ai-provider/seed-from-seed.ts +2 -1
  147. package/src/server/serverFns/ai-provider/update.ts +4 -1
  148. package/src/server/serverFns/anyhub/market.ts +8 -1
  149. package/src/server/serverFns/audit.ts +14 -1
  150. package/src/server/serverFns/auth/setup.ts +3 -1
  151. package/src/server/serverFns/compliance.ts +32 -3
  152. package/src/server/serverFns/components/import.ts +69 -14
  153. package/src/server/serverFns/components/list.ts +4 -1
  154. package/src/server/serverFns/components/mutations.ts +9 -1
  155. package/src/server/serverFns/dependency/list.ts +28 -5
  156. package/src/server/serverFns/dependency/sync.ts +7 -2
  157. package/src/server/serverFns/dependency/update.ts +4 -1
  158. package/src/server/serverFns/developer-log-auto-generate.ts +63 -32
  159. package/src/server/serverFns/developer-logs.ts +5 -1
  160. package/src/server/serverFns/invitations.ts +7 -1
  161. package/src/server/serverFns/knowledge-public/bookmarks/create.ts +2 -1
  162. package/src/server/serverFns/knowledge-public/bookmarks/delete.ts +2 -1
  163. package/src/server/serverFns/knowledge-public/bookmarks/detail.ts +2 -1
  164. package/src/server/serverFns/knowledge-public/bookmarks/list.ts +2 -1
  165. package/src/server/serverFns/knowledge-public/bookmarks/sync-all-github.ts +2 -1
  166. package/src/server/serverFns/knowledge-public/bookmarks/update.ts +2 -1
  167. package/src/server/serverFns/knowledge-public/compliance/create.ts +2 -1
  168. package/src/server/serverFns/knowledge-public/compliance/delete.ts +2 -1
  169. package/src/server/serverFns/knowledge-public/compliance/detail.ts +2 -1
  170. package/src/server/serverFns/knowledge-public/compliance/list.ts +2 -1
  171. package/src/server/serverFns/knowledge-public/compliance/update.ts +2 -1
  172. package/src/server/serverFns/knowledge-public/legal/create.ts +2 -1
  173. package/src/server/serverFns/knowledge-public/legal/delete.ts +2 -1
  174. package/src/server/serverFns/knowledge-public/legal/detail.ts +2 -1
  175. package/src/server/serverFns/knowledge-public/legal/list.ts +2 -1
  176. package/src/server/serverFns/knowledge-public/legal/update.ts +2 -1
  177. package/src/server/serverFns/licenses.ts +8 -2
  178. package/src/server/serverFns/monitoring/get-errors.ts +2 -1
  179. package/src/server/serverFns/monitoring/get-health.ts +2 -1
  180. package/src/server/serverFns/monitoring/get-metrics.ts +2 -1
  181. package/src/server/serverFns/monitoring/get-request-logs.ts +2 -1
  182. package/src/server/serverFns/monitoring/report-error.ts +2 -1
  183. package/src/server/serverFns/monitoring/reset.ts +2 -1
  184. package/src/server/serverFns/oauth-providers.ts +4 -1
  185. package/src/server/serverFns/permissions.ts +18 -11
  186. package/src/server/serverFns/sentry/config.ts +11 -8
  187. package/src/server/serverFns/sso-config.ts +17 -2
  188. package/src/server/serverFns/user/create.ts +6 -1
  189. package/src/server/serverFns/user/delete.ts +6 -1
  190. package/src/server/serverFns/user/detail.ts +5 -2
  191. package/src/server/serverFns/user/list.ts +19 -4
  192. package/src/server/serverFns/user/reset-password.ts +10 -2
  193. package/src/server/serverFns/user/update-role.ts +10 -2
  194. package/src/server/serverFns/user/update-status.ts +10 -2
  195. package/src/styles/globals.css +4 -0
  196. package/src/components/ui/input.tsx +0 -19
  197. /package/{src → allblue-ui/src}/hooks/use-mobile.ts +0 -0
  198. /package/{src → allblue-ui/src}/lib/avatar.ts +0 -0
  199. /package/{src/components → allblue-ui/src}/ui/alert.tsx +0 -0
  200. /package/{src/components → allblue-ui/src}/ui/avatar.tsx +0 -0
  201. /package/{src/components → allblue-ui/src}/ui/badge.tsx +0 -0
  202. /package/{src/components → allblue-ui/src}/ui/button.tsx +0 -0
  203. /package/{src/components → allblue-ui/src}/ui/card.tsx +0 -0
  204. /package/{src/components → allblue-ui/src}/ui/collapsible.tsx +0 -0
  205. /package/{src/components → allblue-ui/src}/ui/label.tsx +0 -0
  206. /package/{src/components → allblue-ui/src}/ui/skeleton.tsx +0 -0
  207. /package/{src/components → allblue-ui/src}/ui/textarea.tsx +0 -0
  208. /package/src/routes/{api.auth.$.ts → api/auth/$.ts} +0 -0
  209. /package/src/routes/{api.sentry-test.ts → api/sentry-test.ts} +0 -0
@@ -4,7 +4,7 @@ import { Route } from '@/routes/_nav/developer-logs/route'
4
4
  import type { DeveloperLogEntry } from '@allbluecn/kernel'
5
5
  import { useQueryClient } from '@tanstack/react-query'
6
6
  import { useServerFn } from '@tanstack/react-start'
7
- import { toast } from '@/components/ui/toast'
7
+ import { toast } from '@allbluecn/ui/toast'
8
8
  import {
9
9
  Plus,
10
10
  Pencil,
@@ -19,22 +19,12 @@ import {
19
19
  DialogHeader,
20
20
  DialogTitle,
21
21
  DialogFooter,
22
- } from '@/components/ui/dialog'
23
- import {
24
- AlertDialog,
25
- AlertDialogAction,
26
- AlertDialogCancel,
27
- AlertDialogContent,
28
- AlertDialogDescription,
29
- AlertDialogFooter,
30
- AlertDialogHeader,
31
- AlertDialogTitle,
32
- AlertDialogTrigger,
33
- } from '@/components/ui/alert-dialog'
34
- import { Input } from '@/components/ui/input'
35
- import { Textarea } from '@/components/ui/textarea'
36
- import { Label } from '@/components/ui/label'
37
- import { Button } from '@/components/ui/button'
22
+ } from '@allbluecn/ui/dialog'
23
+ import { ConfirmDialog } from '@allbluecn/ui/components/confirm-dialog'
24
+ import { Input } from '@allbluecn/ui/input'
25
+ import { Textarea } from '@allbluecn/ui/textarea'
26
+ import { Label } from '@allbluecn/ui/label'
27
+ import { Button } from '@allbluecn/ui/button'
38
28
  import { createDeveloperLogFn, updateDeveloperLogFn, deleteDeveloperLogFn } from '@/server/serverFns/developer-logs'
39
29
  import { autoGenerateLogsFn, backfillLogDetailsFn } from '@/server/serverFns/developer-log-auto-generate'
40
30
 
@@ -315,21 +305,15 @@ function DeveloperLogPage() {
315
305
  <Button variant="ghost" size="icon" className="size-7" onClick={() => handleEdit(entry)}>
316
306
  <Pencil className="size-3.5" />
317
307
  </Button>
318
- <AlertDialog>
319
- <AlertDialogTrigger render={<Button variant="ghost" size="icon" className="size-7 text-destructive" />}>
320
- <Trash2 className="size-3.5" />
321
- </AlertDialogTrigger>
322
- <AlertDialogContent>
323
- <AlertDialogHeader>
324
- <AlertDialogTitle>{m.common_button_delete()}</AlertDialogTitle>
325
- <AlertDialogDescription>{m.common_developerLogs_deleteConfirm()}</AlertDialogDescription>
326
- </AlertDialogHeader>
327
- <AlertDialogFooter>
328
- <AlertDialogCancel>{m.common_button_cancel()}</AlertDialogCancel>
329
- <AlertDialogAction onClick={() => handleDelete(entry.id)} className="bg-destructive hover:bg-destructive/90">{m.common_button_confirm()}</AlertDialogAction>
330
- </AlertDialogFooter>
331
- </AlertDialogContent>
332
- </AlertDialog>
308
+ <ConfirmDialog
309
+ trigger={<Button variant="ghost" size="icon" className="size-7 text-destructive"><Trash2 className="size-3.5" /></Button>}
310
+ title={m.common_button_delete()}
311
+ description={m.common_developerLogs_deleteConfirm()}
312
+ cancelLabel={m.common_button_cancel()}
313
+ confirmLabel={m.common_button_confirm()}
314
+ confirmClassName="bg-destructive hover:bg-destructive/90"
315
+ onConfirm={() => handleDelete(entry.id)}
316
+ />
333
317
  </div>
334
318
  </td>
335
319
  </tr>
@@ -20,37 +20,27 @@ import { useMemo, useState } from "react"
20
20
  import {
21
21
  Eraser,
22
22
  Loader2,
23
- RotateCw,
24
23
  Search,
25
24
  TriangleAlert,
26
25
  Trash2,
27
26
  } from "lucide-react"
28
27
 
29
28
  import { m } from "@/paraglide/messages.js"
30
- import { formatTimestamp } from "@allbluecn/web-app/lib/datetime"
31
- import { toast } from "@/components/ui/toast"
32
- import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
33
- import { Badge } from "@/components/ui/badge"
34
- import { Button } from "@/components/ui/button"
35
- import { Card, CardContent } from "@/components/ui/card"
36
- import {
37
- AlertDialog,
38
- AlertDialogAction,
39
- AlertDialogCancel,
40
- AlertDialogContent,
41
- AlertDialogDescription,
42
- AlertDialogFooter,
43
- AlertDialogHeader,
44
- AlertDialogTitle,
45
- } from "@/components/ui/alert-dialog"
29
+ import { formatTimestamp } from "@allbluecn/ui/lib/datetime"
30
+ import { toast } from "@allbluecn/ui/toast"
31
+ import { Alert, AlertDescription, AlertTitle } from "@allbluecn/ui/alert"
32
+ import { Badge } from "@allbluecn/ui/badge"
33
+ import { Button } from "@allbluecn/ui/button"
34
+ import { Card, CardContent } from "@allbluecn/ui/card"
35
+ import { ConfirmDialog } from "@allbluecn/ui/components/confirm-dialog"
46
36
  import {
47
37
  Select,
48
38
  SelectContent,
49
39
  SelectItem,
50
40
  SelectTrigger,
51
41
  SelectValue,
52
- } from "@/components/ui/select"
53
- import { DataTable, type AdminColumnDef } from "@/components/data-table/data-table"
42
+ } from "@allbluecn/ui/select"
43
+ import { DataTable, type AdminColumnDef } from "@allbluecn/ui/data-table"
54
44
  import { listMemoryFactsFn } from "@/server/serverFns/ai-memory/list"
55
45
  import { deleteMemoryFactFn } from "@/server/serverFns/ai-memory/delete"
56
46
  import { clearMemoryFactsFn } from "@/server/serverFns/ai-memory/clear"
@@ -322,62 +312,32 @@ export function MemoryFactsPanel({
322
312
  </CardContent>
323
313
  </Card>
324
314
 
325
- <AlertDialog open={pendingDelete !== null} onOpenChange={(open) => { if (!open) setPendingDelete(null) }}>
326
- <AlertDialogContent>
327
- <AlertDialogHeader>
328
- <AlertDialogTitle>
329
- {m["admin-ai-memory_delete_confirm_title"]()}
330
- </AlertDialogTitle>
331
- <AlertDialogDescription>
332
- {m["admin-ai-memory_delete_confirm_description"]()}
333
- </AlertDialogDescription>
334
- </AlertDialogHeader>
335
- <AlertDialogFooter>
336
- <AlertDialogCancel>
337
- {m["admin-ai-memory_delete_cancel"]()}
338
- </AlertDialogCancel>
339
- <AlertDialogAction
340
- disabled={deletingId !== null}
341
- onClick={(event) => {
342
- if (!pendingDelete) return
343
- event.preventDefault()
344
- void handleDelete(pendingDelete, () => setPendingDelete(null))
345
- }}
346
- >
347
- {m["admin-ai-memory_delete_confirm_action"]()}
348
- </AlertDialogAction>
349
- </AlertDialogFooter>
350
- </AlertDialogContent>
351
- </AlertDialog>
315
+ <ConfirmDialog
316
+ open={pendingDelete !== null}
317
+ onOpenChange={(open) => { if (!open) setPendingDelete(null) }}
318
+ title={m["admin-ai-memory_delete_confirm_title"]()}
319
+ description={m["admin-ai-memory_delete_confirm_description"]()}
320
+ cancelLabel={m["admin-ai-memory_delete_cancel"]()}
321
+ confirmLabel={m["admin-ai-memory_delete_confirm_action"]()}
322
+ confirmDisabled={deletingId !== null}
323
+ onConfirm={() => {
324
+ if (!pendingDelete) return
325
+ void handleDelete(pendingDelete, () => setPendingDelete(null))
326
+ }}
327
+ />
352
328
 
353
- <AlertDialog
329
+ <ConfirmDialog
354
330
  open={confirmingClear}
355
331
  onOpenChange={(open) => {
356
332
  if (!open) setConfirmingClear(false)
357
333
  }}
358
- >
359
- <AlertDialogContent>
360
- <AlertDialogHeader>
361
- <AlertDialogTitle>
362
- {m["admin-ai-memory_clear_confirm_title"]()}
363
- </AlertDialogTitle>
364
- <AlertDialogDescription>
365
- {m["admin-ai-memory_clear_confirm_description"]()}
366
- </AlertDialogDescription>
367
- </AlertDialogHeader>
368
- <AlertDialogFooter>
369
- <AlertDialogCancel>
370
- {m["admin-ai-memory_clear_cancel"]()}
371
- </AlertDialogCancel>
372
- <AlertDialogAction
373
- disabled={loading}
374
- onClick={() => void handleClear()}
375
- >
376
- {m["admin-ai-memory_clear_confirm_action"]()}
377
- </AlertDialogAction>
378
- </AlertDialogFooter>
379
- </AlertDialogContent>
380
- </AlertDialog>
334
+ title={m["admin-ai-memory_clear_confirm_title"]()}
335
+ description={m["admin-ai-memory_clear_confirm_description"]()}
336
+ cancelLabel={m["admin-ai-memory_clear_cancel"]()}
337
+ confirmLabel={m["admin-ai-memory_clear_confirm_action"]()}
338
+ confirmDisabled={loading}
339
+ onConfirm={() => void handleClear()}
340
+ />
381
341
  </div>
382
342
  )
383
343
  }
@@ -20,7 +20,7 @@ import { useCallback, useEffect, useRef, useState } from "react"
20
20
  import { AlertTriangle, Loader2 } from "lucide-react"
21
21
 
22
22
  import { m } from "@/paraglide/messages.js"
23
- import { Input } from "@/components/ui/input"
23
+ import { Input } from "@allbluecn/ui/input"
24
24
  import {
25
25
  PROMPT_PREVIEW_DEBOUNCE_MS,
26
26
  useDebouncedCallback,
@@ -18,7 +18,6 @@
18
18
  // apps/admin/src/components/ai-prompts/prompt-editor.tsx
19
19
  import { useCallback, useEffect, useState } from "react"
20
20
  import type {
21
- SystemPromptSectionDTO,
22
21
  SystemPromptTemplateDTO,
23
22
  } from "@allbluecn/kernel"
24
23
  import { useMutation } from "@tanstack/react-query"
@@ -26,18 +25,18 @@ import { Link } from "@tanstack/react-router"
26
25
  import { ArrowLeft, Loader2, Save, ShieldCheck } from "lucide-react"
27
26
 
28
27
  import { m } from "@/paraglide/messages.js"
29
- import { toast } from "@/components/ui/toast"
30
- import { Badge } from "@/components/ui/badge"
31
- import { Button } from "@/components/ui/button"
32
- import { Field, FieldContent, FieldLabel } from "@/components/ui/field"
33
- import { Input } from "@/components/ui/input"
34
- import { Switch } from "@/components/ui/switch"
35
- import { Textarea } from "@/components/ui/textarea"
28
+ import { toast } from "@allbluecn/ui/toast"
29
+ import { Badge } from "@allbluecn/ui/badge"
30
+ import { Button } from "@allbluecn/ui/button"
31
+ import { Field, FieldContent, FieldLabel } from "@allbluecn/ui/field"
32
+ import { Input } from "@allbluecn/ui/input"
33
+ import { Switch } from "@allbluecn/ui/switch"
34
+ import { Textarea } from "@allbluecn/ui/textarea"
36
35
  import {
37
36
  Tooltip,
38
37
  TooltipContent,
39
38
  TooltipTrigger,
40
- } from "@/components/ui/tooltip"
39
+ } from "@allbluecn/ui/tooltip"
41
40
  import { activatePromptTemplateFn } from "@/server/serverFns/ai-prompts/activate"
42
41
  import { getPromptTemplateFn } from "@/server/serverFns/ai-prompts/get"
43
42
  import { rollbackPromptTemplateFn } from "@/server/serverFns/ai-prompts/rollback"
@@ -19,14 +19,14 @@
19
19
  import { useMutation } from "@tanstack/react-query"
20
20
  import { Link, useRouter } from "@tanstack/react-router"
21
21
  import { Edit, ShieldCheck } from "lucide-react"
22
- import { formatTimestamp } from "@allbluecn/web-app/lib/datetime"
22
+ import { formatTimestamp } from "@allbluecn/ui/lib/datetime"
23
23
 
24
24
  import { m } from "@/paraglide/messages.js"
25
- import { toast } from "@/components/ui/toast"
26
- import { Badge } from "@/components/ui/badge"
27
- import { Button } from "@/components/ui/button"
28
- import { Switch } from "@/components/ui/switch"
29
- import { DataTable, type AdminColumnDef } from "@/components/data-table/data-table"
25
+ import { toast } from "@allbluecn/ui/toast"
26
+ import { Badge } from "@allbluecn/ui/badge"
27
+ import { Button } from "@allbluecn/ui/button"
28
+ import { Switch } from "@allbluecn/ui/switch"
29
+ import { DataTable, type AdminColumnDef } from "@allbluecn/ui/data-table"
30
30
  import { activatePromptTemplateFn } from "@/server/serverFns/ai-prompts/activate"
31
31
  import type { PromptTemplateRow } from "./prompt-utils"
32
32
 
@@ -19,9 +19,9 @@
19
19
  import { ArrowDown, ArrowUp, Plus, Trash2 } from "lucide-react"
20
20
 
21
21
  import { m } from "@/paraglide/messages.js"
22
- import { Button } from "@/components/ui/button"
23
- import { Input } from "@/components/ui/input"
24
- import { Textarea } from "@/components/ui/textarea"
22
+ import { Button } from "@allbluecn/ui/button"
23
+ import { Input } from "@allbluecn/ui/input"
24
+ import { Textarea } from "@allbluecn/ui/textarea"
25
25
  import {
26
26
  appendSection,
27
27
  moveSection,
@@ -19,8 +19,8 @@
19
19
  import { AlertTriangle, Plus, Trash2 } from "lucide-react"
20
20
 
21
21
  import { m } from "@/paraglide/messages.js"
22
- import { Button } from "@/components/ui/button"
23
- import { Input } from "@/components/ui/input"
22
+ import { Button } from "@allbluecn/ui/button"
23
+ import { Input } from "@allbluecn/ui/input"
24
24
  import {
25
25
  addVariable,
26
26
  removeVariable,
@@ -18,26 +18,17 @@
18
18
  // apps/admin/src/components/ai-prompts/version-history.tsx
19
19
  import { useState } from "react"
20
20
  import { History, Loader2, RotateCcw } from "lucide-react"
21
- import { formatTimestamp } from "@allbluecn/web-app/lib/datetime"
21
+ import { formatTimestamp } from "@allbluecn/ui/lib/datetime"
22
22
 
23
23
  import { m } from "@/paraglide/messages.js"
24
- import { Badge } from "@/components/ui/badge"
25
- import { Button } from "@/components/ui/button"
24
+ import { Badge } from "@allbluecn/ui/badge"
25
+ import { Button } from "@allbluecn/ui/button"
26
26
  import {
27
27
  Collapsible,
28
28
  CollapsibleContent,
29
29
  CollapsibleTrigger,
30
- } from "@/components/ui/collapsible"
31
- import {
32
- AlertDialog,
33
- AlertDialogAction,
34
- AlertDialogCancel,
35
- AlertDialogContent,
36
- AlertDialogDescription,
37
- AlertDialogFooter,
38
- AlertDialogHeader,
39
- AlertDialogTitle,
40
- } from "@/components/ui/alert-dialog"
30
+ } from "@allbluecn/ui/collapsible"
31
+ import { ConfirmDialog } from "@allbluecn/ui/components/confirm-dialog"
41
32
  import type { PromptVersionSummary } from "./prompt-utils"
42
33
 
43
34
  interface VersionHistoryProps {
@@ -125,33 +116,22 @@ export function VersionHistory({
125
116
  })}
126
117
  </CollapsibleContent>
127
118
 
128
- <AlertDialog open={rollbackTarget !== null} onOpenChange={(open) => { if (!open) setRollbackTarget(null) }}>
129
- <AlertDialogContent>
130
- <AlertDialogHeader>
131
- <AlertDialogTitle>
132
- {m["admin-ai_prompts_rollback_confirm_title"]({
133
- version: rollbackTarget ?? 0,
134
- })}
135
- </AlertDialogTitle>
136
- <AlertDialogDescription>
137
- {m["admin-ai_prompts_rollback_confirm_description"]({
138
- version: rollbackTarget ?? 0,
139
- })}
140
- </AlertDialogDescription>
141
- </AlertDialogHeader>
142
- <AlertDialogFooter>
143
- <AlertDialogCancel>{m.common_common_cancel()}</AlertDialogCancel>
144
- <AlertDialogAction
145
- disabled={rollbackPending}
146
- onClick={() => {
147
- if (rollbackTarget !== null) onRollback(rollbackTarget)
148
- }}
149
- >
150
- {m["admin-ai_prompts_rollback_confirm_action"]()}
151
- </AlertDialogAction>
152
- </AlertDialogFooter>
153
- </AlertDialogContent>
154
- </AlertDialog>
119
+ <ConfirmDialog
120
+ open={rollbackTarget !== null}
121
+ onOpenChange={(open) => { if (!open) setRollbackTarget(null) }}
122
+ title={m["admin-ai_prompts_rollback_confirm_title"]({
123
+ version: rollbackTarget ?? 0,
124
+ })}
125
+ description={m["admin-ai_prompts_rollback_confirm_description"]({
126
+ version: rollbackTarget ?? 0,
127
+ })}
128
+ cancelLabel={m.common_common_cancel()}
129
+ confirmLabel={m["admin-ai_prompts_rollback_confirm_action"]()}
130
+ confirmDisabled={rollbackPending}
131
+ onConfirm={() => {
132
+ if (rollbackTarget !== null) onRollback(rollbackTarget)
133
+ }}
134
+ />
155
135
  </Collapsible>
156
136
  )
157
137
  }
@@ -17,9 +17,8 @@
17
17
 
18
18
  // apps/admin/src/components/ai-provider/model-list-editor.tsx
19
19
  import { Plus, Trash2 } from "lucide-react"
20
- import { m } from '@/paraglide/messages.js'
21
- import { Button } from "@/components/ui/button"
22
- import { Input } from "@/components/ui/input"
20
+ import { Button } from "@allbluecn/ui/button"
21
+ import { Input } from "@allbluecn/ui/input"
23
22
  import { cn } from "@/lib/utils"
24
23
  import {
25
24
  MODEL_CAPABILITY_OPTIONS,
@@ -21,7 +21,7 @@ import { m } from '@/paraglide/messages.js'
21
21
  import { useMutation } from "@tanstack/react-query"
22
22
  import { Link, useNavigate, useRouter } from "@tanstack/react-router"
23
23
  import { ArrowLeft, Loader2, Save } from "lucide-react"
24
- import { toast } from '@/components/ui/toast'
24
+ import { toast } from '@allbluecn/ui/toast'
25
25
  import {
26
26
  ADAPTER_KINDS,
27
27
  PROVIDER_CATEGORIES,
@@ -29,17 +29,17 @@ import {
29
29
  type AdapterKind,
30
30
  type ProviderCategory,
31
31
  } from "@allbluecn/kernel"
32
- import { Button } from "@/components/ui/button"
33
- import { Input } from "@/components/ui/input"
34
- import { Textarea } from "@/components/ui/textarea"
35
- import { Switch } from "@/components/ui/switch"
32
+ import { Button } from "@allbluecn/ui/button"
33
+ import { Input } from "@allbluecn/ui/input"
34
+ import { Textarea } from "@allbluecn/ui/textarea"
35
+ import { Switch } from "@allbluecn/ui/switch"
36
36
  import {
37
37
  Select,
38
38
  SelectContent,
39
39
  SelectItem,
40
40
  SelectTrigger,
41
41
  SelectValue,
42
- } from "@/components/ui/select"
42
+ } from "@allbluecn/ui/select"
43
43
  import {
44
44
  Field,
45
45
  FieldContent,
@@ -49,7 +49,7 @@ import {
49
49
  FieldSet,
50
50
  FieldLegend,
51
51
  FieldSeparator,
52
- } from "@/components/ui/field"
52
+ } from "@allbluecn/ui/field"
53
53
  import { createAiProviderAdminFn } from "@/server/serverFns/ai-provider/create"
54
54
  import { updateAiProviderAdminFn } from "@/server/serverFns/ai-provider/update"
55
55
  import { ModelListEditor } from "./model-list-editor"
@@ -21,22 +21,13 @@ import { m } from '@/paraglide/messages.js'
21
21
  import { useMutation } from "@tanstack/react-query"
22
22
  import { Link, useRouter } from "@tanstack/react-router"
23
23
  import { Edit, Plus, RefreshCw, Trash2, Users } from "lucide-react"
24
- import { toast } from '@/components/ui/toast'
24
+ import { toast } from '@allbluecn/ui/toast'
25
25
  import { ADAPTER_KINDS, PROVIDER_BADGE_STYLES, type AiProviderRow } from "@allbluecn/kernel"
26
- import { Button } from "@/components/ui/button"
27
- import { Switch } from "@/components/ui/switch"
28
- import { Badge } from "@/components/ui/badge"
29
- import {
30
- AlertDialog,
31
- AlertDialogAction,
32
- AlertDialogCancel,
33
- AlertDialogContent,
34
- AlertDialogDescription,
35
- AlertDialogFooter,
36
- AlertDialogHeader,
37
- AlertDialogTitle,
38
- } from "@/components/ui/alert-dialog"
39
- import { DataTable, type AdminColumnDef } from "@/components/data-table/data-table"
26
+ import { Button } from "@allbluecn/ui/button"
27
+ import { Switch } from "@allbluecn/ui/switch"
28
+ import { Badge } from "@allbluecn/ui/badge"
29
+ import { ConfirmDialog } from "@allbluecn/ui/components/confirm-dialog"
30
+ import { DataTable, type AdminColumnDef } from "@allbluecn/ui/data-table"
40
31
  import { ProviderIcon } from "./provider-icon"
41
32
  import { updateAiProviderAdminFn } from "@/server/serverFns/ai-provider/update"
42
33
  import { deleteAiProviderAdminFn } from "@/server/serverFns/ai-provider/delete"
@@ -245,33 +236,19 @@ export function ProviderTable({ data }: { data: AiProviderRow[] }) {
245
236
  </div>
246
237
  <DataTable columns={columns} data={data} />
247
238
 
248
- <AlertDialog
239
+ <ConfirmDialog
249
240
  open={!!pendingDelete}
250
241
  onOpenChange={(open: boolean) => !open && setPendingDelete(null)}
251
- >
252
- <AlertDialogContent>
253
- <AlertDialogHeader>
254
- <AlertDialogTitle>
255
- {m['admin-ai_table_deleteConfirm_title']({ name: pendingDelete?.displayName ?? '' })}
256
- </AlertDialogTitle>
257
- <AlertDialogDescription>
258
- {m['admin-ai_table_deleteConfirm_description']()}
259
- </AlertDialogDescription>
260
- </AlertDialogHeader>
261
- <AlertDialogFooter>
262
- <AlertDialogCancel>{m.common_common_cancel()}</AlertDialogCancel>
263
- <AlertDialogAction
264
- className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
265
- onClick={() =>
266
- pendingDelete && deleteMutation.mutate(pendingDelete.id)
267
- }
268
- disabled={deleteMutation.isPending}
269
- >
270
- {m['admin-ai_table_deleteConfirm_confirm']()}
271
- </AlertDialogAction>
272
- </AlertDialogFooter>
273
- </AlertDialogContent>
274
- </AlertDialog>
242
+ title={m['admin-ai_table_deleteConfirm_title']({ name: pendingDelete?.displayName ?? '' })}
243
+ description={m['admin-ai_table_deleteConfirm_description']()}
244
+ cancelLabel={m.common_common_cancel()}
245
+ confirmLabel={m['admin-ai_table_deleteConfirm_confirm']()}
246
+ confirmClassName="bg-destructive text-destructive-foreground hover:bg-destructive/90"
247
+ confirmDisabled={deleteMutation.isPending}
248
+ onConfirm={() =>
249
+ pendingDelete && deleteMutation.mutate(pendingDelete.id)
250
+ }
251
+ />
275
252
  </div>
276
253
  )
277
254
  }
@@ -15,16 +15,16 @@
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 { LogOut, User, Mail, Users, BarChart3, Shield, Settings, ArrowRight, ArrowLeft, Target } from "lucide-react";
18
+ import { LogOut, Mail, Users, BarChart3, Shield, Settings, ArrowRight, ArrowLeft, Target } from "lucide-react";
19
19
  import { m } from '@/paraglide/messages.js'
20
20
  import { useState } from "react";
21
21
  import { signIn, signOut } from "@/lib/auth-client";
22
- import { Button } from "@/components/ui/button";
23
- import { Checkbox } from "@/components/ui/checkbox";
24
- import { Field, FieldLabel } from "@/components/ui/field";
25
- import { Card, CardContent } from "@/components/ui/card";
26
- import { toast } from '@/components/ui/toast';
27
- import { UserAvatar } from "@allbluecn/web-app/user-avatar";
22
+ import { Button } from "@allbluecn/ui/button";
23
+ import { Checkbox } from "@allbluecn/ui/checkbox";
24
+ import { Field, FieldLabel } from "@allbluecn/ui/field";
25
+ import { Card, CardContent } from "@allbluecn/ui/card";
26
+ import { toast } from '@allbluecn/ui/toast';
27
+ import { UserAvatar } from "@allbluecn/ui/components/user-avatar";
28
28
  import type { AvatarConfig, ShapeType } from "@allbluecn/kernel";
29
29
  import { AuthLayout, AuthLayoutLeft, AuthLayoutRight } from "@/components/auth/auth-layout";
30
30
  import { AuthHeader } from "@/components/auth/auth-header";
@@ -16,8 +16,8 @@
16
16
  // along with this program. If not, see <https://www.gnu.org/licenses/>.
17
17
 
18
18
 
19
- import { Input } from '@/components/ui/input'
20
- import { Label } from '@/components/ui/label'
19
+ import { Input } from '@allbluecn/ui/input'
20
+ import { Label } from '@allbluecn/ui/label'
21
21
  import type { LucideIcon } from 'lucide-react'
22
22
 
23
23
  interface IconInputProps extends React.InputHTMLAttributes<HTMLInputElement> {
@@ -17,8 +17,8 @@
17
17
 
18
18
  import { useState } from 'react'
19
19
  import { m } from '@/paraglide/messages.js'
20
- import { Input } from '@/components/ui/input'
21
- import { Label } from '@/components/ui/label'
20
+ import { Input } from '@allbluecn/ui/input'
21
+ import { Label } from '@allbluecn/ui/label'
22
22
  import { Lock } from 'lucide-react'
23
23
 
24
24
  interface PasswordInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'> {
@@ -17,28 +17,28 @@
17
17
 
18
18
  import { useState, useEffect } from 'react'
19
19
  import { m } from '@/paraglide/messages.js'
20
- import { Button } from '@/components/ui/button'
21
- import { Input } from '@/components/ui/input'
22
- import { Label } from '@/components/ui/label'
23
- import { Textarea } from '@/components/ui/textarea'
24
- import { Switch } from '@/components/ui/switch'
20
+ import { Button } from '@allbluecn/ui/button'
21
+ import { Input } from '@allbluecn/ui/input'
22
+ import { Label } from '@allbluecn/ui/label'
23
+ import { Textarea } from '@allbluecn/ui/textarea'
24
+ import { Switch } from '@allbluecn/ui/switch'
25
25
  import {
26
26
  Select,
27
27
  SelectContent,
28
28
  SelectItem,
29
29
  SelectTrigger,
30
30
  SelectValue,
31
- } from '@/components/ui/select'
31
+ } from '@allbluecn/ui/select'
32
32
  import {
33
33
  Dialog,
34
34
  DialogContent,
35
35
  DialogFooter,
36
36
  DialogHeader,
37
37
  DialogTitle,
38
- } from '@/components/ui/dialog'
39
- import { getComponent, ComponentPreview } from '@allbluecn/web-app/prototype'
38
+ } from '@allbluecn/ui/dialog'
39
+ import { ComponentPreview } from './component-preview'
40
40
  import { createComponentFn, updateComponentFn } from '@/server/serverFns/components/mutations'
41
- import { toast } from '@/components/ui/toast'
41
+ import { toast } from '@allbluecn/ui/toast'
42
42
  import type { ComponentItem } from './component-table'
43
43
 
44
44
  const CATEGORY_KEYS = ['base', 'block', 'template'] as const
@@ -153,19 +153,11 @@ export function ComponentFormDialog({ open, onOpenChange, component, onSuccess }
153
153
  if (!component) {
154
154
  return <span className="text-xs text-muted-foreground">{m.common_component_form_previewUnavailable()}</span>
155
155
  }
156
- const config = getComponent(component.prototypeKey ?? '')
157
- const Comp = config?.component
158
- if (Comp) {
159
- return (
160
- <div className="pointer-events-none flex h-full w-full items-center justify-center overflow-hidden p-3">
161
- <Comp props={propsState} style={(component.defaultStyle as Record<string, any>) ?? {}} />
162
- </div>
163
- )
164
- }
165
156
  return (
166
157
  <ComponentPreview
167
158
  type={component.type}
168
159
  name={component.name}
160
+ prototypeKey={component.prototypeKey}
169
161
  defaultProps={propsState}
170
162
  defaultStyle={component.defaultStyle as Record<string, any>}
171
163
  size="md"