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

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

Issue 178253010: rebaseline_server: use new intermediate JSON format (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: incorporate Ravi's suggestions Created 6 years, 10 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
« no previous file with comments | « gm/rebaseline_server/static/constants.js ('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.extraColumnHeaders and $scope.imagePairs .
5 */ 5 */
6 var Loader = angular.module( 6 var Loader = angular.module(
7 'Loader', 7 'Loader',
8 ['diff_viewer'] 8 ['ConstantsModule', 'diff_viewer']
9 ); 9 );
10 10
11
12 // TODO(epoger): Combine ALL of our filtering operations (including 11 // TODO(epoger): Combine ALL of our filtering operations (including
13 // truncation) into this one filter, so that runs most efficiently? 12 // truncation) into this one filter, so that runs most efficiently?
14 // (We would have to make sure truncation still took place after 13 // (We would have to make sure truncation still took place after
15 // sorting, though.) 14 // sorting, though.)
16 Loader.filter( 15 Loader.filter(
17 'removeHiddenItems', 16 'removeHiddenImagePairs',
18 function() { 17 function(constants) {
19 return function(unfilteredItems, hiddenResultTypes, hiddenConfigs, 18 return function(unfilteredImagePairs, hiddenResultTypes, hiddenConfigs,
20 builderSubstring, testSubstring, viewingTab) { 19 builderSubstring, testSubstring, viewingTab) {
21 var filteredItems = []; 20 var filteredImagePairs = [];
22 for (var i = 0; i < unfilteredItems.length; i++) { 21 for (var i = 0; i < unfilteredImagePairs.length; i++) {
23 var item = unfilteredItems[i]; 22 var imagePair = unfilteredImagePairs[i];
23 var extraColumnValues = imagePair[constants.KEY__EXTRA_COLUMN_VALUES];
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 // Besides, I don't think we have access to $scope in here...
27 if (!(true == hiddenResultTypes[item.resultType]) && 27 if (!(true == hiddenResultTypes[extraColumnValues[
28 !(true == hiddenConfigs[item.config]) && 28 constants.KEY__EXTRACOLUMN__RESULT_TYPE]]) &&
29 !(-1 == item.builder.indexOf(builderSubstring)) && 29 !(true == hiddenConfigs[extraColumnValues[
30 !(-1 == item.test.indexOf(testSubstring)) && 30 constants.KEY__EXTRACOLUMN__CONFIG]]) &&
31 (viewingTab == item.tab)) { 31 !(-1 == extraColumnValues[constants.KEY__EXTRACOLUMN__BUILDER]
32 filteredItems.push(item); 32 .indexOf(builderSubstring)) &&
33 !(-1 == extraColumnValues[constants.KEY__EXTRACOLUMN__TEST]
34 .indexOf(testSubstring)) &&
35 (viewingTab == imagePair.tab)) {
36 filteredImagePairs.push(imagePair);
33 } 37 }
34 } 38 }
35 return filteredItems; 39 return filteredImagePairs;
36 }; 40 };
37 } 41 }
38 ); 42 );
39 43
40 44
41 Loader.controller( 45 Loader.controller(
42 'Loader.Controller', 46 'Loader.Controller',
43 function($scope, $http, $filter, $location, $timeout) { 47 function($scope, $http, $filter, $location, $timeout, constants) {
48 $scope.constants = constants;
44 $scope.windowTitle = "Loading GM Results..."; 49 $scope.windowTitle = "Loading GM Results...";
45 $scope.resultsToLoad = $location.search().resultsToLoad; 50 $scope.resultsToLoad = $location.search().resultsToLoad;
46 $scope.loadingMessage = "Loading results of type '" + $scope.resultsToLoad + 51 $scope.loadingMessage = "Loading results of type '" + $scope.resultsToLoad +
47 "', please wait..."; 52 "', please wait...";
48 53
49 /** 54 /**
50 * On initial page load, load a full dictionary of results. 55 * On initial page load, load a full dictionary of results.
51 * Once the dictionary is loaded, unhide the page elements so they can 56 * Once the dictionary is loaded, unhide the page elements so they can
52 * render the data. 57 * render the data.
53 */ 58 */
54 $http.get("/results/" + $scope.resultsToLoad).success( 59 $http.get("/results/" + $scope.resultsToLoad).success(
55 function(data, status, header, config) { 60 function(data, status, header, config) {
56 if (data.header.resultsStillLoading) { 61 var dataHeader = data[constants.KEY__HEADER];
62 if (dataHeader[constants.KEY__HEADER__IS_STILL_LOADING]) {
57 $scope.loadingMessage = 63 $scope.loadingMessage =
58 "Server is still loading results; will retry at " + 64 "Server is still loading results; will retry at " +
59 $scope.localTimeString(data.header.timeNextUpdateAvailable); 65 $scope.localTimeString(dataHeader[
66 constants.KEY__HEADER__TIME_NEXT_UPDATE_AVAILABLE]);
60 $timeout( 67 $timeout(
61 function(){location.reload();}, 68 function(){location.reload();},
62 (data.header.timeNextUpdateAvailable * 1000) - new Date().getTime( )); 69 (dataHeader[constants.KEY__HEADER__TIME_NEXT_UPDATE_AVAILABLE]
70 * 1000) - new Date().getTime());
63 } else { 71 } else {
64 $scope.loadingMessage = "Processing data, please wait..."; 72 $scope.loadingMessage = "Processing data, please wait...";
65 73
66 $scope.header = data.header; 74 $scope.header = dataHeader;
67 $scope.categories = data.categories; 75 $scope.extraColumnHeaders = data[constants.KEY__EXTRACOLUMNHEADERS];
68 $scope.testData = data.testData; 76 $scope.imagePairs = data[constants.KEY__IMAGEPAIRS];
69 $scope.sortColumn = 'weightedDiffMeasure'; 77 $scope.imageSets = data[constants.KEY__IMAGESETS];
78 $scope.sortColumnSubdict = constants.KEY__DIFFERENCE_DATA;
79 $scope.sortColumnKey = constants.KEY__DIFFERENCE_DATA__WEIGHTED_DIFF;
70 $scope.showTodos = false; 80 $scope.showTodos = false;
71 81
72 $scope.showSubmitAdvancedSettings = false; 82 $scope.showSubmitAdvancedSettings = false;
73 $scope.submitAdvancedSettings = {}; 83 $scope.submitAdvancedSettings = {};
74 $scope.submitAdvancedSettings['reviewed-by-human'] = true; 84 $scope.submitAdvancedSettings[
75 $scope.submitAdvancedSettings['ignore-failure'] = false; 85 constants.KEY__EXPECTATIONS__REVIEWED] = true;
86 $scope.submitAdvancedSettings[
87 constants.KEY__EXPECTATIONS__IGNOREFAILURE] = false;
76 $scope.submitAdvancedSettings['bug'] = ''; 88 $scope.submitAdvancedSettings['bug'] = '';
77 89
78 // Create the list of tabs (lists into which the user can file each 90 // Create the list of tabs (lists into which the user can file each
79 // test). This may vary, depending on isEditable. 91 // test). This may vary, depending on isEditable.
80 $scope.tabs = [ 92 $scope.tabs = [
81 'Unfiled', 'Hidden' 93 'Unfiled', 'Hidden'
82 ]; 94 ];
83 if (data.header.isEditable) { 95 if (dataHeader[constants.KEY__HEADER__IS_EDITABLE]) {
84 $scope.tabs = $scope.tabs.concat( 96 $scope.tabs = $scope.tabs.concat(
85 ['Pending Approval']); 97 ['Pending Approval']);
86 } 98 }
87 $scope.defaultTab = $scope.tabs[0]; 99 $scope.defaultTab = $scope.tabs[0];
88 $scope.viewingTab = $scope.defaultTab; 100 $scope.viewingTab = $scope.defaultTab;
89 101
90 // Track the number of results on each tab. 102 // Track the number of results on each tab.
91 $scope.numResultsPerTab = {}; 103 $scope.numResultsPerTab = {};
92 for (var i = 0; i < $scope.tabs.length; i++) { 104 for (var i = 0; i < $scope.tabs.length; i++) {
93 $scope.numResultsPerTab[$scope.tabs[i]] = 0; 105 $scope.numResultsPerTab[$scope.tabs[i]] = 0;
94 } 106 }
95 $scope.numResultsPerTab[$scope.defaultTab] = $scope.testData.length; 107 $scope.numResultsPerTab[$scope.defaultTab] = $scope.imagePairs.length;
96 108
97 // Add index and tab fields to all records. 109 // Add index and tab fields to all records.
98 for (var i = 0; i < $scope.testData.length; i++) { 110 for (var i = 0; i < $scope.imagePairs.length; i++) {
99 $scope.testData[i].index = i; 111 $scope.imagePairs[i].index = i;
100 $scope.testData[i].tab = $scope.defaultTab; 112 $scope.imagePairs[i].tab = $scope.defaultTab;
101 } 113 }
102 114
103 // Arrays within which the user can toggle individual elements. 115 // Arrays within which the user can toggle individual elements.
104 $scope.selectedItems = []; 116 $scope.selectedImagePairs = [];
105 117
106 // Sets within which the user can toggle individual elements. 118 // Sets within which the user can toggle individual elements.
107 $scope.hiddenResultTypes = { 119 $scope.hiddenResultTypes = {};
108 'failure-ignored': true, 120 $scope.hiddenResultTypes[
109 'no-comparison': true, 121 constants.KEY__RESULT_TYPE__FAILUREIGNORED] = true;
110 'succeeded': true, 122 $scope.hiddenResultTypes[
111 }; 123 constants.KEY__RESULT_TYPE__NOCOMPARISON] = true;
112 $scope.allResultTypes = Object.keys(data.categories['resultType']); 124 $scope.hiddenResultTypes[
125 constants.KEY__RESULT_TYPE__SUCCEEDED] = true;
126 $scope.allResultTypes = Object.keys(
127 $scope.extraColumnHeaders[constants.KEY__EXTRACOLUMN__RESULT_TYPE]
128 [constants.KEY__VALUES_AND_COUNTS]);
113 $scope.hiddenConfigs = {}; 129 $scope.hiddenConfigs = {};
114 $scope.allConfigs = Object.keys(data.categories['config']); 130 $scope.allConfigs = Object.keys(
131 $scope.extraColumnHeaders[constants.KEY__EXTRACOLUMN__CONFIG]
132 [constants.KEY__VALUES_AND_COUNTS]);
115 133
116 // Associative array of partial string matches per category. 134 // Associative array of partial string matches per category.
117 $scope.categoryValueMatch = {}; 135 $scope.categoryValueMatch = {};
118 $scope.categoryValueMatch.builder = ""; 136 $scope.categoryValueMatch.builder = "";
119 $scope.categoryValueMatch.test = ""; 137 $scope.categoryValueMatch.test = "";
120 138
121 // If any defaults were overridden in the URL, get them now. 139 // If any defaults were overridden in the URL, get them now.
122 $scope.queryParameters.load(); 140 $scope.queryParameters.load();
123 141
124 $scope.updateResults(); 142 $scope.updateResults();
(...skipping 10 matching lines...) Expand all
135 ); 153 );
136 154
137 155
138 // 156 //
139 // Select/Clear/Toggle all tests. 157 // Select/Clear/Toggle all tests.
140 // 158 //
141 159
142 /** 160 /**
143 * Select all currently showing tests. 161 * Select all currently showing tests.
144 */ 162 */
145 $scope.selectAllItems = function() { 163 $scope.selectAllImagePairs = function() {
146 var numItemsShowing = $scope.limitedTestData.length; 164 var numImagePairsShowing = $scope.limitedImagePairs.length;
147 for (var i = 0; i < numItemsShowing; i++) { 165 for (var i = 0; i < numImagePairsShowing; i++) {
148 var index = $scope.limitedTestData[i].index; 166 var index = $scope.limitedImagePairs[i].index;
149 if (!$scope.isValueInArray(index, $scope.selectedItems)) { 167 if (!$scope.isValueInArray(index, $scope.selectedImagePairs)) {
150 $scope.toggleValueInArray(index, $scope.selectedItems); 168 $scope.toggleValueInArray(index, $scope.selectedImagePairs);
151 } 169 }
152 } 170 }
153 } 171 }
154 172
155 /** 173 /**
156 * Deselect all currently showing tests. 174 * Deselect all currently showing tests.
157 */ 175 */
158 $scope.clearAllItems = function() { 176 $scope.clearAllImagePairs = function() {
159 var numItemsShowing = $scope.limitedTestData.length; 177 var numImagePairsShowing = $scope.limitedImagePairs.length;
160 for (var i = 0; i < numItemsShowing; i++) { 178 for (var i = 0; i < numImagePairsShowing; i++) {
161 var index = $scope.limitedTestData[i].index; 179 var index = $scope.limitedImagePairs[i].index;
162 if ($scope.isValueInArray(index, $scope.selectedItems)) { 180 if ($scope.isValueInArray(index, $scope.selectedImagePairs)) {
163 $scope.toggleValueInArray(index, $scope.selectedItems); 181 $scope.toggleValueInArray(index, $scope.selectedImagePairs);
164 } 182 }
165 } 183 }
166 } 184 }
167 185
168 /** 186 /**
169 * Toggle selection of all currently showing tests. 187 * Toggle selection of all currently showing tests.
170 */ 188 */
171 $scope.toggleAllItems = function() { 189 $scope.toggleAllImagePairs = function() {
172 var numItemsShowing = $scope.limitedTestData.length; 190 var numImagePairsShowing = $scope.limitedImagePairs.length;
173 for (var i = 0; i < numItemsShowing; i++) { 191 for (var i = 0; i < numImagePairsShowing; i++) {
174 var index = $scope.limitedTestData[i].index; 192 var index = $scope.limitedImagePairs[i].index;
175 $scope.toggleValueInArray(index, $scope.selectedItems); 193 $scope.toggleValueInArray(index, $scope.selectedImagePairs);
176 } 194 }
177 } 195 }
178 196
179 197
180 // 198 //
181 // Tab operations. 199 // Tab operations.
182 // 200 //
183 201
184 /** 202 /**
185 * Change the selected tab. 203 * Change the selected tab.
186 * 204 *
187 * @param tab (string): name of the tab to select 205 * @param tab (string): name of the tab to select
188 */ 206 */
189 $scope.setViewingTab = function(tab) { 207 $scope.setViewingTab = function(tab) {
190 $scope.viewingTab = tab; 208 $scope.viewingTab = tab;
191 $scope.updateResults(); 209 $scope.updateResults();
192 } 210 }
193 211
194 /** 212 /**
195 * Move the items in $scope.selectedItems to a different tab, 213 * Move the imagePairs in $scope.selectedImagePairs to a different tab,
196 * and then clear $scope.selectedItems. 214 * and then clear $scope.selectedImagePairs.
197 * 215 *
198 * @param newTab (string): name of the tab to move the tests to 216 * @param newTab (string): name of the tab to move the tests to
199 */ 217 */
200 $scope.moveSelectedItemsToTab = function(newTab) { 218 $scope.moveSelectedImagePairsToTab = function(newTab) {
201 $scope.moveItemsToTab($scope.selectedItems, newTab); 219 $scope.moveImagePairsToTab($scope.selectedImagePairs, newTab);
202 $scope.selectedItems = []; 220 $scope.selectedImagePairs = [];
203 $scope.updateResults(); 221 $scope.updateResults();
204 } 222 }
205 223
206 /** 224 /**
207 * Move a subset of $scope.testData to a different tab. 225 * Move a subset of $scope.imagePairs to a different tab.
208 * 226 *
209 * @param itemIndices (array of ints): indices into $scope.testData 227 * @param imagePairIndices (array of ints): indices into $scope.imagePairs
210 * indicating which test results to move 228 * indicating which test results to move
211 * @param newTab (string): name of the tab to move the tests to 229 * @param newTab (string): name of the tab to move the tests to
212 */ 230 */
213 $scope.moveItemsToTab = function(itemIndices, newTab) { 231 $scope.moveImagePairsToTab = function(imagePairIndices, newTab) {
214 var itemIndex; 232 var imagePairIndex;
215 var numItems = itemIndices.length; 233 var numImagePairs = imagePairIndices.length;
216 for (var i = 0; i < numItems; i++) { 234 for (var i = 0; i < numImagePairs; i++) {
217 itemIndex = itemIndices[i]; 235 imagePairIndex = imagePairIndices[i];
218 $scope.numResultsPerTab[$scope.testData[itemIndex].tab]--; 236 $scope.numResultsPerTab[$scope.imagePairs[imagePairIndex].tab]--;
219 $scope.testData[itemIndex].tab = newTab; 237 $scope.imagePairs[imagePairIndex].tab = newTab;
220 } 238 }
221 $scope.numResultsPerTab[newTab] += numItems; 239 $scope.numResultsPerTab[newTab] += numImagePairs;
222 } 240 }
223 241
224 242
225 // 243 //
226 // $scope.queryParameters: 244 // $scope.queryParameters:
227 // Transfer parameter values between $scope and the URL query string. 245 // Transfer parameter values between $scope and the URL query string.
228 // 246 //
229 $scope.queryParameters = {}; 247 $scope.queryParameters = {};
230 248
231 // load and save functions for parameters of each type 249 // load and save functions for parameters of each type
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 } 288 }
271 }, 289 },
272 290
273 }; 291 };
274 292
275 // parameter name -> copier objects to load/save parameter value 293 // parameter name -> copier objects to load/save parameter value
276 $scope.queryParameters.map = { 294 $scope.queryParameters.map = {
277 'resultsToLoad': $scope.queryParameters.copiers.simple, 295 'resultsToLoad': $scope.queryParameters.copiers.simple,
278 'displayLimitPending': $scope.queryParameters.copiers.simple, 296 'displayLimitPending': $scope.queryParameters.copiers.simple,
279 'imageSizePending': $scope.queryParameters.copiers.simple, 297 'imageSizePending': $scope.queryParameters.copiers.simple,
280 'sortColumn': $scope.queryParameters.copiers.simple, 298 'sortColumnSubdict': $scope.queryParameters.copiers.simple,
281 299 'sortColumnKey': $scope.queryParameters.copiers.simple,
282 'builder': $scope.queryParameters.copiers.categoryValueMatch,
283 'test': $scope.queryParameters.copiers.categoryValueMatch,
284 300
285 'hiddenResultTypes': $scope.queryParameters.copiers.set, 301 'hiddenResultTypes': $scope.queryParameters.copiers.set,
286 'hiddenConfigs': $scope.queryParameters.copiers.set, 302 'hiddenConfigs': $scope.queryParameters.copiers.set,
287 }; 303 };
304 $scope.queryParameters.map[constants.KEY__EXTRACOLUMN__BUILDER] =
305 $scope.queryParameters.copiers.categoryValueMatch;
306 $scope.queryParameters.map[constants.KEY__EXTRACOLUMN__TEST] =
307 $scope.queryParameters.copiers.categoryValueMatch;
288 308
289 // Loads all parameters into $scope from the URL query string; 309 // Loads all parameters into $scope from the URL query string;
290 // any which are not found within the URL will keep their current value. 310 // any which are not found within the URL will keep their current value.
291 $scope.queryParameters.load = function() { 311 $scope.queryParameters.load = function() {
292 var nameValuePairs = $location.search(); 312 var nameValuePairs = $location.search();
293 angular.forEach($scope.queryParameters.map, 313 angular.forEach($scope.queryParameters.map,
294 function(copier, paramName) { 314 function(copier, paramName) {
295 copier.load(nameValuePairs, paramName); 315 copier.load(nameValuePairs, paramName);
296 } 316 }
297 ); 317 );
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 352
333 /** 353 /**
334 * Update the displayed results, based on filters/settings, 354 * Update the displayed results, based on filters/settings,
335 * and call $scope.queryParameters.save() so that the new filter results 355 * and call $scope.queryParameters.save() so that the new filter results
336 * can be bookmarked. 356 * can be bookmarked.
337 */ 357 */
338 $scope.updateResults = function() { 358 $scope.updateResults = function() {
339 $scope.displayLimit = $scope.displayLimitPending; 359 $scope.displayLimit = $scope.displayLimitPending;
340 // TODO(epoger): Every time we apply a filter, AngularJS creates 360 // TODO(epoger): Every time we apply a filter, AngularJS creates
341 // another copy of the array. Is there a way we can filter out 361 // another copy of the array. Is there a way we can filter out
342 // the items as they are displayed, rather than storing multiple 362 // the imagePairs as they are displayed, rather than storing multiple
343 // array copies? (For better performance.) 363 // array copies? (For better performance.)
344 364
345 if ($scope.viewingTab == $scope.defaultTab) { 365 if ($scope.viewingTab == $scope.defaultTab) {
346 366
347 // TODO(epoger): Until we allow the user to reverse sort order, 367 // TODO(epoger): Until we allow the user to reverse sort order,
348 // there are certain columns we want to sort in a different order. 368 // there are certain columns we want to sort in a different order.
349 var doReverse = ( 369 var doReverse = (
350 ($scope.sortColumn == 'percentDifferingPixels') || 370 ($scope.sortColumnKey ==
351 ($scope.sortColumn == 'weightedDiffMeasure')); 371 constants.KEY__DIFFERENCE_DATA__PERCENT_DIFF_PIXELS) ||
372 ($scope.sortColumnKey ==
373 constants.KEY__DIFFERENCE_DATA__WEIGHTED_DIFF));
352 374
353 $scope.filteredTestData = 375 $scope.filteredImagePairs =
354 $filter("orderBy")( 376 $filter("orderBy")(
355 $filter("removeHiddenItems")( 377 $filter("removeHiddenImagePairs")(
356 $scope.testData, 378 $scope.imagePairs,
357 $scope.hiddenResultTypes, 379 $scope.hiddenResultTypes,
358 $scope.hiddenConfigs, 380 $scope.hiddenConfigs,
359 $scope.categoryValueMatch.builder, 381 $scope.categoryValueMatch.builder,
360 $scope.categoryValueMatch.test, 382 $scope.categoryValueMatch.test,
361 $scope.viewingTab 383 $scope.viewingTab
362 ), 384 ),
363 $scope.sortColumn, doReverse); 385 $scope.getSortColumnValue, doReverse);
364 $scope.limitedTestData = $filter("limitTo")( 386 $scope.limitedImagePairs = $filter("limitTo")(
365 $scope.filteredTestData, $scope.displayLimit); 387 $scope.filteredImagePairs, $scope.displayLimit);
366 } else { 388 } else {
367 $scope.filteredTestData = 389 $scope.filteredImagePairs =
368 $filter("orderBy")( 390 $filter("orderBy")(
369 $filter("filter")( 391 $filter("filter")(
370 $scope.testData, 392 $scope.imagePairs,
371 {tab: $scope.viewingTab}, 393 {tab: $scope.viewingTab},
372 true 394 true
373 ), 395 ),
374 $scope.sortColumn); 396 $scope.getSortColumnValue);
375 $scope.limitedTestData = $scope.filteredTestData; 397 $scope.limitedImagePairs = $scope.filteredImagePairs;
376 } 398 }
377 $scope.imageSize = $scope.imageSizePending; 399 $scope.imageSize = $scope.imageSizePending;
378 $scope.setUpdatesPending(false); 400 $scope.setUpdatesPending(false);
379 $scope.queryParameters.save(); 401 $scope.queryParameters.save();
380 } 402 }
381 403
382 /** 404 /**
383 * Re-sort the displayed results. 405 * Re-sort the displayed results.
384 * 406 *
385 * @param sortColumn (string): name of the column to sort on 407 * @param subdict (string): which subdictionary
408 * (constants.KEY__DIFFERENCE_DATA, constants.KEY__EXPECTATIONS_DATA,
409 * constants.KEY__EXTRA_COLUMN_VALUES) the sort column key is within
410 * @param key (string): sort by value associated with this key in subdict
386 */ 411 */
387 $scope.sortResultsBy = function(sortColumn) { 412 $scope.sortResultsBy = function(subdict, key) {
388 $scope.sortColumn = sortColumn; 413 $scope.sortColumnSubdict = subdict;
414 $scope.sortColumnKey = key;
389 $scope.updateResults(); 415 $scope.updateResults();
390 } 416 }
391 417
392 /** 418 /**
419 * For a particular ImagePair, return the value of the column we are
420 * sorting on (according to $scope.sortColumnSubdict and
421 * $scope.sortColumnKey).
422 *
423 * @param imagePair: imagePair to get a column value out of.
424 */
425 $scope.getSortColumnValue = function(imagePair) {
426 if ($scope.sortColumnSubdict in imagePair) {
427 return imagePair[$scope.sortColumnSubdict][$scope.sortColumnKey];
428 } else {
429 return undefined;
430 }
431 }
432
433 /**
393 * Set $scope.categoryValueMatch[name] = value, and update results. 434 * Set $scope.categoryValueMatch[name] = value, and update results.
394 * 435 *
395 * @param name 436 * @param name
396 * @param value 437 * @param value
397 */ 438 */
398 $scope.setCategoryValueMatch = function(name, value) { 439 $scope.setCategoryValueMatch = function(name, value) {
399 $scope.categoryValueMatch[name] = value; 440 $scope.categoryValueMatch[name] = value;
400 $scope.updateResults(); 441 $scope.updateResults();
401 } 442 }
402 443
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 490
450 491
451 // 492 //
452 // Operations for sending info back to the server. 493 // Operations for sending info back to the server.
453 // 494 //
454 495
455 /** 496 /**
456 * Tell the server that the actual results of these particular tests 497 * Tell the server that the actual results of these particular tests
457 * are acceptable. 498 * are acceptable.
458 * 499 *
459 * @param testDataSubset an array of test results, most likely a subset of 500 * TODO(epoger): This assumes that the original expectations are in
460 * $scope.testData (perhaps with some modifications) 501 * imageSetA, and the actuals are in imageSetB.
502 *
503 * @param imagePairsSubset an array of test results, most likely a subset of
504 * $scope.imagePairs (perhaps with some modifications)
461 */ 505 */
462 $scope.submitApprovals = function(testDataSubset) { 506 $scope.submitApprovals = function(imagePairsSubset) {
463 $scope.submitPending = true; 507 $scope.submitPending = true;
464 508
465 // Convert bug text field to null or 1-item array. 509 // Convert bug text field to null or 1-item array.
466 var bugs = null; 510 var bugs = null;
467 var bugNumber = parseInt($scope.submitAdvancedSettings['bug']); 511 var bugNumber = parseInt($scope.submitAdvancedSettings['bug']);
468 if (!isNaN(bugNumber)) { 512 if (!isNaN(bugNumber)) {
469 bugs = [bugNumber]; 513 bugs = [bugNumber];
470 } 514 }
471 515
472 // TODO(epoger): This is a suboptimal way to prevent users from 516 // TODO(epoger): This is a suboptimal way to prevent users from
473 // rebaselining failures in alternative renderModes, but it does work. 517 // rebaselining failures in alternative renderModes, but it does work.
474 // For a better solution, see 518 // For a better solution, see
475 // https://code.google.com/p/skia/issues/detail?id=1748 ('gm: add new 519 // https://code.google.com/p/skia/issues/detail?id=1748 ('gm: add new
476 // result type, RenderModeMismatch') 520 // result type, RenderModeMismatch')
477 var encounteredComparisonConfig = false; 521 var encounteredComparisonConfig = false;
478 522
479 var newResults = []; 523 var updatedExpectations = [];
480 for (var i = 0; i < testDataSubset.length; i++) { 524 for (var i = 0; i < imagePairsSubset.length; i++) {
481 var actualResult = testDataSubset[i]; 525 var imagePair = imagePairsSubset[i];
482 var expectedResult = { 526 var updatedExpectation = {};
483 builder: actualResult['builder'], 527 updatedExpectation[constants.KEY__EXPECTATIONS_DATA] =
484 test: actualResult['test'], 528 imagePair[constants.KEY__EXPECTATIONS_DATA];
485 config: actualResult['config'], 529 updatedExpectation[constants.KEY__EXTRA_COLUMN_VALUES] =
486 expectedHashType: actualResult['actualHashType'], 530 imagePair[constants.KEY__EXTRA_COLUMN_VALUES];
487 expectedHashDigest: actualResult['actualHashDigest'], 531 updatedExpectation[constants.KEY__NEW_IMAGE_URL] =
488 }; 532 imagePair[constants.KEY__IMAGE_B_URL];
489 if (0 == expectedResult.config.indexOf('comparison-')) { 533 if (0 == updatedExpectation[constants.KEY__EXTRA_COLUMN_VALUES]
534 [constants.KEY__EXTRACOLUMN__CONFIG]
535 .indexOf('comparison-')) {
490 encounteredComparisonConfig = true; 536 encounteredComparisonConfig = true;
491 } 537 }
492 538
493 // Advanced settings... 539 // Advanced settings...
494 expectedResult['reviewed-by-human'] = 540 if (null == updatedExpectation[constants.KEY__EXPECTATIONS_DATA]) {
495 $scope.submitAdvancedSettings['reviewed-by-human']; 541 updatedExpectation[constants.KEY__EXPECTATIONS_DATA] = {};
496 if (true == $scope.submitAdvancedSettings['ignore-failure']) { 542 }
543 updatedExpectation[constants.KEY__EXPECTATIONS_DATA]
544 [constants.KEY__EXPECTATIONS__REVIEWED] =
545 $scope.submitAdvancedSettings[
546 constants.KEY__EXPECTATIONS__REVIEWED];
547 if (true == $scope.submitAdvancedSettings[
548 constants.KEY__EXPECTATIONS__IGNOREFAILURE]) {
497 // if it's false, don't send it at all (just keep the default) 549 // if it's false, don't send it at all (just keep the default)
498 expectedResult['ignore-failure'] = true; 550 updatedExpectation[constants.KEY__EXPECTATIONS_DATA]
551 [constants.KEY__EXPECTATIONS__IGNOREFAILURE] = true;
499 } 552 }
500 expectedResult['bugs'] = bugs; 553 updatedExpectation[constants.KEY__EXPECTATIONS_DATA]
554 [constants.KEY__EXPECTATIONS__BUGS] = bugs;
501 555
502 newResults.push(expectedResult); 556 updatedExpectations.push(updatedExpectation);
503 } 557 }
504 if (encounteredComparisonConfig) { 558 if (encounteredComparisonConfig) {
505 alert("Approval failed -- you cannot approve results with config " + 559 alert("Approval failed -- you cannot approve results with config " +
506 "type comparison-*"); 560 "type comparison-*");
507 $scope.submitPending = false; 561 $scope.submitPending = false;
508 return; 562 return;
509 } 563 }
564 var modificationData = {};
565 modificationData[constants.KEY__EDITS__MODIFICATIONS] =
566 updatedExpectations;
567 modificationData[constants.KEY__EDITS__OLD_RESULTS_HASH] =
568 $scope.header[constants.KEY__HEADER__DATAHASH];
569 modificationData[constants.KEY__EDITS__OLD_RESULTS_TYPE] =
570 $scope.header[constants.KEY__HEADER__TYPE];
510 $http({ 571 $http({
511 method: "POST", 572 method: "POST",
512 url: "/edits", 573 url: "/edits",
513 data: { 574 data: modificationData
514 oldResultsType: $scope.header.type, 575 }).success(function(data, status, headers, config) {
515 oldResultsHash: $scope.header.dataHash, 576 var imagePairIndicesToMove = [];
516 modifications: newResults 577 for (var i = 0; i < imagePairsSubset.length; i++) {
578 imagePairIndicesToMove.push(imagePairsSubset[i].index);
517 } 579 }
518 }).success(function(data, status, headers, config) { 580 $scope.moveImagePairsToTab(imagePairIndicesToMove,
519 var itemIndicesToMove = []; 581 "HackToMakeSureThisImagePairDisappears");
520 for (var i = 0; i < testDataSubset.length; i++) {
521 itemIndicesToMove.push(testDataSubset[i].index);
522 }
523 $scope.moveItemsToTab(itemIndicesToMove,
524 "HackToMakeSureThisItemDisappears");
525 $scope.updateResults(); 582 $scope.updateResults();
526 alert("New baselines submitted successfully!\n\n" + 583 alert("New baselines submitted successfully!\n\n" +
527 "You still need to commit the updated expectations files on " + 584 "You still need to commit the updated expectations files on " +
528 "the server side to the Skia repo.\n\n" + 585 "the server side to the Skia repo.\n\n" +
529 "When you click OK, your web UI will reload; after that " + 586 "When you click OK, your web UI will reload; after that " +
530 "completes, you will see the updated data (once the server has " + 587 "completes, you will see the updated data (once the server has " +
531 "finished loading the update results into memory!) and you can " + 588 "finished loading the update results into memory!) and you can " +
532 "submit more baselines if you want."); 589 "submit more baselines if you want.");
533 // I don't know why, but if I just call reload() here it doesn't work. 590 // I don't know why, but if I just call reload() here it doesn't work.
534 // Making a timer call it fixes the problem. 591 // Making a timer call it fixes the problem.
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 * @param brightnessString (string): 0-255, 0 is completely black 732 * @param brightnessString (string): 0-255, 0 is completely black
676 * 733 *
677 * TODO(epoger): It might be nice to tint the color when it's not completely 734 * TODO(epoger): It might be nice to tint the color when it's not completely
678 * black or completely white. 735 * black or completely white.
679 */ 736 */
680 $scope.brightnessStringToHexColor = function(brightnessString) { 737 $scope.brightnessStringToHexColor = function(brightnessString) {
681 var v = parseInt(brightnessString); 738 var v = parseInt(brightnessString);
682 return $scope.hexColorString(v, v, v); 739 return $scope.hexColorString(v, v, v);
683 } 740 }
684 741
742 /**
743 * Returns the last path component of image diff URL for a given ImagePair.
744 *
745 * Depending on which diff this is (whitediffs, pixeldiffs, etc.) this
746 * will be relative to different base URLs.
747 *
748 * We must keep this function in sync with _get_difference_locator() in
749 * ../imagediffdb.py
750 *
751 * @param imagePair: ImagePair to generate image diff URL for
752 */
753 $scope.getImageDiffRelativeUrl = function(imagePair) {
754 var before =
755 imagePair[constants.KEY__IMAGE_A_URL] + "-vs-" +
756 imagePair[constants.KEY__IMAGE_B_URL];
757 return before.replace(/[^\w\-]/g, "_") + ".png";
758 }
759
685 } 760 }
686 ); 761 );
OLDNEW
« no previous file with comments | « gm/rebaseline_server/static/constants.js ('k') | gm/rebaseline_server/static/view.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698