Skip to content

Commit

Permalink
Merl 1306 multiple queries (#1661)
Browse files Browse the repository at this point in the history
* Create FaustContext and Faust template `queries` property

* Implement new method of fetching queries with their own variables

* Remove unneeded context check

* Fix linting issues

* Allow typing for `useFaustQuery`

* Update package-lock.json

* WIP: set queries in Faust Context

* Fix types

* Remove unneeded properties of single.js

* Refactor WordPressTemplate

* Wrap up final touches for WordPressTemplate

* <WordPressTemplate/> tests

* Finish test for WordPressTemplateInternal

* update package-lock.json

* Fix failing builds

* use FaustQueries type

* Add error boundary for when both `template.queries` and `template.query` are provided

* Added changeset
  • Loading branch information
blakewilson authored Dec 14, 2023
1 parent 8dcda28 commit c79c8c2
Show file tree
Hide file tree
Showing 12 changed files with 832 additions and 211 deletions.
29 changes: 29 additions & 0 deletions .changeset/eleven-elephants-raise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
'@faustwp/core': minor
---

Added the ability to provide multiple queries to a given Faust Template:

```js
import {GET_POST, GET_LAYOUT} from './queries.js'

export default function Component(props) {
}

Component.queries = [
{
query: GET_LAYOUT
},
{
query: GET_POST,
variables: (seedNode, ctx) {
return {
id: seedNode.databaseId,
asPreview: ctx?.asPreview
}
}
}
]
```
**Note:** Your Faust template can use either `Component.queries` or `Component.query`, but not both.
129 changes: 72 additions & 57 deletions examples/next/faustwp-getting-started/wp-templates/single.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,73 @@
import { gql } from '@apollo/client';
import * as MENUS from '../constants/menus';
import { BlogInfoFragment } from '../fragments/GeneralSettings';
import { useFaustQuery } from '@faustwp/core';
import {
Header,
Footer,
Main,
Container,
EntryHeader,
NavigationMenu,
ContentWrapper,
EntryHeader,
FeaturedImage,
Footer,
Header,
Main,
NavigationMenu,
SEO,
} from '../components';
import * as MENUS from '../constants/menus';
import { BlogInfoFragment } from '../fragments/GeneralSettings';

const GET_LAYOUT_QUERY = gql`
${BlogInfoFragment}
${NavigationMenu.fragments.entry}
query GetLayout(
$headerLocation: MenuLocationEnum
$footerLocation: MenuLocationEnum
) {
generalSettings {
...BlogInfoFragment
}
headerMenuItems: menuItems(where: { location: $headerLocation }) {
nodes {
...NavigationMenuItemFragment
}
}
footerMenuItems: menuItems(where: { location: $footerLocation }) {
nodes {
...NavigationMenuItemFragment
}
}
}
`;

const GET_POST_QUERY = gql`
${FeaturedImage.fragments.entry}
query GetPost($databaseId: ID!, $asPreview: Boolean = false) {
post(id: $databaseId, idType: DATABASE_ID, asPreview: $asPreview) {
title
content
date
author {
node {
name
}
}
...FeaturedImageFragment
}
}
`;

export default function Component(props) {
// Loading state for previews
if (props.loading) {
return <>Loading...</>;
}

const { title: siteTitle, description: siteDescription } =
props?.data?.generalSettings;
const primaryMenu = props?.data?.headerMenuItems?.nodes ?? [];
const footerMenu = props?.data?.footerMenuItems?.nodes ?? [];
const { title, content, featuredImage, date, author } = props.data.post;
const { post } = useFaustQuery(GET_POST_QUERY);
const { generalSettings, headerMenuItems, footerMenuItems } =
useFaustQuery(GET_LAYOUT_QUERY);

const { title: siteTitle, description: siteDescription } = generalSettings;
const primaryMenu = headerMenuItems?.nodes ?? [];
const footerMenu = footerMenuItems?.nodes ?? [];
const { title, content, featuredImage, date, author } = post ?? {};

return (
<>
Expand Down Expand Up @@ -55,48 +99,19 @@ export default function Component(props) {
);
}

Component.query = gql`
${BlogInfoFragment}
${NavigationMenu.fragments.entry}
${FeaturedImage.fragments.entry}
query GetPost(
$databaseId: ID!
$headerLocation: MenuLocationEnum
$footerLocation: MenuLocationEnum
$asPreview: Boolean = false
) {
post(id: $databaseId, idType: DATABASE_ID, asPreview: $asPreview) {
title
content
date
author {
node {
name
}
}
...FeaturedImageFragment
}
generalSettings {
...BlogInfoFragment
}
headerMenuItems: menuItems(where: { location: $headerLocation }) {
nodes {
...NavigationMenuItemFragment
}
}
footerMenuItems: menuItems(where: { location: $footerLocation }) {
nodes {
...NavigationMenuItemFragment
}
}
}
`;

Component.variables = ({ databaseId }, ctx) => {
return {
databaseId,
headerLocation: MENUS.PRIMARY_LOCATION,
footerLocation: MENUS.FOOTER_LOCATION,
asPreview: ctx?.asPreview,
};
};
Component.queries = [
{
query: GET_LAYOUT_QUERY,
variables: (seedNode, ctx) => ({
headerLocation: MENUS.PRIMARY_LOCATION,
footerLocation: MENUS.FOOTER_LOCATION,
}),
},
{
query: GET_POST_QUERY,
variables: ({ databaseId }, ctx) => ({
databaseId,
asPreview: ctx?.asPreview,
}),
},
];
22 changes: 11 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

47 changes: 32 additions & 15 deletions packages/faustwp-core/src/components/FaustProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import React, { useState } from 'react';
import { ApolloProvider } from '@apollo/client';
import React from 'react';
// eslint-disable-next-line import/extensions
import { useRouter } from 'next/router';
// eslint-disable-next-line import/extensions
import { AppProps } from 'next/app';
import { useApollo } from '../client.js';
import { Toolbar } from './Toolbar/index.js';
import { SeedNode } from '../queries/seedQuery.js';
import { getConfig } from '../config/index.js';
import { FaustContext, FaustQueries } from '../store/FaustContext.js';
import { FaustProps } from './WordPressTemplate.js';

export type FaustPageProps = AppProps['pageProps'] & {
__SEED_NODE__?: SeedNode;
};
export type FaustPageProps = AppProps['pageProps'] & FaustProps;

export function FaustProvider(props: {
children: React.ReactNode;
Expand All @@ -22,16 +21,34 @@ export function FaustProvider(props: {
const router = useRouter();
const apolloClient = useApollo(pageProps);

const setQueries = (newQueries: FaustQueries) => {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
setFaustContext((prevContext) => {
return {
...prevContext,
queries: newQueries,
};
});
};

const [faustContext, setFaustContext] = useState({
// eslint-disable-next-line no-underscore-dangle
queries: pageProps.__FAUST_QUERIES__,
setQueries,
});

return (
<ApolloProvider client={apolloClient}>
{experimentalToolbar && (
<Toolbar
key={`faust-toolbar-${router.asPath}`} // Required in order to load each route's own seed node.
// eslint-disable-next-line no-underscore-dangle
seedNode={pageProps.__SEED_NODE__}
/>
)}
{children}
</ApolloProvider>
<FaustContext.Provider value={faustContext}>
<ApolloProvider client={apolloClient}>
{experimentalToolbar && (
<Toolbar
key={`faust-toolbar-${router.asPath}`} // Required in order to load each route's own seed node.
// eslint-disable-next-line no-underscore-dangle
seedNode={pageProps.__SEED_NODE__}
/>
)}
{children}
</ApolloProvider>
</FaustContext.Provider>
);
}
2 changes: 1 addition & 1 deletion packages/faustwp-core/src/components/Toolbar/Toolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export type FaustToolbarContext = {
* Toolbar props.
*/
export type ToolbarProps = {
seedNode?: SeedNode;
seedNode?: SeedNode | null;
};
/**
* The component to actually render the toolbar. At this point we can assume
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { getAdminUrl } from '../../../lib/getAdminUrl.js';
import { ToolbarItem } from '../index.js';

type Props = {
seedNode?: SeedNode;
seedNode?: SeedNode | null;
};

export function Edit({ seedNode }: Props) {
Expand Down
Loading

0 comments on commit c79c8c2

Please sign in to comment.