From 459c66bc3ee2e79a97a4844285141513c87faae3 Mon Sep 17 00:00:00 2001 From: Gulum Date: Sat, 6 Jun 2026 08:52:02 +0200 Subject: [PATCH] =?UTF-8?q?Hotfix:=20gerbil=20search=20contains=20operator?= =?UTF-8?q?=20=E2=80=94=20drop=20trailing=20'*'=20(Gridify=20=3D*=20is=20c?= =?UTF-8?q?ontains;=20name=3D*a=20not=20name=3D*a*)=20+=20e2e=20mock=20mir?= =?UTF-8?q?rors=20real=20Gridify?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gerbil-manager-web/e2e/mock-api.ts | 5 ++++- gerbil-manager-web/src/api/gridify.ts | 7 +++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/gerbil-manager-web/e2e/mock-api.ts b/gerbil-manager-web/e2e/mock-api.ts index ea19acb..6219a76 100644 --- a/gerbil-manager-web/e2e/mock-api.ts +++ b/gerbil-manager-web/e2e/mock-api.ts @@ -27,7 +27,10 @@ function matchesFilter(row: Row, filter: string | null): boolean { if (!filter) return true return filter.split(',').every((andPart) => andPart.split('|').some((cond) => { - let m = cond.match(/^(\w+)=\*(.*)\*(\/i)?$/) + // Gridify "contains": `field=*value` — value runs to the end (optionally /i). + // Mirror the REAL backend: no trailing `*` (the old `=\*(.*)\*` regex hid the + // SQL-LIKE `name=*a*` bug that returned 0 rows against real Gridify). + let m = cond.match(/^(\w+)=\*(.*?)(\/i)?$/) if (m) { return String(row[m[1]] ?? '') .toLowerCase() diff --git a/gerbil-manager-web/src/api/gridify.ts b/gerbil-manager-web/src/api/gridify.ts index cce4f66..cbb1c0c 100644 --- a/gerbil-manager-web/src/api/gridify.ts +++ b/gerbil-manager-web/src/api/gridify.ts @@ -43,9 +43,12 @@ export interface FilterCondition { export function condition(c: FilterCondition): string { const escaped = escapeGridifyValue(String(c.value)) if (c.op === 'contains') { - // Gridify "contains" operator is =* ; default to case-insensitive. + // Gridify's "contains" operator is `=*` — the value follows directly and is + // matched as a substring. Do NOT wrap the value in asterisks (SQL-LIKE habit): + // a trailing `*` is a literal character to Gridify, so `name=*a*` searches for + // the literal "a*" and matches nothing. Correct form: `name=*a`. const suffix = c.caseInsensitive === false ? '' : '/i' - return `${c.field}=*${escaped}*${suffix}` + return `${c.field}=*${escaped}${suffix}` } // Gridify's equals operator is a single '='; callers use '==' semantically. const op = c.op === '==' ? '=' : c.op