From 87eab79f7070034eef7a6367d5a6451fe68d8e8e Mon Sep 17 00:00:00 2001 From: gconsidine Date: Tue, 12 Sep 2017 14:57:07 -0400 Subject: [PATCH] Add support for quoted values containing spaces in search --- .../smart-search/smart-search.controller.js | 11 +++++-- .../smart-search/smart-search.service.js | 29 +++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/awx/ui/client/src/shared/smart-search/smart-search.controller.js b/awx/ui/client/src/shared/smart-search/smart-search.controller.js index 5b47b77ece..c3898dac41 100644 --- a/awx/ui/client/src/shared/smart-search/smart-search.controller.js +++ b/awx/ui/client/src/shared/smart-search/smart-search.controller.js @@ -161,10 +161,15 @@ export default ['$stateParams', '$scope', '$state', 'GetBasePath', 'QuerySet', ' terms = (terms) ? terms.trim() : ""; if(terms && terms !== '') { - // Split the terms up - let splitTerms = SmartSearchService.splitSearchIntoTerms(terms); - _.forEach(splitTerms, (term) => { + let splitTerms; + if ($scope.singleSearchParam === 'host_filter') { + splitTerms = SmartSearchService.splitHostIntoTerms(terms); + } else { + splitTerms = SmartSearchService.splitSearchIntoTerms(terms); + } + + _.forEach(splitTerms, (term) => { let termParts = SmartSearchService.splitTermIntoParts(term); function combineSameSearches(a,b){ diff --git a/awx/ui/client/src/shared/smart-search/smart-search.service.js b/awx/ui/client/src/shared/smart-search/smart-search.service.js index 48681b1e0d..1fea6ab4c6 100644 --- a/awx/ui/client/src/shared/smart-search/smart-search.service.js +++ b/awx/ui/client/src/shared/smart-search/smart-search.service.js @@ -1,5 +1,34 @@ export default [function() { return { + /** + * For the Smart Host Filter, values with spaces are wrapped with double quotes on input. + * To avoid having these quoted values split up and treated as terms themselves, some + * work is done to encode quotes in quoted values and the spaces within those quoted + * values before calling to `splitSearchIntoTerms`. + */ + splitHostIntoTerms (searchString) { + let groups = []; + let quoted; + + searchString.split(' ').forEach(substring => { + if (substring.includes(':"')) { + quoted = substring; + } else if (quoted) { + quoted += ` ${substring}`; + + if (substring.includes('"')) { + quoted = quoted.replace(/"/g, encodeURIComponent('"')); + quoted = quoted.replace(/ /g, encodeURIComponent(' ')); + groups.push(quoted); + quoted = undefined; + } + } else { + groups.push(substring); + } + }); + + return this.splitSearchIntoTerms(groups.join(' ')); + }, splitSearchIntoTerms(searchString) { return searchString.match(/(?:[^\s"']+|"[^"]*"|'[^']*')+/g); },