Skip to content
This repository has been archived by the owner on Mar 31, 2024. It is now read-only.

Commit

Permalink
Merge pull request elastic#2013 from w33ble/page-table
Browse files Browse the repository at this point in the history
Paginated table directive
  • Loading branch information
lukasolson committed Nov 26, 2014
2 parents 61df9b3 + 17ce200 commit c6a3313
Show file tree
Hide file tree
Showing 8 changed files with 352 additions and 263 deletions.
35 changes: 5 additions & 30 deletions src/kibana/components/agg_table/agg_table.html
Original file line number Diff line number Diff line change
@@ -1,38 +1,13 @@
<paginate
<paginated-table
ng-if="formattedRows.length"

list="formattedRows"
per-page-prop="perPage"

class="agg-table">
<div class="agg-table-paginated">
<table class="table table-condensed">
<thead>
<tr bindonce>
<th
ng-repeat="col in table.columns"
ng-click="aggTable.cycleSort(col)"
ng-class="aggTable.getColumnClass(col, $first, $last)">
<span bo-text="col.title"></span>
<i
class="fa"
ng-class="{
'fa-sort-asc': aggTable.sort.col === col && aggTable.sort.asc,
'fa-sort-desc': aggTable.sort.col === col && !aggTable.sort.asc,
'fa-sort': !aggTable.sort || aggTable.sort.col !== col
}">
</i>
</th>
</tr>
</thead>
<tbody kbn-rows="page" kbn-rows-min="perPage"></tbody>
</table>
</div>
rows="formattedRows"
columns="formattedColumns"
per-page="perPage">

