<commit_before>const coreApp = require('kolibri');
const logging = require('kolibri.lib.logging');

const ClassroomResource = coreApp.resources.ClassroomResource;
const FacilityUserResource = coreApp.resources.FacilityUserResource;
const TaskResource = coreApp.resources.TaskResource;
const RoleResource = coreApp.resources.RoleResource;

const coreActions = require('kolibri.coreVue.vuex.actions');
const ConditionalPromise = require('kolibri.lib.conditionalPromise');
const constants = require('./state/constants');
const UserKinds = require('kolibri.coreVue.vuex.constants').UserKinds;
const PageNames = constants.PageNames;
const ContentWizardPages = constants.ContentWizardPages;
const samePageCheckGenerator = require('kolibri.coreVue.vuex.actions').samePageCheckGenerator;


/**
 * Vuex State Mappers
 *
 * The methods below help map data from
 * the API to state in the Vuex store
 */
function _classState(data) {
  const state = {
    id: data.id,
    name: data.name,
  };
  return state;
}


function _userState(apiUserData) {
  function calcUserKind() {
    if (apiUserData.roles) {
      // array of strings, where each string represents a role object
      const roleKinds = apiUserData.roles.map((roleObj) => roleObj.kind);
      if (roleKinds.includes(UserKinds.ADMIN || UserKinds.SUPERUSER)) {
        return UserKinds.ADMIN;
      } else if (roleKinds.includes(UserKinds.COACH)) {
        return UserKinds.COACH;
      }
    }
    return UserKinds.LEARNER;
  }

  return {
    id: apiUserData.id,
    facility_id: apiUserData.facility,
    username: apiUserData.username,
    full_name: apiUserData.full_name,
    kind: calcUserKind(apiUserData.roles),
  };
}


function _taskState(data) {
  const state = {
    id: data.id,
    type: data.type,
    status: data.status,
    metadata: data.metadata,
    percentage: data.percentage,
  };
  return state;
}

/**
 * Title Helper
 */

function _managePageTitle(title) {
  return `Manage ${title}`;
}


/**
 * Actions
 *
 * These methods are used to update client-side state
 */


// ================================
// CLASSES MANAGEMENT ACTIONS

/**
 * Do a POST to create new class
 * @param {object} stateClassData
 *  Needed: name
 */
function createClass(store, stateClassData) {
  const classData = {
    name: stateClassData.name,
  };

  return new Promise((resolve, reject) => {
    ClassroomResource.createModel(classData).save().then(
      (classModel) => {
        resolve(classModel);
      },
      (error) => reject(error)
    );
  }).then(
    // dispatch newly created class
    newClass => store.dispatch('ADD_CLASS', _classState(newClass)),
    // send back error if necessary
    error => Promise.reject(error)
  );
}

/**
 * Do a DELETE to delete the class.
 * @param {string or Integer} id
 */
function deleteClass(store, id) {
  if (!id) {
    // if no id passed, abort the function
    return;
  }
  ClassroomResource.getModel(id).delete().then(
    cl => { store.dispatch('DELETE_CLASS', id); },
    error => { coreActions.handleApiError(store, error); }
  );
}

function showClassesPage(store) {
  store.dispatch('SET_PAGE_NAME', PageNames.CLASS_MGMT_PAGE);
  // need to replace the following with real logic for grabbing data from server-side.
  store.dispatch('SET_PAGE_STATE', { classes: [{
    name: 'lalaland',
    id: 1323,
    learners: 33,
    coaches: 4,
    admins: 0,
  }] });
  store.dispatch('CORE_SET_PAGE_LOADING', false);
  store.dispatch('CORE_SET_ERROR', null);
  store.dispatch('CORE_SET_TITLE', _managePageTitle('Classes'));
}

function showClassEditPage(store, classId) {
  store.dispatch('SET_PAGE_NAME', PageNames.CLASS_EDIT_MGMT_PAGE);
  // need to replace the following with real logic for grabbing data from server-side.
  store.dispatch('SET_PAGE_STATE', { classId });
  store.dispatch('CORE_SET_PAGE_LOADING', false);
  store.dispatch('CORE_SET_ERROR', null);
  store.dispatch('CORE_SET_TITLE', _managePageTitle('Classes'));
}

function showClassEnrollPage(store, classId) {
  store.dispatch('SET_PAGE_NAME', PageNames.CLASS_ENROLL_MGMT_PAGE);
  // need to replace the following with real logic for grabbing data from server-side.
  store.dispatch('SET_PAGE_STATE', { classId });
  store.dispatch('CORE_SET_PAGE_LOADING', false);
  store.dispatch('CORE_SET_ERROR', null);
  store.dispatch('CORE_SET_TITLE', _managePageTitle('Classes'));
}


// ================================
// USERS MANAGEMENT ACTIONS

