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

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: Added unit tests and fixed gitiles link icon 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:refresh" 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)]]</p> 125 <p>[[_formatCategory(category)]]</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 errorMessage: { 228 revision: {
215 type: String, 229 type: String,
216 value: null 230 value: null
231 },
232
233 timestamp: {
234 type: String,
235 value: null
236 },
237
238 url: {
239 type: String
217 } 240 }
218 }, 241 },
219 242
220 _forceRefresh: function() { 243 _forceRefresh: function() {
221 this.refreshMessage = null; 244 this.refreshMessage = null;
222 this.$.refreshConfigs.generateRequest(); 245 this.$.refreshConfigs.generateRequest();
223 this.isRefreshing = true; 246 this.isRefreshing = true;
224 }, 247 },
225 248
226 _frontPageIsActive: function() {
227 if (this.frontPageIsActive === false) {
228 this.isLoading = true;
229 if (!this.initialized) {
230 document.addEventListener('fetch-configs', function() {
231 this.$.requestConfigs.generateRequest();
232 }.bind(this));
233 } else {
234 this.$.requestConfigs.generateRequest();
235 }
236 }
237 },
238
239 _isEmpty: function(list) {
240 return list.length === 0;
241 },
242
243 _formatCategory: function(category) { 249 _formatCategory: function(category) {
244 if (category === "projects") return "Project"; 250 if (category === "projects") return "Project";
245 if (category === "services") return "Service"; 251 if (category === "services") return "Service";
246 }, 252 },
247 253
248 _onCompleteRefresh: function() { 254 _onCompleteRefresh: function() {
249 this.isRefreshing = false; 255 this.isRefreshing = false;
250 this.refreshMessage = "Refresh successful."; 256 this.refreshMessage = "Reimport successful.";
251 this.fire('refreshComplete'); 257 this.fire('refreshComplete');
252 }, 258 },
253 259
254 _not: function(b) {
255 return !b;
256 },
257
258 _onGotConfigFiles: function(event) { 260 _onGotConfigFiles: function(event) {
259 var config_set = event.detail.response.config_sets[0]; 261 var config_set = event.detail.response.config_sets[0];
260 this.files = config_set.files || []; 262 this.files = config_set.files || [];
261 this.lastImportAttempt = config_set.last_import_attempt || null; 263 this.lastImportAttempt = config_set.last_import_attempt || null;
262 if (config_set.revision && config_set.revision.url) { 264 if (this.lastImportAttempt && this.lastImportAttempt.success) {
263 this.url = config_set.revision.url; 265 this.url = config_set.last_import_attempt.revision.url;
266 this.revision = config_set.last_import_attempt.revision;
267 } else if (config_set.revision) {
268 this.url = config_set.revision.url || config_set.location;
269 this.revision = config_set.revision;
264 } else { 270 } else {
265 this.url = config_set.location; 271 this.url = config_set.location;
266 } 272 }
273 this.timestamp = this._getTimestamp(this.lastImportAttempt, this.revisio n);
267 this.isLoading = false; 274 this.isLoading = false;
268 this.errorMessage = null; 275 this.errorMessage = null;
269 this.fire('processedConfigFiles'); 276 this.fire('processedConfigFiles');
270 }, 277 },
271 278
272 _onRefreshError: function() { 279 _onRefreshError: function() {
273 this.isRefreshing = false; 280 this.isRefreshing = false;
274 this.refreshMessage = "Error: Files could not be refreshed."; 281 this.refreshMessage = "Error: Files could not be reimported.";
275 this.fire('refreshError'); 282 this.fire('refreshError');
276 }, 283 },
277 284
278 _onRequestError: function(event) { 285 _onRequestError: function(event) {
279 var error = parseInt(event.detail.error.message.match(/\d+/g)); 286 var error = parseInt(event.detail.error.message.match(/\d+/g));
280 this.isLoading = false; 287 this.isLoading = false;
281 if (error === 403) { 288 if (error === 403) {
282 if (!this.auth_headers) { 289 if (!this.auth_headers) {
283 this.errorMessage = "Access denied, please sign in."; 290 this.errorMessage = "Access denied, please sign in.";
284 } else { 291 } else {
285 this.errorMessage = "Access denied, " + this.profile.email + 292 this.errorMessage = "Access denied, " + this.profile.email +
286 " is not authorized to access this config set." + 293 " is not authorized to access this config set." +
287 " Request access or sign in as a different user."; 294 " Request access or sign in as a different user.";
288 } 295 }
289 } else if (500 <= error && error < 600) { 296 } else if (500 <= error && error < 600) {
290 this.errorMessage = "Internal server error."; 297 this.errorMessage = "Internal server error.";
291 } else { 298 } else {
292 this.errorMessage = "Error occured. Try again later."; 299 this.errorMessage = "Error occured. Try again later.";
293 } 300 }
294 this.fire('fetchError'); 301 this.fire('fetchError');
302 },
303
304 _openConfigGitiles: function() {
305 window.open(this.url);
295 } 306 }
296 307
297 }); 308 });
298 </script> 309 </script>
299 </dom-module> 310 </dom-module>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698