<div class="agg-table-controls">
<a class="small" ng-click="aggTable.exportAsCsv()">
Export <i class="fa fa-download"></i>
</a>
<paginate-controls></paginate-controls>
</div>
</paginate>
</paginated-table>
78 changes: 27 additions & 51 deletions src/kibana/components/agg_table/agg_table.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
define(function (require) {
require('components/paginated_table/paginated_table');
require('services/compile_recursive_directive');
require('css!components/agg_table/agg_table.css');

Expand All @@ -7,7 +8,6 @@ define(function (require) {
.directive('kbnAggTable', function ($filter, config, Private, compileRecursiveDirective) {
var _ = require('lodash');

var tabifyAggResponse = Private(require('components/agg_response/tabify/tabify'));
var orderBy = $filter('orderBy');

return {
Expand All @@ -33,42 +33,6 @@ define(function (require) {
quoteValues: config.get('csv:quoteValues')
};

self.getColumnClass = function (col, $first, $last) {
var cls = [];
var agg = $scope.table.aggConfig(col);

if ($last || (agg.schema.group === 'metrics')) {
cls.push('visualize-table-right');
}

if (!self.sort || self.sort.field !== col) {
cls.push('no-sort');
}

return cls.join(' ');
};

self.cycleSort = function (col) {
if (!self.sort || self.sort.col !== col) {
self.sort = {
col: col,
asc: true
};
} else if (self.sort.asc) {
self.sort.asc = false;
} else {
self.sort = null;
}

if (self.sort && !self.sort.getter) {
var colI = $scope.table.columns.indexOf(self.sort.col);
self.sort.getter = function (row) {
return row[colI];
};
if (colI === -1) self.sort = null;
}
};

self.exportAsCsv = function () {
var csv = new Blob([self.toCsv()], { type: 'text/plain' });
self._saveAs(csv, self.csv.filename);
Expand Down Expand Up @@ -104,39 +68,51 @@ define(function (require) {
}).join('');
};

$scope.$watchMulti([
'table',
'aggTable.sort.asc',
'aggTable.sort.col'
], function () {
$scope.$watch('table', function () {
var table = $scope.table;

if (!table) {
$scope.formattedRows = null;
$scope.formattedColumns = null;
return;
}

setFormattedRows(table);
setFormattedColumns(table);
});

function setFormattedColumns(table) {
$scope.formattedColumns = table.columns.map(function (col, i) {
var formattedColumn = {
title: col.title
};

var agg = $scope.table.aggConfig(col);
var last = i === (table.columns.length - 1);

if (last || (agg.schema.group === 'metrics')) {
formattedColumn.class = 'visualize-table-right';
}

return formattedColumn;
});
}

function setFormattedRows(table) {
var formatters = table.columns.map(function (col) {
return table.fieldFormatter(col);
});

// sort the row values, not formatted
if (self.sort) {
$scope.formattedRows = orderBy(table.rows, self.sort.getter, !self.sort.asc);
} else {
$scope.formattedRows = null;
}

// format all row values
$scope.formattedRows = ($scope.formattedRows || table.rows).map(function (row) {
$scope.formattedRows = (table.rows).map(function (row) {
return row.map(function (cell, i) {
return formatters[i](cell);
});
});

// update the csv file's title
self.csv.filename = (table.title() || 'table') + '.csv';
});
}
}
};
});
Expand Down
34 changes: 34 additions & 0 deletions src/kibana/components/paginated_table/paginated_table.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<paginate
ng-if="sortedRows.length"
list="sortedRows"
per-page-prop="perPage"
class="agg-table">
<div class="agg-table-paginated">
<table class="table table-condensed">
<thead>
<tr bindonce>
<th
ng-repeat="col in columns"
ng-click="paginatedTable.sortColumn(col)"
class="{{ col.class }}">
<span bo-text="col.title"></span>
<i
class="fa"
ng-class="{
'fa-sort-asc': paginatedTable.sort.columnName === col.title && paginatedTable.sort.direction === 'asc',
'fa-sort-desc': paginatedTable.sort.columnName === col.title && paginatedTable.sort.direction === 'desc',
'fa-sort': paginatedTable.sort.direction === null || paginatedTable.sort.columnName !== col.title
}">
</i>
</th>
</tr>
</thead>
<tbody kbn-rows="page" kbn-rows-min="perPage"></tbody>
</table>
</div>

<!-- auto-inserted by the paginate directive... -->
<!-- <paginate-controls></paginate-controls> -->
<div class="pagination-container" ng-transclude></div>

</paginate>
77 changes: 77 additions & 0 deletions src/kibana/components/paginated_table/paginated_table.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
define(function (require) {
require('modules')
.get('kibana')
.directive('paginatedTable', function ($filter, config, Private) {
var _ = require('lodash');
var orderBy = $filter('orderBy');

return {
restrict: 'E',
template: require('text!components/paginated_table/paginated_table.html'),
transclude: true,
scope: {
rows: '=',
columns: '=',
perPage: '=?',
sortHandler: '=?',
showSelector: '=?'
},
controllerAs: 'paginatedTable',
controller: function ($scope) {
var self = this;
self.sort = {
columnName: null,
direction: null
};

self.sortColumn = function (col) {
var sortDirection;
var cols = _.pluck($scope.columns, 'title');
var index = cols.indexOf(col.title);

if (index === -1) return;

if (self.sort.columnName !== col.title) {
sortDirection = 'asc';
} else {
var directions = {
null: 'asc',
'asc': 'desc',
'desc': null
};
sortDirection = directions[self.sort.direction];
}

self.sort.columnName = col.title;
self.sort.direction = sortDirection;
self._setSortGetter(index);
};

self._setSortGetter = function (index) {
if (_.isFunction($scope.sortHandler)) {
// use custom sort handler
self.sort.getter = $scope.sortHandler(index);
} else {
// use generic sort handler
self.sort.getter = function (row) {
return row[index];
};
}
};

// update the sordedRows result
$scope.$watchMulti([
'paginatedTable.sort.direction',
'rows'
], function () {
if (self.sort.direction == null) {
$scope.sortedRows = $scope.rows.slice(0);
return;
}

$scope.sortedRows = orderBy($scope.rows, self.sort.getter, self.sort.direction === 'desc');
});
}
};
});
});
52 changes: 23 additions & 29 deletions src/kibana/components/visualize/spy/spy.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ define(function (require) {
link: function ($scope, $el) {
var $container = $el.find('.visualize-spy-container');
var fullPageSpy = false;
// $scope.spyMode = null; // inherited from the parent
$scope.modes = modes;

$scope.toggleDisplay = function () {
Expand All @@ -36,38 +35,33 @@ define(function (require) {
var current = $scope.spyMode;
var change = false;

function set() {
// no change
if (current && newMode && newMode.name === current.name) return;

// clear the current value
if (current) {
current.$container.remove();
current.$scope.$destroy();
delete $scope.spyMode;
current = null;
change = true;
}

// no further changes
if (!newMode) return;
// no change
if (current && newMode && newMode.name === current.name) return;

// clear the current value
if (current) {
current.$container.remove();
current.$scope.$destroy();
delete $scope.spyMode;
current = null;
change = true;
current = $scope.spyMode = {
// copy a couple values over
name: newMode.name,
display: newMode.display,
fill: fullPageSpy,
$scope: $scope.$new(),
$container: $('<div class="visualize-spy-content">').appendTo($container)
};

current.$container.append($compile(newMode.template)(current.$scope));
newMode.link && newMode.link(current.$scope, current.$container);
}

// wrapped in fn to enable early return
set();
// no further changes
if (!newMode) return;

change = true;
current = $scope.spyMode = {
// copy a couple values over
name: newMode.name,
display: newMode.display,
fill: fullPageSpy,
$scope: $scope.$new(),
$container: $('<div class="visualize-spy-content">').appendTo($container)
};

current.$container.append($compile(newMode.template)(current.$scope));
newMode.link && newMode.link(current.$scope, current.$container);
};
}
};
Expand Down
2 changes: 1 addition & 1 deletion src/kibana/directives/paginate.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ define(function (require) {
}

self.perPage = _.parseInt(self.perPage) || $scope[self.perPageProp];
if (!self.perPage) {
if (self.perPage == null) {
self.perPage = ALL;
return;
}
Expand Down
Loading

0 comments on commit c6a3313

Please sign in to comment.