UNPKG

ag-grid

Version:

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

1,081 lines 106 kB
/** * ag-grid - Advanced Data Grid / Data Table supporting Javascript / React / AngularJS / Web Components * @version v18.1.2 * @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 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(); this.suppressColumnVirtualisation = this.gridOptionsWrapper.isSuppressColumnVirtualisation(); if (this.isPivotSettingAllowed(pivotMode)) { this.pivotMode = pivotMode; } this.usingTreeData = this.gridOptionsWrapper.isTreeData(); }; ColumnController.prototype.isAutoRowHeightActive = function () { return this.autoRowHeightColumns && this.autoRowHeightColumns.length > 0; }; ColumnController.prototype.getAllAutoRowHeightCols = function () { return this.autoRowHeightColumns; }; 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, emptySpaceBeforeColumn) { var result = []; var lastConsideredCol = null; var _loop_1 = function (i) { var col = displayedColumns[i]; var colSpan = col.getColSpan(rowNode); var columnsToCheckFilter = [col]; if (colSpan > 1) { var colsToRemove = colSpan - 1; for (var j = 1; j <= colsToRemove; j++) { columnsToCheckFilter.push(displayedColumns[i + j]); } i += colsToRemove; } // see which cols we should take out for column virtualisation var filterPasses; if (filterCallback) { // if user provided a callback, means some columns may not be in the viewport. // the user will NOT provide a callback if we are talking about pinned areas, // as pinned areas have no horizontal scroll and do not virtualise the columns. // if lots of columns, that means column spanning, and we set filterPasses = true // if one or more of the columns spanned pass the filter. filterPasses = false; columnsToCheckFilter.forEach(function (colForFilter) { if (filterCallback(colForFilter)) filterPasses = true; }); } else { filterPasses = true; } if (filterPasses) { if (result.length === 0 && lastConsideredCol) { var gapBeforeColumn = emptySpaceBeforeColumn ? emptySpaceBeforeColumn(col) : false; if (gapBeforeColumn) { result.push(lastConsideredCol); } } result.push(col); } lastConsideredCol = col; out_i_1 = i; }; var out_i_1; for (var i = 0; i < displayedColumns.length; i++) { _loop_1(i); i = out_i_1; } 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 emptySpaceBeforeColumn = function (col) { return col.getLeft() > _this.viewportLeft; }; // if doing column virtualisation, then we filter based on the viewport. var filterCallback = this.suppressColumnVirtualisation ? null : this.isColumnInViewport.bind(this); return this.getDisplayedColumnsForRow(rowNode, this.displayedCenterColumns, filterCallback, emptySpaceBeforeColumn); }; 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 // note: this should be cached ColumnController.prototype.getPinnedLeftContainerWidth = function () { return this.getWidthOfColsInList(this.displayedLeftColumns); }; // note: this should 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 && !this.gridOptionsWrapper.isSuppressMakeColumnVisibleAfterUnGroup()) { 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, // @key - the column who's size we want to change newWidth, // @newWidth - width in pixels shiftKey, // @takeFromAdjacent - if user has 'shift' pressed, then pixels are taken from adjacent column finished, // @finished - ends up in the event, tells the user if more events are to come source) { if (source === void 0) { source = "api"; } var col = this.getPrimaryOrGridColumn(key); if (!col) { return; } var sets = []; sets.push({ width: newWidth, ratios: [1], columns: [col] }); // if user wants to do shift resize by default, then we invert the shift operation var defaultIsShift = this.gridOptionsWrapper.getColResizeDefault() === 'shift'; if (defaultIsShift) { shiftKey = !shiftKey; } if (shiftKey) { var otherCol = this.getDisplayedColAfter(col); if (!otherCol) { return; } var widthDiff = col.getActualWidth() - newWidth; var otherColWidth = otherCol.getActualWidth() + widthDiff; sets.push({ width: otherColWidth, ratios: [1], columns: [otherCol] }); } this.resizeColumnSets(sets, finished, source); }; ColumnController.prototype.checkMinAndMaxWidthsForSet = function (columnResizeSet) { var columns = columnResizeSet.columns, width = columnResizeSet.width; // every col has a min width, so sum them all up and see if we have enough room // for all the min widths var minWidthAccumulated = 0; var maxWidthAccumulated = 0; var maxWidthActive = true; columns.forEach(function (col) { minWidthAccumulated += col.getMinWidth(); if (col.getMaxWidth() > 0) { maxWidthAccumulated += col.getMaxWidth(); } else { // if at least one columns has no max width, it means the group of columns // then has no max width, as at least one column can take as much width as possible maxWidthActive = false; } }); var minWidthPasses = width >= minWidthAccumulated; var maxWidthPasses = !maxWidthActive || (width <= maxWidthAccumulated); return minWidthPasses && maxWidthPasses; }; // method takes sets of columns and resizes them. either all sets will be resized, or nothing // be resized. this is used for example when user tries to resize a group and holds shift key, // then both the current group (grows), and the adjacent group (shrinks), will get resized, // so that's two sets for this method. ColumnController.prototype.resizeColumnSets = function (resizeSets, finished, source) { var passMinMaxCheck = utils_1.Utils.every(resizeSets, this.checkMinAndMaxWidthsForSet.bind(this)); if (!passMinMaxCheck) { return; } var changedCols = []; var allCols = []; resizeSets.forEach(function (set) { var width = set.width, columns = set.columns, ratios = set.ratios; // keep track of pixels used, and last column gets the remaining, // to cater for rounding errors, and min width adjustments var newWidths = {}; var finishedCols = {}; columns.forEach(function (col) { return allCols.push(col); }); // the loop below goes through each col. if a col exceeds it's min/max width, // it then gets set to its min/max width and the column is removed marked as 'finished' // and the calculation is done again leaving this column out. take for example columns // {A, width: 50, maxWidth: 100} // {B, width: 50} // {C, width: 50} // and then the set is set to width 600 - on the first pass the grid tries to set each column // to 200. it checks A and sees 200 > 100 and so sets the width to 100. col A is then marked // as 'finished' and the calculation is done again with the remaining cols B and C, which end up // splitting the remaining 500 pixels. var finishedColsGrew = true; var loopCount = 0; var _loop_2 = function () { loopCount++; if (loopCount > 1000) { // this should never happen, but in the future, someone might introduce a bug here, // so we stop the browser from hanging and report bug properly console.error('ag-Grid: infinite loop in resizeColumnSets'); return "break"; } finishedColsGrew = false; var subsetCols = []; var subsetRatios = []; var subsetRatioTotal = 0; var pixelsToDistribute = width; columns.forEach(function (col, index) { var thisColFinished = finishedCols[col.getId()]; if (thisColFinished) { pixelsToDistribute -= newWidths[col.getId()]; } else { subsetCols.push(col); var ratioThisCol = ratios[index]; subsetRatioTotal += ratioThisCol; subsetRatios.push(ratioThisCol); } }); // because we are not using all of the ratios (cols can be missing), // we scale the ratio. if all columns are included, then subsetRatioTotal=1, // and so the ratioScale will be 1. var ratioScale = 1 / subsetRatioTotal; subsetCols.forEach(function (col, index) { var lastCol = index === (subsetCols.length - 1); var colNewWidth; if (lastCol) { colNewWidth = pixelsToDistribute; } else { colNewWidth = Math.round(ratios[index] * width * ratioScale); pixelsToDistribute -= colNewWidth; } if (colNewWidth < col.getMinWidth()) { colNewWidth = col.getMinWidth(); finishedCols[col.getId()] = true; finishedColsGrew = true; } else if (col.getMaxWidth() > 0 && colNewWidth > col.getMaxWidth()) { colNewWidth = col.getMaxWidth(); finishedCols[col.getId()] = true; finishedColsGrew = true; } newWidths[col.getId()] = colNewWidth; }); }; while (finishedColsGrew) { var state_1 = _loop_2(); if (state_1 === "break") break; } columns.forEach(function (col) { var newWidth = newWidths[col.getId()]; if (col.getActualWidth() !== newWidth) { col.setActualWidth(newWidth); changedCols.push(col); } }); }); // if no cols changed, then no need to update more or send event. var atLeastOneColChanged = changedCols.length > 0; if (atLeastOneColChanged) { 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 (atLeastOneColChanged || finished) { var event_3 = { type: events_1.Events.EVENT_COLUMN_RESIZED, columns: allCols, column: allCols.length === 1 ? allCols[0] : null, 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 : []; }; // + clientSideRowModel 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: // + clientSideRowController -> 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