feat: Refactor sidebar props to simplify data flow

This commit is contained in:
2025-12-06 23:04:49 +01:00
parent 54d72138d2
commit bd1cdc0817
8 changed files with 111 additions and 247 deletions
+3 -3
View File
@@ -14,11 +14,11 @@ import useDocumentsShell from './useDocumentsShell';
import useFolderData from '../documents/data/useFolderData'; import useFolderData from '../documents/data/useFolderData';
const DocumentsInner: React.FC<{ const DocumentsInner: React.FC<{
sidebarProps: ComponentProps<typeof Sidebar> | null;
surfaceConfig: any; surfaceConfig: any;
folderData: any; folderData: any;
onNavigate: (documentId: string) => void; onNavigate: (documentId: string) => void;
}> = ({ sidebarProps, surfaceConfig, folderData, onNavigate }) => { sidebarProps: ComponentProps<typeof Sidebar> | null;
}> = ({ surfaceConfig, folderData, onNavigate, sidebarProps }) => {
const { openPreview } = usePreviewContext(); const { openPreview } = usePreviewContext();
const { collapsed: sidebarCollapsed } = useSidebarContext(); const { collapsed: sidebarCollapsed } = useSidebarContext();
const { const {
@@ -112,10 +112,10 @@ const DocumentsRouteContent: React.FC = () => {
onNavigate={handleDocumentNavigate} onNavigate={handleDocumentNavigate}
> >
<DocumentsInner <DocumentsInner
sidebarProps={sidebarProps}
surfaceConfig={surfaceConfig} surfaceConfig={surfaceConfig}
folderData={folderData} folderData={folderData}
onNavigate={handleDocumentNavigate} onNavigate={handleDocumentNavigate}
sidebarProps={sidebarProps}
/> />
</PreviewProvider> </PreviewProvider>
</DocumentsFilterProvider> </DocumentsFilterProvider>
@@ -157,9 +157,6 @@ const useDocumentsWorkspace = ({
const { client: apiClient } = useApi(); const { client: apiClient } = useApi();
const tenantRecord = (tenant ?? null) as TenantOption | null; const tenantRecord = (tenant ?? null) as TenantOption | null;
const tenantNameCandidate = tenantRecord?.name ?? tenantRecord?.slug ?? null;
const tenantName = tenantNameCandidate ? String(tenantNameCandidate) : null;
const currentTenantId: Identifier | null = (tenantRecord?.id ?? null) as Identifier | null; const currentTenantId: Identifier | null = (tenantRecord?.id ?? null) as Identifier | null;
const tenantOptions: TenantOption[] = Array.isArray(tenantOptionsRaw) const tenantOptions: TenantOption[] = Array.isArray(tenantOptionsRaw)
@@ -606,7 +603,6 @@ const useDocumentsWorkspace = ({
const { const {
dropOverlayState, dropOverlayState,
handleFileDrop, handleFileDrop,
handleFileSelection,
uploadQueue, uploadQueue,
clearUploadQueue, clearUploadQueue,
resetUploadsState, resetUploadsState,
@@ -1242,7 +1238,6 @@ const useDocumentsWorkspace = ({
); );
const sidebarProps = useSidebarProps({ const sidebarProps = useSidebarProps({
folderNodes,
folderClickHandlers, folderClickHandlers,
handleFolderDelete, handleFolderDelete,
handleFolderRename, handleFolderRename,
@@ -1252,20 +1247,6 @@ const useDocumentsWorkspace = ({
draggedFolderId, draggedFolderId,
handlePromptCreateFolder, handlePromptCreateFolder,
creatingFolder, creatingFolder,
tags,
handleTagCreate,
correspondents,
handleCorrespondentCreate,
appStatus,
previewActive,
handleLogout,
tenantName,
tenantOptions,
currentTenantId,
handleTenantSelect,
openSettings,
handleFileSelection,
uploadQueue,
}); });
const contextValue = { const contextValue = {
@@ -1320,6 +1301,10 @@ const useDocumentsWorkspace = ({
documentsManager, documentsManager,
foldersManager, foldersManager,
handleBreadcrumbNavigate, handleBreadcrumbNavigate,
tenant: tenantRecord,
tenants: tenantOptions,
tenantOptions,
handleTenantSelect,
}; };
// hook callers handle rendering / routing // hook callers handle rendering / routing
+52 -51
View File
@@ -1,23 +1,19 @@
import React, { useRef } from 'react'; import React, { useRef, useSyncExternalStore, useCallback } from 'react';
import { useAppShell } from '../lib/context/AppShellContext';
import { usePanelManager, usePanelResizeBindings } from '../app/PanelManagerContext'; import FoldersManager from '../documents/FoldersManager';
import { usePanelResizeBindings } from '../app/PanelManagerContext';
import type { Identifier } from '../types/identifiers'; import type { Identifier } from '../types/identifiers';
import SidebarFolderList from './components/SidebarFolderList'; import SidebarFolderList from './components/SidebarFolderList';
import SidebarTagList, { TagEntry } from './components/SidebarTagList'; import SidebarTagList from './components/SidebarTagList';
import SidebarCorrespondentList, { CorrespondentEntry } from './components/SidebarCorrespondentList'; import SidebarCorrespondentList from './components/SidebarCorrespondentList';
import { FolderIdentifier, FolderTreeNode } from './components/SidebarFolderNode'; import { FolderIdentifier } from './components/SidebarFolderNode';
import { TenantOption } from './components/SidebarMenu'; import { TenantOption } from './components/SidebarMenu';
import SidebarHeader from './components/SidebarHeader'; import SidebarHeader from './components/SidebarHeader';
import SidebarSearch from './components/SidebarSearch'; import SidebarSearch from './components/SidebarSearch';
type UploadHandler = (
files: FileList | File[] | Iterable<File>,
targetFolderId?: FolderIdentifier | null,
) => void;
interface SidebarProps { interface SidebarProps {
folderNodes: Map<FolderIdentifier, FolderTreeNode>;
onToggle: (folderId: FolderIdentifier) => void; onToggle: (folderId: FolderIdentifier) => void;
onSelect: (folderId: FolderIdentifier) => void; onSelect: (folderId: FolderIdentifier) => void;
onDrop: (event: React.DragEvent<HTMLDivElement>, folderId: FolderIdentifier) => void; onDrop: (event: React.DragEvent<HTMLDivElement>, folderId: FolderIdentifier) => void;
@@ -29,26 +25,11 @@ interface SidebarProps {
onFolderDragStart?: (event: React.DragEvent<HTMLDivElement>, folderId: FolderIdentifier) => void; onFolderDragStart?: (event: React.DragEvent<HTMLDivElement>, folderId: FolderIdentifier) => void;
onFolderDragEnd?: (event: React.DragEvent<HTMLDivElement>) => void; onFolderDragEnd?: (event: React.DragEvent<HTMLDivElement>) => void;
draggedFolderId?: FolderIdentifier | null; draggedFolderId?: FolderIdentifier | null;
onCreateFolder?: (parentId?: FolderIdentifier | null) => void; onCreateFolder?: (parentId?: Identifier | null) => void;
creatingFolder?: boolean; creatingFolder?: boolean;
tags?: TagEntry[];
untaggedFilterId?: Identifier | null;
correspondents?: CorrespondentEntry[];
onManageTags?: () => void;
onManageCorrespondents?: () => void;
onCreateTag?: (label: string) => Promise<void> | void;
onCreateCorrespondent?: (name: string) => Promise<void> | void;
onLogout?: () => void;
tenantName?: string | null;
tenants?: TenantOption[];
activeTenantId?: Identifier | null;
onSelectTenant?: (tenant: TenantOption | null, options?: { refreshOnly?: boolean }) => void;
onOpenSettings?: () => void;
onUploadFiles?: UploadHandler;
} }
const Sidebar: React.FC<SidebarProps> = ({ const Sidebar: React.FC<SidebarProps> = ({
folderNodes,
onToggle, onToggle,
onSelect, onSelect,
onDrop, onDrop,
@@ -62,24 +43,46 @@ const Sidebar: React.FC<SidebarProps> = ({
draggedFolderId = null, draggedFolderId = null,
onCreateFolder, onCreateFolder,
creatingFolder = false, creatingFolder = false,
tags = [],
untaggedFilterId = null,
correspondents = [],
onManageTags,
onManageCorrespondents,
onCreateTag,
onCreateCorrespondent,
onLogout,
tenantName,
tenants = [],
activeTenantId = null,
onSelectTenant,
onOpenSettings,
onUploadFiles,
}) => { }) => {
const { const {
sidebarSuppressed, sidebarSuppressed,
} = usePanelManager(); openTagsModal,
openCorrespondentsModal,
handleLogout,
tags = [],
correspondents = [],
foldersManager,
tenant,
tenants,
tenantOptions,
handleTenantSelect,
openSettings,
handleFileSelection, // Used for upload
} = useAppShell();
// Subscribe to folder tree updates
const subscribeToTree = useCallback((callback: () => void) => {
if (!foldersManager) return () => { };
return (foldersManager as FoldersManager).subscribe(callback);
}, [foldersManager]);
const getTreeSnapshot = useCallback(() => {
if (!foldersManager) return [];
return (foldersManager as FoldersManager).getTreeSnapshot();
}, [foldersManager]);
const roots = useSyncExternalStore(subscribeToTree, getTreeSnapshot);
const onManageTags = openTagsModal;
const onManageCorrespondents = openCorrespondentsModal;
// Derived or context-based handlers/values
const tenantName = (tenant as TenantOption)?.name;
const effectiveTenants = (tenants || tenantOptions || []);
const activeTenantId = (tenant as TenantOption)?.id;
// Upload handler wrapper (if needed, or pass handleFileSelection directly if signature matches)
const onUploadFiles = handleFileSelection;
const sidebarRef = useRef<HTMLDivElement | null>(null); const sidebarRef = useRef<HTMLDivElement | null>(null);
const { const {
@@ -109,11 +112,11 @@ const Sidebar: React.FC<SidebarProps> = ({
<SidebarHeader <SidebarHeader
tenantName={tenantName} tenantName={tenantName}
tenants={tenants} tenants={effectiveTenants}
activeTenantId={activeTenantId} activeTenantId={activeTenantId}
onSelectTenant={onSelectTenant} onSelectTenant={handleTenantSelect}
onOpenSettings={onOpenSettings} onOpenSettings={openSettings}
onLogout={onLogout} onLogout={handleLogout}
onUploadFiles={onUploadFiles} onUploadFiles={onUploadFiles}
selectedFolder={selectedFolder} selectedFolder={selectedFolder}
/> />
@@ -122,7 +125,7 @@ const Sidebar: React.FC<SidebarProps> = ({
<SidebarSearch /> <SidebarSearch />
<SidebarFolderList <SidebarFolderList
folderNodes={folderNodes} roots={roots}
selectedFolder={selectedFolder} selectedFolder={selectedFolder}
onToggle={onToggle} onToggle={onToggle}
onSelect={onSelect} onSelect={onSelect}
@@ -140,14 +143,12 @@ const Sidebar: React.FC<SidebarProps> = ({
<SidebarTagList <SidebarTagList
tags={tags} tags={tags}
untaggedFilterId={untaggedFilterId} untaggedFilterId={null}
onCreateTag={onCreateTag}
onManageTags={onManageTags} onManageTags={onManageTags}
/> />
<SidebarCorrespondentList <SidebarCorrespondentList
correspondents={correspondents} correspondents={correspondents}
onCreateCorrespondent={onCreateCorrespondent}
onManageCorrespondents={onManageCorrespondents} onManageCorrespondents={onManageCorrespondents}
/> />
</div> </div>
@@ -3,7 +3,7 @@ import { PlusIcon, SettingsIcon } from '../../components/icons';
import type { Identifier } from '../../types/identifiers'; import type { Identifier } from '../../types/identifiers';
import { useDocumentsFilter } from '../../documents/context/DocumentsFilterContext'; import { useDocumentsFilter } from '../../documents/context/DocumentsFilterContext';
export interface CorrespondentEntry { interface CorrespondentEntry {
id: Identifier; id: Identifier;
name: string; name: string;
} }
@@ -2,10 +2,11 @@ import React, { useCallback } from 'react';
import type { ReactNode } from 'react'; import type { ReactNode } from 'react';
import type { Identifier } from '../../types/identifiers'; import type { Identifier } from '../../types/identifiers';
import { FolderPlusIcon } from '../../components/icons'; import { FolderPlusIcon } from '../../components/icons';
import FolderNode, { FolderIdentifier, FolderTreeNode } from './SidebarFolderNode'; import FolderNode, { FolderIdentifier } from './SidebarFolderNode';
import type { FolderTreeNode } from '../../lib/api/apiTypes';
interface SidebarFolderListProps { interface SidebarFolderListProps {
folderNodes: Map<FolderIdentifier, FolderTreeNode>; roots: FolderTreeNode[];
selectedFolder: FolderIdentifier | null; selectedFolder: FolderIdentifier | null;
onToggle: (folderId: FolderIdentifier) => void; onToggle: (folderId: FolderIdentifier) => void;
onSelect: (folderId: FolderIdentifier) => void; onSelect: (folderId: FolderIdentifier) => void;
@@ -22,7 +23,7 @@ interface SidebarFolderListProps {
} }
const SidebarFolderList: React.FC<SidebarFolderListProps> = ({ const SidebarFolderList: React.FC<SidebarFolderListProps> = ({
folderNodes, roots,
selectedFolder, selectedFolder,
onToggle, onToggle,
onSelect, onSelect,
@@ -37,20 +38,44 @@ const SidebarFolderList: React.FC<SidebarFolderListProps> = ({
onCreateFolder, onCreateFolder,
creatingFolder, creatingFolder,
}) => { }) => {
const rootNode = folderNodes.get('root'); // Local expansion state for the UI
const [expandedIds, setExpandedIds] = React.useState<Set<string>>(new Set(['root']));
// Override validation or external toggle if needed
React.useEffect(() => {
if (selectedFolder) {
// ensure parent paths are expanded?
// Without a parent map, we can't easily auto-expand up.
// Rely on user or initial state for now, or add parent pointers.
}
}, [selectedFolder]);
const handleToggle = useCallback((folderId: FolderIdentifier) => {
setExpandedIds((prev) => {
const next = new Set(prev);
const id = String(folderId);
if (next.has(id)) {
next.delete(id);
} else {
next.add(id);
}
return next;
});
onToggle(folderId); // propagate event just in case parent needs it
}, [onToggle]);
const renderNodes = useCallback( const renderNodes = useCallback(
(ids: FolderIdentifier[], depth: number): ReactNode => (nodes: FolderTreeNode[], depth: number): ReactNode =>
ids.map((id) => { nodes.map((node) => {
const node = folderNodes.get(id); const isExpanded = expandedIds.has(String(node.id));
if (!node) return null;
return ( return (
<FolderNode <FolderNode
key={id} key={node.id}
node={node} node={node}
depth={depth} depth={depth}
isSelected={selectedFolder === id} isSelected={selectedFolder === node.id}
onToggle={onToggle} onToggle={handleToggle}
expanded={isExpanded}
onSelect={onSelect} onSelect={onSelect}
onDrop={onDrop} onDrop={onDrop}
onDragOver={onDragOver} onDragOver={onDragOver}
@@ -66,9 +91,9 @@ const SidebarFolderList: React.FC<SidebarFolderListProps> = ({
); );
}), }),
[ [
folderNodes, expandedIds,
selectedFolder, selectedFolder,
onToggle, handleToggle,
onSelect, onSelect,
onDrop, onDrop,
onDragOver, onDragOver,
@@ -101,7 +126,7 @@ const SidebarFolderList: React.FC<SidebarFolderListProps> = ({
) : null} ) : null}
</div> </div>
<ul className="folder-tree"> <ul className="folder-tree">
{rootNode && renderNodes([rootNode.id], 0)} {renderNodes(roots, 0)}
</ul> </ul>
</div> </div>
); );
@@ -9,16 +9,9 @@ import {
} from '../../components/icons'; } from '../../components/icons';
import type { Identifier } from '../../types/identifiers'; import type { Identifier } from '../../types/identifiers';
export type FolderIdentifier = Identifier | 'root'; import type { FolderTreeNode } from '../../lib/api/apiTypes';
export interface FolderTreeNode { export type FolderIdentifier = Identifier | 'root';
id: FolderIdentifier;
name?: string;
children: FolderIdentifier[];
hasChildren?: boolean;
loaded?: boolean;
expanded?: boolean;
}
interface FolderNodeProps { interface FolderNodeProps {
node: FolderTreeNode; node: FolderTreeNode;
@@ -31,7 +24,8 @@ interface FolderNodeProps {
onDragLeave: (event: React.DragEvent<HTMLDivElement>) => void; onDragLeave: (event: React.DragEvent<HTMLDivElement>) => void;
onDelete: (folderId: FolderIdentifier) => void; onDelete: (folderId: FolderIdentifier) => void;
onRename?: (folderId: FolderIdentifier, name: string) => void; onRename?: (folderId: FolderIdentifier, name: string) => void;
renderChildren: (ids: FolderIdentifier[], depth: number) => ReactNode; renderChildren: (nodes: FolderTreeNode[], depth: number) => ReactNode;
expanded: boolean;
onFolderDragStart?: (event: React.DragEvent<HTMLDivElement>, folderId: FolderIdentifier) => void; onFolderDragStart?: (event: React.DragEvent<HTMLDivElement>, folderId: FolderIdentifier) => void;
onFolderDragEnd?: (event: React.DragEvent<HTMLDivElement>) => void; onFolderDragEnd?: (event: React.DragEvent<HTMLDivElement>) => void;
draggingFolderId?: FolderIdentifier | null; draggingFolderId?: FolderIdentifier | null;
@@ -50,20 +44,21 @@ const FolderNode: React.FC<FolderNodeProps> = ({
onDelete, onDelete,
onRename, onRename,
renderChildren, renderChildren,
expanded,
onFolderDragStart, onFolderDragStart,
onFolderDragEnd, onFolderDragEnd,
draggingFolderId, draggingFolderId,
onCreateFolder, onCreateFolder,
}) => { }) => {
const isRoot = node.id === 'root'; const isRoot = node.id === 'root';
const childIds = Array.isArray(node.children) ? node.children : []; const childNodes = node.children || [];
const hasChildren = Boolean(node.hasChildren || childIds.length); const hasChildren = childNodes.length > 0;
const canToggle = hasChildren || !node.loaded; const canToggle = hasChildren; // Simplified: only toggle if we have children to show
const showChevron = canToggle; const showChevron = canToggle;
const icon = showChevron ? <ChevronIcon className="toggle-icon" /> : null; const icon = showChevron ? <ChevronIcon className="toggle-icon" /> : null;
const canDrag = !isRoot; const canDrag = !isRoot;
const isDragging = draggingFolderId === node.id; const isDragging = draggingFolderId === node.id;
const isExpanded = Boolean(node.expanded); const isExpanded = expanded;
const rowClasses = ['folder-row']; const rowClasses = ['folder-row'];
if (isSelected) { if (isSelected) {
rowClasses.push('active'); rowClasses.push('active');
@@ -162,9 +157,9 @@ const FolderNode: React.FC<FolderNodeProps> = ({
)} )}
</div> </div>
</div> </div>
{isExpanded && childIds.length > 0 && ( {isExpanded && childNodes.length > 0 && (
<ul className={`folder-children${depth === 0 ? ' folder-children--level1' : ''}`}> <ul className={`folder-children${depth === 0 ? ' folder-children--level1' : ''}`}>
{renderChildren(childIds, depth + 1)} {renderChildren(childNodes, depth + 1)}
</ul> </ul>
)} )}
</li> </li>
@@ -4,7 +4,7 @@ import { getTagColorStyle } from '../../utils/colors';
import type { Identifier } from '../../types/identifiers'; import type { Identifier } from '../../types/identifiers';
import { useDocumentsFilter } from '../../documents/context/DocumentsFilterContext'; import { useDocumentsFilter } from '../../documents/context/DocumentsFilterContext';
export interface TagEntry { interface TagEntry {
id: Identifier; id: Identifier;
label: string; label: string;
color?: string | null; color?: string | null;
-142
View File
@@ -1,20 +1,7 @@
import { useMemo } from 'react'; import { useMemo } from 'react';
import type { DragEvent } from 'react'; import type { DragEvent } from 'react';
import { TAG_FILTER_UNTAGGED } from '../app/workspaceUtils';
import type { Identifier } from '../types/identifiers'; import type { Identifier } from '../types/identifiers';
interface FolderTreeNode {
id: Identifier;
name?: string;
hasChildren?: boolean;
loaded?: boolean;
expanded?: boolean;
children: Identifier[];
[key: string]: unknown;
}
type FolderNodeMap = Map<Identifier, FolderTreeNode>;
type FolderToggleHandler = (folderId: Identifier) => void | Promise<void>; type FolderToggleHandler = (folderId: Identifier) => void | Promise<void>;
type FolderDropHandler = ( type FolderDropHandler = (
event: DragEvent<HTMLElement>, event: DragEvent<HTMLElement>,
@@ -29,45 +16,8 @@ interface FolderClickHandlers {
onDragLeave: (event: DragEvent<HTMLElement>) => void; onDragLeave: (event: DragEvent<HTMLElement>) => 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<File>,
targetFolderId: Identifier | 'root',
) => void | Promise<void>;
interface UseSidebarPropsArgs { interface UseSidebarPropsArgs {
folderNodes: FolderNodeMap;
folderClickHandlers: FolderClickHandlers; folderClickHandlers: FolderClickHandlers;
handleFolderDelete: (folderId: Identifier) => void | Promise<void>; handleFolderDelete: (folderId: Identifier) => void | Promise<void>;
handleFolderRename: (folderId: Identifier, name: string) => void | Promise<void>; handleFolderRename: (folderId: Identifier, name: string) => void | Promise<void>;
@@ -77,28 +27,9 @@ interface UseSidebarPropsArgs {
draggedFolderId: Identifier | null; draggedFolderId: Identifier | null;
handlePromptCreateFolder?: (parentId?: Identifier | null) => void; handlePromptCreateFolder?: (parentId?: Identifier | null) => void;
creatingFolder: boolean; creatingFolder: boolean;
tags: TagOption[];
handleTagCreate: (payload: { label?: string }) => void | Promise<void>;
correspondents: CorrespondentOption[];
handleCorrespondentCreate: (payload: { name?: string }) =>
| Promise<CorrespondentOption | null | void>
| CorrespondentOption
| null
| void;
appStatus: string;
previewActive: boolean;
handleLogout: () => void | Promise<void>;
tenantName: string | null;
tenantOptions: TenantOption[];
currentTenantId: Identifier | null;
handleTenantSelect: (tenant: TenantOption | null, options?: { refreshOnly?: boolean }) => void | Promise<void>;
openSettings?: () => void;
handleFileSelection?: UploadFilesHandler;
uploadQueue?: UploadQueueItem[];
} }
interface SidebarHookResult { interface SidebarHookResult {
folderNodes: FolderNodeMap;
onToggle: FolderClickHandlers['onToggle']; onToggle: FolderClickHandlers['onToggle'];
onSelect: FolderClickHandlers['onSelect']; onSelect: FolderClickHandlers['onSelect'];
onDrop: FolderClickHandlers['onDrop']; onDrop: FolderClickHandlers['onDrop'];
@@ -112,24 +43,9 @@ interface SidebarHookResult {
draggedFolderId: Identifier | null; draggedFolderId: Identifier | null;
onCreateFolder: UseSidebarPropsArgs['handlePromptCreateFolder']; onCreateFolder: UseSidebarPropsArgs['handlePromptCreateFolder'];
creatingFolder: boolean; creatingFolder: boolean;
tags: TagOption[];
untaggedFilterId: typeof TAG_FILTER_UNTAGGED;
onCreateTag: (label: string) => void;
correspondents: CorrespondentOption[];
onCreateCorrespondent: (name: string) => void;
previewActive: boolean;
onLogout: UseSidebarPropsArgs['handleLogout'];
tenantName: string | null;
tenants: TenantOption[];
activeTenantId: Identifier | null;
onSelectTenant: UseSidebarPropsArgs['handleTenantSelect'];
onOpenSettings: UseSidebarPropsArgs['openSettings'];
onUploadFiles: (files: FileList | File[] | Iterable<File>, targetFolderId?: Identifier | 'root') => void;
uploadQueue?: UploadQueueItem[];
} }
const useSidebarProps = ({ const useSidebarProps = ({
folderNodes,
folderClickHandlers, folderClickHandlers,
handleFolderDelete, handleFolderDelete,
handleFolderRename, handleFolderRename,
@@ -139,24 +55,9 @@ const useSidebarProps = ({
draggedFolderId, draggedFolderId,
handlePromptCreateFolder, handlePromptCreateFolder,
creatingFolder, creatingFolder,
tags,
handleTagCreate,
correspondents,
handleCorrespondentCreate,
appStatus,
previewActive,
handleLogout,
tenantName,
tenantOptions,
currentTenantId,
handleTenantSelect,
openSettings,
handleFileSelection,
uploadQueue,
}: UseSidebarPropsArgs): SidebarHookResult => }: UseSidebarPropsArgs): SidebarHookResult =>
useMemo( useMemo(
() => ({ () => ({
folderNodes,
onToggle: folderClickHandlers.onToggle, onToggle: folderClickHandlers.onToggle,
onSelect: folderClickHandlers.onSelect, onSelect: folderClickHandlers.onSelect,
onDrop: folderClickHandlers.onDrop, onDrop: folderClickHandlers.onDrop,
@@ -170,60 +71,17 @@ const useSidebarProps = ({
draggedFolderId, draggedFolderId,
onCreateFolder: (parentId) => handlePromptCreateFolder?.(parentId), onCreateFolder: (parentId) => handlePromptCreateFolder?.(parentId),
creatingFolder, creatingFolder,
tags,
untaggedFilterId: TAG_FILTER_UNTAGGED,
onCreateTag: (label) => handleTagCreate({ label }),
correspondents,
onCreateCorrespondent: (name) => handleCorrespondentCreate({ name }),
appStatus,
previewActive,
onLogout: handleLogout,
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,
appStatus,
correspondents,
creatingFolder, creatingFolder,
currentTenantId,
folderClickHandlers, folderClickHandlers,
folderNodes,
handleCorrespondentCreate,
handleFolderDragEnd, handleFolderDragEnd,
handleFolderDragStart, handleFolderDragStart,
handleFolderDelete, handleFolderDelete,
handleFolderRename, handleFolderRename,
handleLogout,
handlePromptCreateFolder, handlePromptCreateFolder,
handleTagCreate,
handleTenantSelect,
openSettings,
previewActive,
draggedFolderId, draggedFolderId,
selectedFolder, selectedFolder,
tags,
tenantName,
tenantOptions,
], ],
); );