From baf9fa0dff65cbf8108674d9d844491e90ebdba2 Mon Sep 17 00:00:00 2001 From: David Remer Date: Fri, 24 Nov 2023 12:09:16 +0200 Subject: [PATCH] Read state from URL and write state to URL [MAILPOET-5395] --- .../segments/dynamic/list/listing-helpers.ts | 40 +++++++++---------- .../src/segments/dynamic/list/listing-tab.tsx | 19 +++++++-- .../js/src/segments/dynamic/store/actions.ts | 15 +++++++ .../assets/js/src/segments/dynamic/types.ts | 1 - 4 files changed, 50 insertions(+), 25 deletions(-) diff --git a/mailpoet/assets/js/src/segments/dynamic/list/listing-helpers.ts b/mailpoet/assets/js/src/segments/dynamic/list/listing-helpers.ts index ad5f9acd1e..50e6a3dcd5 100644 --- a/mailpoet/assets/js/src/segments/dynamic/list/listing-helpers.ts +++ b/mailpoet/assets/js/src/segments/dynamic/list/listing-helpers.ts @@ -2,16 +2,15 @@ import { select, dispatch } from '@wordpress/data'; import { DynamicSegmentQuery } from '../types'; import { storeName } from '../store'; +const defaultQuery = { + offset: 0, + limit: 2, + search: '', + sort_by: 'updated_at', + sort_order: 'desc', + group: 'all', +}; export function updateDynamicQuery(values: Partial): void { - const defaultQuery = { - offset: 0, - limit: 2, - filter: {}, - search: '', - sort_by: 'updated_at', - sort_order: 'desc', - group: 'all', - }; const currentQuery = select(storeName).getDynamicSegmentsQuery(); const query = currentQuery ?? defaultQuery; const newQuery = { ...query, ...values }; @@ -26,18 +25,7 @@ export function updateDynamicQuery(values: Partial): void { export function updateDynamicQueryFromLocation(pathname: string): void { const pathElements = pathname.split('/'); - if (pathElements[1] !== 'segments') { - return; - } - const defaultQuery = { - offset: 0, - limit: 2, - filter: {}, - search: '', - sort_by: 'updated_at', - sort_order: 'desc', - group: 'all', - }; + const currentQuery = select(storeName).getDynamicSegmentsQuery(); const query = currentQuery !== null ? currentQuery : defaultQuery; const queryKeys = Object.keys(query); @@ -65,3 +53,13 @@ export function updateDynamicQueryFromLocation(pathname: string): void { } updateDynamicQuery(query); } + +export function getTabFromLocation(pathname: string): string { + const pathElements = pathname.split('/'); + for (let i = 0; i < pathElements.length; i += 1) { + if (pathElements[i].startsWith(`group[`)) { + return pathElements[i].replace(`group[`, '').replace(']', ''); + } + } + return 'all'; +} diff --git a/mailpoet/assets/js/src/segments/dynamic/list/listing-tab.tsx b/mailpoet/assets/js/src/segments/dynamic/list/listing-tab.tsx index afe232b14e..8f99f83fb9 100644 --- a/mailpoet/assets/js/src/segments/dynamic/list/listing-tab.tsx +++ b/mailpoet/assets/js/src/segments/dynamic/list/listing-tab.tsx @@ -1,10 +1,15 @@ import { useSelect } from '@wordpress/data'; import { useCallback, useMemo } from 'react'; +import { useLocation } from 'react-router-dom'; import { TabPanel } from '@wordpress/components'; import { __, _x } from '@wordpress/i18n'; import { storeName } from '../store'; import { ListingTable } from './listing-table'; -import { updateDynamicQuery } from './listing-helpers'; +import { + getTabFromLocation, + updateDynamicQuery, + updateDynamicQueryFromLocation, +} from './listing-helpers'; const tabConfig = [ { @@ -20,7 +25,8 @@ const tabConfig = [ ] as const; export function ListingTab(): JSX.Element { - const { dynamicSegmentsGroups } = useSelect((s) => ({ + const location = useLocation(); + const { dynamicSegmentQuery, dynamicSegmentsGroups } = useSelect((s) => ({ dynamicSegments: s(storeName).getDynamicSegments(), dynamicSegmentQuery: s(storeName).getDynamicSegmentsQuery(), dynamicSegmentsGroups: s(storeName).getDynamicSegmentsGroups(), @@ -53,8 +59,15 @@ export function ListingTab(): JSX.Element { { + if (dynamicSegmentQuery === null) { + updateDynamicQueryFromLocation(location.pathname); + return; + } + if (dynamicSegmentQuery.group === tab) { + return; + } updateDynamicQuery({ group: tab, offset: 0 }); }} > diff --git a/mailpoet/assets/js/src/segments/dynamic/store/actions.ts b/mailpoet/assets/js/src/segments/dynamic/store/actions.ts index 7bd087868d..7950782f1a 100644 --- a/mailpoet/assets/js/src/segments/dynamic/store/actions.ts +++ b/mailpoet/assets/js/src/segments/dynamic/store/actions.ts @@ -272,10 +272,25 @@ export async function loadDynamicSegments(query?: DynamicSegmentQuery) { } as const; } +function updateUrlWithQueryParams(query: DynamicSegmentQuery) { + const currentUrl = window.location.href; + let hash = '/segments'; + const keys = Object.keys(query); + for (let i = 0; i < keys.length; i += 1) { + const key = keys[i]; + const value = query[key] as string; + if (value) { + hash += `/${key}[${value}]`; + } + } + window.history.pushState(null, '', `${currentUrl.split('#')[0]}#${hash}`); +} + export function updateDynamicSegmentsQuery( query: DynamicSegmentQuery, ): UpdateDynamicSegmentsQueryActionType { void dispatch(storeName).loadDynamicSegments(query); + updateUrlWithQueryParams(query); return { type: Actions.UPDATE_DYNAMIC_SEGMENTS_QUERY, query, diff --git a/mailpoet/assets/js/src/segments/dynamic/types.ts b/mailpoet/assets/js/src/segments/dynamic/types.ts index 44b587c488..578d579e49 100644 --- a/mailpoet/assets/js/src/segments/dynamic/types.ts +++ b/mailpoet/assets/js/src/segments/dynamic/types.ts @@ -332,7 +332,6 @@ export interface SegmentFormDataWindow extends Window { export type DynamicSegmentQuery = { offset: number; limit: number; - filter: Record; search: string; sort_by: string; sort_order: string;