Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
HostDetailsView.js 5.71 KiB
import { useEffect, useContext } from "react";
import useUrlState from "@ahooksjs/use-url-state";
import { Box, IconButton, Typography, Stack } from "@mui/material";
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
import {
  KeyValueTable,
  SimpleAccordion,
  GlobalAppBarContext,
  AlertBannerList,
  ExternalLink
} from "@ess-ics/ce-ui-common";
import { LokiPanel } from "../../../components/common/Loki/LokiPanel";
import { useNavigate } from "react-router-dom";
import { applicationTitle } from "../../../components/common/Helper";
import AccessControl from "../../../components/auth/AccessControl";
import {
  serialize,
  deserialize
} from "../../../components/common/URLState/URLState";
import { HostDetailsTable } from "./HostDetailsTable";
import { HostStatus } from "../../../components/host/HostStatus";
import { HostJobsSection } from "./HostJobsSection";
import { HostIocSection } from "./HostIocSection";
import env from "../../../config/env";

export function HostDetailsView({ hostId, host, alert }) {
  const { setTitle } = useContext(GlobalAppBarContext);

  useEffect(() => {
    if (host && host.name) {
      setTitle(applicationTitle("Host Details: " + host.name));
    }
  }, [host, setTitle]);

  const [urlState, setUrlState] = useUrlState(
    {
      iocs_rows: 20,
      iocs_page: 0,
      details_open: false,
      log_stream_open: false,
      job_log_open: false,
      job_log_rows: 20,
      job_log_page: 0
    },
    { navigateMode: "replace" }
  );
  const navigate = useNavigate();

  return (
    <Stack gap={2}>
      <Box>
        <IconButton
          color="inherit"
          onClick={() => navigate(-1)}
          size="large"
        >
          <ArrowBackIcon />
        </IconButton>
      </Box>
      {host && (
        <>
          <AlertBannerList alerts={alert.alerts ?? []} />
          <Stack
            flexDirection="row"
            alignItems="center"
            justifyContent="flex-start"
          >
            <Box
              sx={{
                marginRight: (theme) => theme.spacing(4),
                marginLeft: (theme) => theme.spacing(6)
              }}
            >
              <HostStatus
                hostId={hostId}
                hideAlerts
              />
            </Box>
            <Box sx={{ flex: 1 }}>
              <Typography
                noWrap
                variant="subtitle1"
                component="p"
                color="textPrimary"
              >
                {host.fqdn}
              </Typography>
              <Typography
                noWrap
                component="p"
                variant="subtitle2"
              >
                {host.network || "---"}
              </Typography>
            </Box>
          </Stack>
          <Stack gap={2}>
            <HostIocSection
              hostId={hostId}
              rows={deserialize(urlState.iocs_rows)}
              page={deserialize(urlState.iocs_page)}
              onUrlStateChange={(params) => setUrlState(params)}
            />
          </Stack>
          <HostJobsSection
            hostId={hostId}
            rows={deserialize(urlState.job_log_rows)}
            page={deserialize(urlState.job_log_page)}
            expanded={deserialize(urlState.job_log_open)}
            onUrlStateChange={(params) => setUrlState(params)}
          />

          <AccessControl
            allowedRoles={["DeploymentToolAdmin", "DeploymentToolIntegrator"]}
            renderNoAccess={() => <></>}
          >
            <SimpleAccordion
              summary={
                <Typography
                  variant="h3"
                  component="h2"
                >
                  Host details
                </Typography>
              }
              expanded={deserialize(urlState.details_open)}
              onChange={(_, expanded) =>
                setUrlState({ details_open: serialize(expanded) })
              }
            >
              <HostDetailsTable host={host} />
            </SimpleAccordion>

            <SimpleAccordion
              summary={
                <Typography
                  variant="h3"
                  component="h2"
                >
                  Host log stream
                </Typography>
              }
              expanded={deserialize(urlState.log_stream_open)}
              onChange={(_, expanded) =>
                setUrlState({ log_stream_open: serialize(expanded) })
              }
            >
              <LokiPanel
                hostName={host.name}
                isSyslog
                isDeployed
              />
            </SimpleAccordion>
          </AccessControl>
          <KeyValueTable
            obj={{
              "Host Configuration": (
                <ExternalLink
                  href={
                    host.vm
                      ? `${env.NETBOX_ADDRESS}/virtualization/virtual-machines/${host.id}`
                      : `${env.NETBOX_ADDRESS}/dcim/devices/${host.id}`
                  }
                  aria-label="Host Configuration"
                >
                  {" "}
                  {host.vm
                    ? `${env.NETBOX_ADDRESS}/virtualization/virtual-machines/${host.id}`
                    : `${env.NETBOX_ADDRESS}/dcim/devices/${host.id}`}
                </ExternalLink>
              ),
              "Host Metrics": (
                <ExternalLink
                  href={`https://grafana.tn.esss.lu.se/d/5zJT23xWz/node-exporter-full?orgId=1&var-node=${host.fqdn}`}
                  aria-label="Host Metrics"
                >
                  {`https://grafana.tn.esss.lu.se/d/5zJT23xWz/node-exporter-full?orgId=1&var-node=${host.fqdn}`}
                </ExternalLink>
              )
            }}
            variant="overline"
          />
        </>
      )}
    </Stack>
  );
}