Skip to content

Commit 07ad5f2

Browse files
Migrate Storybook for Next.js (#1525)
* Next.js Initial Migration (#1505) * Next.js scaffold * Supply env vars on process.env.NEXT_PUBLIC_ * Replace react-router hook with next/navigation * MUI theme provider for Next.js * Styled elements * Restructuring to bring pages and components into ssr project * Images and link fixes * Set up prerendering with React Query and fetch Featured Courses carousel on server * Head meta tags * Main entrypoint. Include in yarn workspaces. API URL for local * Add remaining homepage sections * Move into frontends * Lint fixes * Routed drawer and updates for homepage resource drawer search triggers * Move pages (conflict with Next.js Pages Router) * Webpack configs for babel loader (import type) and ignore test files from build * Typescript config, move common/urls * Updates towards successful build * Suspense boudary for header useSearchParam * Provide origin on environment (cannot reference window) * Update drawer hooks for next/navigation * Unit listing page and dependencies * Image fixes. ol-component compatibility updates * Logo image fixes and footer image * Search page * Remove temp course-serach-utils * Remove temp course-serach-utils * Channel Page. Rewrite for image paths * Move @mui/material-nextjs into ol-components * Department listing page * Topic listing page * Terms page * Privacy page * Image paths * Lockfile * Migrates the dashboard pages * Migrate learning path listing page * Migrate learning path details page * Prettier fixes * Migrate test utils. Fixes for passing typechecks on test files (excluding React Router dependencies) * Migrate the onboarding page * Migrate program letter page * Migrate error page * Resolves issue with Server Components treated as Client Components (transpiler). Wraps library imports for use in Next.js. User lists detail page. * Metadata utility * Fetch learning resource for metadata when drawer is open * Async and sync metadata utilities * .env example file * Preserve hero image aspect * Put back SliderInput * Fix linting on nextjs branch (#1509) Resolve linting errors for nextjs branch and introduce nextjs linting plugin * Fixes for successful build (#1516) - Removes unnecessary Client Component wrappers and "use client" directives. - Set `<Suspense />` boundaries to client render components that useSearchParams() around: - all of the Search page. - the Learning Resource drawer. - the dashboard carousels. * Move Storybook root to ol-components * Move GlobalStyles to ol-components * Self contained images * Storybook for Next.js * Remove react-router addon. Upgrade Storybook addons * Fix issue trying to resolve react-dom/test-utils. Storybook 8 migration script package updates * Local image * Replace react-router useLocation * Images fixes. Copy images into ol-components. Embedly fallback * Migrate routed drawer stories for @storybook/nextjs * Next.js Initial Migration (#1505) * Next.js scaffold * Supply env vars on process.env.NEXT_PUBLIC_ * Replace react-router hook with next/navigation * MUI theme provider for Next.js * Styled elements * Restructuring to bring pages and components into ssr project * Images and link fixes * Set up prerendering with React Query and fetch Featured Courses carousel on server * Head meta tags * Main entrypoint. Include in yarn workspaces. API URL for local * Add remaining homepage sections * Move into frontends * Lint fixes * Routed drawer and updates for homepage resource drawer search triggers * Move pages (conflict with Next.js Pages Router) * Webpack configs for babel loader (import type) and ignore test files from build * Typescript config, move common/urls * Updates towards successful build * Suspense boudary for header useSearchParam * Provide origin on environment (cannot reference window) * Update drawer hooks for next/navigation * Unit listing page and dependencies * Image fixes. ol-component compatibility updates * Logo image fixes and footer image * Search page * Remove temp course-serach-utils * Remove temp course-serach-utils * Channel Page. Rewrite for image paths * Move @mui/material-nextjs into ol-components * Department listing page * Topic listing page * Terms page * Privacy page * Image paths * Lockfile * Migrates the dashboard pages * Migrate learning path listing page * Migrate learning path details page * Prettier fixes * Migrate test utils. Fixes for passing typechecks on test files (excluding React Router dependencies) * Migrate the onboarding page * Migrate program letter page * Migrate error page * Resolves issue with Server Components treated as Client Components (transpiler). Wraps library imports for use in Next.js. User lists detail page. * Metadata utility * Fetch learning resource for metadata when drawer is open * Async and sync metadata utilities * .env example file * Preserve hero image aspect * Put back SliderInput * Fix linting on nextjs branch (#1509) Resolve linting errors for nextjs branch and introduce nextjs linting plugin * Fixes for successful build (#1516) - Removes unnecessary Client Component wrappers and "use client" directives. - Set `<Suspense />` boundaries to client render components that useSearchParams() around: - all of the Search page. - the Learning Resource drawer. - the dashboard carousels. * Enable Storybook action * Enable Storybook action * Update lockfile * Use client directive missing from layout --------- Co-authored-by: Chris Chudzicki <christopher.chudzicki@gmail.com>
1 parent 19c13e5 commit 07ad5f2

Some content is hidden

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

51 files changed

+2740
-1308
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ jobs:
180180
run: yarn install
181181

182182
- name: Build Storybook
183-
run: yarn workspace mit-learn build-storybook
183+
run: yarn workspace ol-components build-storybook
184184

185185
openapi-generated-client-check-v0:
186186
# This job checks that the output of openapi-generator-typescript-axios that

frontends/main/src/app-pages/ChannelPage/ChannelPage.tsx

Lines changed: 1 addition & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -11,72 +11,17 @@ import type {
1111
BooleanFacets,
1212
} from "@mitodl/course-search-utils"
1313
import { ChannelTypeEnum } from "api/v0"
14-
import { useLearningResourceTopics } from "api/hooks/learningResources"
15-
import { ChipLink, Container, styled, Typography } from "ol-components"
16-
import { propsNotNil } from "ol-utilities"
1714
import LearningResourceDrawer from "@/page-components/LearningResourceDrawer/LearningResourceDrawer"
1815

19-
const SubTopicsContainer = styled(Container)(({ theme }) => ({
20-
marginBottom: "60px",
21-
[theme.breakpoints.down("sm")]: {
22-
marginBottom: "24px",
23-
},
24-
}))
25-
26-
const SubTopicsHeader = styled(Typography)(({ theme }) => ({
27-
marginBottom: "10px",
28-
...theme.typography.subtitle1,
29-
}))
30-
31-
const ChipsContainer = styled.div({
32-
display: "flex",
33-
flexWrap: "wrap",
34-
gap: "12px",
35-
})
36-
3716
type RouteParams = {
3817
channelType: ChannelTypeEnum
3918
name: string
4019
}
4120

42-
type SubTopicDisplayProps = {
43-
parentTopicId: number
44-
}
45-
46-
const SubTopicsDisplay: React.FC<SubTopicDisplayProps> = (props) => {
47-
const { parentTopicId } = props
48-
const topicsQuery = useLearningResourceTopics({
49-
parent_topic_id: [parentTopicId],
50-
})
51-
const totalSubtopics = topicsQuery.data?.results.length ?? 0
52-
const subTopics = topicsQuery.data?.results.filter(
53-
propsNotNil(["channel_url"]),
54-
)
55-
return (
56-
totalSubtopics > 0 && (
57-
<SubTopicsContainer>
58-
<SubTopicsHeader>Related Topics</SubTopicsHeader>
59-
<ChipsContainer>
60-
{subTopics?.map((topic) => (
61-
<ChipLink
62-
size="large"
63-
variant="outlinedWhite"
64-
key={topic.id}
65-
href={topic.channel_url}
66-
label={topic.name}
67-
/>
68-
))}
69-
</ChipsContainer>
70-
</SubTopicsContainer>
71-
)
72-
)
73-
}
74-
7521
const ChannelPage: React.FC = () => {
7622
const { channelType, name } = useParams<RouteParams>()
7723
const channelQuery = useChannelDetail(String(channelType), String(name))
7824
const searchParams: Facets & BooleanFacets = {}
79-
const publicDescription = channelQuery.data?.public_description
8025

8126
if (channelQuery.data?.search_filter) {
8227
const urlParams = new URLSearchParams(channelQuery.data.search_filter)
@@ -97,15 +42,7 @@ const ChannelPage: React.FC = () => {
9742
<>
9843
<LearningResourceDrawer />
9944
<ChannelPageTemplate name={name} channelType={channelType}>
100-
{publicDescription && (
101-
<Typography variant="body1">{publicDescription}</Typography>
102-
)}
103-
{channelQuery.data?.channel_type === ChannelTypeEnum.Topic &&
104-
channelQuery.data?.topic_detail?.topic ? (
105-
<SubTopicsDisplay
106-
parentTopicId={channelQuery.data?.topic_detail?.topic}
107-
/>
108-
) : null}
45+
<p>{channelQuery.data?.public_description}</p>
10946
{channelQuery.data?.search_filter && (
11047
<ChannelSearch
11148
channelTitle={channelQuery.data.title}

frontends/main/src/app-pages/LearningPathDetailsPage/ListDetailsPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const ListDetailsPage: React.FC<ItemsListingComponentProps> = ({
2020
}) => {
2121
return (
2222
<BannerPage
23-
src="/static/images/course_search_banner.png"
23+
src="/images/backgrounds/course_search_banner.png"
2424
className="learningpaths-page"
2525
>
2626
{/* TODO <MetaTags title={list?.title} social={false} /> */}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import "slick-carousel/slick/slick.css"
2+
import "slick-carousel/slick/slick-theme.css"

frontends/main/src/app/layout.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1+
"use client"
2+
13
import React from "react"
24
import Header from "@/page-components/Header/Header"
35
import Footer from "@/page-components/Footer/Footer"
46
import { PageWrapper, PageWrapperInner } from "./styled"
57
import Providers from "./providers"
6-
import GlobalStyles from "./GlobalStyles"
8+
import { MITLearnGlobalStyles } from "ol-components"
9+
10+
import "./GlobalStyles"
711

812
export default function RootLayout({
913
children,
@@ -14,7 +18,7 @@ export default function RootLayout({
1418
<html lang="en">
1519
<body>
1620
<Providers>
17-
<GlobalStyles />
21+
<MITLearnGlobalStyles />
1822
<PageWrapper>
1923
<Header />
2024
<PageWrapperInner>{children}</PageWrapperInner>

frontends/mit-learn/.storybook/main.ts

Lines changed: 0 additions & 49 deletions
This file was deleted.

frontends/mit-learn/package.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@
1111
"watch": "NODE_ENV=development LOAD_ENV_FILES=true webpack serve",
1212
"watch:docker": "NODE_ENV=development webpack serve",
1313
"build": "webpack --config webpack.config.js --bail",
14-
"build-exports": "webpack --config webpack.exports.js --bail",
15-
"storybook": "storybook dev -p 6006",
16-
"build-storybook": "storybook build"
14+
"build-exports": "webpack --config webpack.exports.js --bail"
1715
},
1816
"devDependencies": {
1917
"@emotion/react": "^11.11.1",
@@ -23,7 +21,6 @@
2321
"@storybook/addon-essentials": "^8.0.9",
2422
"@storybook/addon-interactions": "^8.0.9",
2523
"@storybook/addon-links": "^8.0.9",
26-
"@storybook/addon-webpack5-compiler-swc": "^1.0.2",
2724
"@storybook/blocks": "^8.0.9",
2825
"@storybook/react": "^8.0.9",
2926
"@storybook/react-webpack5": "^8.0.9",
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { resolve, join, dirname } from "path"
2+
import * as dotenv from "dotenv"
3+
import * as webpack from "webpack"
4+
import { StorybookConfig } from '@storybook/nextjs';
5+
6+
dotenv.config({ path: resolve(__dirname, "../../../.env") })
7+
8+
/**
9+
* This function is used to resolve the absolute path of a package.
10+
* It is needed in projects that use Yarn PnP or are set up within a monorepo.
11+
*/
12+
function getAbsolutePath(value: string) {
13+
return dirname(require.resolve(join(value, "package.json")))
14+
}
15+
16+
const config: StorybookConfig = {
17+
stories: [
18+
"../src/**/*.mdx",
19+
"../src/**/*.stories.tsx",
20+
"../../ol-components/src/**/*.mdx",
21+
"../../ol-components/src/**/*.stories.@(tsx|ts)",
22+
],
23+
24+
staticDirs: ["./public"],
25+
26+
addons: [
27+
getAbsolutePath("@storybook/addon-links"),
28+
getAbsolutePath("@storybook/addon-essentials"),
29+
getAbsolutePath("@storybook/addon-interactions"),
30+
getAbsolutePath("@storybook/addon-webpack5-compiler-swc"),
31+
getAbsolutePath("@storybook/addon-mdx-gfm")
32+
],
33+
34+
framework: {
35+
name: getAbsolutePath("@storybook/nextjs"),
36+
options: {}
37+
},
38+
39+
docs: {},
40+
41+
webpackFinal: async (config: any) => {
42+
config.plugins.push(
43+
new webpack.DefinePlugin({
44+
APP_SETTINGS: {
45+
EMBEDLY_KEY: JSON.stringify(process.env.EMBEDLY_KEY),
46+
PUBLIC_URL: JSON.stringify(process.env.PUBLIC_URL),
47+
},
48+
}),
49+
)
50+
51+
52+
/* Fix for this error:
53+
Module not found: Error: Can't resolve 'react-dom/test-utils' in './node_modules/@testing-library/react/dist/@testing-library'
54+
55+
Described here: https://github.com/vercel/next.js/issues/55620
56+
57+
react-dom/test-utils is deprecated and replaced with @testing-library/react and @storybook/nextjs introduces an incompatibility.
58+
The fix is to use @storybook/test in place of @testing-library/react, which provides the same API.
59+
The issue is that we are using factories from api/test-utils, which imports ol-test-utilities, which imports @testing-library/react, which itself requires react-dom/test-utils,
60+
We should not use @storybook packages in ol-test-utilities or anywhere outside of ol-components as they are not related
61+
so below we are aliasing @testing-library/react.
62+
*/
63+
config.resolve = {
64+
...config.resolve,
65+
alias: {
66+
...config.resolve?.alias,
67+
"@testing-library/react": "@storybook/test"
68+
}
69+
}
70+
71+
return config
72+
},
73+
74+
typescript: {
75+
reactDocgen: "react-docgen-typescript"
76+
}
77+
}
78+
79+
export default config

0 commit comments

Comments
 (0)