Skip to content

Commit

Permalink
Add TimesSquareParametersProvider
Browse files Browse the repository at this point in the history
This context and provider lets us wrap up the concerns around taking URL
path and query parameters and breaking those down into the Times Square
API URL, notebook parameters, and display settings.

This dramatically simplifies the page components and lets us reuse code
between the regular and github-pr pages.

It also lets us avoid prop drilling to pass this info to the several
components that consume this info.
  • Loading branch information
jonathansick committed Mar 27, 2024
1 parent 326ac7f commit 3eacc32
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,11 @@ import Error from 'next/error';

import useTimesSquarePage from '../../hooks/useTimesSquarePage';
import TimesSquareParameters from '../TimesSquareParameters';
import TimesSquareParametersContext from '../TimesSquareParametersProvider';

export default function TimesSquareGitHubPagePanel({
tsPageUrl,
userParameters,
displaySettings,
}) {
export default function TimesSquareGitHubPagePanel({}) {
const { publicRuntimeConfig } = getConfig();
const { tsPageUrl } = React.useContext(TimesSquareParametersContext);
const pageData = useTimesSquarePage(tsPageUrl);

if (pageData.loading) {
Expand All @@ -39,11 +37,7 @@ export default function TimesSquareGitHubPagePanel({
{description && (
<div dangerouslySetInnerHTML={{ __html: description.html }}></div>
)}
<TimesSquareParameters
pageData={pageData}
userParameters={userParameters}
displaySettings={displaySettings}
/>
<TimesSquareParameters />
</div>
</PagePanelContainer>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
* from Times Square with a notebook render.
*/

import React from 'react';
import styled from 'styled-components';

import useHtmlStatus from './useHtmlStatus';
import { TimesSquareParametersContext } from '../TimesSquareParametersProvider';

const StyledIframe = styled.iframe`
/* --shadow-color: 0deg 0% 74%;
Expand All @@ -19,11 +21,8 @@ const StyledIframe = styled.iframe`
height: 100%;
`;

export default function TimesSquareNotebookViewer({
tsPageUrl,
parameters,
displaySettings,
}) {
export default function TimesSquareNotebookViewer({}) {
const { tsPageUrl } = React.useContext(TimesSquareParametersContext);
const htmlStatus = useHtmlStatus(tsPageUrl, parameters, displaySettings);

if (htmlStatus.error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import Button, { RedGhostButton } from '../Button';
import StringInput from './StringInput';
import ParameterInput from './ParameterInput';

import { TimesSquareParametersContext } from '../TimesSquareParametersProvider';
import useTimesSquarePage from '../../hooks/useTimesSquarePage';

// Create input components based on the parameter's JSON schema
function inputFactory(props) {
const { paramName, paramSchema, value, onChange, errors, touched } = props;
Expand All @@ -28,13 +31,16 @@ function inputFactory(props) {
);
}

export default function TimesSquareParameters({
pageData,
userParameters,
displaySettings,
}) {
export default function TimesSquareParameters({}) {
const router = useRouter();
const { parameters } = pageData;

const {
tsPageUrl,
displaySettings,
notebookParameters: userParameters,
} = React.useContext(TimesSquareParametersContext);
const { parameters } = useTimesSquarePage(tsPageUrl);

const ajv = new Ajv({ coerceTypes: true });

// Merge userParameters with defaults
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Context provider for the current page's notebook and display parameters.
*/

import React from 'react';
import getConfig from 'next/config';
import { useRouter } from 'next/router';

export const TimesSquareParametersContext = React.createContext();

export default function TimesSquareParametersProvider({ children }) {
// const [displayParameters, setDisplayParameters] = React.useState({
// ts_hide_code: '1',
// });
// const [notebookParameters, setNotebookParameters] = React.useState({});

const { publicRuntimeConfig } = getConfig();
const { timesSquareUrl } = publicRuntimeConfig;
const router = useRouter();

// Get components out of the URL path
const { tsSlug, owner = '', repo = '', commit = '' } = router.query;

// Since the page's path is a [...tsSlug], we need to join the parts of the
// path to get the full slug. This combines the owner, repo, directory, and
// notebook name for regular /github/ pages, or just the directory and
// notebook name for /github-pr/ pages.
const githubSlug = tsSlug.join('/');

// Construct the URL for the Times Square API endpoint
const tsPageUrl = router.pathname.startsWith('/times-square/github-pr')
? `${timesSquareUrl}/v1/github-pr/${owner}/${repo}/${commit}/${githubSlug}`
: `${timesSquareUrl}/v1/github/${githubSlug}`;

// Get the user query parameters from the URL. In next 13 we can use the
// useSearchParams hook (https://nextjs.org/docs/app/api-reference/functions/use-search-params)
// to get these directly, but for now we have to filter them out of the
// router.query object. Even if path components leak in, we can still filter
// them out in the UI for setting parameters because we only show parameters
// matching the parameter schema.
const userParameters = Object.fromEntries(
Object.entries(router.query)
.filter((item) => item[0] != 'tsSlug')
.map((item) => item)
);

// pop display settings from the user parameters and to also separate out
// the notebook parameters.
const { ts_hide_code = '1', ...notebookParameters } = userParameters;
const displaySettings = { ts_hide_code };

return (
<TimesSquareParametersContext.Provider
value={{ tsPageUrl, displaySettings, notebookParameters }}
>
{children}
</TimesSquareParametersContext.Provider>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './TimesSquareParametersProvider';
export { default } from './TimesSquareParametersProvider';
Original file line number Diff line number Diff line change
Expand Up @@ -6,49 +6,24 @@ import WideContentLayout from '../../../../../../components/WideContentLayout';
import TimesSquarePrGitHubNav from '../../../../../../components/TimesSquarePrGitHubNav';
import TimesSquareNotebookViewer from '../../../../../../components/TimesSquareNotebookViewer';
import TimesSquareGitHubPagePanel from '../../../../../../components/TimesSquareGitHubPagePanel/TimesSquareGitHubPagePanel';

export function TimesSquareGitHubPrNav({ pagePath }) {
return <div>Nav component</div>;
}
import TimesSquareParametersProvider from '../../../../../../components/TimesSquareParametersProvider';

export default function GitHubPrNotebookViewPage({}) {
const { publicRuntimeConfig } = getConfig();
const { timesSquareUrl } = publicRuntimeConfig;
const router = useRouter();
const { owner, repo, commit, tsSlug } = router.query;
const tsPageUrl = `${timesSquareUrl}/v1/github-pr/${owner}/${repo}/${commit}/${tsSlug.join(
'/'
)}`;

const userParameters = Object.fromEntries(
Object.entries(router.query)
.filter((item) => item[0] != 'tsSlug')
.map((item) => item)
);

const { ts_hide_code = '1' } = userParameters;
const displaySettings = { ts_hide_code };
const { owner, repo, commit } = router.query;

const pageNav = (
<TimesSquarePrGitHubNav owner={owner} repo={repo} commitSha={commit} />
);

const pagePanel = (
<TimesSquareGitHubPagePanel
tsPageUrl={tsPageUrl}
userParameters={userParameters}
displaySettings={displaySettings}
/>
);
const pagePanel = <TimesSquareGitHubPagePanel />;

return (
<TimesSquareApp pageNav={pageNav} pagePanel={pagePanel}>
<TimesSquareNotebookViewer
tsPageUrl={tsPageUrl}
parameters={userParameters}
displaySettings={displaySettings}
/>
</TimesSquareApp>
<TimesSquareParametersProvider>
<TimesSquareApp pageNav={pageNav} pagePanel={pagePanel}>
<TimesSquareNotebookViewer />
</TimesSquareApp>
</TimesSquareParametersProvider>
);
}

Expand Down
33 changes: 7 additions & 26 deletions apps/squareone/src/pages/times-square/github/[...tsSlug].js
Original file line number Diff line number Diff line change
Expand Up @@ -6,42 +6,23 @@ import WideContentLayout from '../../../components/WideContentLayout';
import TimesSquareMainGitHubNav from '../../../components/TimesSquareMainGitHubNav';
import TimesSquareNotebookViewer from '../../../components/TimesSquareNotebookViewer';
import TimesSquareGitHubPagePanel from '../../../components/TimesSquareGitHubPagePanel/TimesSquareGitHubPagePanel';
import TimesSquareParametersProvider from '../../../components/TimesSquareParametersProvider';

export default function GitHubNotebookViewPage({}) {
const { publicRuntimeConfig } = getConfig();
const { timesSquareUrl } = publicRuntimeConfig;
const router = useRouter();
const { tsSlug } = router.query;
const githubSlug = tsSlug.join('/');
const tsPageUrl = `${timesSquareUrl}/v1/github/${githubSlug}`;

const userParameters = Object.fromEntries(
Object.entries(router.query)
.filter((item) => item[0] != 'tsSlug')
.map((item) => item)
);

const { ts_hide_code = '1' } = userParameters;
const displaySettings = { ts_hide_code };

const pageNav = <TimesSquareMainGitHubNav pagePath={githubSlug} />;

const pagePanel = (
<TimesSquareGitHubPagePanel
tsPageUrl={tsPageUrl}
userParameters={userParameters}
displaySettings={displaySettings}
/>
);
const pagePanel = <TimesSquareGitHubPagePanel />;

return (
<TimesSquareApp pageNav={pageNav} pagePanel={pagePanel}>
<TimesSquareNotebookViewer
tsPageUrl={tsPageUrl}
parameters={userParameters}
displaySettings={displaySettings}
/>
</TimesSquareApp>
<TimesSquareParametersProvider>
<TimesSquareApp pageNav={pageNav} pagePanel={pagePanel}>
<TimesSquareNotebookViewer />
</TimesSquareApp>
</TimesSquareParametersProvider>
);
}

Expand Down

0 comments on commit 3eacc32

Please sign in to comment.