1- import { Group , Image , NavLink , Stack } from "@mantine/core" ;
1+ import {
2+ ActionIcon ,
3+ Box ,
4+ Button , ButtonGroup ,
5+ Flex ,
6+ Group ,
7+ Image ,
8+ Menu ,
9+ NavLink ,
10+ Stack ,
11+ Text ,
12+ Tooltip ,
13+ } from "@mantine/core" ;
214import {
315 IconDatabase ,
416 IconFolders ,
517 IconLogs ,
618 IconSettings ,
719 IconTerminal2 ,
20+ IconInfoCircle ,
21+ IconReload ,
22+ IconLayoutSidebarLeftExpand ,
23+ IconLayoutSidebarLeftCollapse ,
24+ IconStarFilled ,
25+ IconStar ,
26+ IconTools ,
27+ IconArrowRight ,
28+ IconChevronCompactRight ,
29+ IconChevronRight ,
30+ IconShield ,
31+ IconShieldLockFilled ,
32+ IconTemplate ,
33+ IconShieldLock ,
834} from "@tabler/icons-react" ;
935import { useCallback } from "react" ;
1036import { Link , useLocation } from "wouter" ;
37+ import { useAppContext } from "../../hooks/useAppContext.tsx" ;
1138import styles from "./Sidebar.module.css" ;
12- import iconImage from "/logo-dark.png" ;
39+ import iconImage from "/icon.png" ;
40+
41+ interface SidebarProps {
42+ collapsed : boolean ;
43+ onToggle : ( ) => void ;
44+ }
1345
14- export function Sidebar ( ) {
46+ export function Sidebar ( { collapsed , onToggle } : SidebarProps ) {
1547 const [ location , setLocation ] = useLocation ( ) ;
48+ const { config, selectedWorkspace } = useAppContext ( ) ;
49+ const currentWorkspaceName = selectedWorkspace || config ?. currentWorkspace || "—" ;
50+ const currentNamespace = config ?. currentNamespace || "—" ;
1651
1752 const navigateToWorkspaces = useCallback ( ( ) => {
1853 setLocation ( `/workspaces` ) ;
@@ -39,12 +74,30 @@ export function Sidebar() {
3974 } , [ setLocation ] ) ;
4075
4176 return (
42- < div className = { styles . sidebar } >
43- < Link to = "/" className = { styles . sidebar__logo } >
44- < Image src = { iconImage } alt = "flow" fit = "contain" />
45- </ Link >
46- < Stack gap = "xs" >
47- < Group gap = "xs" mt = "md" >
77+ < Stack justify = "space-between" className = { `${ styles . sidebar } ${ collapsed ? styles . sidebarCollapsed : "" } ` } >
78+ < Box >
79+ < Flex justify = "space-between" align = { collapsed ? "center" : "flex-end" } direction = { collapsed ? "column-reverse" : "column" } >
80+ < ActionIcon
81+ variant = "transparent"
82+ aria-label = { collapsed ? "Expand sidebar" : "Collapse sidebar" }
83+ onClick = { onToggle }
84+ color = "bodyLight"
85+ >
86+ { collapsed ? < IconLayoutSidebarLeftExpand size = { 16 } /> : < IconLayoutSidebarLeftCollapse size = { 16 } /> }
87+ </ ActionIcon >
88+ < Link to = "/" className = { styles . sidebar__logo } >
89+ < Image src = { iconImage } alt = "flow" fit = "contain" />
90+ </ Link >
91+ </ Flex >
92+
93+ < Stack gap = "xs" mt = "xl" justify = "stretch" align = { collapsed ? "center" : "flex-start" } >
94+ < NavLink
95+ label = "Favorites"
96+ leftSection = { < IconStar size = { 16 } /> }
97+ active = { location . startsWith ( "/favorites" ) }
98+ variant = "filled"
99+ onClick = { navigateToWorkspaces }
100+ />
48101 < NavLink
49102 label = "Workspaces"
50103 leftSection = { < IconFolders size = { 16 } /> }
@@ -60,45 +113,83 @@ export function Sidebar() {
60113 variant = "filled"
61114 onClick = { navigateToExecutables }
62115 />
116+ </ Stack >
117+ </ Box >
118+ < Box >
119+ { collapsed ? (
120+ < Group justify = "center" gap = { 8 } >
121+ < Tooltip label = { `Workspace: ${ currentWorkspaceName } | Namespace: ${ currentNamespace } ` } position = "right" openDelay = { 300 } >
122+ < ActionIcon variant = "transparent" size = "sm" aria-label = "Context" >
123+ < IconInfoCircle size = { 14 } />
124+ </ ActionIcon >
125+ </ Tooltip >
126+ < Tooltip label = "Sync" position = "right" openDelay = { 300 } >
127+ < ActionIcon variant = "light" size = "sm" aria-label = "Sync workspaces and executables" >
128+ < IconReload size = { 14 } />
129+ </ ActionIcon >
130+ </ Tooltip >
131+ </ Group >
132+ ) : (
63133
64- < NavLink
65- label = "Logs"
66- leftSection = { < IconLogs size = { 16 } /> }
67- active = { location . startsWith ( "/logs" ) }
68- variant = "filled"
69- onClick = { navigateToLogs }
70- />
134+ < Stack gap = "xs" align = "stretch" justify = "center" >
71135
72- < NavLink
73- label = "Data"
74- leftSection = { < IconDatabase size = { 16 } /> }
75- variant = "filled"
76- childrenOffset = { 28 }
77- >
78- < NavLink
79- label = "Cache"
80- variant = "filled"
81- active = { location . startsWith ( "/cache" ) }
82- onClick = { navigateToCache }
83- / >
84- < NavLink
85- label = "Vault"
86- variant = "filled"
87- active = { location . startsWith ( "/vault" ) }
88- onClick = { navigateToVault }
89- / >
90- </ NavLink >
91-
92- < NavLink
93- label = "Settings"
94- leftSection = { < IconSettings size = { 16 } /> }
95- active = { location . startsWith ( "/settings" ) }
96- variant = "filled"
97- onClick = { navigateToSettings }
98- / >
99- </ Group >
136+ < Box className = { styles . sidebar__context } >
137+ < Group gap = "xs" justify = "space-between" mb = "xs" >
138+ < Text size = "xs" fw = { 700 } c = "dimmed" > Context </ Text >
139+ < IconInfoCircle size = { 16 } />
140+ </ Group >
141+ < Group >
142+ < Text size = "xs" c = "dimmed" > Workspace </ Text >
143+ < Text size = "xs" truncate > { currentWorkspaceName } </ Text >
144+ </ Group >
145+ < Group >
146+ < Text size = "xs" c = "dimmed" mt = { 6 } > Namespace </ Text >
147+ < Text size = "xs" truncate > { currentNamespace } </ Text >
148+ </ Group >
149+ </ Box >
150+ < ButtonGroup style = { { alignSelf : 'center' } } >
151+ < Button
152+ leftSection = { < IconReload size = { 12 } /> }
153+ size = "compact-xs" variant = "transparent" justify = "start" > Sync </ Button >
154+ < Menu shadow = "md" position = "top-start" offset = { 15 } width = { 200 } withArrow >
155+ < Menu . Target >
156+ < Button
157+ leftSection = { < IconTools size = { 12 } /> }
158+ size = "compact-xs"
159+ variant = "transparent"
160+ onClick = { navigateToSettings }
161+ justify = "start"
162+ > Tools </ Button >
163+ </ Menu . Target >
100164
101- </ Stack >
102- </ div >
165+ < Menu . Dropdown >
166+ < Menu . Item leftSection = { < IconShieldLock size = { 14 } /> } >
167+ Vault
168+ </ Menu . Item >
169+ < Menu . Item leftSection = { < IconDatabase size = { 14 } /> } >
170+ Cache Store
171+ </ Menu . Item >
172+ < Menu . Item leftSection = { < IconTemplate size = { 14 } /> } >
173+ Templates
174+ </ Menu . Item >
175+ < Menu . Item
176+ leftSection = { < IconLogs size = { 14 } /> }
177+ >
178+ Logs
179+ </ Menu . Item >
180+ </ Menu . Dropdown >
181+ </ Menu >
182+ < Button
183+ leftSection = { < IconSettings size = { 12 } /> }
184+ size = "compact-xs"
185+ variant = "transparent"
186+ onClick = { navigateToSettings }
187+ justify = "start"
188+ > Settings</ Button >
189+ </ ButtonGroup >
190+ </ Stack >
191+ ) }
192+ </ Box >
193+ </ Stack >
103194 ) ;
104195}
0 commit comments