@adaptabletools/adaptable
Version:
Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
242 lines (241 loc) • 11 kB
JavaScript
import * as PlusMinusRedux from '../Redux/ActionsReducers/PlusMinusRedux';
import * as ModuleConstants from '../Utilities/Constants/ModuleConstants';
import { ArrayExtensions } from '../Utilities/Extensions/ArrayExtensions';
import { Helper } from '../Utilities/Helpers/Helper';
import { AdaptableModuleBase } from './AdaptableModuleBase';
import { PlusMinusModuleId } from '../Utilities/Constants/ModuleConstants';
import { getObjectTagsViewItems } from '../Utilities/getObjectTagsViewItems';
import { getRuleViewItems } from '../Utilities/getRuleViewItems';
import { getScopeViewItems } from '../Utilities/getScopeViewItems';
import { MovePlusMinus } from '../View/PlusMinus/MovePlusMinus';
import { PlusMinusWizard } from '../View/PlusMinus/Wizard/PlusMinusWizard';
import { errorOnce } from '../agGrid/AdaptableLogger';
export class PlusMinusModule extends AdaptableModuleBase {
constructor(api) {
super(ModuleConstants.PlusMinusModuleId, ModuleConstants.PlusMinusFriendlyName, 'add-circle', 'PlusMinusPopup', 'Configure how a cell value will edit when the + or - keys are pressed', api);
this.shouldHandleKeyDown = false;
this.adaptable = api.internalApi.getAdaptableInstance();
}
getModuleAdaptableObjects(config) {
return this.api.plusMinusApi.getAllPlusMinus(config);
}
getExplicitlyReferencedColumnIds(plusMinusNudge) {
if (this.api.columnScopeApi.scopeHasColumns(plusMinusNudge.Scope)) {
return this.api.columnScopeApi
.getColumnsInScope(plusMinusNudge.Scope)
.map((adaptableColumn) => adaptableColumn.columnId);
}
return [];
}
getReferencedNamedQueryNames(plusMinusNudge) {
if (!plusMinusNudge.Rule?.BooleanExpression) {
return [];
}
return this.api.namedQueryApi.internalApi.getReferencedNamedQueryNames(plusMinusNudge.Rule?.BooleanExpression);
}
onAdaptableReady() {
let plusMinusNudges = this.api.plusMinusApi.getAllPlusMinus();
this.shouldHandleKeyDown = ArrayExtensions.IsNotNullOrEmpty(plusMinusNudges);
if (this.shouldHandleKeyDown) {
this.setupKeyDownListener();
}
}
setupKeyDownListener() {
this.adaptable._on('KeyDown', (keyDownEvent) => {
this.handleKeyDown(keyDownEvent);
});
}
checkListenToKeyDown() {
const oldShouldHandleKeyDown = this.shouldHandleKeyDown;
const newShouldHandleKeyDown = ArrayExtensions.IsNotNullOrEmpty(this.api.plusMinusApi.getAllPlusMinus());
if (!oldShouldHandleKeyDown && newShouldHandleKeyDown) {
this.setupKeyDownListener();
}
this.shouldHandleKeyDown = newShouldHandleKeyDown;
}
createColumnMenuItems(column) {
if (column && this.isModuleEditable() && column.dataType == 'number') {
let popupParam = {
column: column,
action: 'New',
source: 'ColumnMenu',
};
return [
this.createMenuItemShowPopup('plus-minus-add', 'Create Plus/Minus Rule', this.moduleInfo.Popup, this.moduleInfo.Glyph, popupParam),
];
}
}
handleKeyDown(keyEvent) {
if (this.shouldHandleKeyDown) {
//it's a special key so we handle the string representation of the key '
let keyEventString = Helper.getStringRepresentionFromKey(keyEvent);
if (keyEventString == '-' || keyEventString == '+') {
let plusMinusNudges = this.api.plusMinusApi.getAllActivePlusMinus();
if (ArrayExtensions.IsNotNullOrEmpty(plusMinusNudges)) {
let side = keyEventString == '-' ? 'down' : 'up';
let selectedCellInfo = this.api.gridApi.getSelectedCellInfo();
let isPlusMinusApplicable = this.applyPlusMinus(plusMinusNudges, selectedCellInfo.gridCells, side);
if (isPlusMinusApplicable) {
keyEvent.preventDefault();
}
}
}
}
}
applyPlusMinus(plusMinusNudges, cellsToUpdate, direction) {
let shouldApplyPlusMinus = false;
let successfulValues = [];
let failedPreventEdits = [];
let side = direction == 'up' ? 1 : -1;
cellsToUpdate.forEach((gridCell) => {
if (gridCell.column &&
gridCell.column.dataType == 'number' &&
this.api.gridApi.isCellEditable(gridCell)) {
let foundRule;
let replacementGridCell;
plusMinusNudges.forEach((pmr) => {
if (!foundRule) {
if (this.api.columnScopeApi.isColumnInScope(gridCell.column, pmr.Scope)) {
//for aggrid as we are getting strings sometimes
if (typeof gridCell.rawValue != 'number') {
gridCell.rawValue = parseFloat(gridCell.rawValue);
}
const isSatisfiedExpression = this.isPlusMinusNudgeApplied(pmr, gridCell);
if (isSatisfiedExpression) {
foundRule = pmr;
shouldApplyPlusMinus = true;
let computedValue = gridCell.rawValue + pmr.NudgeValue * side;
//avoid the 0.0000000000x??
// computedValue= parseFloat(computedValue.toFixed(12));
replacementGridCell = {
primaryKeyValue: gridCell.primaryKeyValue,
column: gridCell.column,
rawValue: computedValue,
displayValue: computedValue,
normalisedValue: computedValue,
rowNode: gridCell.rowNode,
isPivotCell: false,
isRowGroupCell: false,
};
}
}
}
});
if (foundRule && replacementGridCell) {
const dataChangedEvent = this.api.internalApi.buildCellDataChangedInfo({
oldValue: Number(gridCell.rawValue),
newValue: replacementGridCell.rawValue,
column: gridCell.column,
primaryKeyValue: gridCell.primaryKeyValue,
rowNode: gridCell.rowNode,
trigger: 'edit',
});
let validationRules = this.api.internalApi
.getValidationService()
.getValidationRulesForDataChange(dataChangedEvent);
if (validationRules.length > 0) {
failedPreventEdits.push(validationRules[0]);
}
else {
successfulValues.push(replacementGridCell);
}
}
}
});
this.ShowErrorPreventMessage(failedPreventEdits);
if (ArrayExtensions.IsNotNullOrEmpty(successfulValues)) {
const cellUpdateRequests = [];
successfulValues.forEach((gridCell) => {
cellUpdateRequests.push({
columnId: gridCell.column.columnId,
newValue: gridCell.normalisedValue,
primaryKeyValue: gridCell.primaryKeyValue,
rowNode: gridCell.rowNode,
});
});
this.api.plusMinusApi.applyPlusMinus(cellUpdateRequests);
}
return shouldApplyPlusMinus;
}
isPlusMinusNudgeApplied(plusMinusNudge, gridCell) {
if (plusMinusNudge.Rule?.BooleanExpression) {
return this.evaluateExpression(plusMinusNudge, gridCell.rowNode);
}
return true;
}
evaluateExpression(plusMinusNudge, node) {
try {
return this.api.internalApi
.getQueryLanguageService()
.evaluateBooleanExpression(plusMinusNudge.Rule?.BooleanExpression, PlusMinusModuleId, node);
}
catch (error) {
errorOnce(error.message);
return false;
}
}
ShowErrorPreventMessage(failedRules) {
if (failedRules.length > 0) {
let failedMessages = [];
failedRules.forEach((fr) => {
let failedMessage = this.api.internalApi.getValidationService().createValidationMessage(fr) + '\n';
let existingMessage = failedMessages.find((f) => f == failedMessage);
if (existingMessage == null) {
failedMessages.push(failedMessage);
}
});
this.api.alertApi.showAlertError('Nudge(s) failed rule', failedMessages.toString());
}
}
getTeamSharingAction() {
return {
ModuleEntities: this.api.plusMinusApi.getAllPlusMinus(),
AddAction: PlusMinusRedux.PlusMinusNudgeAdd,
EditAction: PlusMinusRedux.PlusMinusNudgeEdit,
};
}
toView(plusMinus) {
return {
abObject: plusMinus,
items: [
{
name: 'Target',
...getScopeViewItems(plusMinus.Scope, this.api),
},
plusMinus.Rule && {
name: 'Settings',
label: 'Rule',
values: getRuleViewItems(plusMinus.Rule, this.api).values,
},
{
name: 'Settings',
label: 'Nudge Value',
values: [plusMinus.NudgeValue],
},
getObjectTagsViewItems(plusMinus, this.api),
].filter(Boolean),
};
}
toViewAll() {
return this.getModuleAdaptableObjects({
includeLayoutNotAssociatedObjects: this.showLayoutNotAssociatedObjects(),
}).map((plusMinus) => this.toView(plusMinus));
}
getViewProperties() {
return {
actions: [MovePlusMinus],
getEditAction: PlusMinusRedux.PlusMinusNudgeEdit,
getDeleteAction: PlusMinusRedux.PlusMinusNudgeDelete,
getSuspendAction: PlusMinusRedux.PlusMinusNudgeSuspend,
getUnSuspendAction: PlusMinusRedux.PlusMinusNudgeUnSuspend,
getSuspendAllAction: PlusMinusRedux.PlusMinusNudgeSuspendAll,
getUnSuspendAllAction: PlusMinusRedux.PlusMinusNudgeUnSuspendAll,
getEditWizard() {
return PlusMinusWizard;
},
};
}
canBeAssociatedWithLayouts() {
return true;
}
}