Skip to content

Commit

Permalink
refactor: code refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
PKulkoRaccoonGang committed Jan 8, 2024
1 parent cb00386 commit c668b38
Show file tree
Hide file tree
Showing 15 changed files with 69 additions and 78 deletions.
1 change: 0 additions & 1 deletion .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ ENABLE_NEW_VIDEO_UPLOAD_PAGE = false
ENABLE_UNIT_PAGE = true
ENABLE_VIDEO_UPLOAD_PAGE_LINK_IN_CONTENT_DROPDOWN = false
ENABLE_TAGGING_TAXONOMY_PAGES = true
ENABLE_NEW_COURSE_OUTLINE_PAGE = true
BBB_LEARN_MORE_URL=''
HOTJAR_APP_ID=''
HOTJAR_VERSION=6
Expand Down
16 changes: 4 additions & 12 deletions src/CourseAuthoringRoutes.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,6 @@ import { CourseUnit } from './course-unit';
import CourseExportPage from './export-page/CourseExportPage';
import CourseImportPage from './import-page/CourseImportPage';

const COURSEWARE = [
'/container/:blockId/:sequenceId/:unitId',
'/container/:blockId/:sequenceId',
'/container/:courseId',
];

/**
* As of this writing, these routes are mounted at a path prefixed with the following:
*
Expand Down Expand Up @@ -75,12 +69,10 @@ const CourseAuthoringRoutes = () => {
path="custom-pages/*"
element={<PageWrap><CustomPages courseId={courseId} /></PageWrap>}
/>
{COURSEWARE.map((route) => (
<Route
path={route}
element={process.env.ENABLE_UNIT_PAGE === 'true' ? <PageWrap><CourseUnit courseId={courseId} /></PageWrap> : null}
/>
))}
<Route
path="/container/:blockId/:sequenceId"
element={process.env.ENABLE_UNIT_PAGE === 'true' ? <PageWrap><CourseUnit courseId={courseId} /></PageWrap> : null}
/>
<Route
path="editor/course-videos/:blockId"
element={process.env.ENABLE_NEW_EDITOR_PAGES === 'true' ? <PageWrap><VideoSelectorContainer courseId={courseId} /></PageWrap> : null}
Expand Down
1 change: 0 additions & 1 deletion src/course-unit/CourseUnit.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import HeaderTitle from './header-title/HeaderTitle';
import Breadcrumbs from './breadcrumbs/Breadcrumbs';
import HeaderNavigations from './header-navigations/HeaderNavigations';
import Sequence from './course-sequence';

import { useCourseUnit } from './hooks';
import messages from './messages';

Expand Down
17 changes: 17 additions & 0 deletions src/course-unit/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {
BookOpen as BookOpenIcon,
Edit as EditIcon,
FormatListBulleted as FormatListBulletedIcon,
Lock as LockIcon,
VideoCamera as VideoCameraIcon,
} from '@edx/paragon/icons/es5';

export const UNIT_ICON_TYPES = ['video', 'other', 'vertical', 'problem', 'lock'];

export const typeToIconMapping = {
video: VideoCameraIcon,
other: BookOpenIcon,
vertical: FormatListBulletedIcon,
problem: EditIcon,
lock: LockIcon,
};
23 changes: 12 additions & 11 deletions src/course-unit/course-sequence/Sequence.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,23 @@ import PropTypes from 'prop-types';
import { useSelector } from 'react-redux';
import classNames from 'classnames';
import { breakpoints, useWindowSize } from '@edx/paragon';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { injectIntl, useIntl } from '@edx/frontend-platform/i18n';

import Loading from '../../generic/Loading';
import SequenceNavigation from './sequence-navigation/SequenceNavigation';
import { RequestStatus } from '../../data/constants';
import SequenceNavigation from './sequence-navigation/SequenceNavigation';
import messages from './messages';

const Sequence = ({
courseId,
sequenceId,
unitId,
}) => {
const intl = useIntl();
const { IN_PROGRESS, FAILED, SUCCESSFUL } = RequestStatus;
const shouldDisplayNotificationTriggerInSequence = useWindowSize().width < breakpoints.small.minWidth;
const sequenceStatus = useSelector(state => state.courseUnit.sequenceStatus);
const sequenceMightBeUnit = useSelector(state => state.courseUnit.sequenceMightBeUnit);
const TEST = useSelector(state => state);
console.log('TEST', TEST);
const { sequenceStatus, sequenceMightBeUnit } = useSelector(state => state.courseUnit);

const defaultContent = (
<div className="sequence-container d-inline-flex flex-row">
<div className={classNames('sequence w-100', { 'position-relative': shouldDisplayNotificationTriggerInSequence })}>
Expand All @@ -32,16 +33,16 @@ const Sequence = ({

// If sequence might be a unit, we want to keep showing a spinner - the courseware container will redirect us when
// it knows which sequence to actually go to.
const loading = sequenceStatus === RequestStatus.IN_PROGRESS || (sequenceStatus === RequestStatus.FAILED && sequenceMightBeUnit);
const loading = sequenceStatus === IN_PROGRESS || (sequenceStatus === FAILED && sequenceMightBeUnit);
if (loading) {
if (!sequenceId) {
return (<div>There is no content here.</div>);
return (<div>{intl.formatMessage(messages.sequenceNoContent)}</div>);
}
// eslint-disable-next-line react/jsx-no-useless-fragment

return <Loading />;
}

if (sequenceStatus === RequestStatus.SUCCESSFUL) {
if (sequenceStatus === SUCCESSFUL) {
return (
<div>
{defaultContent}
Expand All @@ -52,7 +53,7 @@ const Sequence = ({
// sequence status 'failed' and any other unexpected sequence status.
return (
<p className="text-center py-5 mx-auto" style={{ maxWidth: '30em' }}>
failed
{intl.formatMessage(messages.sequenceLoadFailure)}
</p>
);
};
Expand Down
14 changes: 9 additions & 5 deletions src/course-unit/course-sequence/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,23 @@ import { useLayoutEffect, useRef, useState } from 'react';
import { useWindowSize } from '@edx/paragon';

import { useModel } from '../../generic/model-store';
import { sequenceIdsSelector } from '../data/selectors';
import { RequestStatus } from '../../data/constants';
import { getCourseSectionVertical, getSequenceStatus, sequenceIdsSelector } from '../data/selectors';

export function useSequenceNavigationMetadata(currentSequenceId, currentUnitId) {
const { SUCCESSFUL } = RequestStatus;
const sequenceIds = useSelector(sequenceIdsSelector);
const sequenceStatus = useSelector(getSequenceStatus);
const { nextUrl, prevUrl } = useSelector(getCourseSectionVertical);
const sequence = useModel('sequences', currentSequenceId);
const { courseId, status } = useSelector(state => state.courseDetail);
const courseStatus = status;
const sequenceStatus = useSelector(state => state.courseUnit.sequenceStatus);
const { nextUrl, prevUrl } = useSelector(state => state.courseUnit.courseSectionVertical);

const isCourseOrSequenceNotSuccessful = status !== SUCCESSFUL || sequenceStatus !== SUCCESSFUL;
const areIdsNotValid = !currentSequenceId || !currentUnitId || !sequence.unitIds;
const isNotSuccessfulCompletion = isCourseOrSequenceNotSuccessful || areIdsNotValid;

// If we don't know the sequence and unit yet, then assume no.
if (courseStatus !== RequestStatus.SUCCESSFUL || sequenceStatus !== RequestStatus.SUCCESSFUL || !currentSequenceId || !currentUnitId || !sequence.unitIds) {
if (isNotSuccessfulCompletion) {
return { isFirstUnit: false, isLastUnit: false };
}

Expand Down
8 changes: 8 additions & 0 deletions src/course-unit/course-sequence/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ const messages = defineMessages({
id: 'course-authoring.course-unit.sequence-nav-label-text',
defaultMessage: 'Sequence navigation',
},
sequenceLoadFailure: {
id: 'course-authoring.course-unit.sequence.load.failure',
defaultMessage: 'There was an error loading this course.',
},
sequenceNoContent: {
id: 'course-authoring.course-unit.sequence.no.content',
defaultMessage: 'There is no content here.',
},
});

export default messages;
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Link } from 'react-router-dom';
import { useSelector } from 'react-redux';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import {
Expand All @@ -8,14 +10,12 @@ import {
ChevronLeft as ChevronLeftIcon,
ChevronRight as ChevronRightIcon,
} from '@edx/paragon/icons';
import { Link } from 'react-router-dom';
import { useSelector } from 'react-redux';

import { useModel } from '../../../generic/model-store';
import { RequestStatus } from '../../../data/constants';
import messages from '../messages';
import { useSequenceNavigationMetadata } from '../hooks';
import SequenceNavigationTabs from './SequenceNavigationTabs';
import { RequestStatus } from '../../../data/constants';

const SequenceNavigation = ({
intl,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const SequenceNavigationDropdown = ({ unitId, unitIds }) => (
<FormattedMessage
defaultMessage="{current} of {total}"
description="The title of the mobile menu for sequence navigation of units"
id="learn.course.sequence.navigation.mobile.menu"
id="course-authoring.course-unit.sequence.navigation.mobile.menu"
values={{
current: unitIds.indexOf(unitId) + 1,
total: unitIds.length,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ import PropTypes from 'prop-types';
import { Button } from '@edx/paragon';
import { Plus as PlusIcon } from '@edx/paragon/icons';
import { Link } from 'react-router-dom';
import { useIntl } from '@edx/frontend-platform/i18n';

import { useIndexOfLastVisibleChild } from '../hooks';
import messages from '../messages';
import SequenceNavigationDropdown from './SequenceNavigationDropdown';
import UnitButton from './UnitButton';

const SequenceNavigationTabs = ({ unitIds, unitId }) => {
const intl = useIntl();
const [
indexOfLastVisibleChild,
containerRef,
Expand Down Expand Up @@ -37,7 +40,7 @@ const SequenceNavigationTabs = ({ unitIds, unitId }) => {
as={Link}
to="/"
>
New unit
{intl.formatMessage(messages.newUnitBtnText)}
</Button>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ import { Link } from 'react-router-dom';
import UnitIcon from './UnitIcon';

const UnitButton = ({
title, contentType, isActive, unitId, className, showTitle, style,
title, contentType, isActive, unitId, className, showTitle,
}) => {
const { courseId } = useSelector(state => state.courseDetail);
const { sequenceId } = useSelector(state => state.courseUnit);
const { courseId, sequenceId } = useSelector(state => state.courseUnit);

return (
<Button
Expand All @@ -18,7 +17,6 @@ const UnitButton = ({
as={Link}
title={title}
to={`/course/${courseId}/container/${unitId}/${sequenceId}/`}
style={style}
>
<UnitIcon type={contentType} />
{showTitle && <span className="unit-title">{title}</span>}
Expand Down
41 changes: 4 additions & 37 deletions src/course-unit/course-sequence/sequence-navigation/UnitIcon.jsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,13 @@
import PropTypes from 'prop-types';
import { Icon } from '@edx/paragon';
import {
VideoCamera as VideoCameraIcon,
BookOpen as BookOpenIcon,
FormatListBulleted as FormatListBulletedIcon,
Edit as EditIcon,
Lock as LockIcon,
} from '@edx/paragon/icons';
import { BookOpen as BookOpenIcon } from '@edx/paragon/icons';

export const UNIT_ICON_TYPES = ['video', 'other', 'vertical', 'problem', 'lock'];
import { typeToIconMapping, UNIT_ICON_TYPES } from '../../constants';

const UnitIcon = ({ type }) => {
let icon = null;
let srText = null;
const icon = typeToIconMapping[type] || BookOpenIcon;

switch (type) {
case 'video':
icon = VideoCameraIcon;
srText = type;
break;
case 'other':
icon = BookOpenIcon;
srText = type;
break;
case 'vertical':
icon = FormatListBulletedIcon;
srText = type;
break;
case 'problem':
icon = EditIcon;
srText = type;
break;
case 'lock':
icon = LockIcon;
srText = type;
break;
default:
icon = BookOpenIcon;
srText = type;
}

return (<Icon src={icon} screenReaderText={srText} />);
return <Icon src={icon} screenReaderText={type} />;
};

UnitIcon.propTypes = {
Expand Down
4 changes: 4 additions & 0 deletions src/course-unit/data/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ export const getSavingStatus = (state) => state.courseUnit.savingStatus;

export const getLoadingStatus = (state) => state.courseUnit.loadingStatus;

export const getSequenceStatus = (state) => state.courseUnit.sequenceStatus;

export const getCourseSectionVertical = (state) => state.courseUnit.courseSectionVertical;

export function sequenceIdsSelector(state) {
if (state.courseUnit.courseStatus !== RequestStatus.SUCCESSFUL) {
return [];
Expand Down
2 changes: 1 addition & 1 deletion src/course-unit/data/thunk.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export function fetchSequence(sequenceId) {
dispatch(fetchSequenceRequest({ sequenceId }));
try {
const { sequence, units } = await getSequenceMetadata(sequenceId);
// console.log('units', units);

if (sequence.blockType !== 'sequential') {
// Some other block types (particularly 'chapter') can be returned
// by this API. We want to error in that case, since downstream
Expand Down
1 change: 0 additions & 1 deletion src/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
@import "~@edx/paragon/scss/core/core";
@import "~@edx/brand/paragon/overrides";
@import "~@edx/frontend-component-header/dist/index";

@import "assets/scss/variables";
@import "assets/scss/form";
@import "assets/scss/utilities";
Expand Down

0 comments on commit c668b38

Please sign in to comment.