Skip to content

Commit

Permalink
feat: create the storage to manage the app state (#4)
Browse files Browse the repository at this point in the history
* feat: create the api conexion funtions

* feat: create the storage to manage the app state
  • Loading branch information
dcoa authored Aug 30, 2023
1 parent d4e0c5f commit 4ca0b6e
Show file tree
Hide file tree
Showing 10 changed files with 372 additions and 6 deletions.
37 changes: 37 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"@fortawesome/free-regular-svg-icons": "5.15.4",
"@fortawesome/free-solid-svg-icons": "5.15.4",
"@fortawesome/react-fontawesome": "0.2.0",
"@reduxjs/toolkit": "^1.9.5",
"core-js": "3.32.1",
"prop-types": "15.8.1",
"react": "17.0.2",
Expand All @@ -63,4 +64,4 @@
"husky": "7.0.4",
"jest": "29.6.2"
}
}
}
Empty file removed src/data/.gitkeep
Empty file.
4 changes: 0 additions & 4 deletions src/data/README.rst

This file was deleted.

107 changes: 107 additions & 0 deletions src/data/api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import {
camelCaseObject,
ensureConfig,
getConfig,
snakeCaseObject,
} from '@edx/frontend-platform';
import { getAuthenticatedHttpClient, getAuthenticatedUser } from '@edx/frontend-platform/auth';
import { VALIDATION_API_PATH } from './constants';

ensureConfig(['LMS_BASE_URL'], 'Validation Panel API');

export const getApiBaseUrl = () => getConfig().LMS_BASE_URL;
export const getCoursesApiUrl = () => `${getApiBaseUrl()}/api/courses/v1/courses/`;
export const getValidationApiUrl = (service) => `${getApiBaseUrl()}/plugin-cvw/api/v1/${service}/`;

/**
* Fetches all courses created by the current user (course author).
* @returns {Promise<[{}]>}
*/

export async function getCoursesByUser() {
const { data } = await getAuthenticatedHttpClient()
.get(getCoursesApiUrl(), {
params: {
username: getAuthenticatedUser().username,
},
});
return camelCaseObject(data);
}

/**
* Fetches all the validation records created by the current user or related to a validation body.
* * @param {object} params
* @returns {Promise<[{}]>}
*/

export async function getValidationProcesses(params) {
const { data } = await getAuthenticatedHttpClient()
.get(getValidationApiUrl(VALIDATION_API_PATH.VALIDATION_PROCESS), {
params,
});
return camelCaseObject(data);
}

/**
* Fetches validation body acording with the organization.
* @param {string} org
* @returns {Promise<[{}]>}
*/

export async function getValidationBody(org) {
const { data } = await getAuthenticatedHttpClient()
.get(getValidationApiUrl(VALIDATION_API_PATH.VALIDATION_BODY), {
params: {
org,
},
});
return camelCaseObject(data);
}

/**
* Fetches all the categories associated with the current course.
* @param {string} courseId
* @returns {Promise<[{}]>}
*/

export async function getCourseCategories(courseId) {
const { data } = await getAuthenticatedHttpClient()
.get(getValidationApiUrl(VALIDATION_API_PATH.COURSE_CATEGORY), {
params: {
courseId,
},
});
return camelCaseObject(data);
}

/**
* Creates a new validation process for the course
* @param {object} config
* courseId: { string }
* organization: { string }
* categories: { array<string> },
* validationBody: { string }
* */
export async function postValidationProcess(config) {
const { data } = await getAuthenticatedHttpClient().post(
getValidationApiUrl(VALIDATION_API_PATH.VALIDATION_PROCESS),
snakeCaseObject(config),
);
return camelCaseObject(data);
}

/**
* Creates a new validation process event
* @param {object} config
* status: { string }
* reason: { string | null }
* comment: { string }
* user { string }
* */
export async function postValidationProcessEvent(config) {
const { data } = await getAuthenticatedHttpClient().post(
getValidationApiUrl(VALIDATION_API_PATH.VALIDATION_EVENT),
snakeCaseObject(config),
);
return data;
}
42 changes: 42 additions & 0 deletions src/data/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
const VALIDATION_STATUS = {
SUBMITTED: 'Submitted',
IN_REVIEW: 'In Review',
DRAFT: 'Draft',
APPROVED: 'Approved',
DISAPPROVED: 'Disapproved',
CANCELLED: 'Cancelled',
EXEMPT: 'Exempt',
};

const VALIDATION_ACCESS_ROLE = {
AUTHOR: 'author',
VALIDATOR: 'validator',
};

