diff --git a/src/components/IOC/CreateIOC/CreateIOC.js b/src/components/IOC/CreateIOC/CreateIOC.js index fde4c006ee2587ac686acc0996efee25d649bdb9..71abff0170810205b180d808a9737cd7ac8cee90 100644 --- a/src/components/IOC/CreateIOC/CreateIOC.js +++ b/src/components/IOC/CreateIOC/CreateIOC.js @@ -14,18 +14,7 @@ import { } from "@mui/material"; import { useAPIMethod } from "@ess-ics/ce-ui-common"; import { apiContext } from "../../../api/DeployApi"; - -const renderErrorMessage = (error) => { - const { response, status: requestStatus, message: requestMessage } = error; - const { - body: { description }, - status: httpStatus - } = response; - - return `${httpStatus ?? requestStatus ?? "unknown"}: ${ - description ?? requestMessage ?? "An unknown error has occurred" - }`; -}; +import { getErrorMessage } from "../../common/Helper"; const createRequestParams = (query) => { return { @@ -211,7 +200,7 @@ export function CreateIOC() { autoSelect /> {error ? ( - <Alert severity="error">{renderErrorMessage(error)}</Alert> + <Alert severity="error">{getErrorMessage(error)}</Alert> ) : ( <></> )} diff --git a/src/components/common/Helper.js b/src/components/common/Helper.js index feda071b423fc83d9853e636c6a9897d4be981b3..e075163ba03fb7edf1f6f45dedd606df09ac34cf 100644 --- a/src/components/common/Helper.js +++ b/src/components/common/Helper.js @@ -101,6 +101,21 @@ export function initRequestParams(lazyParams, filter, columnSort) { return requestParams; } +export const getErrorMessage = (error) => { + const { response, status: requestStatus, message: requestMessage } = error; + if (response && response?.body) { + const { + body: { description }, + status: httpStatus + } = response; + + return `${httpStatus ?? requestStatus ?? "unknown"}: ${ + description ?? requestMessage ?? "An unknown error has occurred" + }`; + } + return `${requestStatus}: ${requestMessage}`; +}; + export const compareArrays = (a1, a2) => a1.length === a2.length && a1.every((element, index) => element === a2[index]); diff --git a/src/views/host/details/HostDetailsView.js b/src/views/host/details/HostDetailsView.js index a98a58bf6719550c8ca5b97df9b315fd9a3988ef..9f87142b199d2ac9cd40abe9d2a82227353ebec1 100644 --- a/src/views/host/details/HostDetailsView.js +++ b/src/views/host/details/HostDetailsView.js @@ -26,6 +26,7 @@ import { import { apiContext } from "../../../api/DeployApi"; import IOCTable from "../../../components/IOC/IOCTable"; import { HostDetailsTable } from "./HostDetailsTable"; +import { HostJobsSection } from "./HostJobsSection"; export function HostDetailsView({ hostId, host }) { const { setTitle } = useContext(GlobalAppBarContext); @@ -141,7 +142,7 @@ export function HostDetailsView({ hostId, host }) { <HostBadge host={host} /> </> ) : null} - <Stack gap={2}> + <Stack> <Typography variant="h3">IOCs</Typography> <IOCTable iocs={iocs?.deployedIocs} @@ -151,6 +152,8 @@ export function HostDetailsView({ hostId, host }) { onPage={onPage} /> </Stack> + {hostId ? <HostJobsSection hostId={hostId} /> : null} + <AccessControl allowedRoles={["DeploymentToolAdmin", "DeploymentToolIntegrator"]} renderNoAccess={() => <></>} @@ -168,6 +171,7 @@ export function HostDetailsView({ hostId, host }) { </SimpleAccordion> ) : null} </AccessControl> + <AccessControl allowedRoles={["DeploymentToolAdmin", "DeploymentToolIntegrator"]} renderNoAccess={() => <></>} diff --git a/src/views/host/details/HostJobsSection.js b/src/views/host/details/HostJobsSection.js new file mode 100644 index 0000000000000000000000000000000000000000..b096e6e4cc3d0827b458efa43e528f4f525babba --- /dev/null +++ b/src/views/host/details/HostJobsSection.js @@ -0,0 +1,79 @@ +import React, { useContext, useState, useEffect, useMemo } from "react"; +import { string, object } from "prop-types"; +import { getErrorMessage } from "../../../components/common/Helper"; +import { apiContext } from "../../../api/DeployApi"; +import { + SimpleAccordion, + useAPIMethod, + usePagination +} from "@ess-ics/ce-ui-common"; +import { JobTable } from "../../../components/Job"; +import { Alert } from "@mui/material"; + +const propTypes = { + hostId: string.isRequired, + urlPagination: object +}; + +const rowsPerPage = [20, 50]; + +export const HostJobsSection = ({ hostId }) => { + const client = useContext(apiContext); + const [expanded, setExpanded] = useState(false); + + const { pagination, setPagination } = usePagination({ + rowsPerPageOptions: rowsPerPage, + initLimit: rowsPerPage[0], + initPage: 0 + }); + + const { + value: hostLog, + wrapper: getHostLog, + error, + loading, + abort + } = useAPIMethod({ + fcn: client.apis.Deployments.listOperations, + call: false, + params: useMemo( + () => ({ host_id: hostId, ...pagination }), + [hostId, pagination] + ) + }); + + useEffect(() => { + setPagination({ totalCount: hostLog?.totalCount ?? 0 }); + }, [setPagination, hostLog]); + + useEffect(() => { + if (expanded) { + getHostLog(); + } + }, [expanded, pagination, getHostLog]); + + useEffect(() => { + return () => { + abort(); + }; + }, [abort]); + + return ( + <SimpleAccordion + summary="Job log" + onChange={(_, isExpanded) => setExpanded(isExpanded)} + > + {error ? <Alert severity="error">{getErrorMessage(error)}</Alert> : null} + {hostLog ? ( + <JobTable + jobs={hostLog.operations} + loading={loading} + pagination={pagination} + onPage={setPagination} + /> + ) : null} + </SimpleAccordion> + ); +}; + +HostJobsSection.propTypes = propTypes;