1. Component: Gallery
GitHub Link: Gallery.tsx
1.1 Description
The Gallery component serves as the main interface for browsing and managing media attachments within the application. It provides a comprehensive view with features such as different gallery layouts (tabs like Library, Archive), filtering capabilities, grouping of media by various criteria (e.g., date), and options to adjust display preferences like thumbnail size.
The component is responsible for fetching necessary initial data, including site information, user lists, department details, and questionnaire data. It also manages the process of downloading media, complete with progress indicators and error handling.
1.2 Structure
The Gallery component is built upon a LayoutWithHeader, integrating several specialized sub-components to deliver its functionality:
GalleryHeader: Displays the main header for the gallery, potentially including global actions or information.GalleryFilter: Provides UI elements for users to filter the displayed media based on various criteria (e.g., linked [issues](../Issue Tracker/IssueTrackerOverview.md), upload date).GalleryThumbnailSizeSlider: Allows users to dynamically adjust the size of the media thumbnails.GalleryTabs: Manages navigation between different sections or views of the gallery, such as “Library” or “Archive”.GallerySubHeader: Renders a contextual sub-header, possibly displaying current filter summaries or view-specific actions.GalleryTabContent: Dynamically renders the content for the currently selected gallery tab.AttachmentDetailsModalDrawer: A drawer component that slides in to display detailed information and actions for a selected media attachment.
1.3 Props
The Gallery component does not accept any direct props. Its behavior and display are primarily driven by the Redux state and URL query parameters.
1.4 Redux State Interaction
The component is tightly integrated with the Redux store for managing its state and data.
1.4.1 Subscribed State (useSelector)
state.gallery:activeTab: (Enum:GalleryTabEnum) The currently active tab (e.g., Library, Archive).gridSize: (Number) The current size setting for the media thumbnails.groupBy: (Enum:GalleryGroupByType) The current criteria for grouping media in the “Library” tab (e.g., ALL, DAYS, MONTHS, YEARS).isDownloadErrorModalVisible: (Boolean) Controls the [visibility](../Settings/Data Visibility/DataVisibilityOverview.md) of the modal displayed when a download error occurs (e.g., too many files or total size exceeded).isDownloadInitializationModalVisible: (Boolean) Controls the [visibility](../Settings/Data Visibility/DataVisibilityOverview.md) of the modal shown when a download process is being initiated.downloadProgressModalConfig: (Object) Configuration for the download progress modal:isVisible: (Boolean) [Visibility](../Settings/Data Visibility/DataVisibilityOverview.md) of the progress modal.total: (Number) Total number of files to be downloaded.count: (Number) Number of files successfully downloaded so far.
selectedAttachment: (Object | null) The currently selected attachment object, used byAttachmentDetailsModalDrawer.
state.organization:organization?.organizationID: (String) Used to determine organization-specific limits for downloads (number of files and total size).
1.4.2 Dispatched Actions
siteCompactAction.request({ withDepartmentAccess: true }): Fetches compact site information, including department access details. Typically dispatched on component mount.fetchUsers.request(): Fetches the list of users. Typically dispatched on component mount.fetchDepartments.request(): Fetches the list of departments. Typically dispatched on component mount.getQuestionnairesByPropsAsync.request(): Fetches questionnaire data. Typically dispatched on component mount.setSelectedGalleryAttachment(attachment | null): Sets or clears the currently selected attachment, primarily to control theAttachmentDetailsModalDrawer.toggleGalleryDownloadErrorModal(boolean): Shows or hides the modal that informs the user about download limitations or errors.
1.5 Interactions with Other Components
LayoutWithHeader: Provides the overall page structure, including a title bar and content area.FloatingMenuGroup: A reusable UI component used to display the “Group By” options (All Media,Days,Months,Years) as a floating menu when the “Library” tab is active.ConfirmModal: A generic modal component used to display the download error message, requiring user confirmation.ProgressModal: A generic modal component used to show the progress of ongoing downloads.DownloadInitializationModal: A specific modal displayed during the initial phase of a download process.
1.6 Custom Hooks Utilized
useTranslation: For internationalization (i18n), providing translated strings for UI elements.useIssueDataOptions: Provides data options that are likely used by theGalleryFiltercomponent for filtering based on issue-related criteria.useGalleryTab: Encapsulates logic related to managing the active gallery tab and navigation between tabs. It likely interacts with URL query parameters.useGalleryQueryParams: Manages reading and updating URL query parameters specific to the gallery, allowing gallery state to be reflected in and controlled by the URL.
1.7 Key Functionalities
- Media Display: Renders media items in a grid, with adjustable thumbnail sizes.
- Tabbed Navigation: Allows users to switch between different views (e.g., main library, archives) using
GalleryTabs. - Filtering: Enables users to refine the displayed media using
GalleryFilter. - Grouping: In the “Library” tab, media can be grouped by different timeframes (All, Days, Months, Years) using a
FloatingMenuGroup. - Attachment Details: Users can select an attachment to view more details in the
AttachmentDetailsModalDrawer. - Download Management:
- Initiates downloads of selected media.
- Displays an initialization modal (
DownloadInitializationModal). - Shows download progress (
ProgressModal). - Handles download errors (e.g., exceeding file count or size limits) by displaying a
ConfirmModal. Download limits (fileLimit,sizeLimit) are dynamically determined based on theorganizationID.
- Initial Data Fetching: On mount, dispatches actions to fetch essential data like sites, users, departments, and questionnaires.
1.8 Styling
The component uses styled-components for styling, as indicated by the styled.div definition for HeaderTitle. The HeaderTitle styled component arranges an icon and text to form the main title of the gallery page.
2. Component: GalleryFilter
GitHub Link: GalleryFilter.tsx
2.1 Description
The GalleryFilter component is responsible for providing the user interface and logic to filter media attachments within the gallery. It integrates with global FilterBar and FilterModal components to offer a responsive filtering experience. Users can filter attachments based on criteria such as source ([Issue Trackers](../Issue Tracker/IssueTrackerOverview.md), Reports), attachment type (Photo, Video), site, department, auditor, associated questionnaire, and date range.
The component manages the local state of selected filters and, upon application, updates the global Redux state and URL query parameters, triggering a refresh of the gallery content.
2.2 Props
| Prop Name | Type | Description | Optional/Required |
|---|---|---|---|
issueDataOptions | object | An object containing pre-fetched and pre-mapped data necessary for populating filter dropdowns. This includes maps and options lists for sites, departments, users (auditors), and questionnaires. | Required |
The issueDataOptions object is expected to have the following structure:
{
questionnaireMap: Map<string, any>,
questionnaireOptions: Array<{ label: string, value: string }>,
userMap: Map<string, any>, // Used for auditors
// userOptions might also be part of this for consistency, though only userMap is directly used in filterOptions
departmentMap: Map<string, any>,
departmentOptions: Array<{ label: string, value: string }>,
siteMap: Map<string, any>,
siteOptions: Array<{ label: string, value: string }>
}2.3 Redux State Interaction
2.3.1 Subscribed State (useSelector)
state.gallery:isLoading: (Boolean) Indicates if gallery data is being fetched. Used to disable filter interactions during loading.isFilterOpen: (Boolean) Controls the visibility of the filter interface (primarily theFilterModaland the expanded state of theFilterBar’s container).filters: (GalleryFiltersobject) The currently active filters stored in Redux. These are used to initialize theGalleryFilter’s local state and to reflect the global filter state in the UI. TheGalleryFilterstype includes fields likesource,type,qnrs,auditors,siteID,deptIDs,startDate,endDate.
2.3.2 Dispatched Actions
toggleGalleryFilter(false): Dispatched to close the filter UI (e.g., when the user applies filters or clicks a close button in theFilterModal).resetGalleryFilters(): Dispatched when the user clicks the “Reset” button. This action resets the filter criteria in the Redux store to their default values.setGalleryFilters(updatedSelectedFilters): Dispatched when the user clicks the “Apply” button. This action updates the Redux store with the new filter criteria selected by the user.fetchAttachments.request({}): Dispatched after filters are applied or reset to fetch the gallery attachments that match the new filter criteria.
2.4 Local State (useState)
selectedFilters: (DefaultGalleryFiltersobject) Holds the filter values that the user is currently selecting or modifying in the UI before they are officially applied. This local state allows users to configure multiple filter options and then apply them in a single action. It is initialized based on thefiltersfrom the Redux store or default values.- The
dateproperty withinselectedFiltersis an object:{ startDate: Moment | null, endDate: Moment | null }.
- The
2.5 Interactions with Other Components and Hooks
FilterBar: A reusable global component that displays filter options in a horizontal bar, typically for wider screens.GalleryFilterconfigures and provides data to this component.FilterModal: A reusable global component that displays filter options within a modal dialog, suitable for mobile views or when triggered by a toggle.GalleryFilteralso configures and provides data to this component.useTranslation(react-i18next): Used for internationalization, providing translated text for labels and placeholders.toast(react-toastify): Used to display notifications, such as an error message if a user selects a start date without an end date in the date range filter.useHistory,useLocation(react-router): Standard React Router hooks used to interact with the browser’s navigation history and current URL.useGalleryQueryParams: A custom hook specific to the gallery feature. It is used to:- Read existing query parameters from the URL.
- Generate query strings based on selected filters.
- Update the URL when filters are applied or reset, ensuring the URL reflects the current filtered state of the gallery.
2.6 Role in Filtering
The GalleryFilter component plays a crucial role in enabling users to refine the set of media attachments displayed in the gallery:
- Initialization: It initializes its internal filter selection state (
selectedFilters) based on the currentfiltersfrom the Redux store. These Redux filters themselves might be initialized from URL query parameters when the gallery first loads. - User Interaction: It renders
FilterBarandFilterModalcomponents, providing various input fields (multi-select dropdowns, date pickers) for users to specify their desired filter criteria. - Local State Management: As the user changes filter selections, these changes are stored in the local
selectedFiltersstate. - Filter Application (
onApplyClick):- Validates the selected filters (e.g., checks for a complete date range).
- Formats the selected filter values (e.g., date formatting).
- Dispatches
setGalleryFiltersto update the Redux store with the new filter criteria. - Dispatches
fetchAttachments.requestto trigger a data reload based on the new filters. - Updates the URL query parameters using
useGalleryQueryParamsandhistory.pushto reflect the applied filters. - Closes the filter UI.
- Filter Reset (
onResetClick):- Dispatches
resetGalleryFiltersto clear filters in the Redux store. - Resets its local
selectedFiltersstate to default values. - Updates the URL query parameters to remove filter-specific parameters (while preserving others like
searchorgroupBy). - Dispatches
fetchAttachments.requestto reload data with default filters. - Closes the filter UI.
- Dispatches
- Synchronization with URL: By using
useGalleryQueryParams, it ensures that the applied filters are persisted in the URL, allowing for shareable links that maintain the gallery’s filtered view.
2.7 Filter Configuration
The component defines filterConfigs (for FilterBar) and filterModalConfigs (for FilterModal) which specify the properties of each filter field, such as its name, label, type (e.g., MULTI_SELECT, DATE_RANGE_PRESET), and placeholder text. It also prepares filterOptions (the choices available in dropdowns) and filterValues (the currently selected choices) to be passed to these filter UI components.
2.8 Styling
The component uses styled-components to define a Container styled-component. This container wraps the FilterBar and uses its isOpen prop (derived from Redux state isFilterOpen) to control the visibility and a slide-in/slide-out transition effect for the filter bar area.
3. Component: GalleryHeader
GitHub Link: GalleryHeader.tsx
3.1 Description
The GalleryHeader component is positioned at the top of the gallery interface and provides primary user interactions for searching, filtering, and managing selection mode for gallery attachments. It integrates a sophisticated search input with recommendations and dynamically updates controls based on the current gallery state and user actions.
3.2 Props
The GalleryHeader component does not accept any direct props. Its behavior is managed internally through local state and interactions with the Redux store.
3.3 Redux State Interaction
3.3.1 Subscribed State (useSelector from state.gallery)
isLoading: (Boolean) General loading state for the gallery. Controls are often disabled when true.isLoadingSearch: (Boolean) Specific loading state for search operations. Used to show a loading indicator in the search input.isFilterOpen: (Boolean) Determines the visual state (active/inactive) of the filter toggle button.isSelectMode: (Boolean) Determines the label (“Select” or “Cancel”) of the select mode button and its behavior.activeTab: (GalleryTabEnum) The currently active gallery tab. Used to determine if select mode should be disabled.groupBy: (GalleryGroupByType) The current grouping applied to gallery items. Used to determine if select mode should be disabled and to provide context for search recommendations.searchData: (Object) Contains counts for different categories of search matches, used to populate recommendations. Expected structure:{ questionMatchCount: number, categoryMatchCount: number, issueMatchCount: number }.searchQuery: (String) The current search query string from the Redux store. Used to initialize and synchronize the local search input field.
3.3.2 Dispatched Actions
toggleGalleryFilter(boolean): Dispatched when the filter button is clicked to show or hide theGalleryFiltercomponent.toggleGallerySelectMode(boolean): Dispatched when the select mode button is clicked to enable or disable the gallery’s item selection mode.setGallerySearchQuery(string): Dispatched (debounced) as the user types in the search input, and also when the search is cleared. Updates the search query in the Redux store.searchAttachments.request(): Dispatched aftersetGallerySearchQuery(debounced) to initiate the actual search for attachments based on the current query.setGalleryGroupBy(GalleryGroupByType): Dispatched when a user selects a specific search recommendation (e.g., group by “Questions”). This action sets the grouping criteria for the subsequent search.
3.4 Local State (useState)
isTyping: (Boolean) Set totruewhen the user starts typing in the search input andfalseafter the debounce period. Used to show a loading/typing indicator in theSearchInputWithRecommendation.searchInput: (String) The current text value within the search input field. It’s synchronized withsearchQueryfrom Redux and updated on user input.isRecommendationsVisible: (Boolean) Controls the visibility of the search recommendations dropdown beneath the search input.
3.5 Key Functionalities
3.5.1 Search Operations
- Search Input: Utilizes the
SearchInputWithRecommendationcomponent for text entry. - Debounced Search: User input in the search field is debounced (250ms). After the user stops typing,
setGallerySearchQueryandsearchAttachments.requestare dispatched. - Search Recommendations: As the user types, recommendations are shown based on
searchData(counts of matches in Questions, Categories, Issues).- Selecting a recommendation (e.g., “Questions”) dispatches
setGalleryGroupBywith the chosen type and navigates to the search results page (/gallery/search?search=<query>&groupBy=<type>). - Selecting “See all results” or pressing Enter in the search input navigates to (
/gallery/search?search=<query>).
- Selecting a recommendation (e.g., “Questions”) dispatches
- Clear Search: Clearing the search input resets the
searchInputandsearchQuery. If on the search tab, it navigates back.
3.5.2 Filter Toggle
- A button with an
MdFilterListicon allows users to toggle the visibility of theGalleryFiltercomponent. - The button’s appearance (primary/secondary styling) changes to reflect whether the filter panel is currently open (
isFilterOpenis true) or closed. - It dispatches
toggleGalleryFilter(!isFilterOpen).
3.5.3 Select Mode
- An
OutlineButtonallows users to toggle “select mode.” - The button text changes between “Select” (when
isSelectModeis false) and “Cancel” (whenisSelectModeis true). - It dispatches
toggleGallerySelectMode(!isSelectMode). - Conditional Disabling: The select mode button is disabled (
isSelectModeDisabled) if:isLoadingis true.- The current
groupByisGalleryGroupByType.YEARS. - The
activeTabisGalleryTabEnum.SEARCHand thegroupByis not one of thesearchGroups(predefined valid groupings for search results).
3.6 Interactions with Other Components and Hooks
SearchInputWithRecommendation: A global component providing the search input field and recommendation dropdown logic.GalleryHeadersupplies props for its value, placeholder, loading state, recommendations, and callback handlers.useTranslation(react-i18next): For internationalizing button labels and placeholder text.useHistory(react-router): Used for navigating to search result URLs and handling back navigation on search clear.- Styled Components: Uses
LinkButtonWithIconandOutlineButtonfor styling the action buttons.
3.7 Styling and Layout
The component arranges the search input, filter button, and select mode button horizontally using flexbox (aa-flex aa-gap-3 aa-align-center).
4. Component: GallerySubHeader
GitHub Link: GallerySubHeader.tsx
4.1 Description
The GallerySubHeader component renders a contextual sub-header located below the main gallery header. Its primary purpose is to provide a “Back” button for navigation and display a title that gives context to the current view, such as an album name (specifically, selectedAlbum.siteName) or the nature of a filtered/special view.
It is conditionally rendered and will not appear on certain primary gallery tabs like “Library”, “Album” (the main album listing), or “Non-Relevant”.
4.2 Props
The GallerySubHeader component does not accept any direct props.
4.3 Redux State Interaction
4.3.1 Subscribed State (useSelector from state.gallery)
isLoading: (Boolean) Used to disable the “Back” button when data is loading to prevent navigation issues.activeTab: (GalleryTabEnum) The currently active gallery tab. This is crucial for the conditional rendering logic; the sub-header is hidden ifactiveTabis in theexcludedTabslist (LIBRARY,ALBUM,NONRELEVANT).selectedAlbum: (Object | null) If an album’s content is being viewed, this object (specificallyselectedAlbum.siteName) is used to display the title in the sub-header.searchQuery: (String) While not directly subscribed viauseSelectorin the provided snippet for title display, the component does access the current URL’s search query vialocation.searchto clear the ReduxsearchQuerywhen navigating back from a search results view.
4.3.2 Dispatched Actions
setGallerySearchQuery(''): Dispatched when the “Back” button (handleGoBack) is clicked only if a search query (search) is present in the current URL’s query string. This clears the search term in the Redux store, effectively resetting the search state upon navigating away from search results.
4.4 Routing and Navigation
useHistory(react-router): Thehistory.goBack()method is called when the “Back” button is clicked, providing standard browser back navigation.useLocation(react-router): Thelocation.searchproperty is used to get the query string from the current URL.query-stringlibrary: Theparsefunction from this library is used to extract thesearchparameter fromlocation.search. This helps determine if the back action is from a search context.
4.5 Key Functionalities
- Conditional Rendering: The component is only rendered if the
activeTabis not one ofGalleryTabEnum.LIBRARY,GalleryTabEnum.ALBUM, orGalleryTabEnum.NONRELEVANT. This targets its appearance to specific views like search results, contents of an album, favorites, etc. - Back Button:
- Displays a “Back” button with a left chevron icon (
MdChevronLeft). - On click, it calls
handleGoBack. handleGoBack:- Checks if a
searchquery parameter exists in the URL. If so, it dispatchessetGallerySearchQuery('')to clear the search state in Redux. - Then, calls
history.goBack()to navigate to the previous view.
- Checks if a
- Displays a “Back” button with a left chevron icon (
- Dynamic Title (
renderTitle):- Currently, the title is displayed only if
state.gallery.selectedAlbumis truthy. In this case, the title will beselectedAlbum.siteName. - The implementation is focused, and other potential title contexts (like displaying the current
searchQuerytext or fixed labels for “Archive” or “Favorites” tabs) are not present in the provided code forrenderTitlebut might be intended for other views where this subheader appears.
- Currently, the title is displayed only if
4.6 Interactions with Other Components and Hooks
useTranslation(react-i18next): Used for internationalizing the “Back” button text.MdChevronLeft(react-icons/md): Provides the icon for the “Back” button.- Styled Components: Uses a
Containerstyled-component for layout andLinkButtonfor the back button’s styling.
4.7 Styling and Layout
The Container styles the sub-header as a flexbox, aligning items centrally. The title (.title) is styled to be prominent (larger font size, bold) and centered, taking up available space while accounting for the back button’s width.
5. Component: GalleryTabContent
GitHub Link: GalleryTabContent.tsx
5.1 Description
The GalleryTabContent component acts as a dynamic container responsible for rendering the main content area of the gallery based on the currently active tab. It uses Redux state to determine whether to display a loading indicator, an empty state message (for no data or no search results), or the specific component associated with the active gallery tab (e.g., GalleryLibraryTab, GalleryAlbumTab, GallerySearchTab).
5.2 Props
The GalleryTabContent component does not accept any direct props.
5.3 Redux State Interaction
5.3.1 Subscribed State (useSelector from state.gallery)
isLoading: (Boolean) Global loading indicator for the gallery. If true, anEmptyPagewith a loading type is shown.isLoadingSearch: (Boolean) Specific loading indicator for search operations. If true andactiveTabisSEARCH, anEmptyPagewith a loading type is shown.attachments: (Array) An array of attachment objects. Used in conjunction withsectionsto determine if there is data to display for non-search tabs.sections: (Object) An object where keys might represent group names (e.g., dates, album names) and values are arrays of attachments. Used to determine if data exists for non-search tabs.activeTab: (GalleryTabEnum) The currently selected gallery tab. This is the primary value used in theswitchstatement to decide which tab-specific component to render.searchData: (Object) Contains counts of matches from a search operation (e.g.,questionMatchCount,categoryMatchCount,issueMatchCount). Used to determine if search results exist when theactiveTabisSEARCH.
5.4 Key Functionalities
5.4.1 Content Switching Logic (renderContent)
The component implements a specific order of checks to decide what to render:
-
Loading State:
- If
isLoadingis true, it displays<EmptyPage type={EmptyPageType.LOADING} />. - If
activeTabisGalleryTabEnum.SEARCHandisLoadingSearchis true, it also displays<EmptyPage type={EmptyPageType.LOADING} />.
- If
-
No Search Results State:
- If not in a loading state,
activeTabisGalleryTabEnum.SEARCH, and there are no search results (i.e.,searchData.questionMatchCount,searchData.categoryMatchCount, andsearchData.issueMatchCountare all zero), it displays<EmptyPage type={EmptyPageType.NO_RESULT} />.
- If not in a loading state,
-
No Data State (for non-search tabs):
- If
activeTabis notGalleryTabEnum.SEARCH, and there is no data (i.e.,attachmentsarray is empty ANDsectionsobject has no keys), it displays<EmptyPage type={EmptyPageType.NO_DATA} />.
- If
-
Tab-Specific Component Rendering: If none of the above conditions are met, it proceeds to a
switchstatement based onactiveTab:GalleryTabEnum.ALBUM: Renders<GalleryAlbumTab />.GalleryTabEnum.NONRELEVANT: Also renders<GalleryAlbumTab />. This suggestsGalleryAlbumTabmight be versatile, handling different types of “album” or grouped views.GalleryTabEnum.SEARCH: Renders<GallerySearchTab />.GalleryTabEnum.DETAIL,GalleryTabEnum.LIBRARY(and thedefaultcase): Renders<GalleryLibraryTab />. This impliesDETAILviews are likely part of or handled by theGalleryLibraryTab.
5.4.2 Child Components
EmptyPage: A reusable component that displays different messages to the user, such as “Loading…”, “No Results Found”, or “No Data Available”.GalleryAlbumTab: Component responsible for rendering the content when viewing an album or a similar collection (like non-relevant media).GalleryLibraryTab: Component responsible for rendering the main library view of attachments, likely with grouping and other library-specific features.GallerySearchTab: Component responsible for displaying search results.
5.5 Ref Usage
- A
useRefnamedrefis attached to the mainContainerdiv. While its direct usage is not shown in the snippet, it could be utilized for purposes like managing scroll position, focus, or interactions from parent components.
5.6 Styling
- The component uses a
styled-componentsContainer. - This container is styled to be a flex column (
display: flex; flex-direction: column;), take up available vertical space (flex: 1;), and allow its content to scroll if it overflows (overflow: auto;). Theheight: 0;is often used in flex children to ensure proper flex sizing and prevent overflow issues with scrollable content.
6. Component: GalleryTabs
GitHub Link: GalleryTabs.tsx
6.1 Description
The GalleryTabs component is responsible for rendering the primary navigation tabs within the gallery interface. It typically displays “Library” and “Album” tabs, and conditionally shows a “Non relevant” tab based on feature flag settings. This component handles user interaction by navigating to the appropriate URL when a tab is clicked. It also dynamically adjusts its visibility based on the current gallery view (e.g., it’s hidden when viewing attachment details or search results).
6.2 Props
The GalleryTabs component does not accept any direct props.
6.3 Redux State Interaction
6.3.1 Subscribed State (useSelector)
state.gallery.activeTab: (GalleryTabEnum) Used to:- Determine which tab should be visually styled as “active”.
- Conditionally render the entire tab set. The tabs are hidden if
activeTabisGalleryTabEnum.DETAILorGalleryTabEnum.SEARCH.
state.featureAccess.features.OBJECT_DETECTION: (Boolean, cast to boolean via!!) This flag (objectDetectionFeatureAccess) controls the visibility of the “Non relevant” tab. If true, the tab is rendered; otherwise, it’s hidden.
6.4 Routing and Navigation (react-router)
useHistory: Thehistoryobject from React Router is used to programmatically navigate when a tab is clicked.- Library Tab Click (
handleClickLibrary): Navigates to/gallery. - Album Tab Click (
handleClickAlbum): Navigates to/gallery/album. - Non-Relevant Tab Click (
handleClickNonRelevant): Navigates to/gallery/nonrelevant?isFailedAttachment=true, including a query parameter to indicate the context.
- Library Tab Click (
6.5 Key Functionalities
- Tab Rendering: Displays tabs for “Library”, “Album”, and conditionally “Non relevant”. Each tab includes an icon and a text label.
- Conditional Visibility (Entire Component): The entire tab bar is hidden (returns
null) if the currentactiveTabfrom Redux isGalleryTabEnum.DETAILorGalleryTabEnum.SEARCH. This ensures that main navigation tabs are not shown in contexts where they are not applicable. - Conditional Visibility (“Non relevant” Tab): The “Non relevant” tab is only rendered if the
objectDetectionFeatureAccess(derived from theOBJECT_DETECTIONfeature flag) is true. - Active Tab Styling: The
Tabstyled-component receives anisActiveboolean prop. This prop is true if the tab’s correspondingGalleryTabEnumvalue matches theactiveTabfrom Redux. The styling (border-bottom color and text color) changes to visually indicate the active tab. - Navigation: Clicking on a tab triggers a route change via
history.pushto the relevant section of the gallery.
6.6 Interactions with Other Components and Hooks
useTranslation(react-i18next): Used to translate the labels for the “Library” and “Album” tabs. The “Non relevant” tab label is currently hardcoded.- Icons (
react-icons):MdOutlinePhotoLibrary: Used for the “Library” and “Album” tabs.LuImageOff: Used for the “Non relevant” tab.
- Styled Components:
Container: A flex container that centers the tabs and adds spacing.Tab: A styled button component that handles the visual appearance of individual tabs, including their active state.
6.7 Styling and Layout
- The
Containeruses flexbox to center the tabs horizontally (justify-content: center) with a gap between them. Padding is added at the top. - Individual
Tabbuttons also use flexbox to align their icon and text (align-items: center) with a gap. - The active state of a tab is primarily indicated by a solid border at the bottom and a different text color, controlled via the
isActiveprop in theTabstyled-component.
7. Component: AlbumThumbnailList
GitHub Link: AlbumThumbnailList.tsx
7.1 Description
The AlbumThumbnailList component is a specialized wrapper around the more generic GalleryThumbnailList. Its primary function is to render a list of thumbnails specifically configured to represent albums within the gallery. It achieves this by customizing the appearance and behavior of the items through props passed to GalleryThumbnailList and by ensuring each item is rendered as an AttachmentThumbnailCard with type="album".
7.2 Props
AlbumThumbnailList accepts AttachmentThumbnailListProps, which are the props expected by the underlying GalleryThumbnailList component. These props are directly passed through. Key props inherited and utilized include:
| Prop Name | Type | Description |
|---|---|---|
attachments | Attachment[] | An array of attachment objects that will be treated as album representations. |
gridSize | number | Controls the size of the grid cells, influencing how many thumbnails appear per row. |
isSelectMode | boolean | Indicates if the gallery is currently in “select mode,” which might affect thumbnail interaction or appearance. |
selectedAttachments | Attachment[] | An array of currently selected attachments/albums, used for highlighting or other visual cues in select mode. |
totalHeight | number | The total height of the scrollable area, used by GalleryThumbnailList for virtualization or layout calculations. |
onClick | (attachment: Attachment) => void | Callback function triggered when an album thumbnail is clicked. |
onSelect | (attachment: Attachment) => void | Callback function triggered when an album thumbnail is selected (typically in select mode). |
onLoadMore | (startIndex: number, stopIndex: number) => Promise<void> | Callback for implementing infinite scrolling or lazy loading of more albums. |
hasMore | boolean | Indicates if there are more albums to load. |
isLoadingMore | boolean | Indicates if more albums are currently being loaded. |
noDataMessage | string | A message to display if the attachments list is empty. |
itemContainerStyle | React.CSSProperties | While it defines its own itemContainerStyle, this could technically be overridden by passed props, though usually not intended. |
extraRowHeight | number | While it sets its own extraRowHeight, this could also be overridden. |
(Note: AttachmentThumbnailListProps likely includes other props from react-window or similar list virtualization libraries used by GalleryThumbnailList.)
7.3 Interactions with Other Components
GalleryThumbnailList: This is the core component thatAlbumThumbnailListwraps.AlbumThumbnailListdelegates the actual rendering of the virtualized list, grid layout, and scroll handling toGalleryThumbnailList. It passes most of its props directly toGalleryThumbnailList.- It specifically sets
extraRowHeight={80}. This suggests that album thumbnails might require more vertical space per item than standard media thumbnails, perhaps for displaying album titles or counts. - It provides a custom
itemContainerStylewithpaddingTop: '1rem',paddingRight: '1rem', andpaddingBottom: '1rem', ensuring consistent spacing around each album thumbnail.
- It specifically sets
AttachmentThumbnailCard: For each item in theattachmentsarray,AlbumThumbnailListrenders anAttachmentThumbnailCard.- Crucially, it passes the prop
type="album"toAttachmentThumbnailCard. This instructs the card component to render in its “album” visual variant, which typically includes displaying the album’s name and potentially other album-specific details or actions, differentiating it from a standard media thumbnail.
- Crucially, it passes the prop
7.4 Purpose and Usage
AlbumThumbnailList is used within the gallery’s album view (e.g., when GalleryTabEnum.ALBUM is active and being rendered by GalleryAlbumTab). Its main purpose is to provide a consistent and specialized way to display a collection of albums as thumbnails. By abstracting the common configuration for album display (like extraRowHeight and forcing type="album" on the cards), it simplifies the implementation of album views and ensures a uniform look and feel for album representations throughout the gallery.
7.5 Styling
- The component itself doesn’t introduce new styled-components.
- It defines an inline
itemContainerStyleobject to add padding around each thumbnail, which is passed toGalleryThumbnailList. - The visual appearance of the thumbnails is primarily determined by
AttachmentThumbnailCardwhen itstypeprop is set to"album".
The documentation for AlbumThumbnailList.tsx has been created and appended to gallery.md.I have analyzed src/components/gallery/component/AlbumThumbnailList.tsx and appended its documentation to gallery.md.
The documentation for AlbumThumbnailList.tsx includes:
- A GitHub link.
- A Description explaining it’s a specialized wrapper around
GalleryThumbnailListfor displaying album thumbnails. - A Props section detailing the
AttachmentThumbnailListPropsit accepts and passes through, highlighting key inherited props relevant to list display and interaction. - Interactions with Other Components:
- Explains its relationship with
GalleryThumbnailList, noting the pass-through of props and specific overrides likeextraRowHeight={80}and a customitemContainerStyle. - Details how it uses
AttachmentThumbnailCardand crucially passestype="album"to ensure album-specific rendering.
- Explains its relationship with
- Purpose and Usage: Clarifies its role in the gallery’s album view, providing a consistent way to display album collections.
- Styling: Notes the inline
itemContainerStyleand that the primary visual styling comes fromAttachmentThumbnailCardin its “album” mode.
This completes the documentation for AlbumThumbnailList.tsx.