Fix Layout Controller forwarding arrays from the URL query string. (#38593)

* Revert part of "Remove `qs` dependency from `woocommerce-admin` (#35128)"

This reverts Layout- and Filter-related changes from commit 00c151f9aa, reversing
changes made to eef417fe39.

Removes the fix (keeping the test) from https://github.com/woocommerce/woocommerce/pull/38542 as it's not needed for `qs`

Fixes https://github.com/woocommerce/woocommerce/issues/38582.

* Simplify the use of query params in `ProductTour`

* Add changelog entry
This commit is contained in:
Tomek Wytrębowicz 2023-06-05 09:55:20 +02:00 committed by GitHub
parent ac85cc2c59
commit f569f333a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 74 additions and 50 deletions

View File

@ -21,6 +21,7 @@ import {
defaultTableDateFormat,
getCurrentDates,
} from '@woocommerce/date';
import { stringify } from 'qs';
import { CurrencyContext } from '@woocommerce/currency';
/**
@ -309,7 +310,7 @@ const formatProps = memoize(
[
isError,
isRequesting,
new URLSearchParams( tableQuery ).toString(),
stringify( tableQuery ),
get( revenueData, [ 'totalResults' ], 0 ),
get( revenueData, [ 'data', 'intervals' ], EMPTY_ARRAY ).length,
dateType,

View File

@ -8,6 +8,7 @@ import {
LayoutContextProvider,
getLayoutContextValue,
} from '@woocommerce/admin-layout';
import QueryString, { parse } from 'qs';
/**
* Internal dependencies
@ -20,8 +21,10 @@ import './style.scss';
type QueryParams = EmbeddedBodyProps;
function isWPPage( params: URLSearchParams ): boolean {
return params.get( 'page' ) !== null;
function isWPPage(
params: QueryParams | QueryString.ParsedQs
): params is QueryParams {
return ( params as QueryParams ).page !== undefined;
}
const EMBEDDED_BODY_COMPONENT_LIST: React.ElementType[] = [
@ -41,10 +44,10 @@ export const EmbeddedBodyLayout = () => {
triggerExitPageCesSurvey();
}, [] );
const query = new URLSearchParams( location.search );
const query = parse( location.search.substring( 1 ) );
let queryParams: QueryParams = { page: '', tab: '' };
if ( isWPPage( query ) ) {
queryParams = Object.fromEntries( query ) as QueryParams;
queryParams = query;
}
/**
* Filter an array of body components for WooCommerce non-react pages.

View File

@ -293,10 +293,8 @@ export const ProductTour = () => {
recordEvent( 'walkthrough_product_enable_button_click' );
} );
const query = Object.fromEntries(
new URLSearchParams( window.location.search )
);
if ( query && query.tutorial === 'true' ) {
const query = new URLSearchParams( window.location.search );
if ( query.get( 'tutorial' ) === 'true' ) {
const intervalId = waitUntilElementTopNotChange(
tourConfig.steps[ 0 ].referenceElements?.desktop || '',
() => {

View File

@ -3,6 +3,7 @@
*/
import { Suspense, lazy } from '@wordpress/element';
import { useRef, useEffect } from 'react';
import { parse, stringify } from 'qs';
import { find, isEqual, last, omit } from 'lodash';
import { applyFilters } from '@wordpress/hooks';
import { __ } from '@wordpress/i18n';
@ -429,28 +430,18 @@ export const Controller = ( { ...props } ) => {
*/
export function updateLinkHref( item, nextQuery, excludedScreens ) {
if ( isWCAdmin( item.href ) ) {
// If we accept a full HTMLAnchorElement, then we should be able to use `.search`.
// const query = new URLSearchParams( item.search );
// but to remain backward compatible, we support any object with `href` property.
const search = last( item.href.split( '?' ) );
let query = new URLSearchParams( search );
const path = query.get( 'path' ) || 'homescreen';
const query = parse( search );
const path = query.path || 'homescreen';
const screen = getScreenFromPath( path );
if ( ! excludedScreens.includes( screen ) ) {
query = new URLSearchParams( {
...Object.fromEntries( query ),
...nextQuery,
} );
}
// Remove undefined keys.
for ( const [ key, value ] of Array.from( query.entries() ) ) {
if ( value === 'undefined' || value === undefined ) {
query.delete( key );
}
}
const isExcludedScreen = excludedScreens.includes( screen );
const href = 'admin.php?' + query.toString();
const href =
'admin.php?' +
stringify(
Object.assign( query, isExcludedScreen ? {} : nextQuery )
);
// Replace the href so you can see the url on hover.
item.href = href;

View File

@ -188,9 +188,7 @@ function _Layout( {
const { breadcrumbs, layout = { header: true, footer: true } } = page;
const { header: showHeader = true, footer: showFooter = true } = layout;
const query = Object.fromEntries(
new URLSearchParams( location && location.search )
);
const query = getQuery();
return (
<LayoutContextProvider

View File

@ -92,6 +92,7 @@
"history": "^5.3.0",
"lodash": "^4.17.21",
"memize": "^1.1.0",
"qs": "^6.10.3",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-router-dom": "^6.3.0",

View File

@ -0,0 +1,4 @@
Significance: patch
Type: fix
Fix Layout Controller forwarding arrays from the URL query string.

View File

@ -2579,6 +2579,9 @@ importers:
memize:
specifier: ^1.1.0
version: 1.1.0
qs:
specifier: ^6.10.3
version: 6.10.3
react:
specifier: ^17.0.2
version: 17.0.2
@ -3100,7 +3103,7 @@ importers:
version: link:../../packages/js/eslint-plugin
'@wordpress/prettier-config':
specifier: 2.17.0
version: 2.17.0(wp-prettier@2.8.5)
version: 2.17.0(wp-prettier@2.6.2)
'@wordpress/scripts':
specifier: ^26.4.0
version: 26.4.0(@types/node@16.18.21)(acorn@8.8.1)(react-dom@17.0.2)(react@17.0.2)(typescript@4.9.5)
@ -3109,7 +3112,7 @@ importers:
version: 8.32.0
prettier:
specifier: npm:wp-prettier@^2.6.2
version: /wp-prettier@2.8.5
version: /wp-prettier@2.6.2
ts-loader:
specifier: ^9.4.1
version: 9.4.1(typescript@4.9.5)(webpack@5.76.3)
@ -3906,7 +3909,7 @@ packages:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/core': 7.21.3
'@jridgewell/trace-mapping': 0.3.16
'@jridgewell/trace-mapping': 0.3.17
commander: 4.1.1
convert-source-map: 1.8.0
fs-readdir-recursive: 1.1.0
@ -4897,7 +4900,7 @@ packages:
'@babel/core': ^7.13.0
dependencies:
'@babel/core': 7.17.8
'@babel/helper-plugin-utils': 7.20.2
'@babel/helper-plugin-utils': 7.21.5
'@babel/helper-skip-transparent-expression-wrappers': 7.18.9
'@babel/plugin-proposal-optional-chaining': 7.18.9(@babel/core@7.17.8)
dev: true
@ -4909,7 +4912,7 @@ packages:
'@babel/core': ^7.13.0
dependencies:
'@babel/core': 7.21.3
'@babel/helper-plugin-utils': 7.20.2
'@babel/helper-plugin-utils': 7.21.5
'@babel/helper-skip-transparent-expression-wrappers': 7.18.9
'@babel/plugin-proposal-optional-chaining': 7.18.9(@babel/core@7.21.3)
@ -4990,7 +4993,7 @@ packages:
dependencies:
'@babel/core': 7.17.8
'@babel/helper-environment-visitor': 7.18.9
'@babel/helper-plugin-utils': 7.20.2
'@babel/helper-plugin-utils': 7.21.5
'@babel/helper-remap-async-to-generator': 7.18.9(@babel/core@7.17.8)
'@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.17.8)
transitivePeerDependencies:
@ -5005,7 +5008,7 @@ packages:
dependencies:
'@babel/core': 7.21.3
'@babel/helper-environment-visitor': 7.18.9
'@babel/helper-plugin-utils': 7.20.2
'@babel/helper-plugin-utils': 7.21.5
'@babel/helper-remap-async-to-generator': 7.18.9(@babel/core@7.21.3)
'@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.21.3)
transitivePeerDependencies:
@ -6106,7 +6109,7 @@ packages:
'@babel/core': 7.17.8
'@babel/helper-annotate-as-pure': 7.18.6
'@babel/helper-create-class-features-plugin': 7.19.0(@babel/core@7.17.8)
'@babel/helper-plugin-utils': 7.20.2
'@babel/helper-plugin-utils': 7.21.5
'@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.17.8)
transitivePeerDependencies:
- supports-color
@ -6121,7 +6124,7 @@ packages:
'@babel/core': 7.21.3
'@babel/helper-annotate-as-pure': 7.18.6
'@babel/helper-create-class-features-plugin': 7.19.0(@babel/core@7.21.3)
'@babel/helper-plugin-utils': 7.20.2
'@babel/helper-plugin-utils': 7.21.5
'@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.21.3)
transitivePeerDependencies:
- supports-color
@ -6549,6 +6552,15 @@ packages:
'@babel/helper-plugin-utils': 7.20.2
dev: true
/@babel/plugin-syntax-jsx@7.18.6(@babel/core@7.17.8):
resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/core': 7.17.8
'@babel/helper-plugin-utils': 7.21.5
/@babel/plugin-syntax-jsx@7.18.6(@babel/core@7.21.3):
resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==}
engines: {node: '>=6.9.0'}
@ -6575,6 +6587,7 @@ packages:
dependencies:
'@babel/core': 7.17.8
'@babel/helper-plugin-utils': 7.21.5
dev: true
/@babel/plugin-syntax-jsx@7.21.4(@babel/core@7.21.3):
resolution: {integrity: sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==}
@ -8087,7 +8100,7 @@ packages:
dependencies:
'@babel/core': 7.17.8
'@babel/helper-module-transforms': 7.21.2
'@babel/helper-plugin-utils': 7.20.2
'@babel/helper-plugin-utils': 7.21.5
'@babel/helper-simple-access': 7.20.2
transitivePeerDependencies:
- supports-color
@ -8101,7 +8114,7 @@ packages:
dependencies:
'@babel/core': 7.21.3
'@babel/helper-module-transforms': 7.21.2
'@babel/helper-plugin-utils': 7.20.2
'@babel/helper-plugin-utils': 7.21.5
'@babel/helper-simple-access': 7.20.2
transitivePeerDependencies:
- supports-color
@ -8823,9 +8836,9 @@ packages:
'@babel/core': 7.21.3
'@babel/helper-annotate-as-pure': 7.16.7
'@babel/helper-module-imports': 7.16.7
'@babel/helper-plugin-utils': 7.21.5
'@babel/helper-plugin-utils': 7.18.9
'@babel/plugin-syntax-jsx': 7.16.7(@babel/core@7.21.3)
'@babel/types': 7.22.4
'@babel/types': 7.17.0
dev: true
/@babel/plugin-transform-react-jsx@7.19.0(@babel/core@7.17.8):
@ -10333,8 +10346,8 @@ packages:
'@babel/core': ^7.0.0-0
dependencies:
'@babel/core': 7.21.3
'@babel/helper-plugin-utils': 7.20.2
'@babel/helper-validator-option': 7.18.6
'@babel/helper-plugin-utils': 7.21.5
'@babel/helper-validator-option': 7.21.0
'@babel/plugin-transform-react-display-name': 7.16.7(@babel/core@7.21.3)
'@babel/plugin-transform-react-jsx': 7.19.0(@babel/core@7.21.3)
'@babel/plugin-transform-react-jsx-development': 7.16.7(@babel/core@7.21.3)
@ -10635,8 +10648,8 @@ packages:
'@babel/core': ^7.0.0
dependencies:
'@babel/core': 7.17.8
'@babel/helper-module-imports': 7.21.4
'@babel/plugin-syntax-jsx': 7.21.4(@babel/core@7.17.8)
'@babel/helper-module-imports': 7.18.6
'@babel/plugin-syntax-jsx': 7.18.6(@babel/core@7.17.8)
'@babel/runtime': 7.21.0
'@emotion/hash': 0.9.0
'@emotion/memoize': 0.8.0
@ -12121,6 +12134,7 @@ packages:
dependencies:
'@jridgewell/resolve-uri': 3.1.0
'@jridgewell/sourcemap-codec': 1.4.14
dev: true
/@jridgewell/trace-mapping@0.3.17:
resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==}
@ -19947,6 +19961,15 @@ packages:
prettier: /wp-prettier@2.2.1-beta-1
dev: true
/@wordpress/prettier-config@2.17.0(wp-prettier@2.6.2):
resolution: {integrity: sha512-g4TEQIRDwNW/O8cAf895YV8a3eFfJr7RNLjqu70r8JFH4jmt2clJNu/9nxRburBxJZwqQnykrnDUz0HvXSbcsA==}
engines: {node: '>=14'}
peerDependencies:
prettier: '>=2'
dependencies:
prettier: /wp-prettier@2.6.2
dev: true
/@wordpress/prettier-config@2.17.0(wp-prettier@2.8.5):
resolution: {integrity: sha512-g4TEQIRDwNW/O8cAf895YV8a3eFfJr7RNLjqu70r8JFH4jmt2clJNu/9nxRburBxJZwqQnykrnDUz0HvXSbcsA==}
engines: {node: '>=14'}
@ -21421,8 +21444,8 @@ packages:
peerDependencies:
postcss: ^8.1.0
dependencies:
browserslist: 4.21.4
caniuse-lite: 1.0.30001418
browserslist: 4.20.2
caniuse-lite: 1.0.30001352
fraction.js: 4.2.0
normalize-range: 0.1.2
picocolors: 1.0.0
@ -22987,7 +23010,6 @@ packages:
escalade: 3.1.1
node-releases: 2.0.6
picocolors: 1.0.0
dev: true
/browserslist@4.20.4:
resolution: {integrity: sha512-ok1d+1WpnU24XYN7oC3QWgTyMhY/avPJ/r9T00xxvUOIparA/gc+UPUMaod3i+G6s+nI2nUb9xZ5k794uIwShw==}
@ -45124,6 +45146,12 @@ packages:
hasBin: true
dev: true
/wp-prettier@2.6.2:
resolution: {integrity: sha512-AV33EzqiFJ3fj+mPlKABN59YFPReLkDxQnj067Z3uEOeRQf3g05WprL0RDuqM7UBhSRo9W1rMSC2KvZmjE5UOA==}
engines: {node: '>=10.13.0'}
hasBin: true
dev: true
/wp-prettier@2.8.5:
resolution: {integrity: sha512-gkphzYtVksWV6D7/V530bTehKkhrABUru/Gy4reOLOHJoKH4i9lcE1SxqU2VDxC3gCOx/Nk9alZmWk6xL/IBCw==}
engines: {node: '>=10.13.0'}