From 0d4e38b75282ac293367fbc3bad757a226e5fda7 Mon Sep 17 00:00:00 2001
From: Johanna Szepanski <johanna.szepanski@softhouse.se>
Date: Thu, 16 Jan 2025 08:24:06 +0100
Subject: [PATCH 1/7] updated backend

---
 src/store/deployApi.ts | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/src/store/deployApi.ts b/src/store/deployApi.ts
index abcb3b50..46d056d2 100644
--- a/src/store/deployApi.ts
+++ b/src/store/deployApi.ts
@@ -304,6 +304,12 @@ const injectedRtkApi = api.injectEndpoints({
         url: `/api/v1/hosts/${queryArg.hostId}/info_by_host_id`
       })
     }),
+    checkHostExists: build.query<
+      CheckHostExistsApiResponse,
+      CheckHostExistsApiArg
+    >({
+      query: (queryArg) => ({ url: `/api/v1/hosts/${queryArg.hostId}/exists` })
+    }),
     findHostAlerts: build.query<
       FindHostAlertsApiResponse,
       FindHostAlertsApiArg
@@ -465,7 +471,8 @@ export type UpdateIocApiArg = {
   iocUpdateRequest: IocUpdateRequest;
 };
 export type UnDeployInDbApiResponse =
-  /** status 200 Undeployment created */ Deployment[];
+  /** status 200 Undeployment created */
+  Deployment[] | /** status 204 No Content */ void;
 export type UnDeployInDbApiArg = {
   /** The id of the IOC to undeploy */
   iocId: number;
@@ -657,6 +664,12 @@ export type FindNetBoxHostByHostIdApiArg = {
   /** The host's Host ID */
   hostId: string;
 };
+export type CheckHostExistsApiResponse =
+  /** status 200 Hosts exists in NetBox */ void;
+export type CheckHostExistsApiArg = {
+  /** Host identifier */
+  hostId: string;
+};
 export type FindHostAlertsApiResponse =
   /** status 200 Host alerts */ HostAlertResponse;
 export type FindHostAlertsApiArg = {
@@ -1188,6 +1201,8 @@ export const {
   useLazyFindAssociatedIocsByHostIdQuery,
   useFindNetBoxHostByHostIdQuery,
   useLazyFindNetBoxHostByHostIdQuery,
+  useCheckHostExistsQuery,
+  useLazyCheckHostExistsQuery,
   useFindHostAlertsQuery,
   useLazyFindHostAlertsQuery,
   useFindNetBoxHostByFqdnQuery,
-- 
GitLab


From 389913ed2894f13ffc72901779e49aa6dad21586 Mon Sep 17 00:00:00 2001
From: Johanna Szepanski <johanna.szepanski@softhouse.se>
Date: Thu, 16 Jan 2025 11:54:54 +0100
Subject: [PATCH 2/7] host name should only be a link if host exists

---
 .../Job/JobTable/JobDetailsColumn.tsx         | 34 ++++++++++++++-----
 1 file changed, 25 insertions(+), 9 deletions(-)

diff --git a/src/components/Job/JobTable/JobDetailsColumn.tsx b/src/components/Job/JobTable/JobDetailsColumn.tsx
index fa2423c5..a6913361 100644
--- a/src/components/Job/JobTable/JobDetailsColumn.tsx
+++ b/src/components/Job/JobTable/JobDetailsColumn.tsx
@@ -1,6 +1,7 @@
-import { useMemo } from "react";
-import { Stack, Typography } from "@mui/material";
+import { useMemo, useEffect } from "react";
+import { Stack, Typography, Box } from "@mui/material";
 import { InternalLink } from "@ess-ics/ce-ui-common";
+import { useLazyCheckHostExistsQuery, Job } from "../../../store/deployApi";
 import {
   ACTION_TYPES,
   getNoOfIOCs,
@@ -9,10 +10,13 @@ import {
 } from "../JobUtils";
 import { ActionTypeIconText } from "../JobIcons";
 import { JobRevisionChip } from "../JobRevisionChip";
-import { Job } from "../../../store/deployApi";
 
 export const JobDetailsColumn = ({ job }: { job: Job }) => {
   const isBatchOperation = isBatchJob(job.action);
+  const [
+    callCheckHostExists,
+    { isLoading: checkHostExistsLoading, isSuccess }
+  ] = useLazyCheckHostExistsQuery();
 
   const noOfIOCs = useMemo(() => {
     if (isBatchOperation) {
@@ -26,6 +30,12 @@ export const JobDetailsColumn = ({ job }: { job: Job }) => {
     }
   }, [job, isBatchOperation]);
 
+  useEffect(() => {
+    if (!isBatchOperation && job.host?.hostId) {
+      callCheckHostExists({ hostId: job.host.hostId });
+    }
+  }, [isBatchOperation, job?.host?.hostId, callCheckHostExists]);
+
   return (
     <Stack>
       <ActionTypeIconText action={job.action} />
@@ -58,12 +68,18 @@ export const JobDetailsColumn = ({ job }: { job: Job }) => {
             alignItems="baseline"
             flexWrap="wrap"
           >
-            <InternalLink
-              to={`/hosts/${job?.host?.hostId}`}
-              label={`Host details, ${job.host?.hostName}`}
-            >
-              {job?.host?.hostName}
-            </InternalLink>
+            <Box sx={{ minWidth: "112px" }}>
+              {!checkHostExistsLoading && isSuccess ? (
+                <InternalLink
+                  to={`/hosts/${job?.host?.hostId}`}
+                  label={`Host details, ${job.host?.hostName}`}
+                >
+                  {job.host?.hostName}
+                </InternalLink>
+              ) : (
+                <Typography>{job.host?.hostName}</Typography>
+              )}
+            </Box>
             <Typography variant="body2">{job?.host?.network}</Typography>
           </Stack>
         </Stack>
-- 
GitLab


From c06ddfe142bddaade95e07ea24c8c58036a6fc08 Mon Sep 17 00:00:00 2001
From: Johanna Szepanski <johanna.szepanski@softhouse.se>
Date: Mon, 20 Jan 2025 10:17:12 +0100
Subject: [PATCH 3/7] added som ts fixes

---
 src/components/Job/JobTable/JobDetailsColumn.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/Job/JobTable/JobDetailsColumn.tsx b/src/components/Job/JobTable/JobDetailsColumn.tsx
index a6913361..7354a06f 100644
--- a/src/components/Job/JobTable/JobDetailsColumn.tsx
+++ b/src/components/Job/JobTable/JobDetailsColumn.tsx
@@ -34,7 +34,7 @@ export const JobDetailsColumn = ({ job }: { job: Job }) => {
     if (!isBatchOperation && job.host?.hostId) {
       callCheckHostExists({ hostId: job.host.hostId });
     }
-  }, [isBatchOperation, job?.host?.hostId, callCheckHostExists]);
+  }, [isBatchOperation, job?.host, callCheckHostExists]);
 
   return (
     <Stack>
-- 
GitLab


From d51f16d515006ea6c9f54037a82e9e2ad018bb39 Mon Sep 17 00:00:00 2001
From: Johanna Szepanski <johanna.szepanski@softhouse.se>
Date: Mon, 20 Jan 2025 13:18:20 +0100
Subject: [PATCH 4/7] generalized JobHost to be more reusable

---
 src/components/Job/JobDetailsBatchJob.tsx     |   7 +-
 src/components/Job/JobDetailsSingleJob.tsx    |  28 +++--
 src/components/Job/JobDetailsTable.tsx        | 114 ------------------
 src/components/Job/JobHost.tsx                |  17 ++-
 .../Job/JobTable/JobDetailsColumn.tsx         |  19 ++-
 5 files changed, 38 insertions(+), 147 deletions(-)
 delete mode 100644 src/components/Job/JobDetailsTable.tsx

diff --git a/src/components/Job/JobDetailsBatchJob.tsx b/src/components/Job/JobDetailsBatchJob.tsx
index cbb02c58..f4b3d70e 100644
--- a/src/components/Job/JobDetailsBatchJob.tsx
+++ b/src/components/Job/JobDetailsBatchJob.tsx
@@ -58,7 +58,12 @@ const createRow = (job: JobDetails, action: string | undefined) => {
         </Stack>
       </Stack>
     ),
-    host: <JobHost job={job} />
+    host: (
+      <JobHost
+        url={job.host?.externalIdValid ? job.host.hostId : undefined}
+        label={job.host?.fqdn}
+      />
+    )
   };
 };
 
diff --git a/src/components/Job/JobDetailsSingleJob.tsx b/src/components/Job/JobDetailsSingleJob.tsx
index e60018e1..7ca67c38 100644
--- a/src/components/Job/JobDetailsSingleJob.tsx
+++ b/src/components/Job/JobDetailsSingleJob.tsx
@@ -8,13 +8,13 @@ interface JobDetailsSingleJobProps {
   job: JobDetails;
 }
 
-const getRevision = (operation: JobDetails) => {
+const getRevision = (job: JobDetails) => {
   return {
     revision:
-      operation.gitReference && operation.gitProjectId ? (
+      job.gitReference && job.gitProjectId ? (
         <JobRevisionChip
-          gitReference={operation.gitReference}
-          gitProjectId={operation.gitProjectId}
+          gitReference={job.gitReference}
+          gitProjectId={job.gitProjectId}
         />
       ) : (
         "Unknown"
@@ -22,21 +22,23 @@ const getRevision = (operation: JobDetails) => {
   };
 };
 
-const getSingleOperationFields = (
-  operation: JobDetails,
-  isDeployJob: boolean
-) => {
+const getSingleOperationFields = (job: JobDetails, isDeployJob: boolean) => {
   return {
     ioc: (
       <InternalLink
-        to={`/iocs/${operation.iocName}`}
-        label={`IOC details, ${operation.iocName}`}
+        to={`/iocs/${job.iocName}`}
+        label={`IOC details, ${job.iocName}`}
       >
-        {operation.iocName}
+        {job.iocName}
       </InternalLink>
     ),
-    ...(isDeployJob && getRevision(operation)),
-    host: <JobHost job={operation} />
+    ...(isDeployJob && getRevision(job)),
+    host: (
+      <JobHost
+        url={job.host?.externalIdValid ? job.host.hostId : undefined}
+        label={job.host?.fqdn}
+      />
+    )
   };
 };
 
diff --git a/src/components/Job/JobDetailsTable.tsx b/src/components/Job/JobDetailsTable.tsx
deleted file mode 100644
index 2832645a..00000000
--- a/src/components/Job/JobDetailsTable.tsx
+++ /dev/null
@@ -1,114 +0,0 @@
-import { useMemo } from "react";
-import {
-  EllipsisText,
-  InternalLink,
-  Table,
-  SimpleAccordion
-} from "@ess-ics/ce-ui-common";
-import { Typography, Stack } from "@mui/material";
-import { getNoOfIOCs, getNoOfHosts, isBatchJob } from "./JobUtils";
-import { JobRevisionChip } from "./JobRevisionChip";
-import { JobHost } from "./JobHost";
-import { JobDetails, JobDetailsEntry } from "../../store/deployApi";
-
-const columns = [
-  {
-    field: "ioc",
-    headerName: "IOC",
-    flex: 1
-  },
-  {
-    field: "revision",
-    headerName: "Revision",
-    flex: 1
-  },
-  {
-    field: "host",
-    headerName: "Host",
-    flex: 1
-  }
-];
-
-const createRow = (job: JobDetailsEntry) => {
-  const { iocId, iocName, host, gitReference, gitProjectId } = job;
-  return {
-    id: `${iocId}${host?.hostId}`,
-    ioc: (
-      <InternalLink
-        to={`/iocs/${iocId}`}
-        label={`Ioc details, ${iocName}`}
-        width="100%"
-      >
-        <EllipsisText>{iocName}</EllipsisText>
-      </InternalLink>
-    ),
-    host: <JobHost job={job} />,
-    revision: gitReference && gitProjectId && (
-      <JobRevisionChip
-        gitReference={gitReference}
-        gitProjectId={gitProjectId}
-      />
-    )
-  };
-};
-
-export const JobDetailsTable = ({ operation }: { operation: JobDetails }) => {
-  const isBatchOperation = isBatchJob(operation.action);
-
-  const noOfIOCs = useMemo(() => {
-    if (isBatchOperation) {
-      return getNoOfIOCs(operation.jobs);
-    }
-  }, [operation, isBatchOperation]);
-
-  const noOfHosts = useMemo(() => {
-    if (isBatchOperation) {
-      return getNoOfHosts(operation.jobs);
-    }
-  }, [operation, isBatchOperation]);
-
-  return (
-    <>
-      {isBatchJob(operation.action) ? (
-        <SimpleAccordion
-          summary={
-            <Stack
-              flexDirection="row"
-              alignItems="end"
-              sx={{ width: "100%" }}
-              gap={1}
-            >
-              {" "}
-              <Typography
-                component="h2"
-                variant="h3"
-              >
-                Batch
-              </Typography>
-              <Typography
-                variant="body2"
-                sx={{ fontWeight: "600", marginRight: "10px" }}
-              >
-                {noOfIOCs} {noOfIOCs && noOfIOCs > 1 ? "IOCs" : "IOC"}
-                {", "}
-                {noOfHosts} {noOfHosts && noOfHosts > 1 ? "Hosts" : "Host"}
-              </Typography>
-            </Stack>
-          }
-        >
-          <Table
-            columns={columns}
-            disableColumnSorting
-            rows={operation?.jobs?.map((job) => createRow(job))}
-          />
-        </SimpleAccordion>
-      ) : (
-        <Table
-          columns={columns}
-          disableColumnSorting
-          rows={[operation].map((job) => createRow(job))}
-        />
-      )}
-    </>
-  );
-};
diff --git a/src/components/Job/JobHost.tsx b/src/components/Job/JobHost.tsx
index 465f26a7..285a9c09 100644
--- a/src/components/Job/JobHost.tsx
+++ b/src/components/Job/JobHost.tsx
@@ -1,28 +1,27 @@
 import { EllipsisText, InternalLink } from "@ess-ics/ce-ui-common";
 import { Typography } from "@mui/material";
-import { JobDetails } from "../../store/deployApi";
 
 interface JobHostProps {
-  job: JobDetails;
+  url: string | undefined;
+  label: string | undefined;
 }
 
-export const JobHost = ({ job }: JobHostProps) => {
+export const JobHost = ({ url, label }: JobHostProps) => {
   // host is resolvable => show link for users
-  if (job?.host?.hostId && job?.host?.externalIdValid) {
+  if (url) {
     return (
       <InternalLink
-        to={`/hosts/${job.host.hostId}`}
-        label={`Host Details, ${job.host.fqdn}`}
+        to={`/hosts/${url}`}
+        label={`Host Details, ${label}`}
         width="100%"
       >
-        <EllipsisText>{job.host.fqdn}</EllipsisText>
+        <EllipsisText>{label}</EllipsisText>
       </InternalLink>
     );
   }
-  // gray out hostname if it is from cache
   return (
     <Typography color="gray">
-      <EllipsisText>{job?.host?.fqdn}</EllipsisText>
+      <EllipsisText>{label}</EllipsisText>
     </Typography>
   );
 };
diff --git a/src/components/Job/JobTable/JobDetailsColumn.tsx b/src/components/Job/JobTable/JobDetailsColumn.tsx
index 7354a06f..84d75a57 100644
--- a/src/components/Job/JobTable/JobDetailsColumn.tsx
+++ b/src/components/Job/JobTable/JobDetailsColumn.tsx
@@ -10,6 +10,7 @@ import {
 } from "../JobUtils";
 import { ActionTypeIconText } from "../JobIcons";
 import { JobRevisionChip } from "../JobRevisionChip";
+import { JobHost } from "../JobHost";
 
 export const JobDetailsColumn = ({ job }: { job: Job }) => {
   const isBatchOperation = isBatchJob(job.action);
@@ -69,16 +70,14 @@ export const JobDetailsColumn = ({ job }: { job: Job }) => {
             flexWrap="wrap"
           >
             <Box sx={{ minWidth: "112px" }}>
-              {!checkHostExistsLoading && isSuccess ? (
-                <InternalLink
-                  to={`/hosts/${job?.host?.hostId}`}
-                  label={`Host details, ${job.host?.hostName}`}
-                >
-                  {job.host?.hostName}
-                </InternalLink>
-              ) : (
-                <Typography>{job.host?.hostName}</Typography>
-              )}
+              <JobHost
+                url={
+                  !checkHostExistsLoading && isSuccess
+                    ? job?.host?.hostId
+                    : undefined
+                }
+                label={job.host?.hostName}
+              />
             </Box>
             <Typography variant="body2">{job?.host?.network}</Typography>
           </Stack>
-- 
GitLab


From 7f23a28aa225cd4afdce89802b88894030fbef7e Mon Sep 17 00:00:00 2001
From: Johanna Szepanski <johanna.szepanski@softhouse.se>
Date: Mon, 20 Jan 2025 15:30:09 +0100
Subject: [PATCH 5/7] fixed mocks and handlers

---
 src/mocks/fixtures/Jobs.json | 96 ++++++++++++++++++++++--------------
 src/mocks/mockAPI.ts         | 14 ++++++
 2 files changed, 74 insertions(+), 36 deletions(-)

diff --git a/src/mocks/fixtures/Jobs.json b/src/mocks/fixtures/Jobs.json
index cacb207d..fc2e22f0 100644
--- a/src/mocks/fixtures/Jobs.json
+++ b/src/mocks/fixtures/Jobs.json
@@ -25,7 +25,8 @@
         "hostName": "ccce-test-ioc-02",
         "network": "CSLab-GeneralLab",
         "fqdn": "ccce-test-ioc-02.cslab.esss.lu.se",
-        "netBoxHostFromCache": true
+        "netBoxHostFromCache": true,
+        "deleted": false
       },
       "awxJobId": 7486,
       "jobUrl": "https://awx-lab-01.cslab.esss.lu.se/#/jobs/playbook/7486",
@@ -73,11 +74,12 @@
       "gitShortReference": "0a5b165b",
       "host": {
         "hostId": "MTUxX3RydWU=",
-        "externalIdValid": true,
+        "externalIdValid": false,
         "hostName": "ccce-test-ioc-01",
         "network": "CSLab-GeneralLab",
         "fqdn": "ccce-test-ioc-01.cslab.esss.lu.se",
-        "netBoxHostFromCache": true
+        "netBoxHostFromCache": true,
+        "deleted": true
       },
       "awxJobId": 7482,
       "jobUrl": "https://awx-lab-01.cslab.esss.lu.se/#/jobs/playbook/7482",
@@ -124,11 +126,12 @@
       "gitShortReference": "525c1a89",
       "host": {
         "hostId": "MTUxX3RydWU=",
-        "externalIdValid": true,
+        "externalIdValid": false,
         "hostName": "ccce-test-ioc-01",
         "network": "CSLab-GeneralLab",
         "fqdn": "ccce-test-ioc-01.cslab.esss.lu.se",
-        "netBoxHostFromCache": true
+        "netBoxHostFromCache": true,
+        "deleted": true
       },
       "git_project_info": {
         "id": 595959,
@@ -181,10 +184,11 @@
           "host": {
             "hostId": "MTUxX3RydWU=",
             "externalIdValid": true,
-            "hostName": "ccce-test-ioc-01",
+            "hostName": "ccce-test-ioc-02",
             "network": "CSLab-GeneralLab",
-            "fqdn": "ccce-test-ioc-01.cslab.esss.lu.se",
-            "netBoxHostFromCache": true
+            "fqdn": "ccce-test-ioc-02.cslab.esss.lu.se",
+            "netBoxHostFromCache": true,
+            "deleted": false
           }
         },
         {
@@ -194,11 +198,12 @@
           "gitReference": "engineer_set",
           "host": {
             "hostId": "MTUxX3RydWU=",
-            "externalIdValid": true,
+            "externalIdValid": false,
             "hostName": "ccce-test-ioc-01",
             "network": "CSLab-GeneralLab",
             "fqdn": "ccce-test-ioc-01.cslab.esss.lu.se",
-            "netBoxHostFromCache": true
+            "netBoxHostFromCache": true,
+            "deleted": true
           }
         }
       ],
@@ -250,7 +255,8 @@
             "hostName": "ccce-test-ioc-56-test",
             "network": "CSLab-GeneralLab",
             "fqdn": "ccce-test-ioc-02.test1",
-            "netBoxHostFromCache": true
+            "netBoxHostFromCache": true,
+            "deleted": false
           }
         },
         {
@@ -264,7 +270,8 @@
             "hostName": "ccce-test-ioc-56-test",
             "network": "CSLab-GeneralLab",
             "fqdn": "ccce-test-ioc-02.test1",
-            "netBoxHostFromCache": true
+            "netBoxHostFromCache": true,
+            "deleted": false
           }
         },
         {
@@ -278,7 +285,8 @@
             "hostName": "ccce-test-ioc-56-test",
             "network": "CSLab-GeneralLab",
             "fqdn": "ccce-test-ioc-02.test1",
-            "netBoxHostFromCache": true
+            "netBoxHostFromCache": true,
+            "deleted": false
           }
         },
         {
@@ -292,7 +300,8 @@
             "hostName": "ccce-test-ioc-test",
             "network": "CSLab-GeneralLab",
             "fqdn": "AnotherHost.fqdn",
-            "netBoxHostFromCache": true
+            "netBoxHostFromCache": true,
+            "deleted": false
           }
         }
       ],
@@ -334,11 +343,12 @@
       "gitShortReference": "a278b61c",
       "host": {
         "hostId": "MTUxX3RydWU=",
-        "externalIdValid": true,
+        "externalIdValid": false,
         "hostName": "ccce-test-ioc-01",
         "network": "CSLab-GeneralLab",
         "fqdn": "ccce-test-ioc-01.cslab.esss.lu.se",
-        "netBoxHostFromCache": true
+        "netBoxHostFromCache": true,
+        "deleted": true
       },
       "awxJobId": 7467,
       "jobUrl": "https://awx-lab-01.cslab.esss.lu.se/#/jobs/playbook/7467",
@@ -390,7 +400,8 @@
         "hostName": "ccce-test-ioc-02",
         "network": "CSLab-GeneralLab",
         "fqdn": "ccce-test-ioc-02.cslab.esss.lu.se",
-        "netBoxHostFromCache": true
+        "netBoxHostFromCache": true,
+        "deleted": false
       },
       "awxJobId": 7466,
       "jobUrl": "https://awx-lab-01.cslab.esss.lu.se/#/jobs/command/7466",
@@ -437,11 +448,12 @@
       "gitShortReference": "4567a397",
       "host": {
         "hostId": "MTUxX3RydWU=",
-        "externalIdValid": true,
+        "externalIdValid": false,
         "hostName": "ccce-test-ioc-01",
         "network": "CSLab-GeneralLab",
         "fqdn": "ccce-test-ioc-01.cslab.esss.lu.se",
-        "netBoxHostFromCache": true
+        "netBoxHostFromCache": true,
+        "deleted": true
       },
       "awxJobId": 7450,
       "jobUrl": "https://awx-lab-01.cslab.esss.lu.se/#/jobs/command/7450",
@@ -488,11 +500,12 @@
       "gitShortReference": "a278b61c",
       "host": {
         "hostId": "MTUxX3RydWU=",
-        "externalIdValid": true,
+        "externalIdValid": false,
         "hostName": "ccce-test-ioc-01",
         "network": "CSLab-GeneralLab",
         "fqdn": "ccce-test-ioc-01.cslab.esss.lu.se",
-        "netBoxHostFromCache": true
+        "netBoxHostFromCache": true,
+        "deleted": true
       },
       "awxJobId": 7445,
       "jobUrl": "https://awx-lab-01.cslab.esss.lu.se/#/jobs/playbook/7445",
@@ -540,11 +553,12 @@
       "gitShortReference": "5d102879",
       "host": {
         "hostId": "MTUxX3RydWU=",
-        "externalIdValid": true,
+        "externalIdValid": false,
         "hostName": "ccce-test-ioc-01",
         "network": "CSLab-GeneralLab",
         "fqdn": "ccce-test-ioc-01.cslab.esss.lu.se",
-        "netBoxHostFromCache": true
+        "netBoxHostFromCache": true,
+        "deleted": true
       },
       "awxJobId": 7441,
       "jobUrl": "https://awx-lab-01.cslab.esss.lu.se/#/jobs/playbook/7441",
@@ -592,11 +606,12 @@
       "gitShortReference": "5d102879",
       "host": {
         "hostId": "MTUxX3RydWU=",
-        "externalIdValid": true,
+        "externalIdValid": false,
         "hostName": "ccce-test-ioc-01",
         "network": "CSLab-GeneralLab",
         "fqdn": "ccce-test-ioc-01.cslab.esss.lu.se",
-        "netBoxHostFromCache": true
+        "netBoxHostFromCache": true,
+        "deleted": true
       },
       "awxJobId": 7437,
       "jobUrl": "https://awx-lab-01.cslab.esss.lu.se/#/jobs/playbook/7437",
@@ -648,7 +663,8 @@
         "hostName": "ccce-test-ioc-02",
         "network": "CSLab-GeneralLab",
         "fqdn": "ccce-test-ioc-02.cslab.esss.lu.se",
-        "netBoxHostFromCache": true
+        "netBoxHostFromCache": true,
+        "deleted": false
       },
       "awxJobId": 7433,
       "jobUrl": "https://awx-lab-01.cslab.esss.lu.se/#/jobs/playbook/7433",
@@ -700,7 +716,8 @@
         "hostName": "ccce-test-ioc-02",
         "network": "CSLab-GeneralLab",
         "fqdn": "ccce-test-ioc-02.cslab.esss.lu.se",
-        "netBoxHostFromCache": true
+        "netBoxHostFromCache": true,
+        "deleted": false
       },
       "awxJobId": 7429,
       "jobUrl": "https://awx-lab-01.cslab.esss.lu.se/#/jobs/playbook/7429",
@@ -752,7 +769,8 @@
         "hostName": "ccce-test-ioc-02",
         "network": "CSLab-GeneralLab",
         "fqdn": "ccce-test-ioc-02.cslab.esss.lu.se",
-        "netBoxHostFromCache": true
+        "netBoxHostFromCache": true,
+        "deleted": false
       },
       "awxJobId": 7425,
       "jobUrl": "https://awx-lab-01.cslab.esss.lu.se/#/jobs/playbook/7425",
@@ -794,7 +812,8 @@
         "hostName": "ccce-test-ioc-02",
         "network": "CSLab-GeneralLab",
         "fqdn": "ccce-test-ioc-02.cslab.esss.lu.se",
-        "netBoxHostFromCache": true
+        "netBoxHostFromCache": true,
+        "deleted": false
       },
       "awxJobId": 7421,
       "jobUrl": "https://awx-lab-01.cslab.esss.lu.se/#/jobs/playbook/7421",
