| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- <script lang="ts">
- import {
- BookSearch,
- Bot,
- BotMessageSquare,
- Brain,
- BrainCircuit,
- ChevronDown,
- ChevronUp,
- Component,
- Key,
- LibraryBig,
- Toolbox,
- Wrench,
- } from '@lucide/svelte';
- import { goto } from '$app/navigation';
- import { resolve } from '$app/paths';
- import { page } from '$app/state';
- import type { ResolvedPathname } from '$app/types';
- import * as DropdownMenu from '$lib/components/controls/dropdown-menu';
- import * as Sidebar from '$lib/components/controls/sidebar';
- import type { User } from '$lib/types/user';
- import type { Workspace } from '$lib/types/workspace';
- interface NavItem {
- label: string;
- icon: typeof Bot;
- href: ResolvedPathname;
- }
- interface NavItemGroup {
- label: string;
- items: NavItem[];
- }
- let {
- workspaceId,
- workspaces,
- user,
- }: { workspaceId: string | null; workspaces: Workspace[]; user: User | undefined } = $props();
- const workspaceName = $derived(
- workspaces.find((ws) => ws.id === workspaceId)?.displayName ?? 'Unknown Workspace',
- );
- const navItemGroups: NavItemGroup[] = [
- {
- label: 'Utilities',
- items: [
- { label: 'Agent Chat', icon: BotMessageSquare, href: resolve('/utilities/testing/agent') },
- { label: 'Retrieval', icon: BookSearch, href: resolve('/utilities/testing/kb') },
- { label: 'Tool Calling', icon: Wrench, href: resolve('/utilities/testing/tool') },
- { label: 'Model Inference', icon: BrainCircuit, href: resolve('/utilities/testing/model') },
- ],
- },
- {
- label: 'Workloads',
- items: [
- { label: 'Agents', icon: Bot, href: resolve('/workloads/agents') },
- { label: 'Knowledge Bases', icon: LibraryBig, href: resolve('/workloads/kbs') },
- { label: 'Tools', icon: Toolbox, href: resolve('/workloads/tools') },
- { label: 'Models', icon: Brain, href: resolve('/workloads/models') },
- ],
- },
- {
- label: 'Resources',
- items: [
- { label: 'Secrets', icon: Key, href: resolve('/resources/secrets') },
- { label: 'Stacks', icon: Component, href: resolve('/resources/stacks') },
- ],
- },
- ];
- const isActive = (href: string) =>
- href === '/' ? page.url.pathname === '/' : page.url.pathname.startsWith(href);
- </script>
- <Sidebar.Root class="border-white/10 backdrop-blur-md" collapsible="icon">
- <Sidebar.Header class="group-data-[collapsible=icon]:hidden">
- <Sidebar.Menu>
- <Sidebar.MenuItem>
- <DropdownMenu.Root>
- <DropdownMenu.Trigger>
- {#snippet child({ props })}
- <Sidebar.MenuButton class="whitespace-nowrap" {...props}>
- {workspaceName}
- <ChevronDown class="ms-auto" />
- </Sidebar.MenuButton>
- {/snippet}
- </DropdownMenu.Trigger>
- <DropdownMenu.Content class="w-(--bits-dropdown-menu-anchor-width)">
- {#each workspaces as workspace (workspace.id)}
- <DropdownMenu.Item>
- <span>{workspace.displayName}</span>
- </DropdownMenu.Item>
- {/each}
- </DropdownMenu.Content>
- </DropdownMenu.Root>
- </Sidebar.MenuItem>
- </Sidebar.Menu>
- </Sidebar.Header>
- <Sidebar.Content>
- {#each navItemGroups as group (group.label)}
- <Sidebar.Group>
- <Sidebar.GroupLabel>{group.label}</Sidebar.GroupLabel>
- <Sidebar.GroupContent>
- <Sidebar.Menu>
- {#each group.items as item (item.href)}
- <Sidebar.MenuItem>
- <Sidebar.MenuButton isActive={isActive(item.href)} tooltipContent={item.label}>
- {#snippet child({ props })}
- <a href={item.href} {...props}>
- <item.icon strokeWidth={3} />
- <span>{item.label}</span>
- </a>
- {/snippet}
- </Sidebar.MenuButton>
- </Sidebar.MenuItem>
- {/each}
- </Sidebar.Menu>
- </Sidebar.GroupContent>
- </Sidebar.Group>
- {/each}
- </Sidebar.Content>
- {#if user}
- <Sidebar.Footer class="group-data-[collapsible=icon]:hidden">
- <Sidebar.Menu>
- <Sidebar.MenuItem>
- <DropdownMenu.Root>
- <DropdownMenu.Trigger>
- {#snippet child({ props })}
- <Sidebar.MenuButton
- {...props}
- class="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
- >
- {user.name}
- <ChevronUp class="ms-auto" />
- </Sidebar.MenuButton>
- {/snippet}
- </DropdownMenu.Trigger>
- <DropdownMenu.Content class="w-(--bits-dropdown-menu-anchor-width)" side="top">
- <DropdownMenu.Item onclick={() => goto(resolve('/auth/logout'))}>
- <span>Sign out</span>
- </DropdownMenu.Item>
- </DropdownMenu.Content>
- </DropdownMenu.Root>
- </Sidebar.MenuItem>
- </Sidebar.Menu>
- </Sidebar.Footer>
- {/if}
- </Sidebar.Root>
|