@adaptabletools/adaptable
Version:
Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
468 lines (467 loc) • 17.1 kB
JavaScript
import { ApiBase } from './ApiBase';
import * as GeneralConstants from '../../Utilities/Constants/GeneralConstants';
import * as ModuleConstants from '../../Utilities/Constants/ModuleConstants';
import { ColumnInternalApi } from '../Internal/ColumnInternalApi';
import { GROUP_COLUMN_ID__MULTI_PREFIX, GROUP_COLUMN_ID__SINGLE, } from '../../layout-manager/src/normalizeLayoutModel';
import ArrayExtensions from '../../Utilities/Extensions/ArrayExtensions';
export function isAutoRowGroupColumn(columnId) {
// put this here as there might be other indicators we are not aware of
// perhaps with non auto groups ?
//https://www.ag-grid.com/javascript-grid-grouping/
return columnId?.startsWith(GeneralConstants.AG_GRID_GROUPED_COLUMN);
}
const ROW_GROUP_COLUMN_DEFAULTS = {
columnId: '',
isTreeColumn: false,
friendlyName: 'Group',
isPrimaryKey: false,
readOnly: false,
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,
isFixed: false,
pinned: null,
isSparkline: false,
dataType: 'text',
isCalculatedColumn: false,
isFreeTextColumn: false,
isActionColumn: false,
};
export function generateAutoRowGroupSingleColumn() {
return {
...ROW_GROUP_COLUMN_DEFAULTS,
columnId: GROUP_COLUMN_ID__SINGLE,
};
}
const TREE_COLUMN_FRIENDLY_NAME = '[Tree Column]';
export function generateAutoTreeSingleColumn() {
return {
...ROW_GROUP_COLUMN_DEFAULTS,
columnId: GROUP_COLUMN_ID__SINGLE,
isTreeColumn: true,
friendlyName: TREE_COLUMN_FRIENDLY_NAME,
};
}
export function generateAutoRowGroupColumnForColumn(column) {
return {
...ROW_GROUP_COLUMN_DEFAULTS,
columnId: GROUP_COLUMN_ID__MULTI_PREFIX + column.columnId,
friendlyName: column.friendlyName,
dataType: column.dataType,
};
}
export function getFriendlyNameForPivotResultColumn(columnId) {
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 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);
}
getVisibleColumns() {
const layout = this.getLayoutApi().getCurrentLayout();
const visibleCols = layout.TableColumns.reduce((acc, colId) => {
if (layout.ColumnVisibility?.[colId] !== false) {
acc.add(colId);
}
return acc;
}, new Set());
return this.getColumns().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);
}
isAutoRowGroupColumn(columnId) {
return isAutoRowGroupColumn(columnId);
}
isPivotResultColumn(columnId) {
return isPivotResultColumn(columnId);
}
isAutoRowGroupColumnForSingle(columnId) {
return columnId === GROUP_COLUMN_ID__SINGLE;
}
isAutoRowGroupColumnForMulti(columnId) {
return columnId.startsWith(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); // this.getColumns().find(c => c.ColumnId === columnId);
if (!column) {
return undefined;
}
return column.dataType;
}
getFriendlyNameForColumnId(columnId, layout) {
if (this.isPivotResultColumn(columnId)) {
return getFriendlyNameForPivotResultColumn(columnId);
}
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();
if (currentLayout?.RowGroupedColumns?.length) {
const groupedByLabel = this.isAutoRowGroupColumnForSingle(columnId)
? currentLayout.RowGroupedColumns.map((colId) => this.getFriendlyNameForColumnId(colId, layout)).join(', ')
: this.getFriendlyNameForColumnId(columnId.replace(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);
}
}