RANGER-4641: Handling empty values while displaying ActivationTime & implementing Column Hide/Show functionality in Audit Plugin Status Module

Signed-off-by: Madhan Neethiraj <madhan@apache.org>
diff --git a/security-admin/src/main/webapp/react-webapp/src/components/CommonComponents.jsx b/security-admin/src/main/webapp/react-webapp/src/components/CommonComponents.jsx
index 1fca378..79fcbd1 100644
--- a/security-admin/src/main/webapp/react-webapp/src/components/CommonComponents.jsx
+++ b/security-admin/src/main/webapp/react-webapp/src/components/CommonComponents.jsx
@@ -441,7 +441,11 @@
 export const CustomTooltip = ({ placement, content, icon }) => (
   <OverlayTrigger
     placement={placement}
-    overlay={<Popover id={`tooltip-${placement}`}>{content}</Popover>}
+    overlay={
+      <Popover id={`tooltip-${placement}`}>
+        <span className=" d-block px-2 py-1">{content}</span>
+      </Popover>
+    }
   >
     <i className={icon} data-id="infoTextFiled" data-cy="infoTextFiled"></i>
   </OverlayTrigger>
diff --git a/security-admin/src/main/webapp/react-webapp/src/components/XATableLayout.jsx b/security-admin/src/main/webapp/react-webapp/src/components/XATableLayout.jsx
index 71a33f1..d75315e 100644
--- a/security-admin/src/main/webapp/react-webapp/src/components/XATableLayout.jsx
+++ b/security-admin/src/main/webapp/react-webapp/src/components/XATableLayout.jsx
@@ -28,7 +28,7 @@
 } from "react-table";
 import { Table, ButtonGroup } from "react-bootstrap";
 import DropdownButton from "react-bootstrap/DropdownButton";
-import { isEmpty } from "lodash";
+import { groupBy, isEmpty, uniq, uniqBy } from "lodash";
 
 const IndeterminateCheckbox = forwardRef(
   ({ indeterminate, chkType, ...rest }, ref) => {
@@ -195,6 +195,22 @@
       </span>
     );
   };
+  /* For Column Visibility */
+  const groupedColumnsData = groupBy(allColumns, "parent[id]");
+  delete groupedColumnsData.undefined;
+  const allColumnsData = allColumns.map((column) => {
+    const columnName = column?.parent
+      ? `Group(${column?.parent.id})`
+      : `Non-Group(${column?.id})`;
+    return {
+      columnName,
+      columnData: groupedColumnsData[column.parent?.id] || column
+    };
+  });
+
+  let filterAllColumns = uniqBy(allColumnsData, function (column) {
+    return column.columnName;
+  });
 
   let columnShowHide = [];
   return (
@@ -203,7 +219,7 @@
       {columnHide && (
         <div className="text-right mb-2 mt-n5">
           <DropdownButton
-            className="p-0"
+            className="p-0 column-dropdown"
             menuAlign="right"
             as={ButtonGroup}
             size="sm"
@@ -211,35 +227,70 @@
             variant="info"
             title="Columns"
           >
-            <ul className="list-group">
-              {allColumns.map((column, index) => {
-                columnShowHide.push({
-                  name: column.id,
-                  renderable: column.isVisible
-                });
+            <div className="column-dropdown-maxheight">
+              <ul className="list-group fnt-14">
+                {filterAllColumns.map((column, index) => {
+                  columnShowHide.push({
+                    name: column.columnData.id,
+                    renderable: column.columnData.isVisible
+                  });
 
-                localStorage.setItem(
-                  "showHideTableCol",
-                  JSON.stringify({ bigData: columnShowHide })
-                );
-                return (
-                  <li
-                    className="column-list text-truncate"
-                    key={`col-${index}`}
-                  >
-                    <label>
-                      <input
-                        className="mr-1"
-                        type="checkbox"
-                        {...column.getToggleHiddenProps()}
-                      />
-
-                      {column.Header}
-                    </label>
-                  </li>
-                );
-              })}
-            </ul>
+                  localStorage.setItem(
+                    "showHideTableCol",
+                    JSON.stringify({ bigData: columnShowHide })
+                  );
+                  return column.columnName ==
+                    `Non-Group(${column.columnData.id})` ? (
+                    <li
+                      className="column-list text-truncate"
+                      key={`col-${index}`}
+                    >
+                      <label
+                        title={column.columnData.Header}
+                        className="d-flex align-items-center"
+                      >
+                        <input
+                          className="mr-1"
+                          type="checkbox"
+                          {...column.columnData.getToggleHiddenProps()}
+                        />
+                        {column.columnData.Header}
+                      </label>
+                    </li>
+                  ) : (
+                    <li
+                      className="column-list text-truncate"
+                      key={`col-${index}`}
+                    >
+                      {column.columnName !== undefined && (
+                        <div className="font-weight-bold text-secondary mb-2 fnt-14">
+                          {column.columnName !== undefined &&
+                            column?.columnData[0]?.parent?.id}
+                        </div>
+                      )}
+                      {column.columnData.map((columns) => (
+                        <ul key={columns.id} className="p-0">
+                          <li className=" list-unstyled">
+                            {" "}
+                            <label
+                              title={columns.Header}
+                              className="d-flex align-items-center"
+                            >
+                              <input
+                                className="mr-1"
+                                type="checkbox"
+                                {...columns.getToggleHiddenProps()}
+                              />
+                              {columns.Header}
+                            </label>
+                          </li>
+                        </ul>
+                      ))}
+                    </li>
+                  );
+                })}
+              </ul>
+            </div>
           </DropdownButton>
         </div>
       )}
diff --git a/security-admin/src/main/webapp/react-webapp/src/styles/style.css b/security-admin/src/main/webapp/react-webapp/src/styles/style.css
index ed45e86..f5caff0 100755
--- a/security-admin/src/main/webapp/react-webapp/src/styles/style.css
+++ b/security-admin/src/main/webapp/react-webapp/src/styles/style.css
@@ -3032,3 +3032,13 @@
   max-height: 126px;
   overflow-y: scroll;
 }
