X-Git-Url: https://git.arvados.org/arvados-workbench2.git/blobdiff_plain/48ae17a520d11173e2ae96fb7c78aa4a411a489a..519cf0aa43e6ac3085974506ff4eb1f0a70156c4:/src/store/search-bar/search-bar-actions.ts diff --git a/src/store/search-bar/search-bar-actions.ts b/src/store/search-bar/search-bar-actions.ts index b91dc9d1..54678b50 100644 --- a/src/store/search-bar/search-bar-actions.ts +++ b/src/store/search-bar/search-bar-actions.ts @@ -212,7 +212,7 @@ const searchGroups = (searchValue: string, limit: number) => const { cluster: clusterId } = getAdvancedDataFromQuery(searchValue); const sessions = getSearchSessions(clusterId, getState().auth.sessions); const lists: ListResults[] = await Promise.all(sessions.map(session => { - const filters = queryToFilters(searchValue); + const filters = queryToFilters(searchValue, session.apiRevision); return services.groupsService.contents('', { filters, limit, @@ -225,34 +225,36 @@ const searchGroups = (searchValue: string, limit: number) => } }; -const buildQueryFromKeyMap = (data: any, keyMap: string[][], mode: 'rebuild' | 'reuse') => { +const buildQueryFromKeyMap = (data: any, keyMap: string[][]) => { let value = data.searchValue; const addRem = (field: string, key: string) => { const v = data[key]; - + // Remove previous search expression. if (data.hasOwnProperty(key)) { - const pattern = v === false - ? `${field.replace(':', '\\:\\s*')}\\s*` - : `${field.replace(':', '\\:\\s*')}\\:\\s*"[\\w|\\#|\\-|\\/]*"\\s*`; + let pattern: string; + if (v === false) { + pattern = `${field.replace(':', '\\:\\s*')}\\s*`; + } else if (key.startsWith('prop-')) { + // On properties, only remove key:value duplicates, allowing + // multiple properties with the same key. + const oldValue = key.slice(5).split(':')[1]; + pattern = `${field.replace(':', '\\:\\s*')}\\:\\s*${oldValue}\\s*`; + } else { + pattern = `${field.replace(':', '\\:\\s*')}\\:\\s*[\\w|\\#|\\-|\\/]*\\s*`; + } value = value.replace(new RegExp(pattern), ''); } - + // Re-add it with the current search value. if (v) { const nv = v === true ? `${field}` : `${field}:${v}`; - - if (mode === 'rebuild') { - value = value + ' ' + nv; - } else { - value = nv + ' ' + value; - } + // Always append to the end to keep user-entered text at the start. + value = value + ' ' + nv; } }; - keyMap.forEach(km => addRem(km[0], km[1])); - return value; }; @@ -269,7 +271,9 @@ export const getQueryFromAdvancedData = (data: SearchBarAdvancedFormData, prevDa dateFrom: data.dateFrom, dateTo: data.dateTo, }; - (data.properties || []).forEach(p => fo[`prop-"${p.keyID || p.key}"`] = `"${p.valueID || p.value}"`); + (data.properties || []).forEach(p => + fo[`prop-"${p.keyID || p.key}":"${p.valueID || p.value}"`] = `"${p.valueID || p.value}"` + ); return fo; }; @@ -282,17 +286,13 @@ export const getQueryFromAdvancedData = (data: SearchBarAdvancedFormData, prevDa ['to', 'dateTo'] ]; _.union(data.properties, prevData ? prevData.properties : []) - .forEach(p => keyMap.push([`has:"${p.keyID || p.key}"`, `prop-"${p.keyID || p.key}"`])); + .forEach(p => keyMap.push( + [`has:"${p.keyID || p.key}"`, `prop-"${p.keyID || p.key}":"${p.valueID || p.value}"`] + )); - if (prevData) { - const obj = getModifiedKeysValues(flatData(data), flatData(prevData)); - value = buildQueryFromKeyMap({ - searchValue: data.searchValue, - ...obj - } as SearchBarAdvancedFormData, keyMap, "reuse"); - } else { - value = buildQueryFromKeyMap(flatData(data), keyMap, "rebuild"); - } + const modified = getModifiedKeysValues(flatData(data), prevData ? flatData(prevData):{}); + value = buildQueryFromKeyMap( + {searchValue: data.searchValue, ...modified} as SearchBarAdvancedFormData, keyMap); value = value.trim(); return value; @@ -329,7 +329,7 @@ export const getSearchSessions = (clusterId: string | undefined, sessions: Sessi return sessions.filter(s => s.loggedIn && (!clusterId || s.clusterId === clusterId)); }; -export const queryToFilters = (query: string) => { +export const queryToFilters = (query: string, apiRevision: number) => { const data = getAdvancedDataFromQuery(query); const filter = new FilterBuilder(); const resourceKind = data.type; @@ -352,9 +352,15 @@ export const queryToFilters = (query: string) => { data.properties.forEach(p => { if (p.value) { - filter - .addILike(`properties.${p.key}`, p.value, GroupContentsResourcePrefix.PROJECT) - .addILike(`properties.${p.key}`, p.value, GroupContentsResourcePrefix.COLLECTION); + if (apiRevision < 20200212) { + filter + .addILike(`properties.${p.key}`, p.value, GroupContentsResourcePrefix.PROJECT) + .addILike(`properties.${p.key}`, p.value, GroupContentsResourcePrefix.COLLECTION); + } else { + filter + .addContains(`properties.${p.key}`, p.value, GroupContentsResourcePrefix.PROJECT) + .addContains(`properties.${p.key}`, p.value, GroupContentsResourcePrefix.COLLECTION); + } } filter.addExists(p.key); });