diff --git a/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentsTableShell.tsx b/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentsTableShell.tsx index 6d4187593..93e1cadbf 100644 --- a/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentsTableShell.tsx +++ b/surfsense_web/app/dashboard/[search_space_id]/documents/(manage)/components/DocumentsTableShell.tsx @@ -627,30 +627,28 @@ export function DocumentsTableShell({ )} - {columnVisibility.created_by && ( - - {doc.created_by_name ? ( - doc.created_by_email ? ( - - - - {doc.created_by_name} - - - - {doc.created_by_email} - - + {columnVisibility.created_by && ( + + {doc.created_by_name ? ( + doc.created_by_email ? ( + + + + {doc.created_by_name} + + + + {doc.created_by_email} + + + ) : ( + {doc.created_by_name} + ) ) : ( - {doc.created_by_name} - ) - ) : ( - - {doc.created_by_email || "—"} - - )} - - )} + {doc.created_by_email || "—"} + )} + + )} {columnVisibility.created_at && ( @@ -784,20 +782,20 @@ export function DocumentsTableShell({ {/* Document Content Viewer - lazy loads content on-demand */} !open && handleCloseViewer()}> - - - {viewingDoc?.title} - -
- {viewingLoading ? ( -
- -
- ) : ( - - )} -
-
+ + + {viewingDoc?.title} + +
+ {viewingLoading ? ( +
+ +
+ ) : ( + + )} +
+
); diff --git a/surfsense_web/app/dashboard/[search_space_id]/settings/page.tsx b/surfsense_web/app/dashboard/[search_space_id]/settings/page.tsx index d72bcb977..7ccd35425 100644 --- a/surfsense_web/app/dashboard/[search_space_id]/settings/page.tsx +++ b/surfsense_web/app/dashboard/[search_space_id]/settings/page.tsx @@ -306,9 +306,7 @@ function SettingsContent({ {activeSection === "public-links" && ( )} - {activeSection === "team-roles" && ( - - )} + {activeSection === "team-roles" && } @@ -328,7 +326,8 @@ export default function SettingsPage() { const [isSidebarOpen, setIsSidebarOpen] = useState(false); const sectionParam = searchParams.get("section"); - const activeSection = sectionParam && VALID_SECTIONS.has(sectionParam) ? sectionParam : DEFAULT_SECTION; + const activeSection = + sectionParam && VALID_SECTIONS.has(sectionParam) ? sectionParam : DEFAULT_SECTION; const handleSectionChange = useCallback( (section: string) => { diff --git a/surfsense_web/app/dashboard/[search_space_id]/team/page.tsx b/surfsense_web/app/dashboard/[search_space_id]/team/page.tsx index 44b3f63b6..f8a9cecd0 100644 --- a/surfsense_web/app/dashboard/[search_space_id]/team/page.tsx +++ b/surfsense_web/app/dashboard/[search_space_id]/team/page.tsx @@ -154,10 +154,7 @@ export default function TeamManagementPage() { [access] ); - const { - data: members = [], - isLoading: membersLoading, - } = useAtomValue(membersAtom); + const { data: members = [], isLoading: membersLoading } = useAtomValue(membersAtom); const { mutateAsync: updateMember } = useAtomValue(updateMemberMutationAtom); const { mutateAsync: deleteMember } = useAtomValue(deleteMemberMutationAtom); @@ -211,17 +208,13 @@ export default function TeamManagementPage() { [deleteMember, searchSpaceId] ); - const { - data: roles = [], - } = useQuery({ + const { data: roles = [] } = useQuery({ queryKey: cacheKeys.roles.all(searchSpaceId.toString()), queryFn: () => rolesApiService.getRoles({ search_space_id: searchSpaceId }), enabled: !!searchSpaceId, }); - const { - data: invites = [], - } = useQuery({ + const { data: invites = [] } = useQuery({ queryKey: cacheKeys.invites.all(searchSpaceId.toString()), queryFn: () => invitesApiService.getInvites({ search_space_id: searchSpaceId }), staleTime: 5 * 60 * 1000, @@ -271,12 +264,12 @@ export default function TeamManagementPage() { initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ duration: 0.3 }} - className="bg-background select-none" - > -
-
-
- + className="bg-background select-none" + > +
+
+
+
@@ -335,96 +328,93 @@ export default function TeamManagementPage() { initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ duration: 0.3 }} - className="bg-background select-none" - > -
-
- {/* Header row: Invite button on left, member count on right */} -
-
- {canInvite && ( - - )} - {canInvite && activeInvites.length > 0 && ( - - )} -
-

- {members.length} {members.length === 1 ? "member" : "members"} -

+ className="bg-background select-none" + > +
+
+ {/* Header row: Invite button on left, member count on right */} +
+
+ {canInvite && ( + + )} + {canInvite && activeInvites.length > 0 && ( + + )} +
+

+ {members.length} {members.length === 1 ? "member" : "members"} +

{/* Members & Invites Table */}
- - - - - - - Name - - - - - - Last logged in - - - - - - Role - - - - - - {owners.map((member, index) => ( - - ))} - {paginatedMembers.map((member, index) => ( - - ))} - {members.length === 0 && ( - - -
- -

No members yet

-
-
+
+ + + + + + Name + + + + + + Last logged in + + + + + + Role + + - )} - -
+ + + {owners.map((member, index) => ( + + ))} + {paginatedMembers.map((member, index) => ( + + ))} + {members.length === 0 && ( + + +
+ +

No members yet

+
+
+
+ )} +
+
{/* Pagination */} @@ -513,7 +503,7 @@ function MemberRow({ const initials = getAvatarInitials(member); const avatarColor = getAvatarColor(member.user_id); const displayName = member.user_display_name || member.user_email || "Unknown"; - const roleName = member.is_owner ? "Owner" : (member.role?.name || "No role"); + const roleName = member.is_owner ? "Owner" : member.role?.name || "No role"; const showActions = !member.is_owner && (canManageRoles || canRemove); return ( @@ -547,7 +537,9 @@ function MemberRow({

{displayName}

{member.user_display_name && member.user_email && ( -

{member.user_email}

+

+ {member.user_email} +

)}
@@ -569,7 +561,11 @@ function MemberRow({ - e.preventDefault()} className="min-w-[120px] bg-muted dark:border dark:border-neutral-700"> + e.preventDefault()} + className="min-w-[120px] bg-muted dark:border dark:border-neutral-700" + > {canManageRoles && roles .filter((r) => r.name !== "Owner") @@ -590,40 +586,39 @@ function MemberRow({ > Remove - - - - Remove member? - - This will remove{" "} - {member.user_email}{" "} - from this search space. They will lose access to all resources. - - - - Cancel - onRemoveMember(member.id)} - className="bg-destructive text-destructive-foreground hover:bg-destructive/90" - > - Remove - - - - + + + + Remove member? + + This will remove {member.user_email}{" "} + from this search space. They will lose access to all resources. + + + + Cancel + onRemoveMember(member.id)} + className="bg-destructive text-destructive-foreground hover:bg-destructive/90" + > + Remove + + + + )} router.push(`/dashboard/${searchSpaceId}/settings?section=team-roles`)} + onClick={() => + router.push(`/dashboard/${searchSpaceId}/settings?section=team-roles`) + } > Manage Roles ) : ( - - {roleName} - + {roleName} )} @@ -671,9 +666,7 @@ function CreateInviteDialog({ const invite = await onCreateInvite(data); setCreatedInvite(invite); - const roleName = roleId - ? roles.find((r) => r.id.toString() === roleId)?.name - : undefined; + const roleName = roleId ? roles.find((r) => r.id.toString() === roleId)?.name : undefined; trackSearchSpaceInviteSent(searchSpaceId, { roleName, hasExpiry: !!expiresAt, @@ -707,13 +700,19 @@ function CreateInviteDialog({ return ( (v ? setOpen(true) : handleClose())}> - - e.preventDefault()}> - {createdInvite ? ( + e.preventDefault()} + > + {createdInvite ? ( <> @@ -730,11 +729,7 @@ function CreateInviteDialog({ {window.location.origin}/invite/{createdInvite.invite_code}
@@ -891,24 +886,18 @@ function AllInvitesDialog({ - - Active Invite Links - + Active Invite Links - {invites.length} active {invites.length === 1 ? "invite" : "invites"}. Copy a link or revoke access. + {invites.length} active {invites.length === 1 ? "invite" : "invites"}. Copy a link or + revoke access.
{invites.map((invite) => ( -
+
-

- {invite.name || "Unnamed invite"} -

+

{invite.name || "Unnamed invite"}

{invite.role?.name && ( {invite.role.name} @@ -929,7 +918,11 @@ function AllInvitesDialog({
- @@ -937,8 +930,8 @@ function AllInvitesDialog({ Revoke invite? - This will permanently delete this invite link. Anyone with this link - will no longer be able to join. + This will permanently delete this invite link. Anyone with this link will no + longer be able to join. @@ -961,7 +954,12 @@ function AllInvitesDialog({ : `/invite/${invite.invite_code}`}
- diff --git a/surfsense_web/components/layout/ui/sidebar/AllPrivateChatsSidebar.tsx b/surfsense_web/components/layout/ui/sidebar/AllPrivateChatsSidebar.tsx index 37b335103..36a20cf3f 100644 --- a/surfsense_web/components/layout/ui/sidebar/AllPrivateChatsSidebar.tsx +++ b/surfsense_web/components/layout/ui/sidebar/AllPrivateChatsSidebar.tsx @@ -409,19 +409,19 @@ export function AllPrivateChatsSidebar({ {t("more_options") || "More options"} - - {!thread.archived && ( + + {!thread.archived && ( + handleStartRename(thread.id, thread.title || "New Chat")} + > + + {t("rename") || "Rename"} + + )} handleStartRename(thread.id, thread.title || "New Chat")} + onClick={() => handleToggleArchive(thread.id, thread.archived)} + disabled={isArchiving} > - - {t("rename") || "Rename"} - - )} - handleToggleArchive(thread.id, thread.archived)} - disabled={isArchiving} - > {thread.archived ? ( <> diff --git a/surfsense_web/components/layout/ui/sidebar/AllSharedChatsSidebar.tsx b/surfsense_web/components/layout/ui/sidebar/AllSharedChatsSidebar.tsx index feee30447..108ba4cde 100644 --- a/surfsense_web/components/layout/ui/sidebar/AllSharedChatsSidebar.tsx +++ b/surfsense_web/components/layout/ui/sidebar/AllSharedChatsSidebar.tsx @@ -409,20 +409,20 @@ export function AllSharedChatsSidebar({ {t("more_options") || "More options"} - - {!thread.archived && ( + + {!thread.archived && ( + handleStartRename(thread.id, thread.title || "New Chat")} + > + + {t("rename") || "Rename"} + + )} handleStartRename(thread.id, thread.title || "New Chat")} + onClick={() => handleToggleArchive(thread.id, thread.archived)} + disabled={isArchiving} > - - {t("rename") || "Rename"} - - )} - handleToggleArchive(thread.id, thread.archived)} - disabled={isArchiving} - > - {thread.archived ? ( + {thread.archived ? ( <> {t("unarchive") || "Restore"} diff --git a/surfsense_web/components/layout/ui/sidebar/SidebarUserProfile.tsx b/surfsense_web/components/layout/ui/sidebar/SidebarUserProfile.tsx index 7f3a97f93..1a0fac9e9 100644 --- a/surfsense_web/components/layout/ui/sidebar/SidebarUserProfile.tsx +++ b/surfsense_web/components/layout/ui/sidebar/SidebarUserProfile.tsx @@ -381,11 +381,7 @@ export function SidebarUserProfile({ - {isLoggingOut ? ( - - ) : ( - - )} + {isLoggingOut ? : } {isLoggingOut ? t("loggingOut") : t("logout")} diff --git a/surfsense_web/components/new-chat/chat-share-button.tsx b/surfsense_web/components/new-chat/chat-share-button.tsx index ab04fc4c9..bfb6d91fc 100644 --- a/surfsense_web/components/new-chat/chat-share-button.tsx +++ b/surfsense_web/components/new-chat/chat-share-button.tsx @@ -144,7 +144,9 @@ export function ChatShareButton({ thread, onVisibilityChange, className }: ChatS diff --git a/surfsense_web/components/settings/roles-manager.tsx b/surfsense_web/components/settings/roles-manager.tsx index 42301f99f..96ab2551f 100644 --- a/surfsense_web/components/settings/roles-manager.tsx +++ b/surfsense_web/components/settings/roles-manager.tsx @@ -156,7 +156,6 @@ const ACTION_LABELS: Record = { manage_roles: "Manage Roles", }; - const ROLE_PRESETS = { editor: { name: "Editor", @@ -241,13 +240,9 @@ export function RolesManager({ searchSpaceId }: { searchSpaceId: number }) { [access] ); - const { - data: roles = [], - isLoading: rolesLoading, - } = useQuery({ + const { data: roles = [], isLoading: rolesLoading } = useQuery({ queryKey: cacheKeys.roles.all(searchSpaceId.toString()), - queryFn: () => - rolesApiService.getRoles({ search_space_id: searchSpaceId }), + queryFn: () => rolesApiService.getRoles({ search_space_id: searchSpaceId }), enabled: !!searchSpaceId, }); @@ -358,14 +353,10 @@ function RolePermissionsDialog({ return ( - - {children} - + {children} - - {roleName} — Permissions - + {roleName} — Permissions {isFullAccess ? "This role has unrestricted access to all resources" @@ -379,7 +370,9 @@ function RolePermissionsDialog({

Full access

-

All permissions granted across every category

+

+ All permissions granted across every category +

) : ( @@ -399,9 +392,7 @@ function RolePermissionsDialog({ >
- - {config.label} - + {config.label}
{actions.map((action) => ( @@ -409,8 +400,7 @@ function RolePermissionsDialog({ key={action} className="px-1.5 py-0.5 rounded bg-muted text-muted-foreground text-[11px] font-medium" > - {ACTION_LABELS[action] || - action.replace(/_/g, " ")} + {ACTION_LABELS[action] || action.replace(/_/g, " ")} ))}
@@ -435,7 +425,9 @@ function PermissionsBadge({ permissions }: { permissions: string[] }) { } return (
- {permissions.length} permissions + + {permissions.length} permissions +
); } @@ -514,15 +506,17 @@ function RolesContent({ {editingRole && ( { if (!open) setEditingRoleId(null); }} + onOpenChange={(open) => { + if (!open) setEditingRoleId(null); + }} role={editingRole} groupedPermissions={groupedPermissions} onUpdateRole={onUpdateRole} /> )} -
- {roles.map((role, index) => ( +
+ {roles.map((role, index) => ( {!role.is_system_role && ( -
e.stopPropagation()} onKeyDown={(e) => e.stopPropagation()}> +
e.stopPropagation()} + onKeyDown={(e) => e.stopPropagation()} + > - e.preventDefault()} - > + e.preventDefault()}> {canUpdate && ( setEditingRoleId(role.id)}> @@ -649,18 +645,14 @@ function PermissionsEditor({ const toggleCategoryExpanded = useCallback((category: string) => { setExpandedCategories((prev) => - prev.includes(category) - ? prev.filter((c) => c !== category) - : [...prev, category] + prev.includes(category) ? prev.filter((c) => c !== category) : [...prev, category] ); }, []); const getCategoryStats = useCallback( (category: string) => { const perms = groupedPermissions[category] || []; - const selected = perms.filter((p) => - selectedPermissions.includes(p.value) - ).length; + const selected = perms.filter((p) => selectedPermissions.includes(p.value)).length; return { selected, total: perms.length, @@ -683,15 +675,11 @@ function PermissionsEditor({ className="text-xs h-7" onClick={() => setExpandedCategories( - expandedCategories.length === sortedCategories.length - ? [] - : sortedCategories + expandedCategories.length === sortedCategories.length ? [] : sortedCategories ) } > - {expandedCategories.length === sortedCategories.length - ? "Collapse All" - : "Expand All"} + {expandedCategories.length === sortedCategories.length ? "Collapse All" : "Expand All"}
@@ -709,10 +697,7 @@ function PermissionsEditor({ const perms = groupedPermissions[category] || []; return ( -
+