Skip to content

Commit

Permalink
Catalog card should show Start Anytime if the course is archived (#2359)
Browse files Browse the repository at this point in the history
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
annagav and pre-commit-ci[bot] authored Aug 26, 2024
1 parent ec557d0 commit ade4025
Show file tree
Hide file tree
Showing 10 changed files with 34 additions and 34 deletions.
6 changes: 6 additions & 0 deletions courses/serializers/v1/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ class Meta:
class BaseCourseRunSerializer(serializers.ModelSerializer):
"""Minimal CourseRun model serializer"""

is_archived = serializers.SerializerMethodField()

def get_is_archived(self, instance):
return instance.is_enrollable and instance.is_past

class Meta:
model = models.CourseRun
fields = [
Expand All @@ -51,6 +56,7 @@ class Meta:
"upgrade_deadline",
"is_upgradable",
"is_enrollable",
"is_archived",
"is_self_paced",
"run_tag",
"id",
Expand Down
2 changes: 2 additions & 0 deletions courses/serializers/v1/courses_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ def test_serialize_course_run():
"approved_flexible_price_exists": False,
"live": True,
"is_self_paced": course_run.is_self_paced,
"is_archived": False,
"certificate_available_date": drf_datetime(
course_run.certificate_available_date
),
Expand Down Expand Up @@ -172,6 +173,7 @@ def test_serialize_course_run_with_course():
"is_upgradable": course_run.is_upgradable,
"is_enrollable": course_run.is_enrollable,
"is_self_paced": False,
"is_archived": False,
"id": course_run.id,
"products": BaseProductSerializer(course_run.products, many=True).data,
"approved_flexible_price_exists": False,
Expand Down
2 changes: 1 addition & 1 deletion courses/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,9 @@ def get_unenrollable_courses(queryset):
def get_archived_courseruns(queryset):
"""
Returns course runs that are archived. This is defined as:
- The course runs are open for enrollment
- The course run end date has passed
- The course run enrollment end date is in the future or None.
This logic is set to match the logic found in frontend/public/src/lib/courseApi.js isRunArchived
Args:
queryset: Queryset of CourseRun objects
Expand Down
31 changes: 15 additions & 16 deletions frontend/public/src/components/CourseInfoBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
parseDateString,
formatPrettyShortDate
} from "../lib/util"
import { getFirstRelevantRun, isRunArchived } from "../lib/courseApi"
import { getFirstRelevantRun } from "../lib/courseApi"
import moment from "moment-timezone"

import type { BaseCourseRun } from "../flow/courseTypes"
Expand All @@ -26,12 +26,11 @@ type CourseInfoBoxProps = {
* If the run is under the toggle "More Dates" the format is inline and month
* is shortened to 3 letters.
* @param {EnrollmentFlaggedCourseRun} run
* @param {boolean} isArchived if the course ended, but still enrollable
* @param {boolean} isMoreDates true if this run is going to show up under the More Dates toggle
* */

const getCourseDates = (run, isArchived = false, isMoreDates = false) => {
if (isArchived) {
const getCourseDates = (run, isMoreDates = false) => {
if (run.is_archived) {
return (
<>
<span>Course content available anytime</span>
Expand Down Expand Up @@ -84,16 +83,17 @@ export default class CourseInfoBox extends React.PureComponent<CourseInfoBoxProp
})
}

warningMessage(isArchived) {
const message = isArchived ?
"This course is no longer active, but you can still access selected content." :
"No sessions of this course are currently open for enrollment. More sessions may be added in the future."
warningMessage(run) {
const message =
run && run.is_archived ?
"This course is no longer active, but you can still access selected content." :
"No sessions of this course are currently open for enrollment. More sessions may be added in the future."
return (
<div className="row d-flex callout callout-warning course-status-message">
<i className="material-symbols-outlined warning">error</i>
<p className="p-0">
{message}{" "}
{isArchived ? (
{run && run.is_archived ? (
<button
className="info-link more-info float-none"
onClick={() => this.togglePacingInfoDialogVisibility("Archived")}
Expand Down Expand Up @@ -164,15 +164,14 @@ export default class CourseInfoBox extends React.PureComponent<CourseInfoBoxProp
const course = courses[0]
const run = getFirstRelevantRun(course, course.courseruns)
const product = run && run.products.length > 0 && run.products[0]
const isArchived = isRunArchived(run)

const startDates = []
const moreEnrollableCourseRuns = enrollableCourseRuns.length > 1
if (moreEnrollableCourseRuns) {
enrollableCourseRuns.forEach((courseRun, index) => {
if (courseRun.id !== run.id) {
startDates.push(
<li key={index}>{getCourseDates(courseRun, isArchived, true)}</li>
<li key={index}>{getCourseDates(courseRun, true)}</li>
)
}
})
Expand All @@ -190,7 +189,7 @@ export default class CourseInfoBox extends React.PureComponent<CourseInfoBoxProp
return (
<>
<div className="enrollment-info-box componentized">
{!run || isArchived ? this.warningMessage(isArchived) : null}
{!run || run.is_archived ? this.warningMessage(run) : null}
{run ? (
<div className="row d-flex course-timing-message">
<div className="enrollment-info-icon">
Expand All @@ -204,10 +203,10 @@ export default class CourseInfoBox extends React.PureComponent<CourseInfoBoxProp
aria-level="3"
role="heading"
>
{getCourseDates(run, isArchived)}
{getCourseDates(run)}
</div>

{!isArchived && moreEnrollableCourseRuns ? (
{!run.is_archived && moreEnrollableCourseRuns ? (
<>
<button
className="info-link more-info more-dates"
Expand Down Expand Up @@ -244,7 +243,7 @@ export default class CourseInfoBox extends React.PureComponent<CourseInfoBoxProp
role="heading"
>
<b>Course Format: </b>
{isArchived || run.is_self_paced ? (
{run.is_archived || run.is_self_paced ? (
<>
Self-paced
<button
Expand Down Expand Up @@ -307,7 +306,7 @@ export default class CourseInfoBox extends React.PureComponent<CourseInfoBoxProp
<b>Price: </b> <span>Free</span> to Learn
</div>
<div className="enrollment-info-text course-certificate-message">
{run && product && !isArchived ? (
{run && product && !run.is_archived ? (
<>
<span>Certificate Track: </span>
{formatLocalePrice(getFlexiblePriceForProduct(product))}
Expand Down
6 changes: 3 additions & 3 deletions frontend/public/src/components/CourseProductDetailEnroll.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {

import { formatPrettyDate, emptyOrNil } from "../lib/util"
import moment from "moment-timezone"
import { getFirstRelevantRun, isRunArchived } from "../lib/courseApi"
import { getFirstRelevantRun } from "../lib/courseApi"
import { getCookie } from "../lib/api"
import users, { currentUserSelector } from "../lib/queries/users"
import {
Expand Down Expand Up @@ -419,7 +419,7 @@ export class CourseProductDetailEnroll extends React.Component<
)}`}
className="btn btn-primary btn-enrollment-button btn-lg btn-gradient-red-to-blue highlight"
>
{isRunArchived(run) ? "Access Course Materials" : "Enroll Now"}
{run.is_archived ? "Access Course Materials" : "Enroll Now"}
</a>
</h2>
)
Expand Down Expand Up @@ -469,7 +469,7 @@ export class CourseProductDetailEnroll extends React.Component<
className="btn btn-primary btn-enrollment-button btn-gradient-red-to-blue highlight enroll-now"
disabled={!run.is_enrollable}
>
{isRunArchived(run) ? "Access Course Materials" : "Enroll Now"}
{run.is_archived ? "Access Course Materials" : "Enroll Now"}
</button>
</form>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ describe("CourseProductDetailEnrollShallowRender", () => {
enrollment_start: moment().subtract(1, "years").toISOString(),
start_date: moment().subtract(10, "months").toISOString(),
end_date: moment().subtract(7, "months").toISOString(),
is_archived: true,
upgrade_deadline: null
}
const course = makeCourseDetailNoRuns()
Expand Down Expand Up @@ -366,6 +367,7 @@ describe("CourseProductDetailEnrollShallowRender", () => {
enrollment_start: moment().subtract(1, "years").toISOString(),
start_date: moment().subtract(10, "months").toISOString(),
end_date: moment().subtract(7, "months").toISOString(),
is_archived: true,
upgrade_deadline: null
}
const course = {
Expand Down Expand Up @@ -596,6 +598,7 @@ describe("CourseProductDetailEnrollShallowRender", () => {

it(`shows the disabled enroll button and warning message when no active runs`, async () => {
course = makeCourseDetailNoRuns()
courseRun["is_archived"] = true

const { inner } = await renderPage(
{
Expand Down
1 change: 1 addition & 0 deletions frontend/public/src/factories/course.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export const makeCourseRun = (): CourseRun => {
courseware_id: casual.word.concat(genCoursewareId.next().value),
run_tag: casual.word.concat(genRunTagNumber.next().value),
is_enrollable: true,
is_archived: false,
// $FlowFixMe
id: genCourseRunId.next().value,
course_number: casual.word,
Expand Down
1 change: 1 addition & 0 deletions frontend/public/src/flow/courseTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export type BaseCourseRun = {
upgrade_deadline: ?string,
certificate_available_date: ?string,
is_upgradable: boolean,
is_archived: boolean,
is_enrollable: boolean,
is_self_paced: boolean,
courseware_url: ?string,
Expand Down
14 changes: 1 addition & 13 deletions frontend/public/src/lib/courseApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,7 @@ import React from "react"
import moment from "moment"
import { isNil } from "ramda"

import {
notNil,
parseDateString,
formatPrettyDateTimeAmPmTz,
emptyOrNil
} from "./util"
import { notNil, parseDateString, formatPrettyDateTimeAmPmTz } from "./util"

import { NODETYPE_OPERATOR, NODETYPE_COURSE, NODEOPER_ALL } from "../constants"

Expand Down Expand Up @@ -210,13 +205,6 @@ export const learnerProgramIsCompleted = (learnerRecord: LearnerRecord) => {

return requirementsDone && electivesDone
}
export const isRunArchived = (run: CourseRunDetail) => {
return run ?
moment().isAfter(run.end_date) &&
(moment().isBefore(run.enrollment_end) ||
emptyOrNil(run.enrollment_end)) :
false
}

export const getFirstRelevantRun = (
course: CourseDetail,
Expand Down
2 changes: 1 addition & 1 deletion frontend/public/src/lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ export const getStartDateText = (
if (moment(courseRun.start_date).isAfter(moment())) {
return `Starts: ${formatPrettyDate(parseDateString(courseRun.start_date))}`
} else {
if (courseRun.is_self_paced) {
if (courseRun.is_self_paced || courseRun.is_archived) {
return "Start Anytime"
} else {
return `Started: ${formatPrettyDate(
Expand Down

0 comments on commit ade4025

Please sign in to comment.