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

Side by Side Diff: gm/rebaseline_server/static/loader.js

Issue 44123004: rebaseline_server: UI improvements + set reviewed-by-human on commit (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: javascript_style_fix Created 7 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « gm/rebaseline_server/results.py ('k') | gm/rebaseline_server/static/view.html » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Loader: 2 * Loader:
3 * Reads GM result reports written out by results.py, and imports 3 * Reads GM result reports written out by results.py, and imports
4 * them into $scope.categories and $scope.testData . 4 * them into $scope.categories and $scope.testData .
5 */ 5 */
6 var Loader = angular.module( 6 var Loader = angular.module(
7 'Loader', 7 'Loader',
8 [] 8 []
9 ); 9 );
10 10
11 11
12 // TODO(epoger): Combine ALL of our filtering operations (including 12 // TODO(epoger): Combine ALL of our filtering operations (including
13 // truncation) into this one filter, so that runs most efficiently? 13 // truncation) into this one filter, so that runs most efficiently?
14 // (We would have to make sure truncation still took place after 14 // (We would have to make sure truncation still took place after
15 // sorting, though.) 15 // sorting, though.)
16 Loader.filter( 16 Loader.filter(
17 'removeHiddenItems', 17 'removeHiddenItems',
18 function() { 18 function() {
19 return function(unfilteredItems, hiddenResultTypes, hiddenConfigs, 19 return function(unfilteredItems, hiddenResultTypes, hiddenConfigs,
20 viewingTab) { 20 viewingTab) {
21 var filteredItems = []; 21 var filteredItems = [];
22 for (var i = 0; i < unfilteredItems.length; i++) { 22 for (var i = 0; i < unfilteredItems.length; i++) {
23 var item = unfilteredItems[i]; 23 var item = unfilteredItems[i];
24 » // For performance, we examine the "set" objects directly rather 24 // For performance, we examine the "set" objects directly rather
25 » // than calling $scope.isValueInSet(). 25 // than calling $scope.isValueInSet().
26 // Besides, I don't think we have access to $scope in here...
26 if (!(true == hiddenResultTypes[item.resultType]) && 27 if (!(true == hiddenResultTypes[item.resultType]) &&
27 !(true == hiddenConfigs[item.config]) && 28 !(true == hiddenConfigs[item.config]) &&
28 (viewingTab == item.tab)) { 29 (viewingTab == item.tab)) {
29 filteredItems.push(item); 30 filteredItems.push(item);
30 } 31 }
31 } 32 }
32 return filteredItems; 33 return filteredItems;
33 }; 34 };
34 } 35 }
35 ); 36 );
(...skipping 15 matching lines...) Expand all
51 $http.get("/results/" + resultsToLoad).success( 52 $http.get("/results/" + resultsToLoad).success(
52 function(data, status, header, config) { 53 function(data, status, header, config) {
53 $scope.loadingMessage = "Processing data, please wait..."; 54 $scope.loadingMessage = "Processing data, please wait...";
54 55
55 $scope.header = data.header; 56 $scope.header = data.header;
56 $scope.categories = data.categories; 57 $scope.categories = data.categories;
57 $scope.testData = data.testData; 58 $scope.testData = data.testData;
58 $scope.sortColumn = 'test'; 59 $scope.sortColumn = 'test';
59 $scope.showTodos = false; 60 $scope.showTodos = false;
60 61
62 $scope.showSubmitAdvancedSettings = false;
63 $scope.submitAdvancedSettings = {};
64 $scope.submitAdvancedSettings['reviewed-by-human'] = true;
65 $scope.submitAdvancedSettings['ignore-failures'] = false;
66 $scope.submitAdvancedSettings['bug'] = '';
67
61 // Create the list of tabs (lists into which the user can file each 68 // Create the list of tabs (lists into which the user can file each
62 // test). This may vary, depending on isEditable. 69 // test). This may vary, depending on isEditable.
63 $scope.tabs = [ 70 $scope.tabs = [
64 'Unfiled', 'Hidden' 71 'Unfiled', 'Hidden'
65 ]; 72 ];
66 if (data.header.isEditable) { 73 if (data.header.isEditable) {
67 $scope.tabs = $scope.tabs.concat( 74 $scope.tabs = $scope.tabs.concat(
68 ['Pending Approval']); 75 ['Pending Approval']);
69 } 76 }
70 $scope.defaultTab = $scope.tabs[0]; 77 $scope.defaultTab = $scope.tabs[0];
71 $scope.viewingTab = $scope.defaultTab; 78 $scope.viewingTab = $scope.defaultTab;
72 79
73 // Track the number of results on each tab. 80 // Track the number of results on each tab.
74 $scope.numResultsPerTab = {}; 81 $scope.numResultsPerTab = {};
75 for (var i = 0; i < $scope.tabs.length; i++) { 82 for (var i = 0; i < $scope.tabs.length; i++) {
76 $scope.numResultsPerTab[$scope.tabs[i]] = 0; 83 $scope.numResultsPerTab[$scope.tabs[i]] = 0;
77 } 84 }
78 $scope.numResultsPerTab[$scope.defaultTab] = $scope.testData.length; 85 $scope.numResultsPerTab[$scope.defaultTab] = $scope.testData.length;
79 86
80 // Add index and tab fields to all records. 87 // Add index and tab fields to all records.
81 for (var i = 0; i < $scope.testData.length; i++) { 88 for (var i = 0; i < $scope.testData.length; i++) {
82 $scope.testData[i].index = i; 89 $scope.testData[i].index = i;
83 $scope.testData[i].tab = $scope.defaultTab; 90 $scope.testData[i].tab = $scope.defaultTab;
84 } 91 }
85 92
86 » // Arrays within which the user can toggle individual elements. 93 // Arrays within which the user can toggle individual elements.
87 $scope.selectedItems = []; 94 $scope.selectedItems = [];
88 95
89 » // Sets within which the user can toggle individual elements. 96 // Sets within which the user can toggle individual elements.
90 $scope.hiddenResultTypes = { 97 $scope.hiddenResultTypes = {
91 'failure-ignored': true, 98 'failure-ignored': true,
92 'no-comparison': true, 99 'no-comparison': true,
93 'succeeded': true, 100 'succeeded': true,
94 }; 101 };
95 $scope.hiddenConfigs = {}; 102 $scope.hiddenConfigs = {};
96 103
97 $scope.updateResults(); 104 $scope.updateResults();
98 $scope.loadingMessage = ""; 105 $scope.loadingMessage = "";
99 $scope.windowTitle = "Current GM Results"; 106 $scope.windowTitle = "Current GM Results";
100 } 107 }
101 ).error( 108 ).error(
102 function(data, status, header, config) { 109 function(data, status, header, config) {
103 $scope.loadingMessage = "Failed to load results of type '" 110 $scope.loadingMessage = "Failed to load results of type '"
104 + resultsToLoad + "'"; 111 + resultsToLoad + "'";
105 $scope.windowTitle = "Failed to Load GM Results"; 112 $scope.windowTitle = "Failed to Load GM Results";
106 } 113 }
107 ); 114 );
108 115
109 116
110 // 117 //
118 // Select/Clear/Toggle all tests.
119 //
120
121 /**
122 * Select all currently showing tests.
123 */
124 $scope.selectAllItems = function() {
125 var numItemsShowing = $scope.limitedTestData.length;
126 for (var i = 0; i < numItemsShowing; i++) {
127 var index = $scope.limitedTestData[i].index;
128 if (!$scope.isValueInArray(index, $scope.selectedItems)) {
129 $scope.toggleValueInArray(index, $scope.selectedItems);
130 }
131 }
132 }
133
134 /**
135 * Deselect all currently showing tests.
136 */
137 $scope.clearAllItems = function() {
138 var numItemsShowing = $scope.limitedTestData.length;
139 for (var i = 0; i < numItemsShowing; i++) {
140 var index = $scope.limitedTestData[i].index;
141 if ($scope.isValueInArray(index, $scope.selectedItems)) {
142 $scope.toggleValueInArray(index, $scope.selectedItems);
143 }
144 }
145 }
146
147 /**
148 * Toggle selection of all currently showing tests.
149 */
150 $scope.toggleAllItems = function() {
151 var numItemsShowing = $scope.limitedTestData.length;
152 for (var i = 0; i < numItemsShowing; i++) {
153 var index = $scope.limitedTestData[i].index;
154 $scope.toggleValueInArray(index, $scope.selectedItems);
155 }
156 }
157
158
159 //
111 // Tab operations. 160 // Tab operations.
112 // 161 //
113 162
114 /** 163 /**
115 * Change the selected tab. 164 * Change the selected tab.
116 * 165 *
117 * @param tab (string): name of the tab to select 166 * @param tab (string): name of the tab to select
118 */ 167 */
119 $scope.setViewingTab = function(tab) { 168 $scope.setViewingTab = function(tab) {
120 $scope.viewingTab = tab; 169 $scope.viewingTab = tab;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 $scope.filteredTestData, $scope.displayLimit); 246 $scope.filteredTestData, $scope.displayLimit);
198 } else { 247 } else {
199 $scope.filteredTestData = 248 $scope.filteredTestData =
200 $filter("orderBy")( 249 $filter("orderBy")(
201 $filter("filter")( 250 $filter("filter")(
202 $scope.testData, 251 $scope.testData,
203 {tab: $scope.viewingTab}, 252 {tab: $scope.viewingTab},
204 true 253 true
205 ), 254 ),
206 $scope.sortColumn); 255 $scope.sortColumn);
207 $scope.limitedTestData = $filter("limitTo")( 256 $scope.limitedTestData = $scope.filteredTestData;
208 $scope.filteredTestData, $scope.displayLimit);
209 } 257 }
210 $scope.imageSize = $scope.imageSizePending; 258 $scope.imageSize = $scope.imageSizePending;
211 $scope.setUpdatesPending(false); 259 $scope.setUpdatesPending(false);
212 } 260 }
213 261
214 /** 262 /**
215 * Re-sort the displayed results. 263 * Re-sort the displayed results.
216 * 264 *
217 * @param sortColumn (string): name of the column to sort on 265 * @param sortColumn (string): name of the column to sort on
218 */ 266 */
219 $scope.sortResultsBy = function(sortColumn) { 267 $scope.sortResultsBy = function(sortColumn) {
220 $scope.sortColumn = sortColumn; 268 $scope.sortColumn = sortColumn;
221 $scope.updateResults(); 269 $scope.updateResults();
222 } 270 }
223 271
224 272
225 // 273 //
226 // Operations for sending info back to the server. 274 // Operations for sending info back to the server.
227 // 275 //
228 276
229 /** 277 /**
230 * Tell the server that the actual results of these particular tests 278 * Tell the server that the actual results of these particular tests
231 * are acceptable. 279 * are acceptable.
232 * 280 *
233 * @param testDataSubset an array of test results, most likely a subset of 281 * @param testDataSubset an array of test results, most likely a subset of
234 * $scope.testData (perhaps with some modifications) 282 * $scope.testData (perhaps with some modifications)
235 */ 283 */
236 $scope.submitApprovals = function(testDataSubset) { 284 $scope.submitApprovals = function(testDataSubset) {
237 $scope.submitPending = true; 285 $scope.submitPending = true;
286
287 // Convert bug text field to null or 1-item array.
288 var bugs = null;
289 var bugNumber = parseInt($scope.submitAdvancedSettings['bug']);
290 if (!isNaN(bugNumber)) {
291 bugs = [bugNumber];
292 }
293
294 // TODO(epoger): This is a suboptimal way to prevent users from
295 // rebaselining failures in alternative renderModes, but it does work.
296 // For a better solution, see
297 // https://code.google.com/p/skia/issues/detail?id=1748 ('gm: add new
298 // result type, RenderModeMismatch')
299 var encounteredComparisonConfig = false;
300
238 var newResults = []; 301 var newResults = [];
239 for (var i = 0; i < testDataSubset.length; i++) { 302 for (var i = 0; i < testDataSubset.length; i++) {
240 var actualResult = testDataSubset[i]; 303 var actualResult = testDataSubset[i];
241 var expectedResult = { 304 var expectedResult = {
242 builder: actualResult['builder'], 305 builder: actualResult['builder'],
243 test: actualResult['test'], 306 test: actualResult['test'],
244 config: actualResult['config'], 307 config: actualResult['config'],
245 expectedHashType: actualResult['actualHashType'], 308 expectedHashType: actualResult['actualHashType'],
246 expectedHashDigest: actualResult['actualHashDigest'], 309 expectedHashDigest: actualResult['actualHashDigest'],
247 }; 310 };
311 if (0 == expectedResult.config.indexOf('comparison-')) {
312 encounteredComparisonConfig = true;
313 }
314
315 // Advanced settings...
316 expectedResult['reviewed-by-human'] =
317 $scope.submitAdvancedSettings['reviewed-by-human'];
318 if (true == $scope.submitAdvancedSettings['ignore-failure']) {
319 // if it's false, don't send it at all (just keep the default)
320 expectedResult['ignoreFailure'] = true;
321 }
322 expectedResult['bugs'] = bugs;
323
248 newResults.push(expectedResult); 324 newResults.push(expectedResult);
249 } 325 }
326 if (encounteredComparisonConfig) {
327 alert("Approval failed -- you cannot approve results with config " +
328 "type comparison-*");
329 $scope.submitPending = false;
330 return;
331 }
250 $http({ 332 $http({
251 method: "POST", 333 method: "POST",
252 url: "/edits", 334 url: "/edits",
253 data: { 335 data: {
254 oldResultsType: $scope.header.type, 336 oldResultsType: $scope.header.type,
255 oldResultsHash: $scope.header.dataHash, 337 oldResultsHash: $scope.header.dataHash,
256 modifications: newResults 338 modifications: newResults
257 } 339 }
258 }).success(function(data, status, headers, config) { 340 }).success(function(data, status, headers, config) {
259 var itemIndicesToMove = []; 341 var itemIndicesToMove = [];
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 * 437 *
356 * @param secondsPastEpoch (numeric): seconds past epoch in UTC 438 * @param secondsPastEpoch (numeric): seconds past epoch in UTC
357 */ 439 */
358 $scope.localTimeString = function(secondsPastEpoch) { 440 $scope.localTimeString = function(secondsPastEpoch) {
359 var d = new Date(secondsPastEpoch * 1000); 441 var d = new Date(secondsPastEpoch * 1000);
360 return d.toString(); 442 return d.toString();
361 } 443 }
362 444
363 } 445 }
364 ); 446 );
OLDNEW
« no previous file with comments | « gm/rebaseline_server/results.py ('k') | gm/rebaseline_server/static/view.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698