()
| 229 | "group w-full flex items-center pl-9 pr-2 py-1 outline-item mb-0.5 rounded-xs"; |
| 230 | |
| 231 | export function ProjectSidebar() { |
| 232 | const rawItems = useSidebarItems(); |
| 233 | const filteredItems = useMemo(() => filterSidebarList(rawItems), [rawItems]); |
| 234 | |
| 235 | const route = useCurrentRoute(); |
| 236 | const currentRouteName = route.name?.toString() ?? ""; |
| 237 | const projectId = (route.params.projectId as string | undefined) ?? ""; |
| 238 | |
| 239 | const customLogo = useWorkspace()?.logo ?? ""; |
| 240 | |
| 241 | const { record } = useRecentVisit(); |
| 242 | const recordVisitRef = useRef(record); |
| 243 | recordVisitRef.current = record; |
| 244 | |
| 245 | // Ensure the project is fetched into the store cache. |
| 246 | // ProjectRouteShell also fetches it, but this guards against race conditions. |
| 247 | useEffect(() => { |
| 248 | if (projectId) { |
| 249 | useAppStore |
| 250 | .getState() |
| 251 | .getOrFetchProjectByName(`${projectNamePrefix}${projectId}`, true); |
| 252 | } |
| 253 | }, [projectId]); |
| 254 | |
| 255 | // -- Expand / collapse state ----------------------------------------------- |
| 256 | const [expandedSet, setExpandedSet] = useState<Set<string>>(new Set()); |
| 257 | const manualToggledRef = useRef<Set<string>>(new Set()); |
| 258 | const autoExpandedRef = useRef<Set<string>>(new Set()); |
| 259 | const prevFilteredRef = useRef<SidebarItem[] | null>(null); |
| 260 | |
| 261 | const expandForActiveRoute = useCallback( |
| 262 | (items: SidebarItem[]) => { |
| 263 | setExpandedSet((prev) => { |
| 264 | const next = new Set(prev); |
| 265 | |
| 266 | for (const key of autoExpandedRef.current) { |
| 267 | next.delete(key); |
| 268 | } |
| 269 | autoExpandedRef.current.clear(); |
| 270 | |
| 271 | for (let i = 0; i < items.length; i++) { |
| 272 | const item = items[i]; |
| 273 | const key = `${i}`; |
| 274 | if (!item.children || item.children.length === 0) continue; |
| 275 | if (manualToggledRef.current.has(key)) continue; |
| 276 | if (item.expand) { |
| 277 | next.add(key); |
| 278 | continue; |
| 279 | } |
| 280 | const hasActiveChild = item.children.some( |
| 281 | (child) => getItemClass(child, currentRouteName).length > 0 |
| 282 | ); |
| 283 | if (hasActiveChild && !next.has(key)) { |
| 284 | next.add(key); |
| 285 | autoExpandedRef.current.add(key); |
| 286 | } |
| 287 | } |
| 288 |
nothing calls this directly
no test coverage detected