import { combineEpics, Epic, ofType } from 'redux-observable'; import { forecastFetchCollectionFailure, forecastFetchCollectionRequest, forecastFetchCollectionSuccess, forecastSelectAggregation, forecastSetAggregations, forecastSetDetails, } from 'app/modules/forecast/store/forecast.actions'; import { FILTER_SET_POOL } from 'app/shared/store/filters/filters.types'; import { ROUTER } from 'app/common/routes'; import { ENTERED_FORECAST_PAGE } from 'app/common/store/router/router.constants'; import { resetAllFilters, setPoolFilter } from 'app/shared/store/filters/filters.actions'; import { catchError, filter, map, mergeMap } from 'rxjs/operators'; import { FORECAST } from 'app/modules/forecast/store/forecast.constants'; import { MiddlewareDependencies, PretypedEpic, StoreState } from 'app/common/store/store.types'; import { of } from 'rxjs'; const getSelectedForecastDetails = (selectedIndex: number, store: StoreState) => { const aggregations = store.forecast.aggregations; if (typeof(aggregations[selectedIndex]) === 'undefined') { return {}; } return aggregations[selectedIndex]; }; const updateForecastSelectedAggregationEpic: PretypedEpic = (action$, store) => action$.pipe( ofType(FORECAST.FORECAST_SET_AGGREGATIONS), map(() => { const aggregations = store.value.forecast.aggregations; const aggregationToSelect = aggregations.find((aggregation) => aggregation.type === FORECAST.TYPE_FORECAST); return forecastSelectAggregation(aggregationToSelect === undefined ? null : aggregationToSelect?.id); }), ); const updateForecastDetailsEpic: PretypedEpic = (action$, store) => action$.pipe( ofType(FORECAST.FORECAST_SELECT_AGGREGATION), map((selectedAggregation) => forecastSetDetails(getSelectedForecastDetails(selectedAggregation.payload, store.value))) ); const forecastFilterAggregationsEpic: Epic< { type: string, poolId: number }, any, StoreState, MiddlewareDependencies > = (action$) => action$.pipe( ofType(FILTER_SET_POOL), map((action) => forecastFetchCollectionRequest(action.poolId)), ); const updateForecastAggregationsEpic: PretypedEpic = (action$, store, { forecastService }) => action$.pipe( ofType(FORECAST.FETCH_COLLECTION_REQUEST), filter(() => ROUTER.lookup(store.value.router.location.pathname).name === 'forecastPoolRoute'), mergeMap((action) => forecastService.getForecast(action.payload)), map((aggregations) => [ forecastSetAggregations(aggregations), forecastFetchCollectionSuccess(), ]), catchError(() => of(forecastFetchCollectionFailure())), ); interface Action { type: string, payload?: any } const enteredForecastPageEpic: PretypedEpic<{ pool: number }> = (action$, store) => { return action$.pipe( ofType(ENTERED_FORECAST_PAGE), map((action:Action) => { let actions:Action[] = [ setPoolFilter(action.payload.pool), ]; if (store.value.filters.poolId !== action.payload.pool) { actions.push(resetAllFilters()); } return actions; })); }; export const forecastEpics = combineEpics( updateForecastDetailsEpic, forecastFilterAggregationsEpic, updateForecastAggregationsEpic, updateForecastSelectedAggregationEpic, enteredForecastPageEpic, );