fix(filters): correctly replace the same filter input part when it occurs multiple times
This fixes a bug where a query like "labels in lorem || labels in ipsum" would only replace the first occurrence, leading to errors when sending the query string to the api. Resolves https://github.com/go-vikunja/vikunja/issues/346
This commit is contained in:
parent
6a63ffca28
commit
3d33b7c8d1
|
|
@ -78,6 +78,16 @@ describe('Filter Transformation', () => {
|
|||
expect(transformed).toBe('labels not in 1, 2 && due_date = now')
|
||||
})
|
||||
|
||||
it('should correctly resolve labels with multiple in clauses', () => {
|
||||
const transformed = transformFilterStringForApi(
|
||||
'labels in lorem || labels in ipsum',
|
||||
multipleDummyResolver,
|
||||
nullTitleToIdResolver,
|
||||
)
|
||||
|
||||
expect(transformed).toBe('labels in 1 || labels in 2')
|
||||
})
|
||||
|
||||
it('should correctly resolve projects', () => {
|
||||
const transformed = transformFilterStringForApi(
|
||||
'project = lorem',
|
||||
|
|
@ -228,6 +238,16 @@ describe('Filter Transformation', () => {
|
|||
|
||||
expect(transformed).toBe('labels in lorem, ipsum')
|
||||
})
|
||||
|
||||
it('should correctly resolve multiple labels in clauses', () => {
|
||||
const transformed = transformFilterStringFromApi(
|
||||
'labels in 1 || labels in 2',
|
||||
multipleIdToTitleResolver,
|
||||
nullIdToTitleResolver,
|
||||
)
|
||||
|
||||
expect(transformed).toBe('labels in lorem || labels in ipsum')
|
||||
})
|
||||
|
||||
it('should correctly resolve multiple labels not in', () => {
|
||||
const transformed = transformFilterStringFromApi(
|
||||
|
|
|
|||
|
|
@ -94,6 +94,8 @@ export function transformFilterStringForApi(
|
|||
const pattern = getFilterFieldRegexPattern(field)
|
||||
|
||||
let match: RegExpExecArray | null
|
||||
const replacements: { start: number, length: number, replacement: string }[] = []
|
||||
|
||||
while ((match = pattern.exec(filter)) !== null) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const [matched, prefix, operator, space, keyword] = match
|
||||
|
|
@ -116,10 +118,22 @@ export function transformFilterStringForApi(
|
|||
})
|
||||
|
||||
const actualKeywordStart = (match?.index || 0) + prefix.length
|
||||
filter = filter.substring(0, actualKeywordStart) +
|
||||
replaced +
|
||||
filter.substring(actualKeywordStart + keyword.length)
|
||||
replacements.push({
|
||||
start: actualKeywordStart,
|
||||
length: keyword.length,
|
||||
replacement: replaced,
|
||||
})
|
||||
}
|
||||
|
||||
// We're collecting the results first and then replacing the filter string in the end
|
||||
// to avoid modifying the input string as we iterate over it.
|
||||
let offset = 0
|
||||
replacements.forEach(({start, length, replacement}) => {
|
||||
filter = filter.substring(0, start + offset) +
|
||||
replacement +
|
||||
filter.substring(start + offset + length)
|
||||
offset += replacement.length - length
|
||||
})
|
||||
})
|
||||
return filter
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue