epoger@google.com | f9d134d | 2013-09-27 15:02:44 +0000 | [diff] [blame] | 1 | <!DOCTYPE html> |
| 2 | |
| 3 | <html ng-app="Loader"> |
| 4 | |
| 5 | <head> |
| 6 | <title>Current GM Results</title> |
| 7 | <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.js"></script> |
| 8 | <script src="loader.js"></script> |
| 9 | </head> |
| 10 | |
| 11 | <body> |
| 12 | <div ng-controller="Loader.Controller"> |
| 13 | |
epoger@google.com | afaad3d | 2013-09-30 15:06:25 +0000 | [diff] [blame] | 14 | <!-- TODO(epoger): Add some indication of how old the |
| 15 | expected/actual data is --> |
| 16 | |
epoger@google.com | 5f2bb00 | 2013-10-02 18:57:48 +0000 | [diff] [blame] | 17 | <em ng-hide="categories"> |
| 18 | Loading data, please wait... |
| 19 | </em> |
epoger@google.com | afaad3d | 2013-09-30 15:06:25 +0000 | [diff] [blame] | 20 | |
epoger@google.com | 5f2bb00 | 2013-10-02 18:57:48 +0000 | [diff] [blame] | 21 | <div ng-hide="!categories"> |
epoger@google.com | 9fb6c8a | 2013-10-09 18:05:58 +0000 | [diff] [blame] | 22 | <div ng-hide="!(header.isEditable && header.isExported)" |
| 23 | style="background-color:#ffbb00"> |
| 24 | WARNING! These results are editable and exported, so any user |
| 25 | who can connect to this server over the network can modify them. |
| 26 | </div> |
epoger@google.com | 5f2bb00 | 2013-10-02 18:57:48 +0000 | [diff] [blame] | 27 | <table border="1"> |
| 28 | <tr> |
| 29 | <th colspan="2"> |
| 30 | Filters |
| 31 | </th> |
| 32 | <th> |
| 33 | Settings |
| 34 | </th> |
| 35 | </tr> |
| 36 | <tr valign="top"> |
| 37 | <td> |
| 38 | resultType<br> |
| 39 | <label ng-repeat="(resultType, count) in categories['resultType']"> |
| 40 | <input type="checkbox" |
| 41 | name="resultTypes" |
| 42 | value="{{resultType}}" |
| 43 | ng-checked="!isHiddenResultType(resultType)" |
| 44 | ng-click="toggleHiddenResultType(resultType)"> |
| 45 | {{resultType}} ({{count}})<br> |
| 46 | </label> |
| 47 | </td> |
| 48 | <td> |
| 49 | config<br> |
| 50 | <label ng-repeat="(config, count) in categories['config']"> |
| 51 | <input type="checkbox" |
| 52 | name="configs" |
| 53 | value="{{config}}" |
| 54 | ng-checked="!isHiddenConfig(config)" |
| 55 | ng-click="toggleHiddenConfig(config)"> |
| 56 | {{config}} ({{count}})<br> |
| 57 | </label> |
| 58 | </td> |
| 59 | <td><table> |
| 60 | <tr><td> |
| 61 | Image size |
| 62 | <input type="text" ng-model="imageSizePending" |
| 63 | ng-init="imageSizePending=100" |
| 64 | ng-change="areUpdatesPending = true" |
| 65 | maxlength="4"/> |
| 66 | </td></tr> |
| 67 | <tr><td> |
| 68 | Max records to display |
| 69 | <input type="text" ng-model="displayLimitPending" |
| 70 | ng-init="displayLimitPending=50" |
| 71 | ng-change="areUpdatesPending = true" |
| 72 | maxlength="4"/> |
| 73 | </td></tr> |
| 74 | <tr><td> |
| 75 | <button style="font-size:30px" |
| 76 | ng-click="updateResults()" |
| 77 | ng-disabled="!areUpdatesPending"> |
| 78 | Update Results |
| 79 | </button> |
| 80 | </td></tr> |
| 81 | </tr></table></td> |
| 82 | </tr> |
| 83 | </table> |
epoger@google.com | f9d134d | 2013-09-27 15:02:44 +0000 | [diff] [blame] | 84 | |
| 85 | <p> |
epoger@google.com | 5f2bb00 | 2013-10-02 18:57:48 +0000 | [diff] [blame] | 86 | TODO(epoger): Add ability to filter builder and test names |
| 87 | (using a free-form text field, with partial string match) |
| 88 | <br> |
| 89 | TODO(epoger): Add more columns, such as pixel diffs, notes/bugs, |
| 90 | ignoreFailure boolean |
| 91 | <br> |
| 92 | TODO(epoger): Improve the column sorting, as per |
| 93 | <a href="http://jsfiddle.net/vojtajina/js64b/14/"> |
| 94 | http://jsfiddle.net/vojtajina/js64b/14/ |
| 95 | </a> |
| 96 | <br> |
| 97 | TODO(epoger): Right now, if you change which column is used to |
| 98 | sort the data, the column widths may fluctuate based on the |
| 99 | longest string <i>currently visible</i> within the top {{displayLimit}} |
| 100 | results. Can we fix the column widths to be wide enough to hold |
| 101 | any result, even the currently hidden results? |
| 102 | <p> |
| 103 | Found {{filteredTestData.length}} matches, and displaying the first |
| 104 | {{displayLimit}}: <br> |
| 105 | <!-- TODO(epoger): If (displayLimit <= filteredTestData.length), |
| 106 | modify this message to indicate that all results are shown. --> |
| 107 | (click on the column header radio buttons to re-sort by that column) |
| 108 | <br> |
epoger@google.com | f9d134d | 2013-09-27 15:02:44 +0000 | [diff] [blame] | 109 | <table border="1"> |
| 110 | <tr> |
epoger@google.com | 5f2bb00 | 2013-10-02 18:57:48 +0000 | [diff] [blame] | 111 | <th ng-repeat="categoryName in ['resultType', 'builder', 'test', 'config']"> |
| 112 | <input type="radio" |
| 113 | name="sortColumnRadio" |
| 114 | value="{{categoryName}}" |
| 115 | ng-checked="(sortColumn == categoryName)" |
| 116 | ng-click="sortResultsBy(categoryName)"> |
| 117 | {{categoryName}} |
| 118 | </th> |
| 119 | <th> |
| 120 | <input type="radio" |
| 121 | name="sortColumnRadio" |
| 122 | value="expectedHashDigest" |
| 123 | ng-checked="(sortColumn == 'expectedHashDigest')" |
| 124 | ng-click="sortResultsBy('expectedHashDigest')"> |
| 125 | expected image |
| 126 | </th> |
| 127 | <th> |
| 128 | <input type="radio" |
| 129 | name="sortColumnRadio" |
| 130 | value="actualHashDigest" |
| 131 | ng-checked="(sortColumn == 'actualHashDigest')" |
| 132 | ng-click="sortResultsBy('actualHashDigest')"> |
| 133 | actual image |
| 134 | </th> |
epoger@google.com | 9fb6c8a | 2013-10-09 18:05:58 +0000 | [diff] [blame] | 135 | <th ng-hide="!header.isEditable"> |
| 136 | <!-- item-selection checkbox column --> |
| 137 | {{selectedItems}} <!-- TODO(epoger): temporary debug output --> |
| 138 | </th> |
epoger@google.com | f9d134d | 2013-09-27 15:02:44 +0000 | [diff] [blame] | 139 | </tr> |
epoger@google.com | 5f2bb00 | 2013-10-02 18:57:48 +0000 | [diff] [blame] | 140 | <tr ng-repeat="result in limitedTestData"> |
| 141 | <td>{{result.resultType}}</td> |
epoger@google.com | f9d134d | 2013-09-27 15:02:44 +0000 | [diff] [blame] | 142 | <td>{{result.builder}}</td> |
| 143 | <td>{{result.test}}</td> |
| 144 | <td>{{result.config}}</td> |
| 145 | <td> |
| 146 | <a target="_blank" href="http://chromium-skia-gm.commondatastorage.googleapis.com/gm/{{result.expectedHashType}}/{{result.test}}/{{result.expectedHashDigest}}.png"> |
| 147 | <img width="{{imageSize}}" src="http://chromium-skia-gm.commondatastorage.googleapis.com/gm/{{result.expectedHashType}}/{{result.test}}/{{result.expectedHashDigest}}.png"/> |
| 148 | </a> |
| 149 | </td> |
| 150 | <td> |
| 151 | <a target="_blank" href="http://chromium-skia-gm.commondatastorage.googleapis.com/gm/{{result.actualHashType}}/{{result.test}}/{{result.actualHashDigest}}.png"> |
| 152 | <img width="{{imageSize}}" src="http://chromium-skia-gm.commondatastorage.googleapis.com/gm/{{result.actualHashType}}/{{result.test}}/{{result.actualHashDigest}}.png"/> |
| 153 | </a> |
| 154 | </td> |
epoger@google.com | 9fb6c8a | 2013-10-09 18:05:58 +0000 | [diff] [blame] | 155 | <td ng-hide="!header.isEditable"> |
| 156 | <input type="checkbox" |
| 157 | name="rowSelect" |
| 158 | value="{{result.index}}" |
| 159 | ng-checked="isItemSelected(result.index)" |
| 160 | ng-click="toggleItemSelected(result.index)"> |
epoger@google.com | f9d134d | 2013-09-27 15:02:44 +0000 | [diff] [blame] | 161 | </tr> |
| 162 | </table> |
| 163 | </div> |
epoger@google.com | 5f2bb00 | 2013-10-02 18:57:48 +0000 | [diff] [blame] | 164 | </div> |
epoger@google.com | f9d134d | 2013-09-27 15:02:44 +0000 | [diff] [blame] | 165 | |
| 166 | <!-- TODO(epoger): Can we get the base URLs (commondatastorage and |
| 167 | issues list) from |
| 168 | http://skia.googlecode.com/svn/buildbot/site_config/global_variables.json |
| 169 | ? I tried importing the |
| 170 | http://skia.googlecode.com/svn/buildbot/skia_tools.js script and using |
| 171 | that to do so, but I got Access-Control-Allow-Origin errors. |
| 172 | --> |
| 173 | |
| 174 | </body> |
| 175 | </html> |