diff --git a/surfsense_web/app/dashboard/[search_space_id]/sources/add/page.tsx b/surfsense_web/app/dashboard/[search_space_id]/sources/add/page.tsx index e0729e29b..7c8e85fe7 100644 --- a/surfsense_web/app/dashboard/[search_space_id]/sources/add/page.tsx +++ b/surfsense_web/app/dashboard/[search_space_id]/sources/add/page.tsx @@ -51,11 +51,11 @@ export default function AddSourcesPage() { > {/* Header */}
-

- +

+ Add Sources

-

Add your sources to your search space

+

Add your sources to your search space

{/* Tabs */} 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 ed67fa1f5..8e48c4c3a 100644 --- a/surfsense_web/app/dashboard/[search_space_id]/team/page.tsx +++ b/surfsense_web/app/dashboard/[search_space_id]/team/page.tsx @@ -1,29 +1,15 @@ "use client"; import { useQuery } from "@tanstack/react-query"; -import { - type ColumnDef, - type ColumnFiltersState, - flexRender, - getCoreRowModel, - getFilteredRowModel, - getPaginationRowModel, - getSortedRowModel, - type SortingState, - useReactTable, -} from "@tanstack/react-table"; import { useAtomValue } from "jotai"; import { ArrowLeft, Calendar, Check, - ChevronDown, - ChevronUp, Clock, Copy, Crown, Edit2, - ExternalLink, Hash, Link2, LinkIcon, @@ -32,7 +18,6 @@ import { Plus, RefreshCw, Search, - Settings, Shield, ShieldCheck, Trash2, @@ -40,7 +25,6 @@ import { UserMinus, UserPlus, Users, - X, } from "lucide-react"; import { motion } from "motion/react"; import { useParams, useRouter } from "next/navigation"; @@ -90,7 +74,6 @@ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, - DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; @@ -105,7 +88,6 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select"; -import { Separator } from "@/components/ui/separator"; import { Table, TableBody, @@ -295,7 +277,7 @@ export default function TeamManagementPage() { staleTime: 5 * 60 * 1000, }); - const { data: permissionsData, isLoading: permissionsLoading } = useAtomValue(permissionsAtom); + const { data: permissionsData } = useAtomValue(permissionsAtom); const permissions = permissionsData?.permissions || []; const groupedPermissions = useMemo(() => { const groups: Record = {}; @@ -308,8 +290,6 @@ export default function TeamManagementPage() { return groups; }, [permissions]); - const canManageMembers = hasPermission("members:view"); - const canManageRoles = hasPermission("roles:read"); const canInvite = hasPermission("members:invite"); const handleRefresh = useCallback(async () => { @@ -339,40 +319,40 @@ export default function TeamManagementPage() { variants={staggerContainer} className="min-h-screen bg-background" > -
+
{/* Header */}
-
-
+
+
-
- +
+
-
-

+
+

Team Management

-

+

Manage members, roles, and invite links for your search space

-
- +
{/* Summary Cards */} @@ -435,42 +415,46 @@ export default function TeamManagementPage() { {/* Tabs Content */} -
- - - - Members - - {members.length} - - - - - Roles - - {roles.length} - - - - - Invites - - {invites.filter((i) => i.is_active).length} - - - +
+
+ + + + Members + + {members.length} + + + + + Roles + + {roles.length} + + + + + Invites + + {invites.filter((i) => i.is_active).length} + + + +
{activeTab === "invites" && canInvite && ( )} {activeTab === "roles" && hasPermission("roles:create") && ( )}
@@ -533,8 +517,6 @@ function MembersTab({ canManageRoles: boolean; canRemove: boolean; }) { - const [sorting, setSorting] = useState([]); - const [columnFilters, setColumnFilters] = useState([]); const [searchQuery, setSearchQuery] = useState(""); const filteredMembers = useMemo(() => { @@ -575,13 +557,13 @@ function MembersTab({
{/* Members List */} -
+
- Member - Role - Joined + Member + Role + Joined Actions @@ -604,11 +586,11 @@ function MembersTab({ transition={{ delay: index * 0.05 }} className="group border-b transition-colors hover:bg-muted/50" > - -
+ +
-
- +
+
{member.is_owner && (
@@ -616,12 +598,14 @@ function MembersTab({
)}
-
-

{member.user_email || "Unknown"}

+
+

+ {member.user_email || "Unknown"} +

{member.is_owner && ( Owner @@ -629,7 +613,7 @@ function MembersTab({
- + {canManageRoles && !member.is_owner ? ( ) : ( - - + + {member.role?.name || "No role"} )} - +
{new Date(member.joined_at).toLocaleDateString()}
- + {canRemove && !member.is_owner && ( @@ -962,11 +946,11 @@ function InvitesTab({ className={cn("relative overflow-hidden transition-all", isInactive && "opacity-60")} > -
-
+
+
- Max uses reached + Maxed )} {!invite.is_active && !isExpired && !isMaxedOut && ( @@ -1000,44 +984,44 @@ function InvitesTab({ )}
-
+
{invite.role?.name || "Default role"} - {invite.uses_count} uses - {invite.max_uses && ` / ${invite.max_uses}`} + {invite.uses_count} + {invite.max_uses ? ` / ${invite.max_uses} uses` : " uses"} {invite.expires_at && ( {isExpired ? "Expired" - : `Expires ${new Date(invite.expires_at).toLocaleDateString()}`} + : `Exp: ${new Date(invite.expires_at).toLocaleDateString()}`} )}
-
+
@@ -1088,11 +1072,11 @@ function InvitesTab({ function CreateInviteDialog({ roles, onCreateInvite, - searchSpaceId, + className, }: { roles: Role[]; onCreateInvite: (data: CreateInviteRequest["data"]) => Promise; - searchSpaceId: number; + className?: string; }) { const [open, setOpen] = useState(false); const [creating, setCreating] = useState(false); @@ -1142,12 +1126,12 @@ function CreateInviteDialog({ return ( (v ? setOpen(true) : handleClose())}> - - + {createdInvite ? ( <> @@ -1159,7 +1143,7 @@ function CreateInviteDialog({ Share this link to invite people to your search space. -
+
{window.location.origin}/invite/{createdInvite.invite_code} @@ -1203,7 +1187,7 @@ function CreateInviteDialog({ Create a link to invite people to this search space. -
+
-
+
; onCreateRole: (data: CreateRoleRequest["data"]) => Promise; + className?: string; }) { const [open, setOpen] = useState(false); const [creating, setCreating] = useState(false); @@ -1358,20 +1344,20 @@ function CreateRoleDialog({ return ( - - + Create Custom Role - + Define a new role with specific permissions for this search space. -
-
+
+
-
diff --git a/surfsense_web/components/new-chat/model-config-sidebar.tsx b/surfsense_web/components/new-chat/model-config-sidebar.tsx index f3d3c2dcd..9d755f221 100644 --- a/surfsense_web/components/new-chat/model-config-sidebar.tsx +++ b/surfsense_web/components/new-chat/model-config-sidebar.tsx @@ -184,7 +184,7 @@ export function ModelConfigSidebar({
-

{getTitle()}

+

{getTitle()}

{isGlobal ? ( @@ -207,9 +207,10 @@ export function ModelConfigSidebar({ variant="ghost" size="icon" onClick={() => onOpenChange(false)} - className="rounded-xl hover:bg-destructive/10 hover:text-destructive" + className="h-8 w-8 rounded-full" > - + + Close
diff --git a/surfsense_web/components/new-chat/source-detail-panel.tsx b/surfsense_web/components/new-chat/source-detail-panel.tsx index 6e3e7cce0..35249dc50 100644 --- a/surfsense_web/components/new-chat/source-detail-panel.tsx +++ b/surfsense_web/components/new-chat/source-detail-panel.tsx @@ -352,9 +352,9 @@ export function SourceDetailPanel({ size="icon" variant="ghost" onClick={() => onOpenChange(false)} - className="rounded-xl h-10 w-10 hover:bg-destructive/10 hover:text-destructive transition-colors" + className="h-8 w-8 rounded-full" > - + Close
diff --git a/surfsense_web/components/shared/llm-config-form.tsx b/surfsense_web/components/shared/llm-config-form.tsx index 1ad7817d5..7d450bfc9 100644 --- a/surfsense_web/components/shared/llm-config-form.tsx +++ b/surfsense_web/components/shared/llm-config-form.tsx @@ -156,8 +156,8 @@ export function LLMConfigForm({
{/* System Instructions & Citations Section */}
-
- +
+ System Instructions
@@ -168,7 +168,7 @@ export function LLMConfigForm({ render={({ field }) => (
- Instructions for the AI + Instructions for the AI {defaultInstructions && ( @@ -187,11 +187,11 @@ export function LLMConfigForm({