@@ -836,11 +855,12 @@
       "gitShortReference": "5d102879",
       "host": {
         "hostId": "MTUxX3RydWU=",
-        "externalIdValid": true,
+        "externalIdValid": false,
         "hostName": "ccce-test-ioc-01",
         "network": "CSLab-GeneralLab",
         "fqdn": "ccce-test-ioc-01.cslab.esss.lu.se",
-        "netBoxHostFromCache": true
+        "netBoxHostFromCache": true,
+        "deleted": true
       },
       "awxJobId": 7417,
       "jobUrl": "https://awx-lab-01.cslab.esss.lu.se/#/jobs/playbook/7417",
@@ -872,11 +892,12 @@
       "gitShortReference": "5d102879",
       "host": {
         "hostId": "MTUxX3RydWU=",
-        "externalIdValid": true,
+        "externalIdValid": false,
         "hostName": "ccce-test-ioc-01",
         "network": "CSLab-GeneralLab",
         "fqdn": "ccce-test-ioc-01.cslab.esss.lu.se",
-        "netBoxHostFromCache": true
+        "netBoxHostFromCache": true,
+        "deleted": true
       },
       "awxJobId": 7409,
       "jobUrl": "https://awx-lab-01.cslab.esss.lu.se/#/jobs/playbook/7409",
