Skip to content

Commit

Permalink
Merge pull request #1261 from danskernesdigitalebibliotek/fix/advance…
Browse files Browse the repository at this point in the history
…d-search-cql-precedence

Fix advanced search precedence
  • Loading branch information
Adamik10 authored Jun 20, 2024
2 parents 562aed6 + e7dd06c commit 8d47507
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 15 deletions.
6 changes: 5 additions & 1 deletion src/apps/advanced-search/AdvancedSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ const AdvancedSearch: React.FC<AdvancedSearchProps> = ({ pageSize }) => {

// Only react on url parameters on the initial render.
useEffectOnce(() => {
const advancedSearchQuery = getUrlQueryParam("advancedSearchQuery");
// We have to remove brackets if multiple filters were used so that we can
// translate the string back to an object.
const advancedSearchQuery = getUrlQueryParam("advancedSearchQuery")
?.replace("(", "")
.replace(")", "");
if (advancedSearchQuery) {
// TODO: Add runtime validation
// If the value does not match the type because of url tampering, type
Expand Down
51 changes: 37 additions & 14 deletions src/apps/advanced-search/helpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,28 @@ const translateFilterToCql = (
filterToTranslate: MultiselectOption[],
cqlKey: keyof typeof advancedSearchFilters
) => {
return filterToTranslate.reduce((acc: string, curr: MultiselectOption) => {
let filterTranslation = "";
const relation = acc.trim() === "" ? " AND" : " OR";
if (curr.value === "all") {
return `${acc}`;
}
filterTranslation = filterTranslation.concat(
relation,
` ${advancedSearchFilters[cqlKey]}=`,
`'${curr.value}'`
);
return acc + filterTranslation;
}, "");
let translation = filterToTranslate.reduce(
(acc: string, curr: MultiselectOption) => {
let filterTranslation = "";
const relation = acc.trim() === "" ? " AND" : " OR";
if (curr.value === "all") {
return `${acc}`;
}
filterTranslation = filterTranslation.concat(
relation,
` ${advancedSearchFilters[cqlKey]}=`,
`'${curr.value}'`
);
return acc + filterTranslation;
},
""
);
// If multiple values are selected in a single filter, we need to wrap them in
// parentheses & add move the opening AND clause before the parenthesis opening.
if (filterToTranslate.length > 1) {
translation = ` AND (${translation.split(" AND")[1]})`;
}
return translation;
};

const translateFiltersToCql = (
Expand All @@ -86,12 +95,26 @@ const translateFiltersToCql = (
return translatedFilters;
};

export const wrapFiltersInParentheses = (filters: string) => {
// No filters, no wrapping needed.
if (filters.trim() === "") {
return "";
}
// If there's only one clause, no wrapping is needed either.
if (!filters.includes(" OR ")) {
return filters;
}
// The filter string always start with " AND", so we can work with that.
const splitFiltersArray = filters.split(" AND", 2);
return `${splitFiltersArray.join(" AND (")})`;
};

export const translateSearchObjectToCql = (
searchObject: AdvancedSearchQuery
) => {
const rowsAsCql = translateRowsToCql(searchObject.rows);
const filtersAsCql = translateFiltersToCql(searchObject.filters);
return rowsAsCql + filtersAsCql;
return `${rowsAsCql}${filtersAsCql}`;
};

export const shouldAdvancedSearchButtonBeDisabled = (
Expand Down

0 comments on commit 8d47507

Please sign in to comment.