sagas/admin.js

import { takeEvery, call, put, select } from 'redux-saga/effects';

import { requestPost, requestGet } from '../utils/request';
import { API_URLS, MODALS, SUCCESS_MODALS } from '../constants';
import { getPagination, getUser } from '../selectors/common';
import { aSetUserList, aUserAddFailed } from '../reducers/admin';
import { aSetHasRecord, aSetIsFetched, aSetOpenModal, aSetUserData } from '../reducers/common';
import {
  aUserAdd,
  aUserEditInfo,
  aUserEditRoles,
  aUserEditStatus,
  aUserList,
  aUserRemove,
  aUserResetPass,
} from '../reducers/actions';

/**
 * @namespace sagas/admin
 */
/**
 * @memberof sagas/admin
 * @typedef User
 * @type {object}
 * @property {string} email
 * @property {string} insertionDate
 * @property {string} insertionUser
 * @property {string} lastLogin
 * @property {string} name
 * @property {Array} roles
 * @property {number} status
 * @property {number} userId
 * @property {string} username
 */
/**
 * @memberof sagas/admin
 * @typedef "userList/response.data"
 * @type {object}
 * @property {Array<User>} users
 * @property {object} meta
 */
/**
 * Fetch list of users
 *
 * @memberof sagas/admin
 * @async
 * @param {object} action Action params.
 */
