Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor hardcoded layout strings #834

Closed
wants to merge 11 commits into from
3 changes: 2 additions & 1 deletion apps/studio/prisma/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* @link https://www.prisma.io/docs/guides/database/seed-database
*/
import type { IsomerSchema } from "@opengovsg/isomer-components"
import { ISOMER_PAGE_LAYOUTS } from "@opengovsg/isomer-components"
import cuid2 from "@paralleldrive/cuid2"

import type { Navbar } from "~/server/modules/resource/resource.types"
Expand Down Expand Up @@ -40,7 +41,7 @@ const PUBLISHER_USER = "publisher"

const PAGE_BLOB: IsomerSchema = {
version: "0.1.0",
layout: "homepage",
layout: ISOMER_PAGE_LAYOUTS.Homepage,
page: {},
content: [
{
Expand Down
5 changes: 3 additions & 2 deletions apps/studio/src/components/PageEditor/ComponentSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
VStack,
} from "@chakra-ui/react"
import { Button } from "@opengovsg/design-system-react"
import { ISOMER_PAGE_LAYOUTS } from "@opengovsg/isomer-components"
import { ResourceType } from "~prisma/generated/generatedEnums"
import { type IconType } from "react-icons"

Expand Down Expand Up @@ -168,9 +169,9 @@ function ComponentSelector() {
case ResourceType.RootPage:
return HOMEPAGE_ALLOWED_BLOCKS
case ResourceType.Page:
if (savedPageState.layout === "content") {
if (savedPageState.layout === ISOMER_PAGE_LAYOUTS.Content) {
return CONTENT_ALLOWED_BLOCKS
} else if (savedPageState.layout === "article") {
} else if (savedPageState.layout === ISOMER_PAGE_LAYOUTS.Article) {
return ARTICLE_ALLOWED_BLOCKS
}
throw new Error(`Unsupported page layout: ${savedPageState.layout}`)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { IsomerSchema } from "@opengovsg/isomer-components"
import type { PropsWithChildren } from "react"
import { createContext, useContext, useMemo, useState } from "react"
import { useRouter } from "next/router"
import { ISOMER_PAGE_LAYOUTS } from "@opengovsg/isomer-components"
import { merge } from "lodash"

import articleLayoutPreview from "~/features/editing-experience/data/articleLayoutPreview.json"
Expand Down Expand Up @@ -60,15 +61,17 @@ const useCreatePageWizardContext = ({
defaultValues: {
title: "",
permalink: "",
layout: "content",
layout: ISOMER_PAGE_LAYOUTS.Content,
},
})

const [layout, title] = formMethods.watch(["layout", "title"])

const layoutPreviewJson: IsomerSchema = useMemo(() => {
const jsonPreview =
layout === "content" ? contentLayoutPreview : articleLayoutPreview
layout === ISOMER_PAGE_LAYOUTS.Content
? contentLayoutPreview
: articleLayoutPreview
return merge(jsonPreview, {
page: {
title: title || "Page title here",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useMemo } from "react"
import { Box, Flex, Skeleton, Stack, Text } from "@chakra-ui/react"
import { useIsMobile } from "@opengovsg/design-system-react"
import { ISOMER_PAGE_LAYOUTS } from "@opengovsg/isomer-components"
import { format } from "date-fns"

import Suspense from "~/components/Suspense"
Expand Down Expand Up @@ -67,14 +68,14 @@ const SuspendableLayoutPreview = () => {

const previewOverrides = useMemo(() => {
switch (currentLayout) {
case "article": {
case ISOMER_PAGE_LAYOUTS.Article: {
return {
page: {
date: format(new Date(), "dd MMM yyyy"),
},
}
}
case "content": {
case ISOMER_PAGE_LAYOUTS.Content: {
return {}
}
}
Expand All @@ -91,7 +92,7 @@ const SuspendableLayoutPreview = () => {
permalink={currentPermalink}
siteMap={{
id: "0",
layout: "content",
layout: ISOMER_PAGE_LAYOUTS.Content,
title: "Root",
summary: "",
lastModified: new Date().toISOString(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
export const LAYOUT_TYPES = ["content", "article"] as const
import { ISOMER_PAGE_LAYOUTS } from "@opengovsg/isomer-components"

export const LAYOUT_TYPES = [
ISOMER_PAGE_LAYOUTS.Content,
ISOMER_PAGE_LAYOUTS.Article,
] as const
export type Layout = (typeof LAYOUT_TYPES)[number]

export const LAYOUT_RENDER_DATA: Record<
Expand All @@ -10,13 +15,13 @@ export const LAYOUT_RENDER_DATA: Record<
altText: string
}
> = {
content: {
[ISOMER_PAGE_LAYOUTS.Content]: {
title: "Default layout",
description: "This is the most basic layout for your content.",
imageSrc: "/assets/layout-card/default_layout_card.webp",
altText: "Image preview of Default layout",
},
article: {
[ISOMER_PAGE_LAYOUTS.Article]: {
title: "Article layout",
description:
"Designed for the perfect reading experience. Use this layout for text-heavy content, such as news, press releases, and speeches.",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { IsomerSitemap } from "@opengovsg/isomer-components"
import { ISOMER_PAGE_LAYOUTS } from "@opengovsg/isomer-components"
import { ResourceType } from "~prisma/generated/generatedEnums"
import { useAtomValue } from "jotai"

Expand Down Expand Up @@ -32,15 +33,15 @@ export const EditCollectionLinkPreview = (): JSX.Element => {
id: "root",
permalink: "/",
lastModified: "2024-10-14T07:05:08.803Z",
layout: "homepage",
layout: ISOMER_PAGE_LAYOUTS.Homepage,
title: "An Isomer Site",
summary: "",
children: [
{
id: "collection",
permalink: parentPermalink,
lastModified: "02 May 2023",
layout: "collection",
layout: ISOMER_PAGE_LAYOUTS.Collection,
title: parentTitle,
summary: "",
children: [
Expand All @@ -50,7 +51,7 @@ export const EditCollectionLinkPreview = (): JSX.Element => {
date,
ref: "Test",
summary: summary ?? "",
layout: "link",
layout: ISOMER_PAGE_LAYOUTS.Link,
permalink,
lastModified: new Date().toString(),
category,
Expand All @@ -65,7 +66,7 @@ export const EditCollectionLinkPreview = (): JSX.Element => {
<PreviewWithoutSitemap
content={[]}
page={{ title: parentTitle }}
layout={"collection"}
layout={ISOMER_PAGE_LAYOUTS.Collection}
siteId={siteId}
siteMap={siteMap}
permalink={parentPermalink}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import type { Static } from "@sinclair/typebox"
import { useCallback } from "react"
import { Box, Flex, useDisclosure } from "@chakra-ui/react"
import { Button } from "@opengovsg/design-system-react"
import { getLayoutPageSchema } from "@opengovsg/isomer-components"
import {
getLayoutPageSchema,
ISOMER_PAGE_LAYOUTS,
} from "@opengovsg/isomer-components"
import Ajv from "ajv"
import isEmpty from "lodash/isEmpty"
import isEqual from "lodash/isEqual"
Expand All @@ -18,8 +21,8 @@ import { ErrorProvider, useBuilderErrors } from "./form-builder/ErrorProvider"
import FormBuilder from "./form-builder/FormBuilder"

const HEADER_LABELS: Record<string, string> = {
article: "Edit article page header",
content: "Edit content page header",
[ISOMER_PAGE_LAYOUTS.Article]: "Edit article page header",
[ISOMER_PAGE_LAYOUTS.Content]: "Edit content page header",
}

const ajv = new Ajv({ strict: false, logger: false })
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import type { DropResult } from "@hello-pangea/dnd"
import type { ISOMER_USABLE_PAGE_LAYOUTS } from "@opengovsg/isomer-components"
import { useCallback } from "react"
import { Box, Button, Flex, Icon, Text, VStack } from "@chakra-ui/react"
import { DragDropContext, Droppable } from "@hello-pangea/dnd"
import { useToast } from "@opengovsg/design-system-react"
import { ISOMER_PAGE_LAYOUTS } from "@opengovsg/isomer-components"
import { BiPin, BiPlus, BiPlusCircle } from "react-icons/bi"

import { BlockEditingPlaceholder } from "~/components/Svg"
Expand Down Expand Up @@ -110,10 +112,11 @@ export default function RootStateDrawer() {
],
)

const pageLayout: string = savedPageState.layout
const pageLayout: (typeof ISOMER_USABLE_PAGE_LAYOUTS)[keyof typeof ISOMER_USABLE_PAGE_LAYOUTS] =
savedPageState.layout

const isHeroFixedBlock =
pageLayout === "homepage" &&
pageLayout === ISOMER_PAGE_LAYOUTS.Homepage &&
savedPageState.content.length > 0 &&
savedPageState.content[0]?.type === "hero"

Expand Down
8 changes: 4 additions & 4 deletions apps/studio/src/schemas/page.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { IsomerSchema } from "@opengovsg/isomer-components"
import { schema } from "@opengovsg/isomer-components"
import { ISOMER_PAGE_LAYOUTS, schema } from "@opengovsg/isomer-components"
import { ResourceState, ResourceType } from "~prisma/generated/generatedEnums"
import { z } from "zod"

Expand All @@ -10,8 +10,8 @@ import { generateBasePermalinkSchema } from "./common"
const schemaValidator = ajv.compile<IsomerSchema>(schema)

const NEW_PAGE_LAYOUT_VALUES = [
"article",
"content",
ISOMER_PAGE_LAYOUTS.Article,
ISOMER_PAGE_LAYOUTS.Content,
] as const satisfies readonly PrismaJson.BlobJsonContent["layout"][]

export const MAX_TITLE_LENGTH = 150
Expand Down Expand Up @@ -70,7 +70,7 @@ export const updatePageBlobSchema = basePageSchema.extend({
export const createPageSchema = z.object({
title: pageTitleSchema,
permalink: permalinkSchema,
layout: z.enum(NEW_PAGE_LAYOUT_VALUES).default("content"),
layout: z.enum(NEW_PAGE_LAYOUT_VALUES).default(ISOMER_PAGE_LAYOUTS.Content),
siteId: z.number().min(1),
// NOTE: implies that top level pages are allowed
folderId: z.number().min(1).optional(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { UnwrapTagged } from "type-fest"
import { ISOMER_PAGE_LAYOUTS } from "@opengovsg/isomer-components"
import { format } from "date-fns"

import type { ResourceType } from "../database"
Expand All @@ -7,7 +8,7 @@ export const createCollectionPageJson = ({}: {
type: typeof ResourceType.CollectionPage // Act as soft typeguard
}) => {
return {
layout: "article",
layout: ISOMER_PAGE_LAYOUTS.Article,
page: {
date: format(new Date(), "dd/MM/yyyy"),
// TODO: this is actually supposed to be passed from the frontend
Expand All @@ -26,7 +27,7 @@ export const createCollectionLinkJson = ({}: {
type: typeof ResourceType.CollectionLink // Act as soft typeguard
}) => {
return {
layout: "link",
layout: ISOMER_PAGE_LAYOUTS.Link,
page: {
ref: "",
summary: "",
Expand Down
23 changes: 12 additions & 11 deletions apps/studio/src/server/modules/page/__tests__/page.router.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { IsomerSchema } from "@opengovsg/isomer-components"
import type { z } from "zod"
import { ISOMER_PAGE_LAYOUTS } from "@opengovsg/isomer-components"
import { TRPCError } from "@trpc/server"
import { ResourceState } from "~prisma/generated/generatedEnums"
import { omit, pick } from "lodash"
Expand Down Expand Up @@ -574,7 +575,7 @@ describe("page.router", async () => {
siteId: page.siteId,
content: JSON.stringify({
content: NEW_PAGE_BLOCKS,
layout: "content",
layout: ISOMER_PAGE_LAYOUTS.Content,
page: pick(page, ["title", "permalink"]),
version: "0.1.0",
} as UpdatePageOutput["content"]),
Expand Down Expand Up @@ -704,7 +705,7 @@ describe("page.router", async () => {
siteId: 1,
title: "Test Page",
permalink: "test-page",
layout: "content",
layout: ISOMER_PAGE_LAYOUTS.Content,
})

await expect(result).rejects.toThrowError(
Expand All @@ -718,7 +719,7 @@ describe("page.router", async () => {
siteId: 999999, // should not exist
title: "Test Page",
permalink: "test-page",
layout: "content",
layout: ISOMER_PAGE_LAYOUTS.Content,
})

// Assert
Expand All @@ -744,7 +745,7 @@ describe("page.router", async () => {
siteId: site.id,
title: "Test Page",
permalink: page.permalink,
layout: "content",
layout: ISOMER_PAGE_LAYOUTS.Content,
})

// Assert
Expand Down Expand Up @@ -772,7 +773,7 @@ describe("page.router", async () => {
// Act
const result = await caller.createPage({
...expectedPageArgs,
layout: "content",
layout: ISOMER_PAGE_LAYOUTS.Content,
})

// Assert
Expand All @@ -787,7 +788,7 @@ describe("page.router", async () => {
})
expect(actual).toMatchObject({
...expectedPageArgs,
content: createDefaultPage({ layout: "content" }),
content: createDefaultPage({ layout: ISOMER_PAGE_LAYOUTS.Content }),
})
})

Expand All @@ -807,7 +808,7 @@ describe("page.router", async () => {
// Act
const result = await caller.createPage({
...expectedPageArgs,
layout: "article",
layout: ISOMER_PAGE_LAYOUTS.Article,
})

// Assert
Expand All @@ -822,7 +823,7 @@ describe("page.router", async () => {
})
expect(actual).toMatchObject({
...expectedPageArgs,
content: createDefaultPage({ layout: "article" }),
content: createDefaultPage({ layout: ISOMER_PAGE_LAYOUTS.Article }),
})
})

Expand Down Expand Up @@ -856,7 +857,7 @@ describe("page.router", async () => {
})
expect(actual).toMatchObject({
...expectedPageArgs,
content: createDefaultPage({ layout: "content" }),
content: createDefaultPage({ layout: ISOMER_PAGE_LAYOUTS.Content }),
})
})

Expand All @@ -876,7 +877,7 @@ describe("page.router", async () => {
// Act
const result = await caller.createPage({
...expectedPageArgs,
layout: "content",
layout: ISOMER_PAGE_LAYOUTS.Content,
folderId: Number(folder.id),
})

Expand All @@ -900,7 +901,7 @@ describe("page.router", async () => {
expect(actual).toMatchObject({
...expectedPageArgs,
parentId: folder.id,
content: createDefaultPage({ layout: "content" }),
content: createDefaultPage({ layout: ISOMER_PAGE_LAYOUTS.Content }),
})
})

Expand Down
Loading
Loading