UNPKG

@adaptabletools/adaptable

Version:

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

228 lines (227 loc) 11 kB
import * as AlertRedux from '../Redux/ActionsReducers/AlertRedux'; import * as InternalRedux from '../Redux/ActionsReducers/InternalRedux'; import { OBSERVABLE_EXPRESSION_ROW_ADDED, OBSERVABLE_EXPRESSION_ROW_REMOVED, } from '../Utilities/Constants/GeneralConstants'; import * as ModuleConstants from '../Utilities/Constants/ModuleConstants'; import { ArrayExtensions } from '../Utilities/Extensions/ArrayExtensions'; import { getObjectTagsViewItems } from '../Utilities/getObjectTagsViewItems'; import { getRuleViewItems } from '../Utilities/getRuleViewItems'; import { getScopeViewItems } from '../Utilities/getScopeViewItems'; import { ActiveAlertsPanelItemLabel } from '../View/Alert/ActiveAlertsPanelItemLabel'; import { AlertEmptyView } from '../View/Alert/AlertEmptyView'; import { AlertStatusPanel } from '../View/Alert/AlertStatusSubPanel'; import { getAlertType } from '../View/Alert/Utilities/getAlertType'; import { AlertWizard } from '../View/Alert/Wizard/AlertWizard'; import { AdaptableModuleBase } from './AdaptableModuleBase'; import { getAlertBehaviourViewItems } from './Utilities/Alert/getAlertBehaviourViewItems'; import { getAlertPreviewViewItems } from './Utilities/Alert/getAlertPreviewViewItems'; import { getAlertTypeViewItems } from './Utilities/Alert/getAlertTypeViewItems'; export class AlertModule extends AdaptableModuleBase { constructor(api) { super(ModuleConstants.AlertModuleId, ModuleConstants.AlertModuleFriendlyName, 'alert', 'AlertPopup', 'Get notified when things happen in Adaptable that you need to know about', api); this.isListeningToCellDataChanges = false; } onAdaptableReady() { this.checkListenToCellDataChanged(); } shouldListenToDataChanges() { return ArrayExtensions.IsNotNullOrEmpty(this.api.alertApi.getActiveAlertDefinitions()); } checkListenToCellDataChanged() { if (!this.isListeningToCellDataChanges) { if (this.shouldListenToDataChanges()) { this.setupCellDataChangeListener(); this.isListeningToCellDataChanges = true; } } } setupCellDataChangeListener() { this.api.internalApi .getDataService() .on('CellDataChanged', (cellDataChangedInfo) => { let shouldIgnoreChange = false; if (cellDataChangedInfo.trigger === 'undo') { shouldIgnoreChange = true; } if (cellDataChangedInfo.trigger === 'aggChange') { shouldIgnoreChange = !cellDataChangedInfo.column.isGeneratedPivotResultColumn; } if (shouldIgnoreChange) { // do NOT handle reverted or aggregated changes return; } if (this.api.optionsApi.getAlertOptions().dataChangeDetectionPolicy === 'formattedValue') { const { oldValue, newValue, rowNode } = cellDataChangedInfo; const columnId = cellDataChangedInfo.column.columnId; const oldFormattedValue = this.api.gridApi.getDisplayValueFromRawValue(rowNode, columnId, oldValue); const newFormattedValue = this.api.gridApi.getDisplayValueFromRawValue(rowNode, columnId, newValue); if (oldFormattedValue === newFormattedValue) { // if the formattedValues are identical, then no alert is fired return; } } this.handleCellDataChanged(cellDataChangedInfo); }); this.api.internalApi .getDataService() .on('RowDataChanged', (rowDataChangedInfo) => { if (rowDataChangedInfo.rowTrigger === 'Update') { // changed row alerts should be handled by standard 'AnyChange' Predicate return; } this.handleRowDataChanged(rowDataChangedInfo); }); this.api.internalApi .getAlertService() .onReactiveAlertTriggered((reactiveAlertInfo) => this.handleReactiveAlertTriggered(reactiveAlertInfo)); this.api.alertApi.internalApi.setUpReactiveAlerts(); } getModuleAdaptableObjects(config) { return this.api.alertApi.getAlertDefinitions(config); } getExplicitlyReferencedColumnIds(alertDefinition) { const queryExpression = this.api.expressionApi.getAdaptableQueryExpression(alertDefinition.Rule); if (queryExpression) { return this.api.expressionApi.getColumnsFromExpression(queryExpression); } else if (this.api.columnScopeApi.scopeHasColumns(alertDefinition.Scope)) { return this.api.columnScopeApi .getColumnsInScope(alertDefinition.Scope) .map((adaptableColumn) => adaptableColumn.columnId); } return []; } getReferencedNamedQueryNames(alertDefinition) { const queryExpression = this.api.expressionApi.getAdaptableQueryExpression(alertDefinition.Rule); if (!queryExpression) { return []; } return this.api.namedQueryApi.internalApi.getReferencedNamedQueryNames(queryExpression); } createContextMenuItems(menuContext) { const items = []; if (!menuContext.isRowGroupColumn && this.isModuleAvailable()) { if (menuContext.adaptableColumn && menuContext.rowNode) { let relevantAlert; // find alerts which highlight the current cell relevantAlert = this.api.alertApi.internalApi.getAdaptableAlertWithHighlightCell(menuContext.adaptableColumn.columnId, menuContext.rowNode); if (!relevantAlert) { // find alerts which highlight the current row relevantAlert = this.api.alertApi.internalApi.getAdaptableAlertWithHighlightRow(menuContext.rowNode); } if (relevantAlert) { items.push(this.createMenuItemReduxAction('alert-clear', 'Clear Alert', this.moduleInfo.Glyph, InternalRedux.AdaptableAlertDelete(relevantAlert))); } } } return items; } handleCellDataChanged(cellDataChangedInfo) { const alertDefinitions = this.api.alertApi.internalApi.getAlertDefinitionsForCellDataChange(cellDataChangedInfo); if (ArrayExtensions.IsNotNullOrEmpty(alertDefinitions)) { this.api.alertApi.internalApi.showAlertForDefinitions(cellDataChangedInfo, alertDefinitions); } } handleRowDataChanged(rowDataChangedInfo) { const alertDefinitions = this.getAlertDefinitionsForRowDataChange(rowDataChangedInfo); this.api.alertApi.internalApi.showAlertsForRowDataChanges(rowDataChangedInfo, alertDefinitions); } handleReactiveAlertTriggered(reactiveAlertInfo) { // TODO - suppress Notification if alert is not relevant for layout if (reactiveAlertInfo.type === 'cellDataChangedAlert') { // the row node data is most probably stale because the reactive queries buffer the changed data // so we have to refresh it reactiveAlertInfo.cellChangeLogEntry.rowNode = this.api.gridApi.getRowNodeForPrimaryKey(reactiveAlertInfo.cellChangeLogEntry.primaryKeyValue); reactiveAlertInfo.cellChangeLogEntry.rowData = reactiveAlertInfo.cellChangeLogEntry.rowNode?.data; this.api.alertApi.internalApi.showAlertForDefinitions(reactiveAlertInfo.cellChangeLogEntry, [ reactiveAlertInfo.alertDefinition, ]); } else { // reactiveAlertInfo.type === rowDataChangedAlert' this.api.alertApi.internalApi.showAlertForDefinitions(reactiveAlertInfo.gridChangeLogEntry, [ reactiveAlertInfo.alertDefinition, ]); } } getAlertDefinitionsForRowDataChange(rowDataChangedInfo) { return this.api.alertApi.internalApi .getActiveNonReactiveAlertDefinitions() .filter((alertDefinition) => this.api.alertApi.internalApi.isAlertDefinitionForRowChangeEvent(alertDefinition)) .filter((alertDefinition) => { if (rowDataChangedInfo.rowTrigger === 'Add') { return alertDefinition.Rule?.ObservableExpression.includes(OBSERVABLE_EXPRESSION_ROW_ADDED); } if (rowDataChangedInfo.rowTrigger === 'Delete') { return alertDefinition.Rule?.ObservableExpression.includes(OBSERVABLE_EXPRESSION_ROW_REMOVED); } return false; }); } getTeamSharingAction() { return { ModuleEntities: this.api.alertApi.getAlertDefinitions(), AddAction: AlertRedux.AlertDefinitionAdd, EditAction: AlertRedux.AlertDefinitionEdit, }; } toViewCompact(alert) { return { item: { name: alert.header, label: ActiveAlertsPanelItemLabel, values: [alert.message], }, abObject: alert, }; } toView(alert) { const alertType = getAlertType(alert); return { items: [ getAlertTypeViewItems(alert), alertType === 'DataChange' && { ...getScopeViewItems(alert.Scope, this.api), label: 'Trigger', name: 'Trigger', }, { ...getRuleViewItems(alert.Rule, this.api), label: 'Rule', name: 'Rule' }, getAlertBehaviourViewItems(this.api), getAlertPreviewViewItems(alert, this.api), getObjectTagsViewItems(alert, this.api), ].filter(Boolean), abObject: alert, }; } toViewAll() { return this.getModuleAdaptableObjects({ includeLayoutNotAssociatedObjects: this.showLayoutNotAssociatedObjects(), }).map((alert) => this.toView(alert)); } getViewProperties() { return { getDeleteAction: AlertRedux.AlertDefinitionDelete, getEditAction: AlertRedux.AlertDefinitionEdit, getSuspendAction: AlertRedux.AlertDefinitionSuspend, getUnSuspendAction: AlertRedux.AlertDefinitionUnSuspend, getSuspendAllAction: AlertRedux.AlertDefinitionSuspendAll, getUnSuspendAllAction: AlertRedux.AlertDefinitionUnSuspendAll, getCompactDeleteAction: InternalRedux.AdaptableAlertDelete, getDeleteAllAction: () => { const alerts = this.api.internalApi.getState().Internal.AdaptableAlerts; return InternalRedux.AdaptableAlertDeleteAll(alerts); }, emptyView: AlertEmptyView, getEditWizard: () => AlertWizard, getStatusBarPanelProps: () => { return { popoverMinWidth: 360, view: AlertStatusPanel, }; }, }; } canBeAssociatedWithLayouts() { return true; } }