function* userList(action) {
  const pagination = yield select(getPagination);

  const filters = action.payload || {};
  let params = `?pageSize=10&${new URLSearchParams(filters).toString()}`;
  const keys = Object.keys(filters);

  if (keys.length === 0 && pagination && pagination.page) {
    params += `&page=${pagination.page}`;
  }

  yield put(aSetIsFetched({ isFetched: false }));

  try {
    const response = yield call(requestGet, API_URLS.USER_LIST + params, true);
    if (response.status === 1) {
      yield put(
        aSetUserList({
          userList: response.data,
          meta: response.data.meta,
        })
      );

      yield put({
        type: aSetHasRecord.type,
        payload: {
          hasRecord: response.data.users.length > 0,
        },
      });
      yield put(aSetIsFetched({ isFetched: true }));
    } else {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    }
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Add new user
 *
 * @memberof sagas/admin
 * @async
 * @param {object} action Action info.
 */
function* userAdd(action) {
  yield put(aSetIsFetched({ isFetched: false }));
  try {
    const response = yield call(
      requestPost,
      API_URLS.USER_ADD,
      {
        username: action.payload.username,
        email: action.payload.email,
        name: action.payload.name,
        roleIds: action.payload.roleIds,
      },
      true
    );

    if (response.status === 1) {
      yield put(
        aSetOpenModal({
          modal: MODALS.SUCCESS,
          modalData: {
            message: 'User Added Successfully',
            additionalMessage: "Password sent to user's email",
            modal: SUCCESS_MODALS.ADD_USER,
          },
        })
      );
      yield put(aUserList());
    } else {
      yield put(
        aUserAddFailed({
          error: response.error.message,
        })
      );
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    }
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Remove user
 *
 * @memberof sagas/admin
 * @async
 * @param {object} action Action info.
 */
function* removeUser(action) {
  yield put(aSetIsFetched({ isFetched: false }));

  try {
    const response = yield call(requestPost, API_URLS.USER_REMOVE, action.payload, true);
    if (response.status === 1) {
      yield put(
        aSetOpenModal({
          modal: MODALS.SUCCESS,
          modalData: {
            message: 'Removed user',
            additionalMessage: 'successfully',
            modal: SUCCESS_MODALS.REMOVE_USER,
            user: action.payload,
          },
        })
      );

      yield put(aUserList());
    } else {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    }
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Reset User Password
 *
 * @memberof sagas/admin
 * @async
 * @param {object} action Action info.
 */
function* resetPassword(action) {
  yield put(aSetIsFetched({ isFetched: false }));
  try {
    const response = yield call(requestPost, API_URLS.USER_RESET_PASS, action.payload, true);
    if (response.status === 1) {
      yield put(
        aSetOpenModal({
          modal: MODALS.SUCCESS,
          modalData: {
            message: 'The new password for the user',
            additionalMessage: 'has been sent to',
            heading: 'Password Successfully Reset',
            email: true,
            user: action.payload,
            modal: SUCCESS_MODALS.RESET_PASSWORD,
          },
        })
      );
    } else {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    }
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Edit roles for user
 *
 * @memberof sagas/admin
 * @async
 * @param {object} action Action info.
 */
function* editUserRoles(action) {
  yield put(aSetIsFetched({ isFetched: false }));
  try {
    const response = yield call(
      requestPost,
      API_URLS.USER_EDIT_ROLES,
      {
        userId: action.payload.user.userId,
        roleIds: action.payload.roleIds,
      },
      true
    );
    if (response.status === 1) {
      yield put(
        aSetOpenModal({
          modal: MODALS.SUCCESS,
          modalData: {
            message: 'Roles has been changed for user',
            modal: SUCCESS_MODALS.EDIT_ROLES,
            user: action.payload.user,
            callback: action.payload.callback,
          },
        })
      );
    } else {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    }
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Edit status of user
 *
 * @memberof sagas/admin
 * @async
 * @param {object} action Action info.
 */
function* editUserStatus(action) {
  yield put(aSetIsFetched({ isFetched: false }));
  try {
    const response = yield call(
      requestPost,
      API_URLS.USER_EDIT_STATUS,
      {
        userId: action.payload.userId,
        status: action.payload.status,
      },
      true
    );
    if (response.status === 1) {
      yield put(
        aSetOpenModal({
          modal: MODALS.SUCCESS,
          modalData: {
            message: 'Status has been changed for user',
            modal: SUCCESS_MODALS.EDIT_STATUS,
            user: action.payload,
          },
        })
      );

      yield put(aUserList());
    } else {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    }
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Edit Information of user
 *
 * @memberof sagas/admin
 * @async
 * @param {object} action Action Info.
 */
function* editUserInfo(action) {
  yield put(aSetIsFetched({ isFetched: false }));
  try {
    const payloadUserData = {
      userId: action.payload.user.userId,
      name: action.payload.name,
      email: action.payload.email,
    };
    const response = yield call(requestPost, API_URLS.USER_EDIT_INFO, payloadUserData, true);
    if (response.status === 1) {
      yield put(
        aSetOpenModal({
          modal: MODALS.SUCCESS,
          modalData: {
            message: 'Info has been changed for user',
            modal: SUCCESS_MODALS.EDIT_INFO,
            user: action.payload.user,
          },
        })
      );

      const checkLoggedInUser = yield select(getUser);
      if (action.payload.user.userId === checkLoggedInUser.userId) {
        yield put({
          type: aSetUserData.type,
          payload: {
            user: { ...checkLoggedInUser, ...payloadUserData },
          },
        });
      }
      yield put(aUserList());
    } else {
      const e = new Error(response.error.message);
      e.modal = MODALS.ERROR;
      throw e;
    }
    yield put(aSetIsFetched({ isFetched: true }));
  } catch (error) {
    yield put(
      aSetOpenModal({
        modal: error.modal || MODALS.GENERAL_ERROR,
        errorMessage: error.modal ? error.message : MODALS.GENERAL_ERROR,
      })
    );
  }
}

/**
 * Admin Saga
 *
 * @memberof sagas/admin
 * @async
 */
export default function* adminSaga() {
  yield takeEvery(aUserList, userList);
  yield takeEvery(aUserAdd, userAdd);
  yield takeEvery(aUserRemove, removeUser);
  yield takeEvery(aUserResetPass, resetPassword);
  yield takeEvery(aUserEditRoles, editUserRoles);
  yield takeEvery(aUserEditStatus, editUserStatus);
  yield takeEvery(aUserEditInfo, editUserInfo);
}