diff --git a/package-lock.json b/package-lock.json index e1b28a06..90348fb7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "@edx/frontend-component-header": "npm:@edx/frontend-component-header-edx@^7.0.0", "@edx/frontend-enterprise-catalog-search": "^4.2.0", "@edx/frontend-enterprise-hotjar": "^1.3.0", + "@edx/frontend-enterprise-utils": "^3.2.0", "@edx/frontend-platform": "^4.0.1", "@edx/paragon": "20.29.0", "@fortawesome/fontawesome-svg-core": "1.2.35", @@ -32,7 +33,6 @@ "lodash.escaperegexp": "4.1.2", "npm": "^8.19.3", "prop-types": "15.8.1", - "query-string": "7.1.3", "react": "^16.14.0", "react-dom": "^16.14.0", "react-helmet": "6.1.0", @@ -3697,6 +3697,21 @@ "react-dom": "^16.9.0 || ^17.0.0" } }, + "node_modules/@edx/frontend-component-header/node_modules/@edx/frontend-enterprise-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@edx/frontend-enterprise-utils/-/frontend-enterprise-utils-3.0.0.tgz", + "integrity": "sha512-O9yoHWImWqIl6QNWYDJ9AGSBbgheS0CdqPwVnVipFbart5gusi8JDMYZaxj2kw2Y8kXXQ6WUCgEeMThzSfMWRA==", + "dependencies": { + "@testing-library/react": "11.2.6", + "history": "4.10.1" + }, + "peerDependencies": { + "@edx/frontend-platform": "^4.0.1", + "react": "^16.12.0", + "react-dom": "^16.12.0", + "react-router-dom": "^5.2.0" + } + }, "node_modules/@edx/frontend-component-header/node_modules/@edx/paragon": { "version": "20.32.3", "resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-20.32.3.tgz", @@ -3815,103 +3830,7 @@ "react": ">=16.3" } }, - "node_modules/@edx/frontend-component-header/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@edx/frontend-component-header/node_modules/core-js": { - "version": "3.30.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.30.1.tgz", - "integrity": "sha512-ZNS5nbiSwDTq4hFosEDqm65izl2CWmLz0hARJMyNQBgkUZMIF51cQiMvIQKA6hvuaeWxQDP3hEedM1JZIgTldQ==", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/@edx/frontend-component-header/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@edx/frontend-component-header/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@edx/frontend-component-header/node_modules/react-loading-skeleton": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/react-loading-skeleton/-/react-loading-skeleton-3.3.1.tgz", - "integrity": "sha512-NilqqwMh2v9omN7LteiDloEVpFyMIa0VGqF+ukqp0ncVlYu1sKYbYGX9JEl+GtOT9TKsh04zCHAbavnQ2USldA==", - "peerDependencies": { - "react": ">=16.8.0" - } - }, - "node_modules/@edx/frontend-component-header/node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" - }, - "node_modules/@edx/frontend-enterprise-catalog-search": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@edx/frontend-enterprise-catalog-search/-/frontend-enterprise-catalog-search-4.2.0.tgz", - "integrity": "sha512-rg/kix5IcQZFNaV7v4qCyZQJYm7ilXyjBIbnszY9GaK75crAKcezoRYruS36TNeYLuUo2ri8NwrZ73OxFuInwg==", - "dependencies": { - "@edx/frontend-enterprise-utils": "^3.2.0", - "classnames": "2.2.5", - "lodash.debounce": "4.0.8", - "prop-types": "15.7.2" - }, - "peerDependencies": { - "@edx/frontend-platform": "^4.0.1", - "@edx/paragon": "^19.15.0 || ^20.0.0", - "@fortawesome/free-solid-svg-icons": "^5.8.1", - "@fortawesome/react-fontawesome": "^0.1.4", - "react": "^16.12.0", - "react-dom": "^16.12.0", - "react-instantsearch-dom": "^6.8.3", - "react-router-dom": "^5.2.0" - } - }, - "node_modules/@edx/frontend-enterprise-catalog-search/node_modules/@edx/frontend-enterprise-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@edx/frontend-enterprise-utils/-/frontend-enterprise-utils-3.2.0.tgz", - "integrity": "sha512-3lXRu2QTiOaIF4wljNLjeoUSRFseDnMbw/+/RmK1dAplqvoi632fX9y0lMm0q8Nnr8FP9XyxxAoOYeDQwGIQ+w==", - "dependencies": { - "@testing-library/react": "11.2.6", - "history": "4.10.1" - }, - "peerDependencies": { - "@edx/frontend-platform": "^4.0.1", - "react": "^16.12.0", - "react-dom": "^16.12.0", - "react-router-dom": "^5.2.0" - } - }, - "node_modules/@edx/frontend-enterprise-catalog-search/node_modules/@testing-library/dom": { + "node_modules/@edx/frontend-component-header/node_modules/@testing-library/dom": { "version": "7.31.2", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-7.31.2.tgz", "integrity": "sha512-3UqjCpey6HiTZT92vODYLPxTBWlM8ZOOjr3LX5F37/VRipW2M1kX6I/Cm4VXzteZqfGfagg8yXywpcOgQBlNsQ==", @@ -3929,7 +3848,7 @@ "node": ">=10" } }, - "node_modules/@edx/frontend-enterprise-catalog-search/node_modules/@testing-library/react": { + "node_modules/@edx/frontend-component-header/node_modules/@testing-library/react": { "version": "11.2.6", "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-11.2.6.tgz", "integrity": "sha512-TXMCg0jT8xmuU8BkKMtp8l7Z50Ykew5WNX8UoIKTaLFwKkP2+1YDhOLA2Ga3wY4x29jyntk7EWfum0kjlYiSjQ==", @@ -3945,12 +3864,12 @@ "react-dom": "*" } }, - "node_modules/@edx/frontend-enterprise-catalog-search/node_modules/@types/aria-query": { + "node_modules/@edx/frontend-component-header/node_modules/@types/aria-query": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz", "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==" }, - "node_modules/@edx/frontend-enterprise-catalog-search/node_modules/ansi-styles": { + "node_modules/@edx/frontend-component-header/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", @@ -3964,7 +3883,7 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@edx/frontend-enterprise-catalog-search/node_modules/aria-query": { + "node_modules/@edx/frontend-component-header/node_modules/aria-query": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", @@ -3976,7 +3895,15 @@ "node": ">=6.0" } }, - "node_modules/@edx/frontend-enterprise-catalog-search/node_modules/chalk": { + "node_modules/@edx/frontend-component-header/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", @@ -3991,12 +3918,7 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@edx/frontend-enterprise-catalog-search/node_modules/classnames": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.5.tgz", - "integrity": "sha512-DTt3GhOUDKhh4ONwIJW4lmhyotQmV2LjNlGK/J2hkwUcqcbKkCLAdJPtxQnxnlc7SR3f1CEXCyMmc7WLUsWbNA==" - }, - "node_modules/@edx/frontend-enterprise-catalog-search/node_modules/color-convert": { + "node_modules/@edx/frontend-component-header/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", @@ -4007,12 +3929,40 @@ "node": ">=7.0.0" } }, - "node_modules/@edx/frontend-enterprise-catalog-search/node_modules/color-name": { + "node_modules/@edx/frontend-component-header/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "node_modules/@edx/frontend-enterprise-catalog-search/node_modules/has-flag": { + "node_modules/@edx/frontend-component-header/node_modules/core-js": { + "version": "3.30.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.30.1.tgz", + "integrity": "sha512-ZNS5nbiSwDTq4hFosEDqm65izl2CWmLz0hARJMyNQBgkUZMIF51cQiMvIQKA6hvuaeWxQDP3hEedM1JZIgTldQ==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", @@ -4020,7 +3970,7 @@ "node": ">=8" } }, - "node_modules/@edx/frontend-enterprise-catalog-search/node_modules/history": { + "node_modules/@edx/frontend-component-header/node_modules/history": { "version": "4.10.1", "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", @@ -4033,7 +3983,18 @@ "value-equal": "^1.0.1" } }, - "node_modules/@edx/frontend-enterprise-catalog-search/node_modules/pretty-format": { + "node_modules/@edx/frontend-component-header/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/pretty-format": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", @@ -4047,10 +4008,55 @@ "node": ">= 10" } }, - "node_modules/@edx/frontend-enterprise-catalog-search/node_modules/pretty-format/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + "node_modules/@edx/frontend-component-header/node_modules/react-loading-skeleton": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/react-loading-skeleton/-/react-loading-skeleton-3.3.1.tgz", + "integrity": "sha512-NilqqwMh2v9omN7LteiDloEVpFyMIa0VGqF+ukqp0ncVlYu1sKYbYGX9JEl+GtOT9TKsh04zCHAbavnQ2USldA==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, + "node_modules/@edx/frontend-component-header/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@edx/frontend-enterprise-catalog-search": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@edx/frontend-enterprise-catalog-search/-/frontend-enterprise-catalog-search-4.2.0.tgz", + "integrity": "sha512-rg/kix5IcQZFNaV7v4qCyZQJYm7ilXyjBIbnszY9GaK75crAKcezoRYruS36TNeYLuUo2ri8NwrZ73OxFuInwg==", + "dependencies": { + "@edx/frontend-enterprise-utils": "^3.2.0", + "classnames": "2.2.5", + "lodash.debounce": "4.0.8", + "prop-types": "15.7.2" + }, + "peerDependencies": { + "@edx/frontend-platform": "^4.0.1", + "@edx/paragon": "^19.15.0 || ^20.0.0", + "@fortawesome/free-solid-svg-icons": "^5.8.1", + "@fortawesome/react-fontawesome": "^0.1.4", + "react": "^16.12.0", + "react-dom": "^16.12.0", + "react-instantsearch-dom": "^6.8.3", + "react-router-dom": "^5.2.0" + } + }, + "node_modules/@edx/frontend-enterprise-catalog-search/node_modules/classnames": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.5.tgz", + "integrity": "sha512-DTt3GhOUDKhh4ONwIJW4lmhyotQmV2LjNlGK/J2hkwUcqcbKkCLAdJPtxQnxnlc7SR3f1CEXCyMmc7WLUsWbNA==" }, "node_modules/@edx/frontend-enterprise-catalog-search/node_modules/prop-types": { "version": "15.7.2", @@ -4067,17 +4073,6 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, - "node_modules/@edx/frontend-enterprise-catalog-search/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@edx/frontend-enterprise-hotjar": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@edx/frontend-enterprise-hotjar/-/frontend-enterprise-hotjar-1.3.0.tgz", @@ -4089,9 +4084,9 @@ } }, "node_modules/@edx/frontend-enterprise-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@edx/frontend-enterprise-utils/-/frontend-enterprise-utils-3.0.0.tgz", - "integrity": "sha512-O9yoHWImWqIl6QNWYDJ9AGSBbgheS0CdqPwVnVipFbart5gusi8JDMYZaxj2kw2Y8kXXQ6WUCgEeMThzSfMWRA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@edx/frontend-enterprise-utils/-/frontend-enterprise-utils-3.2.0.tgz", + "integrity": "sha512-3lXRu2QTiOaIF4wljNLjeoUSRFseDnMbw/+/RmK1dAplqvoi632fX9y0lMm0q8Nnr8FP9XyxxAoOYeDQwGIQ+w==", "dependencies": { "@testing-library/react": "11.2.6", "history": "4.10.1" @@ -24496,23 +24491,6 @@ "node": ">=0.6" } }, - "node_modules/query-string": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz", - "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==", - "dependencies": { - "decode-uri-component": "^0.2.2", - "filter-obj": "^1.1.0", - "split-on-first": "^1.0.0", - "strict-uri-encode": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", diff --git a/package.json b/package.json index 383259b0..ddc73c2d 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "@edx/frontend-component-header": "npm:@edx/frontend-component-header-edx@^7.0.0", "@edx/frontend-enterprise-catalog-search": "^4.2.0", "@edx/frontend-enterprise-hotjar": "^1.3.0", + "@edx/frontend-enterprise-utils": "^3.2.0", "@edx/frontend-platform": "^4.0.1", "@edx/paragon": "20.29.0", "@fortawesome/fontawesome-svg-core": "1.2.35", @@ -56,7 +57,6 @@ "lodash.escaperegexp": "4.1.2", "npm": "^8.19.3", "prop-types": "15.8.1", - "query-string": "7.1.3", "react": "^16.14.0", "react-dom": "^16.14.0", "react-helmet": "6.1.0", diff --git a/src/components/catalogSearchResults/CatalogSearchResults.jsx b/src/components/catalogSearchResults/CatalogSearchResults.jsx index 084bff94..3215b59d 100644 --- a/src/components/catalogSearchResults/CatalogSearchResults.jsx +++ b/src/components/catalogSearchResults/CatalogSearchResults.jsx @@ -13,7 +13,6 @@ import { Alert, Badge, Button, CardView, DataTable, } from '@edx/paragon'; import PropTypes from 'prop-types'; -import queryString from 'query-string'; import React, { useCallback, useContext, @@ -322,7 +321,7 @@ export const BaseCatalogSearchResults = ({ () => searchResults?.hits || [], [searchResults?.hits], ); - const query = queryString.parse(window.location.search.substring(1)); + const query = new URLSearchParams(window.location.search.substring(1)); const toggleOptions = preview ? {} : { diff --git a/src/components/catalogSearchResults/associatedComponents/downloadCsvButton/DownloadCsvButton.test.jsx b/src/components/catalogSearchResults/associatedComponents/downloadCsvButton/DownloadCsvButton.test.jsx index c643e131..b3932489 100644 --- a/src/components/catalogSearchResults/associatedComponents/downloadCsvButton/DownloadCsvButton.test.jsx +++ b/src/components/catalogSearchResults/associatedComponents/downloadCsvButton/DownloadCsvButton.test.jsx @@ -65,7 +65,7 @@ describe('Download button', () => { // The query, query param should not have an `&` in it. // TODO: figure out why the process env for catalog base service can't be set in the test const expectedWindowLocation = 'undefined/api/v1/enterprise-catalogs/catalog_workbook?availability=Available' - + '%20Now&availability=Upcoming&query=math%20%26%20science'; + + '+Now&availability=Upcoming&query=math%20%26%20science'; expect(window.location.href).toEqual(expectedWindowLocation); }); }); diff --git a/src/config/index.js b/src/config/index.js index b13aebc9..940dd2c3 100644 --- a/src/config/index.js +++ b/src/config/index.js @@ -1,15 +1,10 @@ -import qs from 'query-string'; +import { hasFeatureFlagEnabled } from '@edx/frontend-enterprise-utils'; import { FEATURE_ENABLE_PROGRAMS, FEATURE_EXEC_ED_INCLUSION, FEATURE_PROGRAM_TYPE_FACET, } from './constants'; -const hasFeatureFlagEnabled = (featureFlag) => { - const { features } = qs.parse(window.location.search); - return features && features.split(',').includes(featureFlag); -}; - const features = { ENABLE_PROGRAMS: process.env.FEATURE_ENABLE_PROGRAMS === 'true' diff --git a/src/data/services/EnterpriseCatalogAPIService.js b/src/data/services/EnterpriseCatalogAPIService.js index 7676d0d1..6ffa5898 100644 --- a/src/data/services/EnterpriseCatalogAPIService.js +++ b/src/data/services/EnterpriseCatalogAPIService.js @@ -1,6 +1,5 @@ -import qs from 'query-string'; - import { getHttpClient } from '@edx/frontend-platform/auth'; +import { createQueryParams } from '../../utils/catalogUtils'; class EnterpriseCatalogApiService { static enterpriseCatalogServiceApiUrl = `${process.env.CATALOG_SERVICE_BASE_URL}/api/v1/enterprise-catalogs`; @@ -9,16 +8,18 @@ class EnterpriseCatalogApiService { static generateCsvDownloadLink(options, query) { const facetQuery = query ? `&query=${encodeURIComponent(query)}` : ''; + const queryParams = createQueryParams(options); const enterpriseListUrl = `${ EnterpriseCatalogApiService.enterpriseCatalogServiceApiUrl - }/catalog_workbook?${qs.stringify(options)}${facetQuery}`; + }/catalog_workbook?${queryParams}${facetQuery}`; return enterpriseListUrl; } static fetchDefaultCoursesInCatalog(options) { + const queryParams = new URLSearchParams(options); const enterpriseListUrl = `${ EnterpriseCatalogApiService.enterpriseCatalogServiceApiUrl - }/default_course_set?${qs.stringify(options)}`; + }/default_course_set?${queryParams.toString()}`; return EnterpriseCatalogApiService.apiClient().get(enterpriseListUrl); } diff --git a/src/utils/catalogUtils.js b/src/utils/catalogUtils.js index 128a5144..dd12336a 100644 --- a/src/utils/catalogUtils.js +++ b/src/utils/catalogUtils.js @@ -45,4 +45,29 @@ function convertLearningTypesToFilters(types) { }, []).join(' OR '); } -export { checkAvailability, checkSubscriptions, convertLearningTypesToFilters }; +/** + * Parses an object that accounts for keys with values that is an array. + * e.g. {'availability': ['Available Now', 'Starting Soon']} will be parsed as + * 'availability=Available+Now&availability=Starting+Soon' + * + * @param Object query parameter with an array of values. + * @returns A string containing a query string suitable for use in a URL. + */ + +function createQueryParams(options) { + const queryParams = new URLSearchParams(); + Object.entries(options).forEach(([key, value]) => { + if (Array.isArray(value)) { + value.forEach((item) => { + queryParams.append(key, item); + }); + return; + } + queryParams.set(key, value); + }); + return queryParams.toString(); +} + +export { + checkAvailability, checkSubscriptions, convertLearningTypesToFilters, createQueryParams, +}; diff --git a/src/utils/catalogUtils.test.js b/src/utils/catalogUtils.test.js index 91b29975..d62ef248 100644 --- a/src/utils/catalogUtils.test.js +++ b/src/utils/catalogUtils.test.js @@ -1,9 +1,24 @@ import { EXEC_ED_TITLE } from '../constants'; -import { convertLearningTypesToFilters } from './catalogUtils'; +import { convertLearningTypesToFilters, createQueryParams } from './catalogUtils'; describe('catalogUtils', () => { it('converts lists of learning types to algolia filters', () => { const algoliaFilter = convertLearningTypesToFilters(['a', 'b', EXEC_ED_TITLE]); expect(algoliaFilter).toEqual('a OR b OR "Executive Education"'); }); + + it('parses an object with an array of values and returns query string', () => { + const options = { + enterprise_catalog_query_titles: [ + 'A la carte', + ], + availability: [ + 'Available Now', + 'Starting Soon', + ], + }; + const expectedQueryParams = 'enterprise_catalog_query_titles=A+la+carte&availability=Available+Now&availability=Starting+Soon'; + const queryParams = createQueryParams(options); + expect(queryParams).toEqual(expectedQueryParams); + }); });