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:
@@ -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
101
src/data/dates.js
Normal 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"
|
||||
}
|
||||
]
|
||||
}
|
||||
`);
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
export {
|
||||
fetchCourse,
|
||||
fetchDatesTab,
|
||||
fetchSequence,
|
||||
} from './thunks';
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 }));
|
||||
|
||||
Reference in New Issue
Block a user