'removeHiddenItems',
function() {
return function(unfilteredItems, hiddenResultTypes, hiddenConfigs,
- viewingTab) {
+ builderSubstring, testSubstring, viewingTab) {
var filteredItems = [];
for (var i = 0; i < unfilteredItems.length; i++) {
var item = unfilteredItems[i];
// Besides, I don't think we have access to $scope in here...
if (!(true == hiddenResultTypes[item.resultType]) &&
!(true == hiddenConfigs[item.config]) &&
+ !(-1 == item.builder.indexOf(builderSubstring)) &&
+ !(-1 == item.test.indexOf(testSubstring)) &&
(viewingTab == item.tab)) {
filteredItems.push(item);
}
'no-comparison': true,
'succeeded': true,
};
+ $scope.allResultTypes = Object.keys(data.categories['resultType']);
$scope.hiddenConfigs = {};
+ $scope.allConfigs = Object.keys(data.categories['config']);
+
+ // Associative array of partial string matches per category.
+ $scope.categoryValueMatch = {};
+ $scope.categoryValueMatch.builder = "";
+ $scope.categoryValueMatch.test = "";
$scope.updateResults();
$scope.loadingMessage = "";
$scope.testData,
$scope.hiddenResultTypes,
$scope.hiddenConfigs,
+ $scope.categoryValueMatch.builder,
+ $scope.categoryValueMatch.test,
$scope.viewingTab
),
$scope.sortColumn);
$scope.updateResults();
}
+ /**
+ * Set $scope.categoryValueMatch[name] = value, and update results.
+ *
+ * @param name
+ * @param value
+ */
+ $scope.setCategoryValueMatch = function(name, value) {
+ $scope.categoryValueMatch[name] = value;
+ $scope.updateResults();
+ }
+
+ /**
+ * Update $scope.hiddenResultTypes so that ONLY this resultType is showing,
+ * and update the visible results.
+ *
+ * @param resultType
+ */
+ $scope.showOnlyResultType = function(resultType) {
+ $scope.hiddenResultTypes = {};
+ // TODO(epoger): Maybe change $scope.allResultTypes to be a Set like
+ // $scope.hiddenResultTypes (rather than an array), so this operation is
+ // simpler (just assign or add allResultTypes to hiddenResultTypes).
+ $scope.toggleValuesInSet($scope.allResultTypes, $scope.hiddenResultTypes);
+ $scope.toggleValueInSet(resultType, $scope.hiddenResultTypes);
+ $scope.updateResults();
+ }
+
+ /**
+ * Update $scope.hiddenConfigs so that ONLY this config is showing,
+ * and update the visible results.
+ *
+ * @param config
+ */
+ $scope.showOnlyConfig = function(config) {
+ $scope.hiddenConfigs = {};
+ $scope.toggleValuesInSet($scope.allConfigs, $scope.hiddenConfigs);
+ $scope.toggleValueInSet(config, $scope.hiddenConfigs);
+ $scope.updateResults();
+ }
+
//
// Operations for sending info back to the server.
}
}
+ /**
+ * For each value in valueArray, call toggleValueInSet(value, set).
+ *
+ * @param valueArray
+ * @param set
+ */
+ $scope.toggleValuesInSet = function(valueArray, set) {
+ var arrayLength = valueArray.length;
+ for (var i = 0; i < arrayLength; i++) {
+ $scope.toggleValueInSet(valueArray[i], set);
+ }
+ }
+
//
// Array operations; similar to our Set operations, but operate on a
new results and tell the user when new results are available
(the user can reload the page if he wants to see them).
</li><li>
- Add ability to filter builder and test names
- (using a free-form text field, with partial string match)
- </li><li>
Add pixel diffs, and sorting by percentage of different pixels
</li><li>
Add ability to sort/filter by reviewed-by-human. Depends on
http://jsfiddle.net/vojtajina/js64b/14/
</a>
</li><li>
+ For the text-filtered categories, allow regular expression matching
+ (or Unix-style wildcard matching) instead of simple substring match?
+ <!-- In order to do this efficiently, we should probably do the
+ expression matching over the list of categories returned,
+ use that to generate a list of category values that fulfill the
+ regex, and when filtering the results just look for category
+ values within that list. -->
+ </li><li>
Right now, if you change which column is used to
sort the data, the column widths may fluctuate based on the
longest string <i>currently visible</i> within the top {{displayLimit}}
<!-- We only show the filters/settings table on the Unfiled tab. -->
<table ng-hide="viewingTab != defaultTab" border="1">
<tr>
- <th colspan="2">
+ <th colspan="4">
Filters
</th>
<th>
ng-click="toggleValueInSet(resultType, hiddenResultTypes); setUpdatesPending(true)">
{{resultType}} ({{count}})<br>
</label>
+ <button ng-click="hiddenResultTypes = {}; updateResults()">
+ all
+ </button>
+ <button ng-click="hiddenResultTypes = {}; toggleValuesInSet(allResultTypes, hiddenResultTypes); updateResults()">
+ none
+ </button>
+ <button ng-click="toggleValuesInSet(allResultTypes, hiddenResultTypes); updateResults()">
+ toggle
+ </button>
+ </td>
+ <td ng-repeat="category in ['builder', 'test']">
+ {{category}}
+ <br>
+ <input type="text"
+ ng-model="categoryValueMatch[category]"
+ ng-change="setUpdatesPending(true)"/>
+ <br>
+ <button ng-click="setCategoryValueMatch(category, '')"
+ ng-disabled="('' == categoryValueMatch[category])">
+ clear (show all)
+ </button>
</td>
<td>
config<br>
ng-click="toggleValueInSet(config, hiddenConfigs); setUpdatesPending(true)">
{{config}} ({{count}})<br>
</label>
+ <button ng-click="hiddenConfigs = {}; updateResults()">
+ all
+ </button>
+ <button ng-click="hiddenConfigs = {}; toggleValuesInSet(allConfigs, hiddenConfigs); updateResults()">
+ none
+ </button>
+ <button ng-click="toggleValuesInSet(allConfigs, hiddenConfigs); updateResults()">
+ toggle
+ </button>
</td>
<td><table>
<tr><td>
<!-- item-selection checkbox column -->
</th>
</tr>
+
+ <!-- For most columns... if the user clicks on the cell, and we are on
+ the default tab, update the filter to only show results with the
+ same value for this category.
+ This is made a bit tricky by the fact that AngularJS expressions
+ do not allow control flow statements. See
+ http://docs.angularjs.org/guide/expression -->
<tr ng-repeat="result in limitedTestData">
- <td ng-repeat="categoryName in ['resultType', 'builder', 'test', 'config']">
+ <td ng-click="(viewingTab != defaultTab) || showOnlyResultType(result.resultType)">
+ {{result.resultType}}
+ </td>
+ <td ng-repeat="categoryName in ['builder', 'test']"
+ ng-click="(viewingTab != defaultTab) || setCategoryValueMatch(categoryName, result[categoryName])">
{{result[categoryName]}}
</td>
+ <td ng-click="(viewingTab != defaultTab) || showOnlyConfig(result.config)">
+ {{result.config}}
+ </td>
<td>
<a ng-repeat="bug in result['bugs']"
href="https://code.google.com/p/skia/issues/detail?id={{bug}}"