@adaptabletools/adaptable
Version:
Powerful AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
963 lines • 77.3 kB
JavaScript
import * as Redux from 'redux';
import * as PluginsRedux from '../ActionsReducers/PluginsRedux';
import * as PopupRedux from '../ActionsReducers/PopupRedux';
import { PROGRESS_INDICATOR_HIDE, PROGRESS_INDICATOR_SHOW } from '../ActionsReducers/PopupRedux';
import { createEngine as createEngineLocal } from './AdaptableReduxLocalStorageEngine';
import { mergeReducer } from './AdaptableReduxMerger';
import { isAdaptableCellChangedAlert, isAdaptableRowChangedAlert, } from '../../AdaptableState/Common/AdaptableAlert';
import { closeAgChartDefinitionIfOpen, closeExternalChartDefinitionIfOpen, } from '../../Utilities/Helpers/ChartHelper';
import { refreshScheduledAlertJobs, refreshScheduledReportJobs, } from '../../Utilities/Helpers/Scheduling/ScheduledJobsMiddlewareHelper';
import { getRuleAlertProperties, isScheduledAlertDefinition, } from '../../Utilities/Helpers/Scheduling/ScheduledAlertHelper';
import { ERROR_LAYOUT } from '../../Utilities/Constants/GeneralConstants';
import * as ModuleConstants from '../../Utilities/Constants/ModuleConstants';
import Emitter from '../../Utilities/Emitter';
import { StringExtensions } from '../../Utilities/Extensions/StringExtensions';
import { PreviewHelper } from '../../Utilities/Helpers/PreviewHelper';
import { ObjectFactory } from '../../Utilities/ObjectFactory';
import { showToast } from '../../View/Components/Popups/AdaptableToaster';
import * as AlertRedux from '../ActionsReducers/AlertRedux';
import * as ApplicationRedux from '../ActionsReducers/ApplicationRedux';
import * as BulkUpdateRedux from '../ActionsReducers/BulkUpdateRedux';
import * as CalculatedColumnRedux from '../ActionsReducers/CalculatedColumnRedux';
import * as ChartingRedux from '../ActionsReducers/ChartingRedux';
import * as CommentsRedux from '../ActionsReducers/CommentsRedux';
import * as CustomSortRedux from '../ActionsReducers/CustomSortRedux';
import * as DashboardRedux from '../ActionsReducers/DashboardRedux';
import * as ExportRedux from '../ActionsReducers/ExportRedux';
import * as FlashingCellRedux from '../ActionsReducers/FlashingCellRedux';
import * as FormatColumnRedux from '../ActionsReducers/FormatColumnRedux';
import * as FreeTextColumnRedux from '../ActionsReducers/FreeTextColumnRedux';
import * as LayoutRedux from '../ActionsReducers/LayoutRedux';
import * as NamedQueryRedux from '../ActionsReducers/NamedQueryRedux';
import * as NoteRedux from '../ActionsReducers/NoteRedux';
import * as PlusMinusRedux from '../ActionsReducers/PlusMinusRedux';
import * as QuickSearchRedux from '../ActionsReducers/QuickSearchRedux';
import * as ShortcutRedux from '../ActionsReducers/ShortcutRedux';
import * as SmartEditRedux from '../ActionsReducers/SmartEditRedux';
import * as StatusBarRedux from '../ActionsReducers/StatusBarRedux';
import * as StyledColumnRedux from '../ActionsReducers/StyledColumnRedux';
import * as InternalRedux from '../ActionsReducers/InternalRedux';
import * as TeamSharingRedux from '../ActionsReducers/TeamSharingRedux';
import * as ThemeRedux from '../ActionsReducers/ThemeRedux';
import * as ToolPanelRedux from '../ActionsReducers/ToolPanelRedux';
import * as UserInterfaceRedux from '../ActionsReducers/UserInterfaceRedux';
import { areAdaptableProfileTracksEnabled, getMarker } from '../../devTools';
import { isAdaptableSharedEntity, isCustomSharedEntity, } from '../../AdaptableState/TeamSharingState';
import { buildAdaptableStateFunctionConfig } from './buildAdaptableStateFunctionConfig';
const INIT_STATE = 'INIT_STATE';
const LOAD_STATE = 'LOAD_STATE';
const NON_PERSIST_ACTIONS = {
'@@INIT': true,
'@@redux/init': true,
[LOAD_STATE]: true,
[INIT_STATE]: true,
[PROGRESS_INDICATOR_SHOW]: true,
[PROGRESS_INDICATOR_HIDE]: true,
};
const NON_PERSISTENT_STORE_KEYS = [
'Internal',
'Popup',
'Comment',
'Plugins',
];
export const getPersistableState = (state) => {
NON_PERSISTENT_STORE_KEYS.forEach((key) => {
delete state[key];
});
return state;
};
export const InitState = () => ({
type: INIT_STATE,
});
export const LoadState = (State) => ({
type: LOAD_STATE,
State,
});
export class AdaptableStore {
TheStore;
Load;
emitter;
beforeEmitter;
storageEngine;
currentStorageState;
previousStorageState;
loadStorageInProgress = false;
loadStateOnStartup = true;
on = (eventName, callback) => {
return this.emitter.on(eventName, callback);
};
onAny = (callback) => {
return this.emitter.onAny(callback);
};
onBeforeAny = (callback) => {
return this.beforeEmitter.onAny(callback);
};
emit = (eventName, data) => {
return this.emitter.emit(eventName, data);
};
constructor(adaptable) {
let rootReducerObject = {
Popup: PopupRedux.PopupReducer,
Internal: InternalRedux.InternalReducer,
Plugins: PluginsRedux.PluginsReducer,
Comment: CommentsRedux.CommentsReducer,
Alert: AlertRedux.AlertReducer,
Application: ApplicationRedux.ApplicationReducer,
CalculatedColumn: CalculatedColumnRedux.CalculatedColumnReducer,
Charting: ChartingRedux.ChartingReducer,
CustomSort: CustomSortRedux.CustomSortReducer,
Dashboard: DashboardRedux.DashboardReducer,
Export: ExportRedux.ExportReducer,
FlashingCell: FlashingCellRedux.FlashingCellReducer,
FormatColumn: FormatColumnRedux.FormatColumnReducer,
FreeTextColumn: FreeTextColumnRedux.FreeTextColumnReducer,
Layout: LayoutRedux.LayoutReducer,
NamedQuery: NamedQueryRedux.NamedQueryReducer,
Note: NoteRedux.NoteReducer,
PlusMinus: PlusMinusRedux.PlusMinusReducer,
QuickSearch: QuickSearchRedux.QuickSearchReducer,
Shortcut: ShortcutRedux.ShortcutReducer,
StatusBar: StatusBarRedux.StatusBarReducer,
StyledColumn: StyledColumnRedux.StyledColumnReducer,
TeamSharing: TeamSharingRedux.TeamSharingReducer,
Theme: ThemeRedux.ThemeReducer,
ToolPanel: ToolPanelRedux.ToolPanelReducer,
UserInterface: UserInterfaceRedux.UserInterfaceReducer,
};
adaptable.forPlugins((plugin) => {
if (plugin.rootReducer) {
rootReducerObject = {
...rootReducerObject,
...plugin.rootReducer(rootReducerObject),
};
}
});
const initialRootReducer = Redux.combineReducers(rootReducerObject);
const rootReducerWithResetManagement = (state, action) => {
switch (action.type) {
case LOAD_STATE:
const { State } = action;
Object.keys(State).forEach((key) => {
state[key] = State[key];
});
break;
}
return initialRootReducer(state, action);
};
let storageEngine;
this.emitter = new Emitter();
this.beforeEmitter = new Emitter();
storageEngine = createEngineLocal({
adaptableId: adaptable.adaptableOptions.adaptableId,
adaptableStateKey: adaptable.adaptableOptions.adaptableStateKey,
userName: adaptable.adaptableOptions.userName,
initialState: adaptable.adaptableOptions.initialState,
loadState: adaptable.adaptableOptions.stateOptions.loadState,
persistState: adaptable.adaptableOptions.stateOptions.persistState,
debounceStateDelay: adaptable.adaptableOptions.stateOptions.debounceStateDelay,
});
const didPersistentStateChange = (state, newState) => {
return Object.keys(newState).some((key) => {
if (NON_PERSISTENT_STORE_KEYS.includes(key)) {
return false;
}
return state?.[key] !== newState?.[key];
});
};
let rootReducer = mergeReducer(rootReducerWithResetManagement, LOAD_STATE);
const composeEnhancers = (x) => x;
const persistedReducer = (state, action) => {
if (adaptable.isDestroyed) {
return state;
}
const init = state === undefined;
const newState = rootReducer(state, action);
const emitterArg = { action, state, newState };
if (!NON_PERSIST_ACTIONS[action.type]) {
this.emitter.emit(action.type, emitterArg);
}
const finalState = emitterArg.newState;
const shouldPersist = state !== finalState &&
didPersistentStateChange(state, finalState) &&
!state?.Internal?.License?.disablePersistence &&
!NON_PERSIST_ACTIONS[action.type] &&
!init &&
!this.loadStorageInProgress;
if (shouldPersist) {
let storageState = { ...finalState };
storageState = getPersistableState(storageState);
this.currentStorageState = storageState;
this.previousStorageState = { ...state };
NON_PERSISTENT_STORE_KEYS.forEach((key) => {
delete this.previousStorageState[key];
});
storageEngine.save(adaptable, storageState, action.type);
}
return finalState;
};
const beforeEmitterMiddleware = (middlewareAPI) => (next) => (action) => {
if (!NON_PERSIST_ACTIONS[action.type]) {
const wasProgressActive = middlewareAPI.getState().Popup?.ProgressIndicator?.active;
this.beforeEmitter.emitSync(action.type, {
action,
state: middlewareAPI.getState(),
});
const isProgressActive = middlewareAPI.getState().Popup?.ProgressIndicator?.active;
if (!wasProgressActive && isProgressActive) {
requestAnimationFrame(() => {
requestAnimationFrame(() => {
next(action);
});
});
return action;
}
}
return next(action);
};
const devToolsActionMarkerMiddleware = createDevToolsActionMarkerMiddleware(adaptable);
const pluginsMiddleware = [];
adaptable.forPlugins((plugin) => {
if (plugin.reduxMiddleware) {
pluginsMiddleware.push(plugin.reduxMiddleware(adaptable));
}
});
const middlewares = [
beforeEmitterMiddleware,
devToolsActionMarkerMiddleware,
adaptableMiddleware(adaptable),
...pluginsMiddleware,
].filter(Boolean);
this.TheStore = Redux.createStore(persistedReducer, composeEnhancers(Redux.applyMiddleware(...middlewares)));
this.storageEngine = storageEngine;
}
destroy() {
this.emitter?.clearListeners();
this.emitter = null;
this.beforeEmitter?.clearListeners();
this.beforeEmitter = null;
}
getCurrentStorageState() {
return this.currentStorageState;
}
getPreviousStorageState() {
return this.previousStorageState;
}
saveStateNow(adaptable, state) {
const newState = state ?? this.getCurrentStorageState();
if (newState) {
return this.storageEngine.saveNow(adaptable, newState, 'API_CALL_SAVE_STATE');
}
return Promise.resolve(true);
}
loadStore = (config) => {
const { adaptable, adaptableStateKey, initialState, postLoadHook } = config;
const postProcessState = postLoadHook ?? ((state) => state);
this.storageEngine.setStateKey(adaptableStateKey);
this.loadStorageInProgress = true;
return (this.Load = this.storageEngine
.load(adaptable, initialState)
.then((storedState) => {
if (storedState && this.loadStateOnStartup) {
this.TheStore.dispatch(LoadState(postProcessState(adaptable.adaptableOptions.stateOptions.applyState(storedState, buildAdaptableStateFunctionConfig(adaptable)))));
}
})
.then(() => {
this.TheStore.dispatch(InitState());
this.loadStorageInProgress = false;
}, (e) => {
adaptable.api.consoleError('Failed to load saved Adaptable state.', e);
this.TheStore.dispatch(InitState());
this.loadStorageInProgress = false;
this.TheStore.dispatch(PopupRedux.PopupShowAlert({
alertType: 'generic',
header: 'Configuration',
message: 'Failed to load your configuration: ' + e,
alertDefinition: ObjectFactory.CreateInternalAlertDefinitionForMessages('Error'),
}));
}));
};
}
function createDevToolsActionMarkerMiddleware(adaptable) {
const adaptableId = adaptable?.adaptableOptions?.adaptableId;
if (!adaptableId) {
return null;
}
if (!areAdaptableProfileTracksEnabled(adaptableId)) {
return null;
}
return (middlewareAPI) => (next) => (action) => {
if (!isTrackableReduxAction(action)) {
return next(action);
}
const previousState = middlewareAPI.getState();
const marker = getMarker(adaptableId).track.Redux.label.Action.start();
try {
return next(action);
}
finally {
const nextState = middlewareAPI.getState();
const changedKeys = detectChangedAdaptableStateKeys(previousState, nextState);
const details = buildDevToolsActionDetails(action, changedKeys);
marker.end({
label: action.type,
tooltip: changedKeys?.length ? `State changes: ${changedKeys.join(', ')}` : undefined,
details: details.length ? details : undefined,
});
}
};
}
const MAX_MARKER_DETAILS = 6;
function buildDevToolsActionDetails(action, changedKeys) {
const details = [];
if (changedKeys && changedKeys.length > 0) {
const truncatedKeys = changedKeys.slice(0, MAX_MARKER_DETAILS);
const suffix = changedKeys.length > truncatedKeys.length
? ` +${changedKeys.length - truncatedKeys.length} more`
: '';
details.push({
name: 'State changes',
value: `${truncatedKeys.join(', ')}${suffix}`,
});
}
if (isActionWithPayload(action)) {
const entries = Object.entries(action).filter(([key]) => key !== 'type');
for (const [key, value] of entries) {
if (details.length >= MAX_MARKER_DETAILS) {
break;
}
details.push({
name: `action.${key}`,
value: coerceMarkerDetailValue(value),
});
}
}
return details;
}
function detectChangedAdaptableStateKeys(previousState, nextState) {
if (!previousState || !nextState || previousState === nextState) {
return undefined;
}
const previous = previousState;
const next = nextState;
const keys = new Set([...Object.keys(previous), ...Object.keys(next)]);
const changed = [];
keys.forEach((key) => {
if (previous[key] !== next[key]) {
changed.push(key);
}
});
return changed.length > 0 ? changed : undefined;
}
function isTrackableReduxAction(action) {
return !!action && typeof action.type === 'string';
}
function isActionWithPayload(action) {
return !!action && typeof action === 'object';
}
function coerceMarkerDetailValue(value) {
if (value === null) {
return 'null';
}
if (value === undefined) {
return 'undefined';
}
const valueType = typeof value;
if (valueType === 'string' || valueType === 'number' || valueType === 'boolean') {
return value;
}
if (valueType === 'function') {
return '[function]';
}
try {
const json = JSON.stringify(value);
if (!json) {
return '[empty]';
}
const MAX_LENGTH = 200;
return json.length > MAX_LENGTH ? `${json.slice(0, MAX_LENGTH - 3)}...` : json;
}
catch (err) {
return '[unserializable]';
}
}
const adaptableMiddleware = (adaptable) => (function(middlewareAPI) {
return function (next) {
return function (action) {
switch (action.type) {
case NamedQueryRedux.NAMED_QUERY_DELETE: {
const actionTyped = action;
if (!adaptable.api.namedQueryApi.internalApi.validateDeletedNamedQuery(actionTyped.namedQuery.Name)) {
return;
}
const ret = next(action);
return ret;
}
case NamedQueryRedux.NAMED_QUERY_EDIT: {
const actionTyped = action;
const editedNamedQuery = actionTyped.namedQuery;
const previousNamedQueryName = middlewareAPI
.getState()
.NamedQuery.NamedQueries.find((namedQuery) => namedQuery.Uuid === editedNamedQuery.Uuid)?.Name ?? '';
if (editedNamedQuery.Name !== previousNamedQueryName) {
if (!adaptable.api.namedQueryApi.internalApi.validateRenamedNamedQuery(previousNamedQueryName)) {
return;
}
}
const ret = next(action);
return ret;
}
case InternalRedux.SUMMARY_ROW_SET: {
let nextAction = next(action);
adaptable.api.layoutApi.internalApi.setupRowSummaries();
return nextAction;
}
case InternalRedux.QUICK_FILTER_BAR_SHOW: {
let nextAction = next(action);
adaptable.showQuickFilter();
return nextAction;
}
case InternalRedux.QUICK_FILTER_BAR_HIDE: {
let nextAction = next(action);
adaptable.hideQuickFilter();
return nextAction;
}
case AlertRedux.ALERT_DEFINITION_ADD:
case AlertRedux.ALERT_DEFINITION_EDIT:
case AlertRedux.ALERT_DEFINITION_DELETE:
case AlertRedux.ALERT_DEFINITION_UNSUSPEND:
case AlertRedux.ALERT_DEFINITION_SUSPEND:
case AlertRedux.ALERT_DEFINITION_UNSUSPEND_ALL:
case AlertRedux.ALERT_DEFINITION_SUSPEND_ALL: {
const returnAction = next(action);
const alertDefinition = returnAction.alertDefinition;
if (alertDefinition) {
if (!isScheduledAlertDefinition(alertDefinition) &&
(returnAction.type === AlertRedux.ALERT_DEFINITION_ADD ||
returnAction.type === AlertRedux.ALERT_DEFINITION_EDIT ||
returnAction.type === AlertRedux.ALERT_DEFINITION_UNSUSPEND)) {
adaptable.api.internalApi.getAlertService().createReactiveAlert(alertDefinition);
}
if (!isScheduledAlertDefinition(alertDefinition) &&
(returnAction.type === AlertRedux.ALERT_DEFINITION_DELETE ||
returnAction.type === AlertRedux.ALERT_DEFINITION_SUSPEND)) {
adaptable.api.internalApi.getAlertService().deleteReactiveAlert(alertDefinition);
}
}
if (returnAction.type === AlertRedux.ALERT_DEFINITION_SUSPEND_ALL) {
adaptable.api.internalApi
.getAlertService()
.getReactiveActiveAlerts()
.forEach((alertDefinition) => {
adaptable.api.internalApi.getAlertService().deleteReactiveAlert(alertDefinition);
});
}
if (returnAction.type === AlertRedux.ALERT_DEFINITION_UNSUSPEND_ALL) {
adaptable.api.alertApi.internalApi
.getReactiveAlertDefinitions()
.forEach((alertDefinition) => {
if (!adaptable.api.internalApi
.getAlertService()
.isReactiveAlertActive(alertDefinition)) {
adaptable.api.internalApi
.getAlertService()
.createReactiveAlert(alertDefinition);
}
});
}
adaptable.updateColumnModelAndRefreshGrid();
let module = (adaptable.adaptableModules.get(ModuleConstants.AlertModuleId));
if (module) {
module.checkListenToCellDataChanged();
}
refreshScheduledAlertJobs(adaptable);
return returnAction;
}
case FlashingCellRedux.FLASHING_CELL_DEFINITION_ADD:
case FlashingCellRedux.FLASHING_CELL_DEFINITION_EDIT:
case FlashingCellRedux.FLASHING_CELL_DEFINITION_DELETE:
case FlashingCellRedux.FLASHING_CELL_DEFINITION_UNSUSPEND:
case FlashingCellRedux.FLASHING_CELL_DEFINITION_SUSPEND:
case FlashingCellRedux.FLASHING_CELL_DEFINITION_UNSUSPEND_ALL:
case FlashingCellRedux.FLASHING_CELL_DEFINITION_SUSPEND_ALL: {
const returnAction = next(action);
adaptable.updateColumnModelAndRefreshGrid();
let module = (adaptable.adaptableModules.get(ModuleConstants.FlashingCellModuleId));
if (module) {
module.checkListenToCellDataChanged();
}
return returnAction;
}
case FreeTextColumnRedux.FREE_TEXT_COLUMN_ADD:
case FreeTextColumnRedux.FREE_TEXT_COLUMN_EDIT:
case FreeTextColumnRedux.FREE_TEXT_COLUMN_DELETE: {
if (action.type === FreeTextColumnRedux.FREE_TEXT_COLUMN_DELETE) {
const actionTyped = action;
if (!adaptable.api.freeTextColumnApi.internalApi.validateDeletedFreeTextColumn(actionTyped.freeTextColumn)) {
return;
}
}
const returnAction = next(action);
let module = (adaptable.adaptableModules.get(ModuleConstants.FreeTextColumnModuleId));
if (module) {
module.checkListenToCellDataChanged();
}
adaptable.api.layoutApi.internalApi.refreshLayout();
return returnAction;
}
case CalculatedColumnRedux.CALCULATED_COLUMN_ADD:
case CalculatedColumnRedux.CALCULATED_COLUMN_EDIT:
case CalculatedColumnRedux.CALCULATED_COLUMN_DELETE: {
const actionTypedCC = action;
const calculatedColumn = actionTypedCC.calculatedColumn;
if (action.type === CalculatedColumnRedux.CALCULATED_COLUMN_DELETE) {
if (!adaptable.api.calculatedColumnApi.internalApi.validateDeletedCalculatedColumn(calculatedColumn)) {
return;
}
}
const returnAction = next(action);
if (action.type === CalculatedColumnRedux.CALCULATED_COLUMN_ADD ||
action.type === CalculatedColumnRedux.CALCULATED_COLUMN_EDIT) {
adaptable.api.internalApi
.getCalculatedColumnExpressionService()
.createAggregatedScalarLiveValue(calculatedColumn);
}
else {
adaptable.api.internalApi
.getCalculatedColumnExpressionService()
.destroyAggregatedScalarLiveValue(calculatedColumn);
}
adaptable.api.eventApi.internalApi.fireCalculatedColumnChangedEvent(action.type, calculatedColumn);
let module = (adaptable.adaptableModules.get(ModuleConstants.CalculatedColumnModuleId));
if (module) {
module.checkListenToCellDataChanged();
}
adaptable.api.layoutApi.internalApi.refreshLayout();
return returnAction;
}
case QuickSearchRedux.QUICK_SEARCH_SET_CELL_MATCHING_STYLE:
case QuickSearchRedux.QUICK_SEARCH_SET_TEXT_MATCHING_STYLE:
case QuickSearchRedux.QUICK_SEARCH_SET_CURRENT_TEXT_MATCHING_STYLE: {
const returnAction = next(action);
adaptable.applyQuickSearchFindCssVars();
if (StringExtensions.IsNotNullOrEmpty(adaptable.api.quickSearchApi.getQuickSearchValue())) {
adaptable.refreshAgGridFind();
}
adaptable.updateColumnModelAndRefreshGrid();
return returnAction;
}
case FormatColumnRedux.FORMAT_COLUMN_ADD_BATCH:
case FormatColumnRedux.FORMAT_COLUMN_ADD:
case FormatColumnRedux.FORMAT_COLUMN_EDIT:
case FormatColumnRedux.FORMAT_COLUMN_DELETE:
case FormatColumnRedux.FORMAT_COLUMN_DELETE_ALL:
case FormatColumnRedux.FORMAT_COLUMN_MOVE_DOWN:
case FormatColumnRedux.FORMAT_COLUMN_MOVE_UP:
case FormatColumnRedux.FORMAT_COLUMN_SUSPEND:
case FormatColumnRedux.FORMAT_COLUMN_UNSUSPEND:
case FormatColumnRedux.FORMAT_COLUMN_SUSPEND_ALL:
case FormatColumnRedux.FORMAT_COLUMN_UNSUSPEND_ALL:
case StyledColumnRedux.STYLED_COLUMN_ADD:
case StyledColumnRedux.STYLED_COLUMN_EDIT:
case StyledColumnRedux.STYLED_COLUMN_DELETE:
case StyledColumnRedux.STYLED_COLUMN_SUSPEND:
case StyledColumnRedux.STYLED_COLUMN_UNSUSPEND:
case StyledColumnRedux.STYLED_COLUMN_SUSPEND_ALL:
case StyledColumnRedux.STYLED_COLUMN_UNSUSPEND_ALL:
case CustomSortRedux.CUSTOM_SORT_ADD:
case CustomSortRedux.CUSTOM_SORT_EDIT:
case CustomSortRedux.CUSTOM_SORT_DELETE:
case CustomSortRedux.CUSTOM_SORT_SUSPEND:
case CustomSortRedux.CUSTOM_SORT_UNSUSPEND:
case CustomSortRedux.CUSTOM_SORT_SUSPEND_ALL:
case CustomSortRedux.CUSTOM_SORT_UNSUSPEND_ALL: {
const returnAction = next(action);
adaptable.updateColumnModelAndRefreshGrid();
return returnAction;
}
case QuickSearchRedux.QUICK_SEARCH_RUN: {
let returnAction = next(action);
const actionTyped = action;
const searchText = actionTyped.quickSearchText;
adaptable.setAgGridFindSearchValue(searchText);
adaptable.api.gridApi.refreshAllCells(true);
if (adaptable.adaptableOptions.quickSearchOptions.filterGridAfterQuickSearch) {
if (StringExtensions.IsNotNullOrEmpty(searchText)) {
adaptable.setAgGridQuickSearch(searchText);
}
else {
adaptable.clearAgGridQuickSearch();
}
}
return returnAction;
}
case InternalRedux.ALERT_DELETE: {
const actionTyped = action;
let ret = next(action);
const adaptableAlert = actionTyped.alert;
if (getRuleAlertProperties(adaptableAlert.alertDefinition)?.HighlightCell &&
isAdaptableCellChangedAlert(adaptableAlert) &&
adaptableAlert.cellDataChangedInfo) {
const rowNode = adaptableAlert.cellDataChangedInfo.rowNode;
adaptable.api.gridApi.refreshCell(rowNode, adaptableAlert.cellDataChangedInfo.column.columnId, true);
}
if (getRuleAlertProperties(adaptableAlert.alertDefinition)?.HighlightRow &&
isAdaptableRowChangedAlert(adaptableAlert) &&
adaptableAlert.rowDataChangedInfo) {
adaptable.api.gridApi.refreshRowNodes(adaptableAlert.rowDataChangedInfo.rowNodes);
}
return ret;
}
case InternalRedux.ALERT_DELETE_ALL: {
const actionTyped = action;
let ret = next(action);
let alerts = actionTyped.alerts;
alerts.forEach((alert) => {
if (getRuleAlertProperties(alert.alertDefinition)?.HighlightCell &&
isAdaptableCellChangedAlert(alert) &&
alert.cellDataChangedInfo) {
let rowNode = alert.cellDataChangedInfo.rowNode;
adaptable.api.gridApi.refreshCell(rowNode, alert.cellDataChangedInfo.column.columnId, true);
}
if (getRuleAlertProperties(alert.alertDefinition)?.HighlightRow &&
isAdaptableRowChangedAlert(alert) &&
alert.rowDataChangedInfo) {
adaptable.api.gridApi.refreshRowNodes(alert.rowDataChangedInfo.rowNodes);
}
});
return ret;
}
case InternalRedux.ALERT_REMOVE_CELL_HIGHLIGHT: {
let ret = next(action);
const actionTyped = action;
const adaptableAlert = actionTyped.alert;
if (getRuleAlertProperties(adaptableAlert.alertDefinition)?.HighlightCell) {
if (isAdaptableCellChangedAlert(adaptableAlert) &&
adaptableAlert.cellDataChangedInfo) {
const rowNode = adaptableAlert.cellDataChangedInfo.rowNode;
adaptable.api.gridApi.refreshCell(rowNode, adaptableAlert.cellDataChangedInfo.column.columnId, true);
}
}
return ret;
}
case InternalRedux.ALERT_REMOVE_ROW_HIGHLIGHT: {
let ret = next(action);
const actionTyped = action;
const adaptableAlert = actionTyped.alert;
if (getRuleAlertProperties(adaptableAlert.alertDefinition)?.HighlightRow) {
if (isAdaptableCellChangedAlert(adaptableAlert) &&
adaptableAlert.cellDataChangedInfo) {
adaptable.api.gridApi.refreshRowNodes([adaptableAlert.cellDataChangedInfo.rowNode]);
}
if (isAdaptableRowChangedAlert(adaptableAlert) && adaptableAlert.rowDataChangedInfo) {
adaptable.api.gridApi.refreshRowNodes(adaptableAlert.rowDataChangedInfo.rowNodes);
}
}
return ret;
}
case InternalRedux.HIGHLIGHT_CELL_ADD: {
const actionTyped = action;
const ret = next(action);
const cellHighlightInfo = actionTyped.cellHighlightInfo;
const rowNode = adaptable.api.gridApi.getRowNodeForPrimaryKey(cellHighlightInfo.primaryKeyValue);
if (rowNode) {
adaptable.api.gridApi.refreshCell(rowNode, cellHighlightInfo.columnId, true);
}
return ret;
}
case InternalRedux.HIGHLIGHT_CELL_DELETE: {
const actionTyped = action;
const ret = next(action);
const rowNode = adaptable.api.gridApi.getRowNodeForPrimaryKey(actionTyped.primaryKeyValue);
if (rowNode) {
adaptable.api.gridApi.refreshCell(rowNode, actionTyped.columnId, true);
}
return ret;
}
case InternalRedux.HIGHLIGHT_CELL_DELETE_ALL: {
const cellHighlightInfos = middlewareAPI.getState().Internal.CellHighlightInfo;
const ret = next(action);
cellHighlightInfos.forEach((cellHighlightInfo) => {
const rowNode = adaptable.api.gridApi.getRowNodeForPrimaryKey(cellHighlightInfo.primaryKeyValue);
if (!rowNode) {
return;
}
adaptable.api.gridApi.refreshCell(rowNode, cellHighlightInfo.columnId, true);
});
return ret;
}
case InternalRedux.HIGHLIGHT_COLUMN_ADD: {
const actionTyped = action;
const ret = next(action);
const columnHighlightInfo = actionTyped.columnHighlightInfo;
adaptable.api.gridApi.refreshColumn(columnHighlightInfo.columnId);
return ret;
}
case InternalRedux.HIGHLIGHT_COLUMN_DELETE: {
const actionTyped = action;
const ret = next(action);
adaptable.api.gridApi.refreshColumn(actionTyped.columnId);
return ret;
}
case InternalRedux.HIGHLIGHT_COLUMN_DELETE_ALL: {
const columnHighlightInfos = middlewareAPI.getState().Internal.ColumnHighlightInfo;
const ret = next(action);
columnHighlightInfos.forEach((columnHighlightInfo) => {
adaptable.api.gridApi.refreshColumn(columnHighlightInfo.columnId);
});
return ret;
}
case InternalRedux.HIGHLIGHT_ROW_ADD: {
const actionTyped = action;
const ret = next(action);
const rowHighlightInfo = actionTyped.rowHighlightInfo;
const rowNode = adaptable.api.gridApi.getRowNodeForPrimaryKey(rowHighlightInfo.primaryKeyValue);
if (rowNode) {
adaptable.api.gridApi.refreshRowNode(rowNode);
}
return ret;
}
case InternalRedux.HIGHLIGHT_ROW_DELETE: {
const actionTyped = action;
const ret = next(action);
const rowNode = adaptable.api.gridApi.getRowNodeForPrimaryKey(actionTyped.primaryKeyValue);
if (rowNode) {
adaptable.api.gridApi.refreshRowNode(rowNode);
}
return ret;
}
case InternalRedux.HIGHLIGHT_ROWS_ADD: {
const actionTyped = action;
const ret = next(action);
const rowsHighlightInfo = actionTyped.rowsHighlightInfo;
const rowNodes = adaptable.api.gridApi.getRowNodesForPrimaryKeys(rowsHighlightInfo.primaryKeyValues);
if (rowNodes.length) {
adaptable.api.gridApi.refreshRowNodes(rowNodes);
}
return ret;
}
case InternalRedux.HIGHLIGHT_ROWS_DELETE: {
const actionTyped = action;
const ret = next(action);
const rowNodes = adaptable.api.gridApi.getRowNodesForPrimaryKeys(actionTyped.primaryKeyValues);
if (rowNodes.length) {
adaptable.api.gridApi.refreshRowNodes(rowNodes);
}
return ret;
}
case InternalRedux.HIGHLIGHT_ROW_DELETE_ALL: {
const rowHighlightInfos = middlewareAPI.getState().Internal.RowHighlightInfo;
const ret = next(action);
rowHighlightInfos.forEach((rowHighlightInfo) => {
const rowNode = adaptable.api.gridApi.getRowNodeForPrimaryKey(rowHighlightInfo.primaryKeyValue);
if (!rowNode) {
return;
}
adaptable.api.gridApi.refreshRowNode(rowNode);
});
return ret;
}
case InternalRedux.DATA_CHANGE_HISTORY_UNDO:
const actionTypedUndo = action;
const cellDataChangedInfo = actionTypedUndo.changeInfo;
adaptable.api.gridApi.undoCellEdit(cellDataChangedInfo);
return next(action);
case InternalRedux.DATA_CHANGE_HISTORY_ENABLE:
case InternalRedux.DATA_CHANGE_HISTORY_DISABLE:
case InternalRedux.DATA_CHANGE_HISTORY_SUSPEND:
case InternalRedux.DATA_CHANGE_HISTORY_RESUME:
const returnAction = next(action);
let module = (adaptable.adaptableModules.get(ModuleConstants.DataChangeHistoryModuleId));
if (module) {
module.checkListenToCellDataChanged();
}
return returnAction;
case InternalRedux.CREATE_CELL_SUMMARY_INFO: {
let module = (adaptable.adaptableModules.get(ModuleConstants.CellSummaryModuleId));
let returnAction = next(action);
let selectedCellInfo = middlewareAPI.getState().Internal.SelectedCellInfo;
let apiSummaryReturn = module.createCellSummaryInfo(selectedCellInfo);
adaptable.api.internalApi.setCellSummaryInfo(apiSummaryReturn);
return returnAction;
}
case InternalRedux.DATA_SET_SELECT: {
let returnAction = next(action);
const dataSet = adaptable.api.dataSetApi.getCurrentDataSet();
if (dataSet) {
adaptable.api.dataSetApi.internalApi.handleDataSetSelected(dataSet);
requestAnimationFrame(() => {
adaptable.api.dataSetApi.internalApi.showDataSetForm(dataSet);
});
}
return returnAction;
}
case ThemeRedux.THEME_SELECT: {
let returnAction = next(action);
adaptable.api.themeApi.applyCurrentTheme();
return returnAction;
}
case NoteRedux.NOTE_ADD:
case NoteRedux.NOTE_EDIT:
case NoteRedux.NOTE_DELETE: {
let returnAction = next(action);
adaptable.AnnotationsService.checkListenToEvents();
const rowNode = adaptable.api.gridApi.getRowNodeForPrimaryKey(returnAction.adaptableNote.PrimaryKeyValue);
adaptable.api.gridApi.refreshCell(rowNode, returnAction.adaptableNote.ColumnId, true);
return returnAction;
}
case CommentsRedux.COMMENT_ADD:
case CommentsRedux.COMMENT_EDIT:
case CommentsRedux.COMMENT_DELETE:
case CommentsRedux.COMMENT_THREAD_DELETE:
case CommentsRedux.COMMENT_THREAD_ADD: {
let returnAction = next(action);
adaptable.AnnotationsService.checkListenToEvents();
let rowNode = null;
let columnId = null;
if ('cellAddress' in returnAction) {
rowNode = adaptable.api.gridApi.getRowNodeForPrimaryKey(returnAction.cellAddress.PrimaryKeyValue);
columnId = returnAction.cellAddress.ColumnId;
}
else if ('cellComments' in returnAction) {
rowNode = adaptable.api.gridApi.getRowNodeForPrimaryKey(returnAction.cellComments.PrimaryKeyValue);
columnId = returnAction.cellComments.ColumnId;
}
if (rowNode && columnId) {
adaptable.api.gridApi.refreshCell(rowNode, columnId, true);
requestAnimationFrame(() => {
const commentThreads = adaptable.api.commentApi.getAllComments();
adaptable.api.eventApi.emit('CommentChanged', commentThreads);
adaptable.api.optionsApi
.getCommentOptions()
?.persistCommentThreads?.(commentThreads);
});
}
return returnAction;
}
case CommentsRedux.COMMENTS_THREADS_LOAD: {
const previousCommentThreads = adaptable.api.commentApi.getAllComments();
let returnAction = next(action);
const newCommentThreads = adaptable.api.commentApi.getAllComments() ?? [];
requestAnimationFrame(() => {
let addedCommentThreads = [];
let deletedCommentThreads = [];
const prevCommentThreadsSet = new Set((previousCommentThreads ?? []).map((c) => c.Uuid));
const newCommentThreadsSet = new Set((newCommentThreads ?? []).map((c) => c.Uuid));
for (const commentThread of newCommentThreads) {
if (!prevCommentThreadsSet.has(commentThread.Uuid)) {
addedCommentThreads.push(commentThread);
}
}
for (const commentThread of previousCommentThreads) {
if (!newCommentThreadsSet.has(commentThread.Uuid)) {
deletedCommentThreads.push(commentThread);
}
}
[...addedCommentThreads, ...deletedCommentThreads].forEach((commentThread) => {
const node = adaptable.api.gridApi.getRowNodeForPrimaryKey(commentThread.PrimaryKeyValue);
if (node && commentThread.ColumnId) {
adaptable.api.gridApi.refreshCell(node, commentThread.ColumnId, true);
}
});
});
return returnAction;
}
case ExportRedux.EXPORT_ENSURE_SCHEDULE_UUIDS:
case ExportRedux.SCHEDULED_REPORT_ADD:
case ExportRedux.SCHEDULED_REPORT_EDIT:
case ExportRedux.SCHEDULED_REPORT_DELETE:
case ExportRedux.SCHEDULED_REPORT_SUSPEND:
case ExportRedux.SCHEDULED_REPORT_UNSUSPEND: {
const returnAction = next(action);
refreshScheduledReportJobs(adaptable);
return returnAction;
}
case UserInterfaceRedux.USER_INTERFACE_SET_HIDE_ADAPTABLE_UI: {
const returnAction = next(action);
const { hideAdaptableUI } = action;
middlewareAPI.dispatch(DashboardRedux.DashboardSetIsHidden(hideAdaptableUI));
if (hideAdaptableUI) {
adaptable.hideAdaptableToolPanel();
}
else {
adaptable.showAdaptableToolPanel();
}
if (hideAdaptableUI) {
adaptable.hideAdaptableStatusBar();
}
else {
adaptable.showAdaptableStatusBar();
}
return returnAction;
}
case DashboardRedux.DASHBOARD_SET_IS_COLLAPSED:
case DashboardRedux.DASHBOARD_SET_MODULE_BUTTONS:
case DashboardRedux.DASHBOARD_ACTIVE_TAB_INDEX_CHANGE:
case DashboardRedux.DASHBOARD_SET_IS_FLOATING:
case DashboardRedux.DASHBOARD_SET_IS_HIDDEN:
case DashboardRedux.DASHBOARD_SET_FLOATING_POSITION:
case DashboardRedux.DASHBOARD_SET_TABS:
case DashboardRedux.DASHBOARD_CLOSE_TOOLBAR: {
const oldDashboardState = middlewareAPI.getState().Dashboard;
let returnAction = next(action);
const newDashboardState = middlewareAPI.getState().Dashboard;
adaptable.api.eventApi.internalApi.fireDashboardChangedEvent(action.type, oldDashboardState, newDashboardState);
return returnAction;
}
case LayoutRedux.LAYOUT_ADD:
case LayoutRedux.LAYOUT_EDIT:
case LayoutRedux.LAYOUT_SAVE:
case LayoutRedux.LAYOUT_DELETE:
case LayoutRedux.LAYOUT_SELECT: {
const oldLayoutState = middlewareAPI.getState().Layout;
const previousLayout = adaptable.api.layoutApi.getCurrentLayout();
let returnAction = next(action);
const newLayoutState = middlewareAPI.getState().Layout;
adaptable.api.eventApi.internalApi.fireLayoutChangedEvent(action.type, oldLayoutState, newLayoutState);
const oldLayout = (oldLayoutState.Layouts || []).find((l) => l.Name == oldLayoutState.CurrentLayout) || ERROR_LAYOUT;
const newLayout = (newLayoutState.Layouts || []).find((l) => l.Name == newLayoutState.CurrentLayout) ||
newLayoutState.Layouts[0] ||
ERROR_LAYOUT;
if (returnAction.type == LayoutRedux.LAYOUT_SELECT ||
returnAction.type == LayoutRedux.LAYOUT_DELETE) {
if (newLayout) {
adaptable.updateLayoutInManagerAfterStoreHasChanged(newLayout);
}
}
let refreshColumnFilters = false;
if (adaptable.api.filterApi.columnFilterApi.internalApi.areColumnFiltersDifferent(oldLayout.ColumnFilters, newLayout.ColumnFilters)) {
refreshColumnFilters = true;
}
let refreshGridFilter = false;
if (adaptable.api.filterApi.gridFilterApi.internalApi.isGridFilterDifferent(oldLayout.GridFilter, newLayout.GridFilter)) {
refreshGridFilter = true;
}
if (refreshColumnFilters || refreshGridFilter) {
adaptable.applyFiltering({ updateColumnFilterModel: refreshColumnFilters });
}
if (returnAction.type == LayoutRedux.LAYOUT_SAVE) {
const savingLayout = returnAction.layout;
if (previousLayout.Name === savingLayout.Name &&
previousLayout !== savingLayout &&
!adaptable.api.layoutApi.internalApi.areLayoutsEqual(previousLayout, savingLayout)) {
adaptable.updateLayoutInManagerAfterStoreHasChanged(savingLayout);
}
}
return returnAction;
}
case LayoutRedux.LAYOUT_COLUMN_FILTER_ADD:
case LayoutRedux.LAYOUT_COLUMN_FILTER_EDIT:
case LayoutRedux.LAYOUT_COLUMN_FILTER_SET:
case LayoutRedux.LAYOUT_COLUMN_FILTER_CLEAR:
case LayoutRedux.LAYOUT_COLUMN_FILTER_CLEAR_ALL:
case LayoutRedux.LAYOUT_COLUMN_FILTER_SUSPEND:
case LayoutRedux.LAYOUT_COLUMN_FILTER_SUSPEND_ALL:
case LayoutRedux.LAYOUT_COLUMN_FILTER_UNSUSPEND:
case LayoutRedux.LAYOUT_COLUMN_FILTER_UNSUSPEND_ALL: {
let returnAction;
const shouldTriggerColumnFiltering = adaptable.api.filterApi.columnFilterApi.internalApi.shouldNewColumnFilterTriggerColumnFiltering(action);
const oldLayoutState = middlewareAPI.getState().Layout;
returnAction = next(action);
adaptable.silentUpdateCurrentLayoutModel();
if (shouldTriggerColumnFiltering) {
setTimeout(() => {
adaptable.applyF