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 by AttachmentDetailsModalDrawer.
  • 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 the AttachmentDetailsModalDrawer.
  • 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 the GalleryFilter component 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 the organizationID.
  • 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 NameTypeDescriptionOptional/Required
issueDataOptionsobjectAn 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 the FilterModal and the expanded state of the FilterBar’s container).
    • filters: (GalleryFilters object) The currently active filters stored in Redux. These are used to initialize the GalleryFilter’s local state and to reflect the global filter state in the UI. The GalleryFilters type includes fields like source, 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 the FilterModal).
  • 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: (DefaultGalleryFilters object) 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 the filters from the Redux store or default values.
    • The date property within selectedFilters is an object: { startDate: Moment | null, endDate: Moment | null }.

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. GalleryFilter configures 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. GalleryFilter also 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:

  1. Initialization: It initializes its internal filter selection state (selectedFilters) based on the current filters from the Redux store. These Redux filters themselves might be initialized from URL query parameters when the gallery first loads.
  2. User Interaction: It renders FilterBar and FilterModal components, providing various input fields (multi-select dropdowns, date pickers) for users to specify their desired filter criteria.
  3. Local State Management: As the user changes filter selections, these changes are stored in the local selectedFilters state.
  4. 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 setGalleryFilters to update the Redux store with the new filter criteria.
    • Dispatches fetchAttachments.request to trigger a data reload based on the new filters.
    • Updates the URL query parameters using useGalleryQueryParams and history.push to reflect the applied filters.
    • Closes the filter UI.
  5. Filter Reset (onResetClick):
    • Dispatches resetGalleryFilters to clear filters in the Redux store.
    • Resets its local selectedFilters state to default values.
    • Updates the URL query parameters to remove filter-specific parameters (while preserving others like search or groupBy).
    • Dispatches fetchAttachments.request to reload data with default filters.
    • Closes the filter UI.
  6. 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 the GalleryFilter component.
  • 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 after setGallerySearchQuery (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 to true when the user starts typing in the search input and false after the debounce period. Used to show a loading/typing indicator in the SearchInputWithRecommendation.
  • searchInput: (String) The current text value within the search input field. It’s synchronized with searchQuery from 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 SearchInputWithRecommendation component for text entry.
  • Debounced Search: User input in the search field is debounced (250ms). After the user stops typing, setGallerySearchQuery and searchAttachments.request are 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 setGalleryGroupBy with 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>).
  • Clear Search: Clearing the search input resets the searchInput and searchQuery. If on the search tab, it navigates back.

3.5.2 Filter Toggle

  • A button with an MdFilterList icon allows users to toggle the visibility of the GalleryFilter component.
  • The button’s appearance (primary/secondary styling) changes to reflect whether the filter panel is currently open (isFilterOpen is true) or closed.
  • It dispatches toggleGalleryFilter(!isFilterOpen).

3.5.3 Select Mode

  • An OutlineButton allows users to toggle “select mode.”
  • The button text changes between “Select” (when isSelectMode is false) and “Cancel” (when isSelectMode is true).
  • It dispatches toggleGallerySelectMode(!isSelectMode).
  • Conditional Disabling: The select mode button is disabled (isSelectModeDisabled) if:
    • isLoading is true.
    • The current groupBy is GalleryGroupByType.YEARS.
    • The activeTab is GalleryTabEnum.SEARCH and the groupBy is not one of the searchGroups (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. GalleryHeader supplies 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 LinkButtonWithIcon and OutlineButton for 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 if activeTab is in the excludedTabs list (LIBRARY, ALBUM, NONRELEVANT).
  • selectedAlbum: (Object | null) If an album’s content is being viewed, this object (specifically selectedAlbum.siteName) is used to display the title in the sub-header.
  • searchQuery: (String) While not directly subscribed via useSelector in the provided snippet for title display, the component does access the current URL’s search query via location.search to clear the Redux searchQuery when 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): The history.goBack() method is called when the “Back” button is clicked, providing standard browser back navigation.
  • useLocation (react-router): The location.search property is used to get the query string from the current URL.
  • query-string library: The parse function from this library is used to extract the search parameter from location.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 activeTab is not one of GalleryTabEnum.LIBRARY, GalleryTabEnum.ALBUM, or GalleryTabEnum.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 search query parameter exists in the URL. If so, it dispatches setGallerySearchQuery('') to clear the search state in Redux.
      • Then, calls history.goBack() to navigate to the previous view.
  • Dynamic Title (renderTitle):
    • Currently, the title is displayed only if state.gallery.selectedAlbum is truthy. In this case, the title will be selectedAlbum.siteName.
    • The implementation is focused, and other potential title contexts (like displaying the current searchQuery text or fixed labels for “Archive” or “Favorites” tabs) are not present in the provided code for renderTitle but might be intended for other views where this subheader appears.

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 Container styled-component for layout and LinkButton for 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, an EmptyPage with a loading type is shown.
  • isLoadingSearch: (Boolean) Specific loading indicator for search operations. If true and activeTab is SEARCH, an EmptyPage with a loading type is shown.
  • attachments: (Array) An array of attachment objects. Used in conjunction with sections to 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 the switch statement 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 the activeTab is SEARCH.

