diff --git a/package-lock.json b/package-lock.json
index 959f3babc75bb54466f1eb6517621385bf4520c9..d9b9a0dee0100b4245ebbb42acb60583259772df 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,7 +11,7 @@
         "@ahooksjs/use-url-state": "^3.5.0",
         "@emotion/react": "^11.11.1",
         "@emotion/styled": "^11.11.0",
-        "@ess-ics/ce-ui-common": "^0.4.2",
+        "@ess-ics/ce-ui-common": "^0.5.0",
         "@fontsource/roboto": "^4.1.0",
         "@mui/icons-material": "^5.14.1",
         "@mui/material": "^5.14.1",
@@ -2655,9 +2655,9 @@
       }
     },
     "node_modules/@ess-ics/ce-ui-common": {
-      "version": "0.4.2",
-      "resolved": "https://artifactory.esss.lu.se/artifactory/api/npm/ics-npm/@ess-ics/ce-ui-common/-/ce-ui-common-0.4.2.tgz",
-      "integrity": "sha1-bHkj1S9gtfMc3yF9gn1tSzwPJ6E=",
+      "version": "0.5.0",
+      "resolved": "https://artifactory.esss.lu.se/artifactory/api/npm/ics-npm/@ess-ics/ce-ui-common/-/ce-ui-common-0.5.0.tgz",
+      "integrity": "sha1-inPHY3jh1frYoaBCh2qTJAaoZYQ=",
       "dependencies": {
         "@fontsource/titillium-web": "^4.5.9",
         "@mui/x-data-grid-pro": "^6.5.0",
@@ -41722,9 +41722,9 @@
       "dev": true
     },
     "@ess-ics/ce-ui-common": {
-      "version": "0.4.2",
-      "resolved": "https://artifactory.esss.lu.se/artifactory/api/npm/ics-npm/@ess-ics/ce-ui-common/-/ce-ui-common-0.4.2.tgz",
-      "integrity": "sha1-bHkj1S9gtfMc3yF9gn1tSzwPJ6E=",
+      "version": "0.5.0",
+      "resolved": "https://artifactory.esss.lu.se/artifactory/api/npm/ics-npm/@ess-ics/ce-ui-common/-/ce-ui-common-0.5.0.tgz",
+      "integrity": "sha1-inPHY3jh1frYoaBCh2qTJAaoZYQ=",
       "requires": {
         "@fontsource/titillium-web": "^4.5.9",
         "@mui/x-data-grid-pro": "^6.5.0",
diff --git a/package.json b/package.json
index 3eedaea6e324fcebac6d891b7c0f5bec54d30d81..ad53ac618cb135c5f76ec7f2f21c326e53ad8403 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,7 @@
     "@ahooksjs/use-url-state": "^3.5.0",
     "@emotion/react": "^11.11.1",
     "@emotion/styled": "^11.11.0",
-    "@ess-ics/ce-ui-common": "^0.4.2",
+    "@ess-ics/ce-ui-common": "^0.5.0",
     "@fontsource/roboto": "^4.1.0",
     "@mui/icons-material": "^5.14.1",
     "@mui/material": "^5.14.1",
diff --git a/src/components/IOC/ChangeHostAdmin/ChangeHostAdmin.js b/src/components/IOC/ChangeHostAdmin/ChangeHostAdmin.js
index 2d3cdc3ec986fd4b5e910c0ce99839a10a5179d4..2ee8c6653d9479f8433257ee51db268f80758937 100644
--- a/src/components/IOC/ChangeHostAdmin/ChangeHostAdmin.js
+++ b/src/components/IOC/ChangeHostAdmin/ChangeHostAdmin.js
@@ -62,7 +62,7 @@ export default function ChangeHostAdmin({
 
   // for the dialog
   const [error, setError] = useState();
-  const [open, setOpen] = useState();
+  const [open, setOpen] = useState(false);
 
   const {
     value: updatedIoc,
diff --git a/src/components/IOC/IOCDelete/IOCDelete.js b/src/components/IOC/IOCDelete/IOCDelete.js
index d5b4f3c6bc0a42a4202c248565a43a19ff30a047..47908811574b596fa25a68530228e73a8a7050df 100644
--- a/src/components/IOC/IOCDelete/IOCDelete.js
+++ b/src/components/IOC/IOCDelete/IOCDelete.js
@@ -137,7 +137,7 @@ export default function IOCDelete({ ioc, buttonDisabled }) {
                     disabled={
                       buttonDisabled ||
                       ioc.operationInProgress ||
-                      ioc.activeDeployment
+                      Boolean(ioc.activeDeployment)
                     }
                     color="error"
                     variant="contained"
diff --git a/src/components/IOC/IOCDeployDialog/IOCDeployDialog.js b/src/components/IOC/IOCDeployDialog/IOCDeployDialog.js
index 7cc9380459b19854a44e0f801e0f00d6f78fa491..681f0e164788e4bd9d8bfbbbb63054ec58f1e8d1 100644
--- a/src/components/IOC/IOCDeployDialog/IOCDeployDialog.js
+++ b/src/components/IOC/IOCDeployDialog/IOCDeployDialog.js
@@ -44,7 +44,8 @@ export function IOCDeployDialog({
     error: tagOrCommitIdError
   } = useAPIMethod({
     fcn: client.apis.Git.listTagsAndCommitIds,
-    call: false
+    call: false,
+    init: []
   });
   const getTagOrCommitId = useCallback(
     (gitProjectId, reference, includeAllReference, searchMethod) => {
diff --git a/src/components/IOC/IOCDetailAdmin/IOCDetailAdmin.js b/src/components/IOC/IOCDetailAdmin/IOCDetailAdmin.js
index 3efa1bf0185d96febfc21b71b5ba5287166eb9ad..515dbec7772f1bfc91ed7f4482bc16400efac83f 100644
--- a/src/components/IOC/IOCDetailAdmin/IOCDetailAdmin.js
+++ b/src/components/IOC/IOCDetailAdmin/IOCDetailAdmin.js
@@ -125,7 +125,7 @@ export default function IOCDetailAdmin({
     }
   }, [uioc, getIOC, resetTab]);
 
-  const iocIsDeployed = ioc.activeDeployment;
+  const iocIsDeployed = Boolean(ioc.activeDeployment);
 
   let nameDisabledTitle = "";
   if (iocIsDeployed) {
diff --git a/src/components/IOC/IOCManage/IOCManage.js b/src/components/IOC/IOCManage/IOCManage.js
index ed29204df52baa1deb51a162d1eb27452c8ab828..f9387bc30638ab3939cff7afd909c8dcb6ac87a5 100644
--- a/src/components/IOC/IOCManage/IOCManage.js
+++ b/src/components/IOC/IOCManage/IOCManage.js
@@ -244,7 +244,7 @@ export function IOCManage({
             submitCallback={closeDeployModal}
             init={formInit}
             iocId={ioc.id}
-            hasActiveDeployment={ioc.activeDeployment}
+            hasActiveDeployment={Boolean(ioc.activeDeployment)}
           />
           <UndeployIOC
             open={undeployDialogOpen}
diff --git a/src/components/common/Loki/LokiPanel.js b/src/components/common/Loki/LokiPanel.js
index 95dde124c65e29fe3266e8f2aa063f52979520f7..9661b00eee1398d19e4278b09cd9b725d24d2cfd 100644
--- a/src/components/common/Loki/LokiPanel.js
+++ b/src/components/common/Loki/LokiPanel.js
@@ -84,6 +84,77 @@ export function LokiPanel({ host, iocName, isSyslog, isDeployed }) {
   const [timeRangeText, setTimeRangeText] = React.useState("12 hours");
   const [periodChange, setPeriodChange] = useState(false);
   const [alertIds, setAlertIds] = useState([]);
+  const [html, setHtml] = useState("");
+
+  const preprocessLog = useCallback(
+    (
+      logData,
+      isDeployed,
+      showWarning,
+      timeRangeText,
+      alertIds,
+      setAlertIds
+    ) => {
+      if (logData?.warning && alertIds?.length === 0) {
+        const warningId = showWarning(logData.warning, "warning");
+        setAlertIds((alertIds) => [...alertIds, warningId]);
+      }
+
+      if (logData && logData.lines?.length > 0) {
+        const logHtml = logData.lines.map((line) => formatLogLine(line));
+        return `<html>
+                    <head><meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+                      <style type="text/css">.logdate { color: #5cb85c; } body.pre{font-family: Monaco, Menlo, Consolas, "Courier New", monospace;}
+                      </style>
+                    </head>
+                    <body>
+                      <pre>${logHtml.join("")}</pre>
+                    </body>
+                  </html>`;
+      } else {
+        if (!(isDeployed === true)) {
+          return "<html><body> NOT DEPLOYED YET! </body></html>";
+        }
+      }
+
+      return `<html><body> - No messages found for ${timeRangeText} period - </body></html>`;
+    },
+    []
+  );
+
+  const logsToPreprocess = useCallback(
+    (
+      isSysLog,
+      logData,
+      procServLog,
+      isDeployed,
+      showWarning,
+      timeRangeText,
+      alertIds,
+      setAlertIds
+    ) => {
+      if (isSysLog === true) {
+        return preprocessLog(
+          logData,
+          true,
+          showWarning,
+          timeRangeText,
+          alertIds,
+          setAlertIds
+        );
+      }
+
+      return preprocessLog(
+        procServLog,
+        isDeployed,
+        showWarning,
+        timeRangeText,
+        alertIds,
+        setAlertIds
+      );
+    },
+    [preprocessLog]
+  );
 
   const params = useMemo(
     () => ({
@@ -171,6 +242,31 @@ export function LokiPanel({ host, iocName, isSyslog, isDeployed }) {
   //     return <div style={{ width: "100%" }}><LinearProgress color="primary" /></div>;
   // }
 
+  useEffect(() => {
+    setHtml(
+      logsToPreprocess(
+        isSyslog,
+        sysLogData,
+        procServLog,
+        isDeployed,
+        showWarning,
+        timeRangeText,
+        alertIds,
+        setAlertIds
+      )
+    );
+  }, [
+    setHtml,
+    alertIds,
+    isDeployed,
+    isSyslog,
+    logsToPreprocess,
+    procServLog,
+    showWarning,
+    sysLogData,
+    timeRangeText
+  ]);
+
   const dataReady = () => {
     return sysLogData || procServLog;
   };
@@ -208,16 +304,7 @@ export function LokiPanel({ host, iocName, isSyslog, isDeployed }) {
               md={12}
             >
               <Console
-                html={logsToPreprocess(
-                  isSyslog,
-                  sysLogData,
-                  procServLog,
-                  isDeployed,
-                  showWarning,
-                  timeRangeText,
-                  alertIds,
-                  setAlertIds
-                )}
+                html={html}
                 dataReady={dataReady}
                 extraClass={isDeployed ? classes.deployed : classes.undeployed}
                 title={isSyslog ? "Host log stream" : "IOC log stream"}
@@ -236,37 +323,6 @@ export function LokiPanel({ host, iocName, isSyslog, isDeployed }) {
   );
 }
 
-function logsToPreprocess(
-  isSysLog,
-  logData,
-  procServLog,
-  isDeployed,
-  showWarning,
-  timeRangeText,
-  alertIds,
-  setAlertIds
-) {
-  if (isSysLog === true) {
-    return preprocessLog(
-      logData,
-      true,
-      showWarning,
-      timeRangeText,
-      alertIds,
-      setAlertIds
-    );
-  }
-
-  return preprocessLog(
-    procServLog,
-    isDeployed,
-    showWarning,
-    timeRangeText,
-    alertIds,
-    setAlertIds
-  );
-}
-
 function formatLogLine(logLine) {
   var Convert = require("ansi-to-html");
   var convert = new Convert();
@@ -279,36 +335,3 @@ function formatLogLine(logLine) {
     "<br/></span>"
   );
 }
-
-function preprocessLog(
-  logData,
-  isDeployed,
-  showWarning,
-  timeRangeText,
-  alertIds,
-  setAlertIds
-) {
-  if (logData.warning && alertIds.length === 0) {
-    const warningId = showWarning(logData.warning, "warning");
-    setAlertIds((alertIds) => [...alertIds, warningId]);
-  }
-
-  if (logData && logData.lines?.length > 0) {
-    var logHtml = logData.lines.map((line) => formatLogLine(line));
-    return `<html>
-                  <head><meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-                    <style type="text/css">.logdate { color: #5cb85c; } body.pre{font-family: Monaco, Menlo, Consolas, "Courier New", monospace;}
-                    </style>
-                  </head>
-                  <body>
-                    <pre>${logHtml.join("")}</pre>
-                  </body>
-                </html>`;
-  } else {
-    if (!(isDeployed === true)) {
-      return "<html><body> NOT DEPLOYED YET! </body></html>";
-    }
-  }
-
-  return `<html><body> - No messages found for ${timeRangeText} period - </body></html>`;
-}
diff --git a/src/views/IOC/IOCDetailsView.js b/src/views/IOC/IOCDetailsView.js
index f8be1d64fae8764f7018fce954460bb40d59a706..32839522266f8db02a5358cc58e4e8e4dc9a0e49 100644
--- a/src/views/IOC/IOCDetailsView.js
+++ b/src/views/IOC/IOCDetailsView.js
@@ -1,4 +1,4 @@
-import { Grid, Tab, Tabs, IconButton } from "@mui/material";
+import { Grid, IconButton, Stack } from "@mui/material";
 import ArrowBackIcon from "@mui/icons-material/ArrowBack";
 import React, {
   useCallback,
@@ -11,12 +11,16 @@ import { IOCLiveStatus } from "../../components/IOC/IOCLiveStatus";
 import { IOCManage } from "../../components/IOC/IOCManage";
 import { useNavigate } from "react-router-dom";
 import IOCAdmin from "../../components/IOC/IOCAdmin";
-import AccessControl from "../../components/auth/AccessControl";
 import {
   applicationTitle,
   initRequestParams
 } from "../../components/common/Helper";
-import { GlobalAppBarContext, useAPIMethod } from "@ess-ics/ce-ui-common";
+import {
+  GlobalAppBarContext,
+  useAPIMethod,
+  useIsCurrentUserPermitted,
+  TabPanel
+} from "@ess-ics/ce-ui-common";
 import { useSafePolling } from "../../hooks/Polling";
 import useUrlState from "@ahooksjs/use-url-state";
 import {
@@ -123,10 +127,13 @@ export function IOCDetailsView({ ioc, getIOC, abortGetIOC, loading }) {
   }, [jobPagination, setJobUrlPagination]);
 
   // Invoked by Table on change to pagination
-  const onPage = (params) => {
-    setJobPagination(params);
-    abortGetOperations();
-  };
+  const onPage = useCallback(
+    (params) => {
+      setJobPagination(params);
+      abortGetOperations();
+    },
+    [abortGetOperations, setJobPagination]
+  );
 
   useSafePolling(getIOC, loading, IOC_POLL_INTERVAL, true, abortGetIOC);
   useSafePolling(
@@ -141,8 +148,8 @@ export function IOCDetailsView({ ioc, getIOC, abortGetIOC, loading }) {
     setButtonDisabled(Boolean(ioc?.operationInProgress));
   }, [ioc?.operationInProgress]);
 
-  const handleTabChange = (event, tab) => {
-    setUrlState({ tab: serialize(tab) });
+  const onTabChange = (index, label) => {
+    setUrlState({ tab: serialize(label) });
   };
 
   // Submit new search whenever pagination or ioc changes
@@ -176,118 +183,90 @@ export function IOCDetailsView({ ioc, getIOC, abortGetIOC, loading }) {
     [getIOC]
   );
 
-  const statusTab = (
-    <Tab
-      key="Status"
-      label="Status"
-      value="Status"
-    />
-  );
-  const manageDeploymentTab = (
-    <Tab
-      key="Management"
-      label="Management"
-      value="Management"
-    />
-  );
-  const iocAdminTab = (
-    <Tab
-      key="Admin"
-      label="Admin"
-      value="Admin"
-    />
-  );
+  const tabs = [
+    {
+      label: "Status",
+      content: <IOCLiveStatus ioc={ioc} />
+    }
+  ];
 
-  const CustomTabs = ({ children }) => {
-    return (
-      <Tabs
-        value={deserialize(urlState.tab)}
-        onChange={handleTabChange}
-      >
-        {children}
-      </Tabs>
-    );
-  };
+  const isPermittedManagement = useIsCurrentUserPermitted({
+    allowedRoles: ["DeploymentToolAdmin", "DeploymentToolIntegrator"]
+  });
+
+  const isPermittedAdmin = useIsCurrentUserPermitted({
+    allowedRoles: ["DeploymentToolAdmin"]
+  });
+
+  if (isPermittedManagement) {
+    tabs.push({
+      label: "Management",
+      content: (
+        <IOCManage
+          ioc={ioc}
+          getIOC={getIOC}
+          buttonDisabled={buttonDisabled}
+          currentCommand={
+            ongoingCommand?.operations?.length > 0
+              ? ongoingCommand.operations[0]
+              : null
+          }
+          operations={operations?.operations}
+          operationsLoading={operationsLoading || !operationsDataReady}
+          getOperations={getOperations}
+          setButtonDisabled={setButtonDisabledAndUpdate}
+          pagination={jobPagination}
+          onPage={onPage}
+        />
+      )
+    });
+  }
+  if (isPermittedAdmin) {
+    tabs.push({
+      label: "Admin",
+      content: (
+        <IOCAdmin
+          ioc={ioc}
+          getIOC={getIOC}
+          resetTab={resetTab}
+          buttonDisabled={buttonDisabled}
+        />
+      )
+    });
+  }
+  const initialIndex = tabs.map((it) => it.label).indexOf(urlState?.tab);
 
   return (
     <Grid
       container
       spacing={1}
     >
-      <Grid
-        item
-        xs={1}
-      >
-        <IconButton
-          color="inherit"
-          onClick={handleClick}
-          size="large"
-        >
-          <ArrowBackIcon />
-        </IconButton>
-      </Grid>
-      <Grid
-        item
-        xs={11}
-      >
-        <Grid
-          container
-          justifyContent="center"
-        >
-          {ioc && (
-            <CustomTabs>
-              {statusTab}
-              <AccessControl
-                allowedRoles={[
-                  "DeploymentToolAdmin",
-                  "DeploymentToolIntegrator"
-                ]}
-                renderNoAccess={() => <></>}
-              >
-                <CustomTabs>{manageDeploymentTab}</CustomTabs>
-              </AccessControl>
-              <AccessControl
-                allowedRoles={["DeploymentToolAdmin"]}
-                renderNoAccess={() => <></>}
-              >
-                <CustomTabs>{iocAdminTab}</CustomTabs>
-              </AccessControl>
-            </CustomTabs>
-          )}
-        </Grid>
-      </Grid>
       <Grid
         item
         xs={12}
         style={{ paddingBottom: 0 }}
       >
-        {deserialize(urlState.tab) === "Status" && <IOCLiveStatus ioc={ioc} />}
-        {deserialize(urlState.tab) === "Management" && (
-          <IOCManage
-            ioc={ioc}
-            getIOC={getIOC}
-            buttonDisabled={buttonDisabled}
-            currentCommand={
-              ongoingCommand?.operations?.length > 0
-                ? ongoingCommand.operations[0]
-                : null
-            }
-            operations={operations?.operations}
-            operationsLoading={operationsLoading || !operationsDataReady}
-            getOperations={getOperations}
-            setButtonDisabled={setButtonDisabledAndUpdate}
-            pagination={jobPagination}
-            onPage={onPage}
-          />
-        )}
-        {deserialize(urlState.tab) === "Admin" && (
-          <IOCAdmin
-            ioc={ioc}
-            getIOC={getIOC}
-            resetTab={resetTab}
-            buttonDisabled={buttonDisabled}
-          />
-        )}
+        <TabPanel
+          tabs={tabs}
+          initialIndex={initialIndex}
+          onTabChange={onTabChange}
+          TabsProps={{ centered: true, sx: { flex: 1 } }}
+          renderTabs={(tabs) => (
+            <Stack
+              flexDirection="row"
+              justifyContent="space-between"
+            >
+              <IconButton
+                color="inherit"
+                onClick={handleClick}
+                size="large"
+              >
+                <ArrowBackIcon />
+              </IconButton>
+              {tabs}
+            </Stack>
+          )}
+        />
       </Grid>
     </Grid>
   );