UNPKG

@adaptabletools/adaptable

Version:

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

271 lines (270 loc) 12.1 kB
import { ApiBase } from '../Implementation/ApiBase'; import StringExtensions from '../../Utilities/Extensions/StringExtensions'; import FormatHelper from '../../Utilities/Helpers/FormatHelper'; import ObjectFactory from '../../Utilities/ObjectFactory'; import * as ModuleConstants from '../../Utilities/Constants/ModuleConstants'; import { errorOnce } from '../../agGrid/AdaptableLogger'; export class FormatColumnInternalApi extends ApiBase { /** * Retrieves all Format Columns in Adaptable State with the `Style` property set * @returns format columns */ getAllFormatColumnWithStyle() { return this.getFormatColumnApi() .getFormatColumns() .filter((fc) => fc.Style); } /** * Retrieves all Format Columns in Adaptable State with the `Style` or the `CellAlignment` property set * @returns format columns */ getAllFormatColumnWithStyleAndCellAlignment() { return this.getFormatColumnApi() .getFormatColumns() .filter((fc) => fc.Style || fc.CellAlignment); } /** * Retrieves all Format Columns in Adaptable State with `DisplayFormat` property set * @returns format columns */ getAllFormatColumnWithDisplayFormat() { return this.getFormatColumnApi() .getFormatColumns() .filter((fc) => fc.DisplayFormat); } /** * Retrieves all Format Columns in Adaptable State with `CellAlignment` property set * @returns format columns */ getAllFormatColumnWithCellAlignment() { return this.getFormatColumnApi() .getFormatColumns() .filter((fc) => fc.CellAlignment); } /** * Get all FormatColumns which are defined for this column and have a custom AdaptableStyle * @param column * @param config * @returns list of FormatColumn */ getFormatColumnsWithStyleForColumn(column, config) { const formatColumns = this.getAllFormatColumnWithStyleAndCellAlignment().filter((formatColumn) => config?.includeSuspended || !formatColumn.IsSuspended); return this.getFormatColumnWithColumnInScope(formatColumns, column); } /** * Gets Format Column if any for given Column which includes Style element with ClassName * @param column The Column for which to retrieve the Format Column * @returns format columns */ getFormatColumnWithStyleClassNameForColumn(column, config) { return this.getFormatColumnsWithStyleForColumn(column, config).filter((formatColumn) => StringExtensions.IsNotNullOrEmpty(formatColumn?.Style?.ClassName)); } getFormatColumnWithColumnInScope(formatColumns, column) { return this.getFormatColumnInColumnScope(formatColumns).filter((scopedFormatColumn) => this.getColumnScopeApi().isColumnInScope(column, scopedFormatColumn.Scope)); } // TODO is this really needed, I don't think it achieves anything getFormatColumnInColumnScope(formatColumns) { // we need to maintain the format columns order, therefore we will extract all 3 scope types in a single iteration return formatColumns.filter((fc) => { return ( // this.getFormatColumnsWithColumnScope(formatColumns) (this.getColumnScopeApi().scopeHasColumns(fc.Scope) || // this.getFormatColumnsWithDataTypeScope(formatColumns) this.getColumnScopeApi().scopeHasDataType(fc.Scope) || // this.getFormatColumnsWithAllScope(formatColumns) this.getColumnScopeApi().scopeIsAll(fc.Scope) || this.getColumnScopeApi().scopeHasColumnType(fc.Scope)) ); }); } /** * Get all FormatColumns which are defined for this column and have a custom DisplayFormat * @param column * @param config * @returns list of FormatColumn */ getFormatColumnsWithDisplayFormatForColumn(column, config) { const formatColumns = this.getAllFormatColumnWithDisplayFormat().filter((formatColumn) => config?.includeSuspended || !formatColumn.IsSuspended); return this.getFormatColumnWithColumnInScope(formatColumns, column); } /** * Format value according to format options. * * @param customDisplayFormatterContext context that includes value to format * @param options formatter options */ getNumberFormattedValue(value, node, column, options) { const preparedValue = this.applyCustomFormatters(value, node, column, options); return FormatHelper.NumberFormatter(preparedValue, options, node, column, this.getAdaptableApi()); } /** * Format value according to format options. * * @param value context that includes value to format * @param options formatter options */ getStringFormattedValue(value, node, column, options) { const preparedValue = this.applyCustomFormatters(value, node, column, options); return FormatHelper.StringFormatter(preparedValue, options, node, column, this.getAdaptableApi()); } /** * Format value according to format options. * * @param customDisplayFormatterContext context that includes value to format * @param options formatter options */ getDateFormattedValue(value, node, abColumn, options) { const preparedValue = this.applyCustomFormatters(value, node, abColumn, options); const dateFormatterOptions = options; // only use DateFormatter if we have a pattern return dateFormatterOptions.Pattern ? FormatHelper.DateFormatter(preparedValue, options) : preparedValue; } applyCustomFormatters(value, node, abColumn, options) { const columnCustomFormatters = options?.CustomDisplayFormats ?? []; if (!columnCustomFormatters?.length) { return value; } const customFormattersFromOptions = this.getFormatColumnOptions()?.customDisplayFormatters ?? []; // formatters are applied in the order they are defined in the options const customFormatters = customFormattersFromOptions.filter((customFormatterOption) => columnCustomFormatters.includes(customFormatterOption.id)); const customDisplayFormatterContext = ObjectFactory.CreateCustomDisplayFormatterContext(value, node, abColumn, this.getAdaptableApi()); return customFormatters.reduce((context, formatter) => { if (formatter && formatter.handler) { return formatter.handler(context); } return context.cellValue; }, customDisplayFormatterContext); } /** * Returns all Predicates appropriate for the given Scope * @param scope Scope to check */ getFormatColumnDefsForScope(scope) { return this.getAdaptableApi() .predicateApi.internalApi.getFormatColumnPredicateDefs(scope) .filter((predicateDef) => this.getColumnScopeApi().isScopeInScope(scope, predicateDef.columnScope)); } /** * Checks if format column is relevant for a given cell (intersection of given AdaptableColumn and RowNode) * * @param formatColumn * @param column * @param params */ formatColumnShouldRender(formatColumn, column, rowNode, cellValue) { // suspended is important to be first if (formatColumn.IsSuspended) { return false; } const isSummaryNode = this.getGridApi().isSummaryNode(rowNode); const isGroupedRowNode = this.getGridApi().isGroupRowNode(rowNode); // For Summary Rows cannot be excluded if (isSummaryNode) { if (formatColumn.RowScope?.ExcludeSummaryRows) { return false; } } else if (isGroupedRowNode) { if (formatColumn.RowScope?.ExcludeGroupRows) { return false; } } else { if (formatColumn.RowScope?.ExcludeDataRows) { return false; } } if (!formatColumn.Rule) { return true; } // first run the predicate if (formatColumn.Rule.Predicates && formatColumn.Rule?.Predicates?.length) { const predicateDefHandlerContext = { value: cellValue, oldValue: null, displayValue: cellValue, node: rowNode, column: column, ...this.getAdaptableInternalApi().buildBaseContext(), }; return this.evaluatePredicate(formatColumn, predicateDefHandlerContext); } // then run the Expression else if (formatColumn.Rule.BooleanExpression) { return this.evaluateExpression(formatColumn, rowNode); } // nothing has passed then return false return false; } evaluatePredicate(formatColumn, predicateDefHandlerContext) { return this.getPredicateApi().handleColumnPredicates(formatColumn.Rule?.Predicates, predicateDefHandlerContext, false); } evaluateExpression(formatColumn, node) { const isValidExpression = this.getExpressionApi().isValidBooleanExpression(formatColumn.Rule.BooleanExpression, ModuleConstants.FormatColumnModuleId, `Invalid format column rule '${formatColumn.Rule.BooleanExpression}'`); try { return (isValidExpression && this.getAdaptableApi() .internalApi.getQueryLanguageService() .evaluateBooleanExpression(formatColumn.Rule.BooleanExpression, ModuleConstants.FormatColumnModuleId, node)); } catch (error) { errorOnce(error.message); return false; } } /** * Extract from the given FormatColumns only the ones which are relevant for a given cell (intersection of given AdaptableColumn and RowNode) * * @param formatColumns * @param column * @param params */ getFormatColumnsRelevantForColumn(formatColumns, column, params) { return formatColumns.filter((formatColumn) => this.formatColumnShouldRender(formatColumn, column, params.node, params.value)); } /** * Extract from the given FormatColumns the one which is the most relevant for a given cell (intersection of given AdaptableColumn and RowNode) * * @param formatColumns * @param column * @param params */ getMostRelevantFormatColumnForColumn(formatColumns, column, params) { return formatColumns.find((formatColumn) => this.formatColumnShouldRender(formatColumn, column, params.node, params.value)); } /** * Retrieves all Format Columns which have an Expression * @returns Format Columns with Expression */ getFormatColumnsWithExpression() { return this.getFormatColumnApi() .getFormatColumns() .filter((fc) => !!fc.Rule?.BooleanExpression); } getFormatColumnsDependentOnColumns(columnSet) { return this.getFormatColumnApi() .getFormatColumns() .filter((fc) => fc.Rule?.Predicates?.some((p) => columnSet.has(p.ColumnId))); } /** * Retrieves the columns that need rerendering based on format column predicates. */ getFormatColumnColumnsDependentOnColumnChange(column) { const impactedColumnIds = new Set(); impactedColumnIds.add(column.columnId); this.getCalculatedColumnApi() .internalApi.getCalculatedColumnsDependentOnColumn(column) .forEach((calculatedColumnId) => { impactedColumnIds.add(calculatedColumnId); }); const columnsThatNeedRefresh = new Set(); this.getFormatColumnsDependentOnColumns(impactedColumnIds).forEach((formatColumn) => { this.getAdaptableApi() .columnScopeApi.getColumnsInScope(formatColumn.Scope) .forEach((col) => { columnsThatNeedRefresh.add(col.columnId); }); }); return [...columnsThatNeedRefresh]; } }