From 286194d61a8b40f8542ce75d82710559f1ba95bb Mon Sep 17 00:00:00 2001 From: Ronald Langeveld Date: Wed, 13 Dec 2023 12:25:06 +0200 Subject: [PATCH] Added global state to avoid losing sorting state in Offers (#19355) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit refs https://linear.app/tryghost/issue/PROD-8/when-i-sort-by-name-→-click-into-an-offer-→-go-back-to-the-list-it - we now handle the state via a global state to ensure we aren't resetting the sorting options after each rerender. --- .../providers/SettingsAppProvider.tsx | 29 +++++++++++++++++-- .../settings/growth/offers/OffersIndex.tsx | 22 +++++++++++--- 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/apps/admin-x-settings/src/components/providers/SettingsAppProvider.tsx b/apps/admin-x-settings/src/components/providers/SettingsAppProvider.tsx index 0eddfbe7b7..5226bef3a2 100644 --- a/apps/admin-x-settings/src/components/providers/SettingsAppProvider.tsx +++ b/apps/admin-x-settings/src/components/providers/SettingsAppProvider.tsx @@ -1,6 +1,6 @@ import GlobalDataProvider from './GlobalDataProvider'; import useSearchService, {SearchService} from '../../utils/search'; -import {ReactNode, createContext, useContext} from 'react'; +import {ReactNode, createContext, useContext, useState} from 'react'; import {ScrollSectionProvider} from '../../hooks/useScrollSection'; import {ZapierTemplate} from '../settings/advanced/integrations/ZapierModal'; @@ -20,6 +20,12 @@ export type OfficialTheme = { variants?: ThemeVariant[] }; +export type Sorting = { + type: string; + option?: string; + direction?: string; +} + export interface UpgradeStatusType { isRequired: boolean; message: string; @@ -30,12 +36,15 @@ interface SettingsAppContextType { zapierTemplates: ZapierTemplate[]; search: SearchService; upgradeStatus?: UpgradeStatusType; + sortingState?: Sorting[]; + setSortingState?: (sortingState: Sorting[]) => void; } const SettingsAppContext = createContext({ officialThemes: [], zapierTemplates: [], - search: {filter: '', setFilter: () => {}, checkVisible: () => true, highlightKeywords: () => ''} + search: {filter: '', setFilter: () => {}, checkVisible: () => true, highlightKeywords: () => ''}, + sortingState: [] }); type SettingsAppProviderProps = Omit & {children: ReactNode}; @@ -43,10 +52,19 @@ type SettingsAppProviderProps = Omit & {childr const SettingsAppProvider: React.FC = ({children, ...props}) => { const search = useSearchService(); + // a few sane defaults for keeping a sorting state + const [sortingState, setSortingState] = useState([{ + type: 'offers', + option: 'date-added', + direction: 'desc' + }]); + return ( @@ -66,3 +84,8 @@ export const useOfficialThemes = () => useSettingsApp().officialThemes; export const useSearch = () => useSettingsApp().search; export const useUpgradeStatus = () => useSettingsApp().upgradeStatus; + +export const useSortingState = () => { + const {sortingState, setSortingState} = useSettingsApp(); + return {sortingState, setSortingState}; +}; diff --git a/apps/admin-x-settings/src/components/settings/growth/offers/OffersIndex.tsx b/apps/admin-x-settings/src/components/settings/growth/offers/OffersIndex.tsx index 60e272fa3a..c8c10d4700 100644 --- a/apps/admin-x-settings/src/components/settings/growth/offers/OffersIndex.tsx +++ b/apps/admin-x-settings/src/components/settings/growth/offers/OffersIndex.tsx @@ -14,6 +14,7 @@ import {useEffect, useState} from 'react'; import {useGlobalData} from '../../../providers/GlobalDataProvider'; import {useModal} from '@ebay/nice-modal-react'; import {useRouting} from '@tryghost/admin-x-framework/routing'; +import {useSortingState} from '../../../providers/SettingsAppProvider'; export type OfferType = 'percent' | 'fixed' | 'trial'; @@ -113,9 +114,14 @@ export const OffersIndexModal = () => { {id: 'active', title: 'Active'}, {id: 'archived', title: 'Archived'} ]; + + const {sortingState, setSortingState} = useSortingState(); + const offersSorting = sortingState?.find(sorting => sorting.type === 'offers'); + const [selectedTab, setSelectedTab] = useState('active'); - const [sortOption, setSortOption] = useState('date-added'); - const [sortDirection, setSortDirection] = useState('desc'); + + const sortOption = offersSorting?.option || 'date-added'; + const sortDirection = offersSorting?.direction || 'desc'; useEffect(() => { if (!hasOffers) { @@ -250,10 +256,18 @@ export const OffersIndexModal = () => { position='right' onDirectionChange={(selectedDirection) => { const newDirection = selectedDirection === 'asc' ? 'desc' : 'asc'; - setSortDirection(newDirection); + setSortingState?.([{ + type: 'offers', + option: sortOption, + direction: newDirection + }]); }} onSortChange={(selectedOption) => { - setSortOption(selectedOption); + setSortingState?.([{ + type: 'offers', + option: selectedOption, + direction: sortDirection + }]); }} />