5.4 Key Functionalities

5.4.1 Content Switching Logic (renderContent)

The component implements a specific order of checks to decide what to render:

  1. Loading State:

    • If isLoading is true, it displays <EmptyPage type={EmptyPageType.LOADING} />.
    • If activeTab is GalleryTabEnum.SEARCH and isLoadingSearch is true, it also displays <EmptyPage type={EmptyPageType.LOADING} />.
  2. No Search Results State:

    • If not in a loading state, activeTab is GalleryTabEnum.SEARCH, and there are no search results (i.e., searchData.questionMatchCount, searchData.categoryMatchCount, and searchData.issueMatchCount are all zero), it displays <EmptyPage type={EmptyPageType.NO_RESULT} />.
  3. No Data State (for non-search tabs):

    • If activeTab is not GalleryTabEnum.SEARCH, and there is no data (i.e., attachments array is empty AND sections object has no keys), it displays <EmptyPage type={EmptyPageType.NO_DATA} />.
  4. Tab-Specific Component Rendering: If none of the above conditions are met, it proceeds to a switch statement based on activeTab:

    • GalleryTabEnum.ALBUM: Renders <GalleryAlbumTab />.
    • GalleryTabEnum.NONRELEVANT: Also renders <GalleryAlbumTab />. This suggests GalleryAlbumTab might be versatile, handling different types of “album” or grouped views.
    • GalleryTabEnum.SEARCH: Renders <GallerySearchTab />.
    • GalleryTabEnum.DETAIL, GalleryTabEnum.LIBRARY (and the default case): Renders <GalleryLibraryTab />. This implies DETAIL views are likely part of or handled by the GalleryLibraryTab.

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 useRef named ref is attached to the main Container div. 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-components Container.
  • 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;). The height: 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 activeTab is GalleryTabEnum.DETAIL or GalleryTabEnum.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: The history object 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.

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 current activeTab from Redux is GalleryTabEnum.DETAIL or GalleryTabEnum.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 the OBJECT_DETECTION feature flag) is true.
  • Active Tab Styling: The Tab styled-component receives an isActive boolean prop. This prop is true if the tab’s corresponding GalleryTabEnum value matches the activeTab from 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.push to 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 Container uses flexbox to center the tabs horizontally (justify-content: center) with a gap between them. Padding is added at the top.
  • Individual Tab buttons 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 isActive prop in the Tab styled-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 NameTypeDescription
attachmentsAttachment[]An array of attachment objects that will be treated as album representations.
gridSizenumberControls the size of the grid cells, influencing how many thumbnails appear per row.
isSelectModebooleanIndicates if the gallery is currently in “select mode,” which might affect thumbnail interaction or appearance.
selectedAttachmentsAttachment[]An array of currently selected attachments/albums, used for highlighting or other visual cues in select mode.
totalHeightnumberThe total height of the scrollable area, used by GalleryThumbnailList for virtualization or layout calculations.
onClick(attachment: Attachment) => voidCallback function triggered when an album thumbnail is clicked.
onSelect(attachment: Attachment) => voidCallback 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.
hasMorebooleanIndicates if there are more albums to load.
isLoadingMorebooleanIndicates if more albums are currently being loaded.
noDataMessagestringA message to display if the attachments list is empty.
itemContainerStyleReact.CSSPropertiesWhile it defines its own itemContainerStyle, this could technically be overridden by passed props, though usually not intended.
extraRowHeightnumberWhile 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 that AlbumThumbnailList wraps. AlbumThumbnailList delegates the actual rendering of the virtualized list, grid layout, and scroll handling to GalleryThumbnailList. It passes most of its props directly to GalleryThumbnailList.
    • 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 itemContainerStyle with paddingTop: '1rem', paddingRight: '1rem', and paddingBottom: '1rem', ensuring consistent spacing around each album thumbnail.
  • AttachmentThumbnailCard: For each item in the attachments array, AlbumThumbnailList renders an AttachmentThumbnailCard.
    • Crucially, it passes the prop type="album" to AttachmentThumbnailCard. 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.

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 itemContainerStyle object to add padding around each thumbnail, which is passed to GalleryThumbnailList.
  • The visual appearance of the thumbnails is primarily determined by AttachmentThumbnailCard when its type prop 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 GalleryThumbnailList for displaying album thumbnails.
  • A Props section detailing the AttachmentThumbnailListProps it 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 like extraRowHeight={80} and a custom itemContainerStyle.
    • Details how it uses AttachmentThumbnailCard and crucially passes type="album" to ensure album-specific rendering.
  • Purpose and Usage: Clarifies its role in the gallery’s album view, providing a consistent way to display album collections.
  • Styling: Notes the inline itemContainerStyle and that the primary visual styling comes from AttachmentThumbnailCard in its “album” mode.

This completes the documentation for AlbumThumbnailList.tsx.