Skip to content

Commit 51560ed

Browse files
deptraiclaude
andcommitted
fix: admin model edit UI and admin email validation
- chat-header: open global model configs in edit mode for admin (was incorrectly opening as view-only) - model-selector: remove opacity-0/hover — edit buttons always visible for admin instead of requiring hover - LayoutDataProvider: add Admin nav item (ShieldCheck) visible only to superusers, linking to /admin/subscription-requests - 126_seed_admin_user: change default email from admin@surfsense.local to admin@surfsense.app — pydantic rejects .local as reserved TLD, causing /users/me to return 500 for the admin account Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent e5b56d7 commit 51560ed

4 files changed

Lines changed: 21 additions & 11 deletions

File tree

surfsense_backend/alembic/versions/126_seed_admin_user.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
77
Seeds one admin user on fresh installs (no-op if any user already exists).
88
Credentials are overridable via env vars:
9-
ADMIN_EMAIL (default: admin@surfsense.local)
9+
ADMIN_EMAIL (default: admin@surfsense.app)
1010
ADMIN_PASSWORD (default: Admin@SurfSense1)
1111
1212
Admin is created with:
@@ -48,7 +48,7 @@ def upgrade() -> None:
4848
if result.fetchone() is not None:
4949
return # Users already exist — skip seed
5050

51-
admin_email = os.environ.get("ADMIN_EMAIL", "admin@surfsense.local")
51+
admin_email = os.environ.get("ADMIN_EMAIL", "admin@surfsense.app")
5252
admin_password = os.environ.get("ADMIN_PASSWORD", "Admin@SurfSense1")
5353
if not os.environ.get("ADMIN_PASSWORD"):
5454
print(

surfsense_web/components/layout/providers/LayoutDataProvider.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
Inbox,
99
LogOut,
1010
Megaphone,
11+
ShieldCheck,
1112
SquareLibrary,
1213
Trash2,
1314
} from "lucide-react";
@@ -387,6 +388,14 @@ export function LayoutDataProvider({ searchSpaceId, children }: LayoutDataProvid
387388
icon: Coins,
388389
isActive: pathname?.includes("/crypto"),
389390
},
391+
user?.is_superuser
392+
? {
393+
title: "Admin",
394+
url: "/admin/subscription-requests",
395+
icon: ShieldCheck,
396+
isActive: pathname?.startsWith("/admin"),
397+
}
398+
: null,
390399
] as (NavItem | null)[]
391400
).filter((item): item is NavItem => item !== null),
392401
[
@@ -398,6 +407,7 @@ export function LayoutDataProvider({ searchSpaceId, children }: LayoutDataProvid
398407
announcementUnreadCount,
399408
searchSpaceId,
400409
pathname,
410+
user,
401411
]
402412
);
403413

surfsense_web/components/new-chat/chat-header.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export function ChatHeader({ searchSpaceId, className }: ChatHeaderProps) {
6363
(config: NewLLMConfigPublic | GlobalNewLLMConfig, global: boolean) => {
6464
setSelectedConfig(config);
6565
setIsGlobal(global);
66-
setDialogMode(global ? "view" : "edit");
66+
setDialogMode("edit");
6767
setDialogOpen(true);
6868
},
6969
[]
@@ -93,7 +93,7 @@ export function ChatHeader({ searchSpaceId, className }: ChatHeaderProps) {
9393
(config: ImageGenerationConfig | GlobalImageGenConfig, global: boolean) => {
9494
setSelectedImageConfig(config);
9595
setIsImageGlobal(global);
96-
setImageDialogMode(global ? "view" : "edit");
96+
setImageDialogMode("edit");
9797
setImageDialogOpen(true);
9898
},
9999
[]
@@ -116,7 +116,7 @@ export function ChatHeader({ searchSpaceId, className }: ChatHeaderProps) {
116116
(config: VisionLLMConfig | GlobalVisionLLMConfig, global: boolean) => {
117117
setSelectedVisionConfig(config);
118118
setIsVisionGlobal(global);
119-
setVisionDialogMode(global ? "view" : "edit");
119+
setVisionDialogMode("edit");
120120
setVisionDialogOpen(true);
121121
},
122122
[]

surfsense_web/components/new-chat/model-selector.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ export function ModelSelector({
548548
<Button
549549
variant="ghost"
550550
size="icon"
551-
className="size-7 shrink-0 rounded-md hover:bg-muted opacity-0 group-hover:opacity-100 transition-opacity"
551+
className="size-7 shrink-0 rounded-md hover:bg-muted transition-opacity"
552552
onClick={(e) => handleEditLLMConfig(e, config, true)}
553553
>
554554
<Edit3 className="size-3.5 text-muted-foreground" />
@@ -613,7 +613,7 @@ export function ModelSelector({
613613
<Button
614614
variant="ghost"
615615
size="icon"
616-
className="size-7 shrink-0 rounded-md hover:bg-muted opacity-0 group-hover:opacity-100 transition-opacity"
616+
className="size-7 shrink-0 rounded-md hover:bg-muted transition-opacity"
617617
onClick={(e) => handleEditLLMConfig(e, config, false)}
618618
>
619619
<Edit3 className="size-3.5 text-muted-foreground" />
@@ -724,7 +724,7 @@ export function ModelSelector({
724724
<Button
725725
variant="ghost"
726726
size="icon"
727-
className="size-7 shrink-0 rounded-md hover:bg-muted opacity-0 group-hover:opacity-100 transition-opacity"
727+
className="size-7 shrink-0 rounded-md hover:bg-muted transition-opacity"
728728
onClick={(e) => {
729729
e.stopPropagation();
730730
setOpen(false);
@@ -780,7 +780,7 @@ export function ModelSelector({
780780
<Button
781781
variant="ghost"
782782
size="icon"
783-
className="h-7 w-7 shrink-0 opacity-0 group-hover:opacity-100 transition-opacity"
783+
className="h-7 w-7 shrink-0 transition-opacity"
784784
onClick={(e) => {
785785
e.stopPropagation();
786786
setOpen(false);
@@ -894,7 +894,7 @@ export function ModelSelector({
894894
<Button
895895
variant="ghost"
896896
size="icon"
897-
className="size-7 shrink-0 rounded-md hover:bg-muted opacity-0 group-hover:opacity-100 transition-opacity"
897+
className="size-7 shrink-0 rounded-md hover:bg-muted transition-opacity"
898898
onClick={(e) => {
899899
e.stopPropagation();
900900
setOpen(false);
@@ -949,7 +949,7 @@ export function ModelSelector({
949949
<Button
950950
variant="ghost"
951951
size="icon"
952-
className="h-7 w-7 shrink-0 opacity-0 group-hover:opacity-100 transition-opacity"
952+
className="h-7 w-7 shrink-0 transition-opacity"
953953
onClick={(e) => {
954954
e.stopPropagation();
955955
setOpen(false);

0 commit comments

Comments
 (0)