blob: 2446486fcb7be8b8e51f3cefee5a18d8cf65f82f [file] [log] [blame]
Becky Siegel8b220de2018-04-04 17:11:06 -07001/**
2 * @license
3 * Copyright (C) 2016 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17(function() {
18 'use strict';
19
20 const MAX_AUTOCOMPLETE_RESULTS = 10;
21 const SELF_EXPRESSION = 'self';
22 const ME_EXPRESSION = 'me';
23
24 Polymer({
25 is: 'gr-smart-search',
26
27 properties: {
28 searchQuery: String,
29 _config: Object,
30 _projectSuggestions: {
31 type: Function,
32 value() {
33 return this._fetchProjects.bind(this);
34 },
35 },
36 _groupSuggestions: {
37 type: Function,
38 value() {
39 return this._fetchGroups.bind(this);
40 },
41 },
42 _accountSuggestions: {
43 type: Function,
44 value() {
45 return this._fetchAccounts.bind(this);
46 },
47 },
48 },
49
50 behaviors: [
Dmitrii Filippov587086b2019-09-03 16:10:06 +020051 Gerrit.DisplayNameBehavior,
Becky Siegel8b220de2018-04-04 17:11:06 -070052 ],
53
54 attached() {
55 this.$.restAPI.getConfig().then(cfg => {
56 this._config = cfg;
57 });
58 },
59
60 _handleSearch(e) {
61 const input = e.detail.inputVal;
62 if (input) {
63 Gerrit.Nav.navigateToSearchQuery(input);
64 }
65 },
66
67 _accountOrAnon(name) {
68 return this.getUserName(this._serverConfig, name, false);
69 },
70
71 /**
72 * Fetch from the API the predicted projects.
Tao Zhou25673ab2019-12-17 09:59:28 +010073 *
Becky Siegel8b220de2018-04-04 17:11:06 -070074 * @param {string} predicate - The first part of the search term, e.g.
75 * 'project'
76 * @param {string} expression - The second part of the search term, e.g.
77 * 'gerr'
78 * @return {!Promise} This returns a promise that resolves to an array of
79 * strings.
80 */
81 _fetchProjects(predicate, expression) {
82 return this.$.restAPI.getSuggestedProjects(
83 expression,
84 MAX_AUTOCOMPLETE_RESULTS)
85 .then(projects => {
86 if (!projects) { return []; }
87 const keys = Object.keys(projects);
Kasper Nilssonc363c9f2018-10-02 14:11:44 -070088 return keys.map(key => ({text: predicate + ':' + key}));
Becky Siegel8b220de2018-04-04 17:11:06 -070089 });
90 },
91
92 /**
93 * Fetch from the API the predicted groups.
Tao Zhou25673ab2019-12-17 09:59:28 +010094 *
Becky Siegel8b220de2018-04-04 17:11:06 -070095 * @param {string} predicate - The first part of the search term, e.g.
96 * 'ownerin'
97 * @param {string} expression - The second part of the search term, e.g.
98 * 'polyger'
99 * @return {!Promise} This returns a promise that resolves to an array of
100 * strings.
101 */
102 _fetchGroups(predicate, expression) {
103 if (expression.length === 0) { return Promise.resolve([]); }
104 return this.$.restAPI.getSuggestedGroups(
105 expression,
106 MAX_AUTOCOMPLETE_RESULTS)
107 .then(groups => {
108 if (!groups) { return []; }
109 const keys = Object.keys(groups);
Kasper Nilssonc363c9f2018-10-02 14:11:44 -0700110 return keys.map(key => ({text: predicate + ':' + key}));
Becky Siegel8b220de2018-04-04 17:11:06 -0700111 });
112 },
113
114 /**
115 * Fetch from the API the predicted accounts.
Tao Zhou25673ab2019-12-17 09:59:28 +0100116 *
Becky Siegel8b220de2018-04-04 17:11:06 -0700117 * @param {string} predicate - The first part of the search term, e.g.
118 * 'owner'
119 * @param {string} expression - The second part of the search term, e.g.
120 * 'kasp'
121 * @return {!Promise} This returns a promise that resolves to an array of
122 * strings.
123 */
124 _fetchAccounts(predicate, expression) {
125 if (expression.length === 0) { return Promise.resolve([]); }
126 return this.$.restAPI.getSuggestedAccounts(
127 expression,
128 MAX_AUTOCOMPLETE_RESULTS)
129 .then(accounts => {
130 if (!accounts) { return []; }
Kasper Nilssonc363c9f2018-10-02 14:11:44 -0700131 return this._mapAccountsHelper(accounts, predicate);
Becky Siegel8b220de2018-04-04 17:11:06 -0700132 }).then(accounts => {
133 // When the expression supplied is a beginning substring of 'self',
134 // add it as an autocomplete option.
135 if (SELF_EXPRESSION.startsWith(expression)) {
Kasper Nilssonc363c9f2018-10-02 14:11:44 -0700136 return accounts.concat(
137 [{text: predicate + ':' + SELF_EXPRESSION}]);
Becky Siegel8b220de2018-04-04 17:11:06 -0700138 } else if (ME_EXPRESSION.startsWith(expression)) {
Kasper Nilssonc363c9f2018-10-02 14:11:44 -0700139 return accounts.concat([{text: predicate + ':' + ME_EXPRESSION}]);
Becky Siegel8b220de2018-04-04 17:11:06 -0700140 } else {
141 return accounts;
142 }
143 });
144 },
Kasper Nilssonc363c9f2018-10-02 14:11:44 -0700145
146 _mapAccountsHelper(accounts, predicate) {
147 return accounts.map(account => ({
148 label: account.name || '',
149 text: account.email ?
Thomas Draebing6ff72df2019-12-27 10:58:03 +0100150 `${predicate}:${account.email}` :
151 `${predicate}:"${this._accountOrAnon(account)}"`,
Kasper Nilssonc363c9f2018-10-02 14:11:44 -0700152 }));
153 },
Becky Siegel8b220de2018-04-04 17:11:06 -0700154 });
155})();