+
+.column-dropdown .dropdown-toggle:focus {
+  color: #fff;
+  background-color: #117a8b;
+  border-color: none;
+}
+.column-dropdown-maxheight {
+  max-height: 400px;
+  overflow-y: auto;
+}
diff --git a/security-admin/src/main/webapp/react-webapp/src/utils/XAEnums.js b/security-admin/src/main/webapp/react-webapp/src/utils/XAEnums.js
index 842cb69..012463e 100755
--- a/security-admin/src/main/webapp/react-webapp/src/utils/XAEnums.js
+++ b/security-admin/src/main/webapp/react-webapp/src/utils/XAEnums.js
@@ -893,3 +893,26 @@
   groupSearchFirstEnabled: "Group search first enabled",
   groupHierarchyLevel: "Group hierarchy level"
 };
+
+export const pluginStatusColumnInfoMsg = {
+  Policy: {
+    title: "Policy (Time details)",
+    lastUpdated: "Last updated time of policy.",
+    downloadTime: "Time when policy actually downloaded(sync-up with Ranger).",
+    activeTime: "Time when policy actually in use for enforcement.",
+    downloadTimeDelayMsg:
+      "Policy is updated but not yet downloaded(sync-up with Ranger).",
+    activationTimeDelayMsg:
+      "Policy is updated but not yet used for any enforcement."
+  },
+  Tag: {
+    title: "Tag Policy (Time details)",
+    lastUpdated: "Last updated time of Tag-service.",
+    downloadTime: "Time when tag-based policies sync-up with Ranger.",
+    activeTime: "Time when tag-based policies in use for enforcement.",
+    downloadTimeDelayMsg:
+      "Policy is updated but not yet downloaded(sync-up with Ranger).",
+    activationTimeDelayMsg:
+      "Policy is updated but not yet used for any enforcement."
+  }
+};
diff --git a/security-admin/src/main/webapp/react-webapp/src/utils/XAMessages.js b/security-admin/src/main/webapp/react-webapp/src/utils/XAMessages.js
index d22ecfa..ee7b010 100644
--- a/security-admin/src/main/webapp/react-webapp/src/utils/XAMessages.js
+++ b/security-admin/src/main/webapp/react-webapp/src/utils/XAMessages.js
@@ -18,6 +18,7 @@
  */
 
 import React from "react";
+import { pluginStatusColumnInfoMsg } from "./XAEnums";
 
 export const RegexMessage = {
   MESSAGE: {
@@ -129,3 +130,24 @@
     </p>
   );
 };
