refactor param changes to use new util function

This commit is contained in:
Keith J. Grant 2021-05-14 15:12:53 -07:00
parent 966eead93f
commit 9bbaa6993f
7 changed files with 114 additions and 65 deletions

View File

@ -13,11 +13,7 @@ import ContentLoading from '../ContentLoading';
import Pagination from '../Pagination';
import DataListToolbar from '../DataListToolbar';
import {
encodeNonDefaultQueryString,
parseQueryString,
replaceParams,
} from '../../util/qs';
import { parseQueryString, replaceNamespacedParams } from '../../util/qs';
import { QSConfig, SearchColumns, SortColumns } from '../../types';
@ -40,7 +36,6 @@ function PaginatedDataList({
pluralizedItemName,
showPageSizeOptions,
location,
renderToolbar,
}) {
const { search, pathname } = useLocation();
@ -51,22 +46,21 @@ function PaginatedDataList({
};
const handleSetPage = (event, pageNumber) => {
const oldParams = parseQueryString(qsConfig, search);
pushHistoryState(replaceParams(oldParams, { page: pageNumber }));
const encodedParams = replaceNamespacedParams(qsConfig, search, {
page: pageNumber,
});
pushHistoryState(encodedParams);
};
const handleSetPageSize = (event, pageSize, page) => {
const oldParams = parseQueryString(qsConfig, search);
pushHistoryState(replaceParams(oldParams, { page_size: pageSize, page }));
const encodedParams = replaceNamespacedParams(qsConfig, search, {
page_size: pageSize,
page,
});
pushHistoryState(encodedParams);
};
const pushHistoryState = params => {
const nonNamespacedParams = parseQueryString({}, history.location.search);
const encodedParams = encodeNonDefaultQueryString(
qsConfig,
params,
nonNamespacedParams
);
const pushHistoryState = encodedParams => {
history.push(encodedParams ? `${pathname}?${encodedParams}` : pathname);
};

View File

@ -3,11 +3,7 @@ import React from 'react';
import { useLocation, useHistory } from 'react-router-dom';
import { Thead, Tr, Th as PFTh } from '@patternfly/react-table';
import styled from 'styled-components';
import {
encodeNonDefaultQueryString,
parseQueryString,
replaceParams,
} from '../../util/qs';
import { parseQueryString, replaceNamespacedParams } from '../../util/qs';
const Th = styled(PFTh)`
--pf-c-table--cell--Overflow: initial;
@ -25,16 +21,10 @@ export default function HeaderRow({
const params = parseQueryString(qsConfig, location.search);
const onSort = (key, order) => {
const newParams = replaceParams(params, {
const encodedParams = replaceNamespacedParams(qsConfig, location.search, {
order_by: order === 'asc' ? key : `-${key}`,
page: null,
});
const nonNamespacedParams = parseQueryString({}, history.location.search);
const encodedParams = encodeNonDefaultQueryString(
qsConfig,
newParams,
nonNamespacedParams
);
history.push(
encodedParams
? `${location.pathname}?${encodedParams}`

View File

@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import { TableComposable, Tbody } from '@patternfly/react-table';
import { t } from '@lingui/macro';
import { useHistory } from 'react-router-dom';
import { useLocation, useHistory } from 'react-router-dom';
import ListHeader from '../ListHeader';
import ContentEmpty from '../ContentEmpty';
@ -14,11 +14,7 @@ import Pagination from '../Pagination';
import DataListToolbar from '../DataListToolbar';
import LoadingSpinner from '../LoadingSpinner';
import {
encodeNonDefaultQueryString,
parseQueryString,
replaceParams,
} from '../../util/qs';
import { parseQueryString, replaceNamespacedParams } from '../../util/qs';
import { QSConfig, SearchColumns } from '../../types';
function PaginatedTable({
@ -35,32 +31,30 @@ function PaginatedTable({
toolbarRelatedSearchableKeys,
pluralizedItemName,
showPageSizeOptions,
renderToolbar,
emptyContentMessage,
ouiaId,
}) {
const { search, pathname } = useLocation();
const history = useHistory();
const pushHistoryState = params => {
const { pathname, search } = history.location;
const nonNamespacedParams = parseQueryString({}, search);
const encodedParams = encodeNonDefaultQueryString(
qsConfig,
params,
nonNamespacedParams
);
const pushHistoryState = encodedParams => {
history.push(encodedParams ? `${pathname}?${encodedParams}` : pathname);
};
const handleSetPage = (event, pageNumber) => {
const oldParams = parseQueryString(qsConfig, history.location.search);
pushHistoryState(replaceParams(oldParams, { page: pageNumber }));
const encodedParams = replaceNamespacedParams(qsConfig, search, {
page: pageNumber,
});
pushHistoryState(encodedParams);
};
const handleSetPageSize = (event, pageSize, page) => {
const oldParams = parseQueryString(qsConfig, history.location.search);
pushHistoryState(replaceParams(oldParams, { page_size: pageSize, page }));
const encodedParams = replaceNamespacedParams(qsConfig, search, {
page_size: pageSize,
page,
});
pushHistoryState(encodedParams);
};
const searchColumns = toolbarSearchColumns.length

View File

@ -1,10 +1,6 @@
import { useState, useEffect } from 'react';
import { useLocation, useHistory } from 'react-router-dom';
import {
parseQueryString,
replaceParams,
encodeNonDefaultQueryString,
} from '../../../util/qs';
import { parseQueryString, replaceNamespacedParams } from '../../../util/qs';
import useWebsocket from '../../../util/useWebsocket';
import useThrottle from '../../../util/useThrottle';
@ -90,12 +86,9 @@ export default function useWsInventories(
) {
// We've deleted the last inventory on this page so we'll
// try to navigate back to the previous page
const newParams = encodeNonDefaultQueryString(
qsConfig,
replaceParams(params, {
page: params.page - 1,
})
);
const newParams = replaceNamespacedParams(qsConfig, location.search, {
page: params.page - 1,
});
history.push(`${location.pathname}?${newParams}`);
return;
}

View File

@ -246,3 +246,22 @@ export function replaceParams(oldParams, newParams) {
...newParams,
};
}
/**
* Update namespaced param(s), returning a new query string. Leaves params
* from other namespaces unaltered
* @param {object} qs config object for namespacing params, filtering defaults
* @param {string} the url query string to update
* @param {object} namespaced params to add or update
* @return {string} url query string
*/
export function replaceNamespacedParams(config, queryString, newParams) {
const oldParams = parseQueryString(config, queryString);
const updatedParams = replaceParams(oldParams, newParams);
const nonNamespacedParams = parseQueryString({}, queryString);
return encodeNonDefaultQueryString(
config,
updatedParams,
nonNamespacedParams
);
}

View File

@ -8,6 +8,7 @@ import {
_addDefaultsToObject,
mergeParams,
replaceParams,
replaceNamespacedParams,
} from './qs';
describe('qs (qs.js)', () => {
@ -810,4 +811,64 @@ describe('qs (qs.js)', () => {
});
});
});
describe('replaceNamespacedParams', () => {
const config = {
namespace: 'template',
defaultParams: { page: 1, page_size: 5, order_by: 'name' },
integerFields: ['page'],
};
test('should update namespaced param', () => {
const query = 'template.name__icontains=workflow&template.page=2';
const newParams = {
page: 3,
};
expect(replaceNamespacedParams(config, query, newParams)).toEqual(
'template.name__icontains=workflow&template.page=3'
);
});
test('should add new namespaced param', () => {
const query = 'template.name__icontains=workflow&template.page=2';
const newParams = {
or__type: 'job_template',
};
expect(replaceNamespacedParams(config, query, newParams)).toEqual(
'template.name__icontains=workflow&template.or__type=job_template&template.page=2'
);
});
test('should maintain non-namespaced param', () => {
const query = 'foo=bar&template.page=2&template.name__icontains=workflow';
const newParams = {
page: 3,
};
expect(replaceNamespacedParams(config, query, newParams)).toEqual(
'foo=bar&template.name__icontains=workflow&template.page=3'
);
});
test('should omit null values', () => {
const query = 'template.name__icontains=workflow&template.page=2';
const newParams = {
page: 3,
name__icontains: null,
};
expect(replaceNamespacedParams(config, query, newParams)).toEqual(
'template.page=3'
);
});
test.skip('should not alter params of other namespaces', () => {
const query =
'template.name__icontains=workflow&template.page=2&credential.page=3';
const newParams = {
page: 3,
};
expect(replaceNamespacedParams(config, query, newParams)).toEqual(
'template.name__icontains=workflow&template.page=3&credential.page=3'
);
});
});
});

View File

@ -4,6 +4,7 @@ import {
parseQueryString,
replaceParams,
encodeNonDefaultQueryString,
replaceNamespacedParams,
} from './qs';
import useIsMounted from './useIsMounted';
@ -111,12 +112,9 @@ export function useDeleteItems(
}
const params = parseQueryString(qsConfig, location.search);
if (params.page > 1 && allItemsSelected) {
const newParams = encodeNonDefaultQueryString(
qsConfig,
replaceParams(params, {
page: params.page - 1,
})
);
const newParams = replaceNamespacedParams(qsConfig, location.search, {
page: params.page - 1,
});
history.push(`${location.pathname}?${newParams}`);
} else {
fetchItems();