@adaptabletools/adaptable
Version:
Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
276 lines (275 loc) • 12 kB
JavaScript
import { SortOrder } from '../../AdaptableState/Common/Enums';
import * as InternalRedux from '../../Redux/ActionsReducers/InternalRedux';
import { getDateComparatorForGridCell, getGenericComparatorForGridCell, getNumericComparatorForGridCell, sortCellValueArrayNumeric, sortCellValueArrayDates, sortCellValueArray, } from '../../Utilities/Extensions/ArrayExtensions';
import { multisort } from '@infinite-table/infinite-react';
import { convertAdaptableStyleToCSS } from '../../Utilities/Helpers/StyleHelper';
import UIHelper from '../../View/UIHelper';
import { ApiBase } from '../Implementation/ApiBase';
export class GridInternalApi extends ApiBase {
/**
* Gets all distinct display values in the Column for given ColumnId
* @param columnId Column to check
*/
getDistinctDisplayValuesForColumnOld(columnId) {
const abColumn = this.getColumnApi().getColumnWithColumnId(columnId);
if (abColumn == undefined) {
return [];
}
const returnValues = this._adaptable.getDistinctGridCellsForColumn(abColumn);
return this.sortDistinctValues(returnValues, abColumn).map((cv) => {
return cv.normalisedValue;
});
}
/**
* Gets all distinct Filter values for the Column with the given ColumnId
* used for Floating Filter and Column Header filter
* either returns a list of values or al ist a list of values with count
*
* This is a general method, and it is used in:
* - Column Filters
* - Query Builder
* - Permitted Values
*
* @param columnId Column to check
*/
async getDistinctFilterDisplayValuesForColumn(options) {
const abColumn = this.getColumnApi().getColumnWithColumnId(options.columnId);
if (abColumn == undefined) {
return { values: [] };
}
const inFilterValues = await this._adaptable.getDistinctFilterValuesForColumn({
column: abColumn,
get currentSearchValue() {
return options.currentSearchValue;
},
previousResult: options.previousResult,
});
return inFilterValues || { values: [] };
}
async getDistinctValuesForColumn(columnId) {
const abColumn = this.getColumnApi().getColumnWithColumnId(columnId);
if (!abColumn) {
return undefined;
}
const gridCells = await this._adaptable.getDistinctValuesForColumn(abColumn);
return gridCells;
}
async getDistinctEditDisplayValuesForColumn(options) {
const abColumn = this.getColumnApi().getColumnWithColumnId(options.columnId);
if (!abColumn) {
return undefined;
}
const valueOptions = await this._adaptable.getDistinctEditValuesForColumn({
column: abColumn,
gridCell: options.gridCell,
get currentSearchValue() {
return options.currentSearchValue;
},
});
return valueOptions || [];
}
/**
* Gets all distinct raw values in Column. Values are sorted.
* @param columnId Column to check
*/
getDistinctRawValuesForColumn(columnId) {
const abColumn = this.getColumnApi().getColumnWithColumnId(columnId);
if (abColumn == undefined) {
return [];
}
return this.sortDistinctValues(this.getUnsortedDistinctRawValuesForColumn(columnId), abColumn).map((cv) => {
return cv.rawValue;
});
}
/**
* Gets all distinct raw values in Column. Values are un-sorted.
* @param columnId Column to check
*/
getUnsortedDistinctRawValuesForColumn(columnId) {
const abColumn = this.getColumnApi().getColumnWithColumnId(columnId);
if (abColumn == undefined) {
return [];
}
return this._adaptable.getDistinctGridCellsForColumn(abColumn);
}
getSortedRowNodesWithCurrentLayoutSortOrder(rowNodes) {
const currentLayout = this.getLayoutApi().getCurrentLayout();
const columnSorts = currentLayout.ColumnSorts || [];
const columnApi = this.getColumnApi();
const rowNodesMapToCells = new Map();
const allRowNodes = [];
// for each row node,let's create an object
// with only those gridcells that are needed - meaning
// for those column that are in the current sort
const rowNodeCallback = (node) => {
allRowNodes.push(node);
const rowNodeCells = {};
rowNodesMapToCells.set(node, rowNodeCells);
columnSorts.forEach((columnSort, i) => {
const { ColumnId } = columnSort;
const gridCell = this._adaptable.getGridCellFromRowNode(node, ColumnId);
rowNodeCells[ColumnId] = gridCell;
});
};
if (rowNodes) {
rowNodes.forEach(rowNodeCallback);
}
else {
this.getAgGridApi().forEachNode(rowNodeCallback);
}
if (!columnSorts.length) {
return allRowNodes;
}
const sortInfo = columnSorts.map((columnSort) => {
const { ColumnId } = columnSort;
// NOTE: the comparator we pass to multisort should always sort in ascending order
// that's why we pass SortOrder.Asc to the comparators
const comparator = columnApi.hasNumberDataType(ColumnId)
? getNumericComparatorForGridCell(SortOrder.Asc)
: columnApi.hasDateDataType(ColumnId)
? getDateComparatorForGridCell(SortOrder.Asc)
: getGenericComparatorForGridCell(SortOrder.Asc);
return {
// but here we pass the actual direction of the column sort
dir: columnSort.SortOrder === 'Asc' ? 1 : -1,
fn: (rowNodeA, rowNodeB) => {
const gridCellA = rowNodesMapToCells.get(rowNodeA)?.[ColumnId];
const gridCellB = rowNodesMapToCells.get(rowNodeB)?.[ColumnId];
if (!gridCellA || !gridCellB) {
return 0;
}
return comparator(gridCellA, gridCellB);
},
};
});
return multisort(sortInfo, allRowNodes);
}
sortDistinctValues(returnValues, column) {
// this does NOT into account Custom Sort - far too hard for now...
let sortOrder = undefined;
let columnSort = this.getGridApi().getColumnSortForColumn(column.columnId);
if (columnSort && columnSort.SortOrder) {
sortOrder =
columnSort.SortOrder === 'Asc'
? SortOrder.Asc
: columnSort.SortOrder === 'Desc'
? SortOrder.Desc
: undefined;
}
if (sortOrder) {
if (this.getColumnApi().hasNumberDataType(column?.columnId)) {
returnValues = sortCellValueArrayNumeric(returnValues, sortOrder);
}
else if (this.getColumnApi().hasDateDataType(column?.columnId)) {
returnValues = sortCellValueArrayDates(returnValues, sortOrder);
}
else {
returnValues = sortCellValueArray(returnValues, sortOrder);
}
}
return returnValues;
}
setColumns(columns) {
this.dispatchAction(InternalRedux.SetColumns(columns));
}
setSelectedCells(selectedCellInfo) {
this.dispatchAction(InternalRedux.SetSelectedCells(selectedCellInfo));
}
setSelectedRows(selectedRowInfo) {
this.dispatchAction(InternalRedux.SetSelectedRows(selectedRowInfo));
}
buildStandaloneColumnHeader(column) {
return this._adaptable.agGridMenuAdapter.buildStandaloneColumnHeader(column);
}
getRowHighlightStyle(params) {
const primaryKeyValue = this.getGridApi().getPrimaryKeyValueForRowNode(params.node);
const highlightRow = this.getAdaptableInternalApi()
.getInternalState()
.RowHighlightInfo?.find((highlightRow) => {
return highlightRow.primaryKeyValue === primaryKeyValue;
});
if (highlightRow) {
return convertAdaptableStyleToCSS(highlightRow.highlightStyle);
}
}
getAlertRowStyle(params) {
const alert = this.getAlertApi().internalApi.getAdaptableAlertWithHighlightRow(params.node);
const highlightRow = alert?.alertDefinition?.AlertProperties?.HighlightRow;
if (highlightRow) {
return typeof highlightRow === 'object'
? convertAdaptableStyleToCSS(highlightRow)
: {
backgroundColor: UIHelper.getColorByMessageType(alert.alertDefinition.MessageType),
};
}
return null;
}
getAlertRowClass(params) {
const alert = this.getAlertApi().internalApi.getAdaptableAlertWithHighlightRow(params.node);
const highlightRow = alert?.alertDefinition?.AlertProperties?.HighlightRow;
return typeof highlightRow === 'object' && highlightRow?.ClassName
? highlightRow?.ClassName
: null;
}
getRowHighlightClass(params) {
const primaryKeyValue = this.getGridApi().getPrimaryKeyValueForRowNode(params.node);
const highlightRow = this.getAdaptableInternalApi()
.getInternalState()
.RowHighlightInfo?.find((highlightRow) => {
return highlightRow.primaryKeyValue === primaryKeyValue;
});
return typeof highlightRow?.highlightStyle === 'object'
? highlightRow.highlightStyle.ClassName
: null;
}
deriveSpecialColumnSettingsFromAgGridDefaultColDef() {
const defaultColumnDefinition = this._adaptable.agGridAdapter.getDefaultColumnDefinition();
return {
Filterable: defaultColumnDefinition.filter,
Resizable: defaultColumnDefinition.resizable,
Groupable: defaultColumnDefinition.enableRowGroup,
Sortable: defaultColumnDefinition.sortable,
Pivotable: defaultColumnDefinition.enablePivot,
Aggregatable: defaultColumnDefinition.enableValue,
SuppressMenu: defaultColumnDefinition.suppressHeaderMenuButton,
SuppressMovable: defaultColumnDefinition.suppressMovable,
HeaderToolTip: defaultColumnDefinition.headerTooltip,
Width: defaultColumnDefinition.width,
};
}
hasCellEditableAccordingToEditOptions() {
return typeof this.getEditOptions()?.isCellEditable === 'function';
}
/**
* Returns UNDEFINED if no EditOptions.isCellEditable is provided, otherwise returns the result of the function
*
* DO NOT USE THIS METHOD DIRECTLY - use `GridApi.isCellEditable` instead
*/
isCellEditableAccordingToEditOptions(gridCell, defaultColDefinitionEditableValue) {
const cellEditable = this.getEditOptions()?.isCellEditable;
if (cellEditable) {
const cellEditableContext = {
...this.getAdaptableInternalApi().buildBaseContext(),
gridCell,
defaultColDefEditableValue: defaultColDefinitionEditableValue,
};
return cellEditable(cellEditableContext);
}
return undefined;
}
isRowFilterable(rowNode) {
// first assess if the Row is filterable - if not, then return true so it appears in Grid
const isRowFilterable = this.getOptionsApi().getFilterOptions().isRowFilterable;
if (typeof isRowFilterable === 'function') {
const rowFilterableContext = {
...this.getAdaptableApi().internalApi.buildBaseContext(),
rowNode,
data: rowNode.data,
};
if (!isRowFilterable(rowFilterableContext)) {
return false;
}
}
return true;
}
}