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

Swappable operation implementations #115

Merged
merged 17 commits into from
Jan 3, 2024
Merged
Show file tree
Hide file tree
Changes from 13 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
31 changes: 16 additions & 15 deletions apps/decap/src/helpers/frame.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Url } from '@custom/schema';
import { FrameQuery, Locale, registerExecutor, Url } from '@custom/schema';
import { NavigationItemSource } from '@custom/schema/source';
import { IntlProvider } from '@custom/ui/intl';
import { Frame } from '@custom/ui/routes/Frame';
Expand All @@ -16,22 +16,23 @@ const menuItems = (amount: number) =>
);

export function PreviewFrame({ children }: PropsWithChildren) {
registerExecutor(FrameQuery, () => ({
mainNavigation: [
{
locale: Locale.En,
items: menuItems(4),
},
],
footerNavigation: [
{
locale: Locale.En,
items: menuItems(4),
},
],
}));
return (
<IntlProvider locale={'en'}>
<Frame
header={{
mainNavigation: {
items: menuItems(4),
},
}}
footer={{
footerNavigation: {
items: menuItems(4),
},
}}
>
{children}
</Frame>
<Frame>{children}</Frame>
</IntlProvider>
);
}
11 changes: 9 additions & 2 deletions apps/decap/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { PreviewDecapPageQuery } from '@custom/schema';
import {
PreviewDecapPageQuery,
registerExecutor,
ViewPageQuery,
} from '@custom/schema';
import { Page } from '@custom/ui/routes/Page';
import CMS from 'decap-cms-app';

Expand Down Expand Up @@ -65,7 +69,10 @@ CMS.registerPreviewTemplate(
createPreview(
PreviewDecapPageQuery,
pageSchema,
({ preview }) => <Page page={preview} />,
(data) => {
registerExecutor(ViewPageQuery, { page: data.preview });
return <Page id="preview" locale="en" />;
},
'previewDecapPage',
),
);
7 changes: 7 additions & 0 deletions apps/website/gatsby-browser.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import './styles.css';

import { registerExecutor } from '@custom/schema';
import { GatsbyBrowser } from 'gatsby';

import { drupalExecutor } from './src/utils/drupal-executor';

export const onClientEntry: GatsbyBrowser['onClientEntry'] = async () => {
registerExecutor(drupalExecutor(`/graphql`));
};

