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

View File

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

View File

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

View File

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

View File

@@ -246,3 +246,22 @@ export function replaceParams(oldParams, newParams) {
...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, _addDefaultsToObject,
mergeParams, mergeParams,
replaceParams, replaceParams,
replaceNamespacedParams,
} from './qs'; } from './qs';
describe('qs (qs.js)', () => { 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, parseQueryString,
replaceParams, replaceParams,
encodeNonDefaultQueryString, encodeNonDefaultQueryString,
replaceNamespacedParams,
} from './qs'; } from './qs';
import useIsMounted from './useIsMounted'; import useIsMounted from './useIsMounted';
@@ -111,12 +112,9 @@ export function useDeleteItems(
} }
const params = parseQueryString(qsConfig, location.search); const params = parseQueryString(qsConfig, location.search);
if (params.page > 1 && allItemsSelected) { if (params.page > 1 && allItemsSelected) {
const newParams = encodeNonDefaultQueryString( const newParams = replaceNamespacedParams(qsConfig, location.search, {
qsConfig, page: params.page - 1,
replaceParams(params, { });
page: params.page - 1,
})
);
history.push(`${location.pathname}?${newParams}`); history.push(`${location.pathname}?${newParams}`);
} else { } else {
fetchItems(); fetchItems();