sagas/common.js

/* eslint-disable sonarjs/cognitive-complexity */
import { takeLatest, put, select, call } from 'redux-saga/effects';

import { getFilterData } from '../selectors/common';
import { API_URLS, PAGES, MODALS, SUCCESS_MODALS } from '../constants';
import { requestGet, requestPost } from '../utils/request';
import { parseRoute } from '../utils/common';
import { aGetInitSuccess, aSetFilterData } from '../reducers/bonus';
import {
  aGetProfileInfoSuccess,
  aSetFilters,
  aSetIsFetched,
  aSetIsLoading,
  aSetOpenModal,
  aSetPaginationData,
} from '../reducers/common';
import { aChangeUserPWD, aGetInit, aGetProfileInfo, aSetPagination } from '../reducers/actions';
import { aSetExportSizeLimit } from '../reducers/exporter';

/**
 * @namespace sagas/common
 */
/**
 * Set new filter
 *
 * @memberof sagas/common
 * @async
 * @param {object} action
 * @property {object} action
 * @property {object} action.payload
 * @property {number} action.payload.type
 * @returns {void}
 */
function* filter(action) {
  yield put(aSetFilterData(action.payload));
  action.payload.callback(action.payload.filter);
}

/**
 * Set new page for pagination
 *
 * @memberof sagas/common
 * @async
 * @param {object} action
 * @property {object} action
 * @property {object} action.payload
 * @property {number} action.payload.type
 * @returns {void}
 */
function* paging(action) {
  yield put(aSetPaginationData(action.payload));
  let filters = yield select(getFilterData);
  filters = { ...filters } || {};
  filters.page = action.payload.page;
  action.payload.callback(filters);
}

/**
 * @memberof sagas/common
 * @typedef User
 * @type {object}
 * @property {Array} permissions
 * @property {boolean} requireNewPassword
 * @property {Array} roles
 * @property {number} userId
 * @property {string} username
 */
/**
 * @memberof sagas/common
 * @typedef init/response.data
 * @type {object}
 * @property {User|null} user
 * @property {string} svgVersion
 * @property {string} currency
 * @property {string} cnt
 * @property {object} selects Data for all dropdowns in app
 */
/**
 * Check user session
 *
 * @param {object} action
 * @memberof sagas/common
 * @async
 */
function* init(action) {
  let response;
  try {
    response = yield call(requestGet, API_URLS.INIT, false);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      const { selectedMenu, selectedMenuItem, heading } = parseRoute(action.payload.location.pathname);
      let params = action.payload.location.search.split('?');
      params = params && params[1] && params[1].split('&');
      let tmp;
      let filters = null;
      if (params) {
        filters = {};
        params.map((x) => {
          tmp = x.split('=');
          if (tmp[0]) {
            if (tmp[1].includes('%2C')) {
              filters[tmp[0]] = tmp[1].split('%2C');
            } else {
              filters[tmp[0]] = tmp[1].replace(/\+/g, ' ').replace(/%3A/g, ':');
            }
          }
        });
      }
      if (!response.data.user) {
        action.payload.navigate(PAGES.LOGIN);
      }

      yield put(
        aGetInitSuccess({
          ...response.data,
          menu: selectedMenu,
          selectedMenuItem,
          heading,
          filters,
          settledCouponFilters: response.data.filters,
        })
      );

      yield put(
        aSetExportSizeLimit({
          exportSizeLimit: response.data.exportConfig.maxCouponRecordsAllowed,
        })
      );

      yield put(
        aSetIsLoading({
          isLoading: false,
        })
      );
    }
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}
/**
 * @memberof sagas/common
 * @typedef getProfileInfo/response.data
 * @type {object}
 * @property {string} email
 * @property {string} lastLogin
 * @property {string} name
 * @property {Array} roles
 * @property {string} username
 */
/**
 * Get User Profile info
 *
 * @memberof sagas/common
 * @async
 */
function* getProfileInfo() {
  let response;
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    response = yield call(requestGet, API_URLS.PROFILE_INFO, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aGetProfileInfoSuccess({
          profileInfo: { ...response.data },
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Change User Password
 *
 * @memberof sagas/common
 * @async
 * @param {object} action
 * @property {object} action
 * @property {object} action.payload
 * @property {string} action.oldPassword
 * @property {string} action.newPassword
 */
function* changePassword(action) {
  let response;
  try {
    yield put(aSetIsFetched({ isFetched: false }));
    response = yield call(requestPost, API_URLS.CHANGE_USER_PWD, action.payload, true);
    if (response.status === -1) {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    } else {
      yield put(
        aSetOpenModal({
          modal: MODALS.SUCCESS,
          modalData: {
            message: 'Password changed',
            additionalMessage: 'successfully',
            modal: SUCCESS_MODALS.CHANGE_USER_PWD,
          },
        })
      );
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * @memberof sagas/common
 * @async
 * @returns {void}
 */
export default function* commonSaga() {
  yield takeLatest(aSetFilters, filter);
  yield takeLatest(aSetPagination, paging);
  yield takeLatest(aGetInit, init);
  yield takeLatest(aGetProfileInfo, getProfileInfo);
  yield takeLatest(aChangeUserPWD, changePassword);
}