UNPKG

ag-grid

Version:

Advanced Data Grid / Data Table supporting Javascript / React / AngularJS / Web Components

1,098 lines (1,097 loc) 94.3 kB
/** * 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);