export const shouldUpdateScroll: GatsbyBrowser['shouldUpdateScroll'] = (
args,
) => {
Expand Down
26 changes: 4 additions & 22 deletions apps/website/gatsby-node.mjs
Original file line number Diff line number Diff line change
@@ -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 { cpSync } from 'fs';
import { resolve } from 'path';
Expand Down Expand Up @@ -35,29 +35,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 {
Expand Down
5 changes: 4 additions & 1 deletion apps/website/gatsby-ssr.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import './styles.css';

import { Locale } from '@custom/schema';
import { Locale, registerExecutor } from '@custom/schema';
import { GatsbySSR } from 'gatsby';

import { drupalExecutor } from './src/utils/drupal-executor';

export const onRenderBody: GatsbySSR['onRenderBody'] = ({
setHtmlAttributes,
pathname,
}) => {
registerExecutor(drupalExecutor(`/graphql`));
const locales = Object.values(Locale);
if (locales.length === 1) {
// Single-language project.
Expand Down
54 changes: 14 additions & 40 deletions apps/website/src/layouts/index.tsx
Original file line number Diff line number Diff line change
@@ -1,57 +1,31 @@
import { SilverbackPageContext } from '@amazeelabs/gatsby-source-silverback';
import { NavigationFragment } from '@custom/schema';
import { FrameQuery, registerExecutor } from '@custom/schema';
import { IntlProvider } from '@custom/ui/intl';
import { Frame } from '@custom/ui/routes/Frame';
import { graphql, useStaticQuery, WrapPageElementNodeArgs } from 'gatsby';
import React, { PropsWithChildren } from 'react';

function useFrameQuery() {
return useStaticQuery<{
main_de: NavigationFragment;
main_en: NavigationFragment;
footer_de: NavigationFragment;
footer_en: NavigationFragment;
}>(graphql`
query Frame {
main_de: mainNavigation(_langcode: { eq: "de" }) {
...Navigation
}
main_en: mainNavigation(_langcode: { eq: "en" }) {
items {
...NavigationItem
}
}
footer_de: footerNavigation(_langcode: { eq: "de" }) {
items {
...NavigationItem
}
}
footer_en: footerNavigation(_langcode: { eq: "en" }) {
items {
...NavigationItem
}
}
}
`);
}

export default function Layout({
children,
pageContext: { locale },
}: PropsWithChildren<
WrapPageElementNodeArgs<any, SilverbackPageContext>['props']
>) {
const data = useFrameQuery();
const main = locale === 'de' ? data.main_de : data.main_en;
const footer = locale === 'de' ? data.footer_de : data.footer_en;
// TODO: Remove duplication of queries here.
const data = useStaticQuery<FrameQuery>(graphql`
query Frame {
mainNavigation: mainNavigations {
...Navigation
}
footerNavigation: footerNavigations {
...Navigation
}
}
`);
registerExecutor(FrameQuery, data);
return (
<IntlProvider locale={locale || 'en'}>
<Frame
header={{ mainNavigation: main }}
footer={{ footerNavigation: footer }}
>
{children}
</Frame>
<Frame>{children}</Frame>
</IntlProvider>
);
}
47 changes: 29 additions & 18 deletions apps/website/src/pages/404.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { PageFragment } from '@custom/schema';
import {
NotFoundPageQuery,
registerExecutor,
ViewPageQuery,
} from '@custom/schema';
import { Page } from '@custom/ui/routes/Page';
import { graphql, PageProps } from 'gatsby';
import React from 'react';
Expand All @@ -12,7 +16,8 @@ export const query = graphql`
query NotFoundPage {
websiteSettings {
notFoundPage {
translations: _translations {
translations {
id
locale
...Page
}
Expand All @@ -21,28 +26,34 @@ export const query = graphql`
}
`;

type NotFoundPageQuery = {
websiteSettings?: {
notFoundPage?: {
translations?: Array<
{
locale: string;
} & PageFragment
>;
};
};
};
function isTruthy<T>(value: T | undefined | null): value is T {
return Boolean(value);
}

export default function Index({ data }: PageProps<NotFoundPageQuery>) {
data.websiteSettings?.notFoundPage?.translations
?.filter(isTruthy)
.forEach(({ id, locale, ...page }) => {
registerExecutor(
ViewPageQuery,
{
id,
locale,
},
{
page,
},
);
});
return (
<LanguageNegotiator defaultLanguage={'en'}>
{data.websiteSettings?.notFoundPage?.translations?.map(
({ locale, ...page }) => (
{data.websiteSettings?.notFoundPage?.translations
?.filter(isTruthy)
.map(({ id, locale }) => (
<LanguageNegotiatorContent key={locale} language={locale}>
<Page page={page} />
<Page id={id} locale={locale} />
</LanguageNegotiatorContent>
),
)}
))}
</LanguageNegotiator>
);
}
39 changes: 23 additions & 16 deletions apps/website/src/preview/page.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
'use client';

import { PreviewDrupalPageQuery, useOperation } from '@custom/schema';
import { Loading } from '@custom/ui/routes/Loading';
import {
PreviewDrupalPageQuery,
registerExecutor,
ViewPageQuery,
} from '@custom/schema';
import { Page } from '@custom/ui/routes/Page';
import React from 'react';

import { drupalExecutor } from '../utils/drupal-executor';
import { usePreviewParameters } from '../utils/preview';

const previewExecutor = drupalExecutor(
`${process.env.GATSBY_DRUPAL_URL}/graphql`,
false,
);

export default function PagePreview() {
const { nid, rid, lang } = usePreviewParameters();
const data = useOperation(
`${process.env.GATSBY_DRUPAL_URL}/graphql`,
PreviewDrupalPageQuery,
nid && rid && lang
? {
id: nid,
rid: rid,
locale: lang,
}
: undefined,
);
return data?.preview ? <Page page={data.preview} /> : <Loading />;
if (nid && rid && lang) {
registerExecutor(ViewPageQuery, async () => {
const data = await previewExecutor(PreviewDrupalPageQuery, {
id: nid,
locale: lang,
rid,
});
return { page: data.preview };
});
return <Page id="preview" locale="en" />;
}
return null;
}
31 changes: 21 additions & 10 deletions apps/website/src/templates/decap-page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { SilverbackPageContext } from '@amazeelabs/gatsby-source-silverback';
import { PageFragment } from '@custom/schema';
import { Locale, registerExecutor, 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 DecapPageTemplate($id: String!) {
page: decapPage(id: { eq: $id }) {
Expand All @@ -12,12 +13,8 @@ export const query = graphql`
}
`;

type PageTemplateQuery = {
page: PageFragment;
};

export function Head({ data }: HeadProps<PageTemplateQuery>) {
return (
export function Head({ data }: HeadProps<ViewPageQuery>) {
return data.page ? (
<>
<title>{data.page.title}</title>
{data.page.metaTags?.map((metaTag, index) => {
Expand All @@ -41,11 +38,25 @@ export function Head({ data }: HeadProps<PageTemplateQuery>) {
return null;
}) || null}
</>
);
) : null;
}

export default function DecapPageTemplate({
data,
}: PageProps<PageTemplateQuery, SilverbackPageContext>) {
return <Page page={data.page} />;
pageContext,
}: PageProps<ViewPageQuery, SilverbackPageContext>) {
registerExecutor(
ViewPageQuery,
{
id: pageContext.id,
locale: pageContext.locale,
},
data,
);
return (
<Page
id={pageContext.id}
locale={(pageContext.locale as Locale) || Locale.En}
/>
);
}
Loading
Loading