From dbb90f07dede7f802ef30228f5187272642bc569 Mon Sep 17 00:00:00 2001 From: Tsu-ba-me Date: Mon, 17 Oct 2022 16:17:51 -0400 Subject: [PATCH] fix(striker-ui): add JobSummary --- striker-ui/components/JobSummary.tsx | 145 +++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 striker-ui/components/JobSummary.tsx diff --git a/striker-ui/components/JobSummary.tsx b/striker-ui/components/JobSummary.tsx new file mode 100644 index 00000000..6dc92a93 --- /dev/null +++ b/striker-ui/components/JobSummary.tsx @@ -0,0 +1,145 @@ +import { Menu } from '@mui/material'; +import { forwardRef, useImperativeHandle, useMemo, useState } from 'react'; + +import API_BASE_URL from '../lib/consts/API_BASE_URL'; + +import { ProgressBar } from './Bars'; +import FlexBox from './FlexBox'; +import Link from './Link'; +import List from './List'; +import periodicFetch from '../lib/fetchers/periodicFetch'; +import { BodyText } from './Text'; +import useProtect from '../hooks/useProtect'; +import useProtectedState from '../hooks/useProtectedState'; + +type AnvilJobs = { + [jobUUID: string]: { + jobCommand: string; + jobName: string; + jobProgress: number; + jobUUID: string; + }; +}; + +type JobSummaryOptionalPropsWithDefault = { + openInitially?: boolean; +}; + +type JobSummaryOptionalPropsWithoutDefault = { + onFetchSuccessAppend?: (data: AnvilJobs) => void; +}; + +type JobSummaryOptionalProps = JobSummaryOptionalPropsWithDefault & + JobSummaryOptionalPropsWithoutDefault; + +type JobSummaryProps = JobSummaryOptionalProps; + +type JobSummaryForwardedRefContent = { + setAnchor?: (element: HTMLElement | undefined) => void; + setOpen?: (value: boolean) => void; +}; + +const JOB_LIST_LENGTH = '20em'; +const JOB_SUMMARY_DEFAULT_PROPS: Required & + JobSummaryOptionalPropsWithoutDefault = { + onFetchSuccessAppend: undefined, + openInitially: false, +}; + +const JobSummary = forwardRef( + ( + { + onFetchSuccessAppend, + openInitially = JOB_SUMMARY_DEFAULT_PROPS.openInitially, + }, + ref, + ) => { + const { protect } = useProtect(); + + const [anvilJobs, setAnvilJobs] = useProtectedState({}, protect); + const [isOpenJobSummary, setIsOpenJobSummary] = + useState(openInitially); + const [menuAnchorElement, setMenuAnchorElement] = useState< + HTMLElement | undefined + >(); + + periodicFetch(`${API_BASE_URL}/job`, { + onError: () => { + setAnvilJobs({}); + }, + onSuccess: (rawAnvilJobs) => { + setAnvilJobs(rawAnvilJobs); + + onFetchSuccessAppend?.call(null, rawAnvilJobs); + }, + }); + + useImperativeHandle( + ref, + () => ({ + setAnchor: (value) => setMenuAnchorElement(value), + setOpen: (value) => setIsOpenJobSummary(value), + }), + [], + ); + + const jobList = useMemo( + () => ( + + ( + + + + {jobName} + + + + + )} + /> + More details + + ), + [anvilJobs], + ); + const jobSummary = useMemo( + () => ( + { + setIsOpenJobSummary(false); + setMenuAnchorElement(undefined); + }} + open={isOpenJobSummary} + variant="menu" + > + {jobList} + + ), + [isOpenJobSummary, jobList, menuAnchorElement], + ); + + return jobSummary; + }, +); + +JobSummary.defaultProps = JOB_SUMMARY_DEFAULT_PROPS; +JobSummary.displayName = 'JobSummary'; + +export type { JobSummaryForwardedRefContent, JobSummaryProps }; + +export default JobSummary;