+
+/* PluginStatus Column Info */
+
+export const pluginStatusColumnInfo = (colName) => {
+  return (
+    <ul className="list-inline">
+      <li className="list-inline-item">
+        <strong>Last Update: </strong>{" "}
+        {pluginStatusColumnInfoMsg[colName].lastUpdated}
+      </li>
+      <li className="list-inline-item">
+        <strong>Download: </strong>
+        {pluginStatusColumnInfoMsg[colName].downloadTime}
+      </li>
+      <li className="list-inline-item">
+        <strong>Active: </strong>{" "}
+        {pluginStatusColumnInfoMsg[colName].activeTime}
+      </li>
+    </ul>
+  );
+};
diff --git a/security-admin/src/main/webapp/react-webapp/src/utils/XAUtils.js b/security-admin/src/main/webapp/react-webapp/src/utils/XAUtils.js
index f834f97..d189e4a 100644
--- a/security-admin/src/main/webapp/react-webapp/src/utils/XAUtils.js
+++ b/security-admin/src/main/webapp/react-webapp/src/utils/XAUtils.js
@@ -198,7 +198,9 @@
     <span title={formatDateTime}>
       {formatDateTime}
       <div className="text-muted">
-        <small>{moment(formatDateTime).fromNow()}</small>
+        <small>
+          {moment(formatDateTime, "MM/DD/YYYY h:mm:ss A").fromNow()}
+        </small>
       </div>
     </span>
   ) : (
diff --git a/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/PluginStatusLogs.jsx b/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/PluginStatusLogs.jsx
index 07ac391..6380782 100644
--- a/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/PluginStatusLogs.jsx
+++ b/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/PluginStatusLogs.jsx
@@ -23,7 +23,6 @@
 import XATableLayout from "Components/XATableLayout";
 import { AuditFilterEntries } from "Components/CommonComponents";
 import moment from "moment-timezone";
-import dateFormat from "dateformat";
 import {
   setTimeStamp,
   fetchSearchFilterParams,
@@ -39,8 +38,18 @@
 } from "../../components/CommonComponents";
 import StructuredFilter from "../../components/structured-filter/react-typeahead/tokenizer";
 import { fetchApi } from "Utils/fetchAPI";
-import { isUndefined, map, sortBy, toUpper, filter } from "lodash";
+import {
+  isUndefined,
+  map,
+  sortBy,
+  toUpper,
+  filter,
+  isNull,
+  isEmpty
+} from "lodash";
 import { getServiceDef } from "../../utils/appState";
+import { pluginStatusColumnInfo } from "../../utils/XAMessages";
+import { pluginStatusColumnInfoMsg } from "../../utils/XAEnums";
 
 function Plugin_Status() {
   const context = useOutletContext();
@@ -120,49 +129,111 @@
     return diff < 0 ? true : false;
   };
 
+  const getLastUpdateTime = (lastUpdateTime) => {
+    if (isUndefined(lastUpdateTime) || isNull(lastUpdateTime)) {
+      return <center>--</center>;
+    }
+    return setTimeStamp(lastUpdateTime);
+  };
+
+  const getDownloadTime = (downloadTime, lastUpdateTime, columnsName) => {
+    if (isUndefined(downloadTime) || isNull(downloadTime)) {
+      return <center>--</center>;
+    }
+
+    if (!isUndefined(lastUpdateTime)) {
+      let downloadDate = new Date(parseInt(downloadTime));
+      let lastUpdateDate = new Date(parseInt(lastUpdateTime));
+      if (isDateDifferenceMoreThanHr(downloadDate, lastUpdateDate)) {
+        if (
+          moment(downloadDate).diff(moment(lastUpdateDate), "minutes") >= -2
+        ) {
+          return (
+            <span className="text-warning">
+              <CustomTooltip
+                placement="bottom"
+                content={
+                  pluginStatusColumnInfoMsg[columnsName].downloadTimeDelayMsg
+                }
+                icon="fa-fw fa fa-exclamation-circle active-policy-alert"
+              />
+              {setTimeStamp(downloadTime)}
+            </span>
+          );
+        } else {
+          return (
+            <span className="text-error">
+              <CustomTooltip
+                placement="bottom"
+                content={
+                  pluginStatusColumnInfoMsg[columnsName].downloadTimeDelayMsg
+                }
+                icon="fa-fw fa fa-exclamation-circle active-policy-alert"
+              />
+              {setTimeStamp(downloadTime)}{" "}
+            </span>
+          );
+        }
+      }
+    }
+    return setTimeStamp(downloadTime);
+  };
+
+  const getActivationTime = (activeTime, lastUdpateTime, columnsName) => {
+    if (isUndefined(activeTime) || isNull(activeTime) || activeTime == 0) {
+      return <center>--</center>;
+    }
+    if (!isUndefined(lastUdpateTime)) {
+      let activeDate = new Date(parseInt(activeTime));
+      let lastUpdateDate = new Date(parseInt(lastUdpateTime));
+      if (isDateDifferenceMoreThanHr(activeDate, lastUpdateDate)) {
+        if (moment(activeDate).diff(moment(lastUpdateDate), "minutes") >= -2) {
+          return (
+            <span className="text-warning">
+              <CustomTooltip
+                placement="bottom"
+                content={
+                  pluginStatusColumnInfoMsg[columnsName].activationTimeDelayMsg
+                }
+                icon="fa-fw fa fa-exclamation-circle active-policy-alert"
+              />
+              {setTimeStamp(activeTime)}
+            </span>
+          );
+        } else {
+          return (
+            <span className="text-error">
+              <CustomTooltip
+                placement="bottom"
+                content={
+                  pluginStatusColumnInfoMsg[columnsName].activationTimeDelayMsg
+                }
+                icon="fa-fw fa fa-exclamation-circle active-policy-alert"
+              />
+              {setTimeStamp(activeTime)}
+            </span>
+          );
+        }
+      }
+    }
+    return setTimeStamp(activeTime);
+  };
+
   const refreshTable = () => {
     setPluginStatusLogs([]);
     setLoader(true);
     setUpdateTable(moment.now());
   };
 
-  const contents = (val) => {
+  const infoIcon = (columnsName) => {
     return (
       <>
-        <ul className="list-inline">
-          <li className="list-inline-item">
-            <strong>Last Update: </strong> Last updated time of{" "}
-            {val == "Tag" ? "Tag-service" : "policy"}.
-          </li>
-          <li className="list-inline-item">
-            <strong>Download: </strong>
-            {val == "Tag"
-              ? "Time when tag-based policies sync-up with Ranger."
-              : "Time when policy actually downloaded(sync-up with Ranger)."}
-          </li>
-          <li className="list-inline-item">
-            <strong>Active: </strong> Time when{" "}
-            {val == "Tag" ? "tag-based" : "policy"} actually in use for
-            enforcement.
-          </li>
-        </ul>
-      </>
-    );
-  };
-
-  const infoIcon = (val) => {
-    return (
-      <>
-        <b>{val} ( Time )</b>
+        <b>{columnsName} ( Time )</b>
 
         <CustomPopover
           icon="fa-fw fa fa-info-circle info-icon"
-          title={
-            val == "Policy"
-              ? "Policy (Time details)"
-              : "Tag Policy (Time details)"
-          }
-          content={contents(val)}
+          title={pluginStatusColumnInfoMsg[columnsName].title}
+          content={pluginStatusColumnInfo(columnsName)}
           placement="left"
           trigger={["hover", "focus"]}
         />
@@ -217,18 +288,18 @@
         accessor: "clusterName",
         Cell: ({ row: { original } }) => {
           let clusterName = original?.info?.clusterName;
-          return isUndefined(clusterName) ? "--" : clusterName;
+          return !isEmpty(clusterName) ? clusterName : <center>--</center>;
         }
       },
       {
         Header: infoIcon("Policy"),
-        id: "policyinfo",
+        id: "Policy (Time)",
         columns: [
           {
             Header: "Last Update",
             accessor: "lastPolicyUpdateTime",
             Cell: ({ row: { original } }) => {
-              return setTimeStamp(original.info.lastPolicyUpdateTime);
+              return getLastUpdateTime(original.info.lastPolicyUpdateTime);
             },
             minWidth: 190
           },
@@ -236,54 +307,11 @@
             Header: "Download",
             accessor: "policyDownloadTime",
             Cell: ({ row: { original } }) => {
-              var downloadDate = new Date(
-                parseInt(original.info.policyDownloadTime)
+              return getDownloadTime(
+                original.info.policyDownloadTime,
+                original.info.lastPolicyUpdateTime,
+                "Policy"
               );
-
-              dateFormat(
-                parseInt(original.info.policyDownloadTime),
-                "mm/dd/yyyy hh:MM:ss TT"
-              );
-              if (!isUndefined(original.info.lastPolicyUpdateTime)) {
-                var lastUpdateDate = new Date(
-                  parseInt(original.info.lastPolicyUpdateTime)
-                );
-                if (isDateDifferenceMoreThanHr(downloadDate, lastUpdateDate)) {
-                  if (
-                    moment(downloadDate).diff(
-                      moment(lastUpdateDate),
-                      "minutes"
-                    ) >= -2
-                  ) {
-                    return (
-                      <span className="text-warning">
-                        <CustomTooltip
-                          placement="bottom"
-                          content={
-                            "Policy is updated but not yet downloaded(sync-upwith Ranger)"
-                          }
-                          icon="fa-fw fa fa-exclamation-circle active-policy-alert"
-                        />
-                        {setTimeStamp(original.info.policyDownloadTime)}
-                      </span>
-                    );
-                  } else {
-                    return (
-                      <span className="text-error">
-                        <CustomTooltip
-                          placement="bottom"
-                          content={
-                            "Policy is updated but not yet downloaded(sync-upwith Ranger)"
-                          }
-                          icon="fa-fw fa fa-exclamation-circle active-policy-alert"
-                        />
-                        {setTimeStamp(original.info.policyDownloadTime)}{" "}
-                      </span>
-                    );
-                  }
-                }
-              }
-              return setTimeStamp(original.info.policyDownloadTime);
             },
             minWidth: 190
           },
@@ -291,51 +319,11 @@
             Header: "Active",
             accessor: "policyActivationTime",
             Cell: ({ row: { original } }) => {
-              let activeDate = new Date(
-                parseInt(original.info.policyActivationTime)
+              return getActivationTime(
+                original.info.policyActivationTime,
+                original.info.lastPolicyUpdateTime,
+                "Policy"
               );
-
-              if (!isUndefined(original.info.lastPolicyUpdateTime)) {
-                let lastUpdateDate = new Date(
-                  parseInt(original.info.lastPolicyUpdateTime)
-                );
-
-                if (isDateDifferenceMoreThanHr(activeDate, lastUpdateDate)) {
-                  if (
-                    moment(activeDate).diff(
-                      moment(lastUpdateDate),
-                      "minutes"
-                    ) >= -2
-                  ) {
-                    return (
-                      <span className="text-warning">
-                        <CustomTooltip
-                          placement="bottom"
-                          content={
-                            " Policy is updated but not yet used for any enforcement."
-                          }
-                          icon="fa-fw fa fa-exclamation-circle active-policy-alert"
-                        />
-                        {setTimeStamp(original.info.policyActivationTime)}
-                      </span>
-                    );
-                  } else {
-                    return (
-                      <span className="text-error">
-                        <CustomTooltip
-                          placement="bottom"
-                          content={
-                            " Policy is updated but not yet used for any enforcement."
-                          }
-                          icon="fa-fw fa fa-exclamation-circle active-policy-alert"
-                        />
-                        {setTimeStamp(original.info.policyActivationTime)}
-                      </span>
-                    );
-                  }
-                }
-              }
-              return setTimeStamp(original.info.policyActivationTime);
             },
             minWidth: 190
           }
@@ -343,13 +331,13 @@
       },
       {
         Header: infoIcon("Tag"),
-        id: "taginfo",
+        id: "Tag (Time)",
         columns: [
           {
             Header: "Last Update",
             accessor: "lastTagUpdateTime",
             Cell: ({ row: { original } }) => {
-              return setTimeStamp(original.info.lastTagUpdateTime);
+              return getLastUpdateTime(original.info.lastTagUpdateTime);
             },
             minWidth: 190
           },
@@ -358,50 +346,11 @@
             accessor: "tagDownloadTime",
 
             Cell: ({ row: { original } }) => {
-              var downloadDate = new Date(
-                parseInt(original.info.tagDownloadTime)
+              return getDownloadTime(
+                original.info.tagDownloadTime,
+                original.info.lastTagUpdateTime,
+                "Tag"
               );
-
-              if (!isUndefined(original.info.lastTagUpdateTime)) {
-                var lastUpdateDate = new Date(
-                  parseInt(original.info.lastTagUpdateTime)
-                );
-                if (isDateDifferenceMoreThanHr(downloadDate, lastUpdateDate)) {
-                  if (
-                    moment(downloadDate).diff(
-                      moment(lastUpdateDate),
-                      "minutes"
-                    ) >= -2
-                  ) {
-                    return (
-                      <span className="text-warning">
-                        <CustomTooltip
-                          placement="bottom"
-                          content={
-                            "Policy is updated but not yet downloaded(sync-upwith Ranger)"
-                          }
-                          icon="fa-fw fa fa-exclamation-circle active-policy-alert"
-                        />
-                        {setTimeStamp(original.info.tagDownloadTime)}
-                      </span>
-                    );
-                  } else {
-                    return (
-                      <span className="text-error">
-                        <CustomTooltip
-                          placement="bottom"
-                          content={
-                            "Policy is updated but not yet downloaded(sync-upwith Ranger)"
-                          }
-                          icon="fa-fw fa fa-exclamation-circle active-policy-alert"
-                        />
-                        {setTimeStamp(original.info.tagDownloadTime)}{" "}
-                      </span>
-                    );
-                  }
-                }
-              }
-              return setTimeStamp(original.info.tagDownloadTime);
             },
             minWidth: 190
           },
@@ -410,50 +359,11 @@
             accessor: "tagActivationTime",
 
             Cell: ({ row: { original } }) => {
-              var downloadDate = new Date(
-                parseInt(original.info.tagActivationTime)
+              return getActivationTime(
+                original.info.tagActivationTime,
+                original.info.lastTagUpdateTime,
+                "Tag"
               );
-
-              if (!isUndefined(original.info.lastTagUpdateTime)) {
-                var lastUpdateDate = new Date(
-                  parseInt(original.info.lastTagUpdateTime)
-                );
-                if (isDateDifferenceMoreThanHr(downloadDate, lastUpdateDate)) {
-                  if (
-                    moment(downloadDate).diff(
-                      moment(lastUpdateDate),
-                      "minutes"
-                    ) >= -2
-                  ) {
-                    return (
-                      <span className="text-warning">
-                        <CustomTooltip
-                          placement="bottom"
-                          content={
-                            "Policy is updated but not yet used for anyenforcement."
-                          }
-                          icon="fa-fw fa fa-exclamation-circle active-policy-alert"
-                        />
-                        {setTimeStamp(original.info.tagActivationTime)}
-                      </span>
-                    );
-                  } else {
-                    return (
-                      <span className="text-error">
-                        <CustomTooltip
-                          placement="bottom"
-                          content={
-                            "Policy is updated but not yet used for anyenforcement."
-                          }
-                          icon="fa-fw fa fa-exclamation-circle active-policy-alert"
-                        />
-                        {setTimeStamp(original.info.tagActivationTime)}{" "}
-                      </span>
-                    );
-                  }
-                }
-              }
-              return setTimeStamp(original.info.tagActivationTime);
             },
             minWidth: 190
           }
@@ -564,7 +474,11 @@
             </div>
           </Col>
         </Row>
-        <AuditFilterEntries entries={entries} refreshTable={refreshTable} />
+        <Row>
+          <Col sm={11}>
+            <AuditFilterEntries entries={entries} refreshTable={refreshTable} />
+          </Col>
+        </Row>
         <XATableLayout
           data={pluginStatusListingData}
           columns={columns}
@@ -574,6 +488,7 @@
           columnSort={true}
           clientSideSorting={true}
           showPagination={false}
+          columnHide={true}
         />
       </React.Fragment>
     </div>
diff --git a/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/PluginsLog.jsx b/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/PluginsLog.jsx
index 53e5079..d6f8b43 100644
--- a/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/PluginsLog.jsx
+++ b/security-admin/src/main/webapp/react-webapp/src/views/AuditEvent/PluginsLog.jsx
@@ -24,7 +24,7 @@
 import { AuditFilterEntries } from "Components/CommonComponents";
 import moment from "moment-timezone";
 import dateFormat from "dateformat";
-import { sortBy, filter } from "lodash";
+import { sortBy, filter, isEmpty } from "lodash";
 import StructuredFilter from "../../components/structured-filter/react-typeahead/tokenizer";
 import { fetchApi } from "Utils/fetchAPI";
 import {
@@ -168,13 +168,15 @@
         Header: "Plugin ID",
         accessor: "agentId",
         Cell: (rawValue) => {
-          return (
+          return !isEmpty(rawValue.value) ? (
             <span
               className="text-truncate text-center d-block"
               title={rawValue.value}
             >
               {rawValue.value}
             </span>
+          ) : (
+            <span className="text-center d-block">--</span>
           );
         },
         disableSortBy: true
@@ -198,13 +200,15 @@
         Header: "Cluster Name",
         accessor: "clusterName",
         Cell: (rawValue) => {
-          return (
+          return !isEmpty(rawValue.value) ? (
             <span
               className="text-truncate text-center d-block"
               title={rawValue.value}
             >
               {rawValue.value}
             </span>
+          ) : (
+            <span className="text-center d-block">--</span>
           );
         },
         width: 100,