import { useMemo } from 'react'; import type { DragEvent } from 'react'; import { TAG_FILTER_UNTAGGED } from '../app/appLayoutUtils'; import type { StatusMessage } from '../hooks/documents/store/useDocumentsStore'; type Identifier = string | number; interface FolderTreeNode { id: Identifier; name?: string; hasChildren?: boolean; loaded?: boolean; expanded?: boolean; children: Identifier[]; [key: string]: unknown; } type FolderNodeMap = Map; type FolderToggleHandler = (folderId: Identifier) => void | Promise; type FolderDropHandler = ( event: DragEvent, folderId: Identifier, ) => void | Promise; interface FolderClickHandlers { onToggle: FolderToggleHandler; onSelect: (folderId: Identifier | null) => void; onDrop: FolderDropHandler; onDragOver: (event: DragEvent, folderId: Identifier) => void; onDragLeave: (event: DragEvent) => void; } interface TagOption { id?: Identifier; label?: string; color?: string | null; [key: string]: unknown; } interface CorrespondentOption { id?: Identifier; name?: string; [key: string]: unknown; } interface TenantOption { id?: Identifier; name?: string; [key: string]: unknown; } interface UploadQueueItem { id: string; name?: string; size?: number | null; folderId?: Identifier | 'root'; status?: string; error?: unknown; code?: number | null; document?: unknown; conflictDocumentId?: Identifier | null; [key: string]: unknown; } type UploadFilesHandler = ( files: FileList | File[] | Iterable, targetFolderId: Identifier | 'root', ) => void | Promise; interface UseSidebarPropsArgs { folderNodes: FolderNodeMap; folderClickHandlers: FolderClickHandlers; handleFolderDelete: (folderId: Identifier) => void | Promise; handleFolderRename: (folderId: Identifier, name: string) => void | Promise; selectedFolder: Identifier | null; handleFolderDragStart: (event: DragEvent, folderId: Identifier) => void; handleFolderDragEnd: (event: DragEvent) => void; draggedFolderId: Identifier | null; handlePromptCreateFolder?: () => void; creatingFolder: boolean; tags: TagOption[]; activeTagFilters: Identifier[]; toggleTagFilter: (tagId: Identifier) => void; handleTagCreate: (payload: { label?: string }) => void | Promise; correspondents: CorrespondentOption[]; activeCorrespondentFilters: Identifier[]; toggleCorrespondentFilter: (correspondentId: Identifier) => void; handleCorrespondentCreate: (payload: { name?: string }) => | Promise | CorrespondentOption | null | void; appStatus: string; loading: boolean; previewActive: boolean; searchQuery: string; handleSearchChange: (value: string) => void; handleSearchSubmit: () => void; clearFilters: () => void; isFilterActive: boolean; handleLogout: () => void | Promise; status: StatusMessage | null; tenantName: string | null; tenantOptions: TenantOption[]; currentTenantId: Identifier | null; handleTenantSelect: (tenant: TenantOption | null, options?: { refreshOnly?: boolean }) => void | Promise; openSettings?: () => void; handleFileSelection?: UploadFilesHandler; uploadQueue?: UploadQueueItem[]; } interface SidebarHookResult { folderNodes: FolderNodeMap; onToggle: FolderClickHandlers['onToggle']; onSelect: FolderClickHandlers['onSelect']; onDrop: FolderClickHandlers['onDrop']; onDragOver: FolderClickHandlers['onDragOver']; onDragLeave: FolderClickHandlers['onDragLeave']; onDeleteFolder: UseSidebarPropsArgs['handleFolderDelete']; onRenameFolder: UseSidebarPropsArgs['handleFolderRename']; selectedFolder: Identifier | null; onFolderDragStart: UseSidebarPropsArgs['handleFolderDragStart']; onFolderDragEnd: UseSidebarPropsArgs['handleFolderDragEnd']; draggedFolderId: Identifier | null; onCreateFolder: UseSidebarPropsArgs['handlePromptCreateFolder']; creatingFolder: boolean; tags: TagOption[]; untaggedFilterId: typeof TAG_FILTER_UNTAGGED; activeTagIds: Identifier[]; onToggleTagFilter: UseSidebarPropsArgs['toggleTagFilter']; onCreateTag: (label: string) => void; correspondents: CorrespondentOption[]; activeCorrespondentIds: Identifier[]; onToggleCorrespondentFilter: UseSidebarPropsArgs['toggleCorrespondentFilter']; onCreateCorrespondent: (name: string) => void; appStatus: string; loading: boolean; previewActive: boolean; searchQuery: string; onSearchChange: UseSidebarPropsArgs['handleSearchChange']; onSearchSubmit: UseSidebarPropsArgs['handleSearchSubmit']; onSearchClear: UseSidebarPropsArgs['clearFilters']; isFilterActive: boolean; onLogout: UseSidebarPropsArgs['handleLogout']; status: StatusMessage | null; tenantName: string | null; tenants: TenantOption[]; activeTenantId: Identifier | null; onSelectTenant: UseSidebarPropsArgs['handleTenantSelect']; onOpenSettings: UseSidebarPropsArgs['openSettings']; onUploadFiles: (files: FileList | File[] | Iterable, targetFolderId?: Identifier | 'root') => void; uploadQueue?: UploadQueueItem[]; } const useSidebarProps = ({ folderNodes, folderClickHandlers, handleFolderDelete, handleFolderRename, selectedFolder, handleFolderDragStart, handleFolderDragEnd, draggedFolderId, handlePromptCreateFolder, creatingFolder, tags, activeTagFilters, toggleTagFilter, handleTagCreate, correspondents, activeCorrespondentFilters, toggleCorrespondentFilter, handleCorrespondentCreate, appStatus, loading, previewActive, searchQuery, handleSearchChange, handleSearchSubmit, clearFilters, isFilterActive, handleLogout, status, tenantName, tenantOptions, currentTenantId, handleTenantSelect, openSettings, handleFileSelection, uploadQueue, }: UseSidebarPropsArgs): SidebarHookResult => useMemo( () => ({ folderNodes, onToggle: folderClickHandlers.onToggle, onSelect: folderClickHandlers.onSelect, onDrop: folderClickHandlers.onDrop, onDragOver: folderClickHandlers.onDragOver, onDragLeave: folderClickHandlers.onDragLeave, onDeleteFolder: handleFolderDelete, onRenameFolder: handleFolderRename, selectedFolder, onFolderDragStart: handleFolderDragStart, onFolderDragEnd: handleFolderDragEnd, draggedFolderId, onCreateFolder: handlePromptCreateFolder, creatingFolder, tags, untaggedFilterId: TAG_FILTER_UNTAGGED, activeTagIds: activeTagFilters, onToggleTagFilter: toggleTagFilter, onCreateTag: (label) => handleTagCreate({ label }), correspondents, activeCorrespondentIds: activeCorrespondentFilters, onToggleCorrespondentFilter: toggleCorrespondentFilter, onCreateCorrespondent: (name) => handleCorrespondentCreate({ name }), appStatus, loading, previewActive, searchQuery, onSearchChange: handleSearchChange, onSearchSubmit: handleSearchSubmit, onSearchClear: clearFilters, isFilterActive, onLogout: handleLogout, status, tenantName, tenants: tenantOptions, activeTenantId: currentTenantId, onSelectTenant: handleTenantSelect, onOpenSettings: openSettings, onUploadFiles: (files, targetFolderId) => { if (!handleFileSelection) { return; } if (!files) { return; } const normalizedFiles = Array.isArray(files) ? files : Array.from(files); if (normalizedFiles.length === 0) { return; } const folderId = targetFolderId ?? selectedFolder ?? 'root'; handleFileSelection(normalizedFiles, folderId); }, uploadQueue, }), [ handleFileSelection, uploadQueue, activeCorrespondentFilters, activeTagFilters, appStatus, clearFilters, correspondents, creatingFolder, currentTenantId, folderClickHandlers, folderNodes, handleCorrespondentCreate, handleFolderDragEnd, handleFolderDragStart, handleFolderDelete, handleFolderRename, handleLogout, handlePromptCreateFolder, handleSearchChange, handleSearchSubmit, handleTagCreate, handleTenantSelect, isFilterActive, loading, openSettings, previewActive, searchQuery, draggedFolderId, selectedFolder, status, tags, tenantName, tenantOptions, toggleCorrespondentFilter, toggleTagFilter, ], ); export default useSidebarProps;