diff --git a/public/js/components/filter/Filter.js b/public/js/components/filter/Filter.js index 1508fb72a..73d2a10e3 100644 --- a/public/js/components/filter/Filter.js +++ b/public/js/components/filter/Filter.js @@ -206,6 +206,7 @@ export const CoreFilterCmpt = { movableColumns: true, columnDefaults:{ tooltip: true, + headerFilterFunc: this.customFilterFunction, }, placeholder, reactiveData: true, @@ -465,6 +466,89 @@ export const CoreFilterCmpt = { this.fetchCmptRefresh === true ? this.fetchCmptRefresh = false : this.fetchCmptRefresh = true; }, + parseFilterExpression(expression){ + const includeGroups = []; + const excludeTerms = []; + const comparisons = []; + + const andParts = expression.split('&&').map(part => part.trim()); + + andParts.forEach(part => { + const orTerms = part.split('||').map(p => p.trim()); + const orRegexes = []; + + orTerms.forEach(term => { + + const comparisonMatch = term.match(/^(<=|>=|<|>|=|!=)\s*(\d+)$/); + + if (comparisonMatch) + { + const operator = comparisonMatch[1]; + const number = parseFloat(comparisonMatch[2]); + + comparisons.push({ operator, number }); + } + else if (term.startsWith('!')) + { + const excludeTerm = term.substring(1).trim().replace(/\*/g, '.*'); + excludeTerms.push(new RegExp(excludeTerm, 'i')); + } + else + { + const includeTerm = term.replace(/\*/g, '.*'); + orRegexes.push(new RegExp(includeTerm, 'i')); + } + }); + + if (orRegexes.length > 0) + { + includeGroups.push(orRegexes); + } + }); + + return { includeGroups, excludeTerms, comparisons }; + }, + + customFilterFunction(headerValue, rowValue) + { + const { includeGroups, excludeTerms, comparisons } = this.parseFilterExpression(headerValue); + + const includes = includeGroups.every(group => + group.some(regex => regex.test(rowValue)) + ); + + const excludes = excludeTerms.every(regex => !regex.test(rowValue)); + + const comparisonCheck = comparisons.every(({ operator, number }) => { + let value = rowValue; + + if (!isNaN(number)) + { + value = parseFloat(rowValue); + if (isNaN(value)) return false; + } + + switch (operator) { + case '<': + return value < number; + case '>': + return value > number; + case '<=': + return value <= number; + case '>=': + return value >= number; + case '=': + return value === number; + case '!=': + return value !== number; + default: + return false; + } + }); + + return includes && excludes && comparisonCheck; + }, + // ------------------------------------------------------------------------------------------------------------------ // Event handlers