@@ -922,7 +943,8 @@
         "hostName": "ccce-test-ioc-02",
         "network": "CSLab-GeneralLab",
         "fqdn": "ccce-test-ioc-02.cslab.esss.lu.se",
-        "netBoxHostFromCache": true
+        "netBoxHostFromCache": true,
+        "deleted": false
       },
       "awxJobId": 7405,
       "jobUrl": "https://awx-lab-01.cslab.esss.lu.se/#/jobs/playbook/7405",
@@ -958,7 +980,8 @@
         "hostName": "ccce-test-ioc-02",
         "network": "CSLab-GeneralLab",
         "fqdn": "ccce-test-ioc-02.cslab.esss.lu.se",
-        "netBoxHostFromCache": true
+        "netBoxHostFromCache": true,
+        "deleted": false
       },
       "awxJobId": 7390,
       "jobUrl": "https://awx-lab-01.cslab.esss.lu.se/#/jobs/command/7390",
@@ -993,7 +1016,8 @@
         "hostName": "ccce-test-ioc-02",
         "network": "CSLab-GeneralLab",
         "fqdn": "ccce-test-ioc-02.cslab.esss.lu.se",
-        "netBoxHostFromCache": true
+        "netBoxHostFromCache": true,
+        "deleted": false
       },
       "awxJobId": 7381,
       "jobUrl": "https://awx-lab-01.cslab.esss.lu.se/#/jobs/playbook/7381",
