From e1c972d64d8e614b3c423a1644e6d9e01e0f8b28 Mon Sep 17 00:00:00 2001 From: kolaente Date: Tue, 12 Mar 2024 22:05:26 +0100 Subject: [PATCH] fix(filters): replace project titles at the match position, not anywhere in the filter string This fixes a bug where the project title would not be replaced correctly in cases where the project title contained parts of the word "project". Resolves https://kolaente.dev/vikunja/vikunja/issues/2194 --- frontend/src/helpers/filters.test.ts | 14 ++++++++++++-- frontend/src/helpers/filters.ts | 9 ++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/frontend/src/helpers/filters.test.ts b/frontend/src/helpers/filters.test.ts index 6f04f5757..2a71d9f9f 100644 --- a/frontend/src/helpers/filters.test.ts +++ b/frontend/src/helpers/filters.test.ts @@ -18,7 +18,7 @@ describe('Filter Transformation', () => { 'labels': 'labels', } - describe('For api', () => { + describe('For API', () => { for (const c in fieldCases) { it('should transform all filter params for ' + c + ' to snake_case', () => { const transformed = transformFilterStringForApi(c + ' = ipsum', nullTitleToIdResolver, nullTitleToIdResolver) @@ -97,6 +97,16 @@ describe('Filter Transformation', () => { expect(transformed).toBe('project in 1, 2') }) + + it('should resolve projects at the correct position', () => { + const transformed = transformFilterStringForApi( + 'project = pr', + nullTitleToIdResolver, + (title: string) => 1, + ) + + expect(transformed).toBe('project = 1') + }) }) describe('To API', () => { @@ -138,7 +148,7 @@ describe('Filter Transformation', () => { expect(transformed).toBe('labels = lorem && dueDate = now && labels = ipsum') }) - + it('should correctly resolve multiple labels in', () => { const transformed = transformFilterStringFromApi( 'labels in 1, 2', diff --git a/frontend/src/helpers/filters.ts b/frontend/src/helpers/filters.ts index 4a15696e3..7f9a39e10 100644 --- a/frontend/src/helpers/filters.ts +++ b/frontend/src/helpers/filters.ts @@ -108,12 +108,19 @@ export function transformFilterStringForApi( keywords = keyword.trim().split(',').map(k => k.trim()) } + let replaced = keyword + keywords.forEach(k => { const projectId = projectResolver(k) if (projectId !== null) { - filter = filter.replace(k, String(projectId)) + replaced = replaced.replace(k, String(projectId)) } }) + + const actualKeywordStart = (match?.index || 0) + prefix.length + filter = filter.substring(0, actualKeywordStart) + + replaced + + filter.substring(actualKeywordStart + keyword.length) } } })