WikiEducationFoundation/WikiEduDashboard

View on GitHub
app/assets/javascripts/actions/training_actions.js

Summary

Maintainability
C
7 hrs
Test Coverage
D
68%
import { extend } from 'lodash-es';
import {
  RECEIVE_TRAINING_MODULE, MENU_TOGGLE, REVIEW_ANSWER,
  SET_CURRENT_SLIDE, RECEIVE_ALL_TRAINING_MODULES,
  EXERCISE_COMPLETION_UPDATE, SLIDE_COMPLETED, API_FAIL
} from '../constants';
import request from '../utils/request';
import logErrorMessage from '../utils/log_error_message';
import { stringify } from 'query-string';

const fetchAllTrainingModulesPromise = async () => {
  const response = await request('/training_modules.json');
  if (!response.ok) {
    logErrorMessage(response);
    const data = await response.text();
    response.responseText = data;
    throw response;
  }
  return response.json();
};

const fetchTrainingModulePromise = async (opts) => {
  const response = await request(`/training_module.json?module_id=${opts.module_id}`);
  if (!response.ok) {
    logErrorMessage(response);
    const data = await response.text();
    response.responseText = data;
    throw response;
  }
  return response.json();
};

const setSlideCompletedPromise = async (opts) => {
  const params = {
    module_id: opts.module_id,
    user_id: opts.user_id,
    slide_id: opts.slide_id
  };
  const response = await request(`/training_modules_users.json?${stringify(params)}`, {
    method: 'POST'
  });
  if (!response.ok) {
    logErrorMessage(response);
    const data = await response.text();
    response.responseText = data;
    throw response;
  }
  return response.json();
};

export const fetchAllTrainingModules = () => (dispatch) => {
  return fetchAllTrainingModulesPromise()
    .then(resp => dispatch({ type: RECEIVE_ALL_TRAINING_MODULES, data: resp }))
    .catch(resp => dispatch({ type: API_FAIL, data: resp }));
};

export const fetchTrainingModule = (opts = {}) => (dispatch) => {
  return fetchTrainingModulePromise(opts)
    .then((resp) => {
      const valid = !!resp.training_module.slides.filter(o => o.slug === opts.slide_id).length;
      dispatch({ type: RECEIVE_TRAINING_MODULE, data: extend(resp, { slide: opts.slide_id, valid }) });

      if (valid && opts.user_id) {
        dispatch(setSlideCompleted(opts));
      }
    }).catch(resp => dispatch({ type: API_FAIL, data: resp }));
};

export const setSlideCompleted = opts => (dispatch, getState) => {
  // No need to ping the server if the module is already complete.
  if (getState().training.completed) { return; }

  return setSlideCompletedPromise(opts)
    .then(resp => dispatch({ type: SLIDE_COMPLETED, data: resp }))
    .catch(resp => dispatch({ type: API_FAIL, data: resp }));
};

const setExerciseModule = (complete = true) => (block_id, module_id) => (dispatch) => {
  return request('/training_modules_users/exercise.json', {
    body: JSON.stringify({ block_id, complete, module_id }),
    method: 'POST'
  }).then(resp => resp.json())
    .then(resp => dispatch({ type: EXERCISE_COMPLETION_UPDATE, data: resp }))
    .catch(resp => dispatch({ type: API_FAIL, data: resp }));
};

export const setExerciseModuleComplete = setExerciseModule();
export const setExerciseModuleIncomplete = setExerciseModule(false);

export const toggleMenuOpen = opts => (dispatch) => {
  return dispatch({
    type: MENU_TOGGLE,
    data: {
      currently: opts.currently
    }
  });
};

export const reviewAnswer = answer => (dispatch) => {
  return dispatch({
    type: REVIEW_ANSWER,
    data: {
      answer
    }
  });
};

export const setCurrentSlide = slideId => (dispatch) => {
  return dispatch({
    type: SET_CURRENT_SLIDE,
    data: {
      slide: slideId
    }
  });
};