From 54da6c3b0dc6e4e5a921bdb98b798ce3ade4516e Mon Sep 17 00:00:00 2001 From: Jonathan Sick Date: Wed, 10 Apr 2024 15:03:17 -0400 Subject: [PATCH] Implement ExecStats for page panel This shows the execution status, including the age of the execution and execution duration if available. It's also where we put the button to request a recomputation of an existing page. The component's data is populated by the TimesSquareHtmlEventsContext. We show how to mock the context in Storybook to design different states. --- apps/squareone/package.json | 1 + .../TimesSquareGitHubPagePanel/ExecStats.js | 54 ++++++++++++++++++ .../ExecStats.stories.js | 56 +++++++++++++++++++ .../TimesSquareGitHubPagePanel.js | 15 +---- pnpm-lock.yaml | 7 +++ 5 files changed, 121 insertions(+), 12 deletions(-) create mode 100644 apps/squareone/src/components/TimesSquareGitHubPagePanel/ExecStats.js create mode 100644 apps/squareone/src/components/TimesSquareGitHubPagePanel/ExecStats.stories.js diff --git a/apps/squareone/package.json b/apps/squareone/package.json index fb6f4d82..822d86d5 100644 --- a/apps/squareone/package.json +++ b/apps/squareone/package.json @@ -46,6 +46,7 @@ "@reach/alert": "^0.17.0", "@reach/menu-button": "^0.17.0", "ajv": "^8.11.0", + "date-fns": "^3.6.0", "formik": "^2.2.9", "js-yaml": "^4.1.0", "next": "^12.2.4", diff --git a/apps/squareone/src/components/TimesSquareGitHubPagePanel/ExecStats.js b/apps/squareone/src/components/TimesSquareGitHubPagePanel/ExecStats.js new file mode 100644 index 00000000..94869ddd --- /dev/null +++ b/apps/squareone/src/components/TimesSquareGitHubPagePanel/ExecStats.js @@ -0,0 +1,54 @@ +/* + * ExecStats provides a summary of the execution status and timing of the + * notebook execution. It also provides a button to request the recomputation + * of the already-executed notebook. + */ + +import React from 'react'; +import styled from 'styled-components'; +import { parseISO, formatDistanceToNow } from 'date-fns'; + +import { TimesSquareHtmlEventsContext } from '../TimesSquareHtmlEventsProvider'; +import { GhostButton } from '../Button'; + +export default function ExecStats({}) { + const htmlEvent = React.useContext(TimesSquareHtmlEventsContext); + + if (htmlEvent.executionStatus == 'complete') { + const dateFinished = parseISO(htmlEvent.dateFinished); + return ( + +

+ Computed{' '} + {' '} + in {htmlEvent.executionDuration} seconds. +

+ console.log('Recompute')}> + Recompute + +
+ ); + } + + if (htmlEvent.executionStatus == 'in_progress') { + return ( + +

Computing…

+
+ ); + } + + return null; +} + +const StyledContainer = styled.div` + display: flex; + flex-direction: column; + gap: 1rem; + margin-top: 1rem; +`; diff --git a/apps/squareone/src/components/TimesSquareGitHubPagePanel/ExecStats.stories.js b/apps/squareone/src/components/TimesSquareGitHubPagePanel/ExecStats.stories.js new file mode 100644 index 00000000..00b6a35c --- /dev/null +++ b/apps/squareone/src/components/TimesSquareGitHubPagePanel/ExecStats.stories.js @@ -0,0 +1,56 @@ +import React from 'react'; + +import { TimesSquareHtmlEventsContext } from '../TimesSquareHtmlEventsProvider'; +import ExecStats from './ExecStats'; + +export default { + component: ExecStats, + title: 'Components/TimesSquare/ExecStats', + parameters: { + viewport: { + viewports: { + sidebar: { + name: 'Sidebar', + styles: { + width: '280px', + height: '900px', + }, + }, + }, + }, + defaultViewport: 'sidebar', + }, +}; + +const Template = (args) => ( + + + +); + +export const Default = Template.bind({}); +Default.args = { + dateSubmitted: '2021-09-01T12:00:00Z', + dateStarted: '2021-09-01T12:00:01Z', + dateFinished: '2021-09-01T12:00:10Z', + executionStatus: 'complete', + executionDuration: 10.12, +}; + +export const InProgressNew = Template.bind({}); +InProgressNew.args = { + dateSubmitted: '2021-09-01T12:00:10Z', + dateStarted: null, + dateFinished: null, + executionStatus: 'in_progress', + executionDuration: null, +}; + +export const InProgressExisting = Template.bind({}); +InProgressExisting.args = { + dateSubmitted: '2021-09-01T12:00:00Z', + dateStarted: '2021-09-01T12:00:01Z', + dateFinished: '2021-09-01T12:00:10Z', + executionStatus: 'in_progress', + executionDuration: 10.12, +}; diff --git a/apps/squareone/src/components/TimesSquareGitHubPagePanel/TimesSquareGitHubPagePanel.js b/apps/squareone/src/components/TimesSquareGitHubPagePanel/TimesSquareGitHubPagePanel.js index 288d0035..d8ec2a6e 100644 --- a/apps/squareone/src/components/TimesSquareGitHubPagePanel/TimesSquareGitHubPagePanel.js +++ b/apps/squareone/src/components/TimesSquareGitHubPagePanel/TimesSquareGitHubPagePanel.js @@ -12,14 +12,12 @@ import Error from 'next/error'; import useTimesSquarePage from '../../hooks/useTimesSquarePage'; import TimesSquareParameters from '../TimesSquareParameters'; -import { TimesSquareHtmlEventsContext } from '../TimesSquareHtmlEventsProvider'; +import ExecStats from './ExecStats'; export default function TimesSquareGitHubPagePanel({}) { const { publicRuntimeConfig } = getConfig(); const pageData = useTimesSquarePage(); - const htmlEvent = React.useContext(TimesSquareHtmlEventsContext); - if (pageData.loading) { return

Loading...

; } @@ -40,15 +38,8 @@ export default function TimesSquareGitHubPagePanel({}) {
)} - {htmlEvent.executionStatus != 'complete' && ( -

{htmlEvent.executionStatus}

- )} - {htmlEvent.executionStatus == 'complete' && ( - <> -

Computed {htmlEvent.dateFinished}

-

Executed in {htmlEvent.executionDuration} seconds

- - )} + + ); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4a6087e1..0fc7ff48 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -68,6 +68,9 @@ importers: ajv: specifier: ^8.11.0 version: 8.11.0 + date-fns: + specifier: ^3.6.0 + version: 3.6.0 formik: specifier: ^2.2.9 version: 2.2.9(react@17.0.2) @@ -9960,6 +9963,10 @@ packages: resolution: {integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==} dev: true + /date-fns@3.6.0: + resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} + dev: false + /debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: