From 43464cab2720cdc5aa00749dd6a3035eb04d597f Mon Sep 17 00:00:00 2001 From: GuillaumeMgz Date: Thu, 19 Sep 2024 14:32:39 +0200 Subject: [PATCH] (PC-31918)[PRO] feat: Manage collective table pagination and sort from the screen. --- .../CollectiveOffersTable.module.scss | 6 +- .../CollectiveOffersTable.tsx | 121 +++--------------- .../CollectiveOffersTableHead.tsx | 3 +- .../CollectiveOffersScreen.module.scss | 4 + .../CollectiveOffersScreen.tsx | 52 +++++++- ...TemplateCollectiveOffersScreen.module.scss | 4 + .../TemplateCollectiveOffersScreen.tsx | 49 ++++++- 7 files changed, 126 insertions(+), 113 deletions(-) diff --git a/pro/src/pages/Offers/OffersTable/CollectiveOffersTable/CollectiveOffersTable.module.scss b/pro/src/pages/Offers/OffersTable/CollectiveOffersTable/CollectiveOffersTable.module.scss index f9718d25cd9..e27b0af439b 100644 --- a/pro/src/pages/Offers/OffersTable/CollectiveOffersTable/CollectiveOffersTable.module.scss +++ b/pro/src/pages/Offers/OffersTable/CollectiveOffersTable/CollectiveOffersTable.module.scss @@ -2,17 +2,13 @@ @use "styles/mixins/_fonts.scss" as fonts; @use "styles/variables/_size.scss" as size; -.offers-pagination { - margin-top: rem.torem(32px); -} - .select-all-container { display: flex; align-items: center; position: relative; margin-bottom: rem.torem(20px); - label { + &-label { @include fonts.caption; } } diff --git a/pro/src/pages/Offers/OffersTable/CollectiveOffersTable/CollectiveOffersTable.tsx b/pro/src/pages/Offers/OffersTable/CollectiveOffersTable/CollectiveOffersTable.tsx index 111f438479a..a2be11166ee 100644 --- a/pro/src/pages/Offers/OffersTable/CollectiveOffersTable/CollectiveOffersTable.tsx +++ b/pro/src/pages/Offers/OffersTable/CollectiveOffersTable/CollectiveOffersTable.tsx @@ -2,13 +2,12 @@ import { CollectiveOfferResponseModel } from 'apiClient/v1' import { MAX_OFFERS_TO_DISPLAY } from 'core/Offers/constants' import { CollectiveSearchFiltersParams } from 'core/Offers/types' import { hasCollectiveSearchFilters } from 'core/Offers/utils/hasSearchFilters' -import { SortingMode, useColumnSorting } from 'hooks/useColumnSorting' -import { usePagination } from 'hooks/usePagination' +import { SortingMode } from 'hooks/useColumnSorting' import { getOffersCountToDisplay } from 'pages/Offers/domain/getOffersCountToDisplay' +import { CollectiveOffersSortingColumn } from 'screens/CollectiveOffersScreen/CollectiveOffersScreen' import { NoResults } from 'screens/IndividualOffersScreen/NoResults/NoResults' import { Banner } from 'ui-kit/Banners/Banner/Banner' import { BaseCheckbox } from 'ui-kit/form/shared/BaseCheckbox/BaseCheckbox' -import { Pagination } from 'ui-kit/Pagination/Pagination' import { Spinner } from 'ui-kit/Spinner/Spinner' import styles from './CollectiveOffersTable.module.scss' @@ -16,14 +15,9 @@ import { CollectiveOffersTableBody } from './CollectiveOffersTableBody/Collectiv import { CollectiveOffersTableHead } from './CollectiveOffersTableHead/CollectiveOffersTableHead' type CollectiveOffersTableProps = { - applyUrlFiltersAndRedirect: ( - filters: CollectiveSearchFiltersParams, - isRefreshing: boolean - ) => void areAllOffersSelected: boolean hasOffers: boolean isLoading: boolean - pageCount: number resetFilters: () => void setSelectedOffer: (offer: CollectiveOfferResponseModel) => void toggleSelectAllCheckboxes: () => void @@ -32,88 +26,31 @@ type CollectiveOffersTableProps = { isRestrictedAsAdmin?: boolean selectedOffers: CollectiveOfferResponseModel[] offers: CollectiveOfferResponseModel[] + onColumnHeaderClick: ( + headersName: CollectiveOffersSortingColumn + ) => SortingMode + currentSortingColumn: CollectiveOffersSortingColumn | null + currentSortingMode: SortingMode + currentPageItems: CollectiveOfferResponseModel[] } -export enum CollectiveOffersSortingColumn { - EVENT_DATE = 'EVENT_DATE', -} - -const sortByEventDate = ( - offerA: CollectiveOfferResponseModel, - offerB: CollectiveOfferResponseModel -) => { - const bookingDateOne = offerA.dates - ? new Date(offerA.dates.start) - : new Date() - const bookingDateTwo = offerB.dates - ? new Date(offerB.dates.start) - : new Date() - if (bookingDateOne > bookingDateTwo) { - return 1 - } else if (bookingDateOne < bookingDateTwo) { - return -1 - } - return 0 -} - -const sortOffers = ( - offers: CollectiveOfferResponseModel[] | undefined, - currentSortingColumn: CollectiveOffersSortingColumn | null, - sortingMode: SortingMode -) => { - if (!offers) { - return [] - } - - if (sortingMode === SortingMode.NONE) { - return offers - } - - const sortedOffers = offers.slice() - - switch (currentSortingColumn) { - case CollectiveOffersSortingColumn.EVENT_DATE: - return sortedOffers.sort( - (a, b) => - sortByEventDate(a, b) * (sortingMode === SortingMode.ASC ? 1 : -1) - ) - default: - return sortedOffers - } -} - -const OFFERS_PER_PAGE = 10 - export const CollectiveOffersTable = ({ areAllOffersSelected, hasOffers, isLoading, - pageCount, resetFilters, selectedOffers, - applyUrlFiltersAndRedirect, setSelectedOffer, toggleSelectAllCheckboxes, urlSearchFilters, isAtLeastOneOfferChecked, isRestrictedAsAdmin = false, offers, + onColumnHeaderClick, + currentSortingColumn, + currentSortingMode, + currentPageItems, }: CollectiveOffersTableProps) => { - const { currentSortingColumn, currentSortingMode, onColumnHeaderClick } = - useColumnSorting() - - const sortedOffers = sortOffers( - offers, - currentSortingColumn, - currentSortingMode - ) - - const { page, previousPage, nextPage, currentPageItems } = usePagination( - sortedOffers, - OFFERS_PER_PAGE, - urlSearchFilters.page - ) - return (
@@ -146,9 +83,15 @@ export const CollectiveOffersTable = ({ disabled={isRestrictedAsAdmin} onChange={toggleSelectAllCheckboxes} label={ - areAllOffersSelected - ? 'Tout désélectionner' - : 'Tout sélectionner' + areAllOffersSelected ? ( + + Tout désélectionner + + ) : ( + + Tout sélectionner + + ) } />
@@ -168,28 +111,6 @@ export const CollectiveOffersTable = ({ )} - {hasOffers && ( -
- { - previousPage() - applyUrlFiltersAndRedirect( - { ...urlSearchFilters, page: page - 1 }, - false - ) - }} - onNextPageClick={() => { - nextPage() - applyUrlFiltersAndRedirect( - { ...urlSearchFilters, page: page + 1 }, - false - ) - }} - /> -
- )} {!hasOffers && hasCollectiveSearchFilters(urlSearchFilters) && ( )} diff --git a/pro/src/pages/Offers/OffersTable/CollectiveOffersTable/CollectiveOffersTableHead/CollectiveOffersTableHead.tsx b/pro/src/pages/Offers/OffersTable/CollectiveOffersTable/CollectiveOffersTableHead/CollectiveOffersTableHead.tsx index 42fee4a7a5a..2eb2f21977e 100644 --- a/pro/src/pages/Offers/OffersTable/CollectiveOffersTable/CollectiveOffersTableHead/CollectiveOffersTableHead.tsx +++ b/pro/src/pages/Offers/OffersTable/CollectiveOffersTable/CollectiveOffersTableHead/CollectiveOffersTableHead.tsx @@ -3,8 +3,7 @@ import classNames from 'classnames' import { SortArrow } from 'components/StocksEventList/SortArrow' import { useActiveFeature } from 'hooks/useActiveFeature' import { SortingMode } from 'hooks/useColumnSorting' - -import { CollectiveOffersSortingColumn } from '../CollectiveOffersTable' +import { CollectiveOffersSortingColumn } from 'screens/CollectiveOffersScreen/CollectiveOffersScreen' import styles from './CollectiveOffersTableHead.module.scss' diff --git a/pro/src/screens/CollectiveOffersScreen/CollectiveOffersScreen.module.scss b/pro/src/screens/CollectiveOffersScreen/CollectiveOffersScreen.module.scss index 446f5c449f2..e2ab405cc44 100644 --- a/pro/src/screens/CollectiveOffersScreen/CollectiveOffersScreen.module.scss +++ b/pro/src/screens/CollectiveOffersScreen/CollectiveOffersScreen.module.scss @@ -20,3 +20,7 @@ } } } + +.offers-pagination { + margin-top: rem.torem(32px); +} diff --git a/pro/src/screens/CollectiveOffersScreen/CollectiveOffersScreen.tsx b/pro/src/screens/CollectiveOffersScreen/CollectiveOffersScreen.tsx index 40a69ca5ddc..4fe28f1dd8b 100644 --- a/pro/src/screens/CollectiveOffersScreen/CollectiveOffersScreen.tsx +++ b/pro/src/screens/CollectiveOffersScreen/CollectiveOffersScreen.tsx @@ -15,9 +15,13 @@ import { import { CollectiveSearchFiltersParams } from 'core/Offers/types' import { hasCollectiveSearchFilters } from 'core/Offers/utils/hasSearchFilters' import { SelectOption } from 'custom_types/form' +import { useColumnSorting } from 'hooks/useColumnSorting' +import { usePagination } from 'hooks/usePagination' import { CollectiveOffersActionsBar } from 'pages/Offers/OffersTable/CollectiveOffersTable/CollectiveOffersActionsBar/CollectiveOffersActionsBar' import { CollectiveOffersTable } from 'pages/Offers/OffersTable/CollectiveOffersTable/CollectiveOffersTable' import { isSameOffer } from 'pages/Offers/utils/isSameOffer' +import { Pagination } from 'ui-kit/Pagination/Pagination' +import { sortCollectiveOffers } from 'utils/sortCollectiveOffers' import styles from './CollectiveOffersScreen.module.scss' import { CollectiveOffersSearchFilters } from './CollectiveOffersSearchFilters/CollectiveOffersSearchFilters' @@ -43,6 +47,10 @@ export type CollectiveOffersScreenProps = { offers: CollectiveOfferResponseModel[] } +export enum CollectiveOffersSortingColumn { + EVENT_DATE = 'EVENT_DATE', +} + export const CollectiveOffersScreen = ({ currentPageNumber, isLoading, @@ -94,9 +102,25 @@ export const CollectiveOffersScreen = ({ const numberOfPages = Math.ceil(offers.length / NUMBER_OF_OFFERS_PER_PAGE) const pageCount = Math.min(numberOfPages, MAX_TOTAL_PAGES) + const { currentSortingColumn, currentSortingMode, onColumnHeaderClick } = + useColumnSorting() + + const sortedOffers = sortCollectiveOffers( + offers, + currentSortingColumn, + currentSortingMode + ) + + const { page, currentPageItems, setPage } = usePagination( + sortedOffers, + NUMBER_OF_OFFERS_PER_PAGE, + urlSearchFilters.page + ) + const applyUrlFiltersAndRedirect = ( filters: CollectiveSearchFiltersParams ) => { + setPage(filters.page ?? 1) redirectWithUrlFilters(filters) } @@ -155,11 +179,9 @@ export const CollectiveOffersScreen = ({ ) : ( <> 1} isRestrictedAsAdmin={isRestrictedAsAdmin} - offers={offers} + offers={sortedOffers} + onColumnHeaderClick={onColumnHeaderClick} + currentSortingColumn={currentSortingColumn} + currentSortingMode={currentSortingMode} + currentPageItems={currentPageItems} /> + {hasOffers && ( +
+ { + applyUrlFiltersAndRedirect({ + ...urlSearchFilters, + page: page - 1, + }) + }} + onNextPageClick={() => { + applyUrlFiltersAndRedirect({ + ...urlSearchFilters, + page: page + 1, + }) + }} + /> +
+ )}
{selectedOffers.length > 0 && ( () + + const sortedOffers = sortCollectiveOffers( + offers, + currentSortingColumn, + currentSortingMode + ) + + const { page, currentPageItems, setPage } = usePagination( + sortedOffers, + NUMBER_OF_OFFERS_PER_PAGE, + urlSearchFilters.page + ) + const applyUrlFiltersAndRedirect = ( filters: CollectiveSearchFiltersParams ) => { + setPage(filters.page ?? 1) redirectWithUrlFilters(filters) } @@ -156,11 +177,9 @@ export const TemplateCollectiveOffersScreen = ({ ) : ( <> 1} isRestrictedAsAdmin={isRestrictedAsAdmin} - offers={offers} + offers={sortedOffers} + onColumnHeaderClick={onColumnHeaderClick} + currentSortingColumn={currentSortingColumn} + currentSortingMode={currentSortingMode} + currentPageItems={currentPageItems} /> + {hasOffers && ( +
+ { + applyUrlFiltersAndRedirect({ + ...urlSearchFilters, + page: page - 1, + }) + }} + onNextPageClick={() => { + applyUrlFiltersAndRedirect({ + ...urlSearchFilters, + page: page + 1, + }) + }} + /> +
+ )}
{selectedOffers.length > 0 && (