diff --git a/awx/ui/src/components/Search/Search.js b/awx/ui/src/components/Search/Search.js index f38f609e18..3cd1fac4a4 100644 --- a/awx/ui/src/components/Search/Search.js +++ b/awx/ui/src/components/Search/Search.js @@ -21,6 +21,7 @@ import styled from 'styled-components'; import { parseQueryString } from 'util/qs'; import { QSConfig, SearchColumns } from 'types'; import AdvancedSearch from './AdvancedSearch'; +import getChipsByKey from './getChipsByKey'; const NoOptionDropdown = styled.div` align-self: stretch; @@ -95,66 +96,11 @@ function Search({ } }; - const filterDefaultParams = (paramsArr, config) => { - const defaultParamsKeys = Object.keys(config.defaultParams || {}); - return paramsArr.filter((key) => defaultParamsKeys.indexOf(key) === -1); - }; - - const getLabelFromValue = (value, colKey) => { - let label = value; - const currentSearchColumn = columns.find(({ key }) => key === colKey); - if (currentSearchColumn?.options?.length) { - [, label] = currentSearchColumn.options.find( - ([optVal]) => optVal === value - ); - } else if (currentSearchColumn?.booleanLabels) { - label = currentSearchColumn.booleanLabels[value]; - } - return (label || colKey).toString(); - }; - - const getChipsByKey = () => { - const queryParams = parseQueryString(qsConfig, location.search); - - const queryParamsByKey = {}; - columns.forEach(({ name, key }) => { - queryParamsByKey[key] = { key, label: name, chips: [] }; - }); - const nonDefaultParams = filterDefaultParams( - Object.keys(queryParams || {}), - qsConfig - ); - - nonDefaultParams.forEach((key) => { - const columnKey = key; - const label = columns.filter( - ({ key: keyToCheck }) => columnKey === keyToCheck - ).length - ? `${ - columns.find(({ key: keyToCheck }) => columnKey === keyToCheck).name - } (${key})` - : columnKey; - - queryParamsByKey[columnKey] = { key, label, chips: [] }; - - if (Array.isArray(queryParams[key])) { - queryParams[key].forEach((val) => - queryParamsByKey[columnKey].chips.push({ - key: `${key}:${val}`, - node: getLabelFromValue(val, columnKey), - }) - ); - } else { - queryParamsByKey[columnKey].chips.push({ - key: `${key}:${queryParams[key]}`, - node: getLabelFromValue(queryParams[key], columnKey), - }); - } - }); - return queryParamsByKey; - }; - - const chipsByKey = getChipsByKey(); + const chipsByKey = getChipsByKey( + parseQueryString(qsConfig, location.search), + columns, + qsConfig + ); const { name: searchColumnName } = columns.find( ({ key }) => key === searchKey diff --git a/awx/ui/src/components/Search/getChipsByKey.js b/awx/ui/src/components/Search/getChipsByKey.js new file mode 100644 index 0000000000..c1fe025859 --- /dev/null +++ b/awx/ui/src/components/Search/getChipsByKey.js @@ -0,0 +1,56 @@ +function filterDefaultParams(paramsArr, config) { + const defaultParamsKeys = Object.keys(config.defaultParams || {}); + return paramsArr.filter((key) => defaultParamsKeys.indexOf(key) === -1); +} + +function getLabelFromValue(columns, value, colKey) { + let label = value; + const currentSearchColumn = columns.find(({ key }) => key === colKey); + if (currentSearchColumn?.options?.length) { + [, label] = currentSearchColumn.options.find( + ([optVal]) => optVal === value + ); + } else if (currentSearchColumn?.booleanLabels) { + label = currentSearchColumn.booleanLabels[value]; + } + return (label || colKey).toString(); +} + +export default function getChipsByKey(queryParams, columns, qsConfig) { + const queryParamsByKey = {}; + columns.forEach(({ name, key }) => { + queryParamsByKey[key] = { key, label: `${name} (${key})`, chips: [] }; + }); + const nonDefaultParams = filterDefaultParams( + Object.keys(queryParams || {}), + qsConfig + ); + + nonDefaultParams.forEach((key) => { + const columnKey = key; + const label = columns.filter( + ({ key: keyToCheck }) => columnKey === keyToCheck + ).length + ? `${ + columns.find(({ key: keyToCheck }) => columnKey === keyToCheck).name + } (${key})` + : columnKey; + + queryParamsByKey[columnKey] = { key, label, chips: [] }; + + if (Array.isArray(queryParams[key])) { + queryParams[key].forEach((val) => + queryParamsByKey[columnKey].chips.push({ + key: `${key}:${val}`, + node: getLabelFromValue(columns, val, columnKey), + }) + ); + } else { + queryParamsByKey[columnKey].chips.push({ + key: `${key}:${queryParams[key]}`, + node: getLabelFromValue(columns, queryParams[key], columnKey), + }); + } + }); + return queryParamsByKey; +} diff --git a/awx/ui/src/components/Search/getChipsByKey.test.js b/awx/ui/src/components/Search/getChipsByKey.test.js new file mode 100644 index 0000000000..cf53a2641c --- /dev/null +++ b/awx/ui/src/components/Search/getChipsByKey.test.js @@ -0,0 +1,98 @@ +import getChipsByKey from './getChipsByKey'; + +describe('getChipsByKey', () => { + const qsConfig = { + namespace: 'job', + defaultParams: { + order_by: '-finished', + page: 1, + page_size: 20, + }, + integerFields: ['id', 'page', 'page_size'], + dateFields: ['modified', 'created'], + }; + const columns = [ + { name: 'Name', key: 'name__icontains', isDefault: true }, + { name: 'ID', key: 'id' }, + { + name: 'Job Type', + key: 'or__type', + options: [ + ['project_update', 'Source Control Update'], + ['inventory_update', 'Inventory Sync'], + ['job', 'Playbook Run'], + ['ad_hoc_command', 'Command'], + ['system_job', 'Management Job'], + ['workflow_job', 'Workflow Job'], + ], + }, + { name: 'Limit', key: 'job__limit' }, + ]; + const defaultQueryParams = { + page: 1, + page_size: 20, + order_by: '-finished', + }; + + test('should get initial chips', () => { + expect(getChipsByKey(defaultQueryParams, columns, qsConfig)).toEqual({ + id: { + key: 'id', + label: 'ID (id)', + chips: [], + }, + job__limit: { + key: 'job__limit', + label: 'Limit (job__limit)', + chips: [], + }, + name__icontains: { + key: 'name__icontains', + label: 'Name (name__icontains)', + chips: [], + }, + or__type: { + key: 'or__type', + label: 'Job Type (or__type)', + chips: [], + }, + }); + }); + + test('should get chips from query string', () => { + const queryParams = { + page: 1, + page_size: 20, + order_by: '-finished', + name__icontains: 'job', + }; + + expect(getChipsByKey(queryParams, columns, qsConfig)).toEqual({ + id: { + key: 'id', + label: 'ID (id)', + chips: [], + }, + job__limit: { + key: 'job__limit', + label: 'Limit (job__limit)', + chips: [], + }, + name__icontains: { + key: 'name__icontains', + label: 'Name (name__icontains)', + chips: [ + { + key: 'name__icontains:job', + node: 'job', + }, + ], + }, + or__type: { + key: 'or__type', + label: 'Job Type (or__type)', + chips: [], + }, + }); + }); +});