feat: Root config and link working on next server.

This commit is contained in:
Sam Tolmay 2021-11-12 15:14:55 +02:00
parent 9e6518a89e
commit cf2562b088
No known key found for this signature in database
GPG Key ID: D004126FCD1A6DF0
13 changed files with 161 additions and 40 deletions

View File

@ -19,6 +19,7 @@ import createReadConfigFile from './readConfigFile.js';
async function createApiContext({ buildDirectory }) {
const readConfigFile = createReadConfigFile({ buildDirectory });
return {
authenticated: false,
authorize: () => true,
readConfigFile,
};

View File

@ -18,11 +18,8 @@ import createApiContext from './context/createApiContext.js';
import createContext from './context/createContext.js';
import getHomePageId from './routes/rootConfig/getHomePageId.js';
import getPageConfig from './routes/page/getPageConfig.js';
import openIdAuthorizationUrl from './routes/auth/openIdAuthorizationUrl.js';
import openIdCallback from './routes/auth/openIdCallback.js';
import openIdLogoutUrl from './routes/auth/openIdLogoutUrl.js';
import getRootConfig from './routes/rootConfig/getRootConfig.js';
import request from './routes/request/request.js';
import rootConfig from './routes/rootConfig/rootConfig.js';
import {
AuthenticationError,
@ -37,11 +34,8 @@ export {
createContext,
getHomePageId,
getPageConfig,
openIdAuthorizationUrl,
openIdCallback,
openIdLogoutUrl,
getRootConfig,
request,
rootConfig,
AuthenticationError,
ConfigurationError,
RequestError,

View File

@ -18,7 +18,7 @@ import findHomePageId from './findHomePageId.js';
import getLowdefyGlobal from './getLowdefyGlobal.js';
import getMenus from './menus/getMenus.js';
async function rootConfig(context) {
async function getRootConfig(context) {
const [lowdefyGlobal, menus] = await Promise.all([getLowdefyGlobal(context), getMenus(context)]);
return {
authenticated: context.authenticated,
@ -28,4 +28,4 @@ async function rootConfig(context) {
};
}
export default rootConfig;
export default getRootConfig;

View File

@ -19,8 +19,9 @@ import { type } from '@lowdefy/helpers';
async function Link({ context, params }) {
const linkParams = type.isString(params) ? { pageId: params } : params;
try {
context.lowdefy.link(linkParams);
context._internal.lowdefy._internal.link(linkParams);
} catch (error) {
console.log(error);
throw new Error(`Invalid Link, check action params. Received "${JSON.stringify(params)}".`);
}
}

View File

@ -23,6 +23,7 @@ module.exports = withLess({
}
return config;
},
poweredByHeader: false,
// productionBrowserSourceMaps: true
// experimental: {
// concurrentFeatures: true,

View File

@ -22,21 +22,16 @@ const LoadingBlock = () => <div>Loading...</div>;
const Context = ({ children, lowdefy, config }) => {
const [context, setContext] = useState({});
const [error, setError] = useState(null);
useEffect(() => {
let mounted = true;
const mount = async () => {
try {
const ctx = await getContext({
config,
lowdefy,
});
if (mounted) {
setContext(ctx);
}
} catch (err) {
setError(err);
const ctx = await getContext({
config,
lowdefy,
});
if (mounted) {
setContext(ctx);
}
};
mount();
@ -45,7 +40,6 @@ const Context = ({ children, lowdefy, config }) => {
};
}, [config, lowdefy]);
if (error) throw error;
if (context.id !== config.id) return <LoadingBlock />;
return children(context);

View File

@ -18,7 +18,6 @@ import React from 'react';
import Head from 'next/head';
const BindHead = ({ properties }) => {
console.log(properties);
return (
<Head>
<title>{properties.title}</title>

View File

@ -17,14 +17,16 @@
import React from 'react';
import blockComponents from '../plugins/blocks.js';
import components from './components.js';
const LowdefyContext = ({ children }) => {
const lowdefy = {
_internal: {
blockComponents,
components,
updaters: {},
displayMessage: (message) => {
console.log(message);
alert(message);
return () => undefined;
},
link: () => undefined,

View File

@ -16,25 +16,45 @@
import React from 'react';
import { useRouter } from 'next/router';
import Context from './Context.js';
import Head from './Head.js';
import Block from './block/Block.js';
import Root from './Root.js';
import setupLink from '../utils/setupLink.js';
const Page = ({ lowdefy, pageConfig }) => {
const Page = ({ lowdefy, pageConfig, rootConfig }) => {
const router = useRouter();
lowdefy._internal.basePath = router.basePath;
lowdefy._internal.pathname = router.pathname;
lowdefy._internal.query = router.query;
lowdefy._internal.router = router;
lowdefy._internal.link = setupLink({ lowdefy });
return (
<Context config={pageConfig} lowdefy={lowdefy}>
{(context) => (
<>
<Head properties={context._internal.RootBlocks.map[pageConfig.pageId].eval.properties} />
<Block
block={context._internal.RootBlocks.map[pageConfig.pageId]}
Blocks={context._internal.RootBlocks}
context={context}
lowdefy={lowdefy}
/>
</>
)}
</Context>
<Root lowdefy={lowdefy} rootConfig={rootConfig}>
{(loaded) =>
!loaded ? (
<div>Loading</div>
) : (
<Context config={pageConfig} lowdefy={lowdefy}>
{(context) => (
<>
<Head
properties={context._internal.RootBlocks.map[pageConfig.pageId].eval.properties}
/>
<Block
block={context._internal.RootBlocks.map[pageConfig.pageId]}
Blocks={context._internal.RootBlocks}
context={context}
lowdefy={lowdefy}
/>
</>
)}
</Context>
)
}
</Root>
);
};

View File

@ -0,0 +1,36 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React, { useEffect, useState } from 'react';
const Root = ({ children, lowdefy, rootConfig }) => {
const [loading, setLoading] = useState(true);
useEffect(() => {
lowdefy.document = document;
lowdefy.window = window;
setLoading(false);
}, [lowdefy]);
lowdefy.homePageId = rootConfig.homePageId;
lowdefy.lowdefyGlobal = rootConfig.lowdefyGlobal;
lowdefy.menus = rootConfig.menus;
if (loading) return <div>Loading...</div>;
return <>{children(true)}</>;
};
export default Root;

View File

@ -0,0 +1,21 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import Link from 'next/link';
export default {
Link,
};

View File

@ -16,13 +16,20 @@
import createApiContext from '@lowdefy/api/context/createApiContext';
import getPageConfig from '@lowdefy/api/routes/page/getPageConfig';
import getRootConfig from '@lowdefy/api/routes/rootConfig/getRootConfig';
import Page from '../components/Page.js';
export async function getServerSideProps(context) {
const { pageId } = context.params;
const apiContext = await createApiContext({ buildDirectory: './.lowdefy/build' });
const pageConfig = await getPageConfig(apiContext, { pageId });
// TODO: Maybe we can only get rootConfig once?
// We can't do getServerSideProps on _app :(
const [rootConfig, pageConfig] = await Promise.all([
getRootConfig(apiContext),
getPageConfig(apiContext, { pageId }),
]);
if (!pageConfig) {
return {
@ -36,6 +43,7 @@ export async function getServerSideProps(context) {
return {
props: {
pageConfig,
rootConfig,
},
};
}

View File

@ -0,0 +1,44 @@
/*
Copyright 2020-2021 Lowdefy, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { createLink } from '@lowdefy/engine';
function setupLink({ lowdefy }) {
const { router, window } = lowdefy._internal;
const sameOriginLink = (path, newTab) => {
if (newTab) {
return window.open(`${window.location.origin}${lowdefy.basePath}${path}`, '_blank').focus();
} else {
// Next handles the basePath here.
return router.push({
pathname: path,
// TODO: Do we handle urlQuery as a param here?
// query: {},
});
}
};
const newOriginLink = (path, newTab) => {
if (newTab) {
return window.open(path, '_blank').focus();
} else {
return (window.location.href = path);
}
};
const backLink = () => window.history.back();
return createLink({ backLink, lowdefy, newOriginLink, sameOriginLink });
}
export default setupLink;