ag-grid
Version:
Advanced Data Grid / Data Table supporting Javascript / React / AngularJS / Web Components
1,098 lines (1,097 loc) • 94.3 kB
JavaScript
/**
* ag-grid - Advanced Data Grid / Data Table supporting Javascript / React / AngularJS / Web Components
* @version v17.0.0
* @link http://www.ag-grid.com/
* @license MIT
*/
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
var utils_1 = require("../utils");
var columnGroup_1 = require("../entities/columnGroup");
var column_1 = require("../entities/column");
var gridOptionsWrapper_1 = require("../gridOptionsWrapper");
var expressionService_1 = require("../valueService/expressionService");
var balancedColumnTreeBuilder_1 = require("./balancedColumnTreeBuilder");
var displayedGroupCreator_1 = require("./displayedGroupCreator");
var autoWidthCalculator_1 = require("../rendering/autoWidthCalculator");
var eventService_1 = require("../eventService");
var columnUtils_1 = require("./columnUtils");
var logger_1 = require("../logger");
var events_1 = require("../events");
var originalColumnGroup_1 = require("../entities/originalColumnGroup");
var groupInstanceIdCreator_1 = require("./groupInstanceIdCreator");
var context_1 = require("../context/context");
var gridPanel_1 = require("../gridPanel/gridPanel");
var columnAnimationService_1 = require("../rendering/columnAnimationService");
var autoGroupColService_1 = require("./autoGroupColService");
var valueCache_1 = require("../valueService/valueCache");
var gridApi_1 = require("../gridApi");
var columnApi_1 = require("./columnApi");
var ColumnController = (function () {
function ColumnController() {
// header row count, based on user provided columns
this.primaryHeaderRowCount = 0;
this.secondaryHeaderRowCount = 0;
this.secondaryColumnsPresent = false;
// header row count, either above, or based on pivoting if we are pivoting
this.gridHeaderRowCount = 0;
// these are the lists used by the rowRenderer to render nodes. almost the leaf nodes of the above
// displayed trees, however it also takes into account if the groups are open or not.
this.displayedLeftColumns = [];
this.displayedRightColumns = [];
this.displayedCenterColumns = [];
// all three lists above combined
this.allDisplayedColumns = [];
// same as above, except trimmed down to only columns within the viewport
this.allDisplayedVirtualColumns = [];
this.allDisplayedCenterVirtualColumns = [];
this.rowGroupColumns = [];
this.valueColumns = [];
this.pivotColumns = [];
this.ready = false;
this.autoGroupsNeedBuilding = false;
this.pivotMode = false;
this.bodyWidth = 0;
this.leftWidth = 0;
this.rightWidth = 0;
this.bodyWidthDirty = true;
}
ColumnController.prototype.init = function () {
var pivotMode = this.gridOptionsWrapper.isPivotMode();
if (this.isPivotSettingAllowed(pivotMode)) {
this.pivotMode = pivotMode;
}
this.usingTreeData = this.gridOptionsWrapper.isTreeData();
};
ColumnController.prototype.setVirtualViewportLeftAndRight = function () {
if (this.gridOptionsWrapper.isEnableRtl()) {
this.viewportLeft = this.bodyWidth - this.scrollPosition - this.scrollWidth;
this.viewportRight = this.bodyWidth - this.scrollPosition;
}
else {
this.viewportLeft = this.scrollPosition;
this.viewportRight = this.scrollWidth + this.scrollPosition;
}
};
// used by clipboard service, to know what columns to paste into
ColumnController.prototype.getDisplayedColumnsStartingAt = function (column) {
var currentColumn = column;
var result = [];
while (utils_1.Utils.exists(currentColumn)) {
result.push(currentColumn);
currentColumn = this.getDisplayedColAfter(currentColumn);
}
return result;
};
// checks what columns are currently displayed due to column virtualisation. fires an event
// if the list of columns has changed.
// + setColumnWidth(), setVirtualViewportPosition(), setColumnDefs(), sizeColumnsToFit()
ColumnController.prototype.checkDisplayedVirtualColumns = function () {
// check displayCenterColumnTree exists first, as it won't exist when grid is initialising
if (utils_1.Utils.exists(this.displayedCenterColumns)) {
var hashBefore = this.allDisplayedVirtualColumns.map(function (column) { return column.getId(); }).join('#');
this.updateVirtualSets();
var hashAfter = this.allDisplayedVirtualColumns.map(function (column) { return column.getId(); }).join('#');
if (hashBefore !== hashAfter) {
var event_1 = {
type: events_1.Events.EVENT_VIRTUAL_COLUMNS_CHANGED,
api: this.gridApi,
columnApi: this.columnApi
};
this.eventService.dispatchEvent(event_1);
}
}
};
ColumnController.prototype.setVirtualViewportPosition = function (scrollWidth, scrollPosition) {
if (scrollWidth !== this.scrollWidth || scrollPosition !== this.scrollPosition || this.bodyWidthDirty) {
this.scrollWidth = scrollWidth;
this.scrollPosition = scrollPosition;
// we need to call setVirtualViewportLeftAndRight() at least once after the body width changes,
// as the viewport can stay the same, but in RTL, if body width changes, we need to work out the
// virtual columns again
this.bodyWidthDirty = true;
this.setVirtualViewportLeftAndRight();
if (this.ready) {
this.checkDisplayedVirtualColumns();
}
}
};
ColumnController.prototype.isPivotMode = function () {
return this.pivotMode;
};
ColumnController.prototype.isPivotSettingAllowed = function (pivot) {
if (pivot) {
if (this.gridOptionsWrapper.isTreeData()) {
console.warn("ag-Grid: Pivot mode not available in conjunction Tree Data i.e. 'gridOptions.treeData: true'");
return false;
}
else {
return true;
}
}
else {
return true;
}
};
ColumnController.prototype.setPivotMode = function (pivotMode, source) {
if (source === void 0) { source = "api"; }
if (pivotMode === this.pivotMode) {
return;
}
if (!this.isPivotSettingAllowed(this.pivotMode)) {
return;
}
this.pivotMode = pivotMode;
this.updateDisplayedColumns(source);
var event = {
type: events_1.Events.EVENT_COLUMN_PIVOT_MODE_CHANGED,
api: this.gridApi,
columnApi: this.columnApi
};
this.eventService.dispatchEvent(event);
};
ColumnController.prototype.getSecondaryPivotColumn = function (pivotKeys, valueColKey) {
if (!this.secondaryColumnsPresent) {
return null;
}
var valueColumnToFind = this.getPrimaryColumn(valueColKey);
var foundColumn = null;
this.secondaryColumns.forEach(function (column) {
var thisPivotKeys = column.getColDef().pivotKeys;
var pivotValueColumn = column.getColDef().pivotValueColumn;
var pivotKeyMatches = utils_1.Utils.compareArrays(thisPivotKeys, pivotKeys);
var pivotValueMatches = pivotValueColumn === valueColumnToFind;
if (pivotKeyMatches && pivotValueMatches) {
foundColumn = column;
}
});
return foundColumn;
};
ColumnController.prototype.setBeans = function (loggerFactory) {
this.logger = loggerFactory.create('ColumnController');
};
ColumnController.prototype.setFirstRightAndLastLeftPinned = function (source) {
var lastLeft;
var firstRight;
if (this.gridOptionsWrapper.isEnableRtl()) {
lastLeft = this.displayedLeftColumns ? this.displayedLeftColumns[0] : null;
firstRight = this.displayedRightColumns ? this.displayedRightColumns[this.displayedRightColumns.length - 1] : null;
}
else {
lastLeft = this.displayedLeftColumns ? this.displayedLeftColumns[this.displayedLeftColumns.length - 1] : null;
firstRight = this.displayedRightColumns ? this.displayedRightColumns[0] : null;
}
this.gridColumns.forEach(function (column) {
column.setLastLeftPinned(column === lastLeft, source);
column.setFirstRightPinned(column === firstRight, source);
});
};
ColumnController.prototype.autoSizeColumns = function (keys, source) {
// because of column virtualisation, we can only do this function on columns that are
// actually rendered, as non-rendered columns (outside the viewport and not rendered
// due to column virtualisation) are not present. this can result in all rendered columns
// getting narrowed, which in turn introduces more rendered columns on the RHS which
// did not get autosized in the original run, leaving the visible grid with columns on
// the LHS sized, but RHS no. so we keep looping through teh visible columns until
// no more cols are available (rendered) to be resized
var _this = this;
if (source === void 0) { source = "api"; }
// keep track of which cols we have resized in here
var columnsAutosized = [];
// initialise with anything except 0 so that while loop executs at least once
var changesThisTimeAround = -1;
while (changesThisTimeAround !== 0) {
changesThisTimeAround = 0;
this.actionOnGridColumns(keys, function (column) {
// if already autosized, skip it
if (columnsAutosized.indexOf(column) >= 0) {
return;
}
// get how wide this col should be
var preferredWidth = _this.autoWidthCalculator.getPreferredWidthForColumn(column);
// preferredWidth = -1 if this col is not on the screen
if (preferredWidth > 0) {
var newWidth = _this.normaliseColumnWidth(column, preferredWidth);
column.setActualWidth(newWidth, source);
columnsAutosized.push(column);
changesThisTimeAround++;
}
return true;
}, source);
}
if (columnsAutosized.length > 0) {
var event_2 = {
type: events_1.Events.EVENT_COLUMN_RESIZED,
columns: columnsAutosized,
column: columnsAutosized.length === 1 ? columnsAutosized[0] : null,
finished: true,
api: this.gridApi,
columnApi: this.columnApi,
source: "autosizeColumns"
};
this.eventService.dispatchEvent(event_2);
}
};
ColumnController.prototype.autoSizeColumn = function (key, source) {
if (source === void 0) { source = "api"; }
this.autoSizeColumns([key], source);
};
ColumnController.prototype.autoSizeAllColumns = function (source) {
if (source === void 0) { source = "api"; }
var allDisplayedColumns = this.getAllDisplayedColumns();
this.autoSizeColumns(allDisplayedColumns, source);
};
ColumnController.prototype.getColumnsFromTree = function (rootColumns) {
var result = [];
recursiveFindColumns(rootColumns);
return result;
function recursiveFindColumns(childColumns) {
for (var i = 0; i < childColumns.length; i++) {
var child = childColumns[i];
if (child instanceof column_1.Column) {
result.push(child);
}
else if (child instanceof originalColumnGroup_1.OriginalColumnGroup) {
recursiveFindColumns(child.getChildren());
}
}
}
};
ColumnController.prototype.getAllDisplayedColumnGroups = function () {
if (this.displayedLeftColumnTree && this.displayedRightColumnTree && this.displayedCentreColumnTree) {
return this.displayedLeftColumnTree
.concat(this.displayedCentreColumnTree)
.concat(this.displayedRightColumnTree);
}
else {
return null;
}
};
// + columnSelectPanel
ColumnController.prototype.getPrimaryColumnTree = function () {
return this.primaryBalancedTree;
};
// + gridPanel -> for resizing the body and setting top margin
ColumnController.prototype.getHeaderRowCount = function () {
return this.gridHeaderRowCount;
};
// + headerRenderer -> setting pinned body width
ColumnController.prototype.getLeftDisplayedColumnGroups = function () {
return this.displayedLeftColumnTree;
};
// + headerRenderer -> setting pinned body width
ColumnController.prototype.getRightDisplayedColumnGroups = function () {
return this.displayedRightColumnTree;
};
// + headerRenderer -> setting pinned body width
ColumnController.prototype.getCenterDisplayedColumnGroups = function () {
return this.displayedCentreColumnTree;
};
ColumnController.prototype.getDisplayedColumnGroups = function (type) {
switch (type) {
case column_1.Column.PINNED_LEFT: return this.getLeftDisplayedColumnGroups();
case column_1.Column.PINNED_RIGHT: return this.getRightDisplayedColumnGroups();
default: return this.getCenterDisplayedColumnGroups();
}
};
// gridPanel -> ensureColumnVisible
ColumnController.prototype.isColumnDisplayed = function (column) {
return this.getAllDisplayedColumns().indexOf(column) >= 0;
};
// + csvCreator
ColumnController.prototype.getAllDisplayedColumns = function () {
return this.allDisplayedColumns;
};
ColumnController.prototype.getAllDisplayedVirtualColumns = function () {
return this.allDisplayedVirtualColumns;
};
ColumnController.prototype.getDisplayedLeftColumnsForRow = function (rowNode) {
if (!this.colSpanActive) {
return this.displayedLeftColumns;
}
else {
return this.getDisplayedColumnsForRow(rowNode, this.displayedLeftColumns);
}
};
ColumnController.prototype.getDisplayedRightColumnsForRow = function (rowNode) {
if (!this.colSpanActive) {
return this.displayedRightColumns;
}
else {
return this.getDisplayedColumnsForRow(rowNode, this.displayedRightColumns);
}
};
ColumnController.prototype.getDisplayedColumnsForRow = function (rowNode, displayedColumns, filterCallback, gapBeforeCallback) {
var result = [];
var lastConsideredCol = null;
for (var i = 0; i < displayedColumns.length; i++) {
var col = displayedColumns[i];
var colSpan = col.getColSpan(rowNode);
if (colSpan > 1) {
var colsToRemove = colSpan - 1;
i += colsToRemove;
}
var filterPasses = filterCallback ? filterCallback(col) : true;
if (filterPasses) {
var gapBeforeColumn = gapBeforeCallback ? gapBeforeCallback(col) : false;
var addInPreviousColumn = result.length === 0 && gapBeforeColumn && lastConsideredCol;
if (addInPreviousColumn) {
result.push(lastConsideredCol);
}
result.push(col);
}
lastConsideredCol = col;
}
return result;
};
// + rowRenderer
// if we are not column spanning, this just returns back the virtual centre columns,
// however if we are column spanning, then different rows can have different virtual
// columns, so we have to work out the list for each individual row.
ColumnController.prototype.getAllDisplayedCenterVirtualColumnsForRow = function (rowNode) {
var _this = this;
if (!this.colSpanActive) {
return this.allDisplayedCenterVirtualColumns;
}
var gapBeforeCallback = function (col) { return col.getLeft() > _this.viewportLeft; };
return this.getDisplayedColumnsForRow(rowNode, this.displayedCenterColumns, this.isColumnInViewport.bind(this), gapBeforeCallback);
};
ColumnController.prototype.isColumnInViewport = function (col) {
var columnLeft = col.getLeft();
var columnRight = col.getLeft() + col.getActualWidth();
var columnToMuchLeft = columnLeft < this.viewportLeft && columnRight < this.viewportLeft;
var columnToMuchRight = columnLeft > this.viewportRight && columnRight > this.viewportRight;
return !columnToMuchLeft && !columnToMuchRight;
};
// used by:
// + angularGrid -> setting pinned body width
// todo: this needs to be cached
ColumnController.prototype.getPinnedLeftContainerWidth = function () {
return this.getWidthOfColsInList(this.displayedLeftColumns);
};
// todo: this needs to be cached
ColumnController.prototype.getPinnedRightContainerWidth = function () {
return this.getWidthOfColsInList(this.displayedRightColumns);
};
ColumnController.prototype.updatePrimaryColumnList = function (keys, masterList, actionIsAdd, columnCallback, eventType, source) {
var _this = this;
if (source === void 0) { source = "api"; }
if (utils_1.Utils.missingOrEmpty(keys)) {
return;
}
var atLeastOne = false;
keys.forEach(function (key) {
var columnToAdd = _this.getPrimaryColumn(key);
if (!columnToAdd) {
return;
}
if (actionIsAdd) {
if (masterList.indexOf(columnToAdd) >= 0) {
return;
}
masterList.push(columnToAdd);
}
else {
if (masterList.indexOf(columnToAdd) < 0) {
return;
}
utils_1.Utils.removeFromArray(masterList, columnToAdd);
}
columnCallback(columnToAdd);
atLeastOne = true;
});
if (!atLeastOne) {
return;
}
if (this.autoGroupsNeedBuilding) {
this.updateGridColumns();
}
this.updateDisplayedColumns(source);
var event = {
type: eventType,
columns: masterList,
column: masterList.length === 1 ? masterList[0] : null,
api: this.gridApi,
columnApi: this.columnApi,
source: source
};
this.eventService.dispatchEvent(event);
};
ColumnController.prototype.setRowGroupColumns = function (colKeys, source) {
if (source === void 0) { source = "api"; }
this.autoGroupsNeedBuilding = true;
this.setPrimaryColumnList(colKeys, this.rowGroupColumns, events_1.Events.EVENT_COLUMN_ROW_GROUP_CHANGED, this.setRowGroupActive.bind(this), source);
};
ColumnController.prototype.setRowGroupActive = function (active, column, source) {
if (active === column.isRowGroupActive()) {
return;
}
column.setRowGroupActive(active, source);
if (!active) {
column.setVisible(true, source);
}
};
ColumnController.prototype.addRowGroupColumn = function (key, source) {
if (source === void 0) { source = "api"; }
this.addRowGroupColumns([key], source);
};
ColumnController.prototype.addRowGroupColumns = function (keys, source) {
if (source === void 0) { source = "api"; }
this.autoGroupsNeedBuilding = true;
this.updatePrimaryColumnList(keys, this.rowGroupColumns, true, this.setRowGroupActive.bind(this, true), events_1.Events.EVENT_COLUMN_ROW_GROUP_CHANGED, source);
};
ColumnController.prototype.removeRowGroupColumns = function (keys, source) {
if (source === void 0) { source = "api"; }
this.autoGroupsNeedBuilding = true;
this.updatePrimaryColumnList(keys, this.rowGroupColumns, false, this.setRowGroupActive.bind(this, false), events_1.Events.EVENT_COLUMN_ROW_GROUP_CHANGED, source);
};
ColumnController.prototype.removeRowGroupColumn = function (key, source) {
if (source === void 0) { source = "api"; }
this.removeRowGroupColumns([key], source);
};
ColumnController.prototype.addPivotColumns = function (keys, source) {
if (source === void 0) { source = "api"; }
this.updatePrimaryColumnList(keys, this.pivotColumns, true, function (column) { return column.setPivotActive(true, source); }, events_1.Events.EVENT_COLUMN_PIVOT_CHANGED, source);
};
ColumnController.prototype.setPivotColumns = function (colKeys, source) {
if (source === void 0) { source = "api"; }
this.setPrimaryColumnList(colKeys, this.pivotColumns, events_1.Events.EVENT_COLUMN_PIVOT_CHANGED, function (added, column) {
column.setPivotActive(added, source);
}, source);
};
ColumnController.prototype.addPivotColumn = function (key, source) {
if (source === void 0) { source = "api"; }
this.addPivotColumns([key], source);
};
ColumnController.prototype.removePivotColumns = function (keys, source) {
if (source === void 0) { source = "api"; }
this.updatePrimaryColumnList(keys, this.pivotColumns, false, function (column) { return column.setPivotActive(false, source); }, events_1.Events.EVENT_COLUMN_PIVOT_CHANGED, source);
};
ColumnController.prototype.removePivotColumn = function (key, source) {
if (source === void 0) { source = "api"; }
this.removePivotColumns([key], source);
};
ColumnController.prototype.setPrimaryColumnList = function (colKeys, masterList, eventName, columnCallback, source) {
var _this = this;
masterList.length = 0;
if (utils_1.Utils.exists(colKeys)) {
colKeys.forEach(function (key) {
var column = _this.getPrimaryColumn(key);
masterList.push(column);
});
}
this.primaryColumns.forEach(function (column) {
var added = masterList.indexOf(column) >= 0;
columnCallback(added, column);
});
if (this.autoGroupsNeedBuilding) {
this.updateGridColumns();
}
this.updateDisplayedColumns(source);
var event = {
type: eventName,
columns: masterList,
column: masterList.length === 1 ? masterList[0] : null,
api: this.gridApi,
columnApi: this.columnApi,
source: source
};
this.eventService.dispatchEvent(event);
};
ColumnController.prototype.setValueColumns = function (colKeys, source) {
if (source === void 0) { source = "api"; }
this.setPrimaryColumnList(colKeys, this.valueColumns, events_1.Events.EVENT_COLUMN_VALUE_CHANGED, this.setValueActive.bind(this), source);
};
ColumnController.prototype.setValueActive = function (active, column, source) {
if (active === column.isValueActive()) {
return;
}
column.setValueActive(active, source);
if (active && !column.getAggFunc()) {
var defaultAggFunc = this.aggFuncService.getDefaultAggFunc(column);
column.setAggFunc(defaultAggFunc);
}
};
ColumnController.prototype.addValueColumns = function (keys, source) {
if (source === void 0) { source = "api"; }
this.updatePrimaryColumnList(keys, this.valueColumns, true, this.setValueActive.bind(this, true), events_1.Events.EVENT_COLUMN_VALUE_CHANGED, source);
};
ColumnController.prototype.addValueColumn = function (colKey, source) {
if (source === void 0) { source = "api"; }
this.addValueColumns([colKey], source);
};
ColumnController.prototype.removeValueColumn = function (colKey, source) {
if (source === void 0) { source = "api"; }
this.removeValueColumns([colKey], source);
};
ColumnController.prototype.removeValueColumns = function (keys, source) {
if (source === void 0) { source = "api"; }
this.updatePrimaryColumnList(keys, this.valueColumns, false, this.setValueActive.bind(this, false), events_1.Events.EVENT_COLUMN_VALUE_CHANGED, source);
};
// returns the width we can set to this col, taking into consideration min and max widths
ColumnController.prototype.normaliseColumnWidth = function (column, newWidth) {
if (newWidth < column.getMinWidth()) {
newWidth = column.getMinWidth();
}
if (column.isGreaterThanMax(newWidth)) {
newWidth = column.getMaxWidth();
}
return newWidth;
};
ColumnController.prototype.getPrimaryOrGridColumn = function (key) {
var column = this.getPrimaryColumn(key);
if (column) {
return column;
}
else {
return this.getGridColumn(key);
}
};
ColumnController.prototype.setColumnWidth = function (key, newWidth, finished, source) {
if (source === void 0) { source = "api"; }
var column = this.getPrimaryOrGridColumn(key);
if (!column) {
return;
}
newWidth = this.normaliseColumnWidth(column, newWidth);
var widthChanged = column.getActualWidth() !== newWidth;
if (widthChanged) {
column.setActualWidth(newWidth, source);
this.setLeftValues(source);
}
this.updateBodyWidths();
this.checkDisplayedVirtualColumns();
// check for change first, to avoid unnecessary firing of events
// however we always fire 'finished' events. this is important
// when groups are resized, as if the group is changing slowly,
// eg 1 pixel at a time, then each change will fire change events
// in all the columns in the group, but only one with get the pixel.
if (finished || widthChanged) {
var event_3 = {
type: events_1.Events.EVENT_COLUMN_RESIZED,
columns: [column],
column: column,
finished: finished,
api: this.gridApi,
columnApi: this.columnApi,
source: source
};
this.eventService.dispatchEvent(event_3);
}
};
ColumnController.prototype.setColumnAggFunc = function (column, aggFunc, source) {
if (source === void 0) { source = "api"; }
column.setAggFunc(aggFunc);
var event = {
type: events_1.Events.EVENT_COLUMN_VALUE_CHANGED,
columns: [column],
column: column,
api: this.gridApi,
columnApi: this.columnApi,
source: source
};
this.eventService.dispatchEvent(event);
};
ColumnController.prototype.moveRowGroupColumn = function (fromIndex, toIndex, source) {
if (source === void 0) { source = "api"; }
var column = this.rowGroupColumns[fromIndex];
this.rowGroupColumns.splice(fromIndex, 1);
this.rowGroupColumns.splice(toIndex, 0, column);
var event = {
type: events_1.Events.EVENT_COLUMN_ROW_GROUP_CHANGED,
columns: this.rowGroupColumns,
column: this.rowGroupColumns.length === 1 ? this.rowGroupColumns[0] : null,
api: this.gridApi,
columnApi: this.columnApi,
source: source
};
this.eventService.dispatchEvent(event);
};
ColumnController.prototype.moveColumns = function (columnsToMoveKeys, toIndex, source) {
if (source === void 0) { source = "api"; }
this.columnAnimationService.start();
if (toIndex > this.gridColumns.length - columnsToMoveKeys.length) {
console.warn('ag-Grid: tried to insert columns in invalid location, toIndex = ' + toIndex);
console.warn('ag-Grid: remember that you should not count the moving columns when calculating the new index');
return;
}
// we want to pull all the columns out first and put them into an ordered list
var columnsToMove = this.getGridColumns(columnsToMoveKeys);
var failedRules = !this.doesMovePassRules(columnsToMove, toIndex);
if (failedRules) {
return;
}
utils_1.Utils.moveInArray(this.gridColumns, columnsToMove, toIndex);
this.updateDisplayedColumns(source);
var event = {
type: events_1.Events.EVENT_COLUMN_MOVED,
columns: columnsToMove,
column: columnsToMove.length === 1 ? columnsToMove[0] : null,
toIndex: toIndex,
api: this.gridApi,
columnApi: this.columnApi,
source: source
};
this.eventService.dispatchEvent(event);
this.columnAnimationService.finish();
};
ColumnController.prototype.doesMovePassRules = function (columnsToMove, toIndex) {
// make a copy of what the grid columns would look like after the move
var proposedColumnOrder = this.gridColumns.slice();
utils_1.Utils.moveInArray(proposedColumnOrder, columnsToMove, toIndex);
// then check that the new proposed order of the columns passes all rules
if (!this.doesMovePassMarryChildren(proposedColumnOrder)) {
return false;
}
if (!this.doesMovePassLockedPositions(proposedColumnOrder)) {
return false;
}
return true;
};
ColumnController.prototype.doesMovePassLockedPositions = function (proposedColumnOrder) {
var foundNonLocked = false;
var rulePassed = true;
// go though the cols, see if any non-locked appear before any locked
proposedColumnOrder.forEach(function (col) {
if (col.isLockPosition()) {
if (foundNonLocked) {
rulePassed = false;
}
}
else {
foundNonLocked = true;
}
});
return rulePassed;
};
ColumnController.prototype.doesMovePassMarryChildren = function (allColumnsCopy) {
var rulePassed = true;
this.columnUtils.depthFirstOriginalTreeSearch(this.gridBalancedTree, function (child) {
if (!(child instanceof originalColumnGroup_1.OriginalColumnGroup)) {
return;
}
var columnGroup = child;
var marryChildren = columnGroup.getColGroupDef() && columnGroup.getColGroupDef().marryChildren;
if (!marryChildren) {
return;
}
var newIndexes = [];
columnGroup.getLeafColumns().forEach(function (col) {
var newColIndex = allColumnsCopy.indexOf(col);
newIndexes.push(newColIndex);
});
var maxIndex = Math.max.apply(Math, newIndexes);
var minIndex = Math.min.apply(Math, newIndexes);
// spread is how far the first column in this group is away from the last column
var spread = maxIndex - minIndex;
var maxSpread = columnGroup.getLeafColumns().length - 1;
// if the columns
if (spread > maxSpread) {
rulePassed = false;
}
// console.log(`maxIndex = ${maxIndex}, minIndex = ${minIndex}, spread = ${spread}, maxSpread = ${maxSpread}, fail = ${spread > (count-1)}`)
// console.log(allColumnsCopy.map( col => col.getColDef().field).join(','));
});
return rulePassed;
};
ColumnController.prototype.moveColumn = function (key, toIndex, source) {
if (source === void 0) { source = "api"; }
this.moveColumns([key], toIndex, source);
};
ColumnController.prototype.moveColumnByIndex = function (fromIndex, toIndex, source) {
if (source === void 0) { source = "api"; }
var column = this.gridColumns[fromIndex];
this.moveColumn(column, toIndex, source);
};
// used by:
// + angularGrid -> for setting body width
// + rowController -> setting main row widths (when inserting and resizing)
// need to cache this
ColumnController.prototype.getBodyContainerWidth = function () {
return this.bodyWidth;
};
ColumnController.prototype.getContainerWidth = function (pinned) {
switch (pinned) {
case column_1.Column.PINNED_LEFT: return this.leftWidth;
case column_1.Column.PINNED_RIGHT: return this.rightWidth;
default: return this.bodyWidth;
}
};
// after setColumnWidth or updateGroupsAndDisplayedColumns
ColumnController.prototype.updateBodyWidths = function () {
var newBodyWidth = this.getWidthOfColsInList(this.displayedCenterColumns);
var newLeftWidth = this.getWidthOfColsInList(this.displayedLeftColumns);
var newRightWidth = this.getWidthOfColsInList(this.displayedRightColumns);
// this is used by virtual col calculation, for RTL only, as a change to body width can impact displayed
// columns, due to RTL inverting the y coordinates
this.bodyWidthDirty = this.bodyWidth !== newBodyWidth;
var atLeastOneChanged = this.bodyWidth !== newBodyWidth || this.leftWidth !== newLeftWidth || this.rightWidth !== newRightWidth;
if (atLeastOneChanged) {
this.bodyWidth = newBodyWidth;
this.leftWidth = newLeftWidth;
this.rightWidth = newRightWidth;
// when this fires, it is picked up by the gridPanel, which ends up in
// gridPanel calling setWidthAndScrollPosition(), which in turn calls setVirtualViewportPosition()
var event_4 = {
type: events_1.Events.EVENT_DISPLAYED_COLUMNS_WIDTH_CHANGED,
api: this.gridApi,
columnApi: this.columnApi
};
this.eventService.dispatchEvent(event_4);
}
};
// + rowController
ColumnController.prototype.getValueColumns = function () {
return this.valueColumns ? this.valueColumns : [];
};
// + rowController
ColumnController.prototype.getPivotColumns = function () {
return this.pivotColumns ? this.pivotColumns : [];
};
// + inMemoryRowModel
ColumnController.prototype.isPivotActive = function () {
return this.pivotColumns && this.pivotColumns.length > 0 && this.pivotMode;
};
// + toolPanel
ColumnController.prototype.getRowGroupColumns = function () {
return this.rowGroupColumns ? this.rowGroupColumns : [];
};
// + rowController -> while inserting rows
ColumnController.prototype.getDisplayedCenterColumns = function () {
return this.displayedCenterColumns;
};
// + rowController -> while inserting rows
ColumnController.prototype.getDisplayedLeftColumns = function () {
return this.displayedLeftColumns;
};
ColumnController.prototype.getDisplayedRightColumns = function () {
return this.displayedRightColumns;
};
ColumnController.prototype.getDisplayedColumns = function (type) {
switch (type) {
case column_1.Column.PINNED_LEFT: return this.getDisplayedLeftColumns();
case column_1.Column.PINNED_RIGHT: return this.getDisplayedRightColumns();
default: return this.getDisplayedCenterColumns();
}
};
// used by:
// + inMemoryRowController -> sorting, building quick filter text
// + headerRenderer -> sorting (clearing icon)
ColumnController.prototype.getAllPrimaryColumns = function () {
return this.primaryColumns;
};
ColumnController.prototype.getAllColumnsForQuickFilter = function () {
return this.columnsForQuickFilter;
};
// + moveColumnController
ColumnController.prototype.getAllGridColumns = function () {
return this.gridColumns;
};
ColumnController.prototype.isEmpty = function () {
return utils_1.Utils.missingOrEmpty(this.gridColumns);
};
ColumnController.prototype.isRowGroupEmpty = function () {
return utils_1.Utils.missingOrEmpty(this.rowGroupColumns);
};
ColumnController.prototype.setColumnVisible = function (key, visible, source) {
if (source === void 0) { source = "api"; }
this.setColumnsVisible([key], visible, source);
};
ColumnController.prototype.setColumnsVisible = function (keys, visible, source) {
var _this = this;
if (source === void 0) { source = "api"; }
this.columnAnimationService.start();
this.actionOnGridColumns(keys, function (column) {
if (column.isVisible() !== visible) {
column.setVisible(visible, source);
return true;
}
else {
return false;
}
}, source, function () {
var event = {
type: events_1.Events.EVENT_COLUMN_VISIBLE,
visible: visible,
column: null,
columns: null,
api: _this.gridApi,
columnApi: _this.columnApi,
source: source
};
return event;
});
this.columnAnimationService.finish();
};
ColumnController.prototype.setColumnPinned = function (key, pinned, source) {
if (source === void 0) { source = "api"; }
this.setColumnsPinned([key], pinned, source);
};
ColumnController.prototype.setColumnsPinned = function (keys, pinned, source) {
var _this = this;
if (source === void 0) { source = "api"; }
this.columnAnimationService.start();
var actualPinned;
if (pinned === true || pinned === column_1.Column.PINNED_LEFT) {
actualPinned = column_1.Column.PINNED_LEFT;
}
else if (pinned === column_1.Column.PINNED_RIGHT) {
actualPinned = column_1.Column.PINNED_RIGHT;
}
else {
actualPinned = null;
}
this.actionOnGridColumns(keys, function (col) {
if (col.getPinned() !== actualPinned) {
col.setPinned(actualPinned);
return true;
}
else {
return false;
}
}, source, function () {
var event = {
type: events_1.Events.EVENT_COLUMN_PINNED,
pinned: actualPinned,
column: null,
columns: null,
api: _this.gridApi,
columnApi: _this.columnApi,
source: source
};
return event;
});
this.columnAnimationService.finish();
};
// does an action on a set of columns. provides common functionality for looking up the
// columns based on key, getting a list of effected columns, and then updated the event
// with either one column (if it was just one col) or a list of columns
// used by: autoResize, setVisible, setPinned
ColumnController.prototype.actionOnGridColumns = function (// the column keys this action will be on
keys,
// the action to do - if this returns false, the column was skipped
// and won't be included in the event
action,
// should return back a column event of the right type
source, createEvent) {
var _this = this;
if (utils_1.Utils.missingOrEmpty(keys)) {
return;
}
var updatedColumns = [];
keys.forEach(function (key) {
var column = _this.getGridColumn(key);
if (!column) {
return;
}
// need to check for false with type (ie !== instead of !=)
// as not returning anything (undefined) would also be false
var resultOfAction = action(column);
if (resultOfAction !== false) {
updatedColumns.push(column);
}
});
if (updatedColumns.length === 0) {
return;
}
this.updateDisplayedColumns(source);
if (utils_1.Utils.exists(createEvent)) {
var event_5 = createEvent();
event_5.columns = updatedColumns;
event_5.column = updatedColumns.length === 1 ? updatedColumns[0] : null;
this.eventService.dispatchEvent(event_5);
}
};
ColumnController.prototype.getDisplayedColBefore = function (col) {
var allDisplayedColumns = this.getAllDisplayedColumns();
var oldIndex = allDisplayedColumns.indexOf(col);
if (oldIndex > 0) {
return allDisplayedColumns[oldIndex - 1];
}
else {
return null;
}
};
// used by:
// + rowRenderer -> for navigation
ColumnController.prototype.getDisplayedColAfter = function (col) {
var allDisplayedColumns = this.getAllDisplayedColumns();
var oldIndex = allDisplayedColumns.indexOf(col);
if (oldIndex < (allDisplayedColumns.length - 1)) {
return allDisplayedColumns[oldIndex + 1];
}
else {
return null;
}
};
ColumnController.prototype.isPinningLeft = function () {
return this.displayedLeftColumns.length > 0;
};
ColumnController.prototype.isPinningRight = function () {
return this.displayedRightColumns.length > 0;
};
ColumnController.prototype.getPrimaryAndSecondaryAndAutoColumns = function () {
var result = this.primaryColumns ? this.primaryColumns.slice(0) : [];
if (utils_1.Utils.exists(this.groupAutoColumns)) {
this.groupAutoColumns.forEach(function (col) { return result.push(col); });
}
if (this.secondaryColumnsPresent) {
this.secondaryColumns.forEach(function (column) { return result.push(column); });
}
return result;
};
ColumnController.prototype.createStateItemFromColumn = function (column) {
var rowGroupIndex = column.isRowGroupActive() ? this.rowGroupColumns.indexOf(column) : null;
var pivotIndex = column.isPivotActive() ? this.pivotColumns.indexOf(column) : null;
var aggFunc = column.isValueActive() ? column.getAggFunc() : null;
var resultItem = {
colId: column.getColId(),
hide: !column.isVisible(),
aggFunc: aggFunc,
width: column.getActualWidth(),
pivotIndex: pivotIndex,
pinned: column.getPinned(),
rowGroupIndex: rowGroupIndex
};
return resultItem;
};
ColumnController.prototype.getColumnState = function () {
if (utils_1.Utils.missing(this.primaryColumns)) {
return [];
}
var columnStateList = this.primaryColumns.map(this.createStateItemFromColumn.bind(this));
if (!this.pivotMode) {
this.orderColumnStateList(columnStateList);
}
return columnStateList;
};
ColumnController.prototype.orderColumnStateList = function (columnStateList) {
var gridColumnIds = this.gridColumns.map(function (column) { return column.getColId(); });
columnStateList.sort(function (itemA, itemB) {
var posA = gridColumnIds.indexOf(itemA.colId);
var posB = gridColumnIds.indexOf(itemB.colId);
return posA - posB;
});
};
ColumnController.prototype.resetColumnState = function (source) {
if (source === void 0) { source = "api"; }
// we can't use 'allColumns' as the order might of messed up, so get the primary ordered list
var primaryColumns = this.getColumnsFromTree(this.primaryBalancedTree);
var state = [];
if (primaryColumns) {
primaryColumns.forEach(function (column) {
state.push({
colId: column.getColId(),
aggFunc: column.getColDef().aggFunc,
hide: column.getColDef().hide,
pinned: column.getColDef().pinned,
rowGroupIndex: column.getColDef().rowGroupIndex,
pivotIndex: column.getColDef().pivotIndex,
width: column.getColDef().width
});
});
}
this.setColumnState(state, source);
};
ColumnController.prototype.setColumnState = function (columnState, source) {
var _this = this;
if (source === void 0) { source = "api"; }
if (utils_1.Utils.missingOrEmpty(this.primaryColumns)) {
return false;
}
this.autoGroupsNeedBuilding = true;
// at the end below, this list will have all columns we got no state for
var columnsWithNoState = this.primaryColumns.slice();
this.rowGroupColumns = [];
this.valueColumns = [];
this.pivotColumns = [];
var success = true;
var rowGroupIndexes = {};
var pivotIndexes = {};
if (columnState) {
columnState.forEach(function (stateItem) {
var column = _this.getPrimaryColumn(stateItem.colId);
if (!column) {
console.warn('ag-grid: column ' + stateItem.colId + ' not found');
success = false;
}
else {
_this.syncColumnWithStateItem(column, stateItem, rowGroupIndexes, pivotIndexes, source);
utils_1.Utils.removeFromArray(columnsWithNoState, column);
}
});
}
// anything left over, we got no data for, so add in the column as non-value, non-rowGroup and hidden
columnsWithNoState.forEach(this.syncColumnWithNoState.bind(this));
// sort the lists according to the indexes that were provided
this.rowGroupColumns.sort(this.sortColumnListUsingIndexes.bind(this, rowGroupIndexes));
this.pivotColumns.sort(this.sortColumnListUsingIndexes.bind(this, pivotIndexes));
this.updateGridColumns();
if (columnState) {
var orderOfColIds_1 = columnState.map(function (stateItem) { return stateItem.colId; });
this.gridColumns.sort(function (colA, colB) {
var indexA = orderOfColIds_1.indexOf(colA.getId());
var indexB = orderOfColIds_1.indexOf(colB.getId());
return indexA - indexB;
});
}
this.updateDisplayedColumns(source);
var event = {
type: events_1.Events.EVENT_COLUMN_EVERYTHING_CHANGED,
api: this.gridApi,
columnApi: this.columnApi,
source: source
};
this.eventService.dispatchEvent(event);
return success;
};
ColumnController.prototype.sortColumnListUsingIndexes = function (indexes, colA, colB) {
var indexA = indexes[colA.getId()];
var indexB = indexes[colB.getId()];
return indexA - indexB;
};
ColumnController.prototype.syncColumnWithNoState = function (column, source) {
column.setVisible(false, source);
column.setAggFunc(null);
column.setPinned(null);
column.setRowGroupActive(false, source);
column.setPivotActive(false, source);
column.setValueActive(false, source);
};
ColumnController.prototype.syncColumnWithStateItem = function (column, stateItem, rowGroupIndexes, pivotIndexes, source) {
// following ensures we are left with boolean true or false, eg converts (null, undefined, 0) all to true
column.setVisible(!stateItem.hide, source);
// sets pinned to 'left' or 'right'
column.setPinned(stateItem.pinned);
// if width provided and valid, use it, otherwise stick with the old width
if (stateItem.width >= this.gridOptionsWrapper.getMinColWidth()) {
column.setActualWidth(stateItem.width, source);
}
if (typeof stateItem.aggFunc === 'string') {
column.setAggFunc(stateItem.aggFunc);
column.setValueActive(true, source);
this.valueColumns.push(column);
}
else {
if (utils_1.Utils.exists(stateItem.aggFunc)) {
console.warn('ag-Grid: stateItem.aggFunc must be a string. if using your own aggregation ' +
'functions, register the functions first before using them in get/set state. This is because it is' +
'intended for the column state to be stored and retrieved as simple JSON.');
}
column.setAggFunc(null);
column.setValueActive(false, source);
}
if (typeof stateItem.rowGroupIndex === 'number') {
this.rowGroupColumns.push(column);