Skip to content

Commit

Permalink
#26: CTY-specific view, using base:folder as demonstration
Browse files Browse the repository at this point in the history
  • Loading branch information
espen42 committed Sep 5, 2021
1 parent 07f0628 commit 3db80f5
Show file tree
Hide file tree
Showing 12 changed files with 99 additions and 49 deletions.
10 changes: 5 additions & 5 deletions hmdb/src/main/resources/lib/headless/contentapi/contentdata.es6
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ const { executeResult } = require("./execute");
// branch (manatory): branch to fetch from: master or draft
// query (mandatory): guillotine query to run
// variables (mandatory if query has any placeholders): optional additional variables for a supplied query.
exports.getContentData = (siteId, branch, query, variables = {}) => {
return branchInvalidError400(branch) ||
queryInvalidError400(query) ||
executeResult(siteId, branch, query, variables);
};
exports.getContentData = (siteId, branch, query, variables = {}) =>
branchInvalidError400(branch) ||
queryInvalidError400(query) ||
executeResult(siteId, branch, query, variables);

16 changes: 7 additions & 9 deletions hmdb/src/main/resources/lib/headless/contentapi/contentmeta.es6
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
const { branchInvalidError400, idOrPathInvalidError400 } = require("./errors");
const { executeResult } = require("./execute");
const {branchInvalidError400, idOrPathInvalidError400} = require("./errors");
const {executeResult} = require("./execute");

const { META_QUERY } = require('../guillotine/queries/_meta');
const {META_QUERY} = require('../guillotine/queries/_meta');

// siteId (manatory): the valid UUID for the root site
// branch (manatory): branch to fetch from, master or draft
// idOrPath (mandatory if no override query is used): used in the _meta query. Can be a valid content UUID, or a (full) content path, eg. /mysite/persons/someone.
exports.getContentMeta = (siteId, branch, idOrPath) => {

return branchInvalidError400(branch) ||
idOrPathInvalidError400(idOrPath) ||
executeResult(siteId, branch, META_QUERY, { idOrPath });
};
exports.getContentMeta = (siteId, branch, idOrPath) =>
branchInvalidError400(branch) ||
idOrPathInvalidError400(idOrPath) ||
executeResult(siteId, branch, META_QUERY, {idOrPath});
23 changes: 13 additions & 10 deletions next/src/components/BasePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import React, {useEffect, useState} from "react";
import {useRouter} from "next/router";

import {fetchContent} from "../shared/data/fetchContent";
import {getTemplate} from "./templateSelector";

import Custom500 from './errors/500';
import Custom404 from './errors/404';
import CustomError from './errors/error';

