From 66c16c8a2b21310f83f73226dcdabef65a06ec91 Mon Sep 17 00:00:00 2001 From: Ahmed Awan Date: Tue, 20 Dec 2022 20:15:40 -0500 Subject: [PATCH] Create getFilterValue function that gets value of filter from filterText --- .../src/stores/history/historyItemsStore.js | 5 +- client/src/utils/filtering.test.js | 11 ++++ client/src/utils/filtering.ts | 54 +++++++++++++++++-- 3 files changed, 64 insertions(+), 6 deletions(-) diff --git a/client/src/stores/history/historyItemsStore.js b/client/src/stores/history/historyItemsStore.js index 2f4659b939c..7a0563dc297 100644 --- a/client/src/stores/history/historyItemsStore.js +++ b/client/src/stores/history/historyItemsStore.js @@ -29,7 +29,7 @@ export const useHistoryItemsStore = defineStore("historyItemsStore", { return (historyId, filterText) => { const itemArray = state.items[historyId] || []; const filters = HistoryFilters.getFilters(filterText).filter((filter) => !filter.includes("related")); - const relatedHid = HistoryFilters.getQueryDict(filterText)["related-eq"] || null; + const relatedHid = HistoryFilters.getFilterValue(filterText, "related"); const filtered = itemArray.filter((item) => { if (!item) { return false; @@ -62,8 +62,6 @@ export const useHistoryItemsStore = defineStore("historyItemsStore", { actions: { async fetchHistoryItems(historyId, filterText, offset) { const queryString = HistoryFilters.getQueryString(filterText); - const filters = HistoryFilters.getQueryDict(filterText); - const relatedHid = filters["related-eq"] || null; const params = `v=dev&order=hid&offset=${offset}&limit=${limit}`; const url = `/api/histories/${historyId}/contents?${params}&${queryString}`; const headers = { accept: "application/vnd.galaxy.history.contents.stats+json" }; @@ -71,6 +69,7 @@ export const useHistoryItemsStore = defineStore("historyItemsStore", { const stats = data.stats; this.totalMatchesCount = stats.total_matches; const payload = data.contents; + const relatedHid = HistoryFilters.getFilterValue(filterText, "related"); this.saveHistoryItems(historyId, payload, relatedHid); }); }, diff --git a/client/src/utils/filtering.test.js b/client/src/utils/filtering.test.js index b7f877a9ab0..da88b73a243 100644 --- a/client/src/utils/filtering.test.js +++ b/client/src/utils/filtering.test.js @@ -29,12 +29,23 @@ describe("filtering", () => { expect(queryDict["name-contains"]).toBe("name of item"); }); test("parse check filter", () => { + expect(HistoryFilters.checkFilter(filterTexts[0], "name", "name of item")).toBe(true); expect(HistoryFilters.checkFilter(filterTexts[0], "tag", "first")).toBe(true); expect(HistoryFilters.checkFilter(filterTexts[0], "tag", "second")).toBe(false); expect(HistoryFilters.checkFilter(filterTexts[0], "deleted", "false")).toBe(true); expect(HistoryFilters.checkFilter(filterTexts[0], "visible", true)).toBe(true); expect(HistoryFilters.checkFilter(filterTexts[0], "visible", "false")).toBe(false); }); + test("parse get filter value", () => { + expect(HistoryFilters.getFilterValue(filterTexts[0], "name")).toBe("name of item"); + expect(HistoryFilters.getFilterValue(filterTexts[0], "hid", "gt")).toBe("10"); + expect(HistoryFilters.getFilterValue(filterTexts[0], "hid", "lt")).toBe("100"); + expect(HistoryFilters.getFilterValue(filterTexts[0], "tag")).toBe("first"); + expect(HistoryFilters.getFilterValue(filterTexts[0], "deleted")).toBe("False"); + expect(HistoryFilters.getFilterValue(filterTexts[0], "visible")).toBe("TRUE"); + expect(HistoryFilters.getFilterValue(filterTexts[1], "hid", "gt")).toBe("10"); + expect(HistoryFilters.getFilterValue(filterTexts[1], "create_time", "gt")).toBe("2021-01-01"); + }); test("parse filter text as entries", () => { filterTexts.forEach((filterText) => { const filters = HistoryFilters.getFilters(filterText); diff --git a/client/src/utils/filtering.ts b/client/src/utils/filtering.ts index 616bd3a3858..9c472e55e10 100644 --- a/client/src/utils/filtering.ts +++ b/client/src/utils/filtering.ts @@ -61,6 +61,27 @@ export function expandNameTag(value: string | object): string { return toLower(value); } +/** Converts string alias to string operator, e.g.: 'gt' to '>' + * @param {string} alias + * @returns {string} Arithmetic operator, e.g.: '>' + * */ +export function getOperatorForAlias(alias: string): string { + switch (alias) { + case "lt": + return "<"; + case "le": + return "<="; + case "ge": + return ">="; + case "gt": + return ">"; + case "eq": + return ":"; + default: + return ""; + } +} + type HandlerReturn = { attribute: string; converter?: Converter; @@ -323,12 +344,39 @@ export default class Filtering { * @returns {Boolean} True if the filter is set to the given value * */ checkFilter(filterText: string, filterName: string, filterValue: T): boolean { - const re = new RegExp(`${filterName}:(\\S+)`); - const reMatch = re.exec(filterText); - const testValue = reMatch ? reMatch[1] : this.defaultFilters[filterName]; + const testValue = this.getFilterValue(filterText, filterName); return toLowerNoQuotes(testValue) === toLowerNoQuotes(filterValue); } + /** Get the value of a particular filter from filterText. + * @param {String} filterText Raw filter text string + * @param {String} filterName Filter key to check + * @returns {String | Boolean} The filterValue for the filter + * */ + getFilterValue(filterText: string, filterName: string, alias = "eq"): string | boolean { + const op = getOperatorForAlias(alias); + const reInQuotes = `'([^']*[^\\s']*)'`; + const reNoQuotes = `(\\S+)`; + // Array of re groups, note: order matters as in quote filterVals must be checked first + const reGroups = [ + `${filterName}${op}${reInQuotes}`, + `${filterName}${op}${reNoQuotes}`, + `${filterName}-${alias}:${reInQuotes}`, + `${filterName}-${alias}:${reNoQuotes}`, + `${filterName}_${alias}:${reInQuotes}`, + `${filterName}_${alias}:${reNoQuotes}`, + ]; + let reMatch = null; + for (const reString of reGroups) { + const re = new RegExp(reString); + reMatch = re.exec(filterText); + if (reMatch) { + break; + } + } + return reMatch ? reMatch[1] : this.defaultFilters[filterName]; + } + /** Test if an item passes all filters. * @param {Object} filters Parsed in key-value pairs from getFilters() * @param {Object} item Item to test against the filters