@adaptabletools/adaptable-cjs
Version:
Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
179 lines (178 loc) • 8.47 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RowSummaryService = void 0;
const tslib_1 = require("tslib");
const RowSummary_1 = require("../../AdaptableState/Common/RowSummary");
const InternalRedux_1 = require("../../Redux/ActionsReducers/InternalRedux");
const ModuleConstants = tslib_1.__importStar(require("../../Utilities/Constants/ModuleConstants"));
const Helper_1 = tslib_1.__importDefault(require("../Helpers/Helper"));
const AggregatedScalarLiveValue_1 = require("./AggregatedScalarLiveValue");
const ObjectExtensions_1 = require("../Extensions/ObjectExtensions");
const throttle_1 = tslib_1.__importDefault(require("lodash/throttle"));
const isEqual_1 = tslib_1.__importDefault(require("lodash/isEqual"));
/**
* The logic is extracted here to make it easier to follow
*/
class RowSummaryService {
constructor(api) {
this.api = api;
this.cachedCellSummary = new Map();
this._throttleAcumulatedColumnsThatChanged = new Set();
/**
*
* @param colId optional to evaluate only one column
*/
this._throttledEvaluateRowSummary = (0, throttle_1.default)(this.evaluateRowSummary, 300);
}
onAdaptableReady() {
this.rowSummariesSubscriptions();
}
rowSummariesSubscriptions() {
// return;
if (this.api.isDestroyed()) {
return;
}
// Currently not available for serverside model
if (!this.api.layoutApi.internalApi.getLayoutSupportedFeatures().RowSummaries) {
return;
}
this.throttledEvaluateRowSummary();
this.api.eventApi.on('AdaptableStateReloaded', () => {
this.throttledEvaluateRowSummary();
});
this.api.internalApi
.getDataService()
.on('RowDataChanged', (rowDataChangedInfo) => {
this.throttledEvaluateRowSummary();
});
this.api.eventApi.on('CellChanged', (event) => {
const columnId = event.cellDataChange.column.columnId;
this.throttledEvaluateRowSummary({
columnIds: [columnId],
});
});
this.api.eventApi.on('LayoutChanged', (event) => {
// exclude filter events, those are handled in another event
if (event.actionName.includes('FILTER')) {
return;
}
setTimeout(() => {
// the timeout is added so the grid has time to repond to the layout changed
this.throttledEvaluateRowSummary();
}, 16);
});
const adaptable = this.api.internalApi.getAdaptableInstance();
adaptable._on('AdapTableFiltersApplied', () => {
// we need to use this instead of layout changed so the rows have time to update
this.throttledEvaluateRowSummary();
});
adaptable._on('FirstDataRendered', () => {
this.throttledEvaluateRowSummary();
});
}
throttledEvaluateRowSummary(reason) {
if (reason) {
reason.columnIds.forEach((col) => this._throttleAcumulatedColumnsThatChanged.add(col));
}
this._throttledEvaluateRowSummary(reason);
}
evaluateRowSummary(reason) {
if (this._throttleAcumulatedColumnsThatChanged.size > 0) {
const columnIds = Array.from(this._throttleAcumulatedColumnsThatChanged.values());
reason = {
columnIds,
};
this._throttleAcumulatedColumnsThatChanged.clear();
}
if (this.api.isDestroyed() || this.api.layoutApi.isCurrentLayoutPivot()) {
return;
}
const currentLayout = this.api.layoutApi.getCurrentLayout();
let previousLayout = this.previousLayout;
// it is added here to be sure it is saved
this.previousLayout = currentLayout;
/**
* If the previous & current layout does not have row summaries, it is safe to exit
*/
if ((0, ObjectExtensions_1.isObjectEmpty)(currentLayout?.RowSummaries) && (0, ObjectExtensions_1.isObjectEmpty)(previousLayout?.RowSummaries)) {
return;
}
const rowSummaries = currentLayout.RowSummaries ?? [];
const aggColsMap = (currentLayout.TableAggregationColumns || []).reduce((acc, { ColumnId, AggFunc }) => {
acc[ColumnId] = AggFunc;
return acc;
}, {});
const rowSummariesResults = rowSummaries
.filter((rowSummary) => !rowSummary.IsSuspended)
.map((rowSummary, index) => {
const { ColumnsMap, Position,
// it defaults to true
IncludeOnlyFilteredRows = true, } = rowSummary;
return {
Position,
RowData: Object.entries(ColumnsMap ?? {}).reduce((acc, [columnId, expression]) => {
if (columnId === 'Uuid' || columnId === 'Source' || columnId === 'AdaptableVersion') {
return acc;
}
const key = `${columnId}-${expression}-IncludeOnlyFilteredRows=${IncludeOnlyFilteredRows ? 'filtered' : 'all'}`;
let expressionLiveValue = this.cachedCellSummary.get(key);
if (expressionLiveValue) {
if (!reason) {
// refresh all of them
expressionLiveValue.refresh();
}
else if ('columnIds' in reason && reason.columnIds.includes(columnId)) {
expressionLiveValue.refresh();
}
}
if (!expressionLiveValue) {
try {
let aggregatedScalarExpression = `${expression}([${columnId}])`;
if (aggregatedScalarExpression.includes(RowSummary_1.WEIGHTED_AVERAGE_AGGREGATED_FUNCTION) &&
aggColsMap[columnId] &&
typeof aggColsMap[columnId] === 'object') {
const weight = aggColsMap[columnId].weightedColumnId;
if (weight) {
aggregatedScalarExpression = `AVG([${columnId}], WEIGHT([${weight}]))`;
}
}
expressionLiveValue = new AggregatedScalarLiveValue_1.AggregatedScalarLiveValue({
aggregatedScalarExpression,
}, ModuleConstants.LayoutModuleId, this.api, () => {
if (rowSummary.IncludeOnlyFilteredRows ?? true) {
return this.api.gridApi.getVisibleRowNodes();
}
else {
return this.api.gridApi.getAllRowNodes();
}
});
}
catch (e) {
this.api.logError('Error evaluating row summary', e);
}
this.cachedCellSummary.set(key, expressionLiveValue);
}
let value = null;
if (expressionLiveValue) {
value = expressionLiveValue.getGlobalAggregatedValue();
if (typeof value === 'number' && !isNaN(value)) {
value = Helper_1.default.roundNumber(value, 2);
}
}
const column = this.api.columnApi.getColumnWithColumnId(columnId);
const fieldName = column?.field ?? column?.columnId ?? columnId;
acc = this.api.internalApi.setValueUsingField(acc, fieldName, value);
return acc;
}, {
[RowSummary_1.ROW_SUMMARY_ROW_ID]: `row-summary-${index}`,
}),
};
});
if (this.previousRowSummaries && (0, isEqual_1.default)(rowSummariesResults, this.previousRowSummaries)) {
return;
}
this.api.internalApi.dispatchReduxAction((0, InternalRedux_1.RowSummarySet)(rowSummariesResults));
this.previousRowSummaries = rowSummariesResults;
}
}
exports.RowSummaryService = RowSummaryService;