diff options
author | 2014-08-08 07:21:00 -0700 | |
---|---|---|
committer | 2014-08-08 07:21:00 -0700 | |
commit | d9bf7dbf0931a626d3f685163fb12913c58f48b8 (patch) | |
tree | a90b251615d889b7203e81377e107087f13196a4 /gm | |
parent | be129b26f13d575fd6b396c6ae759838ecc9bd1a (diff) |
Rebaseline-server: sorting of columns in asc/desc order in frontend.
NOTRY=true
BUG=skia:1907
R=epoger@google.com
Author: stephana@google.com
Review URL: https://codereview.chromium.org/449843002
Diffstat (limited to 'gm')
-rw-r--r-- | gm/rebaseline_server/static/constants.js | 4 | ||||
-rw-r--r-- | gm/rebaseline_server/static/live-loader.js | 15 | ||||
-rw-r--r-- | gm/rebaseline_server/static/live-view.html | 73 | ||||
-rw-r--r-- | gm/rebaseline_server/static/loader.js | 101 | ||||
-rw-r--r-- | gm/rebaseline_server/static/view.css | 14 | ||||
-rw-r--r-- | gm/rebaseline_server/static/view.html | 77 |
6 files changed, 163 insertions, 121 deletions
diff --git a/gm/rebaseline_server/static/constants.js b/gm/rebaseline_server/static/constants.js index 150c8959fd..c397452240 100644 --- a/gm/rebaseline_server/static/constants.js +++ b/gm/rebaseline_server/static/constants.js @@ -80,5 +80,9 @@ module.constant('constants', (function() { KEY__IMAGEPAIRS__ROWSPAN: 'rowspan', URL_KEY__SCHEMA_VERSION: 'urlSchemaVersion', URL_VALUE__SCHEMA_VERSION__CURRENT: 1, + + // Utility constants only used on the client side. + ASC: 'asc', + DESC: 'desc', } })()) diff --git a/gm/rebaseline_server/static/live-loader.js b/gm/rebaseline_server/static/live-loader.js index 00800682f3..16a19aab78 100644 --- a/gm/rebaseline_server/static/live-loader.js +++ b/gm/rebaseline_server/static/live-loader.js @@ -133,6 +133,9 @@ Loader.controller( $scope.setBSection = $location.search().setBSection; $scope.loadingMessage = "please wait..."; + var currSortAsc = true; + + /** * On initial page load, load a full dictionary of results. * Once the dictionary is loaded, unhide the page elements so they can @@ -175,8 +178,11 @@ Loader.controller( $scope.orderedColumnNames = data[constants.KEY__ROOT__EXTRACOLUMNORDER]; $scope.imagePairs = data[constants.KEY__ROOT__IMAGEPAIRS]; $scope.imageSets = data[constants.KEY__ROOT__IMAGESETS]; + + // set the default sort column and make it ascending. $scope.sortColumnSubdict = constants.KEY__IMAGEPAIRS__DIFFERENCES; $scope.sortColumnKey = constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF; + currSortAsc = true; $scope.showSubmitAdvancedSettings = false; $scope.submitAdvancedSettings = {}; @@ -610,14 +616,7 @@ Loader.controller( // array copies? (For better performance.) if ($scope.viewingTab == $scope.defaultTab) { - - // TODO(epoger): Until we allow the user to reverse sort order, - // there are certain columns we want to sort in a different order. - var doReverse = ( - ($scope.sortColumnKey == - constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS) || - ($scope.sortColumnKey == - constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF)); + var doReverse = !currSortAsc; $scope.filteredImagePairs = $filter("orderBy")( diff --git a/gm/rebaseline_server/static/live-view.html b/gm/rebaseline_server/static/live-view.html index 5292f3b966..2f8241e047 100644 --- a/gm/rebaseline_server/static/live-view.html +++ b/gm/rebaseline_server/static/live-view.html @@ -5,7 +5,7 @@ <head> <title ng-bind="windowTitle"></title> <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> - <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.js"></script> + <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.20/angular.js"></script> <script src="constants.js"></script> <script src="live-loader.js"></script> <script src="utils.js"></script> @@ -246,53 +246,54 @@ <tr> <!-- Most column headers are displayed in a common fashion... --> <th ng-repeat="columnName in orderedColumnNames"> - <input type="radio" - name="sortColumnRadio" - value="{{columnName}}" - ng-checked="(sortColumnKey == columnName)" - ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__EXTRACOLUMNS, columnName)"> - {{extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__HEADER_TEXT]}} + <a ng-class="'sort-' + sortedByColumnsCls(columnName)" + ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__EXTRACOLUMNS, columnName)" + href="" + class="sortable-header"> + {{extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__HEADER_TEXT]}} + </a> </th> <!-- ... but there are a few columns where we display things differently. --> <th> - <input type="radio" - name="sortColumnRadio" - value="bugs" - ng-checked="(sortColumnKey == constants.KEY__EXPECTATIONS__BUGS)" - ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__EXPECTATIONS, constants.KEY__EXPECTATIONS__BUGS)"> + <a ng-class="'sort-' + sortedByColumnsCls(constants.KEY__EXPECTATIONS__BUGS)" + ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__EXPECTATIONS, constants.KEY__EXPECTATIONS__BUGS)" + href="" + class="sortable-header"> + bugs + </a> bugs </th> <th width="{{imageSize}}"> - <input type="radio" - name="sortColumnRadio" - value="imageA" - ng-checked="(sortColumnKey == constants.KEY__IMAGEPAIRS__IMAGE_A_URL)" - ng-click="sortResultsBy('none', constants.KEY__IMAGEPAIRS__IMAGE_A_URL)"> - {{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_A][constants.KEY__IMAGESETS__FIELD__DESCRIPTION]}} + <a ng-class="'sort-' + sortedByColumnsCls(constants.KEY__IMAGEPAIRS__IMAGE_A_URL)" + ng-click="sortResultsBy('none', constants.KEY__IMAGEPAIRS__IMAGE_A_URL)" + href="" + class="sortable-header"> + {{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_A][constants.KEY__IMAGESETS__FIELD__DESCRIPTION]}} + </a> </th> <th width="{{imageSize}}"> - <input type="radio" - name="sortColumnRadio" - value="imageB" - ng-checked="(sortColumnKey == constants.KEY__IMAGEPAIRS__IMAGE_B_URL)" - ng-click="sortResultsBy('none', constants.KEY__IMAGEPAIRS__IMAGE_B_URL)"> - {{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_B][constants.KEY__IMAGESETS__FIELD__DESCRIPTION]}} + <a ng-class="'sort-' + sortedByColumnsCls(constants.KEY__IMAGEPAIRS__IMAGE_B_URL)" + ng-click="sortResultsBy('none', constants.KEY__IMAGEPAIRS__IMAGE_B_URL)" + href="" + class="sortable-header"> + {{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_B][constants.KEY__IMAGESETS__FIELD__DESCRIPTION]}} + </a> </th> <th width="{{imageSize}}"> - <input type="radio" - name="sortColumnRadio" - value="percentDifferingPixels" - ng-checked="(sortColumnKey == constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS)" - ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__DIFFERENCES, constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS)"> - differing pixels in white + <a ng-class="'sort-' + sortedByColumnsCls(constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS)" + ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__DIFFERENCES, constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS)" + href="" + class="sortable-header"> + differing pixels in white + </a> </th> <th width="{{imageSize}}"> - <input type="radio" - name="sortColumnRadio" - value="perceptualDiff" - ng-checked="(sortColumnKey == constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF)" - ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__DIFFERENCES, constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF)"> - perceptual difference + <a ng-class="'sort-' + sortedByColumnsCls(constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF)" + ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__DIFFERENCES, constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF)" + href="" + class="sortable-header"> + perceptual difference + </a> <br> <input type="range" ng-model="pixelDiffBgColorBrightness" ng-init="pixelDiffBgColorBrightness=64; pixelDiffBgColor=brightnessStringToHexColor(pixelDiffBgColorBrightness)" diff --git a/gm/rebaseline_server/static/loader.js b/gm/rebaseline_server/static/loader.js index 1ec7305dc6..e6030ad439 100644 --- a/gm/rebaseline_server/static/loader.js +++ b/gm/rebaseline_server/static/loader.js @@ -130,6 +130,9 @@ Loader.controller( $scope.resultsToLoad = $location.search().resultsToLoad; $scope.loadingMessage = "please wait..."; + var currSortAsc = true; + + /** * On initial page load, load a full dictionary of results. * Once the dictionary is loaded, unhide the page elements so they can @@ -167,8 +170,11 @@ Loader.controller( $scope.orderedColumnNames = data[constants.KEY__ROOT__EXTRACOLUMNORDER]; $scope.imagePairs = data[constants.KEY__ROOT__IMAGEPAIRS]; $scope.imageSets = data[constants.KEY__ROOT__IMAGESETS]; + + // set the default sort column and make it ascending. $scope.sortColumnSubdict = constants.KEY__IMAGEPAIRS__DIFFERENCES; $scope.sortColumnKey = constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF; + currSortAsc = true; $scope.showSubmitAdvancedSettings = false; $scope.submitAdvancedSettings = {}; @@ -320,7 +326,7 @@ Loader.controller( $scope.toggleValueInArray(index, $scope.selectedImagePairs); } } - } + }; /** * Deselect all currently showing tests. @@ -333,7 +339,7 @@ Loader.controller( $scope.toggleValueInArray(index, $scope.selectedImagePairs); } } - } + }; /** * Toggle selection of all currently showing tests. @@ -344,7 +350,7 @@ Loader.controller( var index = $scope.limitedImagePairs[i].index; $scope.toggleValueInArray(index, $scope.selectedImagePairs); } - } + }; /** * Toggle selection state of a subset of the currently showing tests. @@ -359,7 +365,7 @@ Loader.controller( var index = $scope.limitedImagePairs[i].index; $scope.toggleValueInArray(index, $scope.selectedImagePairs); } - } + }; // @@ -374,7 +380,7 @@ Loader.controller( $scope.setViewingTab = function(tab) { $scope.viewingTab = tab; $scope.updateResults(); - } + }; /** * Move the imagePairs in $scope.selectedImagePairs to a different tab, @@ -386,7 +392,7 @@ Loader.controller( $scope.moveImagePairsToTab($scope.selectedImagePairs, newTab); $scope.selectedImagePairs = []; $scope.updateResults(); - } + }; /** * Move a subset of $scope.imagePairs to a different tab. @@ -404,7 +410,7 @@ Loader.controller( $scope.imagePairs[imagePairIndex].tab = newTab; } $scope.numResultsPerTab[newTab] += numImagePairs; - } + }; // @@ -597,16 +603,8 @@ Loader.controller( // another copy of the array. Is there a way we can filter out // the imagePairs as they are displayed, rather than storing multiple // array copies? (For better performance.) - if ($scope.viewingTab == $scope.defaultTab) { - - // TODO(epoger): Until we allow the user to reverse sort order, - // there are certain columns we want to sort in a different order. - var doReverse = ( - ($scope.sortColumnKey == - constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS) || - ($scope.sortColumnKey == - constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF)); + var doReverse = !currSortAsc; $scope.filteredImagePairs = $filter("orderBy")( @@ -616,7 +614,8 @@ Loader.controller( $scope.showingColumnValues, $scope.viewingTab ), - [$scope.getSortColumnValue, $scope.getSecondOrderSortValue], + // [$scope.getSortColumnValue, $scope.getSecondOrderSortValue], + $scope.getSortColumnValue, doReverse); $scope.limitedImagePairs = $filter("mergeAndLimit")( $scope.filteredImagePairs, $scope.displayLimit, $scope.mergeIdenticalRows); @@ -628,7 +627,8 @@ Loader.controller( {tab: $scope.viewingTab}, true ), - [$scope.getSortColumnValue, $scope.getSecondOrderSortValue]); + // [$scope.getSortColumnValue, $scope.getSecondOrderSortValue]); + $scope.getSortColumnValue); $scope.limitedImagePairs = $filter("mergeAndLimit")( $scope.filteredImagePairs, -1, $scope.mergeIdenticalRows); } @@ -645,7 +645,7 @@ Loader.controller( $scope.resultsUpdatedCallback = function() { $scope.renderEndTime = window.performance.now(); $log.debug("renderEndTime: " + $scope.renderEndTime); - } + }; /** * Re-sort the displayed results. @@ -656,10 +656,33 @@ Loader.controller( * @param key (string): sort by value associated with this key in subdict */ $scope.sortResultsBy = function(subdict, key) { - $scope.sortColumnSubdict = subdict; - $scope.sortColumnKey = key; + // if we are already sorting by this column then toggle between asc/desc + if ((subdict === $scope.sortColumnSubdict) && ($scope.sortColumnKey === key)) { + currSortAsc = !currSortAsc; + } else { + $scope.sortColumnSubdict = subdict; + $scope.sortColumnKey = key; + currSortAsc = true; + } $scope.updateResults(); - } + }; + + /** + * Returns ASC or DESC (from constants) if currently the data + * is sorted by the provided column. + * + * @param colName: name of the column for which we need to get the class. + */ + + $scope.sortedByColumnsCls = function (colName) { + if ($scope.sortColumnKey !== colName) { + return ''; + } + + var result = (currSortAsc) ? constants.ASC : constants.DESC; + console.log("sort class:", result); + return result; + }; /** * For a particular ImagePair, return the value of the column we are @@ -676,7 +699,7 @@ Loader.controller( } else { return undefined; } - } + }; /** * For a particular ImagePair, return the value we use for the @@ -691,7 +714,7 @@ Loader.controller( $scope.getSecondOrderSortValue = function(imagePair) { return imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL] + "-vs-" + imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL]; - } + }; /** * Set $scope.columnStringMatch[name] = value, and update results. @@ -702,7 +725,7 @@ Loader.controller( $scope.setColumnStringMatch = function(name, value) { $scope.columnStringMatch[name] = value; $scope.updateResults(); - } + }; /** * Update $scope.showingColumnValues[columnName] and $scope.columnStringMatch[columnName] @@ -717,7 +740,7 @@ Loader.controller( $scope.showingColumnValues[columnName] = {}; $scope.toggleValueInSet(columnValue, $scope.showingColumnValues[columnName]); $scope.updateResults(); - } + }; /** * Update $scope.showingColumnValues[columnName] and $scope.columnStringMatch[columnName] @@ -732,7 +755,7 @@ Loader.controller( $scope.toggleValuesInSet($scope.allColumnValues[columnName], $scope.showingColumnValues[columnName]); $scope.updateResults(); - } + }; // @@ -842,7 +865,7 @@ Loader.controller( "Please see server-side log for details."); $scope.submitPending = false; }); - } + }; // @@ -860,7 +883,7 @@ Loader.controller( */ $scope.setSize = function(set) { return Object.keys(set).length; - } + }; /** * Returns true if value "value" is present within set "set". @@ -871,7 +894,7 @@ Loader.controller( */ $scope.isValueInSet = function(value, set) { return (true == set[value]); - } + }; /** * If value "value" is already in set "set", remove it; otherwise, add it. @@ -885,7 +908,7 @@ Loader.controller( } else { set[value] = true; } - } + }; /** * For each value in valueArray, call toggleValueInSet(value, set). @@ -898,7 +921,7 @@ Loader.controller( for (var i = 0; i < arrayLength; i++) { $scope.toggleValueInSet(valueArray[i], set); } - } + }; // @@ -915,7 +938,7 @@ Loader.controller( */ $scope.isValueInArray = function(value, array) { return (-1 != array.indexOf(value)); - } + }; /** * If value "value" is already in array "array", remove it; otherwise, @@ -931,7 +954,7 @@ Loader.controller( } else { array.splice(i, 1); } - } + }; // @@ -959,7 +982,7 @@ Loader.controller( slice.push(array[row][column]); } return slice; - } + }; /** * Returns a human-readable (in local time zone) time string for a @@ -970,7 +993,7 @@ Loader.controller( $scope.localTimeString = function(secondsPastEpoch) { var d = new Date(secondsPastEpoch * 1000); return d.toString(); - } + }; /** * Returns a hex color string (such as "#aabbcc") for the given RGB values. @@ -993,7 +1016,7 @@ Loader.controller( bString = "0" + bString; } return '#' + rString + gString + bString; - } + }; /** * Returns a hex color string (such as "#aabbcc") for the given brightness. @@ -1006,7 +1029,7 @@ Loader.controller( $scope.brightnessStringToHexColor = function(brightnessString) { var v = parseInt(brightnessString); return $scope.hexColorString(v, v, v); - } + }; /** * Returns the last path component of image diff URL for a given ImagePair. @@ -1024,7 +1047,7 @@ Loader.controller( imagePair[constants.KEY__IMAGEPAIRS__IMAGE_A_URL] + "-vs-" + imagePair[constants.KEY__IMAGEPAIRS__IMAGE_B_URL]; return before.replace(/[^\w\-]/g, "_") + ".png"; - } + }; } ); diff --git a/gm/rebaseline_server/static/view.css b/gm/rebaseline_server/static/view.css index ee9be3293b..80f28091c4 100644 --- a/gm/rebaseline_server/static/view.css +++ b/gm/rebaseline_server/static/view.css @@ -88,3 +88,17 @@ padding: 10px; border: 2px solid #222; } + +.sort-desc { + background:no-repeat left center url(data:image/gif;base64,R0lGODlhCgAKALMAAHFxcYKCgp2dnaampq+vr83NzeHh4f///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAAAgAIf/8SUNDUkdCRzEwMTIAAAUwYXBwbAIgAABtbnRyUkdCIFhZWiAH2QACABkACwAaAAthY3NwQVBQTAAAAABhcHBsAAAAAAAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLWFwcGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtkc2NtAAABCAAAAvJkZXNjAAAD/AAAAG9nWFlaAAAEbAAAABR3dHB0AAAEgAAAABRyWFlaAAAElAAAABRiWFlaAAAEqAAAABRyVFJDAAAEvAAAAA5jcHJ0AAAEzAAAADhjaGFkAAAFBAAAACxn/1RSQwAABLwAAAAOYlRSQwAABLwAAAAObWx1YwAAAAAAAAARAAAADGVuVVMAAAAmAAACfmVzRVMAAAAmAAABgmRhREsAAAAuAAAB6mRlREUAAAAsAAABqGZpRkkAAAAoAAAA3GZyRlUAAAAoAAABKml0SVQAAAAoAAACVm5sTkwAAAAoAAACGG5iTk8AAAAmAAABBHB0QlIAAAAmAAABgnN2U0UAAAAmAAABBGphSlAAAAAaAAABUmtvS1IAAAAWAAACQHpoVFcAAAAWAAABbHpoQ04AAAAWAAAB1HJ1UlUAAAAiAAACpHBsUEwAAAAsAAACxgBZAGwAZQBpAG4AZf8AbgAgAFIARwBCAC0AcAByAG8AZgBpAGkAbABpAEcAZQBuAGUAcgBpAHMAawAgAFIARwBCAC0AcAByAG8AZgBpAGwAUAByAG8AZgBpAGwAIABHAOkAbgDpAHIAaQBxAHUAZQAgAFIAVgBCTgCCLAAgAFIARwBCACAw1zDtMNUwoTCkMOuQGnUoACAAUgBHAEIAIIJyX2ljz4/wAFAAZQByAGYAaQBsACAAUgBHAEIAIABHAGUAbgDpAHIAaQBjAG8AQQBsAGwAZwBlAG0AZQBpAG4AZQBzACAAUgBHAEIALQBQAHIAbwBmAGkAbGZukBoAIABSAEcAQgAgY8+P8GX/h072AEcAZQBuAGUAcgBlAGwAIABSAEcAQgAtAGIAZQBzAGsAcgBpAHYAZQBsAHMAZQBBAGwAZwBlAG0AZQBlAG4AIABSAEcAQgAtAHAAcgBvAGYAaQBlAGzHfLwYACAAUgBHAEIAINUEuFzTDMd8AFAAcgBvAGYAaQBsAG8AIABSAEcAQgAgAEcAZQBuAGUAcgBpAGMAbwBHAGUAbgBlAHIAaQBjACAAUgBHAEIAIABQAHIAbwBmAGkAbABlBB4EMQRJBDgEOQAgBD8EQAQ+BEQEOAQ7BEwAIABSAEcAQgBVAG4AaQB3AGUAcgBzAGEAbABuAHkAIABwAHIAbwBm/wBpAGwAIABSAEcAQgAAZGVzYwAAAAAAAAAUR2VuZXJpYyBSR0IgUHJvZmlsZQAAAAAAAAAAAAAAFEdlbmVyaWMgUkdCIFByb2ZpbGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABadQAArHMAABc0WFlaIAAAAAAAAPNSAAEAAAABFs9YWVogAAAAAAAAdE0AAD3uAAAD0FhZWiAAAAAAAAAoGgAAFZ8AALg2Y3VydgAAAAAAAAABAc0AAHRleHQAAAAAQ29weXJpZ2h0IDIwMDcgQXBwbGUgSW5jLkMsIGFsbCByaWdodHMgcmVzZXJ2ZWQuAHNmMzIAAAAAAAEMQgAABd7///MmAAAHkgAA/ZH///ui///9owAAA9wAAMBsACwAAAAACgAKAAAEJZAMIcakQZjNtyhFxwEIIRofAookUnapu26t+6KFLYe1TgQ5VwQAOw%3D%3D); +} + +.sort-asc { + background:no-repeat left center url(data:image/gif;base64,R0lGODlhCgAKALMAAHFxcYKCgp2dnaampq+vr83NzeHh4f///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAAAgAIf/8SUNDUkdCRzEwMTIAAAUwYXBwbAIgAABtbnRyUkdCIFhZWiAH2QACABkACwAaAAthY3NwQVBQTAAAAABhcHBsAAAAAAAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLWFwcGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtkc2NtAAABCAAAAvJkZXNjAAAD/AAAAG9nWFlaAAAEbAAAABR3dHB0AAAEgAAAABRyWFlaAAAElAAAABRiWFlaAAAEqAAAABRyVFJDAAAEvAAAAA5jcHJ0AAAEzAAAADhjaGFkAAAFBAAAACxn/1RSQwAABLwAAAAOYlRSQwAABLwAAAAObWx1YwAAAAAAAAARAAAADGVuVVMAAAAmAAACfmVzRVMAAAAmAAABgmRhREsAAAAuAAAB6mRlREUAAAAsAAABqGZpRkkAAAAoAAAA3GZyRlUAAAAoAAABKml0SVQAAAAoAAACVm5sTkwAAAAoAAACGG5iTk8AAAAmAAABBHB0QlIAAAAmAAABgnN2U0UAAAAmAAABBGphSlAAAAAaAAABUmtvS1IAAAAWAAACQHpoVFcAAAAWAAABbHpoQ04AAAAWAAAB1HJ1UlUAAAAiAAACpHBsUEwAAAAsAAACxgBZAGwAZQBpAG4AZf8AbgAgAFIARwBCAC0AcAByAG8AZgBpAGkAbABpAEcAZQBuAGUAcgBpAHMAawAgAFIARwBCAC0AcAByAG8AZgBpAGwAUAByAG8AZgBpAGwAIABHAOkAbgDpAHIAaQBxAHUAZQAgAFIAVgBCTgCCLAAgAFIARwBCACAw1zDtMNUwoTCkMOuQGnUoACAAUgBHAEIAIIJyX2ljz4/wAFAAZQByAGYAaQBsACAAUgBHAEIAIABHAGUAbgDpAHIAaQBjAG8AQQBsAGwAZwBlAG0AZQBpAG4AZQBzACAAUgBHAEIALQBQAHIAbwBmAGkAbGZukBoAIABSAEcAQgAgY8+P8GX/h072AEcAZQBuAGUAcgBlAGwAIABSAEcAQgAtAGIAZQBzAGsAcgBpAHYAZQBsAHMAZQBBAGwAZwBlAG0AZQBlAG4AIABSAEcAQgAtAHAAcgBvAGYAaQBlAGzHfLwYACAAUgBHAEIAINUEuFzTDMd8AFAAcgBvAGYAaQBsAG8AIABSAEcAQgAgAEcAZQBuAGUAcgBpAGMAbwBHAGUAbgBlAHIAaQBjACAAUgBHAEIAIABQAHIAbwBmAGkAbABlBB4EMQRJBDgEOQAgBD8EQAQ+BEQEOAQ7BEwAIABSAEcAQgBVAG4AaQB3AGUAcgBzAGEAbABuAHkAIABwAHIAbwBm/wBpAGwAIABSAEcAQgAAZGVzYwAAAAAAAAAUR2VuZXJpYyBSR0IgUHJvZmlsZQAAAAAAAAAAAAAAFEdlbmVyaWMgUkdCIFByb2ZpbGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABadQAArHMAABc0WFlaIAAAAAAAAPNSAAEAAAABFs9YWVogAAAAAAAAdE0AAD3uAAAD0FhZWiAAAAAAAAAoGgAAFZ8AALg2Y3VydgAAAAAAAAABAc0AAHRleHQAAAAAQ29weXJpZ2h0IDIwMDcgQXBwbGUgSW5jLkMsIGFsbCByaWdodHMgcmVzZXJ2ZWQuAHNmMzIAAAAAAAEMQgAABd7///MmAAAHkgAA/ZH///ui///9owAAA9wAAMBsACwAAAAACgAKAAAEJRBJREKZsxQDsCSGIVzZFnYTGIqktp7fG46uzAn2TAyCMPC9QAQAOw%3D%3D); +} + +.sortable-header { + padding-right: 3px; + padding-left: 13px; + margin-left: 4px; +} diff --git a/gm/rebaseline_server/static/view.html b/gm/rebaseline_server/static/view.html index bafa3f2f3f..7142fcab8b 100644 --- a/gm/rebaseline_server/static/view.html +++ b/gm/rebaseline_server/static/view.html @@ -5,7 +5,7 @@ <head> <title ng-bind="windowTitle"></title> <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> - <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.js"></script> + <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.20/angular.js"></script> <script src="constants.js"></script> <script src="loader.js"></script> <script src="utils.js"></script> @@ -235,57 +235,58 @@ <table border="0"><tr><td> <!-- table holding results header + results table --> </td></tr><tr><td> - <table border="1" ng-app="diff_viewer"> <!-- results --> + <table border="1"> <!-- results --> <tr> <!-- Most column headers are displayed in a common fashion... --> <th ng-repeat="columnName in orderedColumnNames"> - <input type="radio" - name="sortColumnRadio" - value="{{columnName}}" - ng-checked="(sortColumnKey == columnName)" - ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__EXTRACOLUMNS, columnName)"> - {{extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__HEADER_TEXT]}} + <a ng-class="'sort-' + sortedByColumnsCls(columnName)" + ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__EXTRACOLUMNS, columnName)" + href="" + class="sortable-header"> + {{extraColumnHeaders[columnName][constants.KEY__EXTRACOLUMNHEADERS__HEADER_TEXT]}} + </a> </th> + <!-- ... but there are a few columns where we display things differently. --> <th> - <input type="radio" - name="sortColumnRadio" - value="bugs" - ng-checked="(sortColumnKey == constants.KEY__EXPECTATIONS__BUGS)" - ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__EXPECTATIONS, constants.KEY__EXPECTATIONS__BUGS)"> - bugs + <a ng-class="'sort-' + sortedByColumnsCls(constants.KEY__EXPECTATIONS__BUGS)" + ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__EXPECTATIONS, constants.KEY__EXPECTATIONS__BUGS)" + href="" + class="sortable-header"> + bugs + </a> </th> <th width="{{imageSize}}"> - <input type="radio" - name="sortColumnRadio" - value="imageA" - ng-checked="(sortColumnKey == constants.KEY__IMAGEPAIRS__IMAGE_A_URL)" - ng-click="sortResultsBy('none', constants.KEY__IMAGEPAIRS__IMAGE_A_URL)"> - {{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_A][constants.KEY__IMAGESETS__FIELD__DESCRIPTION]}} + <a ng-class="'sort-' + sortedByColumnsCls(constants.KEY__IMAGEPAIRS__IMAGE_A_URL)" + ng-click="sortResultsBy('none', constants.KEY__IMAGEPAIRS__IMAGE_A_URL)" + href="" + class="sortable-header"> + {{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_A][constants.KEY__IMAGESETS__FIELD__DESCRIPTION]}} + </a> </th> <th width="{{imageSize}}"> - <input type="radio" - name="sortColumnRadio" - value="imageB" - ng-checked="(sortColumnKey == constants.KEY__IMAGEPAIRS__IMAGE_B_URL)" - ng-click="sortResultsBy('none', constants.KEY__IMAGEPAIRS__IMAGE_B_URL)"> - {{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_B][constants.KEY__IMAGESETS__FIELD__DESCRIPTION]}} + <a ng-class="'sort-' + sortedByColumnsCls(constants.KEY__IMAGEPAIRS__IMAGE_B_URL)" + ng-click="sortResultsBy('none', constants.KEY__IMAGEPAIRS__IMAGE_B_URL)" + href="" + class="sortable-header"> + {{imageSets[constants.KEY__IMAGESETS__SET__IMAGE_B][constants.KEY__IMAGESETS__FIELD__DESCRIPTION]}} + </a> </th> <th width="{{imageSize}}"> - <input type="radio" - name="sortColumnRadio" - value="percentDifferingPixels" - ng-checked="(sortColumnKey == constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS)" - ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__DIFFERENCES, constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS)"> - differing pixels in white + <a ng-class="'sort-' + sortedByColumnsCls(constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS)" + ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__DIFFERENCES, constants.KEY__DIFFERENCES__PERCENT_DIFF_PIXELS)" + href="" + class="sortable-header"> + differing pixels in white + </a> </th> <th width="{{imageSize}}"> - <input type="radio" - name="sortColumnRadio" - value="perceptualDiff" - ng-checked="(sortColumnKey == constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF)" - ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__DIFFERENCES, constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF)"> - perceptual difference + <a ng-class="'sort-' + sortedByColumnsCls(constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF)" + ng-click="sortResultsBy(constants.KEY__IMAGEPAIRS__DIFFERENCES, constants.KEY__DIFFERENCES__PERCEPTUAL_DIFF)" + href="" + class="sortable-header"> + perceptual difference + </a> <br> <input type="range" ng-model="pixelDiffBgColorBrightness" ng-init="pixelDiffBgColorBrightness=64; pixelDiffBgColor=brightnessStringToHexColor(pixelDiffBgColorBrightness)" |