Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
427 changes: 422 additions & 5 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions projects/packages/forms/changelog/update-dataviews-to-10-next
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: changed

Forms: Update DataViews to 10.0.1-next
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: changed

Forms: Migrate dashboard routing from React Router to TanStack Router
4 changes: 2 additions & 2 deletions projects/packages/forms/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,15 @@
"@automattic/request-external-access": "1.0.1",
"@automattic/ui": "1.0.2",
"@gravatar-com/hovercards": "0.15.0",
"@tanstack/react-router": ">=1.120.5 <1.121.0",
"@wordpress/base-styles": "6.7.0",
"@wordpress/block-editor": "15.4.0",
"@wordpress/blocks": "15.4.0",
"@wordpress/components": "30.4.0",
"@wordpress/compose": "7.31.0",
"@wordpress/core-data": "7.31.0",
"@wordpress/data": "10.31.0",
"@wordpress/dataviews": "9.1.0",
"@wordpress/dataviews": "10.0.1-next.b8c8708f3.0",
"@wordpress/dom-ready": "4.31.0",
"@wordpress/editor": "14.31.0",
"@wordpress/element": "6.31.0",
Expand All @@ -71,7 +72,6 @@
"libphonenumber-js": "1.12.23",
"lodash": "4.17.21",
"react-redux": "7.2.8",
"react-router": "7.6.2",
"react-transition-group": "^4.4.5",
"redux": "4.2.1",
"redux-thunk": "2.3.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import jetpackAnalytics from '@automattic/jetpack-analytics';
import { useBreakpointMatch } from '@automattic/jetpack-components';
import { formatNumber } from '@automattic/number-formatters';
import { useNavigate, useRouterState } from '@tanstack/react-router';
import {
// eslint-disable-next-line @wordpress/no-unsafe-wp-apis
__experimentalToggleGroupControl as ToggleGroupControl,
Expand All @@ -12,7 +13,6 @@ import {
} from '@wordpress/components';
import { __, _x } from '@wordpress/i18n';
import { useCallback } from 'react';
import { useSearchParams } from 'react-router';
/**
* Internal dependencies
*/
Expand Down Expand Up @@ -40,8 +40,10 @@ type InboxStatusToggleProps = {
* @return {JSX.Element} The status toggle component.
*/
export default function InboxStatusToggle( { onChange }: InboxStatusToggleProps ): JSX.Element {
const [ searchParams, setSearchParams ] = useSearchParams();
const status = searchParams.get( 'status' ) || 'inbox';
const navigate = useNavigate();
const routerState = useRouterState();
const searchParams = routerState?.location?.search || {};
const status = searchParams.status || 'inbox';
const [ isSm ] = useBreakpointMatch( 'sm' );

const { totalItemsInbox, totalItemsSpam, totalItemsTrash } = useInboxData();
Expand All @@ -63,16 +65,17 @@ export default function InboxStatusToggle( { onChange }: InboxStatusToggleProps
previous_status: status,
} );

setSearchParams( prev => {
const params = new URLSearchParams( prev );
params.set( 'status', newStatus );

return params;
navigate( {
// @ts-expect-error - TanStack Router types require strictNullChecks
search: prev => ( {
...prev,
status: newStatus,
} ),
} );

onChange( newStatus );
},
[ isSm, status, setSearchParams, onChange ]
[ isSm, status, navigate, onChange ]
);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
*/
import jetpackAnalytics from '@automattic/jetpack-analytics';
import { useBreakpointMatch } from '@automattic/jetpack-components';
import { Outlet, useLocation, useNavigate } from '@tanstack/react-router';
import { TabPanel } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { useCallback, useEffect, useMemo } from '@wordpress/element';
import { __, _x } from '@wordpress/i18n';
import { Outlet, useLocation, useNavigate } from 'react-router';
/**
* Internal dependencies
*/
Expand Down Expand Up @@ -94,8 +94,8 @@ const Layout = () => {
}

navigate( {
pathname: `/${ tabName }`,
search: tabName === 'responses' ? location.search : '',
to: `/${ tabName }`,
search: tabName === 'responses' ? location.search : undefined,
} );
},
[ navigate, location.search, isSm, getCurrentTab, hasFeedback ]
Expand Down
7 changes: 4 additions & 3 deletions projects/packages/forms/src/dashboard/hooks/use-inbox-data.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/**
* External dependencies
*/
import { useRouterState } from '@tanstack/react-router';
import { useEntityRecords, store as coreDataStore } from '@wordpress/core-data';
import { useDispatch, useSelect } from '@wordpress/data';
import { useMemo } from '@wordpress/element';
import { decodeEntities } from '@wordpress/html-entities';
import { isEmpty } from 'lodash';
import { useSearchParams } from 'react-router';
/**
* Internal dependencies
*/
Expand Down Expand Up @@ -73,9 +73,10 @@ interface UseInboxDataReturn {
* @return {UseInboxDataReturn} The inbox related data.
*/
export default function useInboxData(): UseInboxDataReturn {
const [ searchParams ] = useSearchParams();
const routerState = useRouterState();
const searchParams = routerState?.location?.search || {};
const { setCurrentQuery, setSelectedResponses } = useDispatch( dashboardStore );
const urlStatus = searchParams.get( 'status' );
const urlStatus = searchParams.status;
const statusFilter = getStatusFilter( urlStatus );

const {
Expand Down
30 changes: 17 additions & 13 deletions projects/packages/forms/src/dashboard/inbox/dataviews/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/**
* External dependencies
*/
import { useNavigate, useRouterState } from '@tanstack/react-router';
import {
ExternalLink,
// eslint-disable-next-line @wordpress/no-unsafe-wp-apis
Expand All @@ -13,7 +14,6 @@ import { useCallback, useMemo, useState } from '@wordpress/element';
import { decodeEntities } from '@wordpress/html-entities';
import { __ } from '@wordpress/i18n';
import { useEffect } from 'react';
import { useSearchParams } from 'react-router';
/**
* Internal dependencies
*/
Expand Down Expand Up @@ -74,18 +74,20 @@ const setupSidebarWidthObserver = () => {
*/
export default function InboxView() {
const [ view, setView ] = useView();
const [ searchParams, setSearchParams ] = useSearchParams();
const navigate = useNavigate();
const routerState = useRouterState();
const searchParams = routerState?.location?.search || {};
const [ containerWidth, setContainerWidth ] = useState( 0 );

const dateSettings = getDateSettings();

const containerRef = useResizeObserver(
resizeObserverEntries => {
setContainerWidth( resizeObserverEntries[ 0 ].borderBoxSize[ 0 ].inlineSize );
},
{ box: 'border-box' }
);
const isMobile = containerWidth <= MOBILE_BREAKPOINT;
const selectedResponses = searchParams.get( 'r' );
const selectedResponses = searchParams.r;

useEffect( () => {
return setupSidebarWidthObserver();
Expand Down Expand Up @@ -152,17 +154,19 @@ export default function InboxView() {
records?.find( record => getItemId( record ) === items[ items.length - 1 ] )
);
}
setSearchParams( previousSearchParams => {
const _searchParams = new URLSearchParams( previousSearchParams );
if ( items.length ) {
_searchParams.set( 'r', items.join( ',' ) );
} else {
_searchParams.delete( 'r' );
}
return _searchParams;
navigate( {
search: prev => {
const updated = { ...prev };
if ( items.length ) {
updated.r = items.join( ',' );
} else {
delete updated.r;
}
return updated;
},
} );
},
[ records, setSearchParams, isMobile ]
[ records, navigate, isMobile ]
);
// Because selection is in sync with the URL and data takes some time to load,
// We need to carefully (avoid infinite loops by always updating the state)
Expand Down
31 changes: 20 additions & 11 deletions projects/packages/forms/src/dashboard/inbox/dataviews/views.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/**
* WordPress dependencies
*/
import { useNavigate, useRouterState } from '@tanstack/react-router';
import { useEvent } from '@wordpress/compose';
import { useEffect, useState } from '@wordpress/element';
import { useSearchParams } from 'react-router';

const LAYOUT_TABLE = 'table';

Expand All @@ -29,27 +29,34 @@ export const defaultLayouts = {
* @return {Array} The [ state, setState ] tuple.
*/
export function useView() {
const [ searchParams, setSearchParams ] = useSearchParams();
const urlSearch = searchParams.get( 'search' );
const navigate = useNavigate();
const routerState = useRouterState();
const searchParams = routerState?.location?.search || {};
const urlSearch = searchParams.search;

const [ view, setView ] = useState( () => ( {
...defaultView,
search: urlSearch ?? '',
} ) );

// When view changes, update the URL params if needed.
const setViewWithUrlUpdate = useEvent( newView => {
setView( newView );
if ( newView.search !== urlSearch ) {
setSearchParams( previousSearchParams => {
const _searchParams = new URLSearchParams( previousSearchParams );
if ( newView.search ) {
_searchParams.set( 'search', newView.search );
} else {
_searchParams.delete( 'search' );
}
return _searchParams;
navigate( {
search: prev => {
const updated = { ...prev };
if ( newView.search ) {
updated.search = newView.search;
} else {
delete updated.search;
}
return updated;
},
} );
}
} );

// When search URL param changes, update the view's search filter
// without affecting any other config.
const onUrlSearchChange = useEvent( () => {
Expand All @@ -64,8 +71,10 @@ export function useView() {
};
} );
} );

useEffect( () => {
onUrlSearchChange();
}, [ onUrlSearchChange, urlSearch ] );

return [ view, setViewWithUrlUpdate ];
}
2 changes: 1 addition & 1 deletion projects/packages/forms/src/dashboard/inbox/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useNavigate } from '@tanstack/react-router';
import { useEffect } from '@wordpress/element';
import { useNavigate } from 'react-router';
import useConfigValue from '../../hooks/use-config-value';
import InboxView from './dataviews';
import './style.scss';
Expand Down
Loading
Loading