search cleanup
This commit is contained in:
@@ -28,7 +28,6 @@ const AppLayout: React.FC = () => {
|
||||
onDocumentsSortFieldChange: documentsPreferences.handleDocumentsSortFieldChange,
|
||||
onDocumentsSortDirectionToggle: documentsPreferences.handleDocumentsSortDirectionToggle,
|
||||
searchIncludeDescendants: documentsPreferences.searchIncludeDescendants,
|
||||
onToggleSearchIncludeDescendants: documentsPreferences.toggleSearchIncludeDescendants,
|
||||
onSetSearchIncludeDescendants: documentsPreferences.setSearchIncludeDescendants,
|
||||
sortRefreshReadyRef: documentsPreferences.sortRefreshReadyRef,
|
||||
});
|
||||
|
||||
@@ -2,6 +2,10 @@ import React, { useCallback, useEffect, useMemo } from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useAppShell } from '../appShellContext';
|
||||
import {
|
||||
DocumentsFilterProvider,
|
||||
} from '../documents/context/DocumentsFilterContext';
|
||||
import type { DocumentsFilterValue } from '../documents/context/DocumentsFilterContext';
|
||||
import { useWorkspaceSurface } from './useWorkspaceSurface';
|
||||
import { DocumentsHeaderBreadcrumb } from '../documents/panel/DocumentsPanelHeader';
|
||||
import { SidebarProvider, useSidebarContext } from '../sidebar/SidebarContext';
|
||||
@@ -43,6 +47,7 @@ interface DocumentsRouteAppShell {
|
||||
ensureAssetUrl?: EnsureAssetUrl;
|
||||
getDocumentAsset?: GetDocumentAsset;
|
||||
notifyApiError?: NotifyApiError;
|
||||
documentsFilter: DocumentsFilterValue;
|
||||
}
|
||||
|
||||
const DocumentsRouteContent: React.FC = () => {
|
||||
@@ -62,7 +67,8 @@ const DocumentsRouteContent: React.FC = () => {
|
||||
ensureAssetUrl,
|
||||
getDocumentAsset,
|
||||
notifyApiError,
|
||||
} = useAppShell() as DocumentsRouteAppShell;
|
||||
documentsFilter,
|
||||
} = useAppShell() as unknown as DocumentsRouteAppShell;
|
||||
const navigate = useNavigate();
|
||||
const { collapsed: sidebarCollapsed } = useSidebarContext();
|
||||
const {
|
||||
@@ -124,26 +130,35 @@ const DocumentsRouteContent: React.FC = () => {
|
||||
};
|
||||
}, []);
|
||||
|
||||
if (!surface) {
|
||||
const renderSurface = () => {
|
||||
if (!surface) {
|
||||
return (
|
||||
<main className={`documents-main${sidebarHidden ? ' documents-main--sidebar-hidden' : ''}`}>
|
||||
{!sidebarHidden ? <Sidebar {...sidebarPropsWithActions} /> : null}
|
||||
<div className="main-content">
|
||||
<div className="main-content__body" />
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
const surfaceDetail = (surface as { detail?: ReactNode }).detail || null;
|
||||
return (
|
||||
<main className={`documents-main${sidebarHidden ? ' documents-main--sidebar-hidden' : ''}`}>
|
||||
{!sidebarHidden ? <Sidebar {...sidebarPropsWithActions} /> : null}
|
||||
<div className="main-content">
|
||||
<div className="main-content__body" />
|
||||
<div className="main-content__body">{surface.content}</div>
|
||||
{surfaceDetail}
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const surfaceDetail = (surface as { detail?: ReactNode }).detail || null;
|
||||
const content = renderSurface();
|
||||
return (
|
||||
<main className={`documents-main${sidebarHidden ? ' documents-main--sidebar-hidden' : ''}`}>
|
||||
{!sidebarHidden ? <Sidebar {...sidebarPropsWithActions} /> : null}
|
||||
<div className="main-content">
|
||||
<div className="main-content__body">{surface.content}</div>
|
||||
{surfaceDetail}
|
||||
</div>
|
||||
</main>
|
||||
<DocumentsFilterProvider value={documentsFilter}>
|
||||
{content}
|
||||
</DocumentsFilterProvider>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -47,6 +47,21 @@ interface UseDocumentsSearchResult {
|
||||
clearFilters: () => void;
|
||||
handleSearchChange: (value: string) => void;
|
||||
handleSearchSubmit: () => void;
|
||||
documentsFilterValue: {
|
||||
query: string;
|
||||
searchResults: DocumentLike[] | null;
|
||||
searchLoading: boolean;
|
||||
includeDescendants: boolean;
|
||||
activeTagIds: Identifier[];
|
||||
activeCorrespondentIds: Identifier[];
|
||||
isActive: boolean;
|
||||
setQuery: (value: string) => void;
|
||||
submit: () => void;
|
||||
clear: () => void;
|
||||
toggleTag: (tagId: Identifier) => void;
|
||||
toggleCorrespondent: (correspondentId?: Identifier | null) => void;
|
||||
toggleIncludeDescendants: () => void;
|
||||
};
|
||||
}
|
||||
|
||||
const useDocumentsSearch = ({
|
||||
@@ -124,6 +139,39 @@ const useDocumentsSearch = ({
|
||||
}
|
||||
}, [navigate, selectedFolder, isDocumentsRoute, locationPathname]);
|
||||
|
||||
const documentsFilterValue = useMemo(
|
||||
() => ({
|
||||
query: searchQuery,
|
||||
searchResults,
|
||||
searchLoading,
|
||||
includeDescendants: Boolean(searchIncludeDescendants),
|
||||
activeTagIds: activeTagFilters,
|
||||
activeCorrespondentIds: activeCorrespondentFilters,
|
||||
isActive: isFilterActive,
|
||||
setQuery: handleSearchChange,
|
||||
submit: handleSearchSubmit,
|
||||
clear: clearFilters,
|
||||
toggleTag: toggleTagFilter,
|
||||
toggleCorrespondent: toggleCorrespondentFilter,
|
||||
toggleIncludeDescendants: () => setSearchIncludeDescendants(!searchIncludeDescendants),
|
||||
}),
|
||||
[
|
||||
searchQuery,
|
||||
searchResults,
|
||||
searchLoading,
|
||||
searchIncludeDescendants,
|
||||
activeTagFilters,
|
||||
activeCorrespondentFilters,
|
||||
isFilterActive,
|
||||
handleSearchChange,
|
||||
handleSearchSubmit,
|
||||
clearFilters,
|
||||
toggleTagFilter,
|
||||
toggleCorrespondentFilter,
|
||||
setSearchIncludeDescendants,
|
||||
],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!token) return undefined;
|
||||
|
||||
@@ -237,6 +285,7 @@ const useDocumentsSearch = ({
|
||||
clearFilters,
|
||||
handleSearchChange,
|
||||
handleSearchSubmit,
|
||||
documentsFilterValue,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import React, { createContext, useContext } from 'react';
|
||||
|
||||
type Identifier = string | number;
|
||||
|
||||
export interface DocumentsFilterValue {
|
||||
query: string;
|
||||
searchResults: Array<Record<string, unknown>> | null;
|
||||
searchLoading: boolean;
|
||||
includeDescendants: boolean;
|
||||
activeTagIds: Identifier[];
|
||||
activeCorrespondentIds: Identifier[];
|
||||
isActive: boolean;
|
||||
setQuery: (value: string) => void;
|
||||
submit: () => void;
|
||||
clear: () => void;
|
||||
toggleTag: (tagId: Identifier) => void;
|
||||
toggleCorrespondent: (correspondentId?: Identifier | null) => void;
|
||||
toggleIncludeDescendants: () => void;
|
||||
}
|
||||
|
||||
const DocumentsFilterContext = createContext<DocumentsFilterValue | null>(null);
|
||||
|
||||
interface DocumentsFilterProviderProps {
|
||||
value: DocumentsFilterValue;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export const DocumentsFilterProvider: React.FC<DocumentsFilterProviderProps> = ({ value, children }) => (
|
||||
<DocumentsFilterContext.Provider value={value}>{children}</DocumentsFilterContext.Provider>
|
||||
);
|
||||
|
||||
export const useDocumentsFilter = (): DocumentsFilterValue => {
|
||||
const context = useContext(DocumentsFilterContext);
|
||||
if (!context) {
|
||||
throw new Error('useDocumentsFilter must be used within a DocumentsFilterProvider');
|
||||
}
|
||||
return context;
|
||||
};
|
||||
|
||||
export default DocumentsFilterContext;
|
||||
@@ -28,7 +28,6 @@ export interface UseDocumentsPanelPropsArgs {
|
||||
currentSubfolders?: unknown[];
|
||||
documents?: unknown[];
|
||||
searchResults?: unknown[] | null;
|
||||
isFilterActive?: boolean;
|
||||
folderClickHandlers: FolderClickHandlers;
|
||||
selectFolder?: (...args: unknown[]) => void;
|
||||
handleFolderDragStart?: (...args: unknown[]) => void;
|
||||
@@ -46,16 +45,12 @@ export interface UseDocumentsPanelPropsArgs {
|
||||
activeCorrespondentFilters?: Identifier[];
|
||||
ensureAssetUrl?: (...args: unknown[]) => void;
|
||||
getDocumentAsset?: (...args: unknown[]) => unknown;
|
||||
toggleTagFilter?: (...args: unknown[]) => void;
|
||||
toggleCorrespondentFilter?: (...args: unknown[]) => void;
|
||||
handleDocumentTagDrop?: (...args: unknown[]) => void;
|
||||
documentsViewMode?: string;
|
||||
documentsSortField?: string;
|
||||
documentsSortDirection?: string;
|
||||
handleDocumentsSortFieldChange?: (field: string) => void;
|
||||
handleDocumentsSortDirectionToggle?: () => void;
|
||||
searchIncludeDescendants?: boolean;
|
||||
toggleSearchIncludeDescendants?: () => void;
|
||||
handleDocumentsViewModeChange?: (mode: string) => void;
|
||||
clearDocumentSelection?: () => void;
|
||||
handleDeleteSelection?: () => void;
|
||||
@@ -86,7 +81,6 @@ const useDocumentsPanelProps = (props: UseDocumentsPanelPropsArgs) => {
|
||||
currentSubfolders,
|
||||
documents,
|
||||
searchResults,
|
||||
isFilterActive,
|
||||
folderClickHandlers,
|
||||
selectFolder,
|
||||
handleFolderDragStart,
|
||||
@@ -104,16 +98,12 @@ const useDocumentsPanelProps = (props: UseDocumentsPanelPropsArgs) => {
|
||||
activeCorrespondentFilters,
|
||||
ensureAssetUrl,
|
||||
getDocumentAsset,
|
||||
toggleTagFilter,
|
||||
toggleCorrespondentFilter,
|
||||
handleDocumentTagDrop,
|
||||
documentsViewMode,
|
||||
documentsSortField,
|
||||
documentsSortDirection,
|
||||
handleDocumentsSortFieldChange,
|
||||
handleDocumentsSortDirectionToggle,
|
||||
searchIncludeDescendants,
|
||||
toggleSearchIncludeDescendants,
|
||||
handleDocumentsViewModeChange,
|
||||
handleDeleteSelection,
|
||||
handleEntryPointerCore,
|
||||
@@ -141,7 +131,6 @@ const useDocumentsPanelProps = (props: UseDocumentsPanelPropsArgs) => {
|
||||
subfolders: currentSubfolders,
|
||||
documents,
|
||||
searchResults,
|
||||
isFilterActive,
|
||||
onFolderSelect: selectFolder,
|
||||
onFolderDrop: folderClickHandlers.onDrop,
|
||||
onFolderDragOver: folderClickHandlers.onDragOver,
|
||||
@@ -161,16 +150,12 @@ const useDocumentsPanelProps = (props: UseDocumentsPanelPropsArgs) => {
|
||||
activeCorrespondentIds: activeCorrespondentFilters,
|
||||
ensureAssetUrl,
|
||||
getDocumentAsset,
|
||||
onTagClick: toggleTagFilter,
|
||||
onCorrespondentClick: toggleCorrespondentFilter,
|
||||
onDocumentTagDrop: handleDocumentTagDrop,
|
||||
viewMode: documentsViewMode,
|
||||
sortField: documentsSortField,
|
||||
sortDirection: documentsSortDirection,
|
||||
onSortFieldChange: handleDocumentsSortFieldChange,
|
||||
onSortDirectionToggle: handleDocumentsSortDirectionToggle,
|
||||
searchIncludeDescendants,
|
||||
onToggleSearchIncludeDescendants: toggleSearchIncludeDescendants,
|
||||
onViewModeChange: handleDocumentsViewModeChange,
|
||||
onDeleteSelection: handleDeleteSelection,
|
||||
onEntryPointer: handleEntryPointerCore,
|
||||
@@ -222,19 +207,14 @@ const useDocumentsPanelProps = (props: UseDocumentsPanelPropsArgs) => {
|
||||
handleFolderDragStart,
|
||||
handleFolderRename,
|
||||
inspectDocument,
|
||||
isFilterActive,
|
||||
moveDocumentsToFolder,
|
||||
openDocumentPreview,
|
||||
refreshCurrentFolder,
|
||||
searchIncludeDescendants,
|
||||
searchLoading,
|
||||
searchResults,
|
||||
selectFolder,
|
||||
tagLookupById,
|
||||
tags,
|
||||
toggleCorrespondentFilter,
|
||||
toggleSearchIncludeDescendants,
|
||||
toggleTagFilter,
|
||||
ensureAssetUrl,
|
||||
getDocumentAsset,
|
||||
folderOptions,
|
||||
|
||||
@@ -17,6 +17,7 @@ import DocumentsPanelHeader, {
|
||||
} from './DocumentsPanelHeader';
|
||||
import { SelectionFloatingPanel } from '../SelectionFloatingActions';
|
||||
import { createDocumentsTableHeaderActions } from './DocumentsToolbar';
|
||||
import { useDocumentsFilter } from '../context/DocumentsFilterContext';
|
||||
|
||||
const DEFAULT_GRID_ICON_SIZE = 144;
|
||||
|
||||
@@ -47,7 +48,6 @@ const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = ({
|
||||
subfolders,
|
||||
documents,
|
||||
searchResults,
|
||||
isFilterActive = false,
|
||||
onFolderSelect,
|
||||
onFolderDrop,
|
||||
onFolderDragOver,
|
||||
@@ -66,8 +66,6 @@ const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = ({
|
||||
activeCorrespondentIds = [],
|
||||
ensureAssetUrl = null,
|
||||
getDocumentAsset = defaultGetDocumentAsset,
|
||||
onTagClick,
|
||||
onCorrespondentClick,
|
||||
isSearchLoading = false,
|
||||
onDocumentTagDrop,
|
||||
viewMode = 'list',
|
||||
@@ -80,8 +78,6 @@ const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = ({
|
||||
sortDirection,
|
||||
onSortFieldChange,
|
||||
onSortDirectionToggle,
|
||||
searchIncludeDescendants,
|
||||
onToggleSearchIncludeDescendants,
|
||||
onDeleteSelection,
|
||||
documentLookup,
|
||||
tags,
|
||||
@@ -101,6 +97,13 @@ const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = ({
|
||||
handleEntrySelection,
|
||||
clearSelection,
|
||||
} = useWorkspaceSelectionContext();
|
||||
const {
|
||||
isActive: isFilterActive,
|
||||
includeDescendants,
|
||||
toggleIncludeDescendants,
|
||||
toggleTag: toggleTagFilter,
|
||||
toggleCorrespondent: toggleCorrespondentFilter,
|
||||
} = useDocumentsFilter();
|
||||
const showingSearchResults = searchResults !== null;
|
||||
const rows = showingSearchResults ? searchResults : documents;
|
||||
const documentLinkMap = documentLinks instanceof Map ? documentLinks : null;
|
||||
@@ -121,8 +124,8 @@ const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = ({
|
||||
sortDirection,
|
||||
onSortDirectionToggle,
|
||||
isFilterActive,
|
||||
includeDescendants: searchIncludeDescendants,
|
||||
onToggleIncludeDescendants: onToggleSearchIncludeDescendants,
|
||||
includeDescendants,
|
||||
onToggleIncludeDescendants: toggleIncludeDescendants,
|
||||
}),
|
||||
[
|
||||
viewMode,
|
||||
@@ -133,8 +136,8 @@ const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = ({
|
||||
sortDirection,
|
||||
onSortDirectionToggle,
|
||||
isFilterActive,
|
||||
searchIncludeDescendants,
|
||||
onToggleSearchIncludeDescendants,
|
||||
includeDescendants,
|
||||
toggleIncludeDescendants,
|
||||
],
|
||||
);
|
||||
const floatingActions = useMemo(() => (
|
||||
@@ -740,9 +743,9 @@ const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = ({
|
||||
getDocumentAsset={getDocumentAsset}
|
||||
gridIconSize={gridIconSize}
|
||||
tagLookupById={tagLookupById}
|
||||
onTagClick={onTagClick}
|
||||
onTagClick={toggleTagFilter}
|
||||
scrollRef={scrollRef}
|
||||
onCorrespondentClick={onCorrespondentClick}
|
||||
onCorrespondentClick={toggleCorrespondentFilter}
|
||||
activeCorrespondentIdSet={activeCorrespondentIdSet}
|
||||
onDocumentRename={onDocumentRename}
|
||||
onFolderRename={onFolderRename}
|
||||
@@ -775,8 +778,8 @@ const DocumentsPanelInner: React.FC<DocumentsPanelInnerProps> = ({
|
||||
onDocumentTagDrop={handleDocumentTagDrop}
|
||||
onDocumentRename={onDocumentRename}
|
||||
tagLookupById={tagLookupById}
|
||||
onTagClick={onTagClick}
|
||||
onCorrespondentClick={onCorrespondentClick}
|
||||
onTagClick={toggleTagFilter}
|
||||
onCorrespondentClick={toggleCorrespondentFilter}
|
||||
activeCorrespondentIdSet={activeCorrespondentIdSet}
|
||||
scrollRef={scrollRef}
|
||||
/>
|
||||
|
||||
@@ -93,7 +93,6 @@ interface UseDocumentsWorkspaceOptions {
|
||||
onDocumentsSortFieldChange?: (field: string) => void;
|
||||
onDocumentsSortDirectionToggle?: () => void;
|
||||
searchIncludeDescendants?: boolean;
|
||||
onToggleSearchIncludeDescendants?: () => void;
|
||||
onSetSearchIncludeDescendants?: (value: boolean) => void;
|
||||
sortRefreshReadyRef?: MutableRefObject<boolean>;
|
||||
}
|
||||
@@ -108,14 +107,12 @@ const useDocumentsWorkspace = ({
|
||||
onDocumentsSortFieldChange,
|
||||
onDocumentsSortDirectionToggle,
|
||||
searchIncludeDescendants = true,
|
||||
onToggleSearchIncludeDescendants,
|
||||
onSetSearchIncludeDescendants,
|
||||
sortRefreshReadyRef,
|
||||
}: UseDocumentsWorkspaceOptions = {}) => {
|
||||
const handleDocumentsViewModeChange = onDocumentsViewModeChange || noop;
|
||||
const handleDocumentsSortFieldChange = onDocumentsSortFieldChange || noop;
|
||||
const handleDocumentsSortDirectionToggle = onDocumentsSortDirectionToggle || noop;
|
||||
const toggleSearchIncludeDescendants = onToggleSearchIncludeDescendants || noop;
|
||||
const setSearchIncludeDescendants = onSetSearchIncludeDescendants || noop;
|
||||
|
||||
const fallbackSortFieldRef = useRef(documentsSortField);
|
||||
@@ -348,12 +345,8 @@ const useDocumentsWorkspace = ({
|
||||
setActiveTagFilters,
|
||||
activeCorrespondentFilters,
|
||||
setActiveCorrespondentFilters,
|
||||
toggleTagFilter,
|
||||
toggleCorrespondentFilter,
|
||||
isFilterActive,
|
||||
clearFilters,
|
||||
handleSearchChange,
|
||||
handleSearchSubmit,
|
||||
documentsFilterValue,
|
||||
} = useDocumentsSearch({
|
||||
api,
|
||||
assetManager,
|
||||
@@ -370,6 +363,8 @@ const useDocumentsWorkspace = ({
|
||||
setSearchIncludeDescendants,
|
||||
});
|
||||
|
||||
const documentsFilter = documentsFilterValue;
|
||||
|
||||
useEffect(() => {
|
||||
setSearchResultsRef.current = setSearchResults;
|
||||
}, [setSearchResults]);
|
||||
@@ -1495,7 +1490,6 @@ const useDocumentsWorkspace = ({
|
||||
currentSubfolders,
|
||||
documents,
|
||||
searchResults,
|
||||
isFilterActive,
|
||||
folderClickHandlers,
|
||||
handleFolderDragStart,
|
||||
handleFolderDragEnd,
|
||||
@@ -1511,16 +1505,12 @@ const useDocumentsWorkspace = ({
|
||||
activeCorrespondentFilters,
|
||||
ensureAssetUrl,
|
||||
getDocumentAsset,
|
||||
toggleTagFilter,
|
||||
toggleCorrespondentFilter,
|
||||
handleDocumentTagDrop,
|
||||
documentsViewMode,
|
||||
documentsSortField,
|
||||
documentsSortDirection,
|
||||
handleDocumentsSortFieldChange,
|
||||
handleDocumentsSortDirectionToggle,
|
||||
searchIncludeDescendants,
|
||||
toggleSearchIncludeDescendants,
|
||||
handleDocumentsViewModeChange,
|
||||
clearDocumentSelection,
|
||||
handleDeleteSelection,
|
||||
@@ -1562,21 +1552,12 @@ const useDocumentsWorkspace = ({
|
||||
handlePromptCreateFolder,
|
||||
creatingFolder,
|
||||
tags,
|
||||
activeTagFilters,
|
||||
toggleTagFilter,
|
||||
handleTagCreate,
|
||||
correspondents,
|
||||
activeCorrespondentFilters,
|
||||
toggleCorrespondentFilter,
|
||||
handleCorrespondentCreate,
|
||||
appStatus,
|
||||
loading,
|
||||
previewActive,
|
||||
searchQuery,
|
||||
handleSearchChange,
|
||||
handleSearchSubmit,
|
||||
clearFilters,
|
||||
isFilterActive,
|
||||
handleLogout,
|
||||
status,
|
||||
tenantName,
|
||||
@@ -1639,6 +1620,7 @@ const useDocumentsWorkspace = ({
|
||||
openDetailPanel,
|
||||
uploadQueue,
|
||||
clearUploadQueue,
|
||||
documentsFilter,
|
||||
}),
|
||||
[
|
||||
token,
|
||||
@@ -1690,6 +1672,7 @@ const useDocumentsWorkspace = ({
|
||||
openDetailPanel,
|
||||
uploadQueue,
|
||||
clearUploadQueue,
|
||||
documentsFilter,
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
} from '../ui/icons';
|
||||
import PanelHeader from '../ui/PanelHeader';
|
||||
import useFloatingMenu from '../ui/useFloatingMenu';
|
||||
import { useDocumentsFilter } from '../documents/context/DocumentsFilterContext';
|
||||
|
||||
import { getTagColorStyle } from '../utils/colors';
|
||||
import { useSidebarContext } from './SidebarContext';
|
||||
@@ -126,20 +127,11 @@ interface SidebarProps {
|
||||
creatingFolder?: boolean;
|
||||
tags?: TagEntry[];
|
||||
untaggedFilterId?: Identifier | null;
|
||||
activeTagIds?: Array<Identifier | null>;
|
||||
onToggleTagFilter?: (tagId: Identifier | null) => void;
|
||||
correspondents?: CorrespondentEntry[];
|
||||
activeCorrespondentIds?: Array<Identifier | null>;
|
||||
onToggleCorrespondentFilter?: (correspondentId: Identifier | null) => void;
|
||||
onManageTags?: () => void;
|
||||
onManageCorrespondents?: () => void;
|
||||
onCreateTag?: (label: string) => Promise<void> | void;
|
||||
onCreateCorrespondent?: (name: string) => Promise<void> | void;
|
||||
searchQuery?: string;
|
||||
onSearchChange?: (value: string) => void;
|
||||
onSearchSubmit?: () => void;
|
||||
onSearchClear?: () => void;
|
||||
isFilterActive?: boolean;
|
||||
onLogout?: () => void;
|
||||
status?: StatusMessage | null;
|
||||
tenantName?: string | null;
|
||||
@@ -301,20 +293,11 @@ const Sidebar: React.FC<SidebarProps> = ({
|
||||
creatingFolder = false,
|
||||
tags = [],
|
||||
untaggedFilterId = null,
|
||||
activeTagIds = [],
|
||||
onToggleTagFilter,
|
||||
correspondents = [],
|
||||
activeCorrespondentIds = [],
|
||||
onToggleCorrespondentFilter,
|
||||
onManageTags,
|
||||
onManageCorrespondents,
|
||||
onCreateTag,
|
||||
onCreateCorrespondent,
|
||||
searchQuery = '',
|
||||
onSearchChange,
|
||||
onSearchSubmit,
|
||||
onSearchClear,
|
||||
isFilterActive = false,
|
||||
onLogout,
|
||||
status = null,
|
||||
tenantName,
|
||||
@@ -342,6 +325,17 @@ const Sidebar: React.FC<SidebarProps> = ({
|
||||
sidebarSuppressed,
|
||||
collapseSidebar,
|
||||
} = usePanelManager();
|
||||
const {
|
||||
query: searchQuery,
|
||||
activeTagIds = [],
|
||||
activeCorrespondentIds = [],
|
||||
isActive: isFilterActive,
|
||||
setQuery: setFilterQuery,
|
||||
submit: submitFilter,
|
||||
clear: clearFilterState,
|
||||
toggleTag: toggleTagFilter,
|
||||
toggleCorrespondent: toggleCorrespondentFilter,
|
||||
} = useDocumentsFilter();
|
||||
const uploadInputRef = useRef<HTMLInputElement | null>(null);
|
||||
const sidebarRef = useRef<HTMLDivElement | null>(null);
|
||||
const {
|
||||
@@ -371,9 +365,12 @@ const Sidebar: React.FC<SidebarProps> = ({
|
||||
);
|
||||
const handleToggleTag = useCallback(
|
||||
(tagId: Identifier | null) => {
|
||||
onToggleTagFilter?.(tagId);
|
||||
if (tagId == null) {
|
||||
return;
|
||||
}
|
||||
toggleTagFilter(tagId);
|
||||
},
|
||||
[onToggleTagFilter],
|
||||
[toggleTagFilter],
|
||||
);
|
||||
const activeTagSet = useMemo(
|
||||
() => new Set<Identifier | null>(activeTagIds || []),
|
||||
@@ -623,20 +620,20 @@ const Sidebar: React.FC<SidebarProps> = ({
|
||||
|
||||
const handleSearchInputChange = useCallback(
|
||||
(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
onSearchChange?.(event.target.value);
|
||||
setFilterQuery(event.target.value);
|
||||
},
|
||||
[onSearchChange],
|
||||
[setFilterQuery],
|
||||
);
|
||||
const handleSearchFormSubmit = useCallback(
|
||||
(event: React.FormEvent<HTMLFormElement>) => {
|
||||
event.preventDefault();
|
||||
onSearchSubmit?.();
|
||||
submitFilter();
|
||||
},
|
||||
[onSearchSubmit],
|
||||
[submitFilter],
|
||||
);
|
||||
const handleSearchClear = useCallback(() => {
|
||||
onSearchClear?.();
|
||||
}, [onSearchClear]);
|
||||
clearFilterState();
|
||||
}, [clearFilterState]);
|
||||
const tenantButtonRef = useRef<HTMLButtonElement | null>(null);
|
||||
const {
|
||||
isOpen: tenantMenuOpen,
|
||||
@@ -869,22 +866,20 @@ const Sidebar: React.FC<SidebarProps> = ({
|
||||
<div className={`status-banner ${status.variant}`}>{status.message}</div>
|
||||
</div>
|
||||
)}
|
||||
{onSearchChange && (
|
||||
<form className="sidebar__search" onSubmit={handleSearchFormSubmit}>
|
||||
<input
|
||||
type="search"
|
||||
value={searchQuery}
|
||||
onChange={handleSearchInputChange}
|
||||
placeholder="Search documents"
|
||||
aria-label="Search documents"
|
||||
/>
|
||||
{isFilterActive && (
|
||||
<button type="button" onClick={handleSearchClear}>
|
||||
Clear
|
||||
</button>
|
||||
)}
|
||||
</form>
|
||||
)}
|
||||
<form className="sidebar__search" onSubmit={handleSearchFormSubmit}>
|
||||
<input
|
||||
type="search"
|
||||
value={searchQuery}
|
||||
onChange={handleSearchInputChange}
|
||||
placeholder="Search documents"
|
||||
aria-label="Search documents"
|
||||
/>
|
||||
{isFilterActive && (
|
||||
<button type="button" onClick={handleSearchClear}>
|
||||
Clear
|
||||
</button>
|
||||
)}
|
||||
</form>
|
||||
<div className="sidebar-section sidebar-section--folders">
|
||||
<div className="sidebar-section__header">
|
||||
<h3>Folders</h3>
|
||||
@@ -1011,7 +1006,7 @@ const Sidebar: React.FC<SidebarProps> = ({
|
||||
const className = `sidebar-correspondent-item${isActive ? ' active' : ''}`;
|
||||
const handleSelect = () => {
|
||||
const nextId = isActive ? null : correspondent.id;
|
||||
onToggleCorrespondentFilter?.(nextId);
|
||||
toggleCorrespondentFilter(nextId);
|
||||
};
|
||||
return (
|
||||
<li key={correspondent.id}>
|
||||
|
||||
@@ -80,12 +80,8 @@ interface UseSidebarPropsArgs {
|
||||
handlePromptCreateFolder?: () => void;
|
||||
creatingFolder: boolean;
|
||||
tags: TagOption[];
|
||||
activeTagFilters: Identifier[];
|
||||
toggleTagFilter: (tagId: Identifier) => void;
|
||||
handleTagCreate: (payload: { label?: string }) => void | Promise<void>;
|
||||
correspondents: CorrespondentOption[];
|
||||
activeCorrespondentFilters: Identifier[];
|
||||
toggleCorrespondentFilter: (correspondentId: Identifier) => void;
|
||||
handleCorrespondentCreate: (payload: { name?: string }) =>
|
||||
| Promise<CorrespondentOption | null | void>
|
||||
| CorrespondentOption
|
||||
@@ -94,11 +90,6 @@ interface UseSidebarPropsArgs {
|
||||
appStatus: string;
|
||||
loading: boolean;
|
||||
previewActive: boolean;
|
||||
searchQuery: string;
|
||||
handleSearchChange: (value: string) => void;
|
||||
handleSearchSubmit: () => void;
|
||||
clearFilters: () => void;
|
||||
isFilterActive: boolean;
|
||||
handleLogout: () => void | Promise<void>;
|
||||
status: StatusMessage | null;
|
||||
tenantName: string | null;
|
||||
@@ -127,21 +118,12 @@ interface SidebarHookResult {
|
||||
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;
|
||||
@@ -165,21 +147,12 @@ const useSidebarProps = ({
|
||||
handlePromptCreateFolder,
|
||||
creatingFolder,
|
||||
tags,
|
||||
activeTagFilters,
|
||||
toggleTagFilter,
|
||||
handleTagCreate,
|
||||
correspondents,
|
||||
activeCorrespondentFilters,
|
||||
toggleCorrespondentFilter,
|
||||
handleCorrespondentCreate,
|
||||
appStatus,
|
||||
loading,
|
||||
previewActive,
|
||||
searchQuery,
|
||||
handleSearchChange,
|
||||
handleSearchSubmit,
|
||||
clearFilters,
|
||||
isFilterActive,
|
||||
handleLogout,
|
||||
status,
|
||||
tenantName,
|
||||
@@ -208,21 +181,12 @@ const useSidebarProps = ({
|
||||
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,
|
||||
@@ -249,10 +213,7 @@ const useSidebarProps = ({
|
||||
[
|
||||
handleFileSelection,
|
||||
uploadQueue,
|
||||
activeCorrespondentFilters,
|
||||
activeTagFilters,
|
||||
appStatus,
|
||||
clearFilters,
|
||||
correspondents,
|
||||
creatingFolder,
|
||||
currentTenantId,
|
||||
@@ -265,23 +226,17 @@ const useSidebarProps = ({
|
||||
handleFolderRename,
|
||||
handleLogout,
|
||||
handlePromptCreateFolder,
|
||||
handleSearchChange,
|
||||
handleSearchSubmit,
|
||||
handleTagCreate,
|
||||
handleTenantSelect,
|
||||
isFilterActive,
|
||||
loading,
|
||||
openSettings,
|
||||
previewActive,
|
||||
searchQuery,
|
||||
draggedFolderId,
|
||||
selectedFolder,
|
||||
status,
|
||||
tags,
|
||||
tenantName,
|
||||
tenantOptions,
|
||||
toggleCorrespondentFilter,
|
||||
toggleTagFilter,
|
||||
],
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user