X-Git-Url: https://git.arvados.org/arvados-workbench2.git/blobdiff_plain/6fdd4a4d609cf8fa459786f42eb337f8da6a5afa..623f5deee7b203090fb71f028e01ed55e0f8a38c:/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 ddaf8f31..b010af14 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; }; @@ -266,10 +268,13 @@ export const getQueryFromAdvancedData = (data: SearchBarAdvancedFormData, prevDa cluster: data.cluster, projectUuid: data.projectUuid, inTrash: data.inTrash, + pastVersions: data.pastVersions, 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; }; @@ -278,21 +283,18 @@ export const getQueryFromAdvancedData = (data: SearchBarAdvancedFormData, prevDa ['cluster', 'cluster'], ['project', 'projectUuid'], [`is:${parser.States.TRASHED}`, 'inTrash'], + [`is:${parser.States.PAST_VERSION}`, 'pastVersions'], ['from', 'dateFrom'], ['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; @@ -307,6 +309,7 @@ export const getAdvancedDataFromQuery = (query: string, vocabulary?: Vocabulary) cluster: getValue(Keywords.CLUSTER), projectUuid: getValue(Keywords.PROJECT), inTrash: parser.isTrashed(tokens), + pastVersions: parser.isPastVersion(tokens), dateFrom: getValue(Keywords.FROM) || '', dateTo: getValue(Keywords.TO) || '', properties: vocabulary @@ -329,7 +332,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; @@ -339,7 +342,7 @@ export const queryToFilters = (query: string) => { } if (data.projectUuid) { - filter.addEqual('ownerUuid', data.projectUuid); + filter.addEqual('owner_uuid', data.projectUuid); } if (data.dateFrom) { @@ -352,9 +355,17 @@ 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 + .addEqual(`properties.${p.key}`, p.value, GroupContentsResourcePrefix.PROJECT) + .addEqual(`properties.${p.key}`, p.value, GroupContentsResourcePrefix.COLLECTION) + .addEqual(`properties.${p.key}`, p.value, GroupContentsResourcePrefix.PROCESS); + } else { + filter + .addContains(`properties.${p.key}`, p.value, GroupContentsResourcePrefix.PROJECT) + .addContains(`properties.${p.key}`, p.value, GroupContentsResourcePrefix.COLLECTION) + .addContains(`properties.${p.key}`, p.value, GroupContentsResourcePrefix.PROCESS); + } } filter.addExists(p.key); });