Skip to content

Commit 44179d8

Browse files
Ahtesham QuraishAhtesham Quraish
authored andcommitted
rebase with main
2 parents 575fd90 + 74d69b3 commit 44179d8

130 files changed

Lines changed: 7143 additions & 4938 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,4 @@ USER mitodl
7676

7777
EXPOSE 8061
7878
ENV PORT 8061
79-
CMD ["sh", "-c", "exec granian --interface asginl --host 0.0.0.0 --port 8061 --workers ${GRANIAN_WORKERS:-3} --blocking-threads 1 main.asgi:application"]
79+
CMD ["sh", "-c", "exec granian --interface asginl --reload --host 0.0.0.0 --port 8061 --workers ${GRANIAN_WORKERS:-3} --blocking-threads 1 main.asgi:application"]

RELEASE.rst

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,47 @@
11
Release Notes
22
=============
33

4+
Version 0.68.3 (Released May 19, 2026)
5+
--------------
6+
7+
- fix: link the podcast episode to its detail page and fix the video count on collection page (#3345)
8+
9+
Version 0.68.2 (Released May 19, 2026)
10+
--------------
11+
12+
- feat: add video embed page and route group restructure (#3327)
13+
- dashboard refactor: useHomeDashboardData (#3342)
14+
- fix: add heading tags to B2B org section (#3347)
15+
- fix: certificate page being indexed in google search (#3348)
16+
- Granian reload for local dev (#3351)
17+
18+
Version 0.68.1 (Released May 19, 2026)
19+
--------------
20+
21+
- split EnrollmentDisplay into HomeEnrollmentsDisplay + ProgramEnrollMentDisplay… (#3341)
22+
- Remove enrollment-dashboard feature flag (#3343)
23+
- feat: Added Program Record Link to Learn Dashboard Program Card . (#3336)
24+
- Update dependency drf-spectacular to >=0.29,<0.30 (#2734)
25+
26+
Version 0.68.0 (Released May 13, 2026)
27+
--------------
28+
29+
- fix open textbooks (#3337)
30+
- youtube etl should not unpublish ovs (#3334)
31+
- dashboard refactor stage 2 (#3330)
32+
- Adds a feature flag to link ocw course urls to corresponding learn urls (/courses/o/*) (#3263)
33+
- Min score for vector learning resources endpoint (#3285)
34+
- Update dependency granian to v2.7.4 [SECURITY] (#3309)
35+
- Update dependency litellm to v1.83.10 [SECURITY] (#3331)
36+
- Update dependency urllib3 to v2.7.0 [SECURITY] (#3329)
37+
38+
Version 0.67.2 (Released May 12, 2026)
39+
--------------
40+
41+
- feat: display MicroMasters® label on MITxOnline program product pages (#3318)
42+
- fix: add sitemap for video and podcast page (#3323)
43+
- Show (and count) only published items in userlists/paths (#3321)
44+
445
Version 0.67.1 (Released May 11, 2026)
546
--------------
647

frontends/api/src/generated/v0/api.ts

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontends/main/src/app-pages/DashboardPage/ContractContent.tsx

Lines changed: 45 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,9 @@ import { ErrorContent } from "../ErrorPage/ErrorPageTemplate"
3535
import { matchOrganizationBySlug } from "@/common/utils"
3636
import { ResourceType, getKey } from "./CoursewareDisplay/helpers"
3737
import {
38-
getCourseRunForSelectedLanguage,
39-
getDistinctLanguageOptions,
40-
getResolvedRunForSelectedLanguage,
41-
getSelectedLanguageOption,
42-
selectBestContractEnrollmentForLanguage,
43-
} from "./CoursewareDisplay/languageOptions"
38+
getDistinctDashboardLanguageOptions,
39+
resolveSlotForLanguage,
40+
} from "./CoursewareDisplay/model/dashboardViewModel"
4441
import UnstyledRawHTML from "@/components/UnstyledRawHTML/UnstyledRawHTML"
4542

4643
const HeaderRoot = styled.div(({ theme }) => ({
@@ -159,7 +156,9 @@ const WelcomeMessage: React.FC<{ contract?: ContractPage }> = ({
159156
return (
160157
<Stack gap="12px" paddingTop="40px" paddingBottom="24px">
161158
<Stack direction="row" justifyContent="space-between" alignItems="center">
162-
<Typography variant="h5">{welcomeMessage}</Typography>
159+
<Typography variant="h5" component="h2">
160+
{welcomeMessage}
161+
</Typography>
163162
<Link
164163
scroll={false}
165164
color="red"
@@ -398,54 +397,36 @@ const OrgProgramCollectionDisplay: React.FC<{
398397
enrollments?.filter(
399398
(enrollment) => enrollment.b2b_contract_id === contract.id,
400399
) ?? []
401-
// Prefer the user's existing enrollment for the selected language
402-
// over the next/best run, so older-run enrollments stay visible
403-
// when the contract surfaces a newer run.
404-
const selectedLanguageEnrollment =
405-
selectBestContractEnrollmentForLanguage(
406-
course,
407-
contractEnrollments,
408-
selectedLanguageKey,
409-
)
410-
const selectedLanguageOption = getSelectedLanguageOption(
400+
const { displayedEnrollment, displayedRun } = resolveSlotForLanguage(
411401
course,
402+
contractEnrollments,
412403
selectedLanguageKey,
404+
{ contractId: contract.id },
413405
)
414-
const selectedRun = selectedLanguageEnrollment
415-
? ((course.courseruns ?? []).find(
416-
(r) => r.id === selectedLanguageEnrollment.run.id,
417-
) ?? null)
418-
: getCourseRunForSelectedLanguage(course, selectedLanguageKey)
419-
const resolvedRun = getResolvedRunForSelectedLanguage(
420-
course,
421-
selectedLanguageOption,
422-
selectedRun,
423-
selectedLanguageEnrollment,
424-
contract.id,
425-
)
406+
407+
const resource = displayedEnrollment
408+
? {
409+
type: DashboardType.CourseRunEnrollment,
410+
data: displayedEnrollment,
411+
}
412+
: { type: DashboardType.Course, data: course }
413+
426414
return (
427415
<DashboardCardStyled
428416
Component="li"
429417
key={getKey({
430418
resourceType: ResourceType.Course,
431419
id: course.id,
432-
runId: selectedLanguageEnrollment?.run.id ?? resolvedRun?.id,
420+
runId: displayedEnrollment?.run.id ?? displayedRun?.id,
433421
})}
434-
resource={
435-
selectedLanguageEnrollment
436-
? {
437-
type: DashboardType.CourseRunEnrollment,
438-
data: selectedLanguageEnrollment,
439-
}
440-
: { type: DashboardType.Course, data: course }
441-
}
422+
resource={resource}
442423
noun="Module"
443424
offerUpgrade={false}
444425
buttonHref={
445-
selectedLanguageEnrollment?.run.courseware_url ??
446-
resolvedRun?.courseware_url
426+
displayedEnrollment?.run.courseware_url ??
427+
displayedRun?.courseware_url
447428
}
448-
selectedCourseRun={resolvedRun}
429+
selectedCourseRun={displayedRun}
449430
contractId={contract.id}
450431
/>
451432
)
@@ -526,56 +507,37 @@ const OrgProgramDisplay: React.FC<{
526507
courseRunEnrollments?.filter(
527508
(enrollment) => enrollment.b2b_contract_id === contract?.id,
528509
) ?? []
529-
// Prefer the user's existing enrollment for the selected
530-
// language over the next/best run, so older-run enrollments
531-
// stay visible when the contract surfaces a newer run.
532-
const selectedLanguageEnrollment =
533-
selectBestContractEnrollmentForLanguage(
510+
const { displayedEnrollment, displayedRun } =
511+
resolveSlotForLanguage(
534512
course,
535513
contractEnrollments,
536514
selectedLanguageKey,
515+
{ contractId: contract?.id },
537516
)
538-
const selectedLanguageOption = getSelectedLanguageOption(
539-
course,
540-
selectedLanguageKey,
541-
)
542-
const selectedRun = selectedLanguageEnrollment
543-
? ((course.courseruns ?? []).find(
544-
(r) => r.id === selectedLanguageEnrollment.run.id,
545-
) ?? null)
546-
: getCourseRunForSelectedLanguage(course, selectedLanguageKey)
547-
const resolvedRun = getResolvedRunForSelectedLanguage(
548-
course,
549-
selectedLanguageOption,
550-
selectedRun,
551-
selectedLanguageEnrollment,
552-
contract?.id,
553-
)
517+
518+
const resource = displayedEnrollment
519+
? {
520+
type: DashboardType.CourseRunEnrollment,
521+
data: displayedEnrollment,
522+
}
523+
: { type: DashboardType.Course, data: course }
554524

555525
return (
556526
<DashboardCardStyled
557527
Component="li"
558528
key={getKey({
559529
resourceType: ResourceType.Course,
560530
id: course.id,
561-
runId:
562-
selectedLanguageEnrollment?.run.id ?? resolvedRun?.id,
531+
runId: displayedEnrollment?.run.id ?? displayedRun?.id,
563532
})}
564-
resource={
565-
selectedLanguageEnrollment
566-
? {
567-
type: DashboardType.CourseRunEnrollment,
568-
data: selectedLanguageEnrollment,
569-
}
570-
: { type: DashboardType.Course, data: course }
571-
}
533+
resource={resource}
572534
noun="Module"
573535
offerUpgrade={false}
574536
buttonHref={
575-
selectedLanguageEnrollment?.run.courseware_url ??
576-
resolvedRun?.courseware_url
537+
displayedEnrollment?.run.courseware_url ??
538+
displayedRun?.courseware_url
577539
}
578-
selectedCourseRun={resolvedRun}
540+
selectedCourseRun={displayedRun}
579541
contractId={contract?.id}
580542
/>
581543
)
@@ -644,8 +606,13 @@ const ContractContentInternal: React.FC<ContractContentInternalProps> = ({
644606
[coursesQuery.data?.results],
645607
)
646608
const languageOptions = React.useMemo(
647-
() => getDistinctLanguageOptions(contractCourses),
648-
[contractCourses],
609+
() =>
610+
getDistinctDashboardLanguageOptions(
611+
contractCourses,
612+
courseRunEnrollmentsQuery.data ?? [],
613+
{ contractId: contract.id },
614+
),
615+
[contract.id, contractCourses, courseRunEnrollmentsQuery.data],
649616
)
650617
const [selectedLanguageKey, setSelectedLanguageKey] = React.useState("")
651618

@@ -810,7 +777,7 @@ const ContractContentInternal: React.FC<ContractContentInternalProps> = ({
810777
</ProgramCollectionsList>
811778
{programsQuery.data?.results.length === 0 && (
812779
<HeaderRoot>
813-
<Typography variant="h3" component="h1">
780+
<Typography variant="h3" component="h2">
814781
No programs found
815782
</Typography>
816783
</HeaderRoot>

frontends/main/src/app-pages/DashboardPage/CoursewareDisplay/DashboardCard.test.tsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2044,6 +2044,46 @@ describe.each([
20442044
)
20452045
})
20462046

2047+
test.each([{ useProductPages: false }, { useProductPages: true }])(
2048+
"Context menu for program enrollment includes Program Record to mitxonline (flag=$useProductPages)",
2049+
async ({ useProductPages }) => {
2050+
mockedUseFeatureFlagEnabled.mockReturnValue(useProductPages)
2051+
setupUserApis()
2052+
2053+
const program = mitxonline.factories.programs.simpleProgram({
2054+
id: 99,
2055+
readable_id: "program-for-record-test",
2056+
})
2057+
const programEnrollment =
2058+
mitxonline.factories.enrollment.programEnrollmentV3({
2059+
program,
2060+
})
2061+
2062+
renderWithProviders(
2063+
<DashboardCard
2064+
resource={{
2065+
type: DashboardType.ProgramEnrollment,
2066+
data: programEnrollment,
2067+
}}
2068+
/>,
2069+
)
2070+
2071+
const card = getCard()
2072+
const contextMenuButton = within(card).getByRole("button", {
2073+
name: "More options",
2074+
})
2075+
await user.click(contextMenuButton)
2076+
2077+
const programRecordItem = screen.getByRole("menuitem", {
2078+
name: "Program Record",
2079+
})
2080+
expect(programRecordItem).toHaveAttribute(
2081+
"href",
2082+
mitxonlineLegacyUrl("/records/99/"),
2083+
)
2084+
},
2085+
)
2086+
20472087
test.each([{ useProductPages: false }, { useProductPages: true }])(
20482088
"Context menu for course enrollment shows View Details (flag=$useProductPages) using readable_id",
20492089
async ({ useProductPages }) => {

frontends/main/src/app-pages/DashboardPage/CoursewareDisplay/DashboardCard.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,13 @@ const getContextMenuItems = (
205205
})
206206
}
207207

208+
menuItems.push({
209+
className: "dashboard-card-menu-item",
210+
key: "program-record",
211+
label: "Program Record",
212+
href: mitxonlineLegacyUrl(`/records/${program.id}/`),
213+
})
214+
208215
if (
209216
program.display_mode !== DisplayModeEnum.Course &&
210217
!isVerifiedEnrollmentMode(resource.data.enrollment_mode)

0 commit comments

Comments
 (0)