Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions RELEASE.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
Release Notes
=============

Version 0.51.1
--------------

- Product Page Updates (#2839)
- feat: add course detail in resource card (#2834)
- memory optimizations for embedding process (#2841)
- fix: add delete button for image and media node (#2836)
- fix: editor component migration into main app (#2833)

Version 0.51.0 (Released January 08, 2026)
--------------

Expand Down
850 changes: 257 additions & 593 deletions frontends/api/src/generated/v1/api.ts

Large diffs are not rendered by default.

11 changes: 3 additions & 8 deletions frontends/api/src/hooks/learningResources/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import {
schoolQueries,
platformsQueries,
learningResourceKeys,
clearListMemberships,
} from "./queries"
import { userlistKeys } from "../userLists/queries"
import { learningPathKeys } from "../learningPaths/queries"
Expand Down Expand Up @@ -66,15 +65,11 @@ const useLearningResourcesBulkList = (
const queryClient = useQueryClient()

return useQuery({
queryKey: learningResourceKeys.bulk(ids),
...learningResourceQueries.list({ resource_id: ids }),
enabled: options?.enabled && ids.length > 0,

queryFn: async () => {
const res = (await learningResourcesApi.learningResourcesBulkList({
ids: ids.join(","),
})) as { data: LearningResource[] }

const resources = res.data.map(clearListMemberships)
select: (data) => {
const resources = data.results

resources.forEach((resource) => {
queryClient.setQueryData(
Expand Down
10 changes: 0 additions & 10 deletions frontends/api/src/hooks/learningResources/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,16 +125,6 @@ const learningResourceQueries = {
.learningResourcesRetrieve({ id })
.then((res) => clearListMemberships(res.data)),
}),
learningResourcesBulkList: (ids: string) =>
queryOptions({
queryKey: [...learningResourceKeys.root, "bulk", ids],
queryFn: () =>
learningResourcesApi
.learningResourcesBulkList({ ids })
.then((res) =>
res.data.map((resource) => clearListMemberships(resource)),
),
}),
items: (id: number, params: ItemsListRequest) =>
queryOptions({
queryKey: learningResourceKeys.items(id, params),
Expand Down
17 changes: 17 additions & 0 deletions frontends/main/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,28 @@
"@mitodl/course-search-utils": "^3.5.0",
"@mitodl/mitxonline-api-axios": "^2025.11.24",
"@mitodl/smoot-design": "^6.19.0",
"@mui/material": "^6.4.5",
"@mui/material-nextjs": "^6.4.3",
"@next/bundle-analyzer": "^14.2.15",
"@react-pdf/renderer": "^4.3.0",
"@remixicon/react": "^4.2.0",
"@sentry/nextjs": "^10.0.0",
"@tanstack/react-query": "^5.66",
"@tiptap/core": "^3.13.0",
"@tiptap/extension-document": "^3.13.0",
"@tiptap/extension-heading": "^3.13.0",
"@tiptap/extension-highlight": "^3.13.0",
"@tiptap/extension-horizontal-rule": "^3.13.0",
"@tiptap/extension-image": "^3.13.0",
"@tiptap/extension-list": "^3.13.0",
"@tiptap/extension-subscript": "^3.13.0",
"@tiptap/extension-superscript": "^3.13.0",
"@tiptap/extension-text-align": "^3.13.0",
"@tiptap/extension-typography": "^3.13.0",
"@tiptap/extensions": "^3.13.0",
"@tiptap/pm": "^3.13.0",
"@tiptap/react": "^3.13.0",
"@tiptap/starter-kit": "^3.13.0",
"api": "workspace:*",
"async_hooks": "^1.0.0",
"classnames": "^2.5.1",
Expand Down
3 changes: 2 additions & 1 deletion frontends/main/src/app-pages/Articles/ArticleDetailPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

import React from "react"
import { useArticleDetailRetrieve } from "api/hooks/articles"
import { LoadingSpinner, ArticleEditor, styled } from "ol-components"
import { LoadingSpinner, styled } from "ol-components"
import { ArticleEditor } from "@/page-components/TiptapEditor/ArticleEditor"
import { notFound } from "next/navigation"
import { useFeatureFlagEnabled } from "posthog-js/react"
import { FeatureFlags } from "@/common/feature_flags"
Expand Down
3 changes: 2 additions & 1 deletion frontends/main/src/app-pages/Articles/ArticleEditPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { notFound } from "next/navigation"
import { Permission } from "api/hooks/user"
import { useArticleDetailRetrieve } from "api/hooks/articles"
import RestrictedRoute from "@/components/RestrictedRoute/RestrictedRoute"
import { styled, LoadingSpinner, ArticleEditor } from "ol-components"
import { styled, LoadingSpinner } from "ol-components"
import { ArticleEditor } from "@/page-components/TiptapEditor/ArticleEditor"
import { articlesView } from "@/common/urls"

const PageContainer = styled.div(({ theme }) => ({
Expand Down
3 changes: 2 additions & 1 deletion frontends/main/src/app-pages/Articles/ArticleNewPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import React from "react"
import { useRouter } from "next-nprogress-bar"
import { Permission } from "api/hooks/user"
import RestrictedRoute from "@/components/RestrictedRoute/RestrictedRoute"
import { ArticleEditor, styled } from "ol-components"
import { styled } from "ol-components"
import { ArticleEditor } from "@/page-components/TiptapEditor/ArticleEditor"
import { articlesView } from "@/common/urls"

const PageContainer = styled.div(({ theme }) => ({
Expand Down
4 changes: 2 additions & 2 deletions frontends/main/src/app-pages/ProductPages/CoursePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ const CoursePage: React.FC<CoursePageProps> = ({ readableId }) => {
)
const page = pages.data?.items[0]
const course = courses.data?.results?.[0]
const enabled = useFeatureFlagEnabled(FeatureFlags.ProductPageCourse)
const enabled = useFeatureFlagEnabled(FeatureFlags.MitxOnlineProductPages)
const flagsLoaded = useFeatureFlagsLoaded()

if (!enabled) {
Expand All @@ -102,7 +102,7 @@ const CoursePage: React.FC<CoursePageProps> = ({ readableId }) => {

return (
<ProductPageTemplate
offeredBy="MITx"
tags={["MITx"]}
currentBreadcrumbLabel="Course"
title={page.title}
shortDescription={page.course_details.page.description}
Expand Down
23 changes: 11 additions & 12 deletions frontends/main/src/app-pages/ProductPages/ProductPageTemplate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,14 @@ const StyledBreadcrumbs = styled(Breadcrumbs)(({ theme }) => ({
const TitleBox = styled(Stack)(({ theme }) => ({
color: theme.custom.colors.white,
}))
const OfferedByTag = styled.div(({ theme }) => ({
const ProductTag = styled.div(({ theme }) => ({
backgroundColor: theme.custom.colors.darkGray1,
display: "flex",
alignItems: "center",
justifyContent: "center",
height: "32px",
padding: "0 12px",
padding: "4px 12px",
borderRadius: "4px",
marginBottom: "4px",
...theme.typography.subtitle1,
[theme.breakpoints.down("md")]: {
display: "none",
},
...theme.typography.subtitle2,
}))

const Page = styled.div(({ theme }) => ({
Expand Down Expand Up @@ -162,7 +157,7 @@ type HeadingData = {
}

type ProductPageTemplateProps = {
offeredBy: string
tags: string[]
currentBreadcrumbLabel: string
title: string
shortDescription: React.ReactNode
Expand All @@ -172,7 +167,7 @@ type ProductPageTemplateProps = {
navLinks: HeadingData[]
}
const ProductPageTemplate: React.FC<ProductPageTemplateProps> = ({
offeredBy,
tags,
currentBreadcrumbLabel,
title,
shortDescription,
Expand All @@ -183,15 +178,19 @@ const ProductPageTemplate: React.FC<ProductPageTemplateProps> = ({
return (
<Page>
<BannerBackground backgroundUrl={backgroundSrcSetCSS(backgroundSteps)}>
<TopContainer>
<TopContainer data-testid="banner-container">
<MainCol>
<StyledBreadcrumbs
variant="dark"
ancestors={[{ href: HOME, label: "Home" }]}
current={currentBreadcrumbLabel}
/>
<TitleBox alignItems="flex-start" gap="4px">
<OfferedByTag>{offeredBy}</OfferedByTag>
<Stack direction="row" gap="8px">
{tags.map((tag) => {
return <ProductTag key={tag}>{tag}</ProductTag>
})}
</Stack>
<Stack alignItems="flex-start" gap="16px">
<Typography component="h1" typography={{ xs: "h3", sm: "h2" }}>
{title}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ describe("Program Pacing Row", () => {
)
const summary = screen.getByRole("region", { name: "Program summary" })
const paceRow = within(summary).getByTestId(TestIds.PaceRow)
expect(paceRow).toHaveTextContent(`Program Format: ${expected}`)
expect(paceRow).toHaveTextContent(`Course Format: ${expected}`)
})

test.each([
Expand Down Expand Up @@ -495,21 +495,18 @@ describe("Price & Certificate Row", () => {

expect(priceRow).toHaveTextContent("Free to Learn")
})
})

describe("Program Certificate Track Row", () => {
test("Renders certificate information", () => {
const program = factories.programs.program()
invariant(program.page.price)
renderWithProviders(
<ProgramSummary program={program} programResource={null} />,
)

const summary = screen.getByRole("region", { name: "Program summary" })
const certRow = within(summary).getByTestId(TestIds.CertificateTrackRow)
const certRow = within(summary).getByTestId(TestIds.PriceRow)

expect(certRow).toHaveTextContent("Certificate Track")
expect(certRow).toHaveTextContent(
`${program.min_price}\u2013$${program.max_price}`,
)
expect(certRow).toHaveTextContent(program.page.price)
})
})
Loading
Loading