Skip to content

Commit

Permalink
Add landing page with table to Visualize app. (#9605)
Browse files Browse the repository at this point in the history
* Refactor Visualize Wizard to use explicit controller names, instead of defining them dynamically.
* Add landing page with table to Visualize app.
* Update Visualize wizard UI.
* Add kuiIcon--basic and support icons in Table component. Display icons in Visualize landing page.
* Refactor Visualize Wizard templates to use import syntax.
* Set kuiViewContent width to 100% to avoid it shrink wrapping its content.
* Move ToolBar buttons to the right side. Remove labels and add tooltips.
* Remove unused Visualize load menu template.
* Disable timepicker in Visualization listing.
* Change Visualize route names. Add omitPages attribute to breadcrumbs directive. Make Visualize breadcrumbs into links.
* Remove Open and New menu buttons from Visualize.
* Add ConfirmationModal for deleting visualizations.
* Implement sorting for name and type columns in Visualize listing.
* Refactor Visualize routes into VisualizeConstants file. Fix functional tests.
* Add pager_controls directive and pager service. Add pagination to Dashboard and Visualize landing pages. Change Dashboard listing to use hrefs for each dashboard.
* Use ng-if instead of ng-hide to hide/reveal Table action buttons in Dashboard listing.
* Redirect from old Visualize wizard routes to new ones.
* Use ViewContent and Title components in Visualize wizard.
* Fix Visualize and Dashboard listing table logic so that selection only applies to the current page of items.
* Paging clears the selection.
* Searching clears the selection.
* Sorting clears the selection.
* Use consistent "Create" terminology in both Visualize and Dashboard for creating new items.
* Use NoItems and PromptForItems components in Visualize listing view.
* Use $injector to inject dependencies in Visualize and Dashboard listing.
  • Loading branch information
cjcenizal authored Feb 6, 2017
1 parent c8c03e5 commit a5705f8
Show file tree
Hide file tree
Showing 43 changed files with 850 additions and 205 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
export const DashboardConstants = {
ADD_VISUALIZATION_TO_DASHBOARD_MODE_PARAM: 'addToDashboard',
NEW_VISUALIZATION_ID_PARAM: 'addVisualization',
LANDING_PAGE_URL: '/dashboard'
LANDING_PAGE_PATH: '/dashboard'
};
2 changes: 1 addition & 1 deletion src/core_plugins/kibana/public/dashboard/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ uiRoutes
.defaults(/dashboard/, {
requireDefaultIndex: true
})
.when(DashboardConstants.LANDING_PAGE_URL, {
.when(DashboardConstants.LANDING_PAGE_PATH, {
template: dashboardListingTemplate,
controller: DashboardListingController,
controllerAs: 'listingController'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,13 @@
</div>
</div>

<div class="kuiToolBarSection">
<!-- We need an empty section for the buttons to be positioned consistently. -->
</div>

<div class="kuiToolBarSection">
<!-- Bulk delete button -->
<button
class="kuiButton kuiButton--danger"
ng-click="listingController.deleteSelectedItems()"
aria-label="Delete selected objects"
ng-hide="listingController.getSelectedItemsCount() === 0"
ng-if="listingController.getSelectedItemsCount() > 0"
tooltip="Delete selected dashboards"
>
<span aria-hidden="true" class="kuiButton__icon kuiIcon fa-trash"></span>
Expand All @@ -53,15 +49,30 @@
href="#/dashboard/create"
aria-label="Create new dashboard"
data-test-subj="newDashboardLink"
ng-hide="listingController.getSelectedItemsCount() > 0"
ng-if="listingController.getSelectedItemsCount() === 0"
tooltip="Create new dashboard"
>
<span aria-hidden="true" class="kuiButton__icon kuiIcon fa-plus"></span>
</a>
</div>

<div class="kuiToolBarSection">
<!-- Pagination -->
<tool-bar-pager-text
start-item="listingController.pager.startItem"
end-item="listingController.pager.endItem"
total-items="listingController.pager.totalItems"
></tool-bar-pager-text>
<tool-bar-pager-buttons
has-previous-page="listingController.pager.hasPreviousPage"
has-next-page="listingController.pager.hasNextPage"
on-page-next="listingController.onPageNext"
on-page-previous="listingController.onPagePrevious"
></tool-bar-pager-buttons>
</div>
</div>

<!-- NoResults -->
<!-- NoItems -->
<div
class="kuiPanel kuiPanel--centered kuiPanel--withHeader"
ng-if="!listingController.items.length && listingController.filter"
Expand All @@ -78,7 +89,7 @@
>
<div class="kuiPromptForItems">
<div class="kuiPromptForItems__message">
Looks like you don&rsquo;t have any dashboards. Let&rsquo;s add some!
Looks like you don&rsquo;t have any dashboards. Let&rsquo;s create some!
</div>

<div class="kuiPromptForItems__actions">
Expand All @@ -87,7 +98,7 @@
href="#/dashboard/create"
>
<span class="kuiButton__icon kuiIcon fa-plus"></span>
Add a dashboard
Create a dashboard
</a>
</div>
</div>
Expand Down Expand Up @@ -118,7 +129,7 @@

<tbody>
<tr
ng-repeat="item in listingController.items track by item.id"
ng-repeat="item in listingController.pageOfItems track by item.id"
class="kuiTableRow"
>
<td class="kuiTableRowCell kuiTableRowCell--checkBox">
Expand All @@ -132,7 +143,7 @@

<td class="kuiTableRowCell">
<div class="kuiTableRowCell__liner">
<a class="kuiLink" ng-click="listingController.open(item)">
<a class="kuiLink" ng-href="{{ listingController.getUrlForItem(item) }}">
{{ item.title }}
</a>
</div>
Expand All @@ -149,8 +160,20 @@
{{ listingController.getSelectedItemsCount() }} selected
</div>
</div>
<div class="kuiToolBarFooterSection">
<!-- We need an empty section for the buttons to be positioned consistently. -->

<div class="kuiToolBarSection">
<!-- Pagination -->
<tool-bar-pager-text
start-item="listingController.pager.startItem"
end-item="listingController.pager.endItem"
total-items="listingController.pager.totalItems"
></tool-bar-pager-text>
<tool-bar-pager-buttons
has-previous-page="listingController.pager.hasPreviousPage"
has-next-page="listingController.pager.hasNextPage"
on-page-next="listingController.onPageNext"
on-page-previous="listingController.onPagePrevious"
></tool-bar-pager-buttons>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,64 +1,91 @@
import SavedObjectRegistryProvider from 'ui/saved_objects/saved_object_registry';
import 'ui/pager_control';
import 'ui/pager';
import { DashboardConstants } from '../dashboard_constants';
import _ from 'lodash';

export function DashboardListingController(
$scope,
kbnUrl,
Notifier,
Private,
timefilter,
confirmModal
) {
export function DashboardListingController($injector, $scope) {
const $filter = $injector.get('$filter');
const confirmModal = $injector.get('confirmModal');
const kbnUrl = $injector.get('kbnUrl');
const Notifier = $injector.get('Notifier');
const pagerFactory = $injector.get('pagerFactory');
const Private = $injector.get('Private');
const timefilter = $injector.get('timefilter');

timefilter.enabled = false;

const limitTo = $filter('limitTo');
// TODO: Extract this into an external service.
const services = Private(SavedObjectRegistryProvider).byLoaderPropertiesName;
const dashboardService = services.dashboards;
const notify = new Notifier({ location: 'Dashboard' });

let selectedItems = [];

/**
* Sorts hits either ascending or descending
* @param {Array} hits Array of saved finder object hits
* @return {Array} Array sorted either ascending or descending
*/
const sortItems = () => {
this.items =
this.isAscending
? _.sortBy(this.items, 'title')
: _.sortBy(this.items, 'title').reverse();
};

const calculateItemsOnPage = () => {
sortItems();
this.pager.setTotalItems(this.items.length);
this.pageOfItems = limitTo(this.items, this.pager.pageSize, this.pager.startIndex);
};

const fetchObjects = () => {
dashboardService.find(this.filter)
.then(result => {
this.items = result.hits;
this.sortItems();
calculateItemsOnPage();
});
};

const deselectAll = () => {
selectedItems = [];
};

const selectAll = () => {
selectedItems = this.pageOfItems.slice(0);
};

this.items = [];
this.pageOfItems = [];
this.filter = '';

this.pager = pagerFactory.create(this.items.length, 20, 1);

$scope.$watch(() => this.filter, () => {
deselectAll();
fetchObjects();
});

/**
* Boolean that keeps track of whether hits are sorted ascending (true)
* or descending (false) by title
* @type {Boolean}
*/
this.isAscending = true;

/**
* Sorts hits either ascending or descending
* @param {Array} hits Array of saved finder object hits
* @return {Array} Array sorted either ascending or descending
*/
this.sortItems = function sortItems() {
this.items =
this.isAscending
? _.sortBy(this.items, 'title')
: _.sortBy(this.items, 'title').reverse();
};

this.toggleSort = function toggleSort() {
this.isAscending = !this.isAscending;
this.sortItems();
deselectAll();
calculateItemsOnPage();
};

this.toggleAll = function toggleAll() {
if (this.areAllItemsChecked()) {
selectedItems = [];
deselectAll();
} else {
selectedItems = this.items.slice(0);
selectAll();
}
};

Expand All @@ -76,7 +103,7 @@ export function DashboardListingController(
};

this.areAllItemsChecked = function areAllItemsChecked() {
return this.getSelectedItemsCount() === this.items.length;
return this.getSelectedItemsCount() === this.pageOfItems.length;
};

this.getSelectedItemsCount = function getSelectedItemsCount() {
Expand All @@ -90,10 +117,11 @@ export function DashboardListingController(
dashboardService.delete(selectedIds)
.then(fetchObjects)
.then(() => {
selectedItems = [];
deselectAll();
})
.catch(error => notify.error(error));
};

confirmModal(
'Are you sure you want to delete the selected dashboards? This action is irreversible!',
{
Expand All @@ -102,11 +130,19 @@ export function DashboardListingController(
});
};

this.open = function open(item) {
kbnUrl.change(item.url.substr(1));
this.onPageNext = () => {
deselectAll();
this.pager.nextPage();
calculateItemsOnPage();
};

$scope.$watch(() => this.filter, () => {
fetchObjects();
});
this.onPagePrevious = () => {
deselectAll();
this.pager.previousPage();
calculateItemsOnPage();
};

this.getUrlForItem = function getUrlForItem(item) {
return `#/dashboard/${item.id}`;
};
}
20 changes: 9 additions & 11 deletions src/core_plugins/kibana/public/visualize/editor/editor.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@
<kbn-top-nav name="visualize" config="topNavMenu">
<!-- Transcluded elements. -->
<div data-transclude-slots>
<!-- Title. -->
<div
<!-- Breadcrumbs. -->
<bread-crumbs
data-transclude-slot="topLeftCorner"
class="kuiLocalTitle"
>
<span
ng-show="savedVis.id"
ng-bind="savedVis.lastSavedTitle"
></span>
</div>
page-title="getVisualizationTitle()"
use-links="true"
omit-current-page="true"
omit-pages="['edit']"
></bread-crumbs>

<!-- Search. -->
<div
Expand All @@ -29,11 +27,11 @@
ng-dblclick="unlink()"
tooltip="Double click to unlink from Saved Search"
>
<i aria-hidden="true" class="fa fa-chain-broken"></i>
<span aria-hidden="true" class="fa fa-chain-broken"></span>
</a>
</div>

<!-- Allow searching if there is no linked Saved Searc. -->
<!-- Allow searching if there is no linked Saved Search. -->
<form
ng-if="vis.type.requiresSearch && !$state.linked"
name="queryInput"
Expand Down
Loading

0 comments on commit a5705f8

Please sign in to comment.