@adaptabletools/adaptable
Version:
Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
129 lines (128 loc) • 6.08 kB
JavaScript
import { ExpressionEvaluationError } from '../../parser/src/ExpressionEvaluationError';
import StringExtensions from '../Extensions/StringExtensions';
import { filter } from 'rxjs/operators';
import toNumber from 'lodash/toNumber';
import { evaluateNode } from '../../parser/src/evaluator';
// string functions may be case (in)sensitive, see internalApi.isTextComparisonCaseSensitive()
// if case is insensitive, we convert ALL involved strings to lower case
export const getStringValues = (context, ...stringArguments) => {
return isTextSearchCaseInsensitive(context)
? stringArguments.map((string) => string.toLowerCase())
: stringArguments;
};
export const getStringValue = (context, stringArgument) => {
return isTextSearchCaseInsensitive(context) ? stringArgument.toLowerCase() : stringArgument;
};
export const isTextSearchCaseInsensitive = (context) => !context.adaptableApi.expressionApi.useCaseSensitivity();
// returns an observable which filters the source$ emissions and emits only if the CellDataChangedInfo relates to the given column
// optionally, if a filter function (where clause) is provided, it is also evaluated
export const getDataChangeLog$ = (context, columnNameFilter) => {
let dataChangeLog$ = context.adaptableApi.internalApi.getDataService().cellDataChangeLog$;
// filter only the given column changes
dataChangeLog$ = dataChangeLog$.pipe(filter((dataChangeLog) => dataChangeLog.column.columnId === columnNameFilter));
// filter based on the WHERE clause
if (context.filterFn) {
dataChangeLog$ = dataChangeLog$.pipe(filter((value) => {
return context.filterFn(value.rowNode);
}));
}
return dataChangeLog$;
};
export const getGridChangeLog$ = (context, rowChangeType) => {
const gridChangeLog$ = context.adaptableApi.internalApi.getDataService().rowDataChangeLog$;
let gridChangeStream$ = gridChangeLog$.pipe(filter((rowDataChangedInfo) => rowDataChangedInfo.rowTrigger === rowChangeType));
// filter based on the WHERE clause
if (context.filterFn) {
gridChangeStream$ = gridChangeStream$.pipe(filter((value) => value.rowNodes.some((node) => context.filterFn(node))));
}
return gridChangeStream$;
};
export const handleWhereFunction = (args, context) => {
const reactiveExpressionNode = args[0];
const whereClauseExpressionNode = args[1];
const filterFn = (rowNode) => {
// whereClauseResult
return evaluateNode(whereClauseExpressionNode, {
node: rowNode,
functions: context.whereClauseFunctions,
evaluateCustomQueryVariable: context.adaptableApi.internalApi.getQueryLanguageService().evaluateCustomQueryVariable,
...context.adaptableApi.internalApi.buildBaseContext(),
});
};
// observableExpressionResult
return evaluateExpressionNode(reactiveExpressionNode, context, filterFn);
};
export const evaluateExpressionNode = (expressionNode, context, filterFn = context.filterFn) => {
return evaluateNode(expressionNode, {
node: context.node,
functions: context.functions,
filterFn,
evaluateCustomQueryVariable: context.adaptableApi.internalApi.getQueryLanguageService().evaluateCustomQueryVariable,
...context.adaptableApi.internalApi.buildBaseContext(),
});
};
export const extractColumnParameter = (consumingFunctionName, args) => {
return extractParameter(consumingFunctionName, 'config', ['COL'], args);
};
export const extractColumnParameters = (consumingFunctionName, args) => {
return extractParameters(consumingFunctionName, 'config', ['COL'], args);
};
export const extractParameter = (consumingFunctionName, allowedType, allowedOperands, args, config) => {
const parameters = extractParameters(consumingFunctionName, allowedType, allowedOperands, args, config);
if (parameters == undefined) {
return;
}
if (parameters.length > 1) {
throw new ExpressionEvaluationError(consumingFunctionName, `expects only 1 argument of type '${[...new Set(parameters.map((op) => op.name))].join(`' / '`)}'`);
}
return parameters[0];
};
export const extractParameters = (consumingFunctionName, allowedType, allowedOperands, args, config) => {
const { isOptional } = config ?? {};
const result = args.filter((arg) => arg?.type === allowedType && allowedOperands.includes(arg?.name));
if (isOptional && !result.length) {
return;
}
if (!result.length) {
throw new ExpressionEvaluationError(consumingFunctionName, `expects an argument of type '${allowedOperands.join(`' / '`)}'`);
}
return result;
};
export const handleColumnFunction = (args, context) => {
if (StringExtensions.IsNullOrEmpty(args[0])) {
throw new ExpressionEvaluationError('COL', `no column name is provided`);
}
validateColumnId(args[0], context.adaptableApi);
const result = {
type: 'config',
name: 'COL',
value: args[0],
};
return result;
};
export const getNumericValue = (input, returnRawValue) => {
if (typeof input === 'number') {
return input;
}
const numericValue = toNumber(input);
if (returnRawValue === true) {
return numericValue;
}
return isNaN(numericValue) ? 0 : numericValue;
};
export const validateColumnType = (columnId, validColumnTypes, consumingFunction, api) => {
const columnType = api.columnApi.getColumnDataTypeForColumnId(columnId);
if (!validColumnTypes.some((validType) => validType === columnType)) {
throw new ExpressionEvaluationError(consumingFunction, `expects a column of type ${validColumnTypes.join(' or ')}`);
}
return columnType;
};
const validateColumnId = (columnId, api) => {
const column = api.columnApi.getColumnWithColumnId(columnId);
if (!column) {
throw new ExpressionEvaluationError('', `Column name "${columnId}" is not found`);
}
if (!column.queryable) {
throw new ExpressionEvaluationError('', `Column name "${columnId}" is not queryable`);
}
};