1<%-- 2 ~ Copyright (c) 2016 Google Inc. All Rights Reserved. 3 ~ 4 ~ Licensed under the Apache License, Version 2.0 (the "License"); you 5 ~ may not use this file except in compliance with the License. You may 6 ~ obtain a copy of the License at 7 ~ 8 ~ http://www.apache.org/licenses/LICENSE-2.0 9 ~ 10 ~ Unless required by applicable law or agreed to in writing, software 11 ~ distributed under the License is distributed on an "AS IS" BASIS, 12 ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 13 ~ implied. See the License for the specific language governing 14 ~ permissions and limitations under the License. 15 --%> 16<%@ page contentType='text/html;charset=UTF-8' language='java' %> 17<%@ taglib prefix='fn' uri='http://java.sun.com/jsp/jstl/functions' %> 18<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%> 19 20<html> 21 <link rel='stylesheet' href='/css/dashboard_main.css'> 22 <%@ include file='header.jsp' %> 23 <body> 24 <script> 25 var allTests = ${allTestsJson}; 26 var testSet = new Set(allTests); 27 var subscriptionMap = ${subscriptionMapJson}; 28 29 var addFavorite = function() { 30 if ($(this).hasClass('disabled')) { 31 return; 32 } 33 var test = $('#input-box').val(); 34 if (!testSet.has(test) || test in subscriptionMap) { 35 return; 36 } 37 $('#add-button').addClass('disabled'); 38 $.post('/api/favorites', { testName: test}).then(function(data) { 39 if (!data.key) { 40 return; 41 } 42 subscriptionMap[test] = data.key; 43 var wrapper = $('<div></div>'); 44 var a = $('<a></a>') 45 .attr('href', '${resultsUrl}?testName=' + test); 46 var div = $('<div class="col s11 card hoverable option"></div>'); 47 div.addClass('valign-wrapper waves-effect'); 48 div.appendTo(a); 49 var span = $('<span class="entry valign"></span>').text(test); 50 span.appendTo(div); 51 a.appendTo(wrapper); 52 53 var btnContainer = $('<div class="col s1 center btn-container"></div>'); 54 var silence = $('<a class="col s6 btn-flat notification-button active"></a>'); 55 silence.append('<i class="material-icons">notifications_active</i>'); 56 silence.attr('test', test); 57 silence.attr('title', 'Disable notifications'); 58 silence.appendTo(btnContainer); 59 silence.click(toggleNotifications); 60 61 var clear = $('<a class="col s6 btn-flat remove-button"></a>'); 62 clear.append('<i class="material-icons">clear</i>'); 63 clear.attr('test', test); 64 clear.attr('title', 'Remove favorite'); 65 clear.appendTo(btnContainer); 66 clear.click(removeFavorite); 67 68 btnContainer.appendTo(wrapper); 69 70 wrapper.prependTo('#options').hide() 71 .slideDown(150); 72 $('#input-box').val(null); 73 Materialize.updateTextFields(); 74 }).always(function() { 75 $('#add-button').removeClass('disabled'); 76 }); 77 } 78 79 var toggleNotifications = function() { 80 var self = $(this); 81 if (self.hasClass('disabled')) { 82 return; 83 } 84 self.addClass('disabled'); 85 var test = self.attr('test'); 86 if (!(test in subscriptionMap)) { 87 return; 88 } 89 var muteStatus = self.hasClass('active'); 90 var element = self; 91 $.post('/api/favorites', { userFavoritesKey: subscriptionMap[test], muteNotifications: muteStatus}).then(function(data) { 92 element = self.clone(); 93 if (element.hasClass('active')) { 94 element.find('i').text('notifications_off') 95 element.removeClass('active'); 96 element.addClass('inactive'); 97 element.attr('title', 'Enable notifications'); 98 } else { 99 element.find('i').text('notifications_active') 100 element.removeClass('inactive'); 101 element.addClass('active'); 102 element.attr('title', 'Disable notifications'); 103 } 104 element.click(toggleNotifications); 105 self.replaceWith(function() { 106 return element; 107 }); 108 }).always(function() { 109 element.removeClass('disabled'); 110 }); 111 } 112 113 var removeFavorite = function() { 114 var self = $(this); 115 if (self.hasClass('disabled')) { 116 return; 117 } 118 var test = self.attr('test'); 119 if (!(test in subscriptionMap)) { 120 return; 121 } 122 self.addClass('disabled'); 123 $.ajax({ 124 url: '/api/favorites/' + subscriptionMap[test], 125 type: 'DELETE' 126 }).always(function() { 127 self.removeClass('disabled'); 128 }).then(function() { 129 delete subscriptionMap[test]; 130 self.parent().parent().slideUp(150, function() { 131 self.remove(); 132 }); 133 }); 134 } 135 136 var addFavoriteButton = function() { 137 var self = $(this); 138 var test = self.attr('test'); 139 140 $.post('/api/favorites', { testName: test}).then(function(data) { 141 if (data.key) { 142 subscriptionMap[test] = data.key; 143 144 self.children().text("star"); 145 self.switchClass("add-fav-button", "min-fav-button", 0); 146 147 self.off('click', addFavoriteButton); 148 self.on('click', removeFavoriteButton); 149 } 150 }) 151 .fail(function() { 152 alert( "Error occurred on registering your favorite test case!" ); 153 }); 154 } 155 156 var removeFavoriteButton = function() { 157 var self = $(this); 158 var test = self.attr('test'); 159 160 $.ajax({ 161 url: '/api/favorites/' + subscriptionMap[test], 162 type: 'DELETE' 163 }).then(function() { 164 delete subscriptionMap[test]; 165 166 self.children().text("star_border"); 167 self.switchClass("min-fav-button", "add-fav-button", 0); 168 169 self.off('click', removeFavoriteButton); 170 self.on('click', addFavoriteButton); 171 }); 172 } 173 174 $.widget('custom.sizedAutocomplete', $.ui.autocomplete, { 175 _resizeMenu: function() { 176 this.menu.element.outerWidth($('#input-box').width()); 177 } 178 }); 179 180 $(function() { 181 $('#input-box').sizedAutocomplete({ 182 source: allTests, 183 classes: { 184 'ui-autocomplete': 'card' 185 } 186 }); 187 188 $('#input-box').keyup(function(event) { 189 if (event.keyCode == 13) { // return button 190 $('#add-button').click(); 191 } 192 }); 193 194 $('.remove-button').click(removeFavorite); 195 $('.notification-button').click(toggleNotifications); 196 $('#add-button').click(addFavorite); 197 198 $('.add-fav-button').click(addFavoriteButton); 199 200 $('.min-fav-button').click(removeFavoriteButton); 201 202 $('#favoritesLink').click(function() { 203 window.open('/', '_self'); 204 }); 205 $('#allLink').click(function() { 206 window.open('/?showAll=true', '_self'); 207 }); 208 $('#acksLink').click(function() { 209 window.open('/show_test_acknowledgments', '_self'); 210 }); 211 }); 212 </script> 213 <div class='container wide'> 214 215 <c:if test="${!showAll}"> 216 <ul id="guide_collapsible" class="collapsible" data-collapsible="accordion"> 217 <li> 218 <div class="collapsible-header"> 219 <i class="material-icons">library_books</i> 220 Notice 221 <span class="new badge right" style="position: inherit;">1</span> 222 </div> 223 <div class="collapsible-body"> 224 <div class='row'> 225 <div class='col s12' style="margin: 15px 0px 0px 30px;"> 226 <c:choose> 227 <c:when test="${fn:endsWith(serverName, 'googleplex.com')}"> 228 <c:set var="dataVersion" scope="page" value="new"/> 229 <c:choose> 230 <c:when test="${fn:startsWith(serverName, 'android-vts-internal')}"> 231 <c:set var="dataLink" scope="page" value="https://android-vts.appspot.com"/> 232 </c:when> 233 <c:when test="${fn:startsWith(serverName, 'android-vts-staging')}"> 234 <c:set var="dataLink" scope="page" value="https://android-vts-staging.appspot.com"/> 235 </c:when> 236 <c:otherwise> 237 <c:set var="dataLink" scope="page" value="https://android-vts-staging.appspot.com"/> 238 </c:otherwise> 239 </c:choose> 240 </c:when> 241 <c:when test="${fn:endsWith(serverName, 'appspot.com')}"> 242 <c:set var="dataVersion" scope="page" value="previous"/> 243 <c:choose> 244 <c:when test="${fn:startsWith(serverName, 'android-vts-staging')}"> 245 <c:set var="dataLink" scope="page" value="https://android-vts-staging.googleplex.com"/> 246 </c:when> 247 <c:when test="${fn:startsWith(serverName, 'android-vts')}"> 248 <c:set var="dataLink" scope="page" value="https://android-vts-internal.googleplex.com"/> 249 </c:when> 250 <c:otherwise> 251 <c:set var="dataLink" scope="page" value="https://android-vts-staging.googleplex.com"/> 252 </c:otherwise> 253 </c:choose> 254 </c:when> 255 <c:otherwise> 256 <c:set var="dataVersion" scope="page" value="local dev"/> 257 <c:set var="dataLink" scope="page" value="http://localhost"/> 258 </c:otherwise> 259 </c:choose> 260 Recently, we launched new appspot servers for dashboard. Thus you will have two diffrent versions of server for each staging and production data. 261 <br/> 262 If you want to find the <c:out value = "${dataVersion}"/> test data, please visit the next url <a href="<c:out value = "${dataLink}"/>"><c:out value = "${dataLink}"/></a>. 263 </div> 264 </div> 265 </div> 266 </li> 267 </ul> 268 </c:if> 269 270 <c:choose> 271 <c:when test='${not empty error}'> 272 <div id='error-container' class='row card'> 273 <div class='col s12 center-align'> 274 <h5>${error}</h5> 275 </div> 276 </div> 277 </c:when> 278 <c:otherwise> 279 <div class='row home-tabs-row'> 280 <div class='col s12'> 281 <ul class='tabs'> 282 <li class='tab col s4' id='favoritesLink'><a class='${showAll ? "inactive" : "active"}'>Favorites</a></li> 283 <li class='tab col s4' id='allLink'><a class='${showAll ? "active" : "inactive"}'>All Tests</a></li> 284 <li class='tab col s4' id='acksLink'><a>Test Acknowledgements</a></li> 285 </ul> 286 </div> 287 </div> 288 <c:set var='width' value='${showAll ? 11 : 11}' /> 289 <c:if test='${not showAll}'> 290 <div class='row'> 291 <div class='input-field col s8'> 292 <input type='text' id='input-box'></input> 293 <label for='input-box'>Search for tests to add to favorites</label> 294 </div> 295 <div id='add-button-wrapper' class='col s1 valign-wrapper'> 296 <a id='add-button' class='btn-floating btn waves-effect waves-light red valign'><i class='material-icons'>add</i></a> 297 </div> 298 </div> 299 </c:if> 300 <div class='row' id='options'> 301 <c:forEach items='${testNames}' var='test'> 302 <div> 303 <a href='${resultsUrl}?testName=${test.name}'> 304 <div class='col s${width} card hoverable option valign-wrapper waves-effect'> 305 <span class='entry valign'>${test.name} 306 <c:if test='${test.failCount >= 0 && test.passCount >= 0}'> 307 <c:set var='color' value='${test.failCount > 0 ? "red" : (test.passCount > 0 ? "green" : "grey")}' /> 308 <span class='indicator right center ${color}'> 309 ${test.passCount} / ${test.passCount + test.failCount} 310 </span> 311 </c:if> 312 </span> 313 </div> 314 </a> 315 <c:choose> 316 <c:when test="${showAll}"> 317 <div class="col s1 center btn-container"> 318 <c:choose> 319 <c:when test="${test.isFavorite}"> 320 <a class="col s6 btn-flat min-fav-button" test="${test.name}" title="Remove favorite"> 321 <i class="material-icons">star</i> 322 </a> 323 </c:when> 324 <c:otherwise> 325 <a class="col s6 btn-flat add-fav-button" test="${test.name}" title="Add favorite"> 326 <i class="material-icons">star_border</i> 327 </a> 328 </c:otherwise> 329 </c:choose> 330 </div> 331 </c:when> 332 <c:otherwise> 333 <div class='col s1 center btn-container'> 334 <a class='col s6 btn-flat notification-button ${test.muteNotifications ? "inactive" : "active"}' test='${test.name}' title='${test.muteNotifications ? "Enable" : "Disable"} notifications'> 335 <i class='material-icons'>notifications_${test.muteNotifications ? "off" : "active"}</i> 336 </a> 337 <a class='col s6 btn-flat remove-button' test='${test.name}' title='Remove favorite'> 338 <i class='material-icons'>clear</i> 339 </a> 340 </div> 341 </c:otherwise> 342 </c:choose> 343 </div> 344 </c:forEach> 345 </div> 346 </c:otherwise> 347 </c:choose> 348 </div> 349 <%@ include file='footer.jsp' %> 350 </body> 351</html> 352