const BasePage = ({error, content}) => {
const BasePage = ({error, content, fetching}) => {
if (error) {
switch (error.code) {
case 404:
Expand All @@ -18,28 +19,29 @@ const BasePage = ({error, content}) => {
return <CustomError code={error.code} message={error.message}/>;
}

if (!content) {
return <p>Fetching data...</p>
if (fetching) {
return <p className="spinner">Fetching data...</p>
}

// TODO: general fallback page. Resolve specific pages above
return <div>
<p>content: {JSON.stringify(content)}</p>
</div>;
if (content) {
const TemplatePage = getTemplate(content.type);
return <TemplatePage {...content} />
}

return null;
};

export default BasePage;





////////////////////////////////////////////////////////////////////////

export const clientSideBasePageBuilder = branch => {
const ClientSideFetchingBasePage = () => {

const [props, setProps] = useState({error: null, content: null});
const [props, setProps] = useState({error: null, content: null, fetching: false});

const router = useRouter();
const contentPath = router.query.contentPath;
Expand All @@ -48,6 +50,7 @@ export const clientSideBasePageBuilder = branch => {
() => {

const refresh = async (contentPath) => {
setProps(props => ({...props, fetching: true}));
const contentResult = await fetchContent(branch, contentPath);

setTimeout(() => {
Expand All @@ -64,7 +67,7 @@ export const clientSideBasePageBuilder = branch => {
[contentPath]
);

return <BasePage error={props.error} content={props.content}/>;
return <BasePage error={props.error} content={props.content} fetching={props.fetching}/>;
};
return ClientSideFetchingBasePage;
};
11 changes: 11 additions & 0 deletions next/src/components/templateSelector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import DefaultPage from "./templates/default";

import FolderPage from "./templates/folder";

// Content types mapped to full guillotine query strings.
// If type is not found here, falls back to the default template in templates/item.tsx
const contentTypeSpecificTemplate = {
'base:folder': FolderPage
};

export const getTemplate = (contentType) => contentTypeSpecificTemplate[contentType] || DefaultPage;
17 changes: 17 additions & 0 deletions next/src/components/templates/default.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from "react"

type Props = {
displayName: string,
}

const DefaultPage = (props: Props) => {
return (
<>
<p>Item:</p>
<h2>{props.displayName}</h2>
<pre>{JSON.stringify(props, null, 2)}</pre>
</>
)
}

export default DefaultPage;
32 changes: 32 additions & 0 deletions next/src/components/templates/folder.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from "react"
import Link from "next/link";

type ChildContent = {
displayName: string,
_path: string,
_id: string
};

type Props = {
displayName: string,
children: ChildContent[],
};

const FolderPage = ( props: Props) => {
return (
<>
<p>Folder:</p>
<h2>{props.displayName}</h2>
<ul>
{props.children.map(child => (
<li key={child._id}>
<Link href={child._path.substring(1)}><a>{child.displayName}</a></Link>
</li>)
)}
</ul>
<pre>{JSON.stringify(props, null, 2)}</pre>
</>
)
};

export default FolderPage
5 changes: 1 addition & 4 deletions next/src/components/templates/movie.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,14 @@ import {CastItem, Movie} from "../../shared/data/queries/getMovie";

import { getPhoto} from "../../shared/images";

type Props = {
movie: Movie,
}

const getCast = (cast): CastItem[] | undefined => !cast
? undefined
: (Array.isArray(cast))
? cast
: [cast];

const MoviePage = ({movie}: Props) => {
const MoviePage = (movie: Movie) => {
const movieMeta = movie.data || {};

const moviePhoto = getPhoto(movieMeta.photos);
Expand Down
6 changes: 1 addition & 5 deletions next/src/components/templates/person.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,8 @@ import { Person } from "../../shared/data/queries/getPerson";

import { getPhoto} from "../../shared/images";

type PersonPageProps = {
person: Person
};


const PersonPage = ({person}: PersonPageProps) => {
const PersonPage = (person: Person) => {
const personMeta = person.data || {};
const personPhoto = getPhoto(personMeta.photos);
return (
Expand Down
8 changes: 3 additions & 5 deletions next/src/pages/_master/[[...contentPath]].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,9 @@ type Context = {
params: { contentPath: string[] };
};

export const getServerSideProps = async ({params}: Context) => {
return {
props: await fetchContent(BRANCH, params.contentPath)
};
};
export const getServerSideProps = async ({params}: Context) => ({
props: await fetchContent(BRANCH, params.contentPath)
});

export default BasePage;

Expand Down
2 changes: 0 additions & 2 deletions next/src/shared/data/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,5 @@ export const fetchGuillotine = async (apiUrl, body, key, methodKeyFromQuery = 'g
}
});

// console.log("fetchGuillotine result:", result);

return result;
};
2 changes: 0 additions & 2 deletions next/src/shared/data/fetchContent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ export const fetchContent = async (branch: string, contentPath: string[]): Promi

// TODO: On 200, verify that contentData.content.type is equal to type above (from content-meta). If not, or on other status, invalidate that path in the cache above.

console.log("content: ", contentResult);

return contentResult;
}

Expand Down
16 changes: 9 additions & 7 deletions next/src/shared/data/querySelector.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
import {getContentDataQuery} from "./queries/_defaultGetData";



// Enables maxChildren with the _defaultGetData call: fetching basic data of child items below folder contents.
// Set to 0 or something falsy to disable.
const DEFAULT_MAX_CHILDREN = 1000;
import { getContentDataQuery } from "./queries/_defaultGetData";



Expand All @@ -26,6 +20,14 @@ const contentTypeSpecificGetVariables = {



/////////////////////////////////////////////////////////////////////////////////////////////

// Enables maxChildren with the _defaultGetData call: fetching basic data of child items below folder contents.
// Set to 0 or something falsy to disable.
const DEFAULT_MAX_CHILDREN = 1000;



/////////////////////////////////////////////////////////////////////////////////////////////

const LOW_PERFORMING_DEFAULT_QUERY = getContentDataQuery(DEFAULT_MAX_CHILDREN);
Expand Down

0 comments on commit 3db80f5

Please sign in to comment.