const VALIDATION_ACTION = {
SUBMIT: 'Submit for validation',
CANCEL: 'Cancel validation',
};
const VALIDATION_API_PATH = {
COURSE_CATEGORY: 'course-category',
VALIDATION_BODY: 'validation-body',
VALIDATION_PROCESS: 'validation-process',
VALIDATION_EVENT: 'validation-process-event',
};

const REQUEST_STATUS = {
LOADING: 'LOADING',
LOADED: 'LOADED',
FAILED: 'FAILED',
DENIED: 'DENIED',
SAVING: 'SAVING',
SAVED: 'SAVED',
};

export {
REQUEST_STATUS,
VALIDATION_ACCESS_ROLE,
VALIDATION_ACTION,
VALIDATION_API_PATH,
VALIDATION_STATUS,
};
119 changes: 119 additions & 0 deletions src/data/slice.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/* eslint-disable no-param-reassign */
import { createSlice } from '@reduxjs/toolkit';

export const coursesSlice = createSlice({
name: 'courses',
initialState: {
courses: [],
loadStatus: null,
},
reducers: {
setCourses: (state, { payload }) => {
state.courses = payload.courses;
state.loadStatus = payload.loadStatus;
},
updateCoursesStatus: (state, { payload }) => {
state.loadStatus = payload;
},
},
});

export const { setCourses, updateCoursesStatus } = coursesSlice.actions;

export const validationRecordslice = createSlice({
name: 'validationRecord',
initialState: {
validationRecords: [],
loadStatus: null,
},
reducers: {
updateValidationRecordStatus: (state, { payload }) => {
state.loadStatus = payload;
},
setValidationRecords: (state, { payload }) => {
state.validationRecords = payload.validationRecords;
state.loadStatus = payload.loadStatus;
},
},
});

export const { updateValidationRecordStatus, setValidationRecords } = validationRecordslice.actions;

export const validationBodySlice = createSlice({
name: 'validationBody',
initialState: {
validationBodies: [],
loadStatus: null,

},
reducers: {
updateValidationBodyStatus: (state, { payload }) => {
state.loadStatus = payload;
},
setValidationBodyList: (state, { payload }) => {
state.validationBodies = payload.validationBody;
state.loadStatus = payload.loadStatus;
},
},
});

export const { updateValidationBodyStatus, setValidationBodyList } = validationBodySlice.actions;

export const courseCategorySlice = createSlice({
name: 'courseCategory',
initialState: {
courseCategories: [],
loadStatus: null,
},
reducers: {
updateCourseCatagoryStatus: (state, { payload }) => {
state.loadStatus = payload;
},

},
setCourseCategoryList: (state, { payload }) => {
state.courseCategories = payload.categories;
state.loadStatus = payload.loadStatus;
},
});

export const {
updateCourseCatagoryStatus,
setCourseCategoryList,
} = courseCategorySlice.actions;

export const currentRecordSlice = createSlice({
name: 'currentValidationRecord',
initialState: {
loadStatus: null,
courseName: null,
courseId: null,
organization: null,
categories: [],
validationBody: null,
validationProcessEvents: [],
},
reducers: {
updateCurrentValidationRecordStatus: (state, { payload }) => {
state.loadStatus = payload;
},
setCurrentRecord: (state, { payload }) => {
state.courseName = payload.courseName;
state.courseId = payload.courseId;
state.organization = payload.organization;
state.categories = payload.categories;
state.validationBody = payload.validationBody;
state.validationProcessEvents = payload.processEvents;
state.loadStatus = payload.loadStatus;
},
updateValidationEvents: (state, { payload }) => {
state.validationProcessEvents = payload.validationProcessEvents;
},
},
});

export const {
updateCurrentValidationRecordStatus,
setCurrentRecord,
updateValidationEvents,
} = currentRecordSlice.actions;
21 changes: 21 additions & 0 deletions src/data/store.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { configureStore } from '@reduxjs/toolkit';
import {
coursesSlice, validationRecordslice, validationBodySlice, courseCategorySlice, currentRecordSlice,
} from './slice';

export const initializeStore = (preloadedState = undefined) => (
configureStore({
reducer: {
courses: coursesSlice.reducer,
validationRecord: validationRecordslice.reducer,
validationBody: validationBodySlice.reducer,
courseCategory: courseCategorySlice.reducer,
currentValidationRecord: currentRecordSlice.reducer,
},
preloadedState,
})
);

const store = initializeStore();

export default store;
Loading

0 comments on commit 4ca0b6e

Please sign in to comment.