mirror of
https://github.com/get-drexa/drive.git
synced 2025-12-01 05:51:39 +00:00
feat: global progress indicator in sidebar
add a global progress indicator in the dashboard sidebar that can be used to indicate progress for any background task Co-authored-by: Ona <no-reply@ona.com>
This commit is contained in:
@@ -2,8 +2,8 @@ import { api } from "@fileone/convex/_generated/api"
|
|||||||
import { Link, useLocation } from "@tanstack/react-router"
|
import { Link, useLocation } from "@tanstack/react-router"
|
||||||
import { useAuth } from "@workos-inc/authkit-react"
|
import { useAuth } from "@workos-inc/authkit-react"
|
||||||
import { useQuery as useConvexQuery } from "convex/react"
|
import { useQuery as useConvexQuery } from "convex/react"
|
||||||
|
import { useAtomValue } from "jotai"
|
||||||
import {
|
import {
|
||||||
ChevronDownIcon,
|
|
||||||
FilesIcon,
|
FilesIcon,
|
||||||
HomeIcon,
|
HomeIcon,
|
||||||
LogOutIcon,
|
LogOutIcon,
|
||||||
@@ -19,12 +19,17 @@ import {
|
|||||||
} from "@/components/ui/dropdown-menu"
|
} from "@/components/ui/dropdown-menu"
|
||||||
import {
|
import {
|
||||||
Sidebar,
|
Sidebar,
|
||||||
|
SidebarContent,
|
||||||
|
SidebarFooter,
|
||||||
|
SidebarGroup,
|
||||||
SidebarHeader,
|
SidebarHeader,
|
||||||
SidebarMenu,
|
SidebarMenu,
|
||||||
SidebarMenuButton,
|
SidebarMenuButton,
|
||||||
SidebarMenuItem,
|
SidebarMenuItem,
|
||||||
SidebarRail,
|
SidebarRail,
|
||||||
} from "@/components/ui/sidebar"
|
} from "@/components/ui/sidebar"
|
||||||
|
import { LoadingSpinner } from "../components/ui/loading-spinner"
|
||||||
|
import { backgroundTaskProgressAtom } from "./state"
|
||||||
|
|
||||||
export function DashboardSidebar() {
|
export function DashboardSidebar() {
|
||||||
return (
|
return (
|
||||||
@@ -35,8 +40,17 @@ export function DashboardSidebar() {
|
|||||||
<UserMenu />
|
<UserMenu />
|
||||||
</SidebarMenuItem>
|
</SidebarMenuItem>
|
||||||
</SidebarMenu>
|
</SidebarMenu>
|
||||||
<MainSidebarMenu />
|
|
||||||
</SidebarHeader>
|
</SidebarHeader>
|
||||||
|
<SidebarContent>
|
||||||
|
<SidebarGroup>
|
||||||
|
<MainSidebarMenu />
|
||||||
|
</SidebarGroup>
|
||||||
|
</SidebarContent>
|
||||||
|
<SidebarFooter>
|
||||||
|
<SidebarMenu>
|
||||||
|
<BackgroundTaskProgressItem />
|
||||||
|
</SidebarMenu>
|
||||||
|
</SidebarFooter>
|
||||||
<SidebarRail />
|
<SidebarRail />
|
||||||
</Sidebar>
|
</Sidebar>
|
||||||
)
|
)
|
||||||
@@ -110,6 +124,19 @@ function TrashItem() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function BackgroundTaskProgressItem() {
|
||||||
|
const backgroundTaskProgress = useAtomValue(backgroundTaskProgressAtom)
|
||||||
|
|
||||||
|
if (!backgroundTaskProgress) return null
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SidebarMenuItem className="flex items-center gap-2 opacity-80 text-sm">
|
||||||
|
<LoadingSpinner />
|
||||||
|
{backgroundTaskProgress.label}
|
||||||
|
</SidebarMenuItem>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
function UserMenu() {
|
function UserMenu() {
|
||||||
const { signOut } = useAuth()
|
const { signOut } = useAuth()
|
||||||
|
|
||||||
@@ -120,12 +147,18 @@ function UserMenu() {
|
|||||||
return (
|
return (
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<SidebarMenuButton className="w-fit px-1.5 group-data-[collapsible=icon]:px-1.5! data-[state=open]:bg-sidebar-accent">
|
<SidebarMenuButton size="lg" asChild>
|
||||||
<div className="bg-sidebar-primary text-sidebar-primary-foreground flex aspect-square size-5 items-center justify-center rounded-md">
|
<a href="/">
|
||||||
<User2Icon className="size-3" />
|
<div className="bg-sidebar-primary text-sidebar-primary-foreground flex aspect-square size-8 items-center justify-center rounded-lg">
|
||||||
</div>
|
<User2Icon className="size-4" />
|
||||||
<span className="truncate font-medium">Kenneth</span>
|
</div>
|
||||||
<ChevronDownIcon className="opacity-50" />
|
<div className="grid flex-1 text-left text-sm leading-tight">
|
||||||
|
<span className="truncate font-medium">
|
||||||
|
Acme Inc
|
||||||
|
</span>
|
||||||
|
<span className="truncate text-xs">Enterprise</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
</SidebarMenuButton>
|
</SidebarMenuButton>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent className="w-64" align="start" side="bottom">
|
<DropdownMenuContent className="w-64" align="start" side="bottom">
|
||||||
|
|||||||
9
packages/web/src/dashboard/state.ts
Normal file
9
packages/web/src/dashboard/state.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { atom } from "jotai"
|
||||||
|
|
||||||
|
type BackgroundTaskProgress = {
|
||||||
|
label: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const backgroundTaskProgressAtom = atom<BackgroundTaskProgress | null>(
|
||||||
|
null,
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user