import { Observable } from 'rxjs' import { combineEpics, ActionsObservable } from 'redux-observable' import { Store } from 'redux' import * as UserSelectors from '../auth/selectors' import * as actions from './actions' import * as selectors from './selectors' import * as AuthActions from '../auth/actions' import * as api from './api' import { IPlaybook } from './interfaces' const searchPlaybooks = (action$: ActionsObservable, { getState }: Store) => { return action$ .ofType(actions.searchPlaybooks.toString()) .mergeMap(() => { const accessToken = UserSelectors.accessToken(getState()) return api .searchPlaybooks({ accessToken }) .map((playbooks: any[]) => actions.searchPlaybooksSuccess(playbooks)) .startWith(actions.searchPlaybooksPending()) .catch(() => Observable.of(actions.searchPlaybooksFailed())) }) } const enroll = (action$: ActionsObservable, { getState }: Store) => { return action$ .ofType(actions.enroll.toString()) .pluck('payload') .filter(({ email, tabId }) => !selectors.enrollingEmail(getState(), { email, tabId })) .mergeMap(({ tabId, action, endUserId, email, playbookId }) => { const accessToken = UserSelectors.accessToken(getState()) return api .enroll({ action, accessToken, email, playbookId, endUserId }) .map(() => actions.enrollSuccess({ tabId, email })) .startWith(actions.enrollPending({ tabId, email })) .catch((request: any) => { return Observable.of(actions.enrollFailed({ email, tabId, error: request.xhr.response ? request.xhr.response.message : 'Something went wrong', })) }) }) } const fetchEnrolledSequenceCount = (action$: ActionsObservable, { getState }: Store) => { return action$ .ofType(actions.fetchEnrolledSequenceCount.toString()) .mergeMap(() => { const state = getState() const accessToken = UserSelectors.accessToken(state) return api .fetchEnrolledSequenceCount({ accessToken }) .map((count: number) => actions.fetchEnrolledSequenceCountSuccess(count)) .startWith(actions.fetchEnrolledSequenceCountPending()) .catch(error => Observable.of(actions.fetchEnrolledSequenceCountFailed(error))) }) } const fetchEnrolledSequenceCountFailed = (action$: ActionsObservable) => { return action$ .ofType(actions.fetchEnrolledSequenceCountFailed.toString()) .pluck('payload', 'status') .filter((status: number) => status === 403) .map(() => AuthActions.logout()) } const fetchPlaybookForEndUser = (action$: ActionsObservable, { getState }: Store) => { return action$ .ofType(actions.fetchPlaybookForEndUser.toString()) .pluck('payload') .mergeMap(({ tabId, email, playbookId }) => { const accessToken = UserSelectors.accessToken(getState()) return api .fetchPlaybookForEndUser({ playbookId, accessToken, email }) .map((playbook: IPlaybook) => actions.fetchPlaybookForEndUserSuccess({ playbook, tabId })) .startWith(actions.fetchPlaybookForEndUserPending({ tabId })) .catch(() => Observable.of(actions.fetchPlaybookForEndUserFailed({ tabId }))) }) } export const epic = combineEpics(enroll, searchPlaybooks, fetchEnrolledSequenceCount, fetchPlaybookForEndUser, fetchEnrolledSequenceCountFailed)