/**
 * Does a POST request to assign a user role (only used in this file)
 * @param {object} user<commit_msg>replace mock class data with real data<commit_after>const coreApp = require('kolibri');
const logging = require('kolibri.lib.logging');

const ClassroomResource = coreApp.resources.ClassroomResource;
const FacilityUserResource = coreApp.resources.FacilityUserResource;
const TaskResource = coreApp.resources.TaskResource;
const RoleResource = coreApp.resources.RoleResource;

const coreActions = require('kolibri.coreVue.vuex.actions');
const ConditionalPromise = require('kolibri.lib.conditionalPromise');
const constants = require('./state/constants');
const UserKinds = require('kolibri.coreVue.vuex.constants').UserKinds;
const PageNames = constants.PageNames;
const ContentWizardPages = constants.ContentWizardPages;
const samePageCheckGenerator = require('kolibri.coreVue.vuex.actions').samePageCheckGenerator;


/**
 * Vuex State Mappers
 *
 * The methods below help map data from
 * the API to state in the Vuex store
 */
function _classState(data) {
  const state = {
    id: data.id,
    name: data.name,
  };
  return state;
}


function _userState(apiUserData) {
  function calcUserKind() {
    if (apiUserData.roles) {
      // array of strings, where each string represents a role object
      const roleKinds = apiUserData.roles.map((roleObj) => roleObj.kind);
      if (roleKinds.includes(UserKinds.ADMIN || UserKinds.SUPERUSER)) {
        return UserKinds.ADMIN;
      } else if (roleKinds.includes(UserKinds.COACH)) {
        return UserKinds.COACH;
      }
    }
    return UserKinds.LEARNER;
  }

  return {
    id: apiUserData.id,
    facility_id: apiUserData.facility,
    username: apiUserData.username,
    full_name: apiUserData.full_name,
    kind: calcUserKind(apiUserData.roles),
  };
}


function _taskState(data) {
  const state = {
    id: data.id,
    type: data.type,
    status: data.status,
    metadata: data.metadata,
    percentage: data.percentage,
  };
  return state;
}

/**
 * Title Helper
 */

function _managePageTitle(title) {
  return `Manage ${title}`;
}


/**
 * Actions
 *
 * These methods are used to update client-side state
 */


// ================================
// CLASSES MANAGEMENT ACTIONS

/**
 * Do a POST to create new class
 * @param {object} stateClassData
 *  Needed: name
 */
function createClass(store, stateClassData) {
  const classData = {
    name: stateClassData.name,
    parent: stateClassData.facilityId,
  };

  return new Promise((resolve, reject) => {
    ClassroomResource.createModel(classData).save().then(
      (classModel) => {
        resolve(classModel);
      },
      (error) => reject(error)
    );
  }).then(
    // dispatch newly created class
    newClass => store.dispatch('ADD_CLASS', _classState(newClass)),
    // send back error if necessary
    error => Promise.reject(error)
  );
}

/**
 * Do a DELETE to delete the class.
 * @param {string or Integer} id
 */
function deleteClass(store, id) {
  if (!id) {
    // if no id passed, abort the function
    return;
  }
  ClassroomResource.getModel(id).delete().then(
    cl => { store.dispatch('DELETE_CLASS', id); },
    error => { coreActions.handleApiError(store, error); }
  );
}

function showClassesPage(store) {
  store.dispatch('CORE_SET_PAGE_LOADING', true);
  store.dispatch('SET_PAGE_NAME', PageNames.CLASS_MGMT_PAGE);
  const classCollection = ClassroomResource.getCollection();
  const facilityIdPromise = FacilityUserResource.getCurrentFacility();
  const classPromise = classCollection.fetch({}, true);

  const promises = [facilityIdPromise, classPromise];

  ConditionalPromise.all(promises).only(
    samePageCheckGenerator(store),
    ([facilityId, classes]) => {
      store.dispatch('SET_FACILITY', facilityId[0]); // for mvp, we assume only one facility exists

      const pageState = {
        classes: classes.map(_classState),
      };

      store.dispatch('SET_PAGE_STATE', pageState);
      store.dispatch('CORE_SET_PAGE_LOADING', false);
      store.dispatch('CORE_SET_ERROR', null);
      store.dispatch('CORE_SET_TITLE', _managePageTitle('Classes'));
    },
    error => { coreActions.handleApiError(store, error); }
  );
}

function showClassEditPage(store, classId) {
  store.dispatch('SET_PAGE_NAME', PageNames.CLASS_EDIT_MGMT_PAGE);
  // need to replace the following with real logic for grabbing data from server-side.
  store.dispatch('SET_PAGE_STATE', { classId });
  store.dispatch('CORE_SET_PAGE_LOADING', false);
  store.dispatch('CORE_SET_ERROR', null);
  store.dispatch('CORE_SET_TITLE', _managePageTitle('Classes'));
}

function showClassEnrollPage(store, classId) {
  store.dispatch('SET_PAGE_NAME', PageNames.CLASS_ENROLL_MGMT_PAGE);
  // need to replace the following with real logic for grabbing data from server-side.
  store.dispatch('SET_PAGE_STATE', { classId });
  store.dispatch('CORE_SET_PAGE_LOADING', false);
  store.dispatch('CORE_SET_ERROR', null);
  store.dispatch('CORE_SET_TITLE', _managePageTitle('Classes'));
}


// ================================
// USERS MANAGEMENT ACTIONS

/**
 * Does a POST request to assign a user role (only used in this file)
 * @param {object} user
{'fraction_non_alphanumeric': 0.13513513513513514, 'fraction_numerical': 0.0009355509355509356, 'mean_word_length': 4.142169962586852, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5929070', 'n_tokens_mistral': 3020, 'n_tokens_neox': 2974, 'n_words': 675}