pawarprasad123 commented on code in PR #708:
URL: https://github.com/apache/atlas/pull/708#discussion_r3747356837


##########
dashboardv2/public/js/views/audit/AdminAuditTableLayoutView.js:
##########
@@ -349,25 +392,95 @@ define(['require',
                     };
                 this.showModal(modalData);
             },
-            displayPurgeAndImportAudits: function(obj) {
+            displayPurgeAndImportAudits: function (obj) {
+                var adminTypDetails = Enums.category[obj.operation];
+
+                // If it's a new JSON string (from new API changes), parse it.
+                var isJson = false;
+                var summaryData = {};
+                try {
+                    summaryData = typeof obj.results === 'string' ? 
JSON.parse(obj.results) : obj.results;
+                    if (summaryData && typeof summaryData === 'object' && 
!Array.isArray(summaryData)) {
+                        isJson = true;
+                    }
+                } catch (e) {
+                    isJson = false;
+                }
+
+                if (isJson) {
+                    // It's the new Summary format
+                    var runId = summaryData.runId || obj.model.get('runId') || 
'';
+                    var paramsArr = obj.model.get('params') ? 
obj.model.get('params').split(',') : [];
+
+                    var reqCount = summaryData.requestedCount !== undefined ? 
summaryData.requestedCount : paramsArr.length;
+                    var purgedCount = summaryData.purgedCount !== undefined ? 
summaryData.purgedCount : 0;
+                    var purgedDependenciesCount = 
summaryData.purgedDependenciesCount || 0;
+                    var totalPurgedCount = purgedCount + 
purgedDependenciesCount;
+                    var failedCount = summaryData.failedCount || 0;
+                    var failedDependenciesCount = 
summaryData.failedDependenciesCount || 0;
+                    var totalFailedCount = failedCount + 
failedDependenciesCount;
+                    var skippedCount = summaryData.skippedCount || 0;
+
+                    var html = '<div class="row"><div class="attr-details">';
+
+                    html += '<div class="purge-summary-wrapper">';
+                    if (runId) {
+                        html += '<div class="purge-run-id-row"><strong>Run 
Id:</strong> <span data-id="runIdValue">' + _.escape(runId) + '</span> <i 
class="fa fa-copy purge-run-id-copy" data-id="copyRunIdMain" title="Copy to 
clipboard"></i></div>';
+                    }
+
+                    html += '<div class="purge-summary-container">';
+
+                    // Requested
+                    html += '<div class="purge-summary-card card-blue 
clickable" data-id="drawerSummaryTrigger" data-type="requested" data-runid="' + 
_.escape(runId) + '" data-guid="' + _.escape(obj.model.get('guid')) + '" 
data-params="' + _.escape(obj.model.get('params')) + '">';
+                    html += '<div class="card-label">REQUESTED</div><div 
class="card-value">' + reqCount + '</div></div>';
+
+                    // Total Purged
+                    var rawResults = obj.originalResults ? obj.originalResults 
: (typeof obj.results === 'string' ? obj.results : JSON.stringify(obj.results));
+                    html += '<div class="purge-summary-card card-green ' + 
(totalPurgedCount > 0 ? 'clickable' : '') + '" ' + (totalPurgedCount > 0 ? 
'data-id="drawerSummaryTrigger" data-type="purged" data-runid="' + 
_.escape(runId) + '" data-guid="' + _.escape(obj.model.get('guid')) + '" 
data-results="' + _.escape(rawResults) + '"' : '') + '>';
+                    html += '<div class="card-label">PURGED</div><div 
class="card-value">' + totalPurgedCount + '</div></div>';
+
+                    // Failed
+                    html += '<div class="purge-summary-card card-red ' + 
(totalFailedCount > 0 ? 'has-count' : '') + '" title="Some entities failed to 
purge. Please check purgefailure.log for details.">';
+                    html += '<div class="card-label">FAILED</div><div 
class="card-value">' + totalFailedCount + '</div></div>';
+
+                    // Skipped
+                    html += '<div class="purge-summary-card card-amber ' + 
(skippedCount > 0 ? 'has-count' : '') + '" title="Some entities were skipped 
during purge. Please check purgefailure.log for details.">';

Review Comment:
   title="Some entities failed to purge. Please check purgefailure.log for 
details."
   
   Blocker — Classic UI tooltips always show failure message (even when count = 
0)
   
   Failed/Skipped card title is always the failure message, even when count is 
0. Please match React behavior: show a neutral tooltip when count is 0, failure 
message only when count > 0 or executionFailed.
   



##########
dashboardv2/public/js/views/audit/AdminAuditTableLayoutView.js:
##########
@@ -164,18 +166,41 @@ define(['require',
                     that.getAdminCollection();
                 }
             },
-            getAdminCollection: function(option) {
+            getAdminCollection: function (option) {
                 var that = this,
                     auditFilters = 
CommonViewFunction.attributeFilter.generateAPIObj(that.ruleUrl);
+
+                if (that.isFilters && auditFilters && (auditFilters.criterion 
|| auditFilters.attributeName)) {
+                    var hasRunId = false;
+                    var checkRunId = function (crit) {
+                        if (!crit) return;
+                        if (crit.attributeName === 'runId') hasRunId = true;
+                        if (crit.criterion && Array.isArray(crit.criterion)) {
+                            crit.criterion.forEach(checkRunId);
+                        }
+                    };
+                    checkRunId(auditFilters);
+
+                    if (hasRunId) {
+                        auditFilters = {
+                            "condition": "AND",
+                            "criterion": [
+                                auditFilters,
+                                { "attributeName": "auditRowKind", "operator": 
"eq", "attributeValue": "SUMMARY" }

Review Comment:
   Blocker — Classic UI does not remove existing auditRowKind before injecting 
SUMMARY
   
   React UI removes existing auditRowKind before injecting SUMMARY when 
filtering by runId. Classic UI should do the same for parity — otherwise runId 
+ auditRowKind filters can conflict.



##########
dashboard/src/views/Administrator/Audits/AuditResults.tsx:
##########
@@ -15,227 +15,716 @@
  * limitations under the License.
  */
 
-import { Grid, Link, List, ListItem, ListItemText, Typography } from 
"@mui/material";
-import { auditAction, category } from "@utils/Enum";
+import { Grid, Link, List, ListItem, ListItemText, Typography, Box, Drawer, 
IconButton, Stack, Tooltip, TextField, InputAdornment, Pagination, 
PaginationItem, Skeleton } from "@mui/material";
+import KeyboardDoubleArrowLeftIcon from 
"@mui/icons-material/KeyboardDoubleArrowLeft";
+import KeyboardDoubleArrowRightIcon from 
"@mui/icons-material/KeyboardDoubleArrowRight";
+import ContentCopyIcon from "@mui/icons-material/ContentCopy";
+import SearchIcon from "@mui/icons-material/Search";
+import { auditAction, category, AuditOperation, PurgeActiveView } from 
"@utils/Enum";
 import { isEmpty, jsonParse } from "@utils/Utils";
+import { useVirtualization } from "@hooks/useVirtualization";
 import CustomModal from "@components/Modal";
 import TypeDefAuditDetailModal from "@components/TypeDefAuditDetailModal";
-import { useState } from "react";
-import { Item } from "@utils/Muiutils";
+import { useRef, useState, useEffect } from "react";
 import AuditsTab from "@views/DetailPage/EntityDetailTabs/AuditsTab";
 import ImportExportAudits from "./ImportExportAudits";
+import { LightTooltip } from "@components/muiComponents";
+import { fetchApi } from "@api/apiMethods/fetchApi";
+import "./AuditResults.scss";
+interface AuditEntry {
+  guid: string;
+  operation: string;
+  params?: string;
+  result?: string;
+  runId?: string;
+  [key: string]: unknown;
+}
 
-const AuditResults = ({ componentProps, row }: any) => {
+interface AuditResultsProps {
+  componentProps?: {
+    auditData?: AuditEntry[];
+  };
+  row: {
+    original: {
+      guid: string;
+      runId?: string;
+      [key: string]: unknown;
+    };
+  };
+}
+
+const AuditResults = ({ componentProps, row }: AuditResultsProps) => {
   const { auditData } = componentProps || {};
   const [openModal, setOpenModal] = useState<boolean>(false);
   const [openPurgeModal, setOpenPurgeModal] = useState<boolean>(false);
-  const [currentResultObj, setCurrentObj] = useState<any>({});
-  const [currentPurgeResultObj, setCurrentPurgeResultObj] = useState<any>("");
+  const [currentResultObj, setCurrentObj] = useState<Record<string, unknown> | 
undefined>();
+  // Stores the guid of the clicked purged entity
+  const [currentPurgeResultObj, setCurrentPurgeResultObj] = useState<string | 
undefined>();
+  const [activePurgeView, setActivePurgeView] = 
useState<PurgeActiveView>(PurgeActiveView.NONE);
+  const [drawerSearchText, setDrawerSearchText] = useState<string>('');
+  const [drawerPage, setDrawerPage] = useState<number>(1);
+  const [drawerPageSize, setDrawerPageSize] = useState<number>(25);
+  const [drawerPageSizeInput, setDrawerPageSizeInput] = useState<string>('25');
+  const [scrollTop, setScrollTop] = useState<number>(0);
+  const [copiedRunId, setCopiedRunId] = useState<boolean>(false);
+  const [purgedApiGuids, setPurgedApiGuids] = useState<string[]>([]);
+  const [summaryData, setSummaryData] = useState<Record<string, unknown> | 
null>(null);
+  const [loadingSummary, setLoadingSummary] = useState<boolean>(false);
+
+
   const handleCloseModal = () => {
     setOpenModal(false);
   };
   const handleClosePurgeModal = () => {
     setOpenPurgeModal(false);
   };
-  const auditObj = !isEmpty(auditData)
-    ? auditData.find((obj: { guid: string }) => obj.guid == row.original.guid)
-    : {};
 
-  const { operation, params, result } = auditObj;
+  const auditObj: AuditEntry | undefined = !isEmpty(auditData)
+    ? (auditData as AuditEntry[]).find((obj) => obj.guid === row.original.guid)
+    : undefined;
+
+  const operation = auditObj?.operation ?? '';
+  const params = auditObj?.params;
+  const result = auditObj?.result;
+
+  let isPurgeOperation = operation === AuditOperation.PURGE || operation === 
AuditOperation.AUTO_PURGE;
+  const summaryGuid = auditObj?.guid ?? row.original.guid;
+
+  useEffect(() => {
+    const controller = new AbortController();
+
+    if (isPurgeOperation && summaryGuid) {
+      setLoadingSummary(true);
+      fetchApi(`/api/atlas/admin/audit/${summaryGuid}/summary`, {
+        method: "GET",
+        headers: { 'Accept': 'application/json', 'Content-Type': 
'application/json' },
+        signal: controller.signal
+      })
+        .then(res => {
+          if (!controller.signal.aborted) {
+            if (res.data && !Array.isArray(res.data) && typeof res.data === 
'object') {
+              setSummaryData(res.data);
+            }
+          }
+        })
+        .catch(err => {
+          if (!controller.signal.aborted && err.name !== 'AbortError' && 
err.name !== 'CanceledError') {
+            console.error("Failed to fetch purge summary", err);
+          }
+        })
+        .finally(() => {
+          if (!controller.signal.aborted) {
+            setLoadingSummary(false);
+          }
+        });
+    }
+
+    return () => {
+      controller.abort();
+    };
+  }, [isPurgeOperation, summaryGuid]);
+
+  let summary: Record<string, unknown> = summaryData || {};
+  let requestedEntitiesList: string[] = [];
+  let legacyPurgedList: string[] = [];
+
+  if (isPurgeOperation) {
+    if (!summaryData) {
+      try {
+        const parsed = typeof result === "string" ? JSON.parse(result) : 
result;
+        if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
+          summary = (parsed as Record<string, unknown>).summary
+            ? (parsed as Record<string, unknown>).summary as Record<string, 
unknown>
+            : parsed as Record<string, unknown>;
+        } else if (Array.isArray(parsed)) {
+          legacyPurgedList = (parsed as unknown[]).map((item) =>
+            typeof item === "string" ? item : (item as { guid?: string }).guid 
|| String(item)
+          );
+        }
+      } catch (_e) {
+        if (typeof result === "string" && !result.startsWith("{")) {
+          legacyPurgedList = result.replace(/^\[|\]$/g, "").split(",").map(s 
=> s.trim()).filter(Boolean);
+        }
+      }
+    } else {
+      if (typeof result === "string" && !result.startsWith("{")) {
+        legacyPurgedList = result.replace(/^\[|\]$/g, "").split(",").map(s => 
s.trim()).filter(Boolean);
+      }
+    }
 
-  const resultObj =
-    (operation == "PURGE" || operation == "AUTO_PURGE")
-      ? result.replace("[", "").replace("]", "").split(",")
-      : jsonParse(result);
+    if (params) {
+      try {
+        const parsedParams = JSON.parse(params);
+        if (Array.isArray(parsedParams)) {
+          requestedEntitiesList = parsedParams as string[];
+        } else if (typeof params === "string") {
+          requestedEntitiesList = params.replace(/^\[|\]$/g, 
"").split(",").map(s => s.trim()).filter(Boolean);
+        }
+      } catch (_e) {
+        requestedEntitiesList = typeof params === "string"
+          ? params.replace(/^\[|\]$/g, "").split(",").map(s => 
s.trim()).filter(Boolean)
+          : [];
+      }
+    }
+  } else {
+    try {
+      summary = jsonParse(result) as Record<string, unknown>;
+    } catch (_e) {
+      summary = {};
+    }
+  }
+
+  const runId = (row.original.runId as string | undefined)
+    ?? (summary?.runId as string | undefined)
+    ?? (auditObj?.runId as string | undefined)
+    ?? 'N/A';
+
+  const isSummaryRow = (runId !== 'N/A') && isPurgeOperation;
+
+
+  const requestedCount = (summary?.requestedCount as number | undefined) ?? 
requestedEntitiesList.length;
+  const purgedCount = (summary?.purgedCount as number | undefined) ?? 
legacyPurgedList.length;
+  const purgedDependenciesCount = (summary?.purgedDependenciesCount as number 
| undefined) ?? 0;
+  const totalPurgedCount = (purgedCount as number) + (purgedDependenciesCount 
as number);
+  const failedCount = (summary?.failedCount as number | undefined) ?? 0;
+  const failedDependenciesCount = (summary?.failedDependenciesCount as number 
| undefined) ?? 0;
+  const totalFailedCount = failedCount + failedDependenciesCount;
+  const skippedCount = (summary?.skippedCount as number | undefined) ?? 0;
+  const executionFailed = (summary?.executionFailed as boolean | undefined) || 
(totalFailedCount) > 0;
+
+  const handleOpenPurgedDrawer = () => {
+    if (totalPurgedCount === 0) return;
+    setActivePurgeView(PurgeActiveView.PURGED);
+    setDrawerPage(1);
+    setScrollTop(0);
+    // As requested, Total Purged simply uses the raw `result` object string 
(legacyPurgedList)
+    setPurgedApiGuids(legacyPurgedList);
+  };
 
   return (
     <>
-      {operation != "PURGE" &&
-        operation != "AUTO_PURGE" &&
-        operation != "IMPORT" &&
-        operation != "EXPORT" &&
-        !isEmpty(resultObj) ? (
-        <Grid container spacing={2}>
-          {params.split(",").length > 1 ? (
-            <>
-              {params.split(",")?.map((param: { param: string }) => {
-                return (
-                  <Grid item md={4}>
-                    <Item
-                      sx={{
-                        height: "100%",
-                        maxHeight: "300px",
-                        overflow: "auto",
-                      }}
-                    >
-                      <Typography
-                        sx={{ padding: "1rem 0 0 1rem", textAlign: "left" }}
-                      >{`${category[param as any]} ${auditAction[operation]
-                        }`}</Typography>
-
-                      <List className="audit-results-list">
-                        {resultObj[param as any].map(
-                          (obj: { name: string }) => {
-                            const { name } = obj;
-                            return (
-                              <>
-                                <ListItem className="audit-results-list-item">
-                                  <Link
-                                    className="audit-results-entityid"
-                                    component="button"
-                                    variant="body2"
-                                    onClick={() => {
-                                      setOpenModal(true);
-                                      setCurrentObj(obj);
-                                    }}
-                                    title={name}
-                                    sx={{
-                                      display: "inline-block",
-                                      maxWidth: "100%",
-                                      textOverflow: "ellipsis",
-                                      overflow: "hidden",
-                                      whiteSpace: "nowrap",
-                                      textAlign: "left",
-                                      verticalAlign: "bottom"
-                                    }}
-                                  >
-                                    {name}
-                                  </Link>
-                                </ListItem>
-                              </>
-                            );
-                          }
-                        )}
-                      </List>
-                    </Item>
-                  </Grid>
-                );
-              })}
-            </>
-          ) : (
-            <>
-              <Grid item md={4}>
-                <Item
-                  sx={{
-                    height: "100%",
-                    maxHeight: "300px",
-                    overflow: "auto",
-                  }}
-                >
-                  <Typography
-                    sx={{ padding: "1rem 0 0 1rem", textAlign: "left" }}
-                  >{`${category[params as any]} ${auditAction[operation]
-                    }`}</Typography>
-                  <List className="audit-results-list">
-                    {resultObj[params].map((obj: { name: string }) => {
-                      const { name } = obj;
-                      return (
-                        <>
-                          <ListItem className="audit-results-list-item">
+      <TypeDefAuditDetailModal
+        open={openModal}
+        onClose={handleCloseModal}
+        detailObject={currentResultObj ?? null}
+        maxWidth="md"
+      />
+
+      <CustomModal
+        open={openPurgeModal}
+        onClose={handleClosePurgeModal}
+        title={`Purged Entity Details: ${currentPurgeResultObj}`}

Review Comment:
   Important — AUTO_PURGE modal title regression
   
   New code always uses "Purged Entity Details". Test was updated to expect 
this (line ~1877 in test diff), but Classic UI still uses "Auto Purge Entity 
Details" for AUTO_PURGE.
   
   Suggestion
   
   Modal title no longer distinguishes AUTO_PURGE from PURGE. Classic UI still 
shows "Auto Purge Entity Details". Please restore operation-specific title for 
parity, or document intentional change.



##########
dashboardv2/public/css/scss/drawer.scss:
##########
@@ -0,0 +1,414 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+
+//     http://www.apache.org/licenses/LICENSE-2.0
+
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/* Purge Summary Wrapper to match React */
+.purge-summary-wrapper {
+    background-color: #fafafa;
+    border: 1px solid #e0e0e0;
+    border-radius: 8px;
+    padding: 16px;
+    margin-top: 15px;
+    margin-bottom: 20px;
+}
+
+.purge-run-id-row {
+    margin-bottom: 15px;
+    font-size: 14px;
+    font-weight: 500;
+}
+
+.purge-run-id-copy {
+    cursor: pointer;
+    color: #6b7280;
+    margin-left: 5px;
+}
+
+.purge-warning-alert {
+    padding: 10px;
+    margin-bottom: 15px;
+}
+
+.audit-type-details-title {
+    word-break: break-word;
+}
+
+.purge-summary-container {
+    display: flex;
+    gap: 15px;
+    margin-top: 15px;
+    flex-wrap: wrap;
+}
+
+.purge-summary-card {
+    flex: 1;
+    min-width: 120px;
+    padding: 12px;
+    border-radius: 8px;
+    border: 1px solid rgba(0, 0, 0, 0.08);
+    background-color: #fafafa;
+    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
+    display: flex;
+    flex-direction: column;
+    align-items: flex-start;
+    justify-content: flex-start;
+    text-align: left;
+    cursor: default;
+
+    &.clickable {
+        cursor: pointer;
+        transition: box-shadow 0.2s;
+
+        &:hover {
+            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
+        }
+    }
+
+    &.card-legacy {
+        max-width: 250px;
+    }
+
+    .card-label {
+        font-size: 11px;
+        color: #6b7280;
+        /* textSecondary */
+        margin-bottom: 4px;
+        font-weight: 600;
+        text-transform: uppercase;
+        letter-spacing: 0.5px;
+    }
+
+    .card-value {
+        font-size: 24px;
+        font-weight: 500;
+        color: #111827;
+        /* textPrimary */
+    }
+
+    &.card-blue {
+        background-color: #eff6ff;
+        border-color: #bfdbfe;
+
+        .card-label,
+        .card-value {
+            color: #1d4ed8;
+        }
+    }
+
+    &.card-green {
+        background-color: #f0fdf4;
+        border-color: #bbf7d0;
+
+        .card-label,
+        .card-value {
+            color: #15803d;
+        }
+    }
+
+    &.card-red.has-count {
+        background-color: #fef2f2;
+        border-color: #fecaca;
+
+        .card-label,
+        .card-value {
+            color: #d32f2f;
+        }
+    }
+
+    &.card-amber.has-count {
+        background-color: #fffbeb;
+        border-color: #fef08a;
+
+        .card-label,
+        .card-value {
+            color: #ed6c02;
+        }
+    }
+}
+
+/* Drawer styles */
+.drawer-overlay {
+    position: fixed;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    background-color: rgba(0, 0, 0, 0.4);
+    z-index: 1030;
+    display: none;
+    &.open { display: block; }
+}
+
+.drawer-panel {
+    position: fixed;
+    top: 0;
+    right: -400px;
+    width: 400px;
+    height: 100vh;
+    overflow: hidden;
+    background-color: #fff;
+    box-shadow: -2px 0 8px rgba(0, 0, 0, 0.15);
+    z-index: 1038;
+    transition: right 0.3s ease;
+    display: flex;
+    flex-direction: column;
+
+    &.open { right: 0; }
+
+    .drawer-header {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        padding: 8px 12px;
+        flex-shrink: 0;
+        h4 { margin: 0; font-size: 16px; font-weight: 600; }
+        .close-drawer { cursor: pointer; font-size: 18px; color: #6b7280; 
&:hover { color: #111827; } }
+    }
+
+    .drawer-body {
+        flex: 1;
+        min-height: 0;
+        overflow: hidden;
+        display: flex;
+        flex-direction: column;
+
+        .drawer-search, .drawer-run-id {
+            margin: 4px 12px;
+            flex-shrink: 0;
+        }
+
+        .drawer-search {
+            padding-bottom: 8px;
+            .search-input-wrapper {
+                position: relative;
+                i { position: absolute; left: 12px; top: 10px; color: #9ca3af; 
}
+                input {
+                    width: 100%;
+                    padding: 8px 12px 8px 32px;
+                    border: none;
+                    border-bottom: 1px solid #d1d5db;
+                    border-radius: 0;
+                    font-size: 13px;
+                    outline: none;
+                    background-color: transparent;
+                    &:focus { border-bottom-color: #3b82f6; }
+                }
+            }
+        }
+
+        .drawer-run-id {
+            padding: 4px 0;
+            display: flex;
+            justify-content: flex-start;
+            align-items: center;
+            .run-id-text { font-size: 13px; color: #4b5563; font-weight: 500; }
+            .run-id-value { color: #6b7280; font-weight: normal; margin-left: 
4px; margin-right: 12px;}
+            i { cursor: pointer; color: #6b7280; font-size: 14px; &:hover { 
color: #111827; } }
+        }
+
+        .drawer-list {
+            flex: 1;
+            overflow-y: auto;
+            min-height: 0;
+            margin: 0 15px;
+            padding-right: 5px;
+            
+
+            /* Custom scrollbar to match modern React UI */
+            &::-webkit-scrollbar {
+                width: 6px;
+            }
+            &::-webkit-scrollbar-track {
+                background: #f1f1f1;
+                border-radius: 4px;
+            }
+            &::-webkit-scrollbar-thumb {
+                background: #888;
+                border-radius: 4px;
+            }
+            &::-webkit-scrollbar-thumb:hover {
+                background: #555;
+            }
+
+            .drawer-items-list {
+                list-style-type: none;
+                padding-left: 0;
+                margin: 0;
+
+                .drawer-list-item {
+                    border-bottom: 1px solid rgba(0, 0, 0, 0.04);
+                    padding: 8px 0;
+                    display: flex;
+                    align-items: center;
+                    color: #6b7280;
+                    font-size: 13px;
+                    padding-left: 10px; /* Added left padding for spacing */
+                    
+                    .item-index {
+                        color: #6b7280;
+                        min-width: 24px;
+                        text-align: right;
+                        display: inline-block;
+                    }
+
+                    .blue-link {
+                        cursor: pointer;
+                        flex: 1;
+                        text-overflow: ellipsis;
+                        overflow: hidden;
+                        white-space: nowrap;
+                        margin-left: 12px;
+                    }
+                }
+            }
+        }
+
+        .drawer-empty, .drawer-loading {
+            padding: 20px 0;
+            text-align: center;
+            color: #6b7280;
+        }
+
+        .drawer-load-more {
+            text-align: center;
+            color: rgba(0,0,0,0.6);
+            font-style: italic;
+            margin-top: 15px;
+            margin-bottom: 15px;
+            font-size: 12px;
+            cursor: default;
+        }
+
+        .drawer-observer { height: 20px; width: 100%; }
+    }
+
+    .drawer-pagination-footer {
+        padding: 8px 12px;
+        background-color: #fff;
+        border-top: 1px solid #e2e8f0;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        flex-shrink: 0;
+
+        .drawer-showing {
+            font-size: 13px;
+            color: #6b7280;
+            white-space: nowrap;
+        }
+
+        .drawer-pagination-controls {

Review Comment:
   body.drawer-open-lock 
   Duplicate body.drawer-open-lock rule — remove one copy.



##########
dashboard/src/views/Administrator/Audits/AuditResults.tsx:
##########
@@ -15,227 +15,716 @@
  * limitations under the License.
  */
 
-import { Grid, Link, List, ListItem, ListItemText, Typography } from 
"@mui/material";
-import { auditAction, category } from "@utils/Enum";
+import { Grid, Link, List, ListItem, ListItemText, Typography, Box, Drawer, 
IconButton, Stack, Tooltip, TextField, InputAdornment, Pagination, 
PaginationItem, Skeleton } from "@mui/material";
+import KeyboardDoubleArrowLeftIcon from 
"@mui/icons-material/KeyboardDoubleArrowLeft";
+import KeyboardDoubleArrowRightIcon from 
"@mui/icons-material/KeyboardDoubleArrowRight";
+import ContentCopyIcon from "@mui/icons-material/ContentCopy";
+import SearchIcon from "@mui/icons-material/Search";
+import { auditAction, category, AuditOperation, PurgeActiveView } from 
"@utils/Enum";
 import { isEmpty, jsonParse } from "@utils/Utils";
+import { useVirtualization } from "@hooks/useVirtualization";
 import CustomModal from "@components/Modal";
 import TypeDefAuditDetailModal from "@components/TypeDefAuditDetailModal";
-import { useState } from "react";
-import { Item } from "@utils/Muiutils";
+import { useRef, useState, useEffect } from "react";
 import AuditsTab from "@views/DetailPage/EntityDetailTabs/AuditsTab";
 import ImportExportAudits from "./ImportExportAudits";
+import { LightTooltip } from "@components/muiComponents";
+import { fetchApi } from "@api/apiMethods/fetchApi";
+import "./AuditResults.scss";
+interface AuditEntry {
+  guid: string;
+  operation: string;
+  params?: string;
+  result?: string;
+  runId?: string;
+  [key: string]: unknown;
+}
 
-const AuditResults = ({ componentProps, row }: any) => {
+interface AuditResultsProps {
+  componentProps?: {
+    auditData?: AuditEntry[];
+  };
+  row: {
+    original: {
+      guid: string;
+      runId?: string;
+      [key: string]: unknown;
+    };
+  };
+}
+
+const AuditResults = ({ componentProps, row }: AuditResultsProps) => {
   const { auditData } = componentProps || {};
   const [openModal, setOpenModal] = useState<boolean>(false);
   const [openPurgeModal, setOpenPurgeModal] = useState<boolean>(false);
-  const [currentResultObj, setCurrentObj] = useState<any>({});
-  const [currentPurgeResultObj, setCurrentPurgeResultObj] = useState<any>("");
+  const [currentResultObj, setCurrentObj] = useState<Record<string, unknown> | 
undefined>();
+  // Stores the guid of the clicked purged entity
+  const [currentPurgeResultObj, setCurrentPurgeResultObj] = useState<string | 
undefined>();
+  const [activePurgeView, setActivePurgeView] = 
useState<PurgeActiveView>(PurgeActiveView.NONE);
+  const [drawerSearchText, setDrawerSearchText] = useState<string>('');
+  const [drawerPage, setDrawerPage] = useState<number>(1);
+  const [drawerPageSize, setDrawerPageSize] = useState<number>(25);
+  const [drawerPageSizeInput, setDrawerPageSizeInput] = useState<string>('25');
+  const [scrollTop, setScrollTop] = useState<number>(0);
+  const [copiedRunId, setCopiedRunId] = useState<boolean>(false);
+  const [purgedApiGuids, setPurgedApiGuids] = useState<string[]>([]);
+  const [summaryData, setSummaryData] = useState<Record<string, unknown> | 
null>(null);
+  const [loadingSummary, setLoadingSummary] = useState<boolean>(false);
+
+
   const handleCloseModal = () => {
     setOpenModal(false);
   };
   const handleClosePurgeModal = () => {
     setOpenPurgeModal(false);
   };
-  const auditObj = !isEmpty(auditData)
-    ? auditData.find((obj: { guid: string }) => obj.guid == row.original.guid)
-    : {};
 
-  const { operation, params, result } = auditObj;
+  const auditObj: AuditEntry | undefined = !isEmpty(auditData)
+    ? (auditData as AuditEntry[]).find((obj) => obj.guid === row.original.guid)
+    : undefined;
+
+  const operation = auditObj?.operation ?? '';
+  const params = auditObj?.params;
+  const result = auditObj?.result;
+
+  let isPurgeOperation = operation === AuditOperation.PURGE || operation === 
AuditOperation.AUTO_PURGE;
+  const summaryGuid = auditObj?.guid ?? row.original.guid;
+
+  useEffect(() => {
+    const controller = new AbortController();
+
+    if (isPurgeOperation && summaryGuid) {
+      setLoadingSummary(true);
+      fetchApi(`/api/atlas/admin/audit/${summaryGuid}/summary`, {
+        method: "GET",
+        headers: { 'Accept': 'application/json', 'Content-Type': 
'application/json' },
+        signal: controller.signal
+      })
+        .then(res => {
+          if (!controller.signal.aborted) {
+            if (res.data && !Array.isArray(res.data) && typeof res.data === 
'object') {
+              setSummaryData(res.data);
+            }
+          }
+        })
+        .catch(err => {
+          if (!controller.signal.aborted && err.name !== 'AbortError' && 
err.name !== 'CanceledError') {
+            console.error("Failed to fetch purge summary", err);
+          }
+        })
+        .finally(() => {
+          if (!controller.signal.aborted) {
+            setLoadingSummary(false);
+          }
+        });
+    }
+
+    return () => {
+      controller.abort();
+    };
+  }, [isPurgeOperation, summaryGuid]);
+
+  let summary: Record<string, unknown> = summaryData || {};
+  let requestedEntitiesList: string[] = [];
+  let legacyPurgedList: string[] = [];
+
+  if (isPurgeOperation) {
+    if (!summaryData) {
+      try {
+        const parsed = typeof result === "string" ? JSON.parse(result) : 
result;
+        if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
+          summary = (parsed as Record<string, unknown>).summary
+            ? (parsed as Record<string, unknown>).summary as Record<string, 
unknown>
+            : parsed as Record<string, unknown>;
+        } else if (Array.isArray(parsed)) {
+          legacyPurgedList = (parsed as unknown[]).map((item) =>
+            typeof item === "string" ? item : (item as { guid?: string }).guid 
|| String(item)
+          );
+        }
+      } catch (_e) {
+        if (typeof result === "string" && !result.startsWith("{")) {
+          legacyPurgedList = result.replace(/^\[|\]$/g, "").split(",").map(s 
=> s.trim()).filter(Boolean);
+        }
+      }
+    } else {
+      if (typeof result === "string" && !result.startsWith("{")) {
+        legacyPurgedList = result.replace(/^\[|\]$/g, "").split(",").map(s => 
s.trim()).filter(Boolean);
+      }
+    }
 
-  const resultObj =
-    (operation == "PURGE" || operation == "AUTO_PURGE")
-      ? result.replace("[", "").replace("]", "").split(",")
-      : jsonParse(result);
+    if (params) {
+      try {
+        const parsedParams = JSON.parse(params);
+        if (Array.isArray(parsedParams)) {
+          requestedEntitiesList = parsedParams as string[];
+        } else if (typeof params === "string") {
+          requestedEntitiesList = params.replace(/^\[|\]$/g, 
"").split(",").map(s => s.trim()).filter(Boolean);
+        }
+      } catch (_e) {
+        requestedEntitiesList = typeof params === "string"
+          ? params.replace(/^\[|\]$/g, "").split(",").map(s => 
s.trim()).filter(Boolean)
+          : [];
+      }
+    }
+  } else {
+    try {
+      summary = jsonParse(result) as Record<string, unknown>;
+    } catch (_e) {
+      summary = {};
+    }
+  }
+
+  const runId = (row.original.runId as string | undefined)
+    ?? (summary?.runId as string | undefined)
+    ?? (auditObj?.runId as string | undefined)
+    ?? 'N/A';
+
+  const isSummaryRow = (runId !== 'N/A') && isPurgeOperation;
+
+
+  const requestedCount = (summary?.requestedCount as number | undefined) ?? 
requestedEntitiesList.length;
+  const purgedCount = (summary?.purgedCount as number | undefined) ?? 
legacyPurgedList.length;
+  const purgedDependenciesCount = (summary?.purgedDependenciesCount as number 
| undefined) ?? 0;
+  const totalPurgedCount = (purgedCount as number) + (purgedDependenciesCount 
as number);
+  const failedCount = (summary?.failedCount as number | undefined) ?? 0;
+  const failedDependenciesCount = (summary?.failedDependenciesCount as number 
| undefined) ?? 0;
+  const totalFailedCount = failedCount + failedDependenciesCount;
+  const skippedCount = (summary?.skippedCount as number | undefined) ?? 0;
+  const executionFailed = (summary?.executionFailed as boolean | undefined) || 
(totalFailedCount) > 0;
+
+  const handleOpenPurgedDrawer = () => {
+    if (totalPurgedCount === 0) return;
+    setActivePurgeView(PurgeActiveView.PURGED);
+    setDrawerPage(1);
+    setScrollTop(0);
+    // As requested, Total Purged simply uses the raw `result` object string 
(legacyPurgedList)
+    setPurgedApiGuids(legacyPurgedList);
+  };
 
   return (
     <>
-      {operation != "PURGE" &&
-        operation != "AUTO_PURGE" &&
-        operation != "IMPORT" &&
-        operation != "EXPORT" &&
-        !isEmpty(resultObj) ? (
-        <Grid container spacing={2}>
-          {params.split(",").length > 1 ? (
-            <>
-              {params.split(",")?.map((param: { param: string }) => {
-                return (
-                  <Grid item md={4}>
-                    <Item
-                      sx={{
-                        height: "100%",
-                        maxHeight: "300px",
-                        overflow: "auto",
-                      }}
-                    >
-                      <Typography
-                        sx={{ padding: "1rem 0 0 1rem", textAlign: "left" }}
-                      >{`${category[param as any]} ${auditAction[operation]
-                        }`}</Typography>
-
-                      <List className="audit-results-list">
-                        {resultObj[param as any].map(
-                          (obj: { name: string }) => {
-                            const { name } = obj;
-                            return (
-                              <>
-                                <ListItem className="audit-results-list-item">
-                                  <Link
-                                    className="audit-results-entityid"
-                                    component="button"
-                                    variant="body2"
-                                    onClick={() => {
-                                      setOpenModal(true);
-                                      setCurrentObj(obj);
-                                    }}
-                                    title={name}
-                                    sx={{
-                                      display: "inline-block",
-                                      maxWidth: "100%",
-                                      textOverflow: "ellipsis",
-                                      overflow: "hidden",
-                                      whiteSpace: "nowrap",
-                                      textAlign: "left",
-                                      verticalAlign: "bottom"
-                                    }}
-                                  >
-                                    {name}
-                                  </Link>
-                                </ListItem>
-                              </>
-                            );
-                          }
-                        )}
-                      </List>
-                    </Item>
-                  </Grid>
-                );
-              })}
-            </>
-          ) : (
-            <>
-              <Grid item md={4}>
-                <Item
-                  sx={{
-                    height: "100%",
-                    maxHeight: "300px",
-                    overflow: "auto",
-                  }}
-                >
-                  <Typography
-                    sx={{ padding: "1rem 0 0 1rem", textAlign: "left" }}
-                  >{`${category[params as any]} ${auditAction[operation]
-                    }`}</Typography>
-                  <List className="audit-results-list">
-                    {resultObj[params].map((obj: { name: string }) => {
-                      const { name } = obj;
-                      return (
-                        <>
-                          <ListItem className="audit-results-list-item">
+      <TypeDefAuditDetailModal
+        open={openModal}
+        onClose={handleCloseModal}
+        detailObject={currentResultObj ?? null}
+        maxWidth="md"
+      />
+
+      <CustomModal
+        open={openPurgeModal}
+        onClose={handleClosePurgeModal}
+        title={`Purged Entity Details: ${currentPurgeResultObj}`}
+        button1Handler={undefined}
+        button2Handler={undefined}
+        maxWidth="md"
+        footer={false}
+      >
+        <AuditsTab auditResultGuid={currentPurgeResultObj} />
+      </CustomModal>
+
+      {operation === "TYPE_DEF_CREATE" ||
+        operation === "TYPE_DEF_UPDATE" ||
+        operation === "TYPE_DEF_DELETE" ? (
+        <List className="audit-results-list">
+          {summary &&
+            Object.keys(summary).map((key: string) => {
+              const rawItems = summary[key];
+              const items: Array<Record<string, unknown> | string> = 
Array.isArray(rawItems)
+                ? (rawItems as Array<Record<string, unknown> | string>)
+                : [];
+              return (
+                <div key={key}>
+                  <Typography className="audit-list-header">
+                    {`${category[key as keyof typeof category] || key} 
${auditAction[operation as keyof typeof auditAction] || operation}`}
+                  </Typography>
+                  {items.map((obj: Record<string, unknown> | string, idx: 
number) => {
+                    const name = typeof obj === 'object' && obj !== null
+                      ? (obj.name as string) || String(obj)
+                      : String(obj);
+                    return (
+                      <ListItem key={name + idx} 
className="audit-results-list-item">
+                        <ListItemText
+                          primary={
                             <Link
-                              className="audit-results-entityid"
+                              className="audit-results-entityid 
audit-list-link"
                               component="button"
                               variant="body2"
                               onClick={() => {
                                 setOpenModal(true);
-                                setCurrentObj(obj);
+                                setCurrentObj(typeof obj === "object" ? obj : 
{ name: obj });
                               }}
                               title={name}
-                              sx={{
-                                display: "inline-block",
-                                maxWidth: "100%",
-                                textOverflow: "ellipsis",
-                                overflow: "hidden",
-                                whiteSpace: "nowrap",
-                                textAlign: "left",
-                                verticalAlign: "bottom"
-                              }}
                             >
                               {name}
                             </Link>
-                          </ListItem>
-                        </>
-                      );
-                    })}
-                  </List>
-                </Item>
+                          }
+                        />
+                      </ListItem>
+                    );
+                  })}
+                </div>
+              );
+            })}
+        </List>
+      ) : operation === "IMPORT" || operation === "EXPORT" ? (
+        <ImportExportAudits auditObj={auditObj} />
+      ) : !isPurgeOperation ? (
+        <Typography>No Results Found</Typography>
+      ) : null}
+
+      {/* Purge Audit View */}
+      {isPurgeOperation ? (
+        <Box className="purge-audit-view">
+          {loadingSummary && Object.keys(summary).length === 0 && 
legacyPurgedList.length === 0 && !result ? (
+            <Box sx={{ p: 2 }}>
+              <Skeleton variant="text" width="40%" height={30} sx={{ mb: 2 }} 
/>
+              <Grid container spacing={2}>
+                <Grid item xs={6} sm={3}><Skeleton variant="rectangular" 
height={70} sx={{ borderRadius: 1 }} /></Grid>
+                <Grid item xs={6} sm={3}><Skeleton variant="rectangular" 
height={70} sx={{ borderRadius: 1 }} /></Grid>
+                <Grid item xs={6} sm={3}><Skeleton variant="rectangular" 
height={70} sx={{ borderRadius: 1 }} /></Grid>
+                <Grid item xs={6} sm={3}><Skeleton variant="rectangular" 
height={70} sx={{ borderRadius: 1 }} /></Grid>
               </Grid>
-            </>
+            </Box>
+          ) : (
+            <Box className="purge-summary-container">
+
+              {/* Run Id Header with Copy Action */}
+              {runId !== 'N/A' && (
+                <Box className="purge-runid-header">
+                  <Typography variant="body2" color="textSecondary" 
className="runid-text">
+                    <strong>Run Id:</strong> {runId}
+                  </Typography>
+                  <Tooltip title={copiedRunId ? "Copied!" : "Copy Run Id"}>
+                    <IconButton
+                      size="small"
+                      onClick={() => {
+                        if (navigator.clipboard) {
+                          navigator.clipboard.writeText(runId);
+                        } else {
+                          const textField = document.createElement('textarea');
+                          textField.innerText = runId;
+                          document.body.appendChild(textField);
+                          textField.select();
+                          document.execCommand('copy');
+                          textField.remove();
+                        }
+                        setCopiedRunId(true);
+                        setTimeout(() => setCopiedRunId(false), 2000);
+                      }}
+                      className="purge-runid-copy"
+                    >
+                      <ContentCopyIcon className={`copy-icon ${copiedRunId ? 
"copied" : ""}`} />
+                    </IconButton>
+                  </Tooltip>
+                </Box>
+              )}
+
+              {/* 4 Cards Grid: Requested, Total Purged, Failed (Display 
Only), Skipped (Display Only) */}
+              <Grid container spacing={2}>
+                {/* 1. Clickable Requested Card */}
+                {isSummaryRow && (
+                  <Grid item xs={6} sm={3}>
+                    <Box
+                      onClick={() => {
+                        setActivePurgeView(PurgeActiveView.REQUESTED);
+                        setDrawerPage(1);
+                        setScrollTop(0);
+                      }}
+                      className="purge-card purge-card-requested"
+                    >
+                      <Typography variant="caption" color="primary.main" 
display="block" className="card-title">
+                        Requested
+                      </Typography>
+                      <Typography variant="h5" color="primary.main" 
className="card-count">
+                        {requestedCount}
+                      </Typography>
+                    </Box>
+                  </Grid>
+                )}
+
+                {/* 2. Clickable Total Purged Card */}
+                <Grid item xs={isSummaryRow ? 6 : 12} sm={isSummaryRow ? 3 : 
4}>
+                  <Box
+                    onClick={handleOpenPurgedDrawer}
+                    className={`purge-card purge-card-purged 
${totalPurgedCount > 0 ? "clickable" : ""}`}
+                  >
+                    <Typography variant="caption" color="success.main" 
display="block" className="card-title">
+                      PURGED
+                    </Typography>
+                    <Typography variant="h5" color="success.main" 
className="card-count">
+                      {totalPurgedCount}
+                    </Typography>
+                  </Box>
+                </Grid>
+
+                {/* 3 & 4. Display-Only Failed and Skipped Cards */}
+                {isSummaryRow && (
+                  <>
+                    <Grid item xs={6} sm={3}>
+                      <LightTooltip
+                        title={
+                          totalFailedCount > 0 || executionFailed
+                            ? "Some entities failed to purge. Please check 
purgefailure.log for details."
+                            : "No failed entities during this purge operation."
+                        }
+                        arrow
+                        placement="top"
+                      >
+                        <Box
+                          className={`purge-card ${totalFailedCount > 0 ? 
"purge-card-failed" : "purge-card-failed-empty"}`}
+                        >
+                          <Typography variant="caption" 
color={totalFailedCount > 0 ? "error.main" : "textSecondary"} display="block" 
className="card-title">
+                            Failed
+                          </Typography>
+                          <Typography variant="h5" color={totalFailedCount > 0 
? "error.main" : "textPrimary"} className="card-count">
+                            {totalFailedCount}
+                          </Typography>
+                        </Box>
+                      </LightTooltip>
+                    </Grid>
+
+                    {/* 4. Display-Only Skipped Card */}
+                    <Grid item xs={6} sm={3}>
+                      <LightTooltip
+                        title={
+                          skippedCount > 0 || executionFailed
+                            ? "Some entities were skipped during purge. Please 
check purgefailure.log for details."
+                            : "No skipped entities during this purge 
operation."
+                        }
+                        arrow
+                        placement="top"
+                      >
+                        <Box
+                          className={`purge-card ${skippedCount > 0 ? 
"purge-card-skipped" : "purge-card-skipped-empty"}`}
+                        >
+                          <Typography variant="caption" color={skippedCount > 
0 ? "warning.main" : "textSecondary"} display="block" className="card-title">
+                            Skipped
+                          </Typography>
+                          <Typography variant="h5" color={skippedCount > 0 ? 
"warning.main" : "textPrimary"} className="card-count">
+                            {skippedCount}
+                          </Typography>
+                        </Box>
+                      </LightTooltip>
+                    </Grid>
+                  </>
+                )}
+              </Grid>
+            </Box>
           )}
-        </Grid>
-      ) : (
-        operation != "PURGE" &&
-        operation != "AUTO_PURGE" &&
-        operation != "IMPORT" &&
-        operation != "EXPORT" && <Typography>No Results Found</Typography>
-      )}
-
-      {(operation == "PURGE" || operation == "AUTO_PURGE") && 
!isEmpty(resultObj) ? (
-        <>
-          <Typography>{`${category[operation]}`}</Typography>
-          <List className="audit-results-list">
-            {resultObj.map((obj: string) => {
+
+          {/* Right Side Drawer — client-side pagination for both Purged and 
Requested */}
+          <PurgeEntitiesDrawer
+            activePurgeView={activePurgeView}
+            setActivePurgeView={setActivePurgeView}
+            requestedEntitiesList={requestedEntitiesList}
+            purgedApiGuids={purgedApiGuids}
+            drawerSearchText={drawerSearchText}
+            setDrawerSearchText={setDrawerSearchText}
+            drawerPage={drawerPage}
+            setDrawerPage={setDrawerPage}
+            drawerPageSize={drawerPageSize}
+            setDrawerPageSize={setDrawerPageSize}
+            scrollTop={scrollTop}
+            setScrollTop={setScrollTop}
+            runId={runId}
+            copiedRunId={copiedRunId}
+            setCopiedRunId={setCopiedRunId}
+            setOpenPurgeModal={setOpenPurgeModal}
+            setCurrentPurgeResultObj={setCurrentPurgeResultObj}
+            drawerPageSizeInput={drawerPageSizeInput}
+            setDrawerPageSizeInput={setDrawerPageSizeInput}
+          />
+        </Box>
+      ) : null}
+    </>
+  );
+};
+
+
+interface PurgeEntitiesDrawerProps {
+  activePurgeView: PurgeActiveView;
+  setActivePurgeView: (view: PurgeActiveView) => void;
+  requestedEntitiesList: string[];
+  purgedApiGuids: string[];
+  drawerSearchText: string;
+  setDrawerSearchText: (text: string) => void;
+  drawerPage: number;
+  setDrawerPage: React.Dispatch<React.SetStateAction<number>>;
+  drawerPageSize: number;
+  setDrawerPageSize: React.Dispatch<React.SetStateAction<number>>;
+  scrollTop: number;
+  setScrollTop: React.Dispatch<React.SetStateAction<number>>;
+  runId: string;
+  copiedRunId: boolean;
+  setCopiedRunId: (copied: boolean) => void;
+  setOpenPurgeModal: (open: boolean) => void;
+  setCurrentPurgeResultObj: (guid: string) => void;
+  drawerPageSizeInput: string;
+  setDrawerPageSizeInput: (input: string) => void;
+}
+
+const PurgeEntitiesDrawer: React.FC<PurgeEntitiesDrawerProps> = ({
+  activePurgeView,
+  setActivePurgeView,
+  requestedEntitiesList,
+  purgedApiGuids,
+  drawerSearchText,
+  setDrawerSearchText,
+  drawerPage,
+  setDrawerPage,
+  drawerPageSize,
+  setDrawerPageSize,
+  scrollTop,
+  setScrollTop,
+  runId,
+  copiedRunId,
+  setCopiedRunId,
+  setOpenPurgeModal,
+  setCurrentPurgeResultObj,
+  drawerPageSizeInput,
+  setDrawerPageSizeInput,
+}) => {
+  const listRef = useRef<HTMLUListElement | null>(null);
+
+  useEffect(() => {
+    if (listRef.current) {
+      listRef.current.scrollTop = 0;
+    }
+  }, [drawerPage, drawerSearchText, activePurgeView]);
+
+  const rawListForView: (string | Record<string, any>)[] =
+    activePurgeView === PurgeActiveView.REQUESTED ? requestedEntitiesList : 
purgedApiGuids;
+
+  const filteredList = rawListForView.filter((item: string | Record<string, 
any>) => {
+    if (!drawerSearchText) return true;
+    const guidStr = typeof item === 'object' && item !== null ? item.guid : 
item;
+    const nameStr = typeof item === 'object' && item !== null ? 
item.attributes?.name : '';
+    const searchLower = drawerSearchText.trim().toLowerCase();
+    return (guidStr && guidStr.toLowerCase().includes(searchLower)) ||
+      (nameStr && nameStr.toLowerCase().includes(searchLower));
+  });
+
+  const displayItems = filteredList.slice((drawerPage - 1) * drawerPageSize, 
drawerPage * drawerPageSize);
+
+  const { visibleItems, paddingTop, paddingBottom, startIndex } = 
useVirtualization({
+    items: displayItems,
+    scrollTop,
+    itemHeight: 24
+  });
+
+  const displayTotal = filteredList.length;
+
+  const handleDrawerScroll = (e: React.UIEvent<HTMLUListElement>) => {
+    setScrollTop(e.currentTarget.scrollTop);
+  };
+
+  return (
+    <Drawer
+      anchor="right"
+      open={activePurgeView !== PurgeActiveView.NONE}
+      onClose={() => {
+        setActivePurgeView(PurgeActiveView.NONE);
+        setDrawerSearchText('');
+        setDrawerPage(1);
+        setScrollTop(0);
+      }}
+      PaperProps={{ className: "drawer-paper" }}
+    >
+      <Box className="drawer-content-wrapper">
+        <Stack direction="row" justifyContent="space-between" 
alignItems="center" className="drawer-search-container">
+          <Typography className="drawer-title">
+            {activePurgeView === PurgeActiveView.REQUESTED ? 'Requested 
Entities' : 'Purged Entities'}
+          </Typography>
+          <IconButton
+            aria-label="Close drawer"
+            onClick={() => {
+              setActivePurgeView(PurgeActiveView.NONE);
+              setDrawerSearchText('');
+              setDrawerPage(1);
+              setScrollTop(0);
+            }}
+            size="small"
+          >
+            ✕
+          </IconButton>
+        </Stack>
+
+        {runId !== 'N/A' && (
+          <Box className="drawer-runid-container">
+            <Typography variant="caption" color="textSecondary" 
className="drawer-runid-text">
+              <strong>Run Id:</strong> {runId}
+            </Typography>
+            <Tooltip title={copiedRunId ? "Copied!" : "Copy Run Id"}>
+              <IconButton
+                size="small"
+                onClick={() => {
+                  if (navigator.clipboard) {
+                    navigator.clipboard.writeText(runId);
+                  } else {
+                    const textField = document.createElement('textarea');
+                    textField.innerText = runId;
+                    document.body.appendChild(textField);
+                    textField.select();
+                    document.execCommand('copy');
+                    textField.remove();
+                  }
+                  setCopiedRunId(true);
+                  setTimeout(() => setCopiedRunId(false), 2000);
+                }}
+                className="drawer-copy-btn"
+              >
+                <ContentCopyIcon className={`drawer-copy-icon ${copiedRunId ? 
"copied" : ""}`} />
+              </IconButton>
+            </Tooltip>
+          </Box>
+        )}
+
+        {(activePurgeView === PurgeActiveView.REQUESTED ? 
requestedEntitiesList.length > 0 : purgedApiGuids.length > 0) && (
+          <Box className="drawer-search-container">
+            <TextField
+              fullWidth
+              size="small"
+              variant="standard"
+              placeholder="Search GUIDs..."
+              value={drawerSearchText}
+              onChange={(e) => {
+                setDrawerSearchText(e.target.value);
+                setDrawerPage(1);
+                setScrollTop(0);
+              }}
+              InputProps={{
+                disableUnderline: true,
+                startAdornment: (
+                  <InputAdornment position="start">
+                    <SearchIcon className="drawer-search-icon" />
+                  </InputAdornment>
+                ),
+                endAdornment: drawerSearchText ? (
+                  <InputAdornment position="end">
+                    <IconButton size="small" onClick={() => {
+                      setDrawerSearchText('');
+                      setDrawerPage(1);
+                      setScrollTop(0);
+                    }}>
+                      ✕
+                    </IconButton>
+                  </InputAdornment>
+                ) : null
+              }}
+              className="drawer-search-input"
+            />
+          </Box>
+        )}
+
+
+
+        <List dense className="drawer-list-container" 
onScroll={handleDrawerScroll} onWheel={handleDrawerScroll} ref={listRef}>
+          {(() => {
+            if (displayItems.length === 0) {
               return (
-                <ListItem className="audit-results-list-item">
-                  <ListItemText
-                    primary={
+                <Typography variant="body2" color="textSecondary" 
className="drawer-list-empty">
+                  {activePurgeView === PurgeActiveView.PURGED && 
purgedApiGuids.length === 0 && !drawerSearchText
+                    ? "Entity list not available for summary audits — see 
purgefailure.log"
+                    : "No matching GUIDs found"}
+                </Typography>
+              );
+            }
+
+            return (
+              <>
+                {paddingTop > 0 && <div style={{ height: paddingTop }} />}
+                {visibleItems.map((item: string | Record<string, any>, 
localIndex: number) => {
+                  const index = startIndex + localIndex;
+                  const globalIndex = (drawerPage - 1) * drawerPageSize + 
index + 1;
+                  const isObj = typeof item === 'object' && item !== null;
+                  const guidStr = isObj ? item.guid : item;
+                  return (
+                    <ListItem key={guidStr + index} 
className="drawer-list-item">
+                      <Typography variant="body2" 
className="drawer-list-index">{globalIndex}.</Typography>
                       <Link
-                        className="audit-results-entityid"
                         component="button"
                         variant="body2"
+                        underline="hover"
                         onClick={() => {
                           setOpenPurgeModal(true);
-                          setCurrentPurgeResultObj(obj);
-                        }}
-                        title={obj}
-                        sx={{
-                          display: "inline-block",
-                          maxWidth: "100%",
-                          textOverflow: "ellipsis",
-                          overflow: "hidden",
-                          whiteSpace: "nowrap",
-                          textAlign: "left",
-                          verticalAlign: "bottom"
+                          setCurrentPurgeResultObj(guidStr);
                         }}
+                        title={guidStr}
+                        className="drawer-list-link"
                       >
-                        {obj}
+                        {guidStr}
                       </Link>
-                    }
-                  />
-                </ListItem>
-              );
-            })}
-          </List>
-        </>
-      ) : (
-        (operation == "PURGE" || operation == "AUTO_PURGE") && <Typography>No 
Results Found</Typography>
-      )}
+                    </ListItem>
+                  );
+                })}
+                {paddingBottom > 0 && <div style={{ height: paddingBottom }} 
/>}
+              </>
+            );
+          })()}
 
-      {(operation == "IMPORT" || operation == "EXPORT") && (
-        <ImportExportAudits auditObj={auditObj} />
-      )}
 
-      <TypeDefAuditDetailModal
-        open={openModal}
-        onClose={handleCloseModal}
-        detailObject={currentResultObj}
-        maxWidth="sm"
-      />
+        </List>

Review Comment:
   Add tests for: (1) successful summary fetch populates cards, (2) fetch 
failure falls back to parsed result, (3) loading skeleton shows while fetching, 
(4) AbortController cancels on unmount.
   
   



##########
dashboard/src/views/Administrator/Audits/AuditResults.tsx:
##########
@@ -15,227 +15,716 @@
  * limitations under the License.
  */
 
-import { Grid, Link, List, ListItem, ListItemText, Typography } from 
"@mui/material";
-import { auditAction, category } from "@utils/Enum";
+import { Grid, Link, List, ListItem, ListItemText, Typography, Box, Drawer, 
IconButton, Stack, Tooltip, TextField, InputAdornment, Pagination, 
PaginationItem, Skeleton } from "@mui/material";
+import KeyboardDoubleArrowLeftIcon from 
"@mui/icons-material/KeyboardDoubleArrowLeft";
+import KeyboardDoubleArrowRightIcon from 
"@mui/icons-material/KeyboardDoubleArrowRight";
+import ContentCopyIcon from "@mui/icons-material/ContentCopy";
+import SearchIcon from "@mui/icons-material/Search";
+import { auditAction, category, AuditOperation, PurgeActiveView } from 
"@utils/Enum";
 import { isEmpty, jsonParse } from "@utils/Utils";
+import { useVirtualization } from "@hooks/useVirtualization";
 import CustomModal from "@components/Modal";
 import TypeDefAuditDetailModal from "@components/TypeDefAuditDetailModal";
-import { useState } from "react";
-import { Item } from "@utils/Muiutils";
+import { useRef, useState, useEffect } from "react";
 import AuditsTab from "@views/DetailPage/EntityDetailTabs/AuditsTab";
 import ImportExportAudits from "./ImportExportAudits";
+import { LightTooltip } from "@components/muiComponents";
+import { fetchApi } from "@api/apiMethods/fetchApi";
+import "./AuditResults.scss";
+interface AuditEntry {
+  guid: string;
+  operation: string;
+  params?: string;
+  result?: string;
+  runId?: string;
+  [key: string]: unknown;
+}
 
-const AuditResults = ({ componentProps, row }: any) => {
+interface AuditResultsProps {
+  componentProps?: {
+    auditData?: AuditEntry[];
+  };
+  row: {
+    original: {
+      guid: string;
+      runId?: string;
+      [key: string]: unknown;
+    };
+  };
+}
+
+const AuditResults = ({ componentProps, row }: AuditResultsProps) => {
   const { auditData } = componentProps || {};
   const [openModal, setOpenModal] = useState<boolean>(false);
   const [openPurgeModal, setOpenPurgeModal] = useState<boolean>(false);
-  const [currentResultObj, setCurrentObj] = useState<any>({});
-  const [currentPurgeResultObj, setCurrentPurgeResultObj] = useState<any>("");
+  const [currentResultObj, setCurrentObj] = useState<Record<string, unknown> | 
undefined>();
+  // Stores the guid of the clicked purged entity
+  const [currentPurgeResultObj, setCurrentPurgeResultObj] = useState<string | 
undefined>();
+  const [activePurgeView, setActivePurgeView] = 
useState<PurgeActiveView>(PurgeActiveView.NONE);
+  const [drawerSearchText, setDrawerSearchText] = useState<string>('');
+  const [drawerPage, setDrawerPage] = useState<number>(1);
+  const [drawerPageSize, setDrawerPageSize] = useState<number>(25);
+  const [drawerPageSizeInput, setDrawerPageSizeInput] = useState<string>('25');
+  const [scrollTop, setScrollTop] = useState<number>(0);
+  const [copiedRunId, setCopiedRunId] = useState<boolean>(false);
+  const [purgedApiGuids, setPurgedApiGuids] = useState<string[]>([]);
+  const [summaryData, setSummaryData] = useState<Record<string, unknown> | 
null>(null);
+  const [loadingSummary, setLoadingSummary] = useState<boolean>(false);
+
+
   const handleCloseModal = () => {
     setOpenModal(false);
   };
   const handleClosePurgeModal = () => {
     setOpenPurgeModal(false);
   };
-  const auditObj = !isEmpty(auditData)
-    ? auditData.find((obj: { guid: string }) => obj.guid == row.original.guid)
-    : {};
 
-  const { operation, params, result } = auditObj;
+  const auditObj: AuditEntry | undefined = !isEmpty(auditData)
+    ? (auditData as AuditEntry[]).find((obj) => obj.guid === row.original.guid)
+    : undefined;
+
+  const operation = auditObj?.operation ?? '';
+  const params = auditObj?.params;
+  const result = auditObj?.result;
+
+  let isPurgeOperation = operation === AuditOperation.PURGE || operation === 
AuditOperation.AUTO_PURGE;
+  const summaryGuid = auditObj?.guid ?? row.original.guid;
+
+  useEffect(() => {
+    const controller = new AbortController();
+
+    if (isPurgeOperation && summaryGuid) {
+      setLoadingSummary(true);
+      fetchApi(`/api/atlas/admin/audit/${summaryGuid}/summary`, {
+        method: "GET",
+        headers: { 'Accept': 'application/json', 'Content-Type': 
'application/json' },
+        signal: controller.signal
+      })
+        .then(res => {
+          if (!controller.signal.aborted) {
+            if (res.data && !Array.isArray(res.data) && typeof res.data === 
'object') {
+              setSummaryData(res.data);
+            }
+          }
+        })
+        .catch(err => {
+          if (!controller.signal.aborted && err.name !== 'AbortError' && 
err.name !== 'CanceledError') {
+            console.error("Failed to fetch purge summary", err);
+          }
+        })
+        .finally(() => {
+          if (!controller.signal.aborted) {
+            setLoadingSummary(false);
+          }
+        });
+    }
+
+    return () => {
+      controller.abort();
+    };
+  }, [isPurgeOperation, summaryGuid]);
+
+  let summary: Record<string, unknown> = summaryData || {};
+  let requestedEntitiesList: string[] = [];
+  let legacyPurgedList: string[] = [];
+
+  if (isPurgeOperation) {
+    if (!summaryData) {
+      try {
+        const parsed = typeof result === "string" ? JSON.parse(result) : 
result;
+        if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
+          summary = (parsed as Record<string, unknown>).summary
+            ? (parsed as Record<string, unknown>).summary as Record<string, 
unknown>
+            : parsed as Record<string, unknown>;
+        } else if (Array.isArray(parsed)) {
+          legacyPurgedList = (parsed as unknown[]).map((item) =>
+            typeof item === "string" ? item : (item as { guid?: string }).guid 
|| String(item)
+          );
+        }
+      } catch (_e) {
+        if (typeof result === "string" && !result.startsWith("{")) {
+          legacyPurgedList = result.replace(/^\[|\]$/g, "").split(",").map(s 
=> s.trim()).filter(Boolean);
+        }
+      }
+    } else {
+      if (typeof result === "string" && !result.startsWith("{")) {
+        legacyPurgedList = result.replace(/^\[|\]$/g, "").split(",").map(s => 
s.trim()).filter(Boolean);
+      }
+    }
 
-  const resultObj =
-    (operation == "PURGE" || operation == "AUTO_PURGE")
-      ? result.replace("[", "").replace("]", "").split(",")
-      : jsonParse(result);
+    if (params) {
+      try {
+        const parsedParams = JSON.parse(params);
+        if (Array.isArray(parsedParams)) {
+          requestedEntitiesList = parsedParams as string[];
+        } else if (typeof params === "string") {
+          requestedEntitiesList = params.replace(/^\[|\]$/g, 
"").split(",").map(s => s.trim()).filter(Boolean);
+        }
+      } catch (_e) {
+        requestedEntitiesList = typeof params === "string"
+          ? params.replace(/^\[|\]$/g, "").split(",").map(s => 
s.trim()).filter(Boolean)
+          : [];
+      }
+    }
+  } else {
+    try {
+      summary = jsonParse(result) as Record<string, unknown>;
+    } catch (_e) {
+      summary = {};
+    }
+  }
+
+  const runId = (row.original.runId as string | undefined)
+    ?? (summary?.runId as string | undefined)
+    ?? (auditObj?.runId as string | undefined)
+    ?? 'N/A';
+
+  const isSummaryRow = (runId !== 'N/A') && isPurgeOperation;
+
+
+  const requestedCount = (summary?.requestedCount as number | undefined) ?? 
requestedEntitiesList.length;
+  const purgedCount = (summary?.purgedCount as number | undefined) ?? 
legacyPurgedList.length;
+  const purgedDependenciesCount = (summary?.purgedDependenciesCount as number 
| undefined) ?? 0;
+  const totalPurgedCount = (purgedCount as number) + (purgedDependenciesCount 
as number);
+  const failedCount = (summary?.failedCount as number | undefined) ?? 0;
+  const failedDependenciesCount = (summary?.failedDependenciesCount as number 
| undefined) ?? 0;
+  const totalFailedCount = failedCount + failedDependenciesCount;
+  const skippedCount = (summary?.skippedCount as number | undefined) ?? 0;
+  const executionFailed = (summary?.executionFailed as boolean | undefined) || 
(totalFailedCount) > 0;
+
+  const handleOpenPurgedDrawer = () => {
+    if (totalPurgedCount === 0) return;
+    setActivePurgeView(PurgeActiveView.PURGED);
+    setDrawerPage(1);
+    setScrollTop(0);
+    // As requested, Total Purged simply uses the raw `result` object string 
(legacyPurgedList)
+    setPurgedApiGuids(legacyPurgedList);
+  };
 
   return (
     <>
-      {operation != "PURGE" &&
-        operation != "AUTO_PURGE" &&
-        operation != "IMPORT" &&
-        operation != "EXPORT" &&
-        !isEmpty(resultObj) ? (
-        <Grid container spacing={2}>
-          {params.split(",").length > 1 ? (
-            <>
-              {params.split(",")?.map((param: { param: string }) => {
-                return (
-                  <Grid item md={4}>
-                    <Item
-                      sx={{
-                        height: "100%",
-                        maxHeight: "300px",
-                        overflow: "auto",
-                      }}
-                    >
-                      <Typography
-                        sx={{ padding: "1rem 0 0 1rem", textAlign: "left" }}
-                      >{`${category[param as any]} ${auditAction[operation]
-                        }`}</Typography>
-
-                      <List className="audit-results-list">
-                        {resultObj[param as any].map(
-                          (obj: { name: string }) => {
-                            const { name } = obj;
-                            return (
-                              <>
-                                <ListItem className="audit-results-list-item">
-                                  <Link
-                                    className="audit-results-entityid"
-                                    component="button"
-                                    variant="body2"
-                                    onClick={() => {
-                                      setOpenModal(true);
-                                      setCurrentObj(obj);
-                                    }}
-                                    title={name}
-                                    sx={{
-                                      display: "inline-block",
-                                      maxWidth: "100%",
-                                      textOverflow: "ellipsis",
-                                      overflow: "hidden",
-                                      whiteSpace: "nowrap",
-                                      textAlign: "left",
-                                      verticalAlign: "bottom"
-                                    }}
-                                  >
-                                    {name}
-                                  </Link>
-                                </ListItem>
-                              </>
-                            );
-                          }
-                        )}
-                      </List>
-                    </Item>
-                  </Grid>
-                );
-              })}
-            </>
-          ) : (
-            <>
-              <Grid item md={4}>
-                <Item
-                  sx={{
-                    height: "100%",
-                    maxHeight: "300px",
-                    overflow: "auto",
-                  }}
-                >
-                  <Typography
-                    sx={{ padding: "1rem 0 0 1rem", textAlign: "left" }}
-                  >{`${category[params as any]} ${auditAction[operation]
-                    }`}</Typography>
-                  <List className="audit-results-list">
-                    {resultObj[params].map((obj: { name: string }) => {
-                      const { name } = obj;
-                      return (
-                        <>
-                          <ListItem className="audit-results-list-item">
+      <TypeDefAuditDetailModal
+        open={openModal}
+        onClose={handleCloseModal}
+        detailObject={currentResultObj ?? null}
+        maxWidth="md"
+      />
+
+      <CustomModal
+        open={openPurgeModal}
+        onClose={handleClosePurgeModal}
+        title={`Purged Entity Details: ${currentPurgeResultObj}`}
+        button1Handler={undefined}
+        button2Handler={undefined}
+        maxWidth="md"
+        footer={false}
+      >
+        <AuditsTab auditResultGuid={currentPurgeResultObj} />
+      </CustomModal>
+
+      {operation === "TYPE_DEF_CREATE" ||
+        operation === "TYPE_DEF_UPDATE" ||
+        operation === "TYPE_DEF_DELETE" ? (
+        <List className="audit-results-list">
+          {summary &&
+            Object.keys(summary).map((key: string) => {
+              const rawItems = summary[key];
+              const items: Array<Record<string, unknown> | string> = 
Array.isArray(rawItems)
+                ? (rawItems as Array<Record<string, unknown> | string>)
+                : [];
+              return (
+                <div key={key}>
+                  <Typography className="audit-list-header">
+                    {`${category[key as keyof typeof category] || key} 
${auditAction[operation as keyof typeof auditAction] || operation}`}
+                  </Typography>
+                  {items.map((obj: Record<string, unknown> | string, idx: 
number) => {
+                    const name = typeof obj === 'object' && obj !== null
+                      ? (obj.name as string) || String(obj)
+                      : String(obj);
+                    return (
+                      <ListItem key={name + idx} 
className="audit-results-list-item">
+                        <ListItemText
+                          primary={
                             <Link
-                              className="audit-results-entityid"
+                              className="audit-results-entityid 
audit-list-link"
                               component="button"
                               variant="body2"
                               onClick={() => {
                                 setOpenModal(true);
-                                setCurrentObj(obj);
+                                setCurrentObj(typeof obj === "object" ? obj : 
{ name: obj });
                               }}
                               title={name}
-                              sx={{
-                                display: "inline-block",
-                                maxWidth: "100%",
-                                textOverflow: "ellipsis",
-                                overflow: "hidden",
-                                whiteSpace: "nowrap",
-                                textAlign: "left",
-                                verticalAlign: "bottom"
-                              }}
                             >
                               {name}
                             </Link>
-                          </ListItem>
-                        </>
-                      );
-                    })}
-                  </List>
-                </Item>
+                          }
+                        />
+                      </ListItem>
+                    );
+                  })}
+                </div>
+              );
+            })}
+        </List>
+      ) : operation === "IMPORT" || operation === "EXPORT" ? (
+        <ImportExportAudits auditObj={auditObj} />
+      ) : !isPurgeOperation ? (
+        <Typography>No Results Found</Typography>
+      ) : null}
+
+      {/* Purge Audit View */}
+      {isPurgeOperation ? (
+        <Box className="purge-audit-view">
+          {loadingSummary && Object.keys(summary).length === 0 && 
legacyPurgedList.length === 0 && !result ? (
+            <Box sx={{ p: 2 }}>
+              <Skeleton variant="text" width="40%" height={30} sx={{ mb: 2 }} 
/>
+              <Grid container spacing={2}>
+                <Grid item xs={6} sm={3}><Skeleton variant="rectangular" 
height={70} sx={{ borderRadius: 1 }} /></Grid>
+                <Grid item xs={6} sm={3}><Skeleton variant="rectangular" 
height={70} sx={{ borderRadius: 1 }} /></Grid>
+                <Grid item xs={6} sm={3}><Skeleton variant="rectangular" 
height={70} sx={{ borderRadius: 1 }} /></Grid>
+                <Grid item xs={6} sm={3}><Skeleton variant="rectangular" 
height={70} sx={{ borderRadius: 1 }} /></Grid>
               </Grid>
-            </>
+            </Box>
+          ) : (
+            <Box className="purge-summary-container">
+
+              {/* Run Id Header with Copy Action */}
+              {runId !== 'N/A' && (
+                <Box className="purge-runid-header">
+                  <Typography variant="body2" color="textSecondary" 
className="runid-text">
+                    <strong>Run Id:</strong> {runId}
+                  </Typography>
+                  <Tooltip title={copiedRunId ? "Copied!" : "Copy Run Id"}>
+                    <IconButton
+                      size="small"
+                      onClick={() => {
+                        if (navigator.clipboard) {
+                          navigator.clipboard.writeText(runId);
+                        } else {
+                          const textField = document.createElement('textarea');
+                          textField.innerText = runId;
+                          document.body.appendChild(textField);
+                          textField.select();
+                          document.execCommand('copy');
+                          textField.remove();
+                        }
+                        setCopiedRunId(true);
+                        setTimeout(() => setCopiedRunId(false), 2000);
+                      }}
+                      className="purge-runid-copy"
+                    >
+                      <ContentCopyIcon className={`copy-icon ${copiedRunId ? 
"copied" : ""}`} />
+                    </IconButton>
+                  </Tooltip>
+                </Box>
+              )}
+
+              {/* 4 Cards Grid: Requested, Total Purged, Failed (Display 
Only), Skipped (Display Only) */}
+              <Grid container spacing={2}>
+                {/* 1. Clickable Requested Card */}
+                {isSummaryRow && (
+                  <Grid item xs={6} sm={3}>
+                    <Box
+                      onClick={() => {
+                        setActivePurgeView(PurgeActiveView.REQUESTED);
+                        setDrawerPage(1);
+                        setScrollTop(0);
+                      }}
+                      className="purge-card purge-card-requested"
+                    >
+                      <Typography variant="caption" color="primary.main" 
display="block" className="card-title">
+                        Requested
+                      </Typography>
+                      <Typography variant="h5" color="primary.main" 
className="card-count">
+                        {requestedCount}
+                      </Typography>
+                    </Box>
+                  </Grid>
+                )}
+
+                {/* 2. Clickable Total Purged Card */}
+                <Grid item xs={isSummaryRow ? 6 : 12} sm={isSummaryRow ? 3 : 
4}>
+                  <Box
+                    onClick={handleOpenPurgedDrawer}
+                    className={`purge-card purge-card-purged 
${totalPurgedCount > 0 ? "clickable" : ""}`}
+                  >
+                    <Typography variant="caption" color="success.main" 
display="block" className="card-title">
+                      PURGED
+                    </Typography>
+                    <Typography variant="h5" color="success.main" 
className="card-count">
+                      {totalPurgedCount}
+                    </Typography>
+                  </Box>
+                </Grid>
+
+                {/* 3 & 4. Display-Only Failed and Skipped Cards */}
+                {isSummaryRow && (
+                  <>
+                    <Grid item xs={6} sm={3}>
+                      <LightTooltip
+                        title={
+                          totalFailedCount > 0 || executionFailed
+                            ? "Some entities failed to purge. Please check 
purgefailure.log for details."
+                            : "No failed entities during this purge operation."
+                        }
+                        arrow
+                        placement="top"
+                      >
+                        <Box
+                          className={`purge-card ${totalFailedCount > 0 ? 
"purge-card-failed" : "purge-card-failed-empty"}`}
+                        >
+                          <Typography variant="caption" 
color={totalFailedCount > 0 ? "error.main" : "textSecondary"} display="block" 
className="card-title">
+                            Failed
+                          </Typography>
+                          <Typography variant="h5" color={totalFailedCount > 0 
? "error.main" : "textPrimary"} className="card-count">
+                            {totalFailedCount}
+                          </Typography>
+                        </Box>
+                      </LightTooltip>
+                    </Grid>
+
+                    {/* 4. Display-Only Skipped Card */}
+                    <Grid item xs={6} sm={3}>
+                      <LightTooltip
+                        title={
+                          skippedCount > 0 || executionFailed
+                            ? "Some entities were skipped during purge. Please 
check purgefailure.log for details."
+                            : "No skipped entities during this purge 
operation."
+                        }
+                        arrow
+                        placement="top"
+                      >
+                        <Box
+                          className={`purge-card ${skippedCount > 0 ? 
"purge-card-skipped" : "purge-card-skipped-empty"}`}
+                        >
+                          <Typography variant="caption" color={skippedCount > 
0 ? "warning.main" : "textSecondary"} display="block" className="card-title">
+                            Skipped
+                          </Typography>
+                          <Typography variant="h5" color={skippedCount > 0 ? 
"warning.main" : "textPrimary"} className="card-count">
+                            {skippedCount}
+                          </Typography>
+                        </Box>
+                      </LightTooltip>
+                    </Grid>
+                  </>
+                )}
+              </Grid>
+            </Box>
           )}
-        </Grid>
-      ) : (
-        operation != "PURGE" &&
-        operation != "AUTO_PURGE" &&
-        operation != "IMPORT" &&
-        operation != "EXPORT" && <Typography>No Results Found</Typography>
-      )}
-
-      {(operation == "PURGE" || operation == "AUTO_PURGE") && 
!isEmpty(resultObj) ? (
-        <>
-          <Typography>{`${category[operation]}`}</Typography>
-          <List className="audit-results-list">
-            {resultObj.map((obj: string) => {
+
+          {/* Right Side Drawer — client-side pagination for both Purged and 
Requested */}
+          <PurgeEntitiesDrawer
+            activePurgeView={activePurgeView}
+            setActivePurgeView={setActivePurgeView}
+            requestedEntitiesList={requestedEntitiesList}
+            purgedApiGuids={purgedApiGuids}
+            drawerSearchText={drawerSearchText}
+            setDrawerSearchText={setDrawerSearchText}
+            drawerPage={drawerPage}
+            setDrawerPage={setDrawerPage}
+            drawerPageSize={drawerPageSize}
+            setDrawerPageSize={setDrawerPageSize}
+            scrollTop={scrollTop}
+            setScrollTop={setScrollTop}
+            runId={runId}
+            copiedRunId={copiedRunId}
+            setCopiedRunId={setCopiedRunId}
+            setOpenPurgeModal={setOpenPurgeModal}
+            setCurrentPurgeResultObj={setCurrentPurgeResultObj}
+            drawerPageSizeInput={drawerPageSizeInput}
+            setDrawerPageSizeInput={setDrawerPageSizeInput}
+          />
+        </Box>
+      ) : null}
+    </>
+  );
+};
+
+
+interface PurgeEntitiesDrawerProps {
+  activePurgeView: PurgeActiveView;
+  setActivePurgeView: (view: PurgeActiveView) => void;
+  requestedEntitiesList: string[];
+  purgedApiGuids: string[];
+  drawerSearchText: string;
+  setDrawerSearchText: (text: string) => void;
+  drawerPage: number;
+  setDrawerPage: React.Dispatch<React.SetStateAction<number>>;
+  drawerPageSize: number;
+  setDrawerPageSize: React.Dispatch<React.SetStateAction<number>>;
+  scrollTop: number;
+  setScrollTop: React.Dispatch<React.SetStateAction<number>>;
+  runId: string;
+  copiedRunId: boolean;
+  setCopiedRunId: (copied: boolean) => void;
+  setOpenPurgeModal: (open: boolean) => void;
+  setCurrentPurgeResultObj: (guid: string) => void;
+  drawerPageSizeInput: string;
+  setDrawerPageSizeInput: (input: string) => void;
+}
+
+const PurgeEntitiesDrawer: React.FC<PurgeEntitiesDrawerProps> = ({
+  activePurgeView,
+  setActivePurgeView,
+  requestedEntitiesList,
+  purgedApiGuids,
+  drawerSearchText,
+  setDrawerSearchText,
+  drawerPage,
+  setDrawerPage,
+  drawerPageSize,
+  setDrawerPageSize,
+  scrollTop,
+  setScrollTop,
+  runId,
+  copiedRunId,
+  setCopiedRunId,
+  setOpenPurgeModal,
+  setCurrentPurgeResultObj,
+  drawerPageSizeInput,
+  setDrawerPageSizeInput,
+}) => {
+  const listRef = useRef<HTMLUListElement | null>(null);
+
+  useEffect(() => {
+    if (listRef.current) {
+      listRef.current.scrollTop = 0;
+    }
+  }, [drawerPage, drawerSearchText, activePurgeView]);
+
+  const rawListForView: (string | Record<string, any>)[] =

Review Comment:
   Still using Record<string, any>. Consider (string | { guid: string; 
attributes?: { name?: string } }) for stricter typing.



##########
dashboard/src/hooks/__tests__/useVirtualization.test.ts:
##########
@@ -0,0 +1,89 @@
+/*

Review Comment:
   Please update PR description to reflect final scope: runId/SUMMARY 
filtering, auditRowKind UI hiding, client-side drawer pagination, and TYPE_DEF 
audit rendering changes.



##########
dashboard/src/views/Administrator/Audits/AuditResults.tsx:
##########
@@ -15,227 +15,716 @@
  * limitations under the License.
  */
 
-import { Grid, Link, List, ListItem, ListItemText, Typography } from 
"@mui/material";
-import { auditAction, category } from "@utils/Enum";
+import { Grid, Link, List, ListItem, ListItemText, Typography, Box, Drawer, 
IconButton, Stack, Tooltip, TextField, InputAdornment, Pagination, 
PaginationItem, Skeleton } from "@mui/material";
+import KeyboardDoubleArrowLeftIcon from 
"@mui/icons-material/KeyboardDoubleArrowLeft";
+import KeyboardDoubleArrowRightIcon from 
"@mui/icons-material/KeyboardDoubleArrowRight";
+import ContentCopyIcon from "@mui/icons-material/ContentCopy";
+import SearchIcon from "@mui/icons-material/Search";
+import { auditAction, category, AuditOperation, PurgeActiveView } from 
"@utils/Enum";
 import { isEmpty, jsonParse } from "@utils/Utils";
+import { useVirtualization } from "@hooks/useVirtualization";
 import CustomModal from "@components/Modal";
 import TypeDefAuditDetailModal from "@components/TypeDefAuditDetailModal";
-import { useState } from "react";
-import { Item } from "@utils/Muiutils";
+import { useRef, useState, useEffect } from "react";
 import AuditsTab from "@views/DetailPage/EntityDetailTabs/AuditsTab";
 import ImportExportAudits from "./ImportExportAudits";
+import { LightTooltip } from "@components/muiComponents";
+import { fetchApi } from "@api/apiMethods/fetchApi";
+import "./AuditResults.scss";
+interface AuditEntry {
+  guid: string;
+  operation: string;
+  params?: string;
+  result?: string;
+  runId?: string;
+  [key: string]: unknown;
+}
 
-const AuditResults = ({ componentProps, row }: any) => {
+interface AuditResultsProps {
+  componentProps?: {
+    auditData?: AuditEntry[];
+  };
+  row: {
+    original: {
+      guid: string;
+      runId?: string;
+      [key: string]: unknown;
+    };
+  };
+}
+
+const AuditResults = ({ componentProps, row }: AuditResultsProps) => {
   const { auditData } = componentProps || {};
   const [openModal, setOpenModal] = useState<boolean>(false);
   const [openPurgeModal, setOpenPurgeModal] = useState<boolean>(false);
-  const [currentResultObj, setCurrentObj] = useState<any>({});
-  const [currentPurgeResultObj, setCurrentPurgeResultObj] = useState<any>("");
+  const [currentResultObj, setCurrentObj] = useState<Record<string, unknown> | 
undefined>();
+  // Stores the guid of the clicked purged entity
+  const [currentPurgeResultObj, setCurrentPurgeResultObj] = useState<string | 
undefined>();
+  const [activePurgeView, setActivePurgeView] = 
useState<PurgeActiveView>(PurgeActiveView.NONE);
+  const [drawerSearchText, setDrawerSearchText] = useState<string>('');
+  const [drawerPage, setDrawerPage] = useState<number>(1);
+  const [drawerPageSize, setDrawerPageSize] = useState<number>(25);
+  const [drawerPageSizeInput, setDrawerPageSizeInput] = useState<string>('25');
+  const [scrollTop, setScrollTop] = useState<number>(0);
+  const [copiedRunId, setCopiedRunId] = useState<boolean>(false);
+  const [purgedApiGuids, setPurgedApiGuids] = useState<string[]>([]);
+  const [summaryData, setSummaryData] = useState<Record<string, unknown> | 
null>(null);
+  const [loadingSummary, setLoadingSummary] = useState<boolean>(false);
+
+
   const handleCloseModal = () => {
     setOpenModal(false);
   };
   const handleClosePurgeModal = () => {
     setOpenPurgeModal(false);
   };
-  const auditObj = !isEmpty(auditData)
-    ? auditData.find((obj: { guid: string }) => obj.guid == row.original.guid)
-    : {};
 
-  const { operation, params, result } = auditObj;
+  const auditObj: AuditEntry | undefined = !isEmpty(auditData)
+    ? (auditData as AuditEntry[]).find((obj) => obj.guid === row.original.guid)
+    : undefined;
+
+  const operation = auditObj?.operation ?? '';
+  const params = auditObj?.params;
+  const result = auditObj?.result;
+
+  let isPurgeOperation = operation === AuditOperation.PURGE || operation === 
AuditOperation.AUTO_PURGE;
+  const summaryGuid = auditObj?.guid ?? row.original.guid;
+
+  useEffect(() => {
+    const controller = new AbortController();
+
+    if (isPurgeOperation && summaryGuid) {
+      setLoadingSummary(true);
+      fetchApi(`/api/atlas/admin/audit/${summaryGuid}/summary`, {
+        method: "GET",
+        headers: { 'Accept': 'application/json', 'Content-Type': 
'application/json' },
+        signal: controller.signal
+      })
+        .then(res => {
+          if (!controller.signal.aborted) {
+            if (res.data && !Array.isArray(res.data) && typeof res.data === 
'object') {
+              setSummaryData(res.data);
+            }
+          }
+        })
+        .catch(err => {
+          if (!controller.signal.aborted && err.name !== 'AbortError' && 
err.name !== 'CanceledError') {
+            console.error("Failed to fetch purge summary", err);
+          }
+        })
+        .finally(() => {
+          if (!controller.signal.aborted) {
+            setLoadingSummary(false);
+          }
+        });
+    }
+
+    return () => {
+      controller.abort();
+    };
+  }, [isPurgeOperation, summaryGuid]);
+
+  let summary: Record<string, unknown> = summaryData || {};
+  let requestedEntitiesList: string[] = [];
+  let legacyPurgedList: string[] = [];
+
+  if (isPurgeOperation) {
+    if (!summaryData) {
+      try {
+        const parsed = typeof result === "string" ? JSON.parse(result) : 
result;
+        if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
+          summary = (parsed as Record<string, unknown>).summary
+            ? (parsed as Record<string, unknown>).summary as Record<string, 
unknown>
+            : parsed as Record<string, unknown>;
+        } else if (Array.isArray(parsed)) {
+          legacyPurgedList = (parsed as unknown[]).map((item) =>
+            typeof item === "string" ? item : (item as { guid?: string }).guid 
|| String(item)
+          );
+        }
+      } catch (_e) {
+        if (typeof result === "string" && !result.startsWith("{")) {
+          legacyPurgedList = result.replace(/^\[|\]$/g, "").split(",").map(s 
=> s.trim()).filter(Boolean);
+        }
+      }
+    } else {
+      if (typeof result === "string" && !result.startsWith("{")) {
+        legacyPurgedList = result.replace(/^\[|\]$/g, "").split(",").map(s => 
s.trim()).filter(Boolean);
+      }
+    }
 
-  const resultObj =
-    (operation == "PURGE" || operation == "AUTO_PURGE")
-      ? result.replace("[", "").replace("]", "").split(",")
-      : jsonParse(result);
+    if (params) {
+      try {
+        const parsedParams = JSON.parse(params);
+        if (Array.isArray(parsedParams)) {
+          requestedEntitiesList = parsedParams as string[];
+        } else if (typeof params === "string") {
+          requestedEntitiesList = params.replace(/^\[|\]$/g, 
"").split(",").map(s => s.trim()).filter(Boolean);
+        }
+      } catch (_e) {
+        requestedEntitiesList = typeof params === "string"
+          ? params.replace(/^\[|\]$/g, "").split(",").map(s => 
s.trim()).filter(Boolean)
+          : [];
+      }
+    }
+  } else {
+    try {
+      summary = jsonParse(result) as Record<string, unknown>;
+    } catch (_e) {
+      summary = {};
+    }
+  }
+
+  const runId = (row.original.runId as string | undefined)
+    ?? (summary?.runId as string | undefined)
+    ?? (auditObj?.runId as string | undefined)
+    ?? 'N/A';
+
+  const isSummaryRow = (runId !== 'N/A') && isPurgeOperation;
+
+
+  const requestedCount = (summary?.requestedCount as number | undefined) ?? 
requestedEntitiesList.length;
+  const purgedCount = (summary?.purgedCount as number | undefined) ?? 
legacyPurgedList.length;
+  const purgedDependenciesCount = (summary?.purgedDependenciesCount as number 
| undefined) ?? 0;
+  const totalPurgedCount = (purgedCount as number) + (purgedDependenciesCount 
as number);
+  const failedCount = (summary?.failedCount as number | undefined) ?? 0;
+  const failedDependenciesCount = (summary?.failedDependenciesCount as number 
| undefined) ?? 0;
+  const totalFailedCount = failedCount + failedDependenciesCount;
+  const skippedCount = (summary?.skippedCount as number | undefined) ?? 0;
+  const executionFailed = (summary?.executionFailed as boolean | undefined) || 
(totalFailedCount) > 0;
+
+  const handleOpenPurgedDrawer = () => {
+    if (totalPurgedCount === 0) return;
+    setActivePurgeView(PurgeActiveView.PURGED);
+    setDrawerPage(1);
+    setScrollTop(0);
+    // As requested, Total Purged simply uses the raw `result` object string 
(legacyPurgedList)
+    setPurgedApiGuids(legacyPurgedList);
+  };
 
   return (
     <>
-      {operation != "PURGE" &&
-        operation != "AUTO_PURGE" &&
-        operation != "IMPORT" &&
-        operation != "EXPORT" &&
-        !isEmpty(resultObj) ? (
-        <Grid container spacing={2}>
-          {params.split(",").length > 1 ? (
-            <>
-              {params.split(",")?.map((param: { param: string }) => {
-                return (
-                  <Grid item md={4}>
-                    <Item
-                      sx={{
-                        height: "100%",
-                        maxHeight: "300px",
-                        overflow: "auto",
-                      }}
-                    >
-                      <Typography
-                        sx={{ padding: "1rem 0 0 1rem", textAlign: "left" }}
-                      >{`${category[param as any]} ${auditAction[operation]
-                        }`}</Typography>
-
-                      <List className="audit-results-list">
-                        {resultObj[param as any].map(
-                          (obj: { name: string }) => {
-                            const { name } = obj;
-                            return (
-                              <>
-                                <ListItem className="audit-results-list-item">
-                                  <Link
-                                    className="audit-results-entityid"
-                                    component="button"
-                                    variant="body2"
-                                    onClick={() => {
-                                      setOpenModal(true);
-                                      setCurrentObj(obj);
-                                    }}
-                                    title={name}
-                                    sx={{
-                                      display: "inline-block",
-                                      maxWidth: "100%",
-                                      textOverflow: "ellipsis",
-                                      overflow: "hidden",
-                                      whiteSpace: "nowrap",
-                                      textAlign: "left",
-                                      verticalAlign: "bottom"
-                                    }}
-                                  >
-                                    {name}
-                                  </Link>
-                                </ListItem>
-                              </>
-                            );
-                          }
-                        )}
-                      </List>
-                    </Item>
-                  </Grid>
-                );
-              })}
-            </>
-          ) : (
-            <>
-              <Grid item md={4}>
-                <Item
-                  sx={{
-                    height: "100%",
-                    maxHeight: "300px",
-                    overflow: "auto",
-                  }}
-                >
-                  <Typography
-                    sx={{ padding: "1rem 0 0 1rem", textAlign: "left" }}
-                  >{`${category[params as any]} ${auditAction[operation]
-                    }`}</Typography>
-                  <List className="audit-results-list">
-                    {resultObj[params].map((obj: { name: string }) => {
-                      const { name } = obj;
-                      return (
-                        <>
-                          <ListItem className="audit-results-list-item">
+      <TypeDefAuditDetailModal
+        open={openModal}
+        onClose={handleCloseModal}
+        detailObject={currentResultObj ?? null}
+        maxWidth="md"
+      />
+
+      <CustomModal
+        open={openPurgeModal}
+        onClose={handleClosePurgeModal}
+        title={`Purged Entity Details: ${currentPurgeResultObj}`}
+        button1Handler={undefined}
+        button2Handler={undefined}
+        maxWidth="md"
+        footer={false}
+      >
+        <AuditsTab auditResultGuid={currentPurgeResultObj} />
+      </CustomModal>
+
+      {operation === "TYPE_DEF_CREATE" ||
+        operation === "TYPE_DEF_UPDATE" ||
+        operation === "TYPE_DEF_DELETE" ? (
+        <List className="audit-results-list">
+          {summary &&
+            Object.keys(summary).map((key: string) => {
+              const rawItems = summary[key];
+              const items: Array<Record<string, unknown> | string> = 
Array.isArray(rawItems)
+                ? (rawItems as Array<Record<string, unknown> | string>)
+                : [];
+              return (
+                <div key={key}>
+                  <Typography className="audit-list-header">
+                    {`${category[key as keyof typeof category] || key} 
${auditAction[operation as keyof typeof auditAction] || operation}`}
+                  </Typography>
+                  {items.map((obj: Record<string, unknown> | string, idx: 
number) => {
+                    const name = typeof obj === 'object' && obj !== null
+                      ? (obj.name as string) || String(obj)
+                      : String(obj);
+                    return (
+                      <ListItem key={name + idx} 
className="audit-results-list-item">
+                        <ListItemText
+                          primary={
                             <Link
-                              className="audit-results-entityid"
+                              className="audit-results-entityid 
audit-list-link"
                               component="button"
                               variant="body2"
                               onClick={() => {
                                 setOpenModal(true);
-                                setCurrentObj(obj);
+                                setCurrentObj(typeof obj === "object" ? obj : 
{ name: obj });
                               }}
                               title={name}
-                              sx={{
-                                display: "inline-block",
-                                maxWidth: "100%",
-                                textOverflow: "ellipsis",
-                                overflow: "hidden",
-                                whiteSpace: "nowrap",
-                                textAlign: "left",
-                                verticalAlign: "bottom"
-                              }}
                             >
                               {name}
                             </Link>
-                          </ListItem>
-                        </>
-                      );
-                    })}
-                  </List>
-                </Item>
+                          }
+                        />
+                      </ListItem>
+                    );
+                  })}
+                </div>
+              );
+            })}
+        </List>
+      ) : operation === "IMPORT" || operation === "EXPORT" ? (
+        <ImportExportAudits auditObj={auditObj} />
+      ) : !isPurgeOperation ? (
+        <Typography>No Results Found</Typography>
+      ) : null}
+
+      {/* Purge Audit View */}
+      {isPurgeOperation ? (
+        <Box className="purge-audit-view">
+          {loadingSummary && Object.keys(summary).length === 0 && 
legacyPurgedList.length === 0 && !result ? (
+            <Box sx={{ p: 2 }}>
+              <Skeleton variant="text" width="40%" height={30} sx={{ mb: 2 }} 
/>
+              <Grid container spacing={2}>
+                <Grid item xs={6} sm={3}><Skeleton variant="rectangular" 
height={70} sx={{ borderRadius: 1 }} /></Grid>
+                <Grid item xs={6} sm={3}><Skeleton variant="rectangular" 
height={70} sx={{ borderRadius: 1 }} /></Grid>
+                <Grid item xs={6} sm={3}><Skeleton variant="rectangular" 
height={70} sx={{ borderRadius: 1 }} /></Grid>
+                <Grid item xs={6} sm={3}><Skeleton variant="rectangular" 
height={70} sx={{ borderRadius: 1 }} /></Grid>
               </Grid>
-            </>
+            </Box>
+          ) : (
+            <Box className="purge-summary-container">
+
+              {/* Run Id Header with Copy Action */}
+              {runId !== 'N/A' && (
+                <Box className="purge-runid-header">
+                  <Typography variant="body2" color="textSecondary" 
className="runid-text">
+                    <strong>Run Id:</strong> {runId}
+                  </Typography>
+                  <Tooltip title={copiedRunId ? "Copied!" : "Copy Run Id"}>
+                    <IconButton
+                      size="small"
+                      onClick={() => {
+                        if (navigator.clipboard) {
+                          navigator.clipboard.writeText(runId);
+                        } else {
+                          const textField = document.createElement('textarea');
+                          textField.innerText = runId;
+                          document.body.appendChild(textField);
+                          textField.select();
+                          document.execCommand('copy');
+                          textField.remove();
+                        }
+                        setCopiedRunId(true);
+                        setTimeout(() => setCopiedRunId(false), 2000);
+                      }}
+                      className="purge-runid-copy"
+                    >
+                      <ContentCopyIcon className={`copy-icon ${copiedRunId ? 
"copied" : ""}`} />
+                    </IconButton>
+                  </Tooltip>
+                </Box>
+              )}
+
+              {/* 4 Cards Grid: Requested, Total Purged, Failed (Display 
Only), Skipped (Display Only) */}
+              <Grid container spacing={2}>
+                {/* 1. Clickable Requested Card */}
+                {isSummaryRow && (
+                  <Grid item xs={6} sm={3}>
+                    <Box
+                      onClick={() => {
+                        setActivePurgeView(PurgeActiveView.REQUESTED);
+                        setDrawerPage(1);
+                        setScrollTop(0);
+                      }}
+                      className="purge-card purge-card-requested"
+                    >
+                      <Typography variant="caption" color="primary.main" 
display="block" className="card-title">
+                        Requested
+                      </Typography>
+                      <Typography variant="h5" color="primary.main" 
className="card-count">
+                        {requestedCount}
+                      </Typography>
+                    </Box>
+                  </Grid>
+                )}
+
+                {/* 2. Clickable Total Purged Card */}
+                <Grid item xs={isSummaryRow ? 6 : 12} sm={isSummaryRow ? 3 : 
4}>
+                  <Box
+                    onClick={handleOpenPurgedDrawer}
+                    className={`purge-card purge-card-purged 
${totalPurgedCount > 0 ? "clickable" : ""}`}
+                  >
+                    <Typography variant="caption" color="success.main" 
display="block" className="card-title">
+                      PURGED
+                    </Typography>
+                    <Typography variant="h5" color="success.main" 
className="card-count">
+                      {totalPurgedCount}
+                    </Typography>
+                  </Box>
+                </Grid>
+
+                {/* 3 & 4. Display-Only Failed and Skipped Cards */}
+                {isSummaryRow && (
+                  <>
+                    <Grid item xs={6} sm={3}>
+                      <LightTooltip
+                        title={
+                          totalFailedCount > 0 || executionFailed
+                            ? "Some entities failed to purge. Please check 
purgefailure.log for details."
+                            : "No failed entities during this purge operation."
+                        }
+                        arrow
+                        placement="top"
+                      >
+                        <Box
+                          className={`purge-card ${totalFailedCount > 0 ? 
"purge-card-failed" : "purge-card-failed-empty"}`}
+                        >
+                          <Typography variant="caption" 
color={totalFailedCount > 0 ? "error.main" : "textSecondary"} display="block" 
className="card-title">
+                            Failed
+                          </Typography>
+                          <Typography variant="h5" color={totalFailedCount > 0 
? "error.main" : "textPrimary"} className="card-count">
+                            {totalFailedCount}
+                          </Typography>
+                        </Box>
+                      </LightTooltip>
+                    </Grid>
+
+                    {/* 4. Display-Only Skipped Card */}
+                    <Grid item xs={6} sm={3}>
+                      <LightTooltip
+                        title={
+                          skippedCount > 0 || executionFailed
+                            ? "Some entities were skipped during purge. Please 
check purgefailure.log for details."
+                            : "No skipped entities during this purge 
operation."
+                        }
+                        arrow
+                        placement="top"
+                      >
+                        <Box
+                          className={`purge-card ${skippedCount > 0 ? 
"purge-card-skipped" : "purge-card-skipped-empty"}`}
+                        >
+                          <Typography variant="caption" color={skippedCount > 
0 ? "warning.main" : "textSecondary"} display="block" className="card-title">
+                            Skipped
+                          </Typography>
+                          <Typography variant="h5" color={skippedCount > 0 ? 
"warning.main" : "textPrimary"} className="card-count">
+                            {skippedCount}
+                          </Typography>
+                        </Box>
+                      </LightTooltip>
+                    </Grid>
+                  </>
+                )}
+              </Grid>
+            </Box>
           )}
-        </Grid>
-      ) : (
-        operation != "PURGE" &&
-        operation != "AUTO_PURGE" &&
-        operation != "IMPORT" &&
-        operation != "EXPORT" && <Typography>No Results Found</Typography>
-      )}
-
-      {(operation == "PURGE" || operation == "AUTO_PURGE") && 
!isEmpty(resultObj) ? (
-        <>
-          <Typography>{`${category[operation]}`}</Typography>
-          <List className="audit-results-list">
-            {resultObj.map((obj: string) => {
+
+          {/* Right Side Drawer — client-side pagination for both Purged and 
Requested */}
+          <PurgeEntitiesDrawer
+            activePurgeView={activePurgeView}
+            setActivePurgeView={setActivePurgeView}
+            requestedEntitiesList={requestedEntitiesList}
+            purgedApiGuids={purgedApiGuids}
+            drawerSearchText={drawerSearchText}
+            setDrawerSearchText={setDrawerSearchText}
+            drawerPage={drawerPage}
+            setDrawerPage={setDrawerPage}
+            drawerPageSize={drawerPageSize}
+            setDrawerPageSize={setDrawerPageSize}
+            scrollTop={scrollTop}
+            setScrollTop={setScrollTop}
+            runId={runId}
+            copiedRunId={copiedRunId}
+            setCopiedRunId={setCopiedRunId}
+            setOpenPurgeModal={setOpenPurgeModal}
+            setCurrentPurgeResultObj={setCurrentPurgeResultObj}
+            drawerPageSizeInput={drawerPageSizeInput}
+            setDrawerPageSizeInput={setDrawerPageSizeInput}
+          />
+        </Box>
+      ) : null}
+    </>
+  );
+};
+
+
+interface PurgeEntitiesDrawerProps {
+  activePurgeView: PurgeActiveView;
+  setActivePurgeView: (view: PurgeActiveView) => void;
+  requestedEntitiesList: string[];
+  purgedApiGuids: string[];
+  drawerSearchText: string;
+  setDrawerSearchText: (text: string) => void;
+  drawerPage: number;
+  setDrawerPage: React.Dispatch<React.SetStateAction<number>>;
+  drawerPageSize: number;
+  setDrawerPageSize: React.Dispatch<React.SetStateAction<number>>;
+  scrollTop: number;
+  setScrollTop: React.Dispatch<React.SetStateAction<number>>;
+  runId: string;
+  copiedRunId: boolean;
+  setCopiedRunId: (copied: boolean) => void;
+  setOpenPurgeModal: (open: boolean) => void;
+  setCurrentPurgeResultObj: (guid: string) => void;
+  drawerPageSizeInput: string;
+  setDrawerPageSizeInput: (input: string) => void;
+}
+
+const PurgeEntitiesDrawer: React.FC<PurgeEntitiesDrawerProps> = ({
+  activePurgeView,
+  setActivePurgeView,
+  requestedEntitiesList,
+  purgedApiGuids,
+  drawerSearchText,
+  setDrawerSearchText,
+  drawerPage,
+  setDrawerPage,
+  drawerPageSize,
+  setDrawerPageSize,
+  scrollTop,
+  setScrollTop,
+  runId,
+  copiedRunId,
+  setCopiedRunId,
+  setOpenPurgeModal,
+  setCurrentPurgeResultObj,
+  drawerPageSizeInput,
+  setDrawerPageSizeInput,
+}) => {
+  const listRef = useRef<HTMLUListElement | null>(null);
+
+  useEffect(() => {
+    if (listRef.current) {
+      listRef.current.scrollTop = 0;
+    }
+  }, [drawerPage, drawerSearchText, activePurgeView]);
+
+  const rawListForView: (string | Record<string, any>)[] =
+    activePurgeView === PurgeActiveView.REQUESTED ? requestedEntitiesList : 
purgedApiGuids;
+
+  const filteredList = rawListForView.filter((item: string | Record<string, 
any>) => {
+    if (!drawerSearchText) return true;
+    const guidStr = typeof item === 'object' && item !== null ? item.guid : 
item;
+    const nameStr = typeof item === 'object' && item !== null ? 
item.attributes?.name : '';
+    const searchLower = drawerSearchText.trim().toLowerCase();
+    return (guidStr && guidStr.toLowerCase().includes(searchLower)) ||
+      (nameStr && nameStr.toLowerCase().includes(searchLower));
+  });
+
+  const displayItems = filteredList.slice((drawerPage - 1) * drawerPageSize, 
drawerPage * drawerPageSize);
+
+  const { visibleItems, paddingTop, paddingBottom, startIndex } = 
useVirtualization({
+    items: displayItems,
+    scrollTop,
+    itemHeight: 24
+  });
+
+  const displayTotal = filteredList.length;
+
+  const handleDrawerScroll = (e: React.UIEvent<HTMLUListElement>) => {
+    setScrollTop(e.currentTarget.scrollTop);
+  };
+
+  return (
+    <Drawer
+      anchor="right"
+      open={activePurgeView !== PurgeActiveView.NONE}
+      onClose={() => {
+        setActivePurgeView(PurgeActiveView.NONE);
+        setDrawerSearchText('');
+        setDrawerPage(1);
+        setScrollTop(0);
+      }}
+      PaperProps={{ className: "drawer-paper" }}
+    >
+      <Box className="drawer-content-wrapper">
+        <Stack direction="row" justifyContent="space-between" 
alignItems="center" className="drawer-search-container">
+          <Typography className="drawer-title">
+            {activePurgeView === PurgeActiveView.REQUESTED ? 'Requested 
Entities' : 'Purged Entities'}
+          </Typography>
+          <IconButton
+            aria-label="Close drawer"
+            onClick={() => {
+              setActivePurgeView(PurgeActiveView.NONE);
+              setDrawerSearchText('');
+              setDrawerPage(1);
+              setScrollTop(0);
+            }}
+            size="small"
+          >
+            ✕
+          </IconButton>
+        </Stack>
+
+        {runId !== 'N/A' && (
+          <Box className="drawer-runid-container">
+            <Typography variant="caption" color="textSecondary" 
className="drawer-runid-text">
+              <strong>Run Id:</strong> {runId}
+            </Typography>
+            <Tooltip title={copiedRunId ? "Copied!" : "Copy Run Id"}>
+              <IconButton
+                size="small"
+                onClick={() => {
+                  if (navigator.clipboard) {
+                    navigator.clipboard.writeText(runId);
+                  } else {
+                    const textField = document.createElement('textarea');
+                    textField.innerText = runId;
+                    document.body.appendChild(textField);
+                    textField.select();
+                    document.execCommand('copy');
+                    textField.remove();
+                  }
+                  setCopiedRunId(true);
+                  setTimeout(() => setCopiedRunId(false), 2000);
+                }}
+                className="drawer-copy-btn"
+              >
+                <ContentCopyIcon className={`drawer-copy-icon ${copiedRunId ? 
"copied" : ""}`} />
+              </IconButton>
+            </Tooltip>
+          </Box>
+        )}
+
+        {(activePurgeView === PurgeActiveView.REQUESTED ? 
requestedEntitiesList.length > 0 : purgedApiGuids.length > 0) && (
+          <Box className="drawer-search-container">
+            <TextField
+              fullWidth
+              size="small"
+              variant="standard"
+              placeholder="Search GUIDs..."
+              value={drawerSearchText}
+              onChange={(e) => {
+                setDrawerSearchText(e.target.value);
+                setDrawerPage(1);
+                setScrollTop(0);
+              }}
+              InputProps={{
+                disableUnderline: true,
+                startAdornment: (
+                  <InputAdornment position="start">
+                    <SearchIcon className="drawer-search-icon" />
+                  </InputAdornment>
+                ),
+                endAdornment: drawerSearchText ? (
+                  <InputAdornment position="end">
+                    <IconButton size="small" onClick={() => {
+                      setDrawerSearchText('');
+                      setDrawerPage(1);
+                      setScrollTop(0);
+                    }}>
+                      ✕
+                    </IconButton>
+                  </InputAdornment>
+                ) : null
+              }}
+              className="drawer-search-input"
+            />
+          </Box>
+        )}
+
+
+
+        <List dense className="drawer-list-container" 
onScroll={handleDrawerScroll} onWheel={handleDrawerScroll} ref={listRef}>
+          {(() => {
+            if (displayItems.length === 0) {
               return (
-                <ListItem className="audit-results-list-item">
-                  <ListItemText
-                    primary={
+                <Typography variant="body2" color="textSecondary" 
className="drawer-list-empty">
+                  {activePurgeView === PurgeActiveView.PURGED && 
purgedApiGuids.length === 0 && !drawerSearchText
+                    ? "Entity list not available for summary audits — see 
purgefailure.log"

Review Comment:
    Important — Missing test for summary empty-drawer message
   
   Please add a test: summary row with non-zero PURGED count but empty GUID 
list → click PURGED card → assert "Entity list not available for summary audits 
— see purgefailure.log". Same for Classic DrawerView.js line ~4715 if feasible.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to