From 06367e07b9f867a5d24aa5e2253357e08575e5cc Mon Sep 17 00:00:00 2001 From: Max Frederiksen <maxfrederiksen@Maxs-MacBook-Air.local> Date: Mon, 13 Jan 2025 17:10:37 +0100 Subject: [PATCH] Add typing /components/Job/* + JobTable story --- src/components/Job/JobDetails.tsx | 3 +- src/components/Job/JobDetailsTable.tsx | 28 ++++++++------- .../Job/JobTable/JobDetailsColumn.tsx | 26 ++++++++------ src/components/Job/JobTable/JobTable.tsx | 35 +++++++++++++------ src/components/Job/JobUtils.ts | 11 +++--- .../common/job/JobTable.stories.tsx | 4 +-- 6 files changed, 64 insertions(+), 43 deletions(-) diff --git a/src/components/Job/JobDetails.tsx b/src/components/Job/JobDetails.tsx index 244da05e..d03c90c5 100644 --- a/src/components/Job/JobDetails.tsx +++ b/src/components/Job/JobDetails.tsx @@ -17,11 +17,10 @@ import { ActionTypeIconText } from "./JobIcons"; import { JobDetailsTable } from "./JobDetailsTable"; import { DeploymentJobOutput } from "../deployments/DeploymentJobOutput"; import { AWXJobDetails, Status } from "../../api/DataTypes"; -import { JobDetails, AwxJobDetails } from "../../store/deployApi"; +import { JobDetails } from "../../store/deployApi"; interface JobDetailsProps { jobDetail: JobDetails; - awxJob: AwxJobDetails; } const createAlert = (type: Status, message: string) => { diff --git a/src/components/Job/JobDetailsTable.tsx b/src/components/Job/JobDetailsTable.tsx index 4fd9dca0..ef15b140 100644 --- a/src/components/Job/JobDetailsTable.tsx +++ b/src/components/Job/JobDetailsTable.tsx @@ -8,6 +8,7 @@ import { import { Typography, Stack } from "@mui/material"; import { getNoOfIOCs, getNoOfHosts, isBatchJob } from "./JobUtils"; import { JobRevisionChip } from "./JobRevisionChip"; +import { JobDetails, JobDetailsEntry } from "../../store/deployApi"; const columns = [ { @@ -27,7 +28,7 @@ const columns = [ } ]; -const calculateHostText = (job) => { +const calculateHostText = (job: JobDetailsEntry) => { // host is resolvable => show link for users if (job?.host?.hostId && job?.host?.externalIdValid) { return ( @@ -48,29 +49,30 @@ const calculateHostText = (job) => { ); }; -const createRow = (job) => { +const createRow = (job: JobDetailsEntry) => { + const { iocId, iocName, host, gitReference, gitProjectId } = job; return { - id: `${job.iocId}${job.host.hostId}`, + id: `${iocId}${host?.hostId}`, ioc: ( <InternalLink - to={`/iocs/${job.iocId}`} - label={`Ioc details, ${job.iocName}`} + to={`/iocs/${iocId}`} + label={`Ioc details, ${iocName}`} width="100%" > - <EllipsisText>{job.iocName}</EllipsisText> + <EllipsisText>{iocName}</EllipsisText> </InternalLink> ), host: calculateHostText(job), - revision: ( + revision: gitReference && gitProjectId && ( <JobRevisionChip - gitReference={job.gitReference} - gitProjectId={job.gitProjectId} + gitReference={gitReference} + gitProjectId={gitProjectId} /> ) }; }; -export const JobDetailsTable = ({ operation }) => { +export const JobDetailsTable = ({ operation }: { operation: JobDetails }) => { const isBatchOperation = isBatchJob(operation.action); const noOfIOCs = useMemo(() => { @@ -107,9 +109,9 @@ export const JobDetailsTable = ({ operation }) => { variant="body2" sx={{ fontWeight: "600", marginRight: "10px" }} > - {noOfIOCs} {noOfIOCs > 1 ? "IOCs" : "IOC"} + {noOfIOCs} {noOfIOCs && noOfIOCs > 1 ? "IOCs" : "IOC"} {", "} - {noOfHosts} {noOfHosts > 1 ? "Hosts" : "Host"} + {noOfHosts} {noOfHosts && noOfHosts > 1 ? "Hosts" : "Host"} </Typography> </Stack> } @@ -117,7 +119,7 @@ export const JobDetailsTable = ({ operation }) => { <Table columns={columns} disableColumnSorting - rows={operation.jobs.map((job) => createRow(job))} + rows={operation?.jobs?.map((job) => createRow(job))} /> </SimpleAccordion> ) : ( diff --git a/src/components/Job/JobTable/JobDetailsColumn.tsx b/src/components/Job/JobTable/JobDetailsColumn.tsx index 3cdc3111..11aa15ea 100644 --- a/src/components/Job/JobTable/JobDetailsColumn.tsx +++ b/src/components/Job/JobTable/JobDetailsColumn.tsx @@ -5,8 +5,10 @@ import { getNoOfIOCs, getNoOfHosts, isBatchJob } from "../JobUtils"; import { ActionTypeIconText } from "../JobIcons"; import { ACTION_TYPES } from "../JobData"; import { JobRevisionChip } from "../JobRevisionChip"; +import { Job } from "../../../store/deployApi"; -export const JobDetailsColumn = ({ job }) => { +// Ask johanna regarding batch jobs +export const JobDetailsColumn = ({ job }: { job: Job }) => { const isBatchOperation = isBatchJob(job.action); const noOfIOCs = useMemo(() => { @@ -38,12 +40,14 @@ export const JobDetailsColumn = ({ job }) => { > {job.iocName} </InternalLink> - {job.type === ACTION_TYPES.DEPLOY && ( - <JobRevisionChip - gitReference={job.gitReference} - gitProjectId={job.gitProjectId} - /> - )} + {job?.action === ACTION_TYPES.DEPLOY && + job?.gitReference && + job?.gitProjectId && ( + <JobRevisionChip + gitReference={job.gitReference} + gitProjectId={job.gitProjectId} + /> + )} </Stack> <Stack flexDirection="row" @@ -55,18 +59,18 @@ export const JobDetailsColumn = ({ job }) => { to={`/hosts/${job?.host?.hostId}`} label={`Host details, ${job.host?.hostName}`} > - {job.host.hostName} + {job?.host?.hostName} </InternalLink> - <Typography variant="body2">{job.host.network}</Typography> + <Typography variant="body2">{job?.host?.network}</Typography> </Stack> </Stack> ) : ( <Stack> <Typography variant="body2"> - {noOfIOCs} {noOfIOCs > 1 ? "IOCs" : "IOC"} + {noOfIOCs} {noOfIOCs && noOfIOCs > 1 ? "IOCs" : "IOC"} </Typography> <Typography variant="body2"> - {noOfHosts} {noOfHosts > 1 ? "Hosts" : "Host"} + {noOfHosts} {noOfHosts && noOfHosts > 1 ? "Hosts" : "Host"} </Typography> </Stack> )} diff --git a/src/components/Job/JobTable/JobTable.tsx b/src/components/Job/JobTable/JobTable.tsx index e05170b4..bc7d261c 100644 --- a/src/components/Job/JobTable/JobTable.tsx +++ b/src/components/Job/JobTable/JobTable.tsx @@ -1,10 +1,13 @@ import { useState, useEffect } from "react"; import { Table, InternalLink } from "@ess-ics/ce-ui-common"; +import { type GridColDef } from "@mui/x-data-grid"; import { JobStatusColumn } from "./JobStatusColumn"; import { JobDetailsColumn } from "./JobDetailsColumn"; import { UserAvatar } from "../../common/User/UserAvatar"; +import { Job } from "../../../store/deployApi"; +import { Pagination } from "../../../types/common"; -const defaultColumns = [ +const defaultColumns: GridColDef[] = [ { field: "status", headerName: "Status", @@ -29,14 +32,18 @@ const defaultColumns = [ } ]; -const shapeColumns = (customColumns) => { - return customColumns.map((column) => { - const mappedCol = defaultColumns.find((col) => col.field === column.field); - return mappedCol ? { ...mappedCol, ...column } : null; - }); +const shapeColumns = (customColumns: typeof defaultColumns) => { + return customColumns + .map((column) => { + const mappedCol = defaultColumns.find( + (col) => col.field === column.field + ); + return mappedCol ? { ...mappedCol, ...column } : null; + }) + .filter((column) => column !== null); }; -const createTableRow = (job) => ({ +const createTableRow = (job: Job) => ({ id: job.id, status: <JobStatusColumn {...{ job }} />, jobId: ( @@ -51,14 +58,22 @@ const createTableRow = (job) => ({ user: <UserAvatar username={job.createdBy} /> }); +interface JobTableProps { + jobs?: Job[]; + customColumns?: GridColDef[]; + pagination: Pagination; + onPage: (params: Pagination) => void; + loading: boolean; +} + export const JobTable = ({ jobs, - customColumns = null, + customColumns, pagination, onPage, loading -}) => { - const [columns, setColumns] = useState(null); +}: JobTableProps) => { + const [columns, setColumns] = useState<GridColDef[] | null>(null); useEffect(() => { if (customColumns) { diff --git a/src/components/Job/JobUtils.ts b/src/components/Job/JobUtils.ts index 986a7dcf..157e23bf 100644 --- a/src/components/Job/JobUtils.ts +++ b/src/components/Job/JobUtils.ts @@ -1,10 +1,11 @@ import { ACTION_TYPES } from "./JobData"; +import { Job, JobEntry } from "../../store/deployApi"; -export const isBatchJob = (type) => +export const isBatchJob = (type: Job["action"]) => type === ACTION_TYPES.BATCH_DEPLOY || type === ACTION_TYPES.BATCH_UNDEPLOY; -export const getNoOfIOCs = (jobs) => - [...new Set(jobs.map((job) => job.iocId))].length; +export const getNoOfIOCs = (jobs?: JobEntry[]) => + [...new Set(jobs?.map((job) => job.iocId))].length; -export const getNoOfHosts = (jobs) => - [...new Set(jobs.map((job) => job.host.hostId))].length; +export const getNoOfHosts = (jobs?: JobEntry[]) => + [...new Set(jobs?.map((job) => job?.host?.hostId))].length; diff --git a/src/stories/components/common/job/JobTable.stories.tsx b/src/stories/components/common/job/JobTable.stories.tsx index cb601ac9..98f2a2e1 100644 --- a/src/stories/components/common/job/JobTable.stories.tsx +++ b/src/stories/components/common/job/JobTable.stories.tsx @@ -1,12 +1,12 @@ import { Box } from "@mui/material"; import { RouterHarness } from "../../../../mocks/AppHarness"; import { JobTable } from "../../../../components/Job/JobTable"; -import { type BaseJob } from "../../../../store/deployApi"; import operationList from "../../../../mocks/fixtures/Jobs.json"; import { hideStorybookControls, paginationNoResults } from "../../../utils/common-args"; +import { Job } from "../../../../store/deployApi"; import type { Meta, StoryFn } from "@storybook/react"; export default { @@ -52,7 +52,7 @@ export const Populated: JobTableStory = (args) => <Template {...args} />; Populated.args = { ...Empty.args, - jobs: operationList?.jobs as BaseJob[], + jobs: operationList?.jobs as Job[], pagination: { ...paginationNoResults, totalCount: operationList.totalCount } }; -- GitLab