File tree Expand file tree Collapse file tree 2 files changed +121
-0
lines changed Expand file tree Collapse file tree 2 files changed +121
-0
lines changed Original file line number Diff line number Diff line change
1
+ import { Sidebar } from './ui/sidebar'
2
+ import { useHasMounted } from '@/hooks/useHasMounted'
3
+ import { useBackgroundJobs } from '@/hooks/useBackgroundJobs'
4
+ import { Clock } from 'lucide-react'
5
+ import { BackgroundJobItem } from './BackgroundJobItem'
6
+
7
+ interface BackgroundJobsSidebarProps {
8
+ isOpen : boolean
9
+ onClose : ( ) => void
10
+ onLoadResponse ?: ( jobId : string , response : string ) => void
11
+ onCancelJob ?: ( jobId : string ) => void
12
+ }
13
+
14
+ export function BackgroundJobsSidebar ( {
15
+ isOpen,
16
+ onClose,
17
+ onLoadResponse,
18
+ onCancelJob,
19
+ } : BackgroundJobsSidebarProps ) {
20
+ const { jobs, updateJob, removeJob } = useBackgroundJobs ( )
21
+ const hasMounted = useHasMounted ( )
22
+
23
+ if ( ! hasMounted ) {
24
+ return null
25
+ }
26
+
27
+ return (
28
+ < Sidebar
29
+ isOpen = { isOpen }
30
+ onClose = { onClose }
31
+ title = "Background Jobs"
32
+ className = "w-96"
33
+ >
34
+ < div className = "space-y-4" >
35
+ { jobs . length === 0 ? (
36
+ < div
37
+ className = "text-center text-muted-foreground py-8"
38
+ aria-live = "polite"
39
+ >
40
+ < Clock
41
+ className = "h-8 w-8 mx-auto mb-2 opacity-50"
42
+ aria-hidden = "true"
43
+ />
44
+ < p > No background jobs</ p >
45
+ </ div >
46
+ ) : (
47
+ < ul aria-label = "Background jobs" className = "grid gap-2" >
48
+ { jobs . map ( ( job ) => (
49
+ < li >
50
+ < BackgroundJobItem
51
+ key = { job . id }
52
+ job = { job }
53
+ onLoadResponse = { onLoadResponse }
54
+ onCancelJob = { onCancelJob }
55
+ updateJob = { updateJob }
56
+ removeJob = { removeJob }
57
+ />
58
+ </ li >
59
+ ) ) }
60
+ </ ul >
61
+ ) }
62
+ </ div >
63
+ </ Sidebar >
64
+ )
65
+ }
Original file line number Diff line number Diff line change
1
+ import * as React from 'react'
2
+ import { cn } from '@/lib/utils'
3
+ import { Button } from './button'
4
+ import { X } from 'lucide-react'
5
+
6
+ interface SidebarProps {
7
+ children : React . ReactNode
8
+ isOpen : boolean
9
+ onClose : ( ) => void
10
+ title : string
11
+ className ?: string
12
+ }
13
+
14
+ export function Sidebar ( {
15
+ children,
16
+ isOpen,
17
+ onClose,
18
+ title,
19
+ className
20
+ } : SidebarProps ) {
21
+ return (
22
+ < >
23
+ { /* Overlay */ }
24
+ { isOpen && (
25
+ < div
26
+ className = "fixed inset-0 bg-black/50 z-40"
27
+ onClick = { onClose }
28
+ />
29
+ ) }
30
+
31
+ { /* Sidebar */ }
32
+ < div
33
+ className = { cn (
34
+ 'fixed right-0 top-0 h-full w-80 bg-background border-l shadow-lg transform transition-transform duration-200 ease-in-out z-50' ,
35
+ isOpen ? 'translate-x-0' : 'translate-x-full' ,
36
+ className
37
+ ) }
38
+ >
39
+ < div className = "flex items-center justify-between p-4 border-b" >
40
+ < h2 className = "text-lg font-semibold" > { title } </ h2 >
41
+ < Button
42
+ variant = "ghost"
43
+ size = "icon"
44
+ onClick = { onClose }
45
+ className = "h-8 w-8"
46
+ >
47
+ < X className = "h-4 w-4" />
48
+ </ Button >
49
+ </ div >
50
+ < div className = "p-4 overflow-y-auto h-[calc(100vh-4rem)]" >
51
+ { children }
52
+ </ div >
53
+ </ div >
54
+ </ >
55
+ )
56
+ }
You can’t perform that action at this time.
0 commit comments