diff --git a/webapp/packages/plugin-navigation-tree/src/NavigationTree/ElementsTree/elementsTreeNameFilter.ts b/webapp/packages/plugin-navigation-tree/src/NavigationTree/ElementsTree/elementsTreeNameFilter.ts index 04e80e0bba..8d0f17363c 100644 --- a/webapp/packages/plugin-navigation-tree/src/NavigationTree/ElementsTree/elementsTreeNameFilter.ts +++ b/webapp/packages/plugin-navigation-tree/src/NavigationTree/ElementsTree/elementsTreeNameFilter.ts @@ -73,5 +73,67 @@ export function elementsTreeNameFilterNode(tree: IElementsTree, node: NavNode, f return EEquality.full; } - return nodeName?.includes(filterToLower) ? EEquality.partially : EEquality.none; + return createFilter(filterToLower)(nodeName) ? EEquality.partially : EEquality.none; +} + +function wildcardMatch(value: string, pattern: string): boolean { + const s = value.toLowerCase(); + const p = pattern.trim().toLowerCase(); + const parts = p.split('*'); + + if (parts.length === 1) { + return s.includes(parts[0]!); + } + + let pos = 0; + + for (let i = 0; i < parts.length; i++) { + const part = parts[i]; + if (!part) { + continue; + } + + const idx = s.indexOf(part, pos); + if (idx === -1) { + return false; + } + + if (i === 0 && !p.startsWith('*') && idx !== 0) { + return false; + } + + pos = idx + part.length; + } + + if (!p.endsWith('*') && parts[parts.length - 1]) { + if (!s.endsWith(parts[parts.length - 1]!)) { + return false; + } + } + + return true; +} + +function matchesFilter(value: string, filter: string): boolean { + const groups = filter + .split(',') + .map(g => g.trim()) + .filter(Boolean); + + if (!groups.length) { + return true; + } + + return groups.every(group => { + const alts = group + .split('|') + .map(a => a.trim()) + .filter(Boolean); + + return alts.some(alt => wildcardMatch(value, alt)); + }); +} + +function createFilter(filter: string): (value: string) => boolean { + return (value: string) => matchesFilter(value, filter); }