ultisuite-client/components/gmail/sidebar/sidebar-folder-tree.tsx
2026-05-20 18:22:36 +02:00

95 lines
2.8 KiB
TypeScript

"use client"
import type { ReactNode } from "react"
import type { FolderTreeNode } from "@/lib/sidebar-nav-data"
import type { NavItemPrefs } from "@/lib/sidebar-nav-context"
import {
SidebarFolderRowExpanded,
type SidebarFolderRowExpandedProps,
} from "@/components/gmail/sidebar/sidebar-folder-row-expanded"
export type SidebarFolderRowContextProps = Omit<
SidebarFolderRowExpandedProps,
"node" | "depth"
>
import { SidebarFolderButtonCollapsed } from "@/components/gmail/sidebar/sidebar-folder-button-collapsed"
export function sidebarVisibleFolderNodes(
nodes: FolderTreeNode[],
getNavItemPrefs: (id: string) => Required<Pick<NavItemPrefs, "sidebar" | "messages">>,
folderUnreadCounts: Record<string, number>
): FolderTreeNode[] {
return nodes.filter((node) => {
const p = getNavItemPrefs(node.id)
if (p.sidebar === "hide") return false
if (
p.sidebar === "showUnread" &&
(folderUnreadCounts[node.id] ?? 0) === 0
) {
return false
}
return true
})
}
export function renderExpandedFolderSubtree(
nodes: FolderTreeNode[],
depth: number,
props: SidebarFolderRowContextProps
): ReactNode {
const { expandedFolderIds, getNavItemPrefs, folderUnreadCounts } = props
return sidebarVisibleFolderNodes(nodes, getNavItemPrefs, folderUnreadCounts).map(
(node) => {
const isBranchOpen = expandedFolderIds.has(node.id)
const kids = node.children
return (
<div key={node.id} className="min-w-0">
<SidebarFolderRowExpanded node={node} depth={depth} {...props} />
{kids?.length && isBranchOpen ? (
<div className="min-w-0">
{renderExpandedFolderSubtree(kids, depth + 1, props)}
</div>
) : null}
</div>
)
}
)
}
export function renderCollapsedFolderList(
nodes: FolderTreeNode[],
opts: {
getNavItemPrefs: (id: string) => Required<Pick<NavItemPrefs, "sidebar" | "messages">>
folderUnreadCounts: Record<string, number>
expandedFolderIds: Set<string>
isExpanded: boolean
selectedFolder: string
onSelectFolder: (id: string) => void
}
): ReactNode {
const walk = (list: FolderTreeNode[]): ReactNode[] => {
const out: ReactNode[] = []
for (const node of sidebarVisibleFolderNodes(
list,
opts.getNavItemPrefs,
opts.folderUnreadCounts
)) {
out.push(
<SidebarFolderButtonCollapsed
key={node.id}
node={node}
isExpanded={opts.isExpanded}
selectedFolder={opts.selectedFolder}
folderUnreadCounts={opts.folderUnreadCounts}
onSelectFolder={opts.onSelectFolder}
/>
)
if (node.children?.length && opts.expandedFolderIds.has(node.id)) {
out.push(...walk(node.children))
}
}
return out
}
return walk(nodes)
}