UNPKG

@adaptabletools/adaptable

Version:

Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements

521 lines (520 loc) 19.2 kB
import { ApiBase } from './ApiBase'; import * as GeneralConstants from '../../Utilities/Constants/GeneralConstants'; import { AG_GRID_SELECTION_COLUMN } from '../../Utilities/Constants/GeneralConstants'; import * as ModuleConstants from '../../Utilities/Constants/ModuleConstants'; import { ColumnInternalApi } from '../Internal/ColumnInternalApi'; import { AUTO_GROUP_COLUMN_ID__MULTI_PREFIX, AUTO_GROUP_COLUMN_ID__SINGLE, } from '../../layout-manager/src/normalizeLayoutModel'; import ArrayExtensions from '../../Utilities/Extensions/ArrayExtensions'; import { isPivotColumnTotal } from '../../layout-manager/src/isPivotColumnTotal'; import { isPivotLayout } from './LayoutHelpers'; const ROW_GROUP_COLUMN_DEFAULTS = { columnId: '', isTreeColumn: false, friendlyName: 'Group', isPrimaryKey: false, readOnly: false, resizable: true, visible: true, alwaysHidden: false, fieldOnly: false, queryable: false, sortable: false, filterable: false, groupable: false, pivotable: false, aggregatable: false, moveable: true, hideable: false, exportable: true, isGrouped: true, isGeneratedRowGroupColumn: true, isGeneratedPivotResultColumn: false, isGeneratedSelectionColumn: false, isFixed: false, pinned: null, isSparkline: false, dataType: 'text', isCalculatedColumn: false, isFreeTextColumn: false, isActionColumn: false, isPivotTotalColumn: false, }; export function generateAutoRowGroupSingleColumn() { return { ...ROW_GROUP_COLUMN_DEFAULTS, columnId: AUTO_GROUP_COLUMN_ID__SINGLE, }; } const TREE_COLUMN_FRIENDLY_NAME = '[Tree Column]'; export function generateAutoTreeSingleColumn() { return { ...ROW_GROUP_COLUMN_DEFAULTS, columnId: AUTO_GROUP_COLUMN_ID__SINGLE, isTreeColumn: true, friendlyName: TREE_COLUMN_FRIENDLY_NAME, }; } export function generateAutoRowGroupColumnForColumn(column) { return { ...ROW_GROUP_COLUMN_DEFAULTS, columnId: AUTO_GROUP_COLUMN_ID__MULTI_PREFIX + column.columnId, friendlyName: column.friendlyName, dataType: column.dataType, }; } export function getFriendlyNameForPivotResultColumn(columnId, agGridApi) { if (isPivotGrandTotal(columnId)) { return `[Grand Total] ${columnId .split('_') .slice(2) .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) .join(' ')}`; } if (isPivotColumnTotal(columnId)) { return `[Group Total] ${columnId .split('_') .slice(2) .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) .join(' ')}`; } // is quite consuming on performance // we don't need it anyway because currently (20.0.7) we don't display Pivot Totals at all // if (isPivotAggregationTotalColumn(columnId, agGridApi)) { // return `[Aggregation Total] ${columnId // .split('_') // .slice(2) // .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) // .join(' ')}`; // } return `[Pivot] ${columnId .split('_') .slice(1) .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) .join(' ')}`; } export function isPivotResultColumn(columnId) { // put this here as there might be other indicators we are not aware of? return columnId?.startsWith(GeneralConstants.AG_GRID_PIVOT_COLUMN); } export function isPivotGrandTotal(columnId) { return columnId?.startsWith(GeneralConstants.AG_GRID_PIVOT_GRAND_TOTAL_COLUMN); } export class ColumnApiImpl extends ApiBase { constructor(_adaptable) { super(_adaptable); this.internalApi = new ColumnInternalApi(_adaptable); } getColumns() { return this.getGridApi().getInternalState().Columns ?? []; } getSpecialColumns() { const cols = this.getColumns()?.filter((c) => this.internalApi.isSpecialColumn(c.columnId, c)); return cols ?? []; } getNonSpecialColumns() { const cols = this.getColumns()?.filter((c) => !this.internalApi.isSpecialColumn(c.columnId, c)); return cols ?? []; } getUIAvailableColumns() { return this.getColumns().filter((c) => !c.alwaysHidden && // currently (20.0.7) we don't display Pivot Totals in UI !c.isPivotTotalColumn); } getVisibleColumns() { const layout = this.getLayoutApi().getCurrentLayout(); const allcols = this.getColumns(); if (isPivotLayout(layout)) { return allcols; } const visibleCols = layout.TableColumns.reduce((acc, colId) => { if (layout.ColumnVisibility?.[colId] !== false) { acc.add(colId); } return acc; }, new Set()); return allcols.filter((c) => visibleCols.has(c.columnId)); } selectColumn(columnId) { this._adaptable.selectColumn(columnId); } selectColumns(columnIds) { this._adaptable.selectColumns(columnIds); } addColumnToSelection(columnId) { this._adaptable.selectColumn(columnId, { keepExistingSelection: true }); } addColumnsToSelection(columnIds) { this._adaptable.selectColumns(columnIds, { keepExistingSelection: true }); } selectAllColumns() { this._adaptable.selectAll(); } autosizeColumn(columnId) { this._adaptable.autoSizeColumn(columnId); } autosizeColumns(columnIds) { this._adaptable.autoSizeColumns(columnIds); } autosizeAllColumns() { this._adaptable.autoSizeAllColumns(); } hideColumn(columnId) { this._adaptable.hideColumn(columnId); } showColumn(columnId) { this._adaptable.showColumn(columnId); } isPivotResultColumn(columnId) { return isPivotResultColumn(columnId) || isPivotGrandTotal(columnId); } isSelectionColumn(columnId) { return columnId === AG_GRID_SELECTION_COLUMN; } isAutoRowGroupColumn(columnId) { return (this.isAutoRowGroupColumnForSingle(columnId) || this.isAutoRowGroupColumnForMulti(columnId)); } isAutoRowGroupColumnForSingle(columnId) { return columnId === AUTO_GROUP_COLUMN_ID__SINGLE; } isAutoRowGroupColumnForMulti(columnId) { return columnId.startsWith(AUTO_GROUP_COLUMN_ID__MULTI_PREFIX); } isCalculatedColumn(columnId) { return (this.getCalculatedColumnApi() .getCalculatedColumns() .find((cc) => cc.ColumnId == columnId) != null); } isFreeTextColumn(columnId) { return (this.getFreeTextColumnApi() .getFreeTextColumns() .find((cc) => cc.ColumnId == columnId) != null); } isActionColumn(columnId) { return (this.getActionColumnApi() .getActionColumns() ?.find((cc) => cc.columnId == columnId) != null); } isFdc3Column(columnId) { return this.getFdc3Api().internalApi.getFdc3ColumnIds().includes(columnId); } getColumnWithColumnId(columnId, logWarning) { if (columnId == undefined) { return; } // just return null if no columns rather than logging a warning - otherwise get lots at startup if (ArrayExtensions.IsNullOrEmpty(this.getColumns())) { return; } const foundColumn = this.getColumns().find((c) => c.columnId == columnId); if (foundColumn) { return foundColumn; } if (logWarning) { this.logMissingColumnWarning(columnId); } return undefined; } hasNumberDataType(columnId) { const column = this.getColumnWithColumnId(columnId); if (!column) { return false; } return column?.dataType == 'number'; } hasBooleanDataType(columnId) { const column = this.getColumnWithColumnId(columnId); if (!column) { return false; } return column?.dataType == 'boolean'; } hasArrayDataType(columnId) { return this.hasTextArrayDataType(columnId) || this.hasNumericArrayDataType(columnId); } hasTextArrayDataType(columnId) { const column = this.getColumnWithColumnId(columnId); if (!column) { return false; } return column?.dataType === 'textArray'; } hasNumericArrayDataType(columnId) { const column = this.getColumnWithColumnId(columnId); if (!column) { return false; } return (column?.dataType === 'numberArray' || column?.dataType === 'tupleArray' || column?.dataType === 'objectArray'); } hasDateDataType(columnId) { const column = this.getColumnWithColumnId(columnId); if (!column) { return false; } return column?.dataType === 'date' || column?.dataType === 'dateString'; } getColumnDataTypeForColumnId(columnId) { const column = this.getColumnWithColumnId(columnId); if (!column) { return undefined; } return column.dataType; } getFriendlyNameForColumnId(columnId, layout) { if (this.isPivotResultColumn(columnId)) { return getFriendlyNameForPivotResultColumn(columnId, this.getAgGridApi()); } const foundColumn = this.getColumns().find((c) => c.columnId === columnId); const isRowGroupColumn = this.isAutoRowGroupColumn(columnId); if (foundColumn && foundColumn.friendlyName && !foundColumn.friendlyName.includes(GeneralConstants.MISSING_COLUMN) && !isRowGroupColumn) { return foundColumn.friendlyName; } if (foundColumn?.isTreeColumn && isRowGroupColumn) { return foundColumn.friendlyName; } let result = columnId + GeneralConstants.MISSING_COLUMN; if (this.isAutoRowGroupColumn(columnId)) { if (this.getGridApi().isTreeDataGrid()) { return TREE_COLUMN_FRIENDLY_NAME; } const currentLayout = layout ?? this.getLayoutApi().getCurrentLayout(); const groupColumns = currentLayout?.RowGroupedColumns ?? currentLayout?.PivotGroupedColumns ?? []; if (groupColumns.length) { const groupedByLabel = this.isAutoRowGroupColumnForSingle(columnId) ? groupColumns.map((colId) => this.getFriendlyNameForColumnId(colId, layout)).join(', ') : this.getFriendlyNameForColumnId(columnId.replace(AUTO_GROUP_COLUMN_ID__MULTI_PREFIX, ''), layout); result = `[Grouped Column: ${groupedByLabel}]`; return result; } } this.logMissingColumnWarning(columnId); return result; } doesColumnExist(columnId) { const foundColumn = this.getColumns().find((c) => c.columnId === columnId); return foundColumn ? true : false; } getFriendlyNamesForColumnIds(columnIds) { const friendlyNames = []; if (ArrayExtensions.IsNullOrEmpty(columnIds)) { return friendlyNames; } columnIds.forEach((c) => { friendlyNames.push(this.getFriendlyNameForColumnId(c)); }); return friendlyNames; } getColumnIdForFriendlyName(friendlyName) { if (friendlyName.includes(GeneralConstants.MISSING_COLUMN)) { return friendlyName.replace(GeneralConstants.MISSING_COLUMN, ''); // Ids should stay "pure" } const foundColumn = this.getColumns().find((c) => c.friendlyName === friendlyName); if (foundColumn) { return foundColumn.columnId; } this.logMissingColumnWarning(friendlyName); return friendlyName + GeneralConstants.MISSING_COLUMN; } getColumnIdsForFriendlyNames(friendlyNames) { const columnIds = []; if (ArrayExtensions.IsNullOrEmpty(friendlyNames)) { return columnIds; } friendlyNames.forEach((c) => { columnIds.push(this.getColumnIdForFriendlyName(c)); }); return columnIds; } getColumnsWithFriendlyNames(friendlyNames) { return friendlyNames .map((friendlyName) => this.getColumns().find((x) => x.friendlyName === friendlyName)) .filter(Boolean); } getColumnsWithColumnIds(columnIds, logWarning = true) { let returnCols = []; columnIds.forEach((c) => { const column = this.getColumnWithColumnId(c, logWarning); if (column) { returnCols.push(column); } }); return returnCols; } isColumnInGrid(columnId) { return !!this.getColumnWithColumnId(columnId, false); } getColumnWithFriendlyName(columnFriendlyName, logWarning = true) { // just return null if no columns rather than logging a warning - otherwise get lots at startup if (ArrayExtensions.IsNullOrEmpty(this.getColumns())) { return null; } const foundColumn = this.getColumns().find((c) => c.friendlyName === columnFriendlyName); if (foundColumn) { return foundColumn; } if (logWarning) { this.logMissingColumnWarning(columnFriendlyName); } return null; } getColumnsWithDataType(dataType) { switch (dataType) { case 'boolean': return this.getBooleanColumns(); case 'date': return this.getDateColumns(); case 'number': return this.getNumericColumns(); case 'text': return this.getTextColumns(); case 'textArray': return this.getTextArrayColumns(); case 'numberArray': return this.getNumberArrayColumns(); case 'objectArray': return this.getObjectNumberArrayColumns(); case 'tupleArray': return this.getTupleNumberArrayColumns(); default: return this.getColumns(); } } getNumericColumns() { return this.getColumns().filter((c) => c.dataType === 'number'); } getNumericArrayColumns() { return this.getNumberArrayColumns() .concat(this.getTupleNumberArrayColumns()) .concat(this.getObjectNumberArrayColumns()); } getNumberArrayColumns() { return this.getColumns().filter((c) => c.dataType === 'numberArray'); } getTupleNumberArrayColumns() { return this.getColumns().filter((c) => c.dataType === 'tupleArray'); } getObjectNumberArrayColumns() { return this.getColumns().filter((c) => c.dataType === 'objectArray'); } getTextColumns() { return this.getColumns().filter((c) => c.dataType === 'text'); } getTextArrayColumns() { return this.getColumns().filter((c) => c.dataType === 'textArray'); } getDateColumns() { return this.getColumns().filter((c) => c.dataType === 'date' || c.dataType === 'dateString'); } getBooleanColumns() { return this.getColumns().filter((c) => c.dataType === 'boolean'); } getArrayColumns() { return this.getColumns().filter((c) => c.dataType === 'numberArray' || c.dataType === 'tupleArray' || c.dataType === 'objectArray' || c.dataType === 'textArray'); } getSortableColumns() { return this.getUIAvailableColumns().filter((c) => c.sortable); } getFilterableColumns() { return this.getUIAvailableColumns().filter((c) => c.filterable); } getGroupableColumns() { return this.getUIAvailableColumns().filter((c) => c.groupable); } getPivotableColumns() { return this.getUIAvailableColumns().filter((c) => c.pivotable); } getAggregatableColumns() { return this.getUIAvailableColumns().filter((c) => c.aggregatable && c.dataType === 'number'); } getQueryableColumns() { return this.getColumns().filter((c) => c.queryable); } getExportableColumns() { return this.getColumns().filter((c) => c.exportable); } getAlwaysHiddenColumns() { return this.getColumns().filter((c) => c.alwaysHidden); } logMissingColumnWarning(columnId) { if (this.getColumnOptions().showMissingColumnsWarning === true) { if (!this.isAutoRowGroupColumn(columnId) && !this.isCalculatedColumn(columnId) && !this.isFreeTextColumn(columnId) && !this.isActionColumn(columnId)) { this.logWarn(`No column found named '${columnId}'`); } } } getPrimaryKeyColumn() { return this.getColumnWithColumnId(this.getOptions().primaryKey); } getDefaultAggFunc(columnId) { const abColumn = this.getColumnWithColumnId(columnId); const availableAggregationFunctions = abColumn.availableAggregationFunctions; const agColumn = this.internalApi.getAgGridColumnForAdaptableColumn(columnId)?.getColDef?.(); return agColumn?.defaultAggFunc ?? availableAggregationFunctions[0]; } openColumnInfoSettingsPanel() { this.showModulePopup(ModuleConstants.ColumnInfoModuleId); } getColumnTypes() { const columnTypes = this.getOptions().columnOptions.columnTypes; if (typeof columnTypes === 'function') { const types = this.internalApi.getAllAgGridColumnTypes(); const columnTypesContext = { types, ...this.getAdaptableInternalApi().buildBaseContext(), }; return columnTypes(columnTypesContext); } else { return columnTypes; } } getColumnsByColumnType(columnType) { const abColumns = this.getColumns(); return abColumns.filter((c) => { return (c.columnTypes ?? []).includes(columnType); }); } getRowGroupedColumns() { return this.getLayoutApi() .getCurrentRowGroupsColumnIds() ?.map((n) => { return this.getColumnWithColumnId(n); }); } setColumnCaption(columnId, caption) { return this.getLayoutApi().setColumnCaption(columnId, caption); } getAGGridColDefForColumnId(columnId) { return this.getAgGridApi().getColumnDef(columnId); } getAGGridColumnForColumnId(columnId) { return this.getAgGridApi().getColumn(columnId); } hasColumnType(columnIdentifier, columnType) { if (!columnIdentifier) { return false; } const colDef = typeof columnIdentifier === 'string' ? this.getAgGridApi().getColumnDef(columnIdentifier) : columnIdentifier; if (!colDef?.type) { return false; } if (Array.isArray(colDef.type)) { return colDef.type.includes(columnType); } else { return colDef.type === columnType; } } }