UNPKG

@adaptabletools/adaptable

Version:

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

134 lines (133 loc) 6.74 kB
import { CalculatedColumnModuleId } from '../Constants/ModuleConstants'; import { AggregatedScalarLiveValue } from './AggregatedScalarLiveValue'; export class CalculatedColumnExpressionService { constructor(adaptableApi) { this.adaptableApi = adaptableApi; this.aggregatedScalarLiveValuesMap = new Map(); this.adaptableApi = adaptableApi; } listentoCellDataChange(cellDataChangedInfo) { const refreshedCalculatedColumns = []; this.aggregatedScalarLiveValuesMap.forEach((aggregatedScalarLiveValue, calculatedColumnId) => { const calculatedColumn = this.adaptableApi.calculatedColumnApi.getCalculatedColumnById(calculatedColumnId); const columnDependencies = this.adaptableApi.calculatedColumnApi.internalApi.getReferencedColumnIdsForCalculatedColumn(calculatedColumn); if (columnDependencies.includes(cellDataChangedInfo.column.columnId)) { aggregatedScalarLiveValue.refresh(); refreshedCalculatedColumns.push(calculatedColumn.ColumnId); } }); if (refreshedCalculatedColumns.length) { this.adaptableApi.gridApi.refreshColumns(refreshedCalculatedColumns); } } listentoRowDataChange(rowDataChangedInfo) { const refreshedCalculatedColumns = []; this.aggregatedScalarLiveValuesMap.forEach((aggregatedScalarLiveValue, calculatedColumnId) => { const calculatedColumn = this.adaptableApi.calculatedColumnApi.getCalculatedColumnById(calculatedColumnId); aggregatedScalarLiveValue.refresh(); refreshedCalculatedColumns.push(calculatedColumn.ColumnId); }); if (refreshedCalculatedColumns.length) { this.adaptableApi.gridApi.refreshColumns(refreshedCalculatedColumns); } } destroy() { this.aggregatedScalarLiveValuesMap.clear(); this.aggregatedScalarLiveValuesMap = null; } getCalculatedColumnDataType(calculatedColumnQuery) { try { if (calculatedColumnQuery.AggregatedScalarExpression) { // currently AggregatedScalarExpression support only numerical values // TODO AFL try to derive the type from the aggregatedColumn? // we definitely don't want to aggregate everything only to get the data type return 'number'; } let firstRowNode = this.adaptableApi.gridApi.getFirstRowNode(); let firstRowValue = this.adaptableApi.internalApi .getQueryLanguageService() .evaluateScalarExpression(calculatedColumnQuery.ScalarExpression, CalculatedColumnModuleId, firstRowNode); if (firstRowValue instanceof Date) { return 'date'; } if (typeof firstRowValue === 'boolean') { return 'boolean'; } if (typeof firstRowValue === 'string') { return 'text'; } if (typeof firstRowValue === 'number') { return 'number'; } if (Array.isArray(firstRowValue)) { return 'numberArray'; } } catch (e) { this.adaptableApi.logError(`Invalid CalculatedColumn expression ${this.adaptableApi.expressionApi.getAdaptableQueryExpression(calculatedColumnQuery)} :: ${e}`); return 'number'; } } isCalculatedColumnQueryValid(calculatedColumnQuery) { if (calculatedColumnQuery.ScalarExpression) { try { // TODO AFL add a cached validation for ScalarExpression, just like for all the other types let firstRowNode = this.adaptableApi.gridApi.getFirstRowNode(); this.adaptableApi.internalApi .getQueryLanguageService() .evaluateScalarExpression(calculatedColumnQuery.ScalarExpression, CalculatedColumnModuleId, firstRowNode); return true; } catch (e) { // no logging as this method is used only in the UI return false; } } if (calculatedColumnQuery.AggregatedScalarExpression) { const validationResult = this.adaptableApi.expressionApi.isValidAggregatedScalarExpression(calculatedColumnQuery.AggregatedScalarExpression, CalculatedColumnModuleId); return validationResult; } // if query has neither a ScalarExpression nor an AggregatedScalarExpression => it can only be false return false; } evaluateCalculatedColumnQuery(calculatedColumn, rowNode) { try { if (this.adaptableApi.gridApi.isGroupRowNode(rowNode)) { return undefined; } // no validation here, this function has to be as performant as possible if (calculatedColumn?.Query?.ScalarExpression) { return this.adaptableApi.internalApi .getQueryLanguageService() .evaluateScalarExpression(calculatedColumn.Query.ScalarExpression, CalculatedColumnModuleId, rowNode); } if (calculatedColumn?.Query?.AggregatedScalarExpression) { const aggregatedScalarLiveValue = this.aggregatedScalarLiveValuesMap.get(calculatedColumn.Uuid); return aggregatedScalarLiveValue?.getAggregatedValueForRow(rowNode); } } catch (error) { this.adaptableApi.logError(`Invalid CalculatedColumn expression ${calculatedColumn?.Query?.ScalarExpression ?? calculatedColumn?.Query?.AggregatedScalarExpression} :: ${error}`); return null; } } createAggregatedScalarLiveValue(calculatedColumn) { // if there is already an aggregated scalar, delete it (possible when editing) this.destroyAggregatedScalarLiveValue(calculatedColumn); if (calculatedColumn.Query?.AggregatedScalarExpression) { try { const aggregatedScalarLiveValue = new AggregatedScalarLiveValue({ aggregatedScalarExpression: calculatedColumn.Query?.AggregatedScalarExpression, }, CalculatedColumnModuleId, this.adaptableApi); this.aggregatedScalarLiveValuesMap.set(calculatedColumn.Uuid, aggregatedScalarLiveValue); } catch (e) { this.adaptableApi.logError(`Creating CalculatedColumn ('${calculatedColumn.Query?.AggregatedScalarExpression}') failed!`, e.message); } } } destroyAggregatedScalarLiveValue(calculatedColumn) { this.aggregatedScalarLiveValuesMap.delete(calculatedColumn.Uuid); } }