diff --git a/src/mocks/mockAPI.ts b/src/mocks/mockAPI.ts
index 9a003197..789fee24 100644
--- a/src/mocks/mockAPI.ts
+++ b/src/mocks/mockAPI.ts
@@ -260,6 +260,14 @@ function findHostAlerts(req: any) {
   return { body, status };
 }
 
+function checkHostExists(req: any) {
+  const params = getParameters(req, "/hosts/:hostId/exists");
+  const data = jobsData;
+  const body = data.jobs.find((job: any) => job.host.hostId === params?.hostId);
+  const status = body?.host?.deleted ? 404 : 200;
+  return { status };
+}
+
 function fetchSysLogLines() {
   return { hostSyslogsData };
 }
@@ -329,6 +337,7 @@ const mockAPI = {
     findNetBoxHostByFqdn,
     listHosts,
     findHostStatus,
+    checkHostExists,
     findHostAlerts,
     fetchSysLogLines
   },
@@ -486,6 +495,11 @@ export const apiHandlers = [
     qRegExp(".*/hosts/.*/info_by_fqdn"),
     mockAPI.hosts.findNetBoxHostByFqdn
   ),
+  makeHandler(
+    "GET",
+    qRegExp(".*/hosts/.*/exists"),
+    mockAPI.hosts.checkHostExists
+  ),
   makeHandler(
     "GET",
     qRegExp(".*/hosts/.*/log"),
-- 
GitLab


From c359bd31706649e144aa2ecbb30e3c50f85e41d8 Mon Sep 17 00:00:00 2001
From: Johanna Szepanski <johanna.szepanski@softhouse.se>
Date: Mon, 20 Jan 2025 15:46:02 +0100
Subject: [PATCH 6/7] changed job table header name from Id to ID

---
 src/components/Job/JobTable/JobTable.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/components/Job/JobTable/JobTable.tsx b/src/components/Job/JobTable/JobTable.tsx
index 9c7f3845..29c72707 100644
--- a/src/components/Job/JobTable/JobTable.tsx
+++ b/src/components/Job/JobTable/JobTable.tsx
@@ -15,7 +15,7 @@ const defaultColumns: GridColDef[] = [
   },
   {
     field: "jobId",
-    headerName: "Id",
+    headerName: "ID",
     flex: 0.5
   },
   {
-- 
GitLab


From 0f123608fb537c6634e9c3f7e7a0cbc071ae7c3d Mon Sep 17 00:00:00 2001
From: Johanna Szepanski <johanna.szepanski@softhouse.se>
Date: Tue, 21 Jan 2025 10:10:56 +0100
Subject: [PATCH 7/7] display host and netwrok when checkHostExists has
 resolved

---
 .../Job/JobTable/JobDetailsColumn.tsx         | 40 +++++++++----------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/src/components/Job/JobTable/JobDetailsColumn.tsx b/src/components/Job/JobTable/JobDetailsColumn.tsx
index 84d75a57..24155b7c 100644
--- a/src/components/Job/JobTable/JobDetailsColumn.tsx
+++ b/src/components/Job/JobTable/JobDetailsColumn.tsx
@@ -1,5 +1,5 @@
 import { useMemo, useEffect } from "react";
-import { Stack, Typography, Box } from "@mui/material";
+import { Box, Stack, Typography } from "@mui/material";
 import { InternalLink } from "@ess-ics/ce-ui-common";
 import { useLazyCheckHostExistsQuery, Job } from "../../../store/deployApi";
 import {
@@ -16,7 +16,7 @@ export const JobDetailsColumn = ({ job }: { job: Job }) => {
   const isBatchOperation = isBatchJob(job.action);
   const [
     callCheckHostExists,
-    { isLoading: checkHostExistsLoading, isSuccess }
+    { isLoading: checkHostExistsLoading, isSuccess, isError }
   ] = useLazyCheckHostExistsQuery();
 
   const noOfIOCs = useMemo(() => {
@@ -63,24 +63,24 @@ export const JobDetailsColumn = ({ job }: { job: Job }) => {
                 />
               )}
           </Stack>
-          <Stack
-            flexDirection="row"
-            gap={1}
-            alignItems="baseline"
-            flexWrap="wrap"
-          >
-            <Box sx={{ minWidth: "112px" }}>
-              <JobHost
-                url={
-                  !checkHostExistsLoading && isSuccess
-                    ? job?.host?.hostId
-                    : undefined
-                }
-                label={job.host?.hostName}
-              />
-            </Box>
-            <Typography variant="body2">{job?.host?.network}</Typography>
-          </Stack>
+          <Box sx={{ height: "24px" }}>
+            {!checkHostExistsLoading && (isSuccess || isError) && (
+              <Stack
+                flexDirection="row"
+                gap={1}
+                alignItems="baseline"
+                flexWrap="wrap"
+              >
+                <span>
+                  <JobHost
+                    url={isSuccess ? job?.host?.hostId : undefined}
+                    label={job.host?.hostName}
+                  />
+                </span>
+                <Typography variant="body2">{job?.host?.network}</Typography>
+              </Stack>
+            )}
+          </Box>
         </Stack>
       ) : (
         <Stack>
-- 
GitLab