mirror of
https://github.com/Unleash/unleash.git
synced 2025-02-09 00:18:00 +01:00
feat: serach and filter input to query param parser (#5255)
This commit is contained in:
parent
a2b0507459
commit
fe61947435
@ -0,0 +1,50 @@
|
|||||||
|
import { translateToQueryParams } from './searchToQueryParams';
|
||||||
|
|
||||||
|
describe('translateToQueryParams', () => {
|
||||||
|
describe.each([
|
||||||
|
['search', 'query=search'],
|
||||||
|
[' search', 'query=search'],
|
||||||
|
[' search ', 'query=search'],
|
||||||
|
['search ', 'query=search'],
|
||||||
|
['search with space', 'query=search with space'],
|
||||||
|
['search type:release', 'query=search&type[]=release'],
|
||||||
|
[' search type:release ', 'query=search&type[]=release'],
|
||||||
|
[
|
||||||
|
'search type:release,experiment',
|
||||||
|
'query=search&type[]=release&type[]=experiment',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'search type:release ,experiment',
|
||||||
|
'query=search&type[]=release&type[]=experiment',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'search type:release, experiment',
|
||||||
|
'query=search&type[]=release&type[]=experiment',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'search type:release , experiment',
|
||||||
|
'query=search&type[]=release&type[]=experiment',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'search type: release , experiment',
|
||||||
|
'query=search&type[]=release&type[]=experiment',
|
||||||
|
],
|
||||||
|
['type:release', 'type[]=release'],
|
||||||
|
['type: release', 'type[]=release'],
|
||||||
|
['production:enabled', 'status[]=production:enabled'],
|
||||||
|
[
|
||||||
|
'development:enabled,disabled',
|
||||||
|
'status[]=development:enabled&status[]=development:disabled',
|
||||||
|
],
|
||||||
|
['tag:simple:web', 'tag[]=simple:web'],
|
||||||
|
['tag:enabled:enabled', 'tag[]=enabled:enabled'],
|
||||||
|
[
|
||||||
|
'tag:simple:web,complex:native',
|
||||||
|
'tag[]=simple:web&tag[]=complex:native',
|
||||||
|
],
|
||||||
|
])('when input is "%s"', (input, expected) => {
|
||||||
|
it(`returns "${expected}"`, () => {
|
||||||
|
expect(translateToQueryParams(input)).toBe(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,117 @@
|
|||||||
|
const splitInputQuery = (searchString: string): string[] =>
|
||||||
|
searchString.trim().split(/ (?=\w+:)/);
|
||||||
|
|
||||||
|
const isFilter = (part: string): boolean => part.includes(':');
|
||||||
|
|
||||||
|
const isStatusFilter = (key: string, values: string[]): boolean =>
|
||||||
|
values.every((value) => value === 'enabled' || value === 'disabled');
|
||||||
|
|
||||||
|
const addStatusFilters = (
|
||||||
|
key: string,
|
||||||
|
values: string[],
|
||||||
|
filterParams: Record<string, string | string[]>,
|
||||||
|
): Record<string, string | string[]> => {
|
||||||
|
const newStatuses = values.map((value) => `${key}:${value}`);
|
||||||
|
return {
|
||||||
|
...filterParams,
|
||||||
|
status: [...(filterParams.status || []), ...newStatuses],
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const addTagFilters = (
|
||||||
|
values: string[],
|
||||||
|
filterParams: Record<string, string | string[]>,
|
||||||
|
): Record<string, string | string[]> => ({
|
||||||
|
...filterParams,
|
||||||
|
tag: [...(filterParams.tag || []), ...values],
|
||||||
|
});
|
||||||
|
|
||||||
|
const addRegularFilters = (
|
||||||
|
key: string,
|
||||||
|
values: string[],
|
||||||
|
filterParams: Record<string, string | string[]>,
|
||||||
|
): Record<string, string | string[]> => ({
|
||||||
|
...filterParams,
|
||||||
|
[key]: [...(filterParams[key] || []), ...values],
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleFilter = (
|
||||||
|
part: string,
|
||||||
|
filterParams: Record<string, string | string[]>,
|
||||||
|
): Record<string, string | string[]> => {
|
||||||
|
const [key, ...valueParts] = part.split(':');
|
||||||
|
const valueString = valueParts.join(':').trim();
|
||||||
|
const values = valueString.split(',').map((value) => value.trim());
|
||||||
|
|
||||||
|
if (isStatusFilter(key, values)) {
|
||||||
|
return addStatusFilters(key, values, filterParams);
|
||||||
|
} else if (key === 'tag') {
|
||||||
|
return addTagFilters(values, filterParams);
|
||||||
|
} else {
|
||||||
|
return addRegularFilters(key, values, filterParams);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSearchTerm = (
|
||||||
|
part: string,
|
||||||
|
filterParams: Record<string, string | string[]>,
|
||||||
|
): Record<string, string | string[]> => ({
|
||||||
|
...filterParams,
|
||||||
|
query: filterParams.query
|
||||||
|
? `${filterParams.query} ${part.trim()}`
|
||||||
|
: part.trim(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const appendFilterParamsToQueryParts = (
|
||||||
|
params: Record<string, string | string[]>,
|
||||||
|
): string[] => {
|
||||||
|
let newQueryParts: string[] = [];
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(params)) {
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
newQueryParts = [
|
||||||
|
...newQueryParts,
|
||||||
|
...value.map((item) => `${key}[]=${item}`),
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
newQueryParts.push(`${key}=${value}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newQueryParts;
|
||||||
|
};
|
||||||
|
|
||||||
|
const convertToQueryString = (
|
||||||
|
params: Record<string, string | string[]>,
|
||||||
|
): string => {
|
||||||
|
const { query, ...filterParams } = params;
|
||||||
|
let queryParts: string[] = [];
|
||||||
|
|
||||||
|
if (query) {
|
||||||
|
queryParts.push(`query=${query}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
queryParts = queryParts.concat(
|
||||||
|
appendFilterParamsToQueryParts(filterParams),
|
||||||
|
);
|
||||||
|
|
||||||
|
return queryParts.join('&');
|
||||||
|
};
|
||||||
|
|
||||||
|
const buildSearchParams = (
|
||||||
|
input: string,
|
||||||
|
): Record<string, string | string[]> => {
|
||||||
|
const parts = splitInputQuery(input);
|
||||||
|
return parts.reduce(
|
||||||
|
(searchAndFilterParams, part) =>
|
||||||
|
isFilter(part)
|
||||||
|
? handleFilter(part, searchAndFilterParams)
|
||||||
|
: handleSearchTerm(part, searchAndFilterParams),
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const translateToQueryParams = (searchString: string): string => {
|
||||||
|
const searchParams = buildSearchParams(searchString);
|
||||||
|
return convertToQueryString(searchParams);
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user