Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(195)

Side by Side Diff: appengine/config_service/ui/src/config-ui/config-set.html

Issue 2991013002: config_service: Added revision and timestamp to config-set-cards and config-set pages (Closed)
Patch Set: Refactored test to give each function its own suite Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 <!-- 1 <!--
2 Copyright 2017 The LUCI Authors. All rights reserved. 2 Copyright 2017 The LUCI Authors. All rights reserved.
3 Use of this source code is governed under the Apache License, Version 2.0 3 Use of this source code is governed under the Apache License, Version 2.0
4 that can be found in the LICENSE file. 4 that can be found in the LICENSE file.
5 --> 5 -->
6 6
7 <link rel="import" href="config-file-card.html"> 7 <link rel="import" href="config-file-card.html">
8 <link rel="import" href="../../bower_components/iron-ajax/iron-ajax.html"> 8 <link rel="import" href="../../bower_components/iron-ajax/iron-ajax.html">
9 <link rel="import" href="../../bower_components/iron-icons/iron-icons.html"> 9 <link rel="import" href="../../bower_components/iron-icons/iron-icons.html">
10 <link rel="import" href="../../bower_components/paper-item/paper-item.html"> 10 <link rel="import" href="../../bower_components/paper-item/paper-item.html">
11 <link rel="import" href="../../bower_components/paper-spinner/paper-spinner.html "> 11 <link rel="import" href="../../bower_components/paper-spinner/paper-spinner.html ">
12 <link rel="import" href="../../bower_components/polymer/polymer.html"> 12 <link rel="import" href="../../bower_components/polymer/polymer.html">
13 <link rel="import" href="../../bower_components/iron-icons/maps-icons.html"> 13 <link rel="import" href="../../bower_components/iron-icons/maps-icons.html">
14 <link rel="import" href="../../bower_components/paper-tooltip/paper-tooltip.html "> 14 <link rel="import" href="../../bower_components/paper-tooltip/paper-tooltip.html ">
15 <link rel="import" href="../../common/common-behaviors.html">
15 16
16 <dom-module id="config-set"> 17 <dom-module id="config-set">
17 <template> 18 <template>
18 <style> 19 <style>
19 @media only screen and (min-width: 768px) { 20 @media only screen and (min-width: 768px) {
20 .center { 21 .center {
21 width: 550px; 22 width: 550px;
22 } 23 }
23 } 24 }
24 25
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 method="POST" 83 method="POST"
83 handle-as="json" 84 handle-as="json"
84 on-error="_onRefreshError" 85 on-error="_onRefreshError"
85 on-response="_onCompleteRefresh" 86 on-response="_onCompleteRefresh"
86 headers="[[auth_headers]]"> 87 headers="[[auth_headers]]">
87 </iron-ajax> 88 </iron-ajax>
88 89
89 <div class="center title"> 90 <div class="center title">
90 <div class="name"> 91 <div class="name">
91 [[name]][[route.path]] 92 [[name]][[route.path]]
93 <iron-icon id="launch"
94 icon="icons:launch"
95 class="paper-grey"
96 on-tap="_openConfigGitiles">
97 </iron-icon>
98 <paper-tooltip for="launch" offset="0">
99 [[url]]
100 </paper-tooltip>
92 <template is="dom-if" if="[[_not(isLoading)]]"> 101 <template is="dom-if" if="[[_not(isLoading)]]">
93 <template is="dom-if" if="[[lastImportAttempt]]"> 102 <template is="dom-if" if="[[lastImportAttempt]]">
94 <template is="dom-if" if="[[lastImportAttempt.success]]"> 103 <template is="dom-if" if="[[lastImportAttempt.success]]">
95 <iron-icon id="valid" icon="icons:check-circle" class="paper-green "></iron-icon> 104 <iron-icon id="valid" icon="icons:check-circle" class="paper-green "></iron-icon>
96 </template> 105 </template>
97 <template is="dom-if" if="[[_not(lastImportAttempt.success)]]"> 106 <template is="dom-if" if="[[_not(lastImportAttempt.success)]]">
98 <iron-icon id="invalid" icon="icons:warning" class="paper-red"></i ron-icon> 107 <iron-icon id="invalid" icon="icons:warning" class="paper-red"></i ron-icon>
99 </template> 108 </template>
100 </template> 109 </template>
101 <template is="dom-if" if="[[_not(lastImportAttempt)]]"> 110 <template is="dom-if" if="[[_not(lastImportAttempt)]]">
102 <iron-icon icon="icons:help" class="paper-grey"></iron-icon> 111 <iron-icon icon="icons:help" class="paper-grey"></iron-icon>
103 </template> 112 </template>
104 </template> 113 </template>
105 <template is="dom-if" if="[[auth_headers]]"> 114 <template is="dom-if" if="[[auth_headers]]">
106 <paper-icon-button id="force-refresh" 115 <iron-icon id="force-refresh"
107 icon="icons:file-download" 116 icon="icons:refresh"
108 on-tap="_forceRefresh"> 117 on-tap="_forceRefresh">
109 </paper-icon-button> 118 </iron-icon>
110 <paper-tooltip for="force-refresh" offset="0"> 119 <paper-tooltip for="force-refresh" offset="0">
111 Re-import the config-set from the repository. 120 Re-import the config-set from the repository.
112 </paper-tooltip> 121 </paper-tooltip>
113 </template> 122 </template>
114 </div> 123 </div>
115 <div class="category"> 124 <div class="category">
116 <p>[[_formatCategory(category, route.path)]]</p> 125 <p>[[_formatCategory(category, route.path)]]</p>
117 <template is="dom-if" if="[[_not(isLoading)]]"> 126 <template is="dom-if" if="[[_not(isLoading)]]">
118 <template is="dom-if" if="[[lastImportAttempt]]"> 127 <template is="dom-if" if="[[lastImportAttempt]]">
119 <template is="dom-if" if="[[_not(lastImportAttempt.success)]]"> 128 <template is="dom-if" if="[[_not(lastImportAttempt.success)]]">
120 Last import attempt failed: [[lastImportAttempt.message]] 129 Last import attempt failed: [[lastImportAttempt.message]]
121 </template> 130 </template>
122 <template is="dom-if" if="[[lastImportAttempt.success]]"> 131 <template is="dom-if" if="[[lastImportAttempt.success]]">
123 Last import succeeded. 132 Last import succeeded.
124 </template> 133 </template>
125 </template> 134 </template>
126 <template is="dom-if" if="[[_not(lastImportAttempt)]]"> 135 <template is="dom-if" if="[[_not(lastImportAttempt)]]">
127 Last import attempt info not available. 136 Last import attempt info not available.
128 </template> 137 </template>
138 <p>Revision: [[_getRevision(revision)]]</p>
139 <p>Timestamp: [[_getExactTime(timestamp)]]</p>
129 </template> 140 </template>
130 <p id="refreshStatus">[[refreshMessage]]</p> 141 <p id="refreshStatus">[[refreshMessage]]</p>
131 </div> 142 </div>
132 </div> 143 </div>
133 <template is="dom-if" if="[[_not(errorMessage)]]"> 144 <template is="dom-if" if="[[_not(errorMessage)]]">
134 <template is="dom-if" if="[[isRefreshing]]"> 145 <template is="dom-if" if="[[isRefreshing]]">
135 <div class="spinner"> 146 <div class="spinner">
136 <paper-spinner active></paper-spinner> 147 <paper-spinner active></paper-spinner>
137 </div> 148 </div>
138 </template> 149 </template>
(...skipping 24 matching lines...) Expand all
163 <template is="dom-if" if="[[errorMessage]]"> 174 <template is="dom-if" if="[[errorMessage]]">
164 <div class="center"> 175 <div class="center">
165 <p>[[errorMessage]]</p> 176 <p>[[errorMessage]]</p>
166 </div> 177 </div>
167 </template> 178 </template>
168 </template> 179 </template>
169 <script> 180 <script>
170 Polymer({ 181 Polymer({
171 is: "config-set", 182 is: "config-set",
172 183
184 behaviors: [ConfigUIBehaviors.CommonBehavior],
185
173 properties: { 186 properties: {
174 frontPageIsActive: { 187 category: {
175 type: Boolean, 188 type: String
176 observer: '_frontPageIsActive'
177 }, 189 },
178 190
179 category: { 191 errorMessage: {
180 type: String 192 type: String,
193 value: null
181 }, 194 },
182 195
183 files: { 196 files: {
184 type: Array 197 type: Array
185 }, 198 },
186 199
200 frontPageIsActive: {
201 type: Boolean,
202 observer: '_frontPageIsActive'
203 },
204
187 isLoading: { 205 isLoading: {
188 type: Boolean, 206 type: Boolean,
189 value: true 207 value: true
190 }, 208 },
191 209
192 isRefreshing: { 210 isRefreshing: {
193 type: Boolean, 211 type: Boolean,
194 value: false 212 value: false
195 }, 213 },
196 214
197 lastImportAttempt: { 215 lastImportAttempt: {
198 type: Object 216 type: Object
199 }, 217 },
200 218
201 url: {
202 type: String
203 },
204
205 name: { 219 name: {
206 type: String 220 type: String
207 }, 221 },
208 222
209 refreshMessage: { 223 refreshMessage: {
210 type: String, 224 type: String,
211 value: null 225 value: null
212 }, 226 },
213 227
214 route: { 228 route: {
215 type: Object, 229 type: Object,
216 observer: '_routeChanged' 230 observer: '_routeChanged'
217 }, 231 },
218 232
219 errorMessage: { 233 revision: {
220 type: String, 234 type: String,
221 value: null 235 value: null
236 },
237
238 timestamp: {
239 type: String,
240 value: null
241 },
242
243 url: {
244 type: String
222 } 245 }
223 }, 246 },
224 247
225 _forceRefresh: function() { 248 _forceRefresh: function() {
226 this.refreshMessage = null; 249 this.refreshMessage = null;
227 this.$.refreshConfigs.generateRequest(); 250 this.$.refreshConfigs.generateRequest();
228 this.isRefreshing = true; 251 this.isRefreshing = true;
229 }, 252 },
230 253
231 _frontPageIsActive: function() {
232 if (this.frontPageIsActive === false) {
233 this.isLoading = true;
234 if (!this.initialized) {
235 document.addEventListener('fetch-configs', function() {
236 this.$.requestConfigs.generateRequest();
237 }.bind(this));
238 } else {
239 this.$.requestConfigs.generateRequest();
240 }
241 }
242 },
243
244 _isEmpty: function(list) {
245 return list.length === 0;
246 },
247
248 _formatCategory: function(category, name) { 254 _formatCategory: function(category, name) {
249 if (name.includes("/refs")) return "Ref"; 255 if (name && name.includes("/refs")) return "Ref";
250 if (category === "projects") return "Project"; 256 if (category === "projects") return "Project";
251 if (category === "services") return "Service"; 257 if (category === "services") return "Service";
258 return "Cannot determine type of config set.";
252 }, 259 },
253 260
254 _onCompleteRefresh: function() { 261 _onCompleteRefresh: function() {
255 this.isRefreshing = false; 262 this.isRefreshing = false;
256 this.refreshMessage = "Refresh successful."; 263 this.refreshMessage = "Reimport successful.";
257 this.fire('refreshComplete'); 264 this.fire('refreshComplete');
258 }, 265 },
259 266
260 _not: function(b) {
261 return !b;
262 },
263
264 _onGotConfigFiles: function(event) { 267 _onGotConfigFiles: function(event) {
265 var config_set = event.detail.response.config_sets[0]; 268 var config_set = event.detail.response.config_sets[0];
266 this.files = config_set.files || []; 269 this.files = config_set.files || [];
267 this.lastImportAttempt = config_set.last_import_attempt || null; 270 this.lastImportAttempt = config_set.last_import_attempt || null;
268 if (config_set.revision && config_set.revision.url) { 271 if (this.lastImportAttempt && this.lastImportAttempt.success) {
269 this.url = config_set.revision.url; 272 this.url = config_set.last_import_attempt.revision.url;
273 this.revision = config_set.last_import_attempt.revision;
274 } else if (config_set.revision) {
275 this.url = config_set.revision.url || config_set.location;
276 this.revision = config_set.revision;
270 } else { 277 } else {
271 this.url = config_set.location; 278 this.url = config_set.location;
272 } 279 }
280 this.timestamp = this._getTimestamp(this.lastImportAttempt, this.revisio n);
273 this.isLoading = false; 281 this.isLoading = false;
274 this.errorMessage = null; 282 this.errorMessage = null;
275 this.fire('processedConfigFiles'); 283 this.fire('processedConfigFiles');
276 }, 284 },
277 285
278 _onRefreshError: function() { 286 _onRefreshError: function() {
279 this.isRefreshing = false; 287 this.isRefreshing = false;
280 this.refreshMessage = "Error: Files could not be refreshed."; 288 this.refreshMessage = "Error: Files could not be reimported.";
281 this.fire('refreshError'); 289 this.fire('refreshError');
282 }, 290 },
283 291
284 _onRequestError: function(event) { 292 _onRequestError: function(event) {
285 var error = parseInt(event.detail.error.message.match(/\d+/g)); 293 var error = parseInt(event.detail.error.message.match(/\d+/g));
286 this.isLoading = false; 294 this.isLoading = false;
287 if (error === 403) { 295 if (error === 403) {
288 if (!this.auth_headers) { 296 if (!this.auth_headers) {
289 this.errorMessage = "Access denied, please sign in."; 297 this.errorMessage = "Access denied, please sign in.";
290 } else { 298 } else {
291 this.errorMessage = "Access denied, " + this.profile.email + 299 this.errorMessage = "Access denied, " + this.profile.email +
292 " is not authorized to access this config set." + 300 " is not authorized to access this config set." +
293 " Request access or sign in as a different user."; 301 " Request access or sign in as a different user.";
294 } 302 }
295 } else if (500 <= error && error < 600) { 303 } else if (500 <= error && error < 600) {
296 this.errorMessage = "Internal server error."; 304 this.errorMessage = "Internal server error.";
297 } else { 305 } else {
298 this.errorMessage = "Error occured. Try again later."; 306 this.errorMessage = "Error occured. Try again later.";
299 } 307 }
300 this.fire('fetchError'); 308 this.fire('fetchError');
301 }, 309 },
302 310
303 _routeChanged: function() { 311 _routeChanged: function() {
304 this.isLoading = true; 312 this.isLoading = true;
305 this.$.requestConfigs.generateRequest(); 313 this.$.requestConfigs.generateRequest();
314 },
315
316 _openConfigGitiles: function() {
317 window.open(this.url);
306 } 318 }
307 319
308 }); 320 });
309 </script> 321 </script>
310 </dom-module> 322 </dom-module>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698