blob: 292386b1902613ba251a835c660431fa893a0721 [file] [log] [blame]
epoger@google.comf9d134d2013-09-27 15:02:44 +00001<!DOCTYPE html>
2
epoger@google.com542b65f2013-10-15 20:10:33 +00003<html ng-app="Loader" ng-controller="Loader.Controller">
epoger@google.comf9d134d2013-09-27 15:02:44 +00004
5<head>
epoger@google.com542b65f2013-10-15 20:10:33 +00006 <title ng-bind="windowTitle"></title>
epoger@google.comf9d134d2013-09-27 15:02:44 +00007 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.js"></script>
8 <script src="loader.js"></script>
epoger@google.comeb832592013-10-23 15:07:26 +00009 <link rel="stylesheet" href="view.css">
epoger@google.comf9d134d2013-09-27 15:02:44 +000010</head>
11
12<body>
epoger@google.comdcb4e652013-10-11 18:45:33 +000013 <em>
14 {{loadingMessage}}
epoger@google.com5f2bb002013-10-02 18:57:48 +000015 </em>
epoger@google.comafaad3d2013-09-30 15:06:25 +000016
epoger@google.comeb832592013-10-23 15:07:26 +000017 <div ng-hide="!categories"><!-- everything: hide until data is loaded -->
18
epoger@google.comad0e5522013-10-24 15:38:27 +000019 <div class="warning-div"
20 ng-hide="!(header.isEditable && header.isExported)">
epoger@google.com9fb6c8a2013-10-09 18:05:58 +000021 WARNING! These results are editable and exported, so any user
22 who can connect to this server over the network can modify them.
23 </div>
epoger@google.comeb832592013-10-23 15:07:26 +000024
epoger@google.comad0e5522013-10-24 15:38:27 +000025 <div class="todo-div"><!-- TODOs -->
epoger@google.comeb832592013-10-23 15:07:26 +000026 <p>
27 TODO(epoger):
28 <input type="checkbox" name="showTodosCheckbox" value="true"
29 ng-checked="showTodos == true"
30 ng-click="showTodos = !showTodos">
31 show
32 <ul ng-hide="!showTodos">
33 <li>
34 If server was run with --reload flag, automatically check for
35 new results and tell the user when new results are available
36 (the user can reload the page if he wants to see them).
37 </li><li>
38 Add ability to filter builder and test names
39 (using a free-form text field, with partial string match)
40 </li><li>
41 Add more columns, such as pixel diffs, notes/bugs,
42 ignoreFailure boolean
43 </li><li>
44 Improve the column sorting, as per
45 <a href="http://jsfiddle.net/vojtajina/js64b/14/">
46 http://jsfiddle.net/vojtajina/js64b/14/
47 </a>
48 </li><li>
49 Right now, if you change which column is used to
50 sort the data, the column widths may fluctuate based on the
51 longest string <i>currently visible</i> within the top {{displayLimit}}
52 results. Can we fix the column widths to be wide enough to hold
53 any result, even the currently hidden results?
54 </li>
55 </ul>
56 </div><!-- TODOs -->
57
epoger@google.com542b65f2013-10-15 20:10:33 +000058 <div ng-hide="!(header.timeUpdated)">
59 Results current as of {{localTimeString(header.timeUpdated)}}
60 </div>
epoger@google.comeb832592013-10-23 15:07:26 +000061
epoger@google.comad0e5522013-10-24 15:38:27 +000062 <div><!-- tabs -->
63 <div class="tab-spacer" ng-repeat="tab in tabs">
epoger@google.comeb832592013-10-23 15:07:26 +000064 <div class="tab-{{tab == viewingTab}}"
epoger@google.comeb832592013-10-23 15:07:26 +000065 ng-click="setViewingTab(tab)">
66 &nbsp;{{tab}} ({{numResultsPerTab[tab]}})&nbsp;
67 </div>
epoger@google.comad0e5522013-10-24 15:38:27 +000068 <div class="tab-spacer">
epoger@google.comeb832592013-10-23 15:07:26 +000069 &nbsp;
70 </div>
71 </div>
72 </div><!-- tabs -->
73
epoger@google.comad0e5522013-10-24 15:38:27 +000074 <div class="tab-main"><!-- main display area of selected tab -->
epoger@google.comeb832592013-10-23 15:07:26 +000075
76 <br>
epoger@google.comad0e5522013-10-24 15:38:27 +000077 <!-- We only show the filters/settings table on the Unfiled tab. -->
epoger@google.comeb832592013-10-23 15:07:26 +000078 <table ng-hide="viewingTab != defaultTab" border="1">
epoger@google.com5f2bb002013-10-02 18:57:48 +000079 <tr>
80 <th colspan="2">
81 Filters
82 </th>
83 <th>
84 Settings
85 </th>
86 </tr>
87 <tr valign="top">
88 <td>
89 resultType<br>
90 <label ng-repeat="(resultType, count) in categories['resultType']">
91 <input type="checkbox"
92 name="resultTypes"
93 value="{{resultType}}"
epoger@google.comad0e5522013-10-24 15:38:27 +000094 ng-checked="!isValueInSet(resultType, hiddenResultTypes)"
95 ng-click="toggleValueInSet(resultType, hiddenResultTypes); setUpdatesPending(true)">
epoger@google.com5f2bb002013-10-02 18:57:48 +000096 {{resultType}} ({{count}})<br>
97 </label>
98 </td>
99 <td>
100 config<br>
101 <label ng-repeat="(config, count) in categories['config']">
102 <input type="checkbox"
103 name="configs"
104 value="{{config}}"
epoger@google.comad0e5522013-10-24 15:38:27 +0000105 ng-checked="!isValueInSet(config, hiddenConfigs)"
106 ng-click="toggleValueInSet(config, hiddenConfigs); setUpdatesPending(true)">
epoger@google.com5f2bb002013-10-02 18:57:48 +0000107 {{config}} ({{count}})<br>
108 </label>
109 </td>
110 <td><table>
111 <tr><td>
112 Image size
113 <input type="text" ng-model="imageSizePending"
114 ng-init="imageSizePending=100"
115 ng-change="areUpdatesPending = true"
116 maxlength="4"/>
117 </td></tr>
118 <tr><td>
119 Max records to display
120 <input type="text" ng-model="displayLimitPending"
121 ng-init="displayLimitPending=50"
122 ng-change="areUpdatesPending = true"
123 maxlength="4"/>
124 </td></tr>
125 <tr><td>
epoger@google.comad0e5522013-10-24 15:38:27 +0000126 <button class="update-results-button"
epoger@google.com5f2bb002013-10-02 18:57:48 +0000127 ng-click="updateResults()"
128 ng-disabled="!areUpdatesPending">
129 Update Results
130 </button>
131 </td></tr>
132 </tr></table></td>
133 </tr>
134 </table>
epoger@google.comf9d134d2013-09-27 15:02:44 +0000135
epoger@google.com5f2bb002013-10-02 18:57:48 +0000136 <p>
epoger@google.comeb832592013-10-23 15:07:26 +0000137
epoger@google.comad0e5522013-10-24 15:38:27 +0000138 <!-- Submission UI that we only show in the Pending Approval tab. -->
epoger@google.comeb832592013-10-23 15:07:26 +0000139 <div ng-hide="'Pending Approval' != viewingTab">
140 <div style="display:inline-block">
141 <button style="font-size:20px"
142 ng-click="submitApprovals(filteredTestData)"
143 ng-disabled="submitPending || (filteredTestData.length == 0)">
144 Update these {{filteredTestData.length}} expectations on the server
145 </button>
146 </div>
147 <div style="display:inline-block">
148 <div style="font-size:20px"
149 ng-hide="!submitPending">
150 Submitting, please wait...
151 </div>
152 </div>
153 </div>
154
155 <p>
156
157 <div>
158 <div style="float:left">
159 Found {{filteredTestData.length}} matches;
160 <span ng-hide="filteredTestData.length <= limitedTestData.length">
161 displaying the first {{limitedTestData.length}}
162 </span>
163 <span ng-hide="filteredTestData.length > limitedTestData.length">
164 displaying them all
165 </span>
166 <br>
167 (click on the column header radio buttons to re-sort by that column)
168 </div>
169 <div style="float:right">
170 <div ng-repeat="otherTab in tabs">
171 <button ng-click="moveSelectedItemsToTab(otherTab)"
172 ng-disabled="selectedItems.length == 0"
173 ng-hide="otherTab == viewingTab">
174 {{selectedItems.length}} move selected tests to {{otherTab}} tab
175 </button>
176 </div>
177 </div>
178 <div style="clear:both">
179 </div>
180 </div>
epoger@google.com5f2bb002013-10-02 18:57:48 +0000181 <br>
epoger@google.comeb832592013-10-23 15:07:26 +0000182
epoger@google.comf9d134d2013-09-27 15:02:44 +0000183 <table border="1">
184 <tr>
epoger@google.comad0e5522013-10-24 15:38:27 +0000185 <!-- Most column headers are displayed in a common fashion... -->
epoger@google.com5f2bb002013-10-02 18:57:48 +0000186 <th ng-repeat="categoryName in ['resultType', 'builder', 'test', 'config']">
187 <input type="radio"
188 name="sortColumnRadio"
189 value="{{categoryName}}"
190 ng-checked="(sortColumn == categoryName)"
191 ng-click="sortResultsBy(categoryName)">
192 {{categoryName}}
193 </th>
epoger@google.comad0e5522013-10-24 15:38:27 +0000194 <!-- ... but there are a few columns where we display things differently. -->
epoger@google.com5f2bb002013-10-02 18:57:48 +0000195 <th>
196 <input type="radio"
197 name="sortColumnRadio"
198 value="expectedHashDigest"
199 ng-checked="(sortColumn == 'expectedHashDigest')"
200 ng-click="sortResultsBy('expectedHashDigest')">
201 expected image
202 </th>
203 <th>
204 <input type="radio"
205 name="sortColumnRadio"
206 value="actualHashDigest"
207 ng-checked="(sortColumn == 'actualHashDigest')"
208 ng-click="sortResultsBy('actualHashDigest')">
209 actual image
210 </th>
epoger@google.comeb832592013-10-23 15:07:26 +0000211 <th>
epoger@google.com9fb6c8a2013-10-09 18:05:58 +0000212 <!-- item-selection checkbox column -->
epoger@google.com9fb6c8a2013-10-09 18:05:58 +0000213 </th>
epoger@google.comf9d134d2013-09-27 15:02:44 +0000214 </tr>
epoger@google.com5f2bb002013-10-02 18:57:48 +0000215 <tr ng-repeat="result in limitedTestData">
216 <td>{{result.resultType}}</td>
epoger@google.comf9d134d2013-09-27 15:02:44 +0000217 <td>{{result.builder}}</td>
218 <td>{{result.test}}</td>
219 <td>{{result.config}}</td>
220 <td>
epoger@google.comdcb4e652013-10-11 18:45:33 +0000221 <a target="_blank" href="http://chromium-skia-gm.commondatastorage.googleapis.com/gm/{{result.expectedHashType}}/{{result.test}}/{{result.expectedHashDigest}}.png">
epoger@google.comf9d134d2013-09-27 15:02:44 +0000222 <img width="{{imageSize}}" src="http://chromium-skia-gm.commondatastorage.googleapis.com/gm/{{result.expectedHashType}}/{{result.test}}/{{result.expectedHashDigest}}.png"/>
223 </a>
224 </td>
225 <td>
epoger@google.comdcb4e652013-10-11 18:45:33 +0000226 <a target="_blank" href="http://chromium-skia-gm.commondatastorage.googleapis.com/gm/{{result.actualHashType}}/{{result.test}}/{{result.actualHashDigest}}.png">
227 <img width="{{imageSize}}" src="http://chromium-skia-gm.commondatastorage.googleapis.com/gm/{{result.actualHashType}}/{{result.test}}/{{result.actualHashDigest}}.png"/>
epoger@google.comf9d134d2013-09-27 15:02:44 +0000228 </a>
229 </td>
epoger@google.comeb832592013-10-23 15:07:26 +0000230 <td>
epoger@google.com9fb6c8a2013-10-09 18:05:58 +0000231 <input type="checkbox"
232 name="rowSelect"
233 value="{{result.index}}"
epoger@google.comad0e5522013-10-24 15:38:27 +0000234 ng-checked="isValueInArray(result.index, selectedItems)"
235 ng-click="toggleValueInArray(result.index, selectedItems)">
epoger@google.comf9d134d2013-09-27 15:02:44 +0000236 </tr>
237 </table>
epoger@google.comad0e5522013-10-24 15:38:27 +0000238 </div><!-- main display area of selected tab -->
epoger@google.comeb832592013-10-23 15:07:26 +0000239 </div><!-- everything: hide until data is loaded -->
epoger@google.comf9d134d2013-09-27 15:02:44 +0000240
241 <!-- TODO(epoger): Can we get the base URLs (commondatastorage and
242 issues list) from
243 http://skia.googlecode.com/svn/buildbot/site_config/global_variables.json
244 ? I tried importing the
245 http://skia.googlecode.com/svn/buildbot/skia_tools.js script and using
246 that to do so, but I got Access-Control-Allow-Origin errors.
247 -->
248
249</body>
250</html>