From fc09d0c966679c753bbc3dbf69326bb36cdba54c Mon Sep 17 00:00:00 2001
From: Johanna Szepanski <johanna.szepanski@softhouse.se>
Date: Thu, 20 Jun 2024 08:06:03 +0200
Subject: [PATCH] Replace fetching data banner with linear progress

Before job is started lineear progress is displayed instead of a banner
saying Fetching data. Once the job is queued then a banner i visible
stating the current job step. Should correspond to stepper state, but
they are out of sync. This issue is reported as a bug and out of this scope.
---
 src/api/DataTypes.js             | 12 ++---
 src/components/Job/JobDetails.js | 90 +++++++++++++++-----------------
 2 files changed, 48 insertions(+), 54 deletions(-)

diff --git a/src/api/DataTypes.js b/src/api/DataTypes.js
index ebf4b3f7..0f858e4c 100644
--- a/src/api/DataTypes.js
+++ b/src/api/DataTypes.js
@@ -31,12 +31,12 @@ export class AWXJobDetails {
     return this.job?.status.toLowerCase();
   }
   message() {
-    const stem = this.job ? `${this.typeLabel()} ` : "";
-    const info = this.job
-      ? jobMessages[this.job.status.toLowerCase()]
-      : "Fetching data";
-    const message = stem + info;
-    return message;
+    if (this.job) {
+      const stem = this.typeLabel();
+      const info = jobMessages[this.job.status.toLowerCase()];
+      return `${stem} ${info}`;
+    }
+    return null;
   }
   severity() {
     const status = this.job?.status.toLowerCase();
diff --git a/src/components/Job/JobDetails.js b/src/components/Job/JobDetails.js
index 37d523ee..b041100e 100644
--- a/src/components/Job/JobDetails.js
+++ b/src/components/Job/JobDetails.js
@@ -1,5 +1,11 @@
 import React, { useEffect, useState, useMemo } from "react";
-import { Typography, Card, CardContent, Stack } from "@mui/material";
+import {
+  Typography,
+  Card,
+  CardContent,
+  Stack,
+  LinearProgress
+} from "@mui/material";
 import {
   KeyValueTable,
   SimpleAccordion,
@@ -17,48 +23,31 @@ import AccessControl from "../auth/AccessControl";
 import { AWXJobDetails } from "../../api/DataTypes";
 import { JobStatusStepper } from "./JobStatus";
 
-function createAlert(operation, job) {
-  const jobDetails = new AWXJobDetails(operation.type, job);
-  const message = jobDetails.message();
-  const severity = jobDetails.severity();
+const createAlert = (operation) => {
   return {
-    type: severity,
-    message: message
+    type: operation.severity(),
+    message: operation.message()
   };
-}
-
-export function JobDetails({ operation, job }) {
-  let jobAlert = useMemo(() => operation.alerts ?? [], [operation]);
-
-  const finishedJob = useMemo(
-    () => operation && new AWXJobDetails(operation.type, job).isFinished(),
-    [operation, job]
-  );
-
-  const [alert, setAlert] = useState(createAlert(operation, job));
-
-  useEffect(() => {
-    setAlert(createAlert(operation, job, finishedJob));
-  }, [finishedJob, operation, job]);
-
-  function calculateHostText() {
-    // host is resolvable => show link for users
-    if (operation.host.hostId && operation.host.externalIdValid) {
-      return (
-        <InternalLink
-          to={`/hosts/${operation.host.hostId}`}
-          label={`Host Details, ${operation.host.fqdn}`}
-        >
-          {operation.host.fqdn}
-        </InternalLink>
-      );
-    }
+};
 
-    // gray out hostname if it is from cache
-    return <Typography color="gray">{operation.host.fqdn}</Typography>;
+const calculateHostText = (operation) => {
+  // host is resolvable => show link for users
+  if (operation.host.hostId && operation.host.externalIdValid) {
+    return (
+      <InternalLink
+        to={`/hosts/${operation.host.hostId}`}
+        label={`Host Details, ${operation.host.fqdn}`}
+      >
+        {operation.host.fqdn}
+      </InternalLink>
+    );
   }
+  // gray out hostname if it is from cache
+  return <Typography color="gray">{operation.host.fqdn}</Typography>;
+};
 
-  const deploymentDetails = {
+const getDeploymentDetails = (operation) => {
+  return {
     Revision: (
       <GitRefLink
         url={operation.gitProjectUrl}
@@ -66,7 +55,7 @@ export function JobDetails({ operation, job }) {
         revision={operation.gitShortReference}
       />
     ),
-    host: calculateHostText(),
+    host: calculateHostText(operation),
     user: (
       <InternalLink
         to={`/user/${operation.createdBy}`}
@@ -103,23 +92,28 @@ export function JobDetails({ operation, job }) {
       <EmptyValue />
     )
   };
+};
 
-  const finishedJobAlerts = finishedJob ? (
-    <AlertBannerList alerts={[alert].concat(jobAlert)} />
-  ) : null;
+export const JobDetails = ({ operation, job }) => {
+  const [alerts, setAlerts] = useState(operation.alerts ?? []);
 
-  const unFinishedJobsWithAlerts =
-    !finishedJob && alert ? <AlertBannerList alerts={[alert]} /> : null;
+  const jobOperation = useMemo(
+    () => new AWXJobDetails(operation.type, job),
+    [operation, job]
+  );
+
+  useEffect(() => {
+    setAlerts([createAlert(jobOperation, job), ...operation.alerts]);
+  }, [operation, job, jobOperation]);
 
   return (
     <Stack spacing={2}>
       <Stack>
-        {finishedJobAlerts}
-        {unFinishedJobsWithAlerts}
+        {job ? <AlertBannerList alerts={alerts} /> : <LinearProgress />}
       </Stack>
       <JobBadge operation={operation} />
       <KeyValueTable
-        obj={deploymentDetails}
+        obj={getDeploymentDetails(operation)}
         variant="overline"
         sx={{ border: 0 }}
         valueOptions={{ headerName: "" }}
@@ -145,4 +139,4 @@ export function JobDetails({ operation, job }) {
       </AccessControl>
     </Stack>
   );
-}
+};
-- 
GitLab