From 5558273908a46bfabe42a49b6cb82aa6b6c4a566 Mon Sep 17 00:00:00 2001 From: Peter Hudec Date: Thu, 18 Apr 2024 13:25:10 +0100 Subject: [PATCH] Removed all occurences of qs.parse --- .../ActivityFeed/CollectionList/state.js | 5 +- .../index.jsx | 3 +- .../CollectionList/CollectionSort.jsx | 6 +- .../index.jsx | 3 +- src/client/components/ContactForm/index.jsx | 7 +-- .../Dashboard/my-tasks/TaskListSelect.jsx | 4 +- src/client/components/FilterReset/index.jsx | 5 +- .../FilteredCollectionList/index.jsx | 3 +- src/client/components/Form/index.jsx | 4 +- .../Pagination/RoutedPagination.jsx | 4 +- src/client/components/Resource/Paginated.js | 3 +- .../RoutedCheckboxGroupField/index.jsx | 3 +- .../components/RoutedDateField/index.jsx | 3 +- .../RoutedDownloadDataHeader/index.jsx | 3 +- .../components/RoutedFilterChips/index.jsx | 3 +- src/client/components/RoutedInput/index.jsx | 5 +- src/client/components/RoutedSelect/index.jsx | 3 +- .../components/RoutedTypeahead/index.jsx | 62 +++++++++---------- .../modules/Companies/CollectionList/state.js | 5 +- .../LinkGlobalHQ/state.js | 5 +- .../LinkSubsidiary/state.js | 5 +- .../CompanyOverview/TableCards/state.js | 8 +-- .../modules/Contacts/CollectionList/state.js | 17 +---- .../modules/Contacts/ContactActivity/state.js | 6 +- .../modules/Events/AttendeeSearch/state.js | 15 +---- .../modules/Events/CollectionList/state.js | 5 +- .../EventAventriRegistrationStatus/index.jsx | 9 +-- .../EventAventriRegistrationStatus/state.js | 13 ++-- .../ExportList/ExportSelect.jsx | 6 +- .../Interactions/CollectionList/state.js | 5 +- .../Opportunities/CollectionList/state.js | 5 +- .../Opportunities/OpportunityInteractions.jsx | 4 +- .../Profiles/ProfilesCollection.jsx | 4 +- .../modules/Investments/Profiles/state.js | 5 +- .../Details/EditAssociatedProject/state.js | 6 +- .../Details/EditRecipientCompany/state.js | 5 +- .../Projects/ProjectInteractions.jsx | 4 +- .../Projects/ProjectPropositions.jsx | 4 +- .../Investments/Projects/ProjectTasks.jsx | 6 +- .../modules/Investments/Projects/state.js | 6 +- .../modules/Omis/CollectionList/state.js | 11 ++-- .../Omis/CreateOrder/CompanySelect/state.js | 5 +- ...InvestmentsOutstandingPropositionsList.jsx | 5 +- .../modules/Reminders/RemindersLists.jsx | 5 +- .../Reminders/Settings/RemindersSettings.jsx | 5 +- src/client/modules/Tasks/TaskDetails/state.js | 5 +- .../modules/Tasks/TaskForm/TaskFormAdd.jsx | 8 +-- src/client/utils/index.js | 11 +--- src/client/utils/url.js | 18 ++++-- 49 files changed, 152 insertions(+), 198 deletions(-) diff --git a/src/client/components/ActivityFeed/CollectionList/state.js b/src/client/components/ActivityFeed/CollectionList/state.js index 9da289bb619..7a85e6d3362 100644 --- a/src/client/components/ActivityFeed/CollectionList/state.js +++ b/src/client/components/ActivityFeed/CollectionList/state.js @@ -1,7 +1,7 @@ import { buildSelectedFilters } from './filters' import { SORT_OPTIONS } from './constants' import { transformWasPolicyfeedBackProvidedToApi } from './transformers' -import { parseQueryString } from '../../../utils' +import { locationToQSParamsWithPage } from '../../../utils/url' export const TASK_GET_COMPANY_ACTIVITIES_LIST = 'TASK_GET_COMPANY_ACTIVITIES_LIST' @@ -26,8 +26,7 @@ export const TASK_GET_INTERACTIONS_COMPANY_NAME = export const ID = 'companyActivitiesList' export const state2props = ({ router, ...state }) => { - const queryString = router.location.search.slice(1) - const queryParams = parseQueryString(queryString) + const queryParams = locationToQSParamsWithPage(router.location) const { currentAdviserId } = state const { metadata, selectedAdvisers, selectedCompanies, createdByOthers } = state[ID] diff --git a/src/client/components/ActivityFeedFilteredCollectionList/index.jsx b/src/client/components/ActivityFeedFilteredCollectionList/index.jsx index 697c1509b04..eafddba2bc4 100644 --- a/src/client/components/ActivityFeedFilteredCollectionList/index.jsx +++ b/src/client/components/ActivityFeedFilteredCollectionList/index.jsx @@ -8,6 +8,7 @@ import { GridRow, GridCol } from 'govuk-react' import { isEmpty } from 'lodash' import qs from 'qs' +import { getQueryParamsFromLocation } from '../../utils/url' import Task from '../Task' import CollectionSort from '../CollectionList/CollectionSort' @@ -34,7 +35,7 @@ const ActivityFeedFilteredCollectionList = ({ return ( {({ history, location }) => { - const qsParams = qs.parse(location.search.slice(1)) + const qsParams = getQueryParamsFromLocation(location) const initialPage = parseInt(qsParams.page, 10) if (defaultQueryParams && isEmpty(qsParams)) { history.push({ diff --git a/src/client/components/CollectionList/CollectionSort.jsx b/src/client/components/CollectionList/CollectionSort.jsx index ff8f894d485..9b70797b0ed 100644 --- a/src/client/components/CollectionList/CollectionSort.jsx +++ b/src/client/components/CollectionList/CollectionSort.jsx @@ -1,9 +1,9 @@ import React from 'react' import PropTypes from 'prop-types' import { Route } from 'react-router-dom' -import qs from 'qs' import styled from 'styled-components' +import { getQueryParamsFromLocation } from '../../utils/url' import { DARK_GREY } from '../../utils/colours' import CollectionHeaderRow from './CollectionHeaderRow' import RoutedSelect from '../RoutedSelect' @@ -33,8 +33,8 @@ const CollectionSort = ({ sortOptions, totalPages, ...props }) => { return ( - {({ location: { search } }) => { - const searchParams = qs.parse(search.slice(1)) + {({ location }) => { + const searchParams = getQueryParamsFromLocation(location) return ( Page {searchParams.page || 1} of {totalPages} diff --git a/src/client/components/CompanyActivityFeedFilteredCollectionList/index.jsx b/src/client/components/CompanyActivityFeedFilteredCollectionList/index.jsx index 9706f2e4ba5..98c8cc1730b 100644 --- a/src/client/components/CompanyActivityFeedFilteredCollectionList/index.jsx +++ b/src/client/components/CompanyActivityFeedFilteredCollectionList/index.jsx @@ -8,6 +8,7 @@ import { GridRow, GridCol } from 'govuk-react' import { isEmpty } from 'lodash' import qs from 'qs' +import { getQueryParamsFromLocation } from '../../utils/url' import Task from '../Task' import CollectionSort from '../CollectionList/CollectionSort' @@ -34,7 +35,7 @@ const CompanyActivityFeedFilteredCollectionList = ({ return ( {({ history, location }) => { - const qsParams = qs.parse(location.search.slice(1)) + const qsParams = getQueryParamsFromLocation(location) const initialPage = parseInt(qsParams.page, 10) if (defaultQueryParams && isEmpty(qsParams)) { history.push({ diff --git a/src/client/components/ContactForm/index.jsx b/src/client/components/ContactForm/index.jsx index 3149a97e34b..383451b4a3d 100644 --- a/src/client/components/ContactForm/index.jsx +++ b/src/client/components/ContactForm/index.jsx @@ -1,4 +1,3 @@ -import qs from 'qs' import React, { useEffect } from 'react' import PropTypes from 'prop-types' import _ from 'lodash' @@ -9,6 +8,7 @@ import Label from '@govuk-react/label' import multiInstance from '../../utils/multiinstance' import { CONTACT_FORM__SUBMIT } from '../../actions' +import { getQueryParamsFromLocation } from '../../utils/url' import Form from '../Form' import { @@ -153,9 +153,8 @@ const _ContactForm = ({
{({ referrerUrl, router }) => { - const { origin_url, origin_search } = qs.parse( - router.location.search - ) + const { origin_url, origin_search } = + getQueryParamsFromLocation(router.location) const redirectTo = ({ name, id }) => { return origin_url ? appendParamsToUrl(origin_url, origin_search, id, name) diff --git a/src/client/components/Dashboard/my-tasks/TaskListSelect.jsx b/src/client/components/Dashboard/my-tasks/TaskListSelect.jsx index b7d5f5ebdd1..927b222174f 100644 --- a/src/client/components/Dashboard/my-tasks/TaskListSelect.jsx +++ b/src/client/components/Dashboard/my-tasks/TaskListSelect.jsx @@ -6,6 +6,8 @@ import { get, kebabCase } from 'lodash' import qs from 'qs' import { FONT_SIZE, FONT_WEIGHTS } from '@govuk-react/constants' +import { getQueryParamsFromLocation } from '../../../utils/url' + const StyledSelect = styled(Select)({ select: { width: '100%', @@ -21,7 +23,7 @@ const TaskSelect = ({ label, options = [], qsParam }) => { const location = useLocation() const [value, setValue] = useState() - const qsParams = qs.parse(location.search.slice(1)) + const qsParams = getQueryParamsFromLocation(location) const initialValue = get(qsParams, qsParam, '') useEffect(() => setValue(initialValue), [initialValue]) diff --git a/src/client/components/FilterReset/index.jsx b/src/client/components/FilterReset/index.jsx index f7c45ff2653..cd591ade8ea 100644 --- a/src/client/components/FilterReset/index.jsx +++ b/src/client/components/FilterReset/index.jsx @@ -4,7 +4,8 @@ import PropTypes from 'prop-types' import styled from 'styled-components' import { FONT_SIZE } from '@govuk-react/constants' import { isEmpty } from 'lodash' -import qs from 'qs' + +import { parseQueryString } from '../../utils/url' const StyledButtonLink = styled(ButtonLink)` font-size: ${FONT_SIZE.SIZE_16}; @@ -15,7 +16,7 @@ import { ButtonLink } from '../../components' const FilterReset = ({ children, ...props }) => ( {({ history, location: { pathname, search } }) => { - const { sortby, page, ...filters } = qs.parse(search.slice(1)) + const { sortby, page, ...filters } = parseQueryString(search) return ( !isEmpty(filters) && ( { if (defaultQueryParams && isEmpty(qsParams)) { diff --git a/src/client/components/Form/index.jsx b/src/client/components/Form/index.jsx index 69e802d0106..cd6e09ff5e5 100644 --- a/src/client/components/Form/index.jsx +++ b/src/client/components/Form/index.jsx @@ -6,6 +6,7 @@ import qs from 'qs' import Button from '@govuk-react/button' import Link from '@govuk-react/link' +import { getQueryParamsFromLocation } from '../../utils/url' import multiInstance from '../../utils/multiinstance' import ErrorSummary from '../ErrorSummary' import Task from '../Task' @@ -86,8 +87,7 @@ const _Form = ({ ...props }) => { const history = useHistory() - const location = useLocation() - const qsParams = qs.parse(location.search.slice(1)) + const qsParams = getQueryParamsFromLocation(useLocation()) useEffect(() => { onLoad(initialValues, initialStepIndex) diff --git a/src/client/components/Pagination/RoutedPagination.jsx b/src/client/components/Pagination/RoutedPagination.jsx index 44677cd02a3..27c8d7c588f 100644 --- a/src/client/components/Pagination/RoutedPagination.jsx +++ b/src/client/components/Pagination/RoutedPagination.jsx @@ -6,6 +6,7 @@ import qs from 'qs' import { FONT_SIZE, MEDIA_QUERIES, SPACING } from '@govuk-react/constants' import Link from '@govuk-react/link' +import { getQueryParamsFromLocation } from '../../utils/url' import { GREY_3, LINK_COLOUR, WHITE } from '../../../client/utils/colours' import { PAGINATION_PIECE_PREVIOUS, PAGINATION_PIECE_NEXT } from './constants' @@ -183,13 +184,12 @@ const Pagination = ({ return ( {({ history, location }) => { - const qsParams = qs.parse(location.search.slice(1)) const handleOnClick = (pageNumber, e) => { e.preventDefault() setPage(pageNumber) history.push({ search: qs.stringify({ - ...qsParams, + ...getQueryParamsFromLocation(location), page: pageNumber, }), }) diff --git a/src/client/components/Resource/Paginated.js b/src/client/components/Resource/Paginated.js index 8d1e548d30b..d2a2e6f0a83 100644 --- a/src/client/components/Resource/Paginated.js +++ b/src/client/components/Resource/Paginated.js @@ -5,6 +5,7 @@ import qs from 'qs' import styled from 'styled-components' +import { getQueryParamsFromLocation } from '../../utils/url' import multiInstance from '../../utils/multiinstance' import Task from '../Task' import LoadingBox from '../Task/LoadingBox' @@ -94,7 +95,7 @@ const PaginatedResource = multiInstance({ }) => ( {({ location }) => { - const qsParams = qs.parse(location.search.slice(1)) + const qsParams = getQueryParamsFromLocation(location) const routePage = parseInt(qsParams.page, 10) || 1 const totalPages = result ? Math.ceil(result.count / pageSize) : 0 const hasZeroResults = result?.count === 0 diff --git a/src/client/components/RoutedCheckboxGroupField/index.jsx b/src/client/components/RoutedCheckboxGroupField/index.jsx index 183f79ddd91..647756638be 100644 --- a/src/client/components/RoutedCheckboxGroupField/index.jsx +++ b/src/client/components/RoutedCheckboxGroupField/index.jsx @@ -3,6 +3,7 @@ import PropTypes from 'prop-types' import { Route } from 'react-router-dom' import qs from 'qs' +import { getQueryParamsFromLocation } from '../../utils/url' import CheckboxGroupField from '../CheckboxGroupField' const RoutedCheckboxGroupField = ({ qsParam, ...props }) => { @@ -14,7 +15,7 @@ const RoutedCheckboxGroupField = ({ qsParam, ...props }) => { return ( {({ history, location }) => { - const qsParams = qs.parse(location.search.slice(1)) + const qsParams = getQueryParamsFromLocation(location) return ( ( {({ location, history }) => { - const qsParams = qs.parse(location.search.slice(1)) + const qsParams = getQueryParamsFromLocation(location) return ( ['true', 'false'].includes(value) @@ -30,7 +31,7 @@ const getQueryStringFromQueryParams = (params) => { } const getDownloadLinkFromLocation = (location, baseDownloadLink) => { - const { page, ...queryParams } = qs.parse(location.search.slice(1)) + const { page, ...queryParams } = getQueryParamsFromLocation(location) const queryString = getQueryStringFromQueryParams(queryParams) return queryString ? `${baseDownloadLink}?${queryString}` : baseDownloadLink } diff --git a/src/client/components/RoutedFilterChips/index.jsx b/src/client/components/RoutedFilterChips/index.jsx index 2c70f412328..bab89e1c6d2 100644 --- a/src/client/components/RoutedFilterChips/index.jsx +++ b/src/client/components/RoutedFilterChips/index.jsx @@ -4,6 +4,7 @@ import qs from 'qs' import { Route } from 'react-router-dom' import { omit } from 'lodash' +import { getQueryParamsFromLocation } from '../../utils/url' import { Chip } from '..' /** @@ -33,7 +34,7 @@ const RoutedFilterChips = ({ qsParamName, selectedOptions = [], ...props }) => ( {({ location, history }) => { const clearFilter = (value) => { - const qsParams = qs.parse(location.search.slice(1)) + const qsParams = getQueryParamsFromLocation(location) const newQsParams = removeParamFromQs(qsParams, qsParamName, value) history.push({ search: qs.stringify(newQsParams) }) } diff --git a/src/client/components/RoutedInput/index.jsx b/src/client/components/RoutedInput/index.jsx index 3b0557b153c..d0b19a2ec9f 100644 --- a/src/client/components/RoutedInput/index.jsx +++ b/src/client/components/RoutedInput/index.jsx @@ -4,6 +4,7 @@ import PropTypes from 'prop-types' import qs from 'qs' import { Route } from 'react-router-dom' +import { getQueryParamsFromLocation } from '../../utils/url' import multiInstance from '../../utils/multiinstance' import { useTextCaretPosition } from './useTextCaretPosition' import { @@ -40,7 +41,7 @@ const RoutedInput = ({ return ( {({ history, location }) => { - const qsParams = qs.parse(location.search.slice(1)) + const qsParams = getQueryParamsFromLocation(location) const writeQs = () => history.replace({ search: qs.stringify({ @@ -99,7 +100,7 @@ export default multiInstance({ }), }), componentStateToProps: (cs, { router }, { qsParam }) => { - const qsValue = qs.parse(router.location.search.slice(1))[qsParam] + const qsValue = getQueryParamsFromLocation(router.location)[qsParam] return { ...cs, qsValue } }, reducer: (state, { type, value, selectedValue }) => { diff --git a/src/client/components/RoutedSelect/index.jsx b/src/client/components/RoutedSelect/index.jsx index 262f66d786f..1b57624fe88 100644 --- a/src/client/components/RoutedSelect/index.jsx +++ b/src/client/components/RoutedSelect/index.jsx @@ -3,12 +3,13 @@ import { Route } from 'react-router-dom' import qs from 'qs' import { get } from 'lodash' +import { getQueryParamsFromLocation } from '../../utils/url' import Select from '../Select' const RoutedSelect = ({ qsParamName, ...props }) => ( {({ location, history }) => { - const qsParams = qs.parse(location.search.slice(1)) + const qsParams = getQueryParamsFromLocation(location) const initialValue = get(qsParams, qsParamName, '') const onChange = (e) => { history.push({ diff --git a/src/client/components/RoutedTypeahead/index.jsx b/src/client/components/RoutedTypeahead/index.jsx index 9321a331cbc..2309621bb9c 100644 --- a/src/client/components/RoutedTypeahead/index.jsx +++ b/src/client/components/RoutedTypeahead/index.jsx @@ -6,6 +6,7 @@ import styled from 'styled-components' import { FONT_WEIGHTS, LINE_HEIGHT } from '@govuk-react/constants' +import { getQueryParamsFromLocation } from '../../utils/url' import FieldWrapper from '../Form/elements/FieldWrapper' import Typeahead from '../Typeahead' @@ -40,38 +41,35 @@ const RoutedTypeahead = ({ ...props }) => ( - {({ history, location }) => { - const qsParams = qs.parse(location.search.slice(1)) - return ( - - ({ - value, - label, - }))} - loadOptions={loadOptions} - noOptionsMessage={noOptionsMessage} - onChange={(pickedOptions) => { - history.push({ - search: qs.stringify({ - ...qsParams, - ...(!labelAsQueryParam - ? getParamIds(qsParam, pickedOptions) - : getParamLabels(qsParam, pickedOptions)), - page: 1, - }), - }) - }} - /> - - ) - }} + {({ history, location }) => ( + + ({ + value, + label, + }))} + loadOptions={loadOptions} + noOptionsMessage={noOptionsMessage} + onChange={(pickedOptions) => { + history.push({ + search: qs.stringify({ + ...getQueryParamsFromLocation(location), + ...(!labelAsQueryParam + ? getParamIds(qsParam, pickedOptions) + : getParamLabels(qsParam, pickedOptions)), + page: 1, + }), + }) + }} + /> + + )} ) diff --git a/src/client/modules/Companies/CollectionList/state.js b/src/client/modules/Companies/CollectionList/state.js index 01958871bdd..9949239aeba 100644 --- a/src/client/modules/Companies/CollectionList/state.js +++ b/src/client/modules/Companies/CollectionList/state.js @@ -1,7 +1,7 @@ import { buildSelectedFilters } from './filters' import { COMPANY_STATUS_OPTIONS, SORT_OPTIONS } from './constants' import { transformArchivedToApi, transformPostcodeToApi } from './transformers' -import { parseQueryString } from '../../../utils' +import { locationToQSParamsWithPage } from '../../../utils/url' export const TASK_GET_COMPANIES_LIST = 'TASK_GET_COMPANIES_LIST' export const TASK_GET_COMPANIES_METADATA = 'TASK_GET_COMPANIES_METADATA' @@ -14,8 +14,7 @@ export const ID = 'companiesList' * Convert both location and redux state to props */ export const state2props = ({ router, ...state }) => { - const queryString = router.location.search.slice(1) - const queryParams = parseQueryString(queryString) + const queryParams = locationToQSParamsWithPage(router.location) const archived = transformArchivedToApi(queryParams.archived) const ukPostcode = transformPostcodeToApi(queryParams.uk_postcode) diff --git a/src/client/modules/Companies/CompanyBusinessDetails/LinkGlobalHQ/state.js b/src/client/modules/Companies/CompanyBusinessDetails/LinkGlobalHQ/state.js index 4440ad77e6f..3194c81892d 100644 --- a/src/client/modules/Companies/CompanyBusinessDetails/LinkGlobalHQ/state.js +++ b/src/client/modules/Companies/CompanyBusinessDetails/LinkGlobalHQ/state.js @@ -1,7 +1,7 @@ import { transformPostcodeToApi } from '../../CollectionList/transformers' import { buildSelectedFilters } from './filters' import { SORT_OPTIONS } from '../../CollectionList/constants' -import { parseQueryString } from '../../../../utils' +import { locationToQSParamsWithPage } from '../../../../utils/url' export const ID = 'linkGlobalHQ' export const SET_GLOBAL_HQ_ID = 'setGlobalHQ' @@ -12,8 +12,7 @@ export const TASK_SET_GLOBAL_HQ = 'TASK_SET_GLOBAL_HQ' export const TASK_REMOVE_GLOBAL_HQ = 'TASK_REMOVE_GLOBAL_HQ' export const state2props = ({ router, ...state }) => { - const queryString = router.location.search.slice(1) - const queryParams = parseQueryString(queryString) + const queryParams = locationToQSParamsWithPage(router.location) const ukPostcode = transformPostcodeToApi(queryParams.uk_postcode) const { metadata } = state[ID] diff --git a/src/client/modules/Companies/CompanyBusinessDetails/LinkSubsidiary/state.js b/src/client/modules/Companies/CompanyBusinessDetails/LinkSubsidiary/state.js index 8070ebca09c..a5011263f1f 100644 --- a/src/client/modules/Companies/CompanyBusinessDetails/LinkSubsidiary/state.js +++ b/src/client/modules/Companies/CompanyBusinessDetails/LinkSubsidiary/state.js @@ -1,15 +1,14 @@ import { transformPostcodeToApi } from '../../CollectionList/transformers' import { buildSelectedFilters } from './filters' import { SORT_OPTIONS } from '../../CollectionList/constants' -import { parseQueryString } from '../../../../utils' +import { locationToQSParamsWithPage } from '../../../../utils/url' export const ID = 'linkSubsidiary' export const TASK_GET_SUBSIDIARY_LIST = 'TASK_GET_SUBSIDIARY_LIST' export const state2props = ({ router, ...state }) => { - const queryString = router.location.search.slice(1) - const queryParams = parseQueryString(queryString) + const queryParams = locationToQSParamsWithPage(router.location) const ukPostcode = transformPostcodeToApi(queryParams.uk_postcode) const { metadata } = state[ID] diff --git a/src/client/modules/Companies/CompanyOverview/TableCards/state.js b/src/client/modules/Companies/CompanyOverview/TableCards/state.js index 93fadc211b2..0e78862318d 100644 --- a/src/client/modules/Companies/CompanyOverview/TableCards/state.js +++ b/src/client/modules/Companies/CompanyOverview/TableCards/state.js @@ -1,5 +1,5 @@ import { SORT_OPTIONS } from '../../../Contacts/CollectionList/constants' -import { parseQueryString } from '../../../../utils' +import { locationToQSParamsWithPage } from '../../../../utils/url' export const OVERVIEW_COMPANY_PROJECTS_LIST_ID = 'overviewCompanyProjectsList' export const TASK_GET_PROJECT_WON_COUNT = 'TASK_GET_PROJECT_WON_COUNT' @@ -8,8 +8,7 @@ export const OVERVIEW_COMPANY_EXPORT_WINS_LIST_ID = export const TASK_GET_LATEST_EXPORT_WINS = 'TASK_GET_LATEST_EXPORT_WINS' export const companyProjectsState2props = ({ router, ...state }) => { - const queryString = router.location.search.slice(1) - const queryParams = parseQueryString(queryString) + const queryParams = locationToQSParamsWithPage(router.location) return { ...state[OVERVIEW_COMPANY_PROJECTS_LIST_ID], @@ -21,8 +20,7 @@ export const companyProjectsState2props = ({ router, ...state }) => { } export const exportWinsState2props = ({ router, ...state }) => { - const queryString = router.location.search.slice(1) - const queryParams = parseQueryString(queryString) + const queryParams = locationToQSParamsWithPage(router.location) return { ...state[OVERVIEW_COMPANY_EXPORT_WINS_LIST_ID], diff --git a/src/client/modules/Contacts/CollectionList/state.js b/src/client/modules/Contacts/CollectionList/state.js index 3f8e7c6fc98..02555064d98 100644 --- a/src/client/modules/Contacts/CollectionList/state.js +++ b/src/client/modules/Contacts/CollectionList/state.js @@ -1,6 +1,4 @@ -import { omitBy, isEmpty } from 'lodash' -import qs from 'qs' - +import { locationToQSParamsWithPage } from '../../../utils/url' import { buildSelectedFilters } from './filters' import { transformArchivedToApi } from './transformers' import { STATUS_OPTIONS, SORT_OPTIONS } from './constants' @@ -11,17 +9,8 @@ export const COMPANY_CONTACTS_LIST_ID = 'companyContactsList' export const TASK_GET_CONTACTS_LIST = 'TASK_GET_CONTACTS_LIST' export const TASK_GET_CONTACTS_METADATA = 'TASK_GET_CONTACTS_METADATA' -const getQueryParams = (router) => { - const queryString = router.location.search.slice(1) - const queryParams = omitBy({ ...qs.parse(queryString) }, isEmpty) - return { - ...queryParams, - page: parseInt(queryParams.page || 1, 10), - } -} - export const contactsState2props = ({ router, ...state }) => { - const queryParams = getQueryParams(router) + const queryParams = locationToQSParamsWithPage(router.location) const metadata = state[CONTACTS_LIST_ID].metadata const selectedFilters = buildSelectedFilters(queryParams, metadata) const archived = transformArchivedToApi(queryParams.archived) @@ -42,7 +31,7 @@ export const contactsState2props = ({ router, ...state }) => { } export const companyContactsState2props = ({ router, ...state }) => { - const queryParams = getQueryParams(router) + const queryParams = locationToQSParamsWithPage(router.location) const archived = transformArchivedToApi(queryParams.archived) return { diff --git a/src/client/modules/Contacts/ContactActivity/state.js b/src/client/modules/Contacts/ContactActivity/state.js index 74f86837d4c..27e65179d74 100644 --- a/src/client/modules/Contacts/ContactActivity/state.js +++ b/src/client/modules/Contacts/ContactActivity/state.js @@ -1,12 +1,12 @@ -import qs from 'qs' +import { getQueryParamsFromLocation } from '../../../utils/url' export const TASK_GET_CONTACT_ACTIVITIES = 'TASK_GET_CONTACT_ACTIVITIES' export const ID = 'contactActivity' export const state2props = ({ ...state }) => { - const selectedSortBy = qs.parse(location.search.slice(1)).sortby || 'newest' - const page = qs.parse(location.search.slice(1)).page || '1' + const selectedSortBy = getQueryParamsFromLocation(location).sortby || 'newest' + const page = getQueryParamsFromLocation(location).page || '1' return { ...state[ID], diff --git a/src/client/modules/Events/AttendeeSearch/state.js b/src/client/modules/Events/AttendeeSearch/state.js index 48248ea1448..2dc57f55b9b 100644 --- a/src/client/modules/Events/AttendeeSearch/state.js +++ b/src/client/modules/Events/AttendeeSearch/state.js @@ -1,6 +1,4 @@ -import { omitBy, isEmpty } from 'lodash' -import qs from 'qs' - +import { locationToQSParamsWithPage } from '../../../utils/url' import { SORT_OPTIONS } from '../../Contacts/CollectionList/constants' import { buildSelectedFilters } from './filters' @@ -8,17 +6,8 @@ export const TASK_SEARCH_ATTENDEE = 'TASK_SEARCH_ATTENDEE' export const TASK_GET_ATTENDEE_METADATA = 'TASK_GET_ATTENDEE_METADATA' export const SEARCH_ATTENDEE_ID = 'findAttendees' -const getQueryParams = (router) => { - const queryString = router.location.search.slice(1) - const queryParams = omitBy({ ...qs.parse(queryString) }, isEmpty) - return { - ...queryParams, - page: parseInt(queryParams.page || 1, 10), - } -} - export const state2props = ({ router, ...state }) => { - const queryParams = getQueryParams(router) + const queryParams = locationToQSParamsWithPage(router.location) const metadata = state[SEARCH_ATTENDEE_ID].metadata const selectedFilters = buildSelectedFilters(queryParams, metadata) diff --git a/src/client/modules/Events/CollectionList/state.js b/src/client/modules/Events/CollectionList/state.js index 501963e066d..03b7a7998fc 100644 --- a/src/client/modules/Events/CollectionList/state.js +++ b/src/client/modules/Events/CollectionList/state.js @@ -1,6 +1,6 @@ import { buildSelectedFilters } from './filters' import { SORT_OPTIONS } from './constants' -import { parseQueryString } from '../../../utils' +import { locationToQSParamsWithPage } from '../../../utils/url' export const TASK_GET_EVENTS_LIST = 'TASK_GET_EVENTS_LIST' export const TASK_GET_EVENTS_METADATA = 'TASK_GET_EVENTS_METADATA' @@ -14,8 +14,7 @@ export const ID = 'eventsList' * Convert both location and redux state to props */ export const state2props = ({ router, ...state }) => { - const queryString = router.location.search.slice(1) - const queryParams = parseQueryString(queryString) + const queryParams = locationToQSParamsWithPage(router.location) const { metadata, selectedOrganisers } = state[ID] diff --git a/src/client/modules/Events/EventAventriRegistrationStatus/index.jsx b/src/client/modules/Events/EventAventriRegistrationStatus/index.jsx index 8fb1c7008f4..cfe7c7a9ee8 100644 --- a/src/client/modules/Events/EventAventriRegistrationStatus/index.jsx +++ b/src/client/modules/Events/EventAventriRegistrationStatus/index.jsx @@ -1,7 +1,6 @@ import React from 'react' import { connect } from 'react-redux' import { Route } from 'react-router-dom' -import { isEmpty } from 'lodash' import qs from 'qs' import { GridCol, GridRow } from 'govuk-react' @@ -65,13 +64,9 @@ const EventAventriRegistrationStatus = ({ return ( {({ history, location }) => { - const qsParams = qs.parse(location.search.slice(1)) - - if (isEmpty(qsParams)) { + if (!location.search) { history.push({ - search: qs.stringify({ - ...defaultQueryParams, - }), + search: qs.stringify(defaultQueryParams), }) } diff --git a/src/client/modules/Events/EventAventriRegistrationStatus/state.js b/src/client/modules/Events/EventAventriRegistrationStatus/state.js index f27cdf60924..96d5b5d97f2 100644 --- a/src/client/modules/Events/EventAventriRegistrationStatus/state.js +++ b/src/client/modules/Events/EventAventriRegistrationStatus/state.js @@ -1,7 +1,5 @@ -import qs from 'qs' - import { EVENT_ATTENDEES_MAPPING } from '../../../../apps/companies/apps/activity-feed/constants' -import { parseQueryString } from '../../../utils' +import { locationToQSParamsWithPage } from '../../../utils/url' export const TASK_GET_EVENT_AVENTRI_REGISTRATION_STATUS_ATTENDEES = 'TASK_GET_EVENT_AVENTRI_REGISTRATION_STATUS_ATTENDEES' @@ -15,12 +13,9 @@ export const mapUrlSlugToRegistrationStatus = (urlSlug) => { return Array.isArray(status) ? status[0] : null } -export const state2props = (state, router) => { - const { match, location } = router - const queryString = location.search.slice(1) - const queryParams = parseQueryString(queryString) - const selectedSortBy = - qs.parse(location.search.slice(1)).sortby || 'first_name:asc' +export const state2props = (state, { match, location }) => { + const queryParams = locationToQSParamsWithPage(location) + const selectedSortBy = queryParams.sortby || 'first_name:asc' const registrationStatus = mapUrlSlugToRegistrationStatus(match.params.status) diff --git a/src/client/modules/ExportPipeline/ExportList/ExportSelect.jsx b/src/client/modules/ExportPipeline/ExportList/ExportSelect.jsx index 97e3d9f7079..656644362dd 100644 --- a/src/client/modules/ExportPipeline/ExportList/ExportSelect.jsx +++ b/src/client/modules/ExportPipeline/ExportList/ExportSelect.jsx @@ -5,6 +5,8 @@ import styled from 'styled-components' import { get, kebabCase } from 'lodash' import qs from 'qs' +import { getQueryParamsFromLocation } from '../../../utils/url' + const StyledSelect = styled(Select)({ select: { width: '100%', @@ -13,10 +15,8 @@ const StyledSelect = styled(Select)({ const ExportSelect = ({ label, options = [], qsParam }) => { const history = useHistory() - const location = useLocation() const [value, setValue] = useState() - - const qsParams = qs.parse(location.search.slice(1)) + const qsParams = getQueryParamsFromLocation(useLocation()) const initialValue = get(qsParams, qsParam, '') useEffect(() => setValue(initialValue), [initialValue]) diff --git a/src/client/modules/Interactions/CollectionList/state.js b/src/client/modules/Interactions/CollectionList/state.js index be46495c306..366efc0b5b7 100644 --- a/src/client/modules/Interactions/CollectionList/state.js +++ b/src/client/modules/Interactions/CollectionList/state.js @@ -1,7 +1,7 @@ import { buildSelectedFilters } from './filters' import { SORT_OPTIONS } from './constants' import { transformWasPolicyfeedBackProvidedToApi } from './transformers' -import { parseQueryString } from '../../../utils' +import { locationToQSParamsWithPage } from '../../../utils/url' export const TASK_GET_INTERACTIONS_LIST = 'TASK_GET_INTERACTIONS_LIST' export const TASK_GET_INTERACTIONS_ADVISER_NAME = @@ -14,8 +14,7 @@ export const TASK_GET_INTERACTIONS_COMPANY_NAME = export const ID = 'interactionsList' export const state2props = ({ router, ...state }) => { - const queryString = router.location.search.slice(1) - const queryParams = parseQueryString(queryString) + const queryParams = locationToQSParamsWithPage(router.location) const { currentAdviserId } = state const { metadata, selectedAdvisers, selectedTeams, selectedCompanies } = state[ID] diff --git a/src/client/modules/Investments/Opportunities/CollectionList/state.js b/src/client/modules/Investments/Opportunities/CollectionList/state.js index fd946072398..eb3c96af496 100644 --- a/src/client/modules/Investments/Opportunities/CollectionList/state.js +++ b/src/client/modules/Investments/Opportunities/CollectionList/state.js @@ -1,5 +1,4 @@ -import qs from 'qs' - +import { getQueryParamsFromLocation } from '../../../../utils/url' import { sortOptions } from './metadata' export const TASK_GET_OPPORTUNITIES_LIST = 'TASK_GET_OPPORTUNITIES_LIST' @@ -19,7 +18,7 @@ const collectionListPayload = (paramProps) => { export const state2props = ({ router, ...state }) => { const { metadata } = state.opportunitiesList - const queryProps = qs.parse(router.location.search.slice(1)) + const queryProps = getQueryParamsFromLocation(router.location) const filteredQueryProps = collectionListPayload(queryProps) return { diff --git a/src/client/modules/Investments/Opportunities/OpportunityInteractions.jsx b/src/client/modules/Investments/Opportunities/OpportunityInteractions.jsx index 3cb9ad05bdf..659c6073330 100644 --- a/src/client/modules/Investments/Opportunities/OpportunityInteractions.jsx +++ b/src/client/modules/Investments/Opportunities/OpportunityInteractions.jsx @@ -2,14 +2,14 @@ import React from 'react' import { useHistory, useLocation } from 'react-router-dom' import qs from 'qs' +import { getQueryParamsFromLocation } from '../../../utils/url' import { CollectionList } from '../../../components' import { transformInteractionToListItem } from '../../../../apps/interactions/client/transformers' import { InteractionCollectionResource } from '../../../components/Resource' const OpportunityInteractions = ({ opportunityId }) => { const history = useHistory() - const location = useLocation() - const parsedQueryString = qs.parse(location.search.slice(1)) + const parsedQueryString = getQueryParamsFromLocation(useLocation()) const activePage = parseInt(parsedQueryString.page, 10) || 1 return ( ( {({ location }) => { - const qsParams = qs.parse(location.search.slice(1)) + const qsParams = getQueryParamsFromLocation(location) const selectedCountries = resolveSelectedOptions( qsParams[QS_PARAMS.countryOfOrigin], filterOptions.countries diff --git a/src/client/modules/Investments/Profiles/state.js b/src/client/modules/Investments/Profiles/state.js index 1492334aaf1..3adc490124e 100644 --- a/src/client/modules/Investments/Profiles/state.js +++ b/src/client/modules/Investments/Profiles/state.js @@ -1,6 +1,7 @@ -import qs from 'qs' import { omit } from 'lodash' +import { getQueryParamsFromLocation } from '../../../utils/url' + export const TASK_GET_PROFILES_LIST = 'TASK_GET_PROFILES_LIST' export const ID = 'profilesList' @@ -26,5 +27,5 @@ const collectionListPayload = ({ export const state2props = ({ router, ...state }) => ({ ...state[ID], - payload: collectionListPayload(qs.parse(router.location.search.slice(1))), + payload: collectionListPayload(getQueryParamsFromLocation(router.location)), }) diff --git a/src/client/modules/Investments/Projects/Details/EditAssociatedProject/state.js b/src/client/modules/Investments/Projects/Details/EditAssociatedProject/state.js index 06d08a64b7b..a165e9f53c5 100644 --- a/src/client/modules/Investments/Projects/Details/EditAssociatedProject/state.js +++ b/src/client/modules/Investments/Projects/Details/EditAssociatedProject/state.js @@ -1,4 +1,4 @@ -import { parseQueryString } from '../../../../../utils' +import { locationToQSParamsWithPage } from '../../../../../utils/url' import { generateFinancialYearLabel, getFinancialYearStart, @@ -12,9 +12,7 @@ export const TASK_GET_NON_FDI_PROJECTS_LIST = 'TASK_GET_NON_FDI_PROJECTS_LIST' export const NON_FDI_LIST_ID = 'nonFdiProjectsList' export const state2props = ({ router, ...state }) => { - const queryString = router.location.search.slice(1) - - const queryParams = parseQueryString(queryString) + const queryParams = locationToQSParamsWithPage(router.location) const { metadata } = state[NON_FDI_LIST_ID] const financialYearStart = getFinancialYearStart(new Date()) const financialYearOptions = [ diff --git a/src/client/modules/Investments/Projects/Details/EditRecipientCompany/state.js b/src/client/modules/Investments/Projects/Details/EditRecipientCompany/state.js index 353400d1013..faf4065f717 100644 --- a/src/client/modules/Investments/Projects/Details/EditRecipientCompany/state.js +++ b/src/client/modules/Investments/Projects/Details/EditRecipientCompany/state.js @@ -1,4 +1,4 @@ -import { parseQueryString } from '../../../../../utils' +import { locationToQSParamsWithPage } from '../../../../../utils/url' import { transformPostcodeToApi } from '../../../../Companies/CollectionList/transformers' import { COMPANY_STATUS_OPTIONS, @@ -12,8 +12,7 @@ export const TASK_UPDATE_RECIPIENT_COMPANY = 'TASK_UPDATE_RECIPIENT_COMPANY' export const RECIPIENT_COMPANY_LIST_ID = 'recipientCompanyList' export const state2props = ({ router, ...state }) => { - const queryString = router.location.search.slice(1) - const queryParams = parseQueryString(queryString) + const queryParams = locationToQSParamsWithPage(router.location) const ukPostcode = transformPostcodeToApi(queryParams.uk_postcode) const { metadata } = state[RECIPIENT_COMPANY_LIST_ID] diff --git a/src/client/modules/Investments/Projects/ProjectInteractions.jsx b/src/client/modules/Investments/Projects/ProjectInteractions.jsx index 180b582094a..08c1561848d 100644 --- a/src/client/modules/Investments/Projects/ProjectInteractions.jsx +++ b/src/client/modules/Investments/Projects/ProjectInteractions.jsx @@ -4,6 +4,7 @@ import { LEVEL_SIZE } from '@govuk-react/constants' import qs from 'qs' import { useHistory, useLocation, useParams } from 'react-router-dom' +import { getQueryParamsFromLocation } from '../../../utils/url' import { CollectionList } from '../../../components' import { transformInteractionToListItem } from '../../../../apps/interactions/client/transformers' import { InteractionCollectionResource } from '../../../components/Resource' @@ -13,8 +14,7 @@ import ProjectLayoutNew from '../../../components/Layout/ProjectLayoutNew' const ProjectInteractions = () => { const history = useHistory() - const location = useLocation() - const parsedQueryString = qs.parse(location.search.slice(1)) + const parsedQueryString = getQueryParamsFromLocation(useLocation()) const activePage = parseInt(parsedQueryString.page, 10) || 1 const { projectId } = useParams() diff --git a/src/client/modules/Investments/Projects/ProjectPropositions.jsx b/src/client/modules/Investments/Projects/ProjectPropositions.jsx index 0eecfc76c8a..804e1fb1757 100644 --- a/src/client/modules/Investments/Projects/ProjectPropositions.jsx +++ b/src/client/modules/Investments/Projects/ProjectPropositions.jsx @@ -6,6 +6,7 @@ import qs from 'qs' import { get } from 'lodash' import { useHistory, useLocation, useParams } from 'react-router-dom' +import { getQueryParamsFromLocation } from '../../../utils/url' import { CollectionList } from '../../../components' import { PropositionCollectionResource } from '../../../components/Resource' import urls from '../../../../lib/urls' @@ -87,8 +88,7 @@ const ProjectPropositions = ({ completeStatus, }) => { const history = useHistory() - const location = useLocation() - const parsedQueryString = qs.parse(location.search.slice(1)) + const parsedQueryString = getQueryParamsFromLocation(useLocation) const activePage = parseInt(parsedQueryString.page, 10) || 1 const { projectId } = useParams() diff --git a/src/client/modules/Investments/Projects/ProjectTasks.jsx b/src/client/modules/Investments/Projects/ProjectTasks.jsx index 960b4e036d2..996e2c4cb6f 100644 --- a/src/client/modules/Investments/Projects/ProjectTasks.jsx +++ b/src/client/modules/Investments/Projects/ProjectTasks.jsx @@ -1,11 +1,11 @@ import React from 'react' import { H2 } from 'govuk-react' import { LEVEL_SIZE } from '@govuk-react/constants' -import { useParams } from 'react-router-dom' +import { useParams, useLocation } from 'react-router-dom' import { useSearchParam } from 'react-use' import { connect } from 'react-redux' -import qs from 'qs' +import { getQueryParamsFromLocation } from '../../../utils/url' import { CollectionList } from '../../../components' import { InvestmentProjectTasksResource } from '../../../components/Resource' import urls from '../../../../lib/urls' @@ -19,7 +19,7 @@ import ProjectLayoutNew from '../../../components/Layout/ProjectLayoutNew' const ProjectTasks = () => { const { projectId } = useParams() - const parsedQueryString = qs.parse(location.search.slice(1)) + const parsedQueryString = getQueryParamsFromLocation(useLocation()) const activePage = parseInt(useSearchParam('page'), 10) || 1 const getPageUrl = (page) => `${window.location.pathname}?page=${page}` const setActivePage = (page) => diff --git a/src/client/modules/Investments/Projects/state.js b/src/client/modules/Investments/Projects/state.js index 6f7feb07c51..b4023a12521 100644 --- a/src/client/modules/Investments/Projects/state.js +++ b/src/client/modules/Investments/Projects/state.js @@ -2,7 +2,7 @@ import { getFinancialYearStart, generateFinancialYearLabel, } from '../../../utils/date' -import { parseQueryString } from '../../../utils' +import { locationToQSParamsWithPage } from '../../../utils/url' import { buildSelectedFilters } from './filters' import { SORT_OPTIONS, @@ -31,9 +31,7 @@ export const ID = 'propositionComplete' export const TASK_PROPOSITION_COMPLETE = 'TASK_PROPOSITION_COMPLETE' export const state2props = ({ router, ...state }) => { - const queryString = router.location.search.slice(1) - - const queryParams = parseQueryString(queryString) + const queryParams = locationToQSParamsWithPage(router.location) const { metadata, selectedAdvisers, results } = state[INVESTMENT_PROJECTS_ID] const financialYearStart = getFinancialYearStart(new Date()) const financialYearOptions = [ diff --git a/src/client/modules/Omis/CollectionList/state.js b/src/client/modules/Omis/CollectionList/state.js index 3068512d346..0785c1a3555 100644 --- a/src/client/modules/Omis/CollectionList/state.js +++ b/src/client/modules/Omis/CollectionList/state.js @@ -5,7 +5,7 @@ import { STATUSES, RECONCILIATION_STATUSES, } from './constants' -import { parseQueryString } from '../../../utils' +import { locationToQSParamsWithPage } from '../../../utils/url' export const ORDERS_LIST_ID = 'ordersList' export const COMPANY_ORDERS_LIST_ID = 'companyOrdersList' @@ -18,8 +18,7 @@ export const TASK_GET_ORDERS_RECONCILIATION_METADATA = 'TASK_GET_ORDERS_RECONCILIATION_METADATA' export const ordersState2props = ({ router, ...state }) => { - const queryString = router.location.search.slice(1) - const queryParams = parseQueryString(queryString) + const queryParams = locationToQSParamsWithPage(router.location) const { metadata } = state[ORDERS_LIST_ID] const selectedFilters = buildSelectedFilters(queryParams, metadata) return { @@ -35,8 +34,7 @@ export const ordersState2props = ({ router, ...state }) => { } export const companyOrdersState2props = ({ router, ...state }) => { - const queryString = router.location.search.slice(1) - const queryParams = parseQueryString(queryString) + const queryParams = locationToQSParamsWithPage(router.location) return { ...state[COMPANY_ORDERS_LIST_ID], payload: { ...queryParams }, @@ -49,8 +47,7 @@ export const companyOrdersState2props = ({ router, ...state }) => { } export const reconciliationOrdersState2props = ({ router, ...state }) => { - const queryString = router.location.search.slice(1) - const queryParams = parseQueryString(queryString) + const queryParams = locationToQSParamsWithPage(router.location) const { metadata } = state[ORDERS_RECONCILIATION_LIST_ID] const selectedFilters = buildSelectedFilters(queryParams, metadata) return { diff --git a/src/client/modules/Omis/CreateOrder/CompanySelect/state.js b/src/client/modules/Omis/CreateOrder/CompanySelect/state.js index 5b78fd552b3..19061ebf697 100644 --- a/src/client/modules/Omis/CreateOrder/CompanySelect/state.js +++ b/src/client/modules/Omis/CreateOrder/CompanySelect/state.js @@ -1,15 +1,14 @@ import { transformPostcodeToApi } from '../../../Companies/CollectionList/transformers' import { buildSelectedFilters } from './filters' import { SORT_OPTIONS } from '../../../Companies/CollectionList/constants' -import { parseQueryString } from '../../../../utils' +import { locationToQSParamsWithPage } from '../../../../utils/url' export const ID = 'selectOmisCompany' export const TASK_GET_COMPANIES = 'TASK_GET_COMPANIES' export const state2props = ({ router, ...state }) => { - const queryString = router.location.search.slice(1) - const queryParams = parseQueryString(queryString) + const queryParams = locationToQSParamsWithPage(router.location) const ukPostcode = transformPostcodeToApi(queryParams.uk_postcode) const { metadata } = state[ID] diff --git a/src/client/modules/Reminders/InvestmentsOutstandingPropositionsList.jsx b/src/client/modules/Reminders/InvestmentsOutstandingPropositionsList.jsx index fa97efb9f74..3422d90a418 100644 --- a/src/client/modules/Reminders/InvestmentsOutstandingPropositionsList.jsx +++ b/src/client/modules/Reminders/InvestmentsOutstandingPropositionsList.jsx @@ -3,8 +3,8 @@ import { useLocation } from 'react-router-dom' import { connect } from 'react-redux' import { SPACING, FONT_SIZE } from '@govuk-react/constants' import styled from 'styled-components' -import qs from 'qs' +import { getQueryParamsFromLocation } from '../../utils/url' import { BLACK, GREY_1, GREY_2 } from '../../utils/colours' import { REMINDERS__OUTSTANDING_PROPOSITIONS_LOADED } from '../../actions' @@ -32,8 +32,7 @@ const PaginationSummary = styled(Summary)({ const InvestmentsOutstandingPropositionsList = ({ reminders }) => { const { results, count } = reminders - const location = useLocation() - const qsParams = qs.parse(location.search.slice(1)) + const qsParams = getQueryParamsFromLocation(useLocation()) const page = parseInt(qsParams.page, 10) || 1 const totalPages = Math.ceil( Math.min(count, maxItemsToPaginate) / itemsPerPage diff --git a/src/client/modules/Reminders/RemindersLists.jsx b/src/client/modules/Reminders/RemindersLists.jsx index a0e348e2c8c..bc7e455f926 100644 --- a/src/client/modules/Reminders/RemindersLists.jsx +++ b/src/client/modules/Reminders/RemindersLists.jsx @@ -2,8 +2,8 @@ import React from 'react' import { useLocation } from 'react-router-dom' import { SPACING, FONT_SIZE } from '@govuk-react/constants' import styled from 'styled-components' -import qs from 'qs' +import { getQueryParamsFromLocation } from '../../utils/url' import { BLACK } from '../../../client/utils/colours' import { ID } from './state' @@ -35,8 +35,7 @@ const RemindersLists = ({ itemRenderer, }) => { const { results, count, nextPending } = reminders - const location = useLocation() - const qsParams = qs.parse(location.search.slice(1)) + const qsParams = getQueryParamsFromLocation(useLocation()) const page = parseInt(qsParams.page, 10) || 1 const totalPages = Math.ceil( Math.min(count, maxItemsToPaginate) / itemsPerPage diff --git a/src/client/modules/Reminders/Settings/RemindersSettings.jsx b/src/client/modules/Reminders/Settings/RemindersSettings.jsx index c44b63ceb5b..510c3e87217 100644 --- a/src/client/modules/Reminders/Settings/RemindersSettings.jsx +++ b/src/client/modules/Reminders/Settings/RemindersSettings.jsx @@ -4,9 +4,9 @@ import styled from 'styled-components' import { H2 } from '@govuk-react/heading' import { SPACING, LEVEL_SIZE } from '@govuk-react/constants' import { first, get } from 'lodash' -import qs from 'qs' import { connect } from 'react-redux' +import { getQueryParamsFromLocation } from '../../../utils/url' import { DefaultLayout, RemindersToggleSection } from '../../../components' import { RemindersSettingsTable, @@ -270,8 +270,7 @@ export const RemindersSettings = ({ hasInvestmentFeatureGroup, hasExportFeatureGroup, }) => { - const location = useLocation() - const qsParams = qs.parse(location.search.slice(1)) + const qsParams = getQueryParamsFromLocation(useLocation()) const openSettingsSections = getOpenSettings(qsParams) const breadcrumbs = generateBreadcrumbs(openSettingsSections) diff --git a/src/client/modules/Tasks/TaskDetails/state.js b/src/client/modules/Tasks/TaskDetails/state.js index 12c4b7c0987..b348f9e8415 100644 --- a/src/client/modules/Tasks/TaskDetails/state.js +++ b/src/client/modules/Tasks/TaskDetails/state.js @@ -1,7 +1,6 @@ -import qs from 'qs' - import { transformIdNameToValueLabel } from '../../../transformers' import { getTaskBreadcrumbs } from '../TaskForm/state' +import { getQueryParamsFromLocation } from '../../../utils/url' export const ID = 'taskDetails' @@ -25,6 +24,6 @@ export const state2props = (state) => { export const buttonState2props = ({ router }) => { const { location } = router - const { returnUrl } = qs.parse(location.search.slice(1)) + const { returnUrl } = getQueryParamsFromLocation(location) return { returnUrl: returnUrl } } diff --git a/src/client/modules/Tasks/TaskForm/TaskFormAdd.jsx b/src/client/modules/Tasks/TaskForm/TaskFormAdd.jsx index 87257fa15d8..594b2004e69 100644 --- a/src/client/modules/Tasks/TaskForm/TaskFormAdd.jsx +++ b/src/client/modules/Tasks/TaskForm/TaskFormAdd.jsx @@ -1,8 +1,8 @@ import React from 'react' import { useLocation } from 'react-router-dom' import { connect } from 'react-redux' -import qs from 'qs' +import { getQueryParamsFromLocation } from '../../../utils/url' import { DefaultLayout } from '../../../components' import Task from '../../../components/Task' import { @@ -120,10 +120,8 @@ const TaskFormAdd = ({ breadcrumbs, companyInvestmentProjects, }) => { - const { search } = useLocation() - const { investmentProjectId, interactionId, copyTaskId } = qs.parse( - search.slice(1) - ) + const { investmentProjectId, interactionId, copyTaskId } = + getQueryParamsFromLocation(useLocation()) const taskForm = ( ({ value: id, @@ -8,14 +7,6 @@ export const idNameToValueLabel = ({ id, name }) => ({ export const idNamesToValueLabels = (idNames) => idNames.map(idNameToValueLabel) -export const parseQueryString = (queryString) => { - const queryParams = omitBy({ ...qs.parse(queryString) }, isEmpty) - return { - ...queryParams, - page: parseInt(queryParams.page || 1, 10), - } -} - export const deepKeysToCamelCase = (x) => Array.isArray(x) ? x.map(deepKeysToCamelCase) diff --git a/src/client/utils/url.js b/src/client/utils/url.js index da95d8b56f6..6a3015cf20e 100644 --- a/src/client/utils/url.js +++ b/src/client/utils/url.js @@ -1,7 +1,15 @@ -import { omitBy, isEmpty } from 'lodash' -import qs from 'qs' +export const parseQueryString = (queryString) => + Object.fromEntries(new URLSearchParams(queryString).entries()) -export const getQueryParamsFromLocation = (location) => { - const queryString = location.search.slice(1) - return omitBy({ ...qs.parse(queryString) }, isEmpty) +// TODO: Rename to locationToQSParams +export const getQueryParamsFromLocation = (location) => + parseQueryString(location.search) + +export const locationToQSParamsWithPage = (location) => { + const queryParams = parseQueryString(location.search) + + return { + ...queryParams, + page: parseInt(queryParams.page || 1, 10), + } }