diff --git a/client/app/pages/dashboards/dashboard-list.html b/client/app/pages/dashboards/dashboard-list.html index 9125ced8..796a12fc 100644 --- a/client/app/pages/dashboards/dashboard-list.html +++ b/client/app/pages/dashboards/dashboard-list.html @@ -11,19 +11,31 @@
-
- + - + diff --git a/client/app/pages/dashboards/dashboard-list.js b/client/app/pages/dashboards/dashboard-list.js index d7d1dec7..8367ef48 100644 --- a/client/app/pages/dashboards/dashboard-list.js +++ b/client/app/pages/dashboards/dashboard-list.js @@ -4,31 +4,40 @@ import { Paginator } from '@/lib/pagination'; import template from './dashboard-list.html'; import './dashboard-list.css'; - -function DashboardListCtrl(Dashboard, $location) { +function DashboardListCtrl($scope, currentUser, $location) { const TAGS_REGEX = /(^([\w\s]|[^\u0000-\u007F])+):|(#([\w-]|[^\u0000-\u007F])+)/ig; const page = parseInt($location.search().page || 1, 10); - this.defaultOptions = {}; - this.dashboards = Dashboard.query({}); // shared promise + // use $parent because we're using a component as route target instead of controller; + // $parent refers to scope created for the page by router + this.resource = $scope.$parent.$resolve.resource; + this.currentPage = $scope.$parent.$resolve.currentPage; - this.selectedTags = []; // in scope because it needs to be accessed inside a table refresh + this.defaultOptions = {}; + this.dashboards = this.resource({}); // shared promise + + this.selectedTags = new Set(); this.searchText = ''; - this.tagIsSelected = tag => this.selectedTags.indexOf(tag) > -1; + this.currentUser = currentUser; this.toggleTag = ($event, tag) => { - if (this.tagIsSelected(tag)) { - if ($event.shiftKey) { - this.selectedTags = this.selectedTags.filter(e => e !== tag); + if ($event.shiftKey) { + // toggle tag + if (this.selectedTags.has(tag)) { + this.selectedTags.delete(tag); } else { - this.selectedTags = []; + this.selectedTags.add(tag); } - } else if ($event.shiftKey) { - this.selectedTags.push(tag); } else { - this.selectedTags = [tag]; + // if the tag is the only selected, deselect it, otherwise select only it + if (this.selectedTags.has(tag) && (this.selectedTags.size === 1)) { + this.selectedTags.clear(); + } else { + this.selectedTags.clear(); + this.selectedTags.add(tag); + } } this.update(); @@ -59,13 +68,13 @@ function DashboardListCtrl(Dashboard, $location) { dashboard.untagged_name = dashboard.name.replace(TAGS_REGEX, '').trim(); return dashboard; }).filter((value) => { - if (this.selectedTags.length) { - const valueTags = new Set(value.tags); - const tagMatch = this.selectedTags; - const filteredMatch = tagMatch.filter(x => valueTags.has(x)); - if (tagMatch.length !== filteredMatch.length) { - return false; - } + const valueTags = new Set(value.tags); + const matchesAllTags = _.all( + [...this.selectedTags.values()], + tag => valueTags.has(tag), + ); + if (!matchesAllTags) { + return false; } if (this.searchText && this.searchText.length) { if (!value.untagged_name.toLowerCase().includes(this.searchText.toLowerCase())) { @@ -91,10 +100,41 @@ export default function init(ngModule) { const route = { template: '', reloadOnSearch: false, - title: 'Dashboards', }; return { - '/dashboards': route, + '/dashboards': _.extend({ + title: 'Dashboards', + resolve: { + currentPage: () => 'all', + resource(Dashboard) { + 'ngInject'; + + return Dashboard.query.bind(Dashboard); + }, + }, + }, route), + '/dashboards/my': _.extend({ + title: 'My Dashboards', + resolve: { + currentPage: () => 'my', + resource(Dashboard) { + 'ngInject'; + + return Dashboard.myDashboards.bind(Dashboard); + }, + }, + }, route), + '/dashboards/favorite': _.extend({ + title: 'Favorite Dashboards', + resolve: { + currentPage: () => 'favorites', + resource(Dashboard) { + 'ngInject'; + + return Dashboard.favorites.bind(Dashboard); + }, + }, + }, route), }; } diff --git a/client/app/pages/queries-list/index.js b/client/app/pages/queries-list/index.js index ab1d504f..0e21e0a8 100644 --- a/client/app/pages/queries-list/index.js +++ b/client/app/pages/queries-list/index.js @@ -1,28 +1,23 @@ import moment from 'moment'; +import _ from 'underscore'; import { LivePaginator } from '@/lib/pagination'; import template from './queries-list.html'; class QueriesListCtrl { - constructor($location, Title, Query) { + constructor($scope, $location, Query, currentUser) { const page = parseInt($location.search().page || 1, 10); this.defaultOptions = {}; - const self = this; + // use $parent because we're using a component as route target instead of controller; + // $parent refers to scope created for the page by router + this.resource = $scope.$parent.$resolve.resource; + this.currentPage = $scope.$parent.$resolve.currentPage; - switch ($location.path()) { - case '/queries': - Title.set('Queries'); - this.resource = Query.query.bind(Query); - break; - case '/queries/my': - Title.set('My Queries'); - this.resource = Query.myQueries.bind(Query); - break; - default: - break; - } + this.currentUser = currentUser; + + const self = this; function queriesFetcher(requestedPage, itemsPerPage, paginator) { $location.search('page', requestedPage); @@ -62,14 +57,62 @@ export default function init(ngModule) { controller: QueriesListCtrl, }); + const route = { + template: '', + reloadOnSearch: false, + }; + return { - '/queries': { - template: '', - reloadOnSearch: false, - }, - '/queries/my': { - template: '', - reloadOnSearch: false, - }, + '/queries': _.extend({ + title: 'Queries', + resolve: { + currentPage: () => 'all', + resource(Query) { + 'ngInject'; + + return Query.query.bind(Query); + }, + }, + }, route), + '/queries/my': _.extend({ + title: 'My Queries', + resolve: { + currentPage: () => 'my', + resource: (Query) => { + 'ngInject'; + + return Query.myQueries.bind(Query); + }, + }, + }, route), + '/queries/favorite': _.extend({ + title: 'Favorite Queries', + resolve: { + currentPage: () => 'favorites', + resource: (Query, $q) => { + 'ngInject'; + + return (request) => { + const result = { + results: [], + }; + result.$promise = $q((resolve, reject) => { + // convert plain array to paginator + Query.favorites(request).$promise + .then((data) => { + result.count = data.length; + result.results = data; + result.page = 1; + result.page_size = data.length; + + resolve(result); + }) + .catch(reject); + }); + return result; + }; + }, + }, + }, route), }; } diff --git a/client/app/pages/queries-list/queries-list.html b/client/app/pages/queries-list/queries-list.html index 69c8a9ce..507a1fb7 100644 --- a/client/app/pages/queries-list/queries-list.html +++ b/client/app/pages/queries-list/queries-list.html @@ -9,14 +9,23 @@