feat(api-list): sync filters with URL query
This allows us to recover the filtering state when navigating back and forth between the API list and individual API pages. Closes #490 Closes #497 Closes #507
This commit is contained in:
parent
cc6f9ee33f
commit
445e17a4a7
|
@ -1,4 +1,6 @@
|
||||||
angularIO.directive('apiList', function () {
|
angularIO.directive('apiList', function () {
|
||||||
|
var API_FILTER_KEY = 'apiFilter';
|
||||||
|
var API_TYPE_KEY = 'apiType';
|
||||||
return {
|
return {
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
template:
|
template:
|
||||||
|
@ -20,11 +22,20 @@ angularIO.directive('apiList', function () {
|
||||||
' </div>' +
|
' </div>' +
|
||||||
'</article>',
|
'</article>',
|
||||||
controllerAs: '$ctrl',
|
controllerAs: '$ctrl',
|
||||||
controller: function($scope, $attrs, $http) {
|
controller: function($scope, $attrs, $http, $location) {
|
||||||
var $ctrl = this;
|
var $ctrl = this;
|
||||||
|
|
||||||
$ctrl.apiType = null;
|
$ctrl.apiTypes = [
|
||||||
$ctrl.apiFilter = '';
|
{ cssClass: 'directive', title: 'Directive', matches: ['directive'] },
|
||||||
|
{ cssClass: 'class', title: 'Class', matches: ['class'] },
|
||||||
|
{ cssClass: 'interface', title: 'Interface', matches: ['interface'] },
|
||||||
|
{ cssClass: 'function', title: 'function', matches: ['function'] },
|
||||||
|
{ cssClass: 'const', title: 'Const or Enum', matches: ['const', 'enum'] },
|
||||||
|
{ cssClass: 'var', title: 'Variable', matches: ['var', 'let'] }
|
||||||
|
];
|
||||||
|
|
||||||
|
$ctrl.apiFilter = getApiFilterFromLocation();
|
||||||
|
$ctrl.apiType = getApiTypeFromLocation();
|
||||||
$ctrl.filteredSections = [];
|
$ctrl.filteredSections = [];
|
||||||
|
|
||||||
$ctrl.setType = function (type) {
|
$ctrl.setType = function (type) {
|
||||||
|
@ -36,24 +47,20 @@ angularIO.directive('apiList', function () {
|
||||||
$ctrl.sections = response.data;
|
$ctrl.sections = response.data;
|
||||||
});
|
});
|
||||||
|
|
||||||
$ctrl.apiTypes = [
|
|
||||||
{ cssClass: 'directive', title: 'Directive', matches: ['directive'] },
|
|
||||||
{ cssClass: 'class', title: 'Class', matches: ['class'] },
|
|
||||||
{ cssClass: 'interface', title: 'Interface', matches: ['interface'] },
|
|
||||||
{ cssClass: 'function', title: 'function', matches: ['function'] },
|
|
||||||
{ cssClass: 'const', title: 'Const or Enum', matches: ['const', 'enum'] },
|
|
||||||
{ cssClass: 'var', title: 'Variable', matches: ['var', 'let'] }
|
|
||||||
];
|
|
||||||
|
|
||||||
$scope.$watchGroup(
|
$scope.$watchGroup(
|
||||||
[function() { return $ctrl.apiFilter}, function() { return $ctrl.apiType; }, function() { return $ctrl.sections; }],
|
[function() { return $ctrl.apiFilter}, function() { return $ctrl.apiType; }, function() { return $ctrl.sections; }],
|
||||||
function(filter, type, sections) {
|
function() {
|
||||||
|
var apiFilter = ($ctrl.apiFilter || '').toLowerCase();
|
||||||
|
|
||||||
|
$location.search(API_FILTER_KEY, apiFilter || null);
|
||||||
|
$location.search(API_TYPE_KEY, $ctrl.apiType && $ctrl.apiType.title || null);
|
||||||
|
|
||||||
$ctrl.filteredSections.length = 0;
|
$ctrl.filteredSections.length = 0;
|
||||||
angular.forEach($ctrl.sections, function(section, title) {
|
angular.forEach($ctrl.sections, function(section, title) {
|
||||||
var matchesModule = $ctrl.apiFilter == '' || title.toLowerCase().indexOf($ctrl.apiFilter.toLowerCase()) !== -1;
|
var matchesModule = $ctrl.apiFilter === '' || $ctrl.apiFilter === null || title.toLowerCase().indexOf($ctrl.apiFilter.toLowerCase()) !== -1;
|
||||||
var filteredItems = section.filter(function(item) {
|
var filteredItems = section.filter(function(item) {
|
||||||
var matchesDocType = !$ctrl.apiType || $ctrl.apiType.matches.indexOf(item.docType) !== -1;
|
var matchesDocType = !$ctrl.apiType || $ctrl.apiType.matches.indexOf(item.docType) !== -1;
|
||||||
var matchesTitle = $ctrl.apiFilter == '' || item.title.toLowerCase().indexOf($ctrl.apiFilter.toLowerCase()) !== -1;
|
var matchesTitle = !apiFilter || item.title.toLowerCase().indexOf(apiFilter) !== -1;
|
||||||
return matchesDocType && (matchesTitle || matchesModule);
|
return matchesDocType && (matchesTitle || matchesModule);
|
||||||
});
|
});
|
||||||
if (filteredItems.length) {
|
if (filteredItems.length) {
|
||||||
|
@ -62,6 +69,25 @@ angularIO.directive('apiList', function () {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
function getApiFilterFromLocation() {
|
||||||
|
return $location.search()[API_FILTER_KEY] || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getApiTypeFromLocation() {
|
||||||
|
var apiFilter = $location.search()[API_TYPE_KEY];
|
||||||
|
if (!apiFilter) {
|
||||||
|
return null;
|
||||||
|
} else if (!$ctrl.apiFilter || $ctrl.apiFilter.title != apiFilter) {
|
||||||
|
for(var i = 0, ii = $ctrl.apiTypes.length; i < ii; i++) {
|
||||||
|
if ($ctrl.apiTypes[i].title == apiFilter) {
|
||||||
|
return $ctrl.apiTypes[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If we get here then the apiType query didn't match any apiTypes
|
||||||
|
$location.search(API_TYPE_KEY, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
Loading…
Reference in New Issue