Feat/model backed ui (#1145)

This is an initial PR for a new model-driven UI where extensions can provide definitions of the components & how they're laid out using Containers.
#1140, #1141, #1142, #1143 and #1144 are all tracking additional work needed to improve the initial implementation and fix some issues with the implementation.

Features:
- Supports defining a FlexContainer that maps to a flexbox-based layout.
- Supports creating a card component, which is a key-value pair based control that will lay out simple information to a user. Eventually this will have an optional set of actions associated with it.
- Has a sample project which shows how to use the API and was used for verification
This commit is contained in:
Kevin Cunnane
2018-04-13 15:59:18 -07:00
committed by GitHub
parent e022f4a0d1
commit b2c70e9301
63 changed files with 13238 additions and 84 deletions

View File

@@ -26,7 +26,7 @@ export class RowDetailView {
this._options = mixin(options, this._defaults, false);
}
public init(grid: any) {
public init(grid: any): void {
this._grid = grid;
this._dataView = this._grid.getData();
@@ -61,17 +61,17 @@ export class RowDetailView {
this._options = $.extend(true, {}, this._options, options);
}
public handleClick(e: any, args: any) {
public handleClick(e: any, args: any): void {
// clicking on a row select checkbox
if (this._options.useRowClick || this._grid.getColumns()[args.cell].id === this._options.columnId && $(e.target).hasClass("detailView-toggle")) {
if (this._options.useRowClick || this._grid.getColumns()[args.cell].id === this._options.columnId && $(e.target).hasClass('detailView-toggle')) {
// if editing, try to commit
if (this._grid.getEditorLock().isActive() && !this._grid.getEditorLock().commitCurrentEdit()) {
e.preventDefault();
e.stopImmediatePropagation();
return;
e.preventDefault();
e.stopImmediatePropagation();
return;
}
var item = this._dataView.getItem(args.row);
let item = this._dataView.getItem(args.row);
// trigger an event before toggling
this.onBeforeRowDetailToggle.notify({
@@ -100,36 +100,35 @@ export class RowDetailView {
// If we scroll save detail views that go out of cache range
public handleScroll(e, args) {
var range = this._grid.getRenderedRange();
let range = this._grid.getRenderedRange();
var start = (range.top > 0 ? range.top : 0);
var end = (range.bottom > this._dataView.getLength() ? range.bottom : this._dataView.getLength());
let start: number = (range.top > 0 ? range.top : 0);
let end: number = (range.bottom > this._dataView.getLength() ? range.bottom : this._dataView.getLength());
if (end <= 0) {
return;
}
// Get the item at the top of the view
var topMostItem = this._dataView.getItemByIdx(start);
let topMostItem = this._dataView.getItemByIdx(start);
// Check it is a parent item
if (topMostItem._parent === undefined)
{
if (topMostItem._parent === undefined) {
// This is a standard row as we have no parent.
var nextItem = this._dataView.getItemByIdx(start + 1);
if(nextItem !== undefined && nextItem._parent !== undefined)
{
let nextItem = this._dataView.getItemByIdx(start + 1);
if (nextItem !== undefined && nextItem._parent !== undefined) {
// This is likely the expanded Detail Row View
// Check for safety
if(nextItem._parent === topMostItem)
{
if (nextItem._parent === topMostItem) {
this.saveDetailView(topMostItem);
}
}
}
// Find the bottom most item that is likely to go off screen
var bottomMostItem = this._dataView.getItemByIdx(end - 1);
let bottomMostItem = this._dataView.getItemByIdx(end - 1);
// If we are a detailView and we are about to go out of cache view
if(bottomMostItem._parent !== undefined)
{
if (bottomMostItem._parent !== undefined) {
this.saveDetailView(bottomMostItem._parent);
}
}
@@ -143,17 +142,17 @@ export class RowDetailView {
// Collapse all of the open items
public collapseAll() {
for (var i = this._expandedRows.length - 1; i >= 0; i--) {
for (let i = this._expandedRows.length - 1; i >= 0; i--) {
this.collapseItem(this._expandedRows[i]);
}
}
// Saves the current state of the detail view
public saveDetailView(item) {
var view = $('#innerDetailView_' + item.id);
let view = $('#innerDetailView_' + item.id);
if (view) {
var html = $('#innerDetailView_' + item.id).html();
if(html !== undefined) {
let html = $('#innerDetailView_' + item.id).html();
if (html !== undefined) {
item._detailContent = html;
}
}
@@ -230,7 +229,7 @@ export class RowDetailView {
args.itemDetail._detailViewLoaded = true;
var idxParent = this._dataView.getIdxById(args.itemDetail.id);
let idxParent = this._dataView.getIdxById(args.itemDetail.id);
this._dataView.updateItem(args.itemDetail.id, args.itemDetail);
// trigger an event once the post template is finished loading
@@ -254,7 +253,7 @@ export class RowDetailView {
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
public getPaddingItem(parent, offset) {
var item: any = {};
let item: any = {};
for (let prop in this._grid.getData()) {
item[prop] = null;
@@ -284,7 +283,7 @@ export class RowDetailView {
item._height = (item._sizePadding * this._grid.getOptions().rowHeight);
let idxParent = this._dataView.getIdxById(item.id);
for (var idx = 1; idx <= item._sizePadding; idx++) {
for (let idx = 1; idx <= item._sizePadding; idx++) {
this._dataView.insertItem(idxParent + idx, this.getPaddingItem(item, idx));
}
}
@@ -307,12 +306,12 @@ export class RowDetailView {
public detailSelectionFormatter(row, cell, value, columnDef, dataContext) {
if (dataContext._collapsed === undefined) {
dataContext._collapsed = true,
dataContext._sizePadding = 0, //the required number of pading rows
dataContext._height = 0, //the actual height in pixels of the detail field
dataContext._isPadding = false,
dataContext._parent = undefined,
dataContext._offset = 0
dataContext._collapsed = true;
dataContext._sizePadding = 0; //the required number of pading rows
dataContext._height = 0; //the actual height in pixels of the detail field
dataContext._isPadding = false;
dataContext._parent = undefined;
dataContext._offset = 0;
}
if (dataContext._isPadding === true) {
@@ -320,9 +319,9 @@ export class RowDetailView {
} else if (dataContext._collapsed) {
return '<div class=\'detailView-toggle expand\'></div>';
} else {
var html = [];
var rowHeight = this._grid.getOptions().rowHeight;
var bottomMargin = 5;
let html = [];
let rowHeight = this._grid.getOptions().rowHeight;
let bottomMargin = 5;
//V313HAX:
//putting in an extra closing div after the closing toggle div and ommiting a
@@ -339,7 +338,7 @@ export class RowDetailView {
html.push("style='height:", dataContext._height, "px;"); //set total height of padding
html.push("top:", rowHeight, "px'>"); //shift detail below 1st row
html.push("<div id='detailViewContainer_", dataContext.id, "' class='detail-container' style='max-height:" + (dataContext._height - rowHeight + bottomMargin) + "px'>"); //sub ctr for custom styling
html.push("<div id='innerDetailView_" , dataContext.id , "'>" , dataContext._detailContent, "</div></div>");
html.push("<div id='innerDetailView_", dataContext.id, "'>", dataContext._detailContent, "</div></div>");
//&omit a final closing detail container </div> that would come next
return html.join('');
@@ -351,33 +350,32 @@ export class RowDetailView {
if (!item) return;
// Grad each of the dom items
var mainContainer = document.getElementById('detailViewContainer_' + item.id);
var cellItem = document.getElementById('cellDetailView_' + item.id);
var inner = document.getElementById('innerDetailView_' + item.id);
let mainContainer = document.getElementById('detailViewContainer_' + item.id);
let cellItem = document.getElementById('cellDetailView_' + item.id);
let inner = document.getElementById('innerDetailView_' + item.id);
if (!mainContainer || !cellItem || !inner) return;
for (var idx = 1; idx <= item._sizePadding; idx++) {
for (let idx = 1; idx <= item._sizePadding; idx++) {
this._dataView.deleteItem(item.id + "." + idx);
}
var rowHeight = this._grid.getOptions().rowHeight; // height of a row
var lineHeight = 13; //we know cuz we wrote the custom css innit ;)
let rowHeight = this._grid.getOptions().rowHeight; // height of a row
let lineHeight = 13; //we know cuz we wrote the custom css innit ;)
// Get the inner Item height as this will be the actual size
var itemHeight = inner.clientHeight;
let itemHeight = inner.clientHeight;
// Now work out how many rows
var rowCount = Math.ceil(itemHeight / rowHeight) + 1;
let rowCount = Math.ceil(itemHeight / rowHeight) + 1;
item._sizePadding = Math.ceil(((rowCount * 2) * lineHeight) / rowHeight);
item._height = (item._sizePadding * rowHeight);
// If the padding is now more than the original minRowBuff we need to increase it
if (this._grid.getOptions().minRowBuffer < item._sizePadding)
{
if (this._grid.getOptions().minRowBuffer < item._sizePadding) {
// Update the minRowBuffer so that the view doesn't disappear when it's at top of screen + the original default 3
this._grid.getOptions().minRowBuffer =item._sizePadding + 3;
this._grid.getOptions().minRowBuffer = item._sizePadding + 3;
}
mainContainer.setAttribute("style", "max-height: " + item._height + "px");
@@ -386,7 +384,7 @@ export class RowDetailView {
}
let idxParent = this._dataView.getIdxById(item.id);
for (var idx = 1; idx <= item._sizePadding; idx++) {
for (let idx = 1; idx <= item._sizePadding; idx++) {
this._dataView.insertItem(idxParent + idx, this.getPaddingItem(item, idx));
}
}