berlioz
Version:
Berlioz - cloud deployment and migration services
153 lines (137 loc) • 3.83 kB
JavaScript
const Table = require('cli-table');
const _ = require('the-lodash');
const wrap = require('word-wrap');
class CliTable
{
constructor(screen, headers)
{
this._screen = screen;
this._columns = [];
this._rows = [];
if (headers) {
for(var header of headers) {
this.column(header);
}
}
}
column(name, width, isFixed)
{
var column = {
name: name
};
if (isFixed) {
if (!width) {
throw new Error('Missing fixed width');
}
column.fixedWidth = width;
column.isFixed = true;
} else {
if (!width) {
width = 1;
}
column.relativeWidth = width;
column.isFixed = false;
}
return this._insertColumn(column);
}
autofitColumn(name)
{
var column = {
name: name,
autofit: true
};
return this._insertColumn(column);
}
_insertColumn(column)
{
column.index = this._columns.length;
this._columns.push(column);
return this;
}
addRow(data, predicate)
{
var row = data;
if (predicate) {
row = predicate(data);
}
if (row.length != this._columns.length) {
console.log("----------------------")
console.log(this._columns.map(x => x.name))
console.log(row)
throw new Error(`Cell count does not match with column count`);
}
this._rows.push(row.map(x => {
if (_.isBoolean(x)) {
return x.toString();
}
if (x) {
return x;
}
return '';
}));
return this;
}
addRange(rows, predicate)
{
for (var row of rows) {
this.addRow(row, predicate);
}
return this;
}
output() {
var innerWidth = this._screen.screenWidth;
innerWidth = innerWidth - (this._columns.length - 1);
for(var column of this._columns)
{
if (column.autofit)
{
var widths = this._rows.map(x => x[column.index].length);
widths.push(column.name.length);
column.isFixed = true;
column.fixedWidth = _.max(widths);
}
}
for(var column of this._columns)
{
if (column.isFixed) {
column.width = column.fixedWidth + 3;
innerWidth = innerWidth - column.width;
}
}
var relativeColumns = this._columns.filter(x => !x.isFixed);
var totalRelativeWidth = _.sumBy(relativeColumns, x => x.relativeWidth);
for(var column of relativeColumns)
{
var width = (innerWidth * column.relativeWidth / totalRelativeWidth);
if (width < 1) {
width = 1;
}
column.width = Math.floor(width);
}
var opts = {
head: this._columns.map(x => x.name),
colWidths: this._columns.map(x => x.width)
}
var table = new Table(opts);
for(var row of this._rows)
{
var massagedRow = [];
for(var i = 0; i < row.length; i++)
{
massagedRow.push(this._massageCell(row[i], this._columns[i]));
}
table.push(massagedRow);
}
this._screen._rawOutput(table.toString());
}
_massageCell(cell, column)
{
cell = cell.toString();
return wrap(cell, {
width: column.width - 3,
indent: '',
cut: true
});
}
}
module.exports = CliTable;