@@ -86,7 +86,7 @@ limitations under the License.
.rightItems gr-endpoint-decorator:not(:empty) {
margin-left: 1em;
}
- gr-search-bar {
+ gr-smart-search {
flex-grow: 1;
margin-left: .5em;
max-width: 500px;
@@ -129,7 +129,7 @@ limitations under the License.
font-size: var(--font-size-large);
font-family: var(--font-family-bold);
}
- gr-search-bar,
+ gr-smart-search,
.browse,
.rightItems .hideOnMobile,
.links > li.hideOnMobile {
@@ -171,7 +171,7 @@ limitations under the License.
-
+
diff --git a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html
index b97c056410..8332706296 100644
--- a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html
+++ b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.html
@@ -237,6 +237,15 @@ limitations under the License.
}));
},
+ /**
+ * Navigate to a search query
+ * @param {string} query
+ * @param {number=} opt_offset
+ */
+ navigateToSearchQuery(query, opt_offset) {
+ return this._navigate(this.getUrlForSearchQuery(query, opt_offset));
+ },
+
/**
* @param {!Object} change The change object.
* @param {number=} opt_patchNum
diff --git a/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.html b/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.html
index fdd730d057..b7b2147b3a 100644
--- a/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.html
+++ b/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.html
@@ -15,20 +15,15 @@ See the License for the specific language governing permissions and
limitations under the License.
-->
-
-
+
+
+
+
+
diff --git a/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search.js b/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search.js
new file mode 100644
index 0000000000..5dcd2bb277
--- /dev/null
+++ b/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search.js
@@ -0,0 +1,144 @@
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+(function() {
+ 'use strict';
+
+ const MAX_AUTOCOMPLETE_RESULTS = 10;
+ const SELF_EXPRESSION = 'self';
+ const ME_EXPRESSION = 'me';
+
+ Polymer({
+ is: 'gr-smart-search',
+
+ properties: {
+ searchQuery: String,
+ _config: Object,
+ _projectSuggestions: {
+ type: Function,
+ value() {
+ return this._fetchProjects.bind(this);
+ },
+ },
+ _groupSuggestions: {
+ type: Function,
+ value() {
+ return this._fetchGroups.bind(this);
+ },
+ },
+ _accountSuggestions: {
+ type: Function,
+ value() {
+ return this._fetchAccounts.bind(this);
+ },
+ },
+ },
+
+ behaviors: [
+ Gerrit.AnonymousNameBehavior,
+ ],
+
+ attached() {
+ this.$.restAPI.getConfig().then(cfg => {
+ this._config = cfg;
+ });
+ },
+
+ _handleSearch(e) {
+ const input = e.detail.inputVal;
+ if (input) {
+ Gerrit.Nav.navigateToSearchQuery(input);
+ }
+ },
+
+ _accountOrAnon(name) {
+ return this.getUserName(this._serverConfig, name, false);
+ },
+
+ /**
+ * Fetch from the API the predicted projects.
+ * @param {string} predicate - The first part of the search term, e.g.
+ * 'project'
+ * @param {string} expression - The second part of the search term, e.g.
+ * 'gerr'
+ * @return {!Promise} This returns a promise that resolves to an array of
+ * strings.
+ */
+ _fetchProjects(predicate, expression) {
+ return this.$.restAPI.getSuggestedProjects(
+ expression,
+ MAX_AUTOCOMPLETE_RESULTS)
+ .then(projects => {
+ if (!projects) { return []; }
+ const keys = Object.keys(projects);
+ return keys.map(key => predicate + ':' + key);
+ });
+ },
+
+ /**
+ * Fetch from the API the predicted groups.
+ * @param {string} predicate - The first part of the search term, e.g.
+ * 'ownerin'
+ * @param {string} expression - The second part of the search term, e.g.
+ * 'polyger'
+ * @return {!Promise} This returns a promise that resolves to an array of
+ * strings.
+ */
+ _fetchGroups(predicate, expression) {
+ if (expression.length === 0) { return Promise.resolve([]); }
+ return this.$.restAPI.getSuggestedGroups(
+ expression,
+ MAX_AUTOCOMPLETE_RESULTS)
+ .then(groups => {
+ if (!groups) { return []; }
+ const keys = Object.keys(groups);
+ return keys.map(key => predicate + ':' + key);
+ });
+ },
+
+ /**
+ * Fetch from the API the predicted accounts.
+ * @param {string} predicate - The first part of the search term, e.g.
+ * 'owner'
+ * @param {string} expression - The second part of the search term, e.g.
+ * 'kasp'
+ * @return {!Promise} This returns a promise that resolves to an array of
+ * strings.
+ */
+ _fetchAccounts(predicate, expression) {
+ if (expression.length === 0) { return Promise.resolve([]); }
+ return this.$.restAPI.getSuggestedAccounts(
+ expression,
+ MAX_AUTOCOMPLETE_RESULTS)
+ .then(accounts => {
+ if (!accounts) { return []; }
+ return accounts.map(acct => acct.email ?
+ `${predicate}:${acct.email}` :
+ `${predicate}:"${this._accountOrAnon(acct)}"`);
+ }).then(accounts => {
+ // When the expression supplied is a beginning substring of 'self',
+ // add it as an autocomplete option.
+ if (SELF_EXPRESSION.startsWith(expression)) {
+ return accounts.concat([predicate + ':' + SELF_EXPRESSION]);
+ } else if (ME_EXPRESSION.startsWith(expression)) {
+ return accounts.concat([predicate + ':' + ME_EXPRESSION]);
+ } else {
+ return accounts;
+ }
+ });
+ },
+ });
+})();
diff --git a/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search_test.html b/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search_test.html
new file mode 100644
index 0000000000..66dc0f09bd
--- /dev/null
+++ b/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search_test.html
@@ -0,0 +1,174 @@
+
+
+
+
+
gr-smart-search
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/polygerrit-ui/app/test/index.html b/polygerrit-ui/app/test/index.html
index dbc7dc9ff6..c29e3b513a 100644
--- a/polygerrit-ui/app/test/index.html
+++ b/polygerrit-ui/app/test/index.html
@@ -91,6 +91,7 @@ limitations under the License.
'core/gr-reporting/gr-reporting_test.html',
'core/gr-router/gr-router_test.html',
'core/gr-search-bar/gr-search-bar_test.html',
+ 'core/gr-smart-search/gr-smart-search_test.html',
'diff/gr-comment-api/gr-comment-api_test.html',
'diff/gr-diff-builder/gr-diff-builder_test.html',
'diff/gr-diff-comment-thread-group/gr-diff-comment-thread-group_test.html',