Add basic dates tab (#62)

This is not the final visuals for the dates tab, but an in-progress
page to base further work on.

AA-116
This commit is contained in:
Michael Terry
2020-05-26 13:07:24 -04:00
committed by GitHub
parent e101b41c08
commit 7487d8d32f
12 changed files with 262 additions and 5 deletions

View File

@@ -3,6 +3,9 @@ import { getConfig, camelCaseObject } from '@edx/frontend-platform';
import { getAuthenticatedHttpClient, getAuthenticatedUser } from '@edx/frontend-platform/auth';
import { logError } from '@edx/frontend-platform/logging';
// FIXME: remove this WIP hack once we're done developing the tab
import datesTabData from './dates';
function overrideTabUrls(id, tabs) {
// "LMS tab slug" to "MFE URL slug" for overridden tabs
const tabOverrides = {};
@@ -49,6 +52,16 @@ export async function getCourseMetadata(courseId) {
return normalizeMetadata(data);
}
export async function getTabData(courseId, tab, version) {
if (tab === 'dates') {
return camelCaseObject(datesTabData());
}
const url = `${getConfig().LMS_BASE_URL}/course/${courseId}/api/course_home/${version}/${tab}`;
const { data } = await getAuthenticatedHttpClient().get(url);
return camelCaseObject(data);
}
function normalizeBlocks(courseId, blocks) {
const models = {
courses: {},

101
src/data/dates.js Normal file
View File

@@ -0,0 +1,101 @@
// Sample WIP data while we develop the dates tab
export default function datesData() {
return JSON.parse(`
{
"id": "course-v1:edX+DemoX+Demo_Course",
"isStaff": true,
"number": "DemoX",
"org": "edX",
"title": "Demonstration Course",
"tabs": [
{
"url": "/courses/course-v1:edX+DemoX+Demo_Course/course/",
"title": "Course",
"slug": "courseware",
"type": "courseware",
"priority": 0
},
{
"url": "/courses/course-v1:edX+DemoX+Demo_Course/discussion/forum/",
"title": "Discussion",
"slug": "discussion",
"type": "discussion",
"priority": 1
},
{
"url": "/courses/course-v1:edX+DemoX+Demo_Course/course_wiki",
"title": "Wiki",
"slug": "wiki",
"type": "wiki",
"priority": 2
},
{
"url": "/courses/course-v1:edX+DemoX+Demo_Course/progress",
"title": "Progress",
"slug": "progress",
"type": "progress",
"priority": 3
},
{
"url": "/courses/course-v1:edX+DemoX+Demo_Course/dates",
"title": "Dates",
"slug": "dates",
"type": "dates",
"priority": 4
},
{
"url": "/courses/course-v1:edX+DemoX+Demo_Course/instructor",
"title": "Instructor",
"slug": "instructor",
"type": "instructor",
"priority": 5
}
],
"dates": [
{
"title": "Course Starts",
"link": "/testing",
"date": "2015-02-05T05:00:00Z"
},
{
"contains_gated_content": true,
"link": "/testing",
"title": "Homework - Question Styles force publish",
"date": "2020-01-14T13:00:00Z"
},
{
"title": "New Subsection",
"date": "2020-04-20T08:30:00Z"
},
{
"title": "current_datetime",
"date": "2020-05-05T17:47:55.957725Z"
},
{
"title": "Verification Upgrade Deadline",
"date": "2020-09-16T19:05:00Z"
},
{
"title": "edX Exams",
"date": "2022-01-02T00:00:00Z"
},
{
"title": "Homework - Labs and Demos",
"date": "2022-01-14T13:00:00Z"
},
{
"title": "Homework - Essays",
"date": "2022-04-30T12:00:00Z"
},
{
"title": "Course End",
"date": "2025-02-09T00:30:00Z"
},
{
"title": "Verification Deadline",
"date": "2025-02-09T00:30:00Z"
}
]
}
`);
}

View File

@@ -1,5 +1,6 @@
export {
fetchCourse,
fetchDatesTab,
fetchSequence,
} from './thunks';

View File

@@ -43,6 +43,18 @@ const slice = createSlice({
state.sequenceId = payload.sequenceId;
state.sequenceStatus = FAILED;
},
fetchTabRequest: (state, { payload }) => {
state.courseId = payload.courseId;
state.courseStatus = LOADING;
},
fetchTabSuccess: (state, { payload }) => {
state.courseId = payload.courseId;
state.courseStatus = LOADED;
},
fetchTabFailure: (state, { payload }) => {
state.courseId = payload.courseId;
state.courseStatus = FAILED;
},
},
});
@@ -54,6 +66,9 @@ export const {
fetchSequenceRequest,
fetchSequenceSuccess,
fetchSequenceFailure,
fetchTabRequest,
fetchTabSuccess,
fetchTabFailure,
} = slice.actions;
export const {

View File

@@ -3,6 +3,7 @@ import {
getCourseMetadata,
getCourseBlocks,
getSequenceMetadata,
getTabData,
} from './api';
import {
addModelsMap, updateModel, updateModels, updateModelsMap, addModel,
@@ -15,6 +16,9 @@ import {
fetchSequenceRequest,
fetchSequenceSuccess,
fetchSequenceFailure,
fetchTabRequest,
fetchTabSuccess,
fetchTabFailure,
} from './slice';
export function fetchCourse(courseId) {
@@ -29,6 +33,17 @@ export function fetchCourse(courseId) {
modelType: 'courses',
model: courseMetadataResult.value,
}));
dispatch(addModel({
modelType: 'pageInfo',
model: {
id: courseMetadataResult.value.id,
isStaff: courseMetadataResult.value.isStaff,
number: courseMetadataResult.value.number,
org: courseMetadataResult.value.org,
tabs: courseMetadataResult.value.tabs,
title: courseMetadataResult.value.title,
},
}));
}
if (courseBlocksResult.status === 'fulfilled') {
@@ -85,6 +100,40 @@ export function fetchCourse(courseId) {
};
}
export function fetchTab(courseId, tab, version) {
return async (dispatch) => {
dispatch(fetchTabRequest({ courseId }));
getTabData(courseId, tab, version).then((result) => {
dispatch(addModel({
modelType: 'pageInfo',
model: {
id: result.id,
isStaff: result.isStaff,
number: result.number,
org: result.org,
tabs: result.tabs,
title: result.title,
},
}));
dispatch(addModel({
modelType: tab,
model: result,
}));
// TODO: do we need access restrictions for tabs, like we have for courseware?
dispatch(fetchTabSuccess({ courseId }));
}, (reason) => {
logError(reason);
dispatch(fetchTabFailure({ courseId }));
});
};
}
export function fetchDatesTab(courseId) {
return fetchTab(courseId, 'dates', 'v1');
}
export function fetchSequence(sequenceId) {
return async (dispatch) => {
dispatch(fetchSequenceRequest({ sequenceId }));