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

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

Issue 2985923002: config_service: Handled errors in the front page (Closed)
Patch Set: set isLoading to false after the error message is set 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="../../bower_components/app-layout/app-layout.html"> 7 <link rel="import" href="../../bower_components/app-layout/app-layout.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/paper-button/paper-button.html"> 9 <link rel="import" href="../../bower_components/paper-button/paper-button.html">
10 <link rel="import" href="../../bower_components/paper-search/paper-search-bar.ht ml"> 10 <link rel="import" href="../../bower_components/paper-search/paper-search-bar.ht ml">
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 height: 100%; 59 height: 100%;
60 margin: auto; 60 margin: auto;
61 } 61 }
62 62
63 </style> 63 </style>
64 64
65 <iron-ajax 65 <iron-ajax
66 id="requestConfigs" 66 id="requestConfigs"
67 url="/_ah/api/config/v1/config-sets?include_last_import_attempt=true" 67 url="/_ah/api/config/v1/config-sets?include_last_import_attempt=true"
68 handle-as="json" 68 handle-as="json"
69 on-error="_onRequestError"
69 on-response="_onGotConfigSets" 70 on-response="_onGotConfigSets"
70 headers="[[auth_headers]]"> 71 headers="[[auth_headers]]">
71 </iron-ajax> 72 </iron-ajax>
72 73
73 <div class="search-bar"> 74 <div class="search-bar">
74 <paper-search-bar 75 <paper-search-bar
75 query="{{query}}" 76 query="{{query}}"
76 hide-filter-button="true"></paper-search-bar> 77 hide-filter-button="true"></paper-search-bar>
77 </div> 78 </div>
78 79
79 <div class="config-list"> 80 <div class="config-list">
80 <template is="dom-if" if="[[isLoading]]"> 81 <template is="dom-if" if="[[isLoading]]">
81 <div class="center loading"> 82 <div class="center loading">
82 <paper-spinner active></paper-spinner> 83 <paper-spinner active></paper-spinner>
83 </div> 84 </div>
84 </template> 85 </template>
85 <template is="dom-if" if="[[_not(isLoading)]]"> 86 <template is="dom-if" if="[[_not(isLoading)]]">
86 <template is="dom-if" if="[[_isEmpty(searchResults)]]"> 87 <template is="dom-if" if="[[_not(errorMessage)]]">
87 <div class="center name">No config sets found.</div> 88 <template is="dom-if" if="[[_isEmpty(searchResults)]]">
89 <div class="center name">No config sets found.</div>
90 </template>
91 <template is="dom-if" if="[[_not(_isEmpty(searchResults))]]">
92 <template is="dom-repeat" items="[[searchResults]]" as="config">
93 <div class="center config-card">
94 <config-set-card
95 name="[[config.config_set]]"
96 last-import-attempt="[[_getLastImportAttempt(config.last_impor t_attempt)]]">
97 </config-set-card>
98 </div>
99 </template>
100 </template>
88 </template> 101 </template>
89 <template is="dom-if" if="[[_not(_isEmpty(searchResults))]]"> 102 <template is="dom-if" if="[[errorMessage]]">
90 <template is="dom-repeat" items="[[searchResults]]" as="config"> 103 <div class="center name">[[errorMessage]]</div>
91 <div class="center config-card">
92 <config-set-card
93 name="[[config.config_set]]"
94 last-import-attempt="[[_getLastImportAttempt(config.last_import_ attempt)]]">
95 </config-set-card>
96 </div>
97 </template>
98 </template> 104 </template>
99 </template> 105 </template>
100 </div> 106 </div>
101 </template> 107 </template>
102 <script> 108 <script>
103 Polymer({ 109 Polymer({
104 is: 'front-page', 110 is: 'front-page',
105 111
106 properties: { 112 properties: {
107 configSetList: { 113 configSetList: {
108 type: Array, 114 type: Array,
109 value: () => [] 115 value: () => []
110 }, 116 },
111 117
118 errorMessage: {
119 type: String,
120 value: null
121 },
122
112 isLoading: { 123 isLoading: {
113 type: Boolean, 124 type: Boolean,
114 value: true 125 value: true
115 }, 126 },
116 127
117 query: { 128 query: {
118 type: String, 129 type: String,
119 observer: '_updateSearchResults' 130 observer: '_updateSearchResults'
120 }, 131 },
121 132
(...skipping 21 matching lines...) Expand all
143 return lastImportAttempt; 154 return lastImportAttempt;
144 } else { 155 } else {
145 return null; 156 return null;
146 } 157 }
147 }, 158 },
148 159
149 _isEmpty: function(array) { 160 _isEmpty: function(array) {
150 return array.length === 0; 161 return array.length === 0;
151 }, 162 },
152 163
164 _not: function(b) {
165 return !b;
166 },
167
153 _onGotConfigSets: function(event) { 168 _onGotConfigSets: function(event) {
154 this.configSetList = event.detail.response.config_sets; 169 this.configSetList = event.detail.response.config_sets;
155 this._updateSearchResults(); 170 this._updateSearchResults();
156 this.isLoading = false; 171 this.isLoading = false;
157 this.fire('processedConfigSets'); 172 this.fire('processedConfigSets');
158 }, 173 },
159 174
160 _not: function(b) { 175 _onRequestError: function(event) {
161 return !b; 176 var error = parseInt(event.detail.error.message.match(/\d+/g));
177 if (error === 403) {
178 this.errorMessage = "Access denied. Please try again later.";
Sergey Berezin 2017/07/26 19:40:30 I'd just leave it at "Access denied." There is no
cwpayton 2017/07/26 22:48:50 Done.
179 } else if (500 <= error && error < 600) {
180 this.errorMessage = "Internal server error.";
Sergey Berezin 2017/07/26 19:40:30 Here you want to ask "Please try again later", sin
cwpayton 2017/07/26 22:48:50 I want to try to avoid any timeouts in the code, s
Sergey Berezin 2017/07/26 23:09:13 Timeouts should be avoided for synchronization (e.
181 } else {
182 this.errorMessage = "Error occured. Please try again later.";
183 }
184 this.isLoading = false;
185 this.fire('fetchError');
162 }, 186 },
163 187
164 _updateSearchResults: function() { 188 _updateSearchResults: function() {
165 // This method sorts search results by the name of the config set, that way 189 // This method sorts search results by the name of the config set, that way
166 // the list doesn't consist of all projects followed by all services due to 190 // the list doesn't consist of all projects followed by all services due to
167 // the path beginning with "projects/" or "services/" 191 // the path beginning with "projects/" or "services/"
168 var tempResults = this.configSetList.filter(e => e.config_set.includes(t his.query)); 192 var tempResults = this.configSetList.filter(e => e.config_set.includes(t his.query));
169 tempResults.sort(function(a, b) { 193 tempResults.sort(function(a, b) {
170 return this._formatName(a.config_set).localeCompare(this._formatName(b .config_set)); 194 return this._formatName(a.config_set).localeCompare(this._formatName(b .config_set));
171 }.bind(this)); 195 }.bind(this));
172 this.searchResults = tempResults; 196 this.searchResults = tempResults;
173 }, 197 },
174 198
175 }); 199 });
176 </script> 200 </script>
177 </dom-module> 201 </dom-module>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698