From 566e9ae0220f116234ad6292e5d6dd4c27e978af Mon Sep 17 00:00:00 2001 From: Philipp Melab Date: Sat, 9 Dec 2023 06:00:52 +0000 Subject: [PATCH] WIP --- apps/decap/src/collections/page.tsx | 15 ++- apps/website/gatsby-node.mjs | 26 +---- apps/website/src/pages/404.tsx | 47 ++++---- apps/website/src/templates/page.tsx | 31 +++--- packages/schema/src/operations/IndexPages.gql | 17 +++ .../schema/src/operations/NotFoundPage.gql | 11 ++ packages/schema/src/operations/ViewPage.gql | 2 +- packages/schema/src/schema.graphql | 4 + .../ui/src/components/Routes/Page.stories.ts | 100 ++++++++++-------- packages/ui/src/components/Routes/Page.tsx | 14 +-- packages/ui/src/pages.stories.tsx | 7 +- 11 files changed, 166 insertions(+), 108 deletions(-) create mode 100644 packages/schema/src/operations/IndexPages.gql create mode 100644 packages/schema/src/operations/NotFoundPage.gql diff --git a/apps/decap/src/collections/page.tsx b/apps/decap/src/collections/page.tsx index dc72a7e53..fb544a826 100644 --- a/apps/decap/src/collections/page.tsx +++ b/apps/decap/src/collections/page.tsx @@ -1,4 +1,9 @@ -import { ImageSource, Url, ViewPageQuery } from '@custom/schema'; +import { + ImageSource, + registerOperator, + Url, + ViewPageQuery, +} from '@custom/schema'; import { BlockMarkupSource, BlockMediaSource, @@ -243,7 +248,13 @@ export function PagePreview({ (src) => getAsset(src).url, ); + if (data) { + registerOperator(() => data, ViewPageQuery); + } + return ( - {data?.page ? : null} + + + ); } diff --git a/apps/website/gatsby-node.mjs b/apps/website/gatsby-node.mjs index 9ee484152..0aef4df91 100644 --- a/apps/website/gatsby-node.mjs +++ b/apps/website/gatsby-node.mjs @@ -1,4 +1,4 @@ -// @ts-check +// TODO: re-add @ts-check when the issue with the type definitions is resolved. import { Locale } from '@custom/schema'; import { resolve } from 'path'; @@ -33,29 +33,11 @@ export const createPages = async ({ actions, graphql }) => { statusCode: 200, }); + // TODO: Remove duplication of queries and fix typing. /** - * @type {{ - * data?: { - * websiteSettings?: { - * homePage?: { - * translations: Array<{ - * typeName: string; - * path: string; - * locale: string; - * id: string; - * remoteId: string; - * }>; - * }; - * notFoundPage?: { - * translations: Array<{ - * path: string; - * }>; - * }; - * }; - * }; - * errors?: any[]; - * }} + * @type {{data: import('@custom/schema')['IndexPagesQuery'], errors?: [string]}} */ + // @ts-ignore const settings = await graphql(` query IndexPages { websiteSettings { diff --git a/apps/website/src/pages/404.tsx b/apps/website/src/pages/404.tsx index ba3333f86..1b837fb32 100644 --- a/apps/website/src/pages/404.tsx +++ b/apps/website/src/pages/404.tsx @@ -1,4 +1,8 @@ -import { PageFragment } from '@custom/schema'; +import { + NotFoundPageQuery, + registerOperator, + ViewPageQuery, +} from '@custom/schema'; import { Page } from '@custom/ui/routes/Page'; import { graphql, PageProps } from 'gatsby'; import React from 'react'; @@ -12,7 +16,8 @@ export const query = graphql` query NotFoundPage { websiteSettings { notFoundPage { - translations: _translations { + translations { + id locale ...Page } @@ -21,28 +26,34 @@ export const query = graphql` } `; -type NotFoundPageQuery = { - websiteSettings?: { - notFoundPage?: { - translations?: Array< - { - locale: string; - } & PageFragment - >; - }; - }; -}; +function isTruthy(value: T | undefined | null): value is T { + return Boolean(value); +} export default function Index({ data }: PageProps) { + data.websiteSettings?.notFoundPage?.translations + ?.filter(isTruthy) + .forEach(({ id, locale, ...page }) => { + registerOperator( + () => ({ + page, + }), + ViewPageQuery, + { + id, + locale, + }, + ); + }); return ( - {data.websiteSettings?.notFoundPage?.translations?.map( - ({ locale, ...page }) => ( + {data.websiteSettings?.notFoundPage?.translations + ?.filter(isTruthy) + .map(({ id, locale }) => ( - + - ), - )} + ))} ); } diff --git a/apps/website/src/templates/page.tsx b/apps/website/src/templates/page.tsx index 483087065..8ed764a0f 100644 --- a/apps/website/src/templates/page.tsx +++ b/apps/website/src/templates/page.tsx @@ -1,23 +1,20 @@ import { SilverbackPageContext } from '@amazeelabs/gatsby-source-silverback'; -import { PageFragment } from '@custom/schema'; +import { Locale, registerOperator, ViewPageQuery } from '@custom/schema'; import { Page } from '@custom/ui/routes/Page'; import { graphql, HeadProps, PageProps } from 'gatsby'; import React from 'react'; +// TODO: Remove duplication of queries here. export const query = graphql` - query PageTemplate($remoteId: String!) { - page(_id: { eq: $remoteId }) { + query ViewPageQuery($id: ID!, $rid: ID, $locale: String!) { + page(id: $id, rid: $rid, locale: $locale) { ...Page } } `; -type PageTemplateQuery = { - page: PageFragment; -}; - -export function Head({ data }: HeadProps) { - return ( +export function Head({ data }: HeadProps) { + return data.page ? ( <> {data.page.title} {data.page.metaTags?.map((metaTag, index) => { @@ -41,11 +38,21 @@ export function Head({ data }: HeadProps) { return null; }) || null} - ); + ) : null; } export default function PageTemplate({ data, -}: PageProps) { - return ; + pageContext, +}: PageProps) { + registerOperator(() => data, ViewPageQuery, { + id: pageContext.id, + locale: pageContext.locale, + }); + return ( + + ); } diff --git a/packages/schema/src/operations/IndexPages.gql b/packages/schema/src/operations/IndexPages.gql new file mode 100644 index 000000000..eeb4f16e7 --- /dev/null +++ b/packages/schema/src/operations/IndexPages.gql @@ -0,0 +1,17 @@ +query IndexPages { + websiteSettings { + homePage { + translations { + __typename + locale + id + path + } + } + notFoundPage { + translations { + path + } + } + } +} diff --git a/packages/schema/src/operations/NotFoundPage.gql b/packages/schema/src/operations/NotFoundPage.gql new file mode 100644 index 000000000..bc9dd46e8 --- /dev/null +++ b/packages/schema/src/operations/NotFoundPage.gql @@ -0,0 +1,11 @@ +query NotFoundPage { + websiteSettings { + notFoundPage { + translations { + id + locale + ...Page + } + } + } +} diff --git a/packages/schema/src/operations/ViewPage.gql b/packages/schema/src/operations/ViewPage.gql index 19b3c0626..88975d6d4 100644 --- a/packages/schema/src/operations/ViewPage.gql +++ b/packages/schema/src/operations/ViewPage.gql @@ -1,4 +1,4 @@ -query ViewPage($id: ID!, $rid: ID!, $locale: String!) { +query ViewPage($id: ID!, $rid: ID, $locale: String!) { page(id: $id, rid: $rid, locale: $locale) { ...Page } diff --git a/packages/schema/src/schema.graphql b/packages/schema/src/schema.graphql index deea00138..86dad492f 100644 --- a/packages/schema/src/schema.graphql +++ b/packages/schema/src/schema.graphql @@ -65,6 +65,7 @@ type Page implements ContentHubResultItem @type(id: "page") { id: ID! @resolveEntityId locale: Locale! @resolveEntityLanguage + translations: [Page] @resolveEntityTranslations path: Url! @resolveEntityPath @isPath title: String! @resolveProperty(path: "title.value") teaserImage: MediaImage @@ -136,9 +137,12 @@ type Query { footerNavigation: [FooterNavigation] @gatsbyNodes(type: "FooterNavigation") allPages: [Page] @gatsbyNodes(type: "Page") + websiteSettings: WebsiteSettings + @gatsbyNode(type: "WebsiteSettings", id: "settings") page(id: ID!, rid: ID, locale: String!): Page @fetchEntity(type: "node", id: "$id", rid: "$rid", language: "$locale") + @gatsbyNode(type: "Page", id: "$id") contentHub(query: String, pagination: PaginationInput!): ContentHubResult! @contentHub(query: "$query", pagination: "$pagination") diff --git a/packages/ui/src/components/Routes/Page.stories.ts b/packages/ui/src/components/Routes/Page.stories.ts index 1fdecdc4a..51ea7a838 100644 --- a/packages/ui/src/components/Routes/Page.stories.ts +++ b/packages/ui/src/components/Routes/Page.stories.ts @@ -1,7 +1,9 @@ +import { ViewPageQuery } from '@custom/schema'; import Landscape from '@stories/landscape.jpg?as=metadata'; import { Meta, StoryObj } from '@storybook/react'; import { image } from '../../helpers/image'; +import { buildOperator } from '../../helpers/operators'; import { Mixed, Paragraph } from '../Organisms/PageContent/BlockMarkup.stories'; import { WithCaption } from '../Organisms/PageContent/BlockMedia.stories'; import { Page } from './Page'; @@ -11,56 +13,64 @@ export default { } satisfies Meta; export const Default = { - args: { - page: { - title: 'Page Title', - hero: { - headline: 'Page Hero Headline', - }, - content: [ - { - __typename: 'BlockMarkup', - ...Mixed.args, + parameters: { + operators: [ + buildOperator(ViewPageQuery, () => ({ + page: { + title: 'Page Title', + hero: { + headline: 'Page Hero Headline', + }, + content: [ + { + __typename: 'BlockMarkup', + ...Mixed.args, + }, + { + __typename: 'BlockMedia', + ...WithCaption.args, + }, + { + __typename: 'BlockMarkup', + ...Paragraph.args, + }, + ] as Exclude['content'], }, - { - __typename: 'BlockMedia', - ...WithCaption.args, - }, - { - __typename: 'BlockMarkup', - ...Paragraph.args, - }, - ], - }, + })), + ], }, } satisfies StoryObj; export const FullHero = { - args: { - page: { - title: 'Page Title', - hero: { - headline: 'Page Hero Headline', - lead: 'A longer lead text that even might break into multiple lines.', - image: { - source: image(Landscape, { width: 2000 }), - alt: 'Stock photo landscape hero.', - }, - }, - content: [ - { - __typename: 'BlockMarkup', - ...Mixed.args, - }, - { - __typename: 'BlockMedia', - ...WithCaption.args, - }, - { - __typename: 'BlockMarkup', - ...Paragraph.args, + parameters: { + operators: [ + buildOperator(ViewPageQuery, () => ({ + page: { + title: 'Page Title', + hero: { + headline: 'Page Hero Headline', + lead: 'A longer lead text that even might break into multiple lines.', + image: { + source: image(Landscape, { width: 2000 }), + alt: 'Stock photo landscape hero.', + }, + }, + content: [ + { + __typename: 'BlockMarkup', + ...Mixed.args, + }, + { + __typename: 'BlockMedia', + ...WithCaption.args, + }, + { + __typename: 'BlockMarkup', + ...Paragraph.args, + }, + ] as Exclude['content'], }, - ], - }, + })), + ], }, } satisfies StoryObj; diff --git a/packages/ui/src/components/Routes/Page.tsx b/packages/ui/src/components/Routes/Page.tsx index 89959af5e..b5286da06 100644 --- a/packages/ui/src/components/Routes/Page.tsx +++ b/packages/ui/src/components/Routes/Page.tsx @@ -1,7 +1,8 @@ -import { PageFragment } from '@custom/schema'; +import { PageListEntryFragment, ViewPageQuery } from '@custom/schema'; import React from 'react'; import { isTruthy } from '../../utils/isTruthy'; +import { useOperation } from '../../utils/operation'; import { UnreachableCaseError } from '../../utils/unreachable-case-error'; import { PageTransition } from '../Molecules/PageTransition'; import { BlockForm } from '../Organisms/PageContent/BlockForm'; @@ -9,15 +10,16 @@ import { BlockMarkup } from '../Organisms/PageContent/BlockMarkup'; import { BlockMedia } from '../Organisms/PageContent/BlockMedia'; import { PageHero } from '../Organisms/PageHero'; -export function Page(props: { page: PageFragment }) { - return ( +export function Page(props: PageListEntryFragment) { + const { data } = useOperation(ViewPageQuery, props); + return data?.page ? (
- {props.page.hero ? : null} + {data.page.hero ? : null}
- {props.page?.content?.filter(isTruthy).map((block, index) => { + {data.page?.content?.filter(isTruthy).map((block, index) => { switch (block.__typename) { case 'BlockMedia': return ; @@ -34,5 +36,5 @@ export function Page(props: { page: PageFragment }) {
- ); + ) : null; } diff --git a/packages/ui/src/pages.stories.tsx b/packages/ui/src/pages.stories.tsx index 26e380a4e..50c333498 100644 --- a/packages/ui/src/pages.stories.tsx +++ b/packages/ui/src/pages.stories.tsx @@ -13,12 +13,15 @@ export default { // We don't want to snapshot page examples, that just causes a lot of noise. disableSnapshot: true, }, - operators: [...FrameStory.parameters.operators], + operators: [ + ...FrameStory.parameters.operators, + ...PageStory.parameters.operators, + ], }, } satisfies Meta; export const ContentPage = (() => ( - + )) satisfies StoryFn;