You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by pp...@apache.org on 2026/05/10 15:01:54 UTC

(atlas) branch master updated: ATLAS-5246: ATLAS UI: Dashboard Overview - React UI Dashboard Implementation (#626)

This is an automated email from the ASF dual-hosted git repository.

pawarprasad123 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/atlas.git


The following commit(s) were added to refs/heads/master by this push:
     new 874180f5e ATLAS-5246: ATLAS UI: Dashboard Overview - React UI Dashboard Implementation (#626)
874180f5e is described below

commit 874180f5edccb7992ede23f726e1b652c46dccd7
Author: Prasad Pawar <49...@users.noreply.github.com>
AuthorDate: Sun May 10 20:31:48 2026 +0530

    ATLAS-5246: ATLAS UI: Dashboard Overview - React UI Dashboard Implementation (#626)
    
    * ATLAS-5286: ATLAS UI: Dashboard - Filter query and  shared view helpers changes (#615)
    
    * ATLAS-5287: ATLAS UI: Dashboard- search bar with dropdown (#616)
    
    * ATLAS-5267: ATLAS UI: Create Glossary: Add Import glossary terms tab (template + upload) (#617)
    
    * ATLAS-5256: ATLAS UI: Header - Create Button and Dropdown Menu. (#618)
    
    * ATLAS-5256: ATLAS UI: Header - Create Button and Dropdown Menu
    
    * ATLAS-5256: ATLAS UI: Header - Create Button and Dropdown Menu
    
    * ATLAS-5251: ATLAS UI : Dashboard - Latest Entities List (#619)
    
    * ATLAS-5247, ATLAS-5248, ATLAS-5249, ATLAS-5250, ATLAS-5252, ATLAS-5254, ATLAS-5255: ATLAS UI: Dashboard All cards. (#620)
    
    * ATLAS-5288: ATLAS UI: Dashboard - Classification and Admin Audits (#621)
    
    * ATLAS-5246: ATLAS UI: Dashboard Overview - React UI Dashboard Implementation
---
 dashboard/src/api/apiMethods/searchApiMethod.ts    |   62 +-
 .../components/CreateDropdown/CreateDropdown.tsx   |  176 +++
 dashboard/src/components/CreateDropdown/index.ts   |   18 +
 dashboard/src/components/FilterQuery.tsx           |  197 +++-
 .../src/components/GlobalSearch/QuickSearch.tsx    | 1185 ++++++++++++--------
 dashboard/src/components/ImportDialog.tsx          |   44 +-
 dashboard/src/components/QueryBuilder/Filters.tsx  |  123 +-
 .../src/components/ShowMore/DrawerBodyChipView.tsx |    1 +
 dashboard/src/components/ShowMore/ShowMoreView.tsx |    3 +
 dashboard/src/components/Table/TablePagination.tsx |  120 +-
 dashboard/src/components/TreeNodeIcons.tsx         |   42 +-
 .../src/components/TypeDefAuditDetailModal.tsx     |  108 ++
 dashboard/src/utils/CommonViewFunction.ts          |   17 +-
 dashboard/src/utils/Enum.ts                        |    9 +
 dashboard/src/utils/apiErrorToastMessage.ts        |   43 +
 dashboard/src/utils/auditTypeDefUtils.ts           |   90 ++
 dashboard/src/utils/dashboardSearchUtils.ts        |  189 ++++
 dashboard/src/utils/filterUrlCriterionRemoval.ts   |   81 ++
 dashboard/src/utils/glossaryImportFlow.ts          |   57 +
 dashboard/src/utils/metricsUtils.ts                |  241 ++++
 dashboard/src/utils/scopedQuickSearchUtils.ts      |  466 ++++++++
 dashboard/src/utils/typeCatalogUtils.ts            |  159 +++
 .../views/Administrator/AdministratorLayout.tsx    |   22 +-
 .../views/Administrator/Audits/AuditResults.tsx    |   78 +-
 .../BusinessMetadataAtrributeForm.tsx              |    1 +
 .../BusinessMetadata/BusinessMetadataForm.tsx      |    2 +
 dashboard/src/views/Classification/AddTag.tsx      |    1 +
 .../src/views/Classification/AddTagAttributes.tsx  |    1 +
 .../views/Classification/ClassificationForm.tsx    |    5 +-
 dashboard/src/views/Classification/DeleteTag.tsx   |    1 +
 dashboard/src/views/DashBoard.tsx                  |   83 +-
 .../DashboardOverview/ClassificationCoverage.tsx   |  394 +++++++
 .../ClassificationDistributionCard.tsx             |  227 ++++
 .../views/DashboardOverview/DashboardOverview.tsx  |  149 +++
 .../views/DashboardOverview/DashboardSkeleton.tsx  |   39 +
 .../views/DashboardOverview/EntityStatusDonut.tsx  |  173 +++
 .../views/DashboardOverview/EntityTypeBarChart.tsx |  327 ++++++
 .../EntityTypeBarChartSkeleton.tsx                 |   57 +
 .../DashboardOverview/KafkaTopicSummaryCard.tsx    |  402 +++++++
 .../views/DashboardOverview/LatestEntitiesList.tsx |  273 +++++
 .../DashboardOverview/LatestEntitiesSkeleton.tsx   |   53 +
 .../DashboardOverview/MessageConsumptionChart.tsx  |  257 +++++
 .../src/views/DashboardOverview/OverviewCard.tsx   |  114 ++
 .../src/views/DashboardOverview/RecentActivity.tsx |  408 +++++++
 .../DashboardOverview/RecentActivitySkeleton.tsx   |   37 +
 .../DashboardOverview/dashboardChartPalette.ts     |   42 +
 .../DashboardOverview/latestEntitiesList.utils.ts  |   64 ++
 .../BusinessMetadataDetailsLayout.tsx              |    2 +
 .../EntityDetailTabs/ClassificationsTab.tsx        |    6 +
 .../EntityDetailTabs/PropagationPropertyModal.tsx  |    1 +
 .../DetailPage/GlossaryDetails/TermRelation.tsx    |    1 +
 dashboard/src/views/Entity/EntityForm.tsx          |    1 +
 .../src/views/Glossary/AddUpdateCategoryForm.tsx   |    1 +
 .../src/views/Glossary/AddUpdateGlossaryForm.tsx   |  450 ++++++--
 dashboard/src/views/Glossary/AddUpdateTermForm.tsx |    1 +
 dashboard/src/views/Glossary/AssignCategory.tsx    |    1 +
 dashboard/src/views/Glossary/AssignTerm.tsx        |    1 +
 dashboard/src/views/Glossary/DeleteGlossary.tsx    |   52 +-
 dashboard/src/views/SaveFilters/SaveFilters.tsx    |    1 +
 dashboard/src/views/SearchResult/SearchResult.tsx  |   24 +-
 .../src/views/SideBar/SideBarTree/SideBarTree.tsx  |   23 +-
 dashboard/src/views/Statistics/ServerStats.tsx     |    7 +-
 dashboard/src/views/Statistics/Statistics.tsx      |   45 +-
 63 files changed, 6330 insertions(+), 928 deletions(-)

diff --git a/dashboard/src/api/apiMethods/searchApiMethod.ts b/dashboard/src/api/apiMethods/searchApiMethod.ts
index 11a061e4f..8cc58f041 100644
--- a/dashboard/src/api/apiMethods/searchApiMethod.ts
+++ b/dashboard/src/api/apiMethods/searchApiMethod.ts
@@ -56,10 +56,62 @@ const getRelationShipV2 = (params: { params: Record<string, unknown> }) => {
   return fetchApi(url, { method: "GET" });
 };
 
+/** Atlas `SearchParameters.sortBy` / `sortOrder` (see `SortOrder` enum: DESCENDING). */
+const LATEST_ENTITIES_TIMESTAMP_SORT = "__timestamp" as const;
+
+type LatestEntitiesSearchOptions = {
+  limit: number;
+  includeSubClassifications: boolean;
+};
+
+/**
+ * Request `__timestamp` so sort + “Created … ago” work. Do not set
+ * `excludeHeaderAttributes`: for `_ALL_ENTITY_TYPES`, Atlas validates each
+ * `attributes` entry against `__ENTITY_ROOT` and rejects `name` / `qualifiedName`
+ * / `guid` (see `excludeHeaderAttributesAllEntityType` in Atlas tests). Normal
+ * headers then include name, guid, typeName like the main basic search.
+ */
+const buildLatestEntitiesBasicBody = (opts: LatestEntitiesSearchOptions) => {
+  return {
+    typeName: "_ALL_ENTITY_TYPES",
+    excludeDeletedEntities: true,
+    includeClassificationAttributes: true,
+    includeSubTypes: true,
+    includeSubClassifications: opts.includeSubClassifications,
+    limit: opts.limit,
+    offset: 0,
+    tagFilters: null,
+    entityFilters: null,
+    classification: null,
+    termName: null,
+    relationshipFilters: null,
+    attributes: ["__timestamp"],
+    sortBy: LATEST_ENTITIES_TIMESTAMP_SORT,
+    sortOrder: "DESCENDING",
+  };
+};
+
+/**
+ * Dashboard card only: newest entities by `__timestamp`, no entity filters,
+ * sub-classifications off, full entity headers for name/guid/type.
+ */
+const getLatestEntities = () => {
+  return getBasicSearchResult(
+    {
+      data: buildLatestEntitiesBasicBody({
+        limit: 7,
+        includeSubClassifications: false,
+      }),
+    },
+    "basic"
+  );
+};
+
 export {
-  getBasicSearchResult,
-  getRelationShipResult,
-  getGlobalSearchResult,
-  getRelationShip,
-  getRelationShipV2
+	getBasicSearchResult,
+	getRelationShipResult,
+	getGlobalSearchResult,
+	getRelationShip,
+	getRelationShipV2,
+	getLatestEntities
 };
diff --git a/dashboard/src/components/CreateDropdown/CreateDropdown.tsx b/dashboard/src/components/CreateDropdown/CreateDropdown.tsx
new file mode 100644
index 000000000..cb32d4e2a
--- /dev/null
+++ b/dashboard/src/components/CreateDropdown/CreateDropdown.tsx
@@ -0,0 +1,176 @@
+/*
+ * 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.
+ */
+
+import { useState, useCallback } from "react";
+import { Button, Menu, MenuItem } from "@mui/material";
+import AddIcon from "@mui/icons-material/Add";
+import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
+import CategoryIcon from "@mui/icons-material/Category";
+import LocalOfferIcon from "@mui/icons-material/LocalOffer";
+import MenuBookIcon from "@mui/icons-material/MenuBook";
+import BusinessCenterIcon from "@mui/icons-material/BusinessCenter";
+import ListIcon from "@mui/icons-material/List";
+import { useNavigate } from "react-router-dom";
+import EntityForm from "@views/Entity/EntityForm";
+import ClassificationForm from "@views/Classification/ClassificationForm";
+import AddUpdateGlossaryForm from "@views/Glossary/AddUpdateGlossaryForm";
+const CreateDropdown = () => {
+	const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
+	const [entityModal, setEntityModal] = useState(false);
+	const [classificationModal, setClassificationModal] = useState(false);
+	const [glossaryModal, setGlossaryModal] = useState(false);
+	const navigate = useNavigate();
+
+	const open = Boolean(anchorEl);
+
+	const handleClick = useCallback((event: React.MouseEvent<HTMLElement>) => {
+		setAnchorEl(event.currentTarget);
+	}, []);
+
+	const handleClose = useCallback(() => {
+		setAnchorEl(null);
+	}, []);
+
+	const handleEntityClick = useCallback(() => {
+		handleClose();
+		setEntityModal(true);
+	}, [handleClose]);
+
+	const handleClassificationClick = useCallback(() => {
+		handleClose();
+		setClassificationModal(true);
+	}, [handleClose]);
+
+	const handleGlossaryClick = useCallback(() => {
+		handleClose();
+		setGlossaryModal(true);
+	}, [handleClose]);
+
+	const handleBusinessMetadataClick = useCallback(() => {
+		handleClose();
+		navigate({
+			pathname: "/administrator",
+			search: "tabActive=businessMetadata&create=true"
+		});
+	}, [handleClose, navigate]);
+
+	const handleEnumClick = useCallback(() => {
+		handleClose();
+		navigate({
+			pathname: "/administrator",
+			search: "tabActive=enum"
+		});
+	}, [handleClose, navigate]);
+
+	return (
+		<>
+			<Button
+				variant="contained"
+				color="primary"
+				size="small"
+				onClick={handleClick}
+				endIcon={<ExpandMoreIcon />}
+				startIcon={<AddIcon />}
+				aria-controls={open ? "create-menu" : undefined}
+				aria-haspopup="true"
+				aria-expanded={open ? "true" : undefined}
+				data-cy="create-dropdown"
+			>
+				Create
+			</Button>
+			<Menu
+				id="create-menu"
+				anchorEl={anchorEl}
+				open={open}
+				onClose={handleClose}
+				anchorOrigin={{ horizontal: "left", vertical: "bottom" }}
+				transformOrigin={{ horizontal: "left", vertical: "top" }}
+				slotProps={{
+					paper: {
+						elevation: 2,
+						sx: { mt: 1.5, minWidth: 200 }
+					}
+				}}
+			>
+				<MenuItem
+					onClick={handleEntityClick}
+					data-cy="create-entity"
+					sx={{ gap: 1.5 }}
+				>
+					<CategoryIcon fontSize="small" />
+					Entity
+				</MenuItem>
+				<MenuItem
+					onClick={handleClassificationClick}
+					data-cy="create-classification"
+					sx={{ gap: 1.5 }}
+				>
+					<LocalOfferIcon fontSize="small" />
+					Classification
+				</MenuItem>
+				<MenuItem
+					onClick={handleGlossaryClick}
+					data-cy="create-glossary"
+					sx={{ gap: 1.5 }}
+				>
+					<MenuBookIcon fontSize="small" />
+					Glossary
+				</MenuItem>
+				<MenuItem
+					onClick={handleBusinessMetadataClick}
+					data-cy="create-business-metadata"
+					sx={{ gap: 1.5 }}
+				>
+					<BusinessCenterIcon fontSize="small" />
+					Business Metadata
+				</MenuItem>
+				<MenuItem
+					onClick={handleEnumClick}
+					data-cy="create-enum"
+					sx={{ gap: 1.5 }}
+				>
+					<ListIcon fontSize="small" />
+					Enum
+				</MenuItem>
+			</Menu>
+
+			{entityModal && (
+				<EntityForm
+					open={entityModal}
+					onClose={() => setEntityModal(false)}
+				/>
+			)}
+			{classificationModal && (
+				<ClassificationForm
+					open={classificationModal}
+					isAdd={true}
+					onClose={() => setClassificationModal(false)}
+				/>
+			)}
+			{glossaryModal && (
+				<AddUpdateGlossaryForm
+					open={glossaryModal}
+					isAdd={true}
+					onClose={() => setGlossaryModal(false)}
+					node={undefined}
+				/>
+			)}
+		</>
+	);
+};
+
+export default CreateDropdown;
diff --git a/dashboard/src/components/CreateDropdown/index.ts b/dashboard/src/components/CreateDropdown/index.ts
new file mode 100644
index 000000000..8f1e1ff80
--- /dev/null
+++ b/dashboard/src/components/CreateDropdown/index.ts
@@ -0,0 +1,18 @@
+/*
+ * 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.
+ */
+
+export { default } from "./CreateDropdown";
diff --git a/dashboard/src/components/FilterQuery.tsx b/dashboard/src/components/FilterQuery.tsx
index 69ef98fd2..20351c33a 100644
--- a/dashboard/src/components/FilterQuery.tsx
+++ b/dashboard/src/components/FilterQuery.tsx
@@ -22,8 +22,12 @@ import { attributeFilter } from "@utils/CommonViewFunction";
 import {
   queryBuilderDateRangeUIValueToAPI,
   systemAttributes,
-  filterQueryValue
+  filterQueryValue,
+  getDisplayOperator
 } from "@utils/Enum";
+import { removeCriterionFromFilterUrl } from "@utils/filterUrlCriterionRemoval";
+import type { ParsedApiFilter } from "@utils/filterUrlCriterionRemoval";
+import { dateTimeFormat } from "@utils/Global";
 import moment from "moment";
 import { useLocation, useNavigate } from "react-router-dom";
 import { globalSearchFilterInitialQuery } from "@utils/Utils";
@@ -45,13 +49,18 @@ export const FilterQuery = ({ value }: any) => {
           </Typography>
         );
       } else {
-        if (obj.type === "date" || obj.id == "createTime") {
+        const isDateAttr =
+          obj.type === "date" ||
+          obj.id === "createTime" ||
+          obj.id === "__timestamp" ||
+          obj.id === "__modificationTimestamp";
+        if (isDateAttr) {
           if (queryBuilderDateRangeUIValueToAPI[obj.value]) {
             obj.value = queryBuilderDateRangeUIValueToAPI[obj.value];
+          } else if (/^\d+$/.test(String(obj.value))) {
+            obj.value = `${moment(Number(obj.value)).format(dateTimeFormat)} (${moment.tz(moment.tz.guess()).zoneAbbr()})`;
           } else {
-            obj.value = `${obj.value} (${moment
-              .tz(moment.tz.guess())
-              .zoneAbbr()})`;
+            obj.value = `${obj.value} (${moment.tz(moment.tz.guess()).zoneAbbr()})`;
           }
         }
 
@@ -60,6 +69,7 @@ export const FilterQuery = ({ value }: any) => {
             color="primary"
             className="chip-items"
             data-type={type}
+            data-rule-key={key}
             data-id={`${obj.id}${key}`}
             data-cy={`${obj.id}${key}`}
             label={
@@ -71,7 +81,7 @@ export const FilterQuery = ({ value }: any) => {
                       : obj.id}
                   </Typography>
                   <Typography className="operator" fontWeight="600">
-                    {obj.operator}{" "}
+                    {getDisplayOperator(obj.operator)}{" "}
                   </Typography>
                   <Typography className="searchValue">
                     {filterQueryValue[obj.id]
@@ -97,9 +107,138 @@ export const FilterQuery = ({ value }: any) => {
 
   const clearQueryAttr = (e: any) => {
     const searchParams = new URLSearchParams(location.search);
-    const currentType: any = e?.target
-      ?.closest("[data-type]")
-      ?.getAttribute("data-type");
+    const chipEl = (e?.target as HTMLElement)?.closest?.(
+      "[data-type]"
+    ) as HTMLElement | null;
+    const currentType = chipEl?.getAttribute("data-type");
+    const ruleKeyRaw = chipEl?.getAttribute("data-rule-key");
+
+    const navigateAfterChange = (sp: URLSearchParams) => {
+      const meaningfulFilterParams = [
+        "type",
+        "tag",
+        "query",
+        "term",
+        "relationshipName",
+        "entityFilters",
+        "tagFilters",
+        "relationshipFilters",
+        "excludeST",
+        "excludeSC",
+        "includeDE"
+      ];
+      const hasMeaningfulFilters = meaningfulFilterParams.some((param) =>
+        sp.has(param)
+      );
+      if (!hasMeaningfulFilters) {
+        navigate({
+          pathname: "/search"
+        });
+      } else if ([...sp]?.length <= 1) {
+        navigate({
+          pathname: "/search"
+        });
+      } else {
+        navigate({
+          pathname: "/search/searchResult",
+          search: sp.toString()
+        });
+      }
+    };
+
+    const syncFilterParamGlobalState = (
+      paramKey: "entityFilters" | "tagFilters" | "relationshipFilters",
+      urlValue: string | null
+    ) => {
+      if (!urlValue) {
+        globalSearchFilterInitialQuery.setQuery({ [paramKey]: [] });
+        return;
+      }
+      const api = attributeFilter.extractUrl({
+        value: urlValue,
+        apiObj: true
+      }) as ParsedApiFilter | null;
+      if (!api?.criterion || !Array.isArray(api.criterion)) {
+        globalSearchFilterInitialQuery.setQuery({ [paramKey]: [] });
+        return;
+      }
+      globalSearchFilterInitialQuery.setQuery({
+        [paramKey]: {
+          combinator: String(api.condition || "AND").toLowerCase(),
+          rules: api.criterion.map((rule: any, i: number) => ({
+            id: `url-rule-${i}`,
+            field: rule.attributeName,
+            operator: getDisplayOperator(rule.operator) || rule.operator,
+            value: rule.attributeValue,
+            ...(rule.type ? { type: rule.type } : {})
+          }))
+        }
+      });
+    };
+
+    const isFilterCriterionChip =
+      ruleKeyRaw !== null &&
+      ruleKeyRaw !== "" &&
+      (currentType === "entityFilters" ||
+        currentType === "tagFilters" ||
+        currentType === "relationshipFilters");
+
+    if (isFilterCriterionChip) {
+      const idx = Number.parseInt(ruleKeyRaw as string, 10);
+      if (Number.isNaN(idx)) {
+        return;
+      }
+      const paramKey = currentType as
+        | "entityFilters"
+        | "tagFilters"
+        | "relationshipFilters";
+      const raw = searchParams.get(paramKey);
+      if (!raw) {
+        return;
+      }
+      const allowSimplify = paramKey === "entityFilters";
+      const result = removeCriterionFromFilterUrl(raw, idx, allowSimplify);
+      if (!result) {
+        return;
+      }
+      if (result.kind === "empty") {
+        searchParams.delete(paramKey);
+        globalSearchFilterInitialQuery.setQuery({ [paramKey]: [] });
+        navigateAfterChange(searchParams);
+        return;
+      }
+      if (result.kind === "singleTypeName") {
+        searchParams.set("type", result.typeName);
+        searchParams.delete("entityFilters");
+        if (searchParams.get("includeDE") === "true") {
+          const delUrl = attributeFilter.generateUrl({
+            value: {
+              condition: "AND",
+              criterion: [
+                {
+                  attributeName: "__state",
+                  operator: "eq",
+                  attributeValue: "DELETED"
+                }
+              ]
+            }
+          });
+          if (delUrl) {
+            searchParams.set("entityFilters", delUrl);
+          }
+        }
+        syncFilterParamGlobalState(
+          "entityFilters",
+          searchParams.get("entityFilters")
+        );
+        navigateAfterChange(searchParams);
+        return;
+      }
+      searchParams.set(paramKey, result.url);
+      syncFilterParamGlobalState(paramKey, result.url);
+      navigateAfterChange(searchParams);
+      return;
+    }
 
     if (currentType == "term") {
       searchParams.delete("gtype");
@@ -127,43 +266,11 @@ export const FilterQuery = ({ value }: any) => {
       globalSearchFilterInitialQuery.setQuery({ [currentType]: [] });
     }
 
-    searchParams.delete(currentType);
-
-    // Check if there are any meaningful filters left after removal
-    const meaningfulFilterParams = [
-      "type",
-      "tag",
-      "query",
-      "term",
-      "relationshipName",
-      "entityFilters",
-      "tagFilters",
-      "relationshipFilters",
-      "excludeST",
-      "excludeSC",
-      "includeDE"
-    ];
-
-    const hasMeaningfulFilters = meaningfulFilterParams.some((param) =>
-      searchParams.has(param)
-    );
-
-    // If no meaningful filters remain, navigate to clear all (like Clear button)
-    if (!hasMeaningfulFilters) {
-      navigate({
-        pathname: "/search"
-      });
-    } else if ([...searchParams]?.length <= 1) {
-      // Only searchType or other system params remain
-      navigate({
-        pathname: "/search"
-      });
-    } else {
-      navigate({
-        pathname: "/search/searchResult",
-        search: searchParams.toString()
-      });
+    if (currentType) {
+      searchParams.delete(currentType);
     }
+
+    navigateAfterChange(searchParams);
   };
 
   if (value.type) {
diff --git a/dashboard/src/components/GlobalSearch/QuickSearch.tsx b/dashboard/src/components/GlobalSearch/QuickSearch.tsx
index 272ee107d..c8eba9490 100644
--- a/dashboard/src/components/GlobalSearch/QuickSearch.tsx
+++ b/dashboard/src/components/GlobalSearch/QuickSearch.tsx
@@ -16,518 +16,715 @@
  */
 
 import {
-  Autocomplete,
-  CircularProgress,
-  InputAdornment,
-  Stack,
-  TextField,
-  Typography
+	Autocomplete,
+	CircularProgress,
+	FormControl,
+	InputAdornment,
+	MenuItem,
+	Select,
+	Stack,
+	TextField,
+	Typography,
+	type SelectChangeEvent
 } from "@mui/material";
-import { useRef, useState } from "react";
+import { useCallback, useMemo, useRef, useState } from "react";
 import { getGlobalSearchResult } from "../../api/apiMethods/searchApiMethod";
 import DisplayImage from "../EntityDisplayImage";
 import SearchIcon from "@mui/icons-material/Search";
 import { Link, useLocation, useNavigate } from "react-router-dom";
 import { entityStateReadOnly } from "../../utils/Enum";
 import {
-  extractKeyValueFromEntity,
-  isEmpty,
-  serverError
+	extractKeyValueFromEntity,
+	isEmpty,
+	serverError
 } from "../../utils/Utils";
 import parse from "autosuggest-highlight/parse";
 import match from "autosuggest-highlight/match";
 import ClickAwayListener from "@mui/material/ClickAwayListener";
 import AdvancedSearch from "./AdvancedSearch";
 import {
-  HandleValuesType,
-  QuickSearchOptionListType,
-  SuggestionDataType
+	HandleValuesType,
+	QuickSearchOptionListType,
+	SuggestionDataType
 } from "../../models/globalSearchType";
 import { AxiosResponse } from "axios";
 import { CustomButton } from "@components/muiComponents";
+import { useAppSelector } from "@hooks/reducerHook";
+import {
+	buildBusinessMetadataScopedOptions,
+	buildClassificationScopedOptions,
+	buildEntitiesTreeForQuickSearch,
+	buildGlossaryTermsTreeForQuickSearch,
+	entityTreeToScopedOptions,
+	glossaryTreeToScopedOptions,
+	type QuickSearchScope,
+	type ScopedQuickSearchOption
+} from "@utils/scopedQuickSearchUtils";
+import {
+	navigateToBasicTextQuery,
+	navigateToBusinessMetadataDetailPage,
+	navigateToClassificationDetailPage,
+	navigateToGlossaryTermDetailPage,
+	navigateToServiceTypeEntitySearch
+} from "@utils/dashboardSearchUtils";
+
+interface GlobalOptionRow {
+	title: string;
+	types: string;
+	entityObj?: any;
+	scoped?: ScopedQuickSearchOption;
+}
+
+const SCOPE_SELECT_ID = "quick-search-scope-select";
+
+const SCOPE_LABELS: Record<QuickSearchScope, string> = {
+	default: "Select All",
+	entity: "Entity",
+	classification: "Classification",
+	glossary: "Glossary / Terms",
+	businessMetadata: "Business Metadata"
+};
 
 const QuickSearch = () => {
-  const navigate = useNavigate();
-  const location = useLocation();
-  const toastId = useRef(null);
-  const searchParams = new URLSearchParams(location.search);
-  const [options, setOptions] = useState<any>([]);
-  const [open, setOpen] = useState<boolean>(false);
-  const [openAdvanceSearch, setOpenAdvanceSearch] = useState<boolean>(false);
-  const [loading, setLoading] = useState<boolean>(false);
-  const [value, setValue] = useState<string>("");
-
-  const getData = async (searchTerm: string) => {
-    let entities: QuickSearchOptionListType = [];
-    let suggestionNames: QuickSearchOptionListType = [];
-    let quickSearchResp: AxiosResponse | null = null;
-    let suggestionSearchResp: AxiosResponse | null = null;
-    try {
-      setLoading(true);
-      quickSearchResp = await getGlobalSearchResult("quick", {
-        params: { query: searchTerm, limit: 5, offset: 0 }
-      });
-      setLoading(false);
-    } catch (error) {
-      setLoading(false);
-      console.error("Error fetching quick search results:", error);
-      serverError(error, toastId);
-    }
-
-    try {
-      setLoading(true);
-      suggestionSearchResp = await getGlobalSearchResult("suggestions", {
-        params: { prefixString: searchTerm }
-      });
-      setLoading(false);
-    } catch (error) {
-      setLoading(false);
-      console.error("Error fetching suggestion search results:", error);
-      serverError(error, toastId);
-    }
-    const { searchResults = [] } = quickSearchResp?.data || {};
-    const { suggestions = [] }: SuggestionDataType =
-      suggestionSearchResp?.data || {};
-
-    entities = !isEmpty(searchResults?.entities)
-      ? searchResults?.entities?.map((entityDef: any) => {
-          const { name }: { name: string; found: boolean; key: any } =
-            extractKeyValueFromEntity(entityDef);
-          return {
-            title: `${name}`,
-            parent: entityDef.typeName,
-            types: "Entities",
-            entityObj: entityDef
-          };
-        })
-      : [{ title: "No Entities Found", types: "Entities" }];
-
-    suggestionNames = !isEmpty(suggestions)
-      ? suggestions.map((suggestion: any) => {
-          return {
-            title: `${suggestion}`,
-            types: "Suggestions"
-          };
-        })
-      : [{ title: "No Suggestions Found", types: "Suggestions" }];
-
-    setOptions([...entities, ...suggestionNames]);
-  };
-
-  const onInputChange = (_event: any, value: string) => {
-    // Sanitize input: remove any potential script tags and validate
-    const sanitizedValue = value ? value.trim() : "";
-    
-    if (sanitizedValue) {
-      setOpen(true);
-      getData(sanitizedValue);
-    } else {
-      setOptions([]);
-      setValue("");
-      setOpen(false);
-    }
-  };
-
-  const handleValues = (option: HandleValuesType | string | null) => {
-    // Handle case when option is a string (direct search query)
-    if (typeof option === "string") {
-      const queryValue = option.trim();
-      if (queryValue) {
-        setOpen(false);
-        setOptions([]);
-        // URLSearchParams automatically encodes the value, preventing XSS
-        // Additional validation: ensure query is not empty after trim
-        const sanitizedQuery = queryValue || "*";
-        searchParams.set("query", sanitizedQuery);
-        searchParams.set("searchType", "basic");
-        navigate(
-          {
-            pathname: `/search/searchResult`,
-            search: searchParams.toString()
-          },
-          { replace: true }
-        );
-      }
-      return;
-    }
-
-    // Handle case when option is null or undefined
-    if (!option || typeof option !== "object") {
-      return;
-    }
-
-    const { entityObj, title, types } = option;
-    
-    // Validate that title exists and is not undefined
-    if (!title || title === "undefined" || typeof title !== "string") {
-      return;
-    }
-
-    // Sanitize title: trim and validate
-    const sanitizedTitle = title.trim();
-    if (!sanitizedTitle) {
-      return;
-    }
-
-    setOpen(false);
-    setOptions([]);
-    // URLSearchParams automatically encodes the value, preventing XSS
-    searchParams.set("query", sanitizedTitle);
-    searchParams.set("searchType", "basic");
-
-    if (types === "Entities" && entityObj && entityObj.guid) {
-      navigate(
-        {
-          pathname: `/detailPage/${entityObj.guid}`
-        },
-        { replace: true }
-      );
-    } else {
-      navigate(
-        {
-          pathname: `/search/searchResult`,
-          search: searchParams.toString()
-        },
-        { replace: true }
-      );
-    }
-  };
-
-  const handleClickAway = () => {
-    setOpen(false);
-  };
-
-  const handleCloseModal = () => {
-    setOpenAdvanceSearch(false);
-  };
-
-  return (
-    <>
-      <Stack
-        direction="row"
-        className="global-search-stack"
-        alignItems="center"
-        gap="0.5rem"
-      >
-        <ClickAwayListener onClickAway={handleClickAway}>
-          <Autocomplete
-            open={open}
-            loading={loading}
-            onKeyDown={(e) => {
-              const code = e.keyCode || e.which;
-
-              switch (code) {
-                case 13: { // Enter key
-                  e.preventDefault();
-                  const inputValue = (e.target as HTMLInputElement).value.trim();
-
-                  // If input is empty, use "*" for wildcard search (matching classic UI behavior)
-                  const searchQuery = inputValue === "" ? "*" : inputValue;
-
-                  // Try to find exact match in options
-                  const activeOption = options.find(
-                    (option: { title: any }) =>
-                      typeof option !== "string" &&
-                      option.title === searchQuery
-                  );
-                  
-                  if (activeOption) {
-                    // If exact match found, use that option
-                    handleValues(activeOption as HandleValuesType);
-                  } else {
-                    // If no match found, trigger basic search with typed value (matching classic UI behavior)
-                    handleValues(searchQuery);
-                  }
-                  break;
-                }
-                case 9: // Tab key
-                case 27: // Escape key
-                  setOpen(false);
-                  break;
-                default:
-                  break;
-              }
-            }}
-            freeSolo
-            id="global-search"
-            disablePortal
-            className="global-search-autocomplete"
-            sx={{
-              "& + .MuiAutocomplete-popper .MuiAutocomplete-option": {
-                backgroundColor: "white"
-              },
-              "& + .MuiAutocomplete-popper .MuiAutocomplete-option:hover": {
-                backgroundColor: "#c7e3ff"
-              }
-            }}
-            value={value}
-            onChange={(_event: any, newValue: any) => {
-              if (newValue) {
-                // Only update options if newValue is a valid option object
-                if (typeof newValue === "object" && newValue.title) {
-                  setOptions([newValue, ...options]);
-                }
-                setValue(newValue);
-                // Only call handleValues if newValue is a valid option
-                if (typeof newValue === "object" && newValue.title && newValue.title !== "undefined") {
-                  handleValues(newValue);
-                }
-              } else {
-                setValue("");
-              }
-            }}
-            clearOnBlur={false}
-            autoComplete={true}
-            includeInputInList
-            noOptionsText={"No Entities"}
-            disableClearable
-            onInputChange={onInputChange}
-            getOptionLabel={(option: string | QuickSearchOptionListType) => {
-              if (typeof option === "string") {
-                return option;
-              }
-              // Safely extract title, defaulting to empty string if undefined
-              const title = (option as any)?.title;
-              return title && typeof title === "string" ? title : "";
-            }}
-            renderOption={(props, option, { inputValue }) => {
-              const { entityObj, types, parent } =
-                typeof option !== "string" &&
-                "entityObj" in option &&
-                "types" in option &&
-                "parent" in option
-                  ? (option as {
-                      entityObj: { status?: string; guid?: string };
-                      types: string;
-                      parent: string;
-                    })
-                  : { entityObj: null, types: "", parent: "" };
-              typeof option !== "string" &&
-              "entityObj" in option &&
-              "types" in option
-                ? option
-                : { entityObj: null, types: "", parent: "" };
-              const title =
-                typeof option !== "string" && "title" in option
-                  ? option.title
-                  : option;
-              
-              // Validate and sanitize title to prevent XSS
-              const safeTitle = typeof title === "string" ? title : "";
-              
-              // Validate guid to prevent XSS in URL
-              const guid = (entityObj as { guid?: string })?.guid;
-              const safeGuid = guid && typeof guid === "string" ? guid : "";
-              const href = safeGuid ? `/detailPage/${safeGuid}` : "#";
-              
-              const { name }: { name: string; found: boolean; key: any } =
-                extractKeyValueFromEntity(entityObj);
-              
-              // Safely handle name extraction
-              const safeName = name && typeof name === "string" ? name : "";
-              
-              const matches = match(
-                types === "Entities" ? safeName : safeTitle,
-                inputValue || "",
-                {
-                  findAllOccurrences: true,
-                  insideWords: true
-                }
-              );
-              const parts = parse(
-                types === "Entities" ? safeName : safeTitle,
-                matches
-              );
-              return (
-                <Stack
-                  flexDirection="row"
-                  component="li"
-                  className="global-search-options"
-                  sx={{
-                    "& > span": {
-                      mr: 2,
-                      flexShrink: 0
-                    }
-                  }}
-                  {...props}
-                  onClick={() => {
-                    if (typeof option !== "string") {
-                      handleValues(option as unknown as HandleValuesType);
-                    }
-                  }}
-                >
-                  {types === "Entities" && !isEmpty(entityObj) ? (
-                    <Link
-                      className="entity-name text-decoration-none"
-                      style={{
-                        maxWidth: "100%",
-                        width: "100%",
-                        color: "black",
-                        textDecoration: "none",
-                        display: "inline-flex",
-                        alignItems: "center",
-                        flexWrap: "wrap"
-                      }}
-                      to={{
-                        pathname: href
-                      }}
-                      color={
-                        entityObj?.status &&
-                        entityStateReadOnly[entityObj.status]
-                          ? "error"
-                          : "primary"
-                      }
-                    >
-                      {" "}
-                      {types === "Entities" && !isEmpty(entityObj) && (
-                        <DisplayImage entity={entityObj} />
-                      )}{" "}
-                      {types === "Entities" && !isEmpty(entityObj)
-                        ? parts.map((part, index) => (
-                            <Stack
-                              flexDirection="row"
-                              key={index}
-                              style={{
-                                fontWeight: part.highlight ? "bold" : "regular"
-                              }}
-                            >
-                              {entityObj?.guid !== "-1" && !part.highlight ? (
-                                <Link
-                                  className="entity-name text-blue text-decoration-none"
-                                  style={{
-                                    color: "black",
-                                    textDecoration: "none",
-                                    maxWidth: "100%",
-                                    width: "100%"
-                                  }}
-                                  to={{
-                                    pathname: href
-                                  }}
-                                  color={
-                                    entityObj?.status &&
-                                    entityStateReadOnly[entityObj.status]
-                                      ? "error"
-                                      : "primary"
-                                  }
-                                >
-                                  {part.text}
-                                </Link>
-                              ) : (
-                                part.text
-                              )}
-                            </Stack>
-                          ))
-                        : parts.map((part, index) => (
-                            <Stack
-                              flexDirection="row"
-                              key={index}
-                              style={{
-                                fontWeight: part.highlight ? "bold" : "regular"
-                              }}
-                            >
-                              {part.text}
-                            </Stack>
-                          ))}
-                      {types === "Entities" &&
-                        !isEmpty(entityObj) &&
-                        ` (${parent})`}
-                    </Link>
-                  ) : (
-                    parts.map((part, index) => (
-                      <Typography
-                        component="p"
-                        key={index}
-                        className="global-search-options-text"
-                        sx={{
-                          fontWeight: part.highlight ? "bold" : "regular"
-                        }}
-                      >
-                        {" "}
-                        {part.text}
-                      </Typography>
-                    ))
-                  )}
-                </Stack>
-              );
-            }}
-            renderInput={(params) => (
-              <TextField
-                {...params}
-                placeholder="Search Entities..."
-                fullWidth
-                onClick={() => {
-                  setOpen(true);
-                }}
-                className="text-black-default"
-                InputProps={{
-                  style: {
-                    padding: "1px 10px",
-                    borderRadius: "4px",
-                    color: "white !important",
-                    opacity: 1
-                  },
-                  ...params.InputProps,
-                  type: "search",
-                  endAdornment: (
-                    <InputAdornment position="start">
-                      {loading ? (
-                        <CircularProgress sx={{ color: "gray" }} size={15} />
-                      ) : (
-                        <SearchIcon fontSize="small" />
-                      )}
-                    </InputAdornment>
-                  )
-                }}
-              />
-            )}
-            groupBy={(option) =>
-              typeof option !== "string" && "types" in option
-                ? String(option.types)
-                : ""
-            }
-            options={options}
-            filterOptions={(options) => options}
-          />
-        </ClickAwayListener>
-
-        <CustomButton
-          variant="outlined"
-          size="small"
-          sx={{
-            backgroundColor: "white !important",
-            color: "#4a90e2 !important",
-            borderColor: "#dddddd !important",
-            "&:hover": {
-              backgroundColor: "rgba(74, 144, 226, 0.08) !important",
-              // borderColor: "#4a90e2 !important",
-              color: "#4a90e2 !important"
-            }
-          }}
-          onClick={() => {
-            setOpenAdvanceSearch(true);
-          }}
-        >
-          <Typography
-            sx={{
-              color: "#4a90e2 !important",
-              fontWeight: "600 !important",
-              fontSize: "0.875rem !important"
-            }}
-            display="inline"
-          >
-            Advanced
-          </Typography>
-        </CustomButton>
-      </Stack>
-
-      {openAdvanceSearch && (
-        <AdvancedSearch
-          openAdvanceSearch={openAdvanceSearch}
-          handleCloseModal={handleCloseModal}
-        />
-      )}
-    </>
-  );
+	const navigate = useNavigate();
+	const location = useLocation();
+	const toastId = useRef(null);
+	const searchParams = new URLSearchParams(location.search);
+	const [options, setOptions] = useState<GlobalOptionRow[]>([]);
+	const [open, setOpen] = useState<boolean>(false);
+	const [openAdvanceSearch, setOpenAdvanceSearch] = useState<boolean>(false);
+	const [loading, setLoading] = useState<boolean>(false);
+	const [inputText, setInputText] = useState<string>("");
+	const [scope, setScope] = useState<QuickSearchScope>("default");
+
+	const { typeHeaderData } = useAppSelector((state: any) => state.typeHeader);
+	const { metricsData } = useAppSelector((state: any) => state.metrics);
+	const { allEntityTypesData } = useAppSelector((state: any) => state.allEntityTypes);
+	const { classificationData } = useAppSelector((state: any) => state.classification);
+	const { glossaryData } = useAppSelector((state: any) => state.glossary);
+	const { businessMetaData } = useAppSelector((state: any) => state.businessMetaData);
+
+	const entityTree = useMemo(
+		() =>
+			buildEntitiesTreeForQuickSearch(
+				typeHeaderData,
+				metricsData?.data?.entity,
+				allEntityTypesData?.category
+			),
+		[typeHeaderData, metricsData, allEntityTypesData]
+	);
+
+	const rebuildScopedOptions = useCallback(
+		(term: string): GlobalOptionRow[] => {
+			if (scope === "entity") {
+				return entityTreeToScopedOptions(entityTree, term).map((o) => ({
+					title: o.title,
+					types: o.group,
+					scoped: o
+				}));
+			}
+			if (scope === "classification") {
+				return buildClassificationScopedOptions(
+					classificationData,
+					metricsData?.data?.tag?.tagEntities,
+					term
+				).map((o) => ({
+					title: o.title,
+					types: o.group,
+					scoped: o
+				}));
+			}
+			if (scope === "glossary") {
+				const gTree = buildGlossaryTermsTreeForQuickSearch(glossaryData);
+				return glossaryTreeToScopedOptions(gTree, term).map((o) => ({
+					title: o.title,
+					types: o.group,
+					scoped: o
+				}));
+			}
+			if (scope === "businessMetadata") {
+				return buildBusinessMetadataScopedOptions(
+					businessMetaData?.businessMetadataDefs,
+					term
+				).map((o) => ({
+					title: o.title,
+					types: o.group,
+					scoped: o
+				}));
+			}
+			return [];
+		},
+		[
+			scope,
+			entityTree,
+			classificationData,
+			metricsData,
+			glossaryData,
+			businessMetaData
+		]
+	);
+
+	const getGlobalSearchData = async (searchTerm: string) => {
+		let entities: QuickSearchOptionListType = [];
+		let suggestionNames: QuickSearchOptionListType = [];
+		let quickSearchResp: AxiosResponse | null = null;
+		let suggestionSearchResp: AxiosResponse | null = null;
+		try {
+			setLoading(true);
+			quickSearchResp = await getGlobalSearchResult("quick", {
+				params: { query: searchTerm, limit: 5, offset: 0 }
+			});
+			setLoading(false);
+		} catch (error) {
+			setLoading(false);
+			console.error("Error fetching quick search results:", error);
+			serverError(error, toastId);
+		}
+
+		try {
+			setLoading(true);
+			suggestionSearchResp = await getGlobalSearchResult("suggestions", {
+				params: { prefixString: searchTerm }
+			});
+			setLoading(false);
+		} catch (error) {
+			setLoading(false);
+			console.error("Error fetching suggestion search results:", error);
+			serverError(error, toastId);
+		}
+		const { searchResults = [] } = quickSearchResp?.data || {};
+		const { suggestions = [] }: SuggestionDataType =
+			suggestionSearchResp?.data || {};
+
+		entities = !isEmpty(searchResults?.entities)
+			? searchResults?.entities?.map((entityDef: any) => {
+					const { name }: { name: string; found: boolean; key: any } =
+						extractKeyValueFromEntity(entityDef);
+					return {
+						title: `${name}`,
+						parent: entityDef.typeName,
+						types: "Entities",
+						entityObj: entityDef
+					};
+				})
+			: [{ title: "No Entities Found", types: "Entities" }];
+
+		suggestionNames = !isEmpty(suggestions)
+			? suggestions.map((suggestion: any) => {
+					return {
+						title: `${suggestion}`,
+						types: "Suggestions"
+					};
+				})
+			: [{ title: "No Suggestions Found", types: "Suggestions" }];
+
+		setOptions([...entities, ...suggestionNames] as GlobalOptionRow[]);
+	};
+
+	const onInputChange = (_event: unknown, value: string) => {
+		const sanitizedValue = value ? value.trim() : "";
+		setInputText(value ?? "");
+		if (!sanitizedValue) {
+			setOptions([]);
+			setOpen(false);
+			return;
+		}
+		setOpen(true);
+		if (scope === "default") {
+			void getGlobalSearchData(sanitizedValue);
+		} else {
+			setOptions(rebuildScopedOptions(sanitizedValue));
+		}
+	};
+
+	const handleScopedSelection = (opt: ScopedQuickSearchOption) => {
+		setOpen(false);
+		setOptions([]);
+		setInputText("");
+		if (opt.kind === "entity-type" && opt.entityTypeName) {
+			navigateToBasicTextQuery(navigate, opt.entityTypeName);
+			return;
+		}
+		if (opt.kind === "entity-service" && opt.serviceUnderlyingTypeNames?.length) {
+			navigateToServiceTypeEntitySearch(
+				navigate,
+				opt.serviceUnderlyingTypeNames,
+				false
+			);
+			return;
+		}
+		if (opt.kind === "classification" && opt.classificationName) {
+			navigateToClassificationDetailPage(navigate, opt.classificationName);
+			return;
+		}
+		if (
+			opt.kind === "glossary-term" &&
+			opt.termGuid &&
+			opt.glossaryGuid &&
+			opt.termId &&
+			opt.termParent
+		) {
+			navigateToGlossaryTermDetailPage(navigate, {
+				termGuid: opt.termGuid,
+				termId: opt.termId,
+				glossaryGuid: opt.glossaryGuid,
+				parentName: opt.termParent
+			});
+			return;
+		}
+		if (opt.kind === "business-metadata" && opt.bmGuid) {
+			navigateToBusinessMetadataDetailPage(navigate, opt.bmGuid);
+		}
+	};
+
+	const handleValues = (option: HandleValuesType | GlobalOptionRow | string | null) => {
+		if (typeof option === "string") {
+			const queryValue = option.trim();
+			if (!queryValue) return;
+			setOpen(false);
+			setOptions([]);
+			setInputText("");
+			if (scope !== "default") {
+				return;
+			}
+			const sanitizedQuery = queryValue || "*";
+			searchParams.set("query", sanitizedQuery);
+			searchParams.set("searchType", "basic");
+			navigate(
+				{
+					pathname: `/search/searchResult`,
+					search: searchParams.toString()
+				},
+				{ replace: true }
+			);
+			return;
+		}
+
+		if (!option || typeof option !== "object") return;
+
+		const row = option as GlobalOptionRow;
+		if (row.scoped) {
+			handleScopedSelection(row.scoped);
+			return;
+		}
+
+		const { entityObj, title, types } = row as HandleValuesType;
+		if (!title || title === "undefined" || typeof title !== "string") return;
+
+		const sanitizedTitle = title.trim();
+		if (!sanitizedTitle) return;
+
+		setOpen(false);
+		setOptions([]);
+		setInputText("");
+
+		searchParams.set("query", sanitizedTitle);
+		searchParams.set("searchType", "basic");
+
+		if (types === "Entities" && entityObj && entityObj.guid) {
+			navigate(
+				{
+					pathname: `/detailPage/${entityObj.guid}`
+				},
+				{ replace: true }
+			);
+		} else {
+			navigate(
+				{
+					pathname: `/search/searchResult`,
+					search: searchParams.toString()
+				},
+				{ replace: true }
+			);
+		}
+	};
+
+	const handleSubmitSearch = () => {
+		const q = inputText.trim();
+		if (scope !== "default") {
+			const activeOption = options.find((o) => o.title === q);
+			if (activeOption?.scoped) {
+				handleScopedSelection(activeOption.scoped);
+			}
+			return;
+		}
+		if (!q) {
+			handleValues("*");
+			return;
+		}
+		const activeOption = options.find(
+			(o) => typeof o !== "string" && o.title === q
+		);
+		if (activeOption) {
+			handleValues(activeOption as HandleValuesType);
+		} else {
+			handleValues(q);
+		}
+	};
+
+	const handleScopeChange = (e: SelectChangeEvent<QuickSearchScope>) => {
+		const v = e.target.value as QuickSearchScope;
+		setScope(v);
+		setOptions([]);
+		setInputText("");
+		setOpen(false);
+	};
+
+	const handleClickAway = () => {
+		setOpen(false);
+	};
+
+	const handleCloseModal = () => {
+		setOpenAdvanceSearch(false);
+	};
+
+	const inputPlaceholder =
+		scope === "default" ? "Search Entities..." : "Contains text...";
+
+	return (
+		<>
+			<Stack
+				direction="row"
+				className="global-search-stack"
+				alignItems="center"
+				gap="0.5rem"
+			>
+				<FormControl
+					size="small"
+					sx={{ minWidth: 160, backgroundColor: "white", borderRadius: 1 }}
+				>
+					<Select<QuickSearchScope>
+						id={SCOPE_SELECT_ID}
+						value={scope}
+						onChange={handleScopeChange}
+						aria-label="Search scope"
+						displayEmpty
+						renderValue={(v) => SCOPE_LABELS[v as QuickSearchScope]}
+					>
+						<MenuItem value="default">Select All</MenuItem>
+						<MenuItem value="entity">Entity</MenuItem>
+						<MenuItem value="classification">Classification</MenuItem>
+						<MenuItem value="glossary">Glossary / Terms</MenuItem>
+						<MenuItem value="businessMetadata">Business Metadata</MenuItem>
+					</Select>
+				</FormControl>
+
+				<ClickAwayListener onClickAway={handleClickAway}>
+					<Autocomplete
+						open={open}
+						loading={loading}
+						inputValue={inputText}
+						onInputChange={onInputChange}
+						onKeyDown={(e) => {
+							const code = e.keyCode || e.which;
+							switch (code) {
+								case 13: {
+									e.preventDefault();
+									handleSubmitSearch();
+									break;
+								}
+								case 9:
+								case 27:
+									setOpen(false);
+									break;
+								default:
+									break;
+							}
+						}}
+						freeSolo
+						id="global-search"
+						disablePortal
+						className="global-search-autocomplete"
+						sx={{
+							minWidth: 280,
+							flex: 1,
+							"& + .MuiAutocomplete-popper .MuiAutocomplete-option": {
+								backgroundColor: "white"
+							},
+							"& + .MuiAutocomplete-popper .MuiAutocomplete-option:hover": {
+								backgroundColor: "#c7e3ff"
+							}
+						}}
+						value={null}
+						onChange={(_event: unknown, newValue: unknown) => {
+							if (newValue && typeof newValue === "object") {
+								const o = newValue as GlobalOptionRow;
+								if (o.title) {
+									handleValues(o);
+								}
+							}
+						}}
+						clearOnBlur={false}
+						autoComplete
+						includeInputInList
+						noOptionsText={scope === "default" ? "No Entities" : "No matches"}
+						getOptionLabel={(option: string | GlobalOptionRow) => {
+							if (typeof option === "string") return option;
+							return option?.title && typeof option.title === "string"
+								? option.title
+								: "";
+						}}
+						renderOption={(props, option, { inputValue }) => {
+							const row = option as GlobalOptionRow;
+							if (row.scoped) {
+								const title = row.title;
+								const matches = match(title, inputValue || "", {
+									findAllOccurrences: true,
+									insideWords: true
+								});
+								const parts = parse(title, matches);
+								return (
+									<li {...props} key={row.scoped.id}>
+										<Typography component="span" variant="body2">
+											{parts.map((part, index) => (
+												<span
+													key={index}
+													style={{
+														fontWeight: part.highlight ? 700 : 400
+													}}
+												>
+													{part.text}
+												</span>
+											))}
+										</Typography>
+									</li>
+								);
+							}
+
+							const { entityObj, types, parent } =
+								typeof option !== "string" &&
+								"entityObj" in option &&
+								"types" in option &&
+								"parent" in option
+									? (option as {
+											entityObj: { status?: string; guid?: string };
+											types: string;
+											parent: string;
+										})
+									: { entityObj: null, types: "", parent: "" };
+							const title =
+								typeof option !== "string" && "title" in option
+									? option.title
+									: option;
+							const safeTitle = typeof title === "string" ? title : "";
+							const guid = (entityObj as { guid?: string })?.guid;
+							const safeGuid = guid && typeof guid === "string" ? guid : "";
+							const href = safeGuid ? `/detailPage/${safeGuid}` : "#";
+							const { name }: { name: string; found: boolean; key: any } =
+								extractKeyValueFromEntity(entityObj);
+							const safeName = name && typeof name === "string" ? name : "";
+							const matches = match(
+								types === "Entities" ? safeName : safeTitle,
+								inputValue || "",
+								{
+									findAllOccurrences: true,
+									insideWords: true
+								}
+							);
+							const parts = parse(
+								types === "Entities" ? safeName : safeTitle,
+								matches
+							);
+							return (
+								<Stack
+									flexDirection="row"
+									component="li"
+									className="global-search-options"
+									sx={{
+										"& > span": {
+											mr: 2,
+											flexShrink: 0
+										}
+									}}
+									{...props}
+									onClick={() => {
+										handleValues(option as GlobalOptionRow);
+									}}
+								>
+									{types === "Entities" && !isEmpty(entityObj) ? (
+										<Link
+											className="entity-name text-decoration-none"
+											style={{
+												maxWidth: "100%",
+												width: "100%",
+												color: "black",
+												textDecoration: "none",
+												display: "inline-flex",
+												alignItems: "center",
+												flexWrap: "wrap"
+											}}
+											to={{ pathname: href }}
+											color={
+												entityObj?.status &&
+												entityStateReadOnly[entityObj.status]
+													? "error"
+													: "primary"
+											}
+										>
+											{types === "Entities" && !isEmpty(entityObj) && (
+												<DisplayImage entity={entityObj} />
+											)}
+											{types === "Entities" && !isEmpty(entityObj)
+												? parts.map((part, index) => (
+														<Stack
+															flexDirection="row"
+															key={index}
+															style={{
+																fontWeight: part.highlight ? "bold" : "regular"
+															}}
+														>
+															{entityObj?.guid !== "-1" && !part.highlight ? (
+																<Link
+																	className="entity-name text-blue text-decoration-none"
+																	style={{
+																		color: "black",
+																		textDecoration: "none",
+																		maxWidth: "100%",
+																		width: "100%"
+																	}}
+																	to={{ pathname: href }}
+																	color={
+																		entityObj?.status &&
+																		entityStateReadOnly[entityObj.status]
+																			? "error"
+																			: "primary"
+																	}
+																>
+																	{part.text}
+																</Link>
+															) : (
+																part.text
+															)}
+														</Stack>
+													))
+												: parts.map((part, index) => (
+														<Stack
+															flexDirection="row"
+															key={index}
+															style={{
+																fontWeight: part.highlight ? "bold" : "regular"
+															}}
+														>
+															{part.text}
+														</Stack>
+													))}
+											{types === "Entities" &&
+												!isEmpty(entityObj) &&
+												` (${parent})`}
+										</Link>
+									) : (
+										parts.map((part, index) => (
+											<Typography
+												component="p"
+												key={index}
+												className="global-search-options-text"
+												sx={{
+													fontWeight: part.highlight ? "bold" : "regular"
+												}}
+											>
+												{part.text}
+											</Typography>
+										))
+									)}
+								</Stack>
+							);
+						}}
+						renderInput={(params) => (
+							<TextField
+								{...params}
+								placeholder={inputPlaceholder}
+								fullWidth
+								onClick={() => {
+									setOpen(true);
+								}}
+								className="text-black-default"
+								InputProps={{
+									style: {
+										padding: "1px 10px",
+										borderRadius: "4px",
+										color: "#1a1a1a",
+										backgroundColor: "white"
+									},
+									...params.InputProps,
+									type: "search",
+									endAdornment: (
+										<InputAdornment position="end">
+											{loading ? (
+												<CircularProgress sx={{ color: "gray" }} size={15} />
+											) : (
+												<SearchIcon fontSize="small" sx={{ color: "gray" }} />
+											)}
+										</InputAdornment>
+									)
+								}}
+								inputProps={{
+									...params.inputProps,
+									"aria-label": "Global search"
+								}}
+							/>
+						)}
+						groupBy={(option) =>
+							typeof option !== "string" && "types" in option
+								? String((option as GlobalOptionRow).types)
+								: ""
+						}
+						options={options}
+						filterOptions={(x) => x}
+					/>
+				</ClickAwayListener>
+
+				<CustomButton
+					variant="contained"
+					size="small"
+					sx={{
+						backgroundColor: "#4a90e2 !important",
+						color: "#fff !important",
+						textTransform: "none",
+						fontWeight: 600
+					}}
+					onClick={handleSubmitSearch}
+					aria-label="Run search"
+				>
+					Search
+				</CustomButton>
+
+				<CustomButton
+					variant="outlined"
+					size="small"
+					sx={{
+						backgroundColor: "white !important",
+						color: "#4a90e2 !important",
+						borderColor: "#dddddd !important",
+						"&:hover": {
+							backgroundColor: "rgba(74, 144, 226, 0.08) !important",
+							color: "#4a90e2 !important"
+						}
+					}}
+					onClick={() => {
+						setOpenAdvanceSearch(true);
+					}}
+				>
+					<Typography
+						sx={{
+							color: "#4a90e2 !important",
+							fontWeight: "600 !important",
+							fontSize: "0.875rem !important"
+						}}
+						display="inline"
+					>
+						Advanced
+					</Typography>
+				</CustomButton>
+			</Stack>
+
+			{openAdvanceSearch && (
+				<AdvancedSearch
+					openAdvanceSearch={openAdvanceSearch}
+					handleCloseModal={handleCloseModal}
+				/>
+			)}
+		</>
+	);
 };
 
 export default QuickSearch;
diff --git a/dashboard/src/components/ImportDialog.tsx b/dashboard/src/components/ImportDialog.tsx
index a3adfbb54..10d82aa1d 100644
--- a/dashboard/src/components/ImportDialog.tsx
+++ b/dashboard/src/components/ImportDialog.tsx
@@ -37,7 +37,8 @@ import List from "@mui/material/List";
 import ListItem from "@mui/material/ListItem";
 import ListItemText from "@mui/material/ListItemText";
 import ArrowBackIosNewIcon from "@mui/icons-material/ArrowBackIosNew";
-import { getGlossaryImport } from "../api/apiMethods/glossaryApiMethod";
+import { postGlossaryImportFormData } from "@utils/glossaryImportFlow";
+import { getApiErrorToastMessage } from "@utils/apiErrorToastMessage";
 
 const BootstrapDialog = styled(Dialog)(({ theme }) => ({
   "& .MuiDialogContent-root": {
@@ -77,22 +78,27 @@ export const ImportDialog: React.FC<CustomModalProps> = ({
   const onUpload = async () => {
     if (fileData) {
       try {
-        let apiMethod =
+        const onProgress = (progressValue: number) => {
+          setProgress(progressValue);
+        };
+        const importResp =
           title == "Import Business Metadata"
-            ? getBusinessMetadataImport
-            : getGlossaryImport;
-        let formData = new FormData();
-        formData.append("file", fileData);
-        const importResp = await apiMethod(formData, {
-          onUploadProgress: (progressEvent: {
-            loaded: number;
-            total: number;
-          }) => {
-            let progressValue =
-              (progressEvent.loaded / progressEvent.total) * 100;
-            setProgress(progressValue);
-          }
-        });
+            ? await (async () => {
+                const formData = new FormData();
+                formData.append("file", fileData);
+                return getBusinessMetadataImport(formData, {
+                  onUploadProgress: (progressEvent: {
+                    loaded: number;
+                    total: number;
+                  }) => {
+                    if (!progressEvent.total) return;
+                    onProgress(
+                      (progressEvent.loaded / progressEvent.total) * 100
+                    );
+                  }
+                });
+              })()
+            : await postGlossaryImportFormData(fileData, onProgress);
 
         if (importResp.data.failedImportInfoList == undefined) {
           toast.dismiss(toastId.current);
@@ -114,8 +120,12 @@ export const ImportDialog: React.FC<CustomModalProps> = ({
         }
         setImportData(importResp.data);
       } catch (error) {
+        const message = getApiErrorToastMessage(error);
+        if (message === null) {
+          return;
+        }
         toast.dismiss(toastId.current);
-        toastId.current = toast.error(`Invalid JSON response from server`);
+        toastId.current = toast.error(message);
       }
     }
   };
diff --git a/dashboard/src/components/QueryBuilder/Filters.tsx b/dashboard/src/components/QueryBuilder/Filters.tsx
index 2b305510e..d162f28e6 100644
--- a/dashboard/src/components/QueryBuilder/Filters.tsx
+++ b/dashboard/src/components/QueryBuilder/Filters.tsx
@@ -25,7 +25,7 @@ import {
   FormControlLabel
 } from "@mui/material";
 
-import { useState } from "react";
+import { useState, useEffect, useMemo } from "react";
 import {
   Accordion,
   AccordionDetails,
@@ -47,6 +47,7 @@ import { useAppSelector } from "@hooks/reducerHook";
 import { cloneDeep } from "@utils/Helper";
 import { getObjDef } from "@views/Administrator/Audits/AuditsFilter/AuditFiltersFields";
 import { attributeFilter } from "@utils/CommonViewFunction";
+import { getDisplayOperator } from "@utils/Enum";
 import moment from "moment";
 import RelationshipFilters from "./RelationshipFilters";
 import TypeFilters from "./TypeFilters/TypeFilters";
@@ -70,28 +71,66 @@ const Filters = ({
   const tagParams = searchParams.get("tag");
   const relationshipParams = searchParams.get("relationshipName");
   const entityFilterParams = searchParams.get("entityFilters");
-  const [checkedEntities, setCheckedEntities] = useState<any>(
-    !isEmpty(searchParams.get("includeDE"))
-      ? searchParams.get("includeDE")
-      : false
+  const [checkedEntities, setCheckedEntities] = useState<boolean>(
+    searchParams.get("includeDE") === "true" || searchParams.get("includeDE") === true
   );
-  const [checkedSubClassifications, setCheckedSubClassifications] =
-    useState<any>(
-      !isEmpty(searchParams.get("excludeSC"))
-        ? searchParams.get("excludeSC")
-        : false
-    );
-  const [checkedSubTypes, setCheckedSubTypes] = useState<any>(
-    !isEmpty(searchParams.get("excludeST"))
-      ? searchParams.get("excludeST")
-      : false
+  const [checkedSubClassifications, setCheckedSubClassifications] = useState<boolean>(
+    searchParams.get("excludeSC") === "true" || searchParams.get("excludeSC") === true
+  );
+  const [checkedSubTypes, setCheckedSubTypes] = useState<boolean>(
+    searchParams.get("excludeST") === "true" || searchParams.get("excludeST") === true
   );
+  const parseFiltersFromUrl = (params: string | null) => {
+    if (isEmpty(params)) return null;
+    const parsed = attributeFilter.extractUrl({
+      value: params,
+      formatDate: true
+    });
+    if (!parsed?.rules) return null;
+    const rulesArr = Array.isArray(parsed.rules)
+      ? parsed.rules
+      : Object.keys(parsed.rules || {}).map((k) => parsed.rules[k]);
+    const mappedRules = rulesArr
+      .filter((r) => r && !r.condition)
+      .map((r, i) => ({
+        field: r.id,
+        operator: getDisplayOperator(r.operator) || r.operator,
+        value: r.value,
+        id: `url-rule-${i}`
+      }));
+    if (mappedRules.length === 0) return null;
+    return {
+      combinator: (parsed.condition || "AND").toLowerCase(),
+      rules: mappedRules
+    };
+  };
+
+  const entityFiltersFromUrl = parseFiltersFromUrl(entityFilterParams);
+  const tagFilterParams = searchParams.get("tagFilters");
+  const relationshipFilterParams = searchParams.get("relationshipFilters");
+  const tagFiltersFromUrl = parseFiltersFromUrl(tagFilterParams);
+  const relationshipFiltersFromUrl = parseFiltersFromUrl(relationshipFilterParams);
+
   const [typeQuery, setTypeQuery] = useState(
     !isEmpty(globalSearchFilterInitialQuery.getQuery()?.entityFilters) &&
       !isEmpty(entityFilterParams)
       ? globalSearchFilterInitialQuery.getQuery()?.entityFilters
-      : initialQuery
+      : !isEmpty(entityFiltersFromUrl)
+        ? entityFiltersFromUrl
+        : initialQuery
   );
+
+  useEffect(() => {
+    if (
+      !isEmpty(entityFilterParams) &&
+      isEmpty(globalSearchFilterInitialQuery.getQuery()?.entityFilters) &&
+      !isEmpty(entityFiltersFromUrl)
+    ) {
+      globalSearchFilterInitialQuery.setQuery({
+        entityFilters: entityFiltersFromUrl
+      });
+    }
+  }, [entityFilterParams]);
   const [classificationQuery, setClassificationQuery] = useState(
     !isEmpty(globalSearchFilterInitialQuery.getQuery()?.tagFilters)
       ? globalSearchFilterInitialQuery.getQuery()?.tagFilters
@@ -125,28 +164,63 @@ const Filters = ({
     businessMetadata: businessMetadataDefs
   };
 
+  const appliedIncludeDE = searchParams.get("includeDE") === "true" || searchParams.get("includeDE") === true;
+  const appliedExcludeSC = searchParams.get("excludeSC") === "true" || searchParams.get("excludeSC") === true;
+  const appliedExcludeST = searchParams.get("excludeST") === "true" || searchParams.get("excludeST") === true;
+
+  const hasChanges = useMemo(() => {
+    const switchChanged =
+      !!checkedEntities !== !!appliedIncludeDE ||
+      !!checkedSubClassifications !== !!appliedExcludeSC ||
+      !!checkedSubTypes !== !!appliedExcludeST;
+
+    const normalizeQuery = (q: RuleGroupType | null) => {
+      if (!q || !q.rules || q.rules.length === 0) return JSON.stringify({ combinator: "and", rules: [] });
+      return JSON.stringify({ combinator: q.combinator || "and", rules: q.rules });
+    };
+
+    const entityQueryChanged =
+      normalizeQuery(typeQuery) !== normalizeQuery(entityFiltersFromUrl || initialQuery);
+    const tagQueryChanged =
+      normalizeQuery(classificationQuery) !== normalizeQuery(tagFiltersFromUrl || initialQuery);
+    const relationshipQueryChanged =
+      normalizeQuery(relationshipQuery) !== normalizeQuery(relationshipFiltersFromUrl || initialQuery);
+
+    return switchChanged || entityQueryChanged || tagQueryChanged || relationshipQueryChanged;
+  }, [
+    checkedEntities,
+    checkedSubClassifications,
+    checkedSubTypes,
+    appliedIncludeDE,
+    appliedExcludeSC,
+    appliedExcludeST,
+    typeQuery,
+    classificationQuery,
+    relationshipQuery,
+    entityFiltersFromUrl,
+    tagFiltersFromUrl,
+    relationshipFiltersFromUrl
+  ]);
+
   const handleSwitchChangeEntities = (
     event: React.ChangeEvent<HTMLInputElement>
   ) => {
     event.stopPropagation();
-    searchParams.set("includeDE", event.target.checked);
-    setCheckedEntities(event.target.checked);
+    setCheckedEntities(Boolean(event.target.checked));
   };
 
   const handleSwitchChangeSubClassification = (
     event: React.ChangeEvent<HTMLInputElement>
   ) => {
     event.stopPropagation();
-    searchParams.set("excludeSC", event.target.checked);
-    setCheckedSubClassifications(event.target.checked);
+    setCheckedSubClassifications(Boolean(event.target.checked));
   };
 
   const handleSwitchChangeSubTypes = (
     event: React.ChangeEvent<HTMLInputElement>
   ) => {
     event.stopPropagation();
-    searchParams.set("excludeST", event.target.checked);
-    setCheckedSubTypes(event.target.checked);
+    setCheckedSubTypes(Boolean(event.target.checked));
   };
 
   const paramsObject: Record<string, any> = {};
@@ -187,9 +261,9 @@ const Filters = ({
     let rules_widgets = null;
     let systemAttrArr;
 
-    if (!isEmpty(paramsObject)) {
+    if (!isEmpty(paramsObject?.entityFilters)) {
       rules_widgets = attributeFilter.extractUrl({
-        value: undefined,
+        value: paramsObject.entityFilters,
         formatDate: true
       });
     }
@@ -699,6 +773,7 @@ const Filters = ({
                 <CustomButton
                   variant="contained"
                   size="small"
+                  disabled={!hasChanges}
                   onClick={() => {
                     applyFilter();
                   }}
diff --git a/dashboard/src/components/ShowMore/DrawerBodyChipView.tsx b/dashboard/src/components/ShowMore/DrawerBodyChipView.tsx
index 5a082ef7e..38f702af6 100644
--- a/dashboard/src/components/ShowMore/DrawerBodyChipView.tsx
+++ b/dashboard/src/components/ShowMore/DrawerBodyChipView.tsx
@@ -388,6 +388,7 @@ const DrawerBodyChipView = ({
           button2Label="Remove"
           button2Handler={handleRemove}
           disableButton2={removeLoader}
+          button2Loading={removeLoader}
         >
           <Typography fontSize={14}>
             Remove:{" "}
diff --git a/dashboard/src/components/ShowMore/ShowMoreView.tsx b/dashboard/src/components/ShowMore/ShowMoreView.tsx
index 5a0f1cfc0..3761d0a4d 100644
--- a/dashboard/src/components/ShowMore/ShowMoreView.tsx
+++ b/dashboard/src/components/ShowMore/ShowMoreView.tsx
@@ -182,6 +182,8 @@ const ShowMoreView = ({
       }
     } catch (error) {
       serverError(error, toastId);
+    } finally {
+      setRemoveLoader(false);
     }
   };
 
@@ -379,6 +381,7 @@ const ShowMoreView = ({
           button2Label="Remove"
           button2Handler={handleRemove}
           disableButton2={removeLoader}
+          button2Loading={removeLoader}
         >
           <Typography fontSize={14}>
             Remove:{" "}
diff --git a/dashboard/src/components/Table/TablePagination.tsx b/dashboard/src/components/Table/TablePagination.tsx
index 7577f0007..792d1a711 100644
--- a/dashboard/src/components/Table/TablePagination.tsx
+++ b/dashboard/src/components/Table/TablePagination.tsx
@@ -369,6 +369,18 @@ const TablePagination: React.FC<PaginationProps> = ({
     ? pageTo
     : Math.min((pageIndex + 1) * pageSize, totalDatasetRows);
 
+  /** Last page may return fewer than `limit` rows; cap "to" at known total. */
+  const displayToCapped =
+    isServerSide &&
+    typeof totalCount === "number" &&
+    totalCount >= 0
+      ? Math.min(displayTo, totalCount)
+      : displayTo;
+
+  const footerRangeStart =
+    totalDatasetRows === 0 ? 0 : Math.min(displayFrom, displayToCapped);
+  const footerRangeEnd = totalDatasetRows === 0 ? 0 : displayToCapped;
+
   return (
     <Stack
       spacing={{ xs: 1, sm: 2 }}
@@ -381,8 +393,16 @@ const TablePagination: React.FC<PaginationProps> = ({
     >
       <div>
         <span className="text-grey">
-          Showing <u>{totalDatasetRows.toLocaleString()} records</u> From{" "}
-          {displayFrom} - {displayTo}
+          {totalDatasetRows === 0 ? (
+            "No records to display"
+          ) : (
+            <>
+              Showing {footerRangeStart.toLocaleString()}-
+              {footerRangeEnd.toLocaleString()} of{" "}
+              {totalDatasetRows.toLocaleString()}{" "}
+              {totalDatasetRows === 1 ? "record" : "records"}
+            </>
+          )}
         </span>
       </div>
 
@@ -491,25 +511,27 @@ const TablePagination: React.FC<PaginationProps> = ({
                     value={pendingGoToPageVal}
                   />
                   <LightTooltip title="Goto Page">
-                    <IconButton
-                      type="button"
-                      size="small"
-                      className={`${
-                        !isEmpty(pendingGoToPageVal)
-                          ? "cursor-pointer"
-                          : "cursor-not-allowed"
-                      } table-pagination-gotopage-button`}
-                      aria-label="search"
-                      onClick={() => {
-                        if (!isEmpty(pendingGoToPageVal)) {
-                          setGoToPageTrigger(pendingGoToPageVal);
-                          handleGoToPage();
-                        }
-                      }}
-                      disabled={isEmpty(pendingGoToPageVal)}
-                    >
-                      Go
-                    </IconButton>
+                    <span style={{ display: "inline-flex" }}>
+                      <IconButton
+                        type="button"
+                        size="small"
+                        className={`${
+                          !isEmpty(pendingGoToPageVal)
+                            ? "cursor-pointer"
+                            : "cursor-not-allowed"
+                        } table-pagination-gotopage-button`}
+                        aria-label="search"
+                        onClick={() => {
+                          if (!isEmpty(pendingGoToPageVal)) {
+                            setGoToPageTrigger(pendingGoToPageVal);
+                            handleGoToPage();
+                          }
+                        }}
+                        disabled={isEmpty(pendingGoToPageVal)}
+                      >
+                        Go
+                      </IconButton>
+                    </span>
                   </LightTooltip>
                 </Paper>
               </Stack>
@@ -517,19 +539,21 @@ const TablePagination: React.FC<PaginationProps> = ({
 
             <Stack flexDirection="row" alignItems="center">
               <LightTooltip title="Previous">
-                <IconButton
-                  size="small"
-                  className="pagination-page-change-btn"
-                  onClick={handlePreviousPage}
-                  disabled={isPreviousDisabled}
-                  aria-label="previous page"
-                >
-                  {theme.direction === "rtl" ? (
-                    <KeyboardArrowRight />
-                  ) : (
-                    <KeyboardArrowLeft />
-                  )}
-                </IconButton>
+                <span style={{ display: "inline-flex" }}>
+                  <IconButton
+                    size="small"
+                    className="pagination-page-change-btn"
+                    onClick={handlePreviousPage}
+                    disabled={isPreviousDisabled}
+                    aria-label="previous page"
+                  >
+                    {theme.direction === "rtl" ? (
+                      <KeyboardArrowRight />
+                    ) : (
+                      <KeyboardArrowLeft />
+                    )}
+                  </IconButton>
+                </span>
               </LightTooltip>
 
               <LightTooltip title={`Page ${activePage}`}>
@@ -539,19 +563,21 @@ const TablePagination: React.FC<PaginationProps> = ({
               </LightTooltip>
 
               <LightTooltip title="Next">
-                <IconButton
-                  size="small"
-                  className="pagination-page-change-btn"
-                  onClick={handleNextPage}
-                  disabled={isNextDisabled}
-                  aria-label="next page"
-                >
-                  {theme.direction === "rtl" ? (
-                    <KeyboardArrowLeft />
-                  ) : (
-                    <KeyboardArrowRight />
-                  )}
-                </IconButton>
+                <span style={{ display: "inline-flex" }}>
+                  <IconButton
+                    size="small"
+                    className="pagination-page-change-btn"
+                    onClick={handleNextPage}
+                    disabled={isNextDisabled}
+                    aria-label="next page"
+                  >
+                    {theme.direction === "rtl" ? (
+                      <KeyboardArrowLeft />
+                    ) : (
+                      <KeyboardArrowRight />
+                    )}
+                  </IconButton>
+                </span>
               </LightTooltip>
             </Stack>
           </>
diff --git a/dashboard/src/components/TreeNodeIcons.tsx b/dashboard/src/components/TreeNodeIcons.tsx
index 3e56f70e8..5403a2a9d 100644
--- a/dashboard/src/components/TreeNodeIcons.tsx
+++ b/dashboard/src/components/TreeNodeIcons.tsx
@@ -16,6 +16,7 @@
  */
 
 import { useRef, useState } from "react";
+import { useAsyncPending } from "../hooks/useAsyncPending";
 import IconButton from "@mui/material/IconButton";
 import Menu from "@mui/material/Menu";
 import Stack from "@mui/material/Stack";
@@ -72,6 +73,9 @@ const TreeNodeIcons = (props: {
   const [glossaryModal, setGlossaryModal] = useState<boolean>(false);
   const [termModal, setTermModal] = useState(false);
   const [categoryModal, setCategoryModal] = useState(false);
+  const [savedSearchDeleteLoading, setSavedSearchDeleteLoading] =
+    useState(false);
+  const { pending: renameSubmitting, run: runRenameAction } = useAsyncPending();
 
   const openNode = Boolean(expandNode);
 
@@ -128,6 +132,7 @@ const TreeNodeIcons = (props: {
 
   const handleRemove = async () => {
     try {
+      setSavedSearchDeleteLoading(true);
       await removeSavedSearch(selectedSearchData.guid);
       setDeleteModal(false);
       setExpandNode(null);
@@ -142,23 +147,27 @@ const TreeNodeIcons = (props: {
       toastId.current = toast.success(`${node.id} was deleted successfully`);
     } catch (error) {
       serverError(error, toastId);
+    } finally {
+      setSavedSearchDeleteLoading(false);
     }
   };
 
-  const handleEdit = async () => {
-    try {
-      let filterData = { ...selectedSearchData, name: value };
-      await editSavedSearch(filterData as CustomFiltersNodeType, "PUT");
-      updatedData();
-      setRenameModal(false);
-      setExpandNode(null);
-      toast.dismiss(toastId.current);
-      toastId.current = toast.success(
-        `${filterData.name} was updated successfully`
-      );
-    } catch (error) {
-      serverError(error, toastId);
-    }
+  const handleEdit = () => {
+    void runRenameAction(async () => {
+      try {
+        let filterData = { ...selectedSearchData, name: value };
+        await editSavedSearch(filterData as CustomFiltersNodeType, "PUT");
+        updatedData();
+        setRenameModal(false);
+        setExpandNode(null);
+        toast.dismiss(toastId.current);
+        toastId.current = toast.success(
+          `${filterData.name} was updated successfully`
+        );
+      } catch (error) {
+        serverError(error, toastId);
+      }
+    });
   };
   return (
     <>
@@ -483,7 +492,8 @@ const TreeNodeIcons = (props: {
         button1Handler={handleCloseRenameModal}
         button2Label="Update"
         button2Handler={handleEdit}
-        // disableButton2={value}
+        disableButton2={renameSubmitting}
+        button2Loading={renameSubmitting}
       >
         <Stack
           sx={{
@@ -518,6 +528,8 @@ const TreeNodeIcons = (props: {
         button1Handler={handleCloseDeleteModal}
         button2Label="Ok"
         button2Handler={handleRemove}
+        disableButton2={savedSearchDeleteLoading}
+        button2Loading={savedSearchDeleteLoading}
       >
         <Typography fontSize={15}>
           Are you sure you want to delete <strong>{node.id}</strong> ?{""}
diff --git a/dashboard/src/components/TypeDefAuditDetailModal.tsx b/dashboard/src/components/TypeDefAuditDetailModal.tsx
new file mode 100644
index 000000000..1e780d6fb
--- /dev/null
+++ b/dashboard/src/components/TypeDefAuditDetailModal.tsx
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+
+import { Divider, Stack } from "@mui/material";
+import CustomModal from "@components/Modal";
+import { getValues } from "@components/commonComponents";
+import { StyledPaper } from "@utils/Muiutils";
+import { category } from "@utils/Enum";
+import { isArray, isEmpty } from "@utils/Utils";
+
+export interface TypeDefAuditDetail {
+	category?: string;
+	name?: string;
+	[key: string]: unknown;
+}
+
+interface TypeDefAuditDetailModalProps {
+	open: boolean;
+	onClose: () => void;
+	/** Full type-definition payload from audit `result` (same shape as audit tab click). */
+	detailObject: TypeDefAuditDetail | Record<string, unknown> | null;
+	maxWidth?: "xs" | "sm" | "md" | "lg" | "xl";
+}
+
+const buildTitle = (detailObject: TypeDefAuditDetailModalProps["detailObject"]): string => {
+	if (isEmpty(detailObject)) return "Type Details";
+	const cat = detailObject?.category;
+	const name = detailObject?.name;
+	if (cat != null && name != null && category[String(cat)]) {
+		return `${category[String(cat)]} Type Details: ${String(name)}`;
+	}
+	if (name != null) return `Type Details: ${String(name)}`;
+	return "Type Details";
+};
+
+export const TypeDefAuditDetailModal = ({
+	open,
+	onClose,
+	detailObject,
+	maxWidth = "md",
+}: TypeDefAuditDetailModalProps) => {
+	return (
+		<CustomModal
+			open={open}
+			onClose={onClose}
+			title={buildTitle(detailObject)}
+			footer={false}
+			button1Handler={undefined}
+			button2Handler={undefined}
+			maxWidth={maxWidth}
+		>
+			<StyledPaper variant="outlined">
+				{!isEmpty(detailObject)
+					? Object.entries(detailObject as Record<string, unknown>)
+							.sort(([a], [b]) => a.localeCompare(b))
+							.map(([keys, value]) => (
+								<div key={keys}>
+									<Stack direction="row" spacing={4} marginBottom={1} marginTop={1}>
+										<div
+											style={{
+												flex: 1,
+												wordBreak: "break-all",
+												textAlign: "left",
+												fontWeight: "600",
+											}}
+										>
+											{`${keys} ${isArray(value) ? `(${(value as unknown[]).length})` : ""}`}
+										</div>
+										<div
+											style={{
+												flex: 1,
+												wordBreak: "break-all",
+												textAlign: "left",
+											}}
+										>
+											{getValues(
+												value,
+												undefined,
+												undefined,
+												undefined,
+												"properties"
+											)}
+										</div>
+									</Stack>
+									<Divider />
+								</div>
+							))
+					: "No Record Found"}
+			</StyledPaper>
+		</CustomModal>
+	);
+};
+
+export default TypeDefAuditDetailModal;
diff --git a/dashboard/src/utils/CommonViewFunction.ts b/dashboard/src/utils/CommonViewFunction.ts
index 3760de5a5..d58357bfd 100644
--- a/dashboard/src/utils/CommonViewFunction.ts
+++ b/dashboard/src/utils/CommonViewFunction.ts
@@ -193,13 +193,19 @@ export const attributeFilter = {
             let temp = obj.split("::") || obj.split("|" + spliter + "|");
             let rule = {};
             if (apiObj) {
+              const attrName = temp[0];
+              const isDateAttr =
+                temp[3] === "date" ||
+                attrName === "__timestamp" ||
+                attrName === "__modificationTimestamp" ||
+                attrName === "createTime";
               rule = {
-                attributeName: temp[0],
+                attributeName: attrName,
                 operator: mapUiOperatorToAPI(temp[1]),
                 attributeValue: temp[2]?.trim()
               };
               rule.attributeValue =
-                rule.type === "date" && formatDate && rule.attributeValue.length
+                isDateAttr && formatDate && rule.attributeValue?.length
                   ? formatedDate({
                       date: parseInt(rule.attributeValue),
                       zone: false
@@ -231,9 +237,12 @@ export const attributeFilter = {
                     rule.value;
                 }
               } else if (
-                (rule.type === "date" || rule.attributeName == "createTime") &&
+                (rule.type === "date" ||
+                  rule.attributeName === "createTime" ||
+                  rule.id === "__timestamp" ||
+                  rule.id === "__modificationTimestamp") &&
                 formatDate &&
-                rule.value.length
+                rule.value?.length
               ) {
                 rule.value = formatedDate({
                   date: parseInt(rule.value),
diff --git a/dashboard/src/utils/Enum.ts b/dashboard/src/utils/Enum.ts
index 76ee0712d..50644400b 100644
--- a/dashboard/src/utils/Enum.ts
+++ b/dashboard/src/utils/Enum.ts
@@ -319,6 +319,15 @@ export const queryBuilderUIOperatorToAPI = {
 
 export const queryBuilderApiOperatorToUI = invert(queryBuilderUIOperatorToAPI);
 
+/**
+ * Converts API operator (eq, lte, gte, etc.) to display symbol (=, <=, >=, etc.)
+ * Used when rendering filter query chips above search results table
+ */
+export const getDisplayOperator = (operator: string): string => {
+	const mapped = (queryBuilderApiOperatorToUI as Map<string, string>).get(operator);
+	return mapped ?? operator;
+};
+
 export const queryBuilderDateRangeUIValueToAPI: Record<string, string> = {
   Today: "TODAY",
   Yesterday: "YESTERDAY",
diff --git a/dashboard/src/utils/apiErrorToastMessage.ts b/dashboard/src/utils/apiErrorToastMessage.ts
new file mode 100644
index 000000000..7afa98d0b
--- /dev/null
+++ b/dashboard/src/utils/apiErrorToastMessage.ts
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+/**
+ * Resolves user-visible toast text from an axios/fetchApi error.
+ * @returns null when the caller must not toast (403 is handled in fetchApi).
+ */
+export const getApiErrorToastMessage = (error: unknown): string | null => {
+	const er = error as {
+		response?: { status?: number; data?: unknown };
+	};
+	if (er?.response?.status === 403) {
+		return null;
+	}
+	const data = er?.response?.data;
+	if (data !== null && data !== undefined && typeof data === "object") {
+		const o = data as Record<string, unknown>;
+		if (o.errorMessage != null && String(o.errorMessage).trim() !== "") {
+			return String(o.errorMessage);
+		}
+		if (o.msgDesc != null && String(o.msgDesc).trim() !== "") {
+			return String(o.msgDesc);
+		}
+	}
+	if (typeof data === "string" && data.trim() !== "") {
+		return data;
+	}
+	return "Invalid JSON response from server";
+};
diff --git a/dashboard/src/utils/auditTypeDefUtils.ts b/dashboard/src/utils/auditTypeDefUtils.ts
new file mode 100644
index 000000000..c23097578
--- /dev/null
+++ b/dashboard/src/utils/auditTypeDefUtils.ts
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+import { jsonParse } from "@utils/Utils";
+
+/** TYPE_DEF_* audit params that use the same detail modal as the Administrator Audits tab */
+export const TYPE_DEF_DETAIL_MODAL_PARAMS = new Set([
+	"ENUM",
+	"ENTITY",
+	"STRUCT",
+	"RELATIONSHIP",
+]);
+
+export interface AuditRecordLike {
+	operation?: string;
+	params?: string;
+	result?: string;
+}
+
+/**
+ * Pulls the full typedef object from an audit `result` JSON for ENUM / ENTITY /
+ * STRUCT / RELATIONSHIP rows (matches expanded audit row click payload).
+ */
+export const extractTypeDefDetailObject = (
+	record: AuditRecordLike,
+	resolvedName: string,
+	resolvedGuid: string
+): Record<string, unknown> | null => {
+	const op = record.operation;
+	if (
+		op !== "TYPE_DEF_CREATE" &&
+		op !== "TYPE_DEF_UPDATE" &&
+		op !== "TYPE_DEF_DELETE"
+	) {
+		return null;
+	}
+	const paramKeys = (record.params ?? "")
+		.split(",")
+		.map((k) => k.trim())
+		.filter(Boolean);
+
+	try {
+		const resultObj =
+			typeof record.result === "string" ? jsonParse(record.result) : record.result;
+		if (!resultObj || typeof resultObj !== "object") return null;
+
+		const keysToScan =
+			paramKeys.length > 0 ? paramKeys : Object.keys(resultObj as object);
+
+		for (const key of keysToScan) {
+			if (!TYPE_DEF_DETAIL_MODAL_PARAMS.has(key)) continue;
+			const list = (resultObj as Record<string, unknown>)[key];
+			if (!Array.isArray(list) || list.length === 0) continue;
+			const match = list.find((item: { name?: string; guid?: string }) => {
+				if (!item || typeof item !== "object") return false;
+				if (resolvedName && item.name === resolvedName) return true;
+				if (resolvedGuid && item.guid === resolvedGuid) return true;
+				return false;
+			});
+			if (match && typeof match === "object") {
+				return match as Record<string, unknown>;
+			}
+		}
+
+		const firstKey = paramKeys.find((k) => TYPE_DEF_DETAIL_MODAL_PARAMS.has(k));
+		if (firstKey) {
+			const list = (resultObj as Record<string, unknown>)[firstKey];
+			if (Array.isArray(list) && list[0] && typeof list[0] === "object") {
+				return list[0] as Record<string, unknown>;
+			}
+		}
+	} catch {
+		/* ignore */
+	}
+	return null;
+};
diff --git a/dashboard/src/utils/dashboardSearchUtils.ts b/dashboard/src/utils/dashboardSearchUtils.ts
new file mode 100644
index 000000000..15ebdf699
--- /dev/null
+++ b/dashboard/src/utils/dashboardSearchUtils.ts
@@ -0,0 +1,189 @@
+/*
+ * 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.
+ */
+
+import type { NavigateFunction } from "react-router-dom";
+import { attributeFilter } from "@utils/CommonViewFunction";
+
+export type DashboardSearchType =
+	| "all_entities"
+	| "all_classifications"
+	| "entity_status"
+	| "entity_type";
+
+export interface DashboardSearchParams {
+	type?: string;
+	tag?: string;
+	includeDE?: boolean;
+	entityFilters?: {
+		condition: string;
+		criterion: Array<{ attributeName: string; operator: string; attributeValue: string }>;
+	};
+}
+
+const buildSearchParams = (
+	type: DashboardSearchType,
+	extra?: Partial<DashboardSearchParams>
+): URLSearchParams => {
+	const params = new URLSearchParams();
+	params.set("searchType", "basic");
+
+	if (type === "all_classifications") {
+		params.set("tag", extra?.tag ?? "_ALL_CLASSIFICATION_TYPES");
+		params.set("type", "");
+	} else {
+		params.set("type", extra?.type ?? "_ALL_ENTITY_TYPES");
+	}
+	if (extra?.includeDE) {
+		params.set("includeDE", "true");
+	}
+	if (extra?.entityFilters) {
+		const urlStr = attributeFilter.generateUrl({ value: extra.entityFilters });
+		if (urlStr) params.set("entityFilters", urlStr);
+	}
+	return params;
+};
+
+export const navigateToTaggedSearch = (navigate: NavigateFunction): void => {
+	navigateToSearch(navigate, "all_classifications");
+};
+
+export const navigateToClassificationSearch = (
+	navigate: NavigateFunction,
+	tagName: string
+): void => {
+	navigateToSearch(navigate, "all_classifications", { tag: tagName });
+};
+
+/** "View All" from Latest Entities card: basic all-types search, newest first. */
+export const navigateToLatestEntitiesSearch = (navigate: NavigateFunction): void => {
+	const params = buildSearchParams("all_entities");
+	params.set("pageLimit", "25");
+	params.set("pageOffset", "0");
+	params.set("sortBy", "__timestamp");
+	params.set("sortOrder", "DESCENDING");
+	/* Same as dashboard card: request system create time in the basic-search body. */
+	params.set("attributes", "__timestamp");
+	navigate({ pathname: "/search/searchResult", search: params.toString() });
+};
+
+export const navigateToEntityTypeSearch = (
+	navigate: NavigateFunction,
+	typeName: string,
+	includeDeleted: boolean
+): void => {
+	const extra: Partial<DashboardSearchParams> = {
+		type: typeName,
+		includeDE: includeDeleted
+	};
+	if (includeDeleted) {
+		extra.entityFilters = {
+			condition: "AND",
+			criterion: [{ attributeName: "__state", operator: "eq", attributeValue: "DELETED" }]
+		};
+	}
+	navigateToSearch(navigate, "entity_type", extra);
+};
+
+/** Search all entity typedefs that belong to one service-type bucket (sidebar grouping). */
+export const navigateToServiceTypeEntitySearch = (
+	navigate: NavigateFunction,
+	typeNames: string[],
+	includeDeleted: boolean
+): void => {
+	const cleaned = [...new Set(typeNames.filter(Boolean))].sort((a, b) => a.localeCompare(b));
+	if (cleaned.length === 0) {
+		navigateToSearch(navigate, "all_entities");
+		return;
+	}
+	if (cleaned.length === 1) {
+		navigateToEntityTypeSearch(navigate, cleaned[0], includeDeleted);
+		return;
+	}
+	const criterion = cleaned.map((typeName) => ({
+		attributeName: "__typeName",
+		operator: "eq",
+		attributeValue: typeName,
+	}));
+	navigateToSearch(navigate, "all_entities", {
+		type: "_ALL_ENTITY_TYPES",
+		includeDE: includeDeleted,
+		entityFilters: { condition: "OR", criterion },
+	});
+};
+
+export const navigateToSearch = (
+	navigate: NavigateFunction,
+	type: DashboardSearchType,
+	extra?: Partial<DashboardSearchParams>
+): void => {
+	const search = buildSearchParams(type, extra).toString();
+	navigate({ pathname: "/search/searchResult", search });
+};
+
+/** Basic search using free-text `query` (e.g. entity typedef name). */
+export const navigateToBasicTextQuery = (
+	navigate: NavigateFunction,
+	query: string
+): void => {
+	const params = new URLSearchParams();
+	params.set("searchType", "basic");
+	params.set("query", query.trim());
+	params.set("pageLimit", "25");
+	params.set("pageOffset", "0");
+	navigate({ pathname: "/search/searchResult", search: params.toString() });
+};
+
+export const navigateToClassificationDetailPage = (
+	navigate: NavigateFunction,
+	classificationName: string
+): void => {
+	const sp = new URLSearchParams();
+	sp.set("tag", classificationName);
+	navigate({
+		pathname: `/tag/tagAttribute/${encodeURIComponent(classificationName)}`,
+		search: sp.toString()
+	});
+};
+
+export const navigateToGlossaryTermDetailPage = (
+	navigate: NavigateFunction,
+	args: {
+		termGuid: string;
+		termId: string;
+		glossaryGuid: string;
+		parentName: string;
+	}
+): void => {
+	const sp = new URLSearchParams();
+	sp.set("gid", args.glossaryGuid);
+	sp.set("term", `${args.termId}@${args.parentName}`);
+	sp.set("gtype", "term");
+	sp.set("viewType", "term");
+	sp.set("guid", args.termGuid);
+	sp.set("searchType", "basic");
+	navigate({
+		pathname: `/glossary/${args.termGuid}`,
+		search: sp.toString()
+	});
+};
+
+export const navigateToBusinessMetadataDetailPage = (
+	navigate: NavigateFunction,
+	bmGuid: string
+): void => {
+	navigate({ pathname: `/administrator/businessMetadata/${bmGuid}` });
+};
diff --git a/dashboard/src/utils/filterUrlCriterionRemoval.ts b/dashboard/src/utils/filterUrlCriterionRemoval.ts
new file mode 100644
index 000000000..746fe7998
--- /dev/null
+++ b/dashboard/src/utils/filterUrlCriterionRemoval.ts
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+import { attributeFilter } from "./CommonViewFunction";
+
+export type RemoveCriterionResult =
+	| { kind: "empty" }
+	| { kind: "url"; url: string }
+	| { kind: "singleTypeName"; typeName: string };
+
+type ApiFilterCriterionRow = {
+	attributeName: string;
+	operator: string;
+	attributeValue: string;
+	type?: string;
+};
+
+/** Narrowing shape for `attributeFilter.extractUrl(..., { apiObj: true })`. */
+export type ParsedApiFilter = {
+	condition: string;
+	criterion: ApiFilterCriterionRow[];
+};
+
+/**
+ * Drops one criterion from a serialized filter URL (entity / tag / relationship).
+ * When allowTypeParamSimplification is true and exactly one __typeName eq remains,
+ * returns singleTypeName so the UI can use type=<typedef> (matches sidebar search).
+ */
+export const removeCriterionFromFilterUrl = (
+	filterUrl: string,
+	index: number,
+	allowTypeParamSimplification = false
+): RemoveCriterionResult | null => {
+	if (!filterUrl || index < 0) {
+		return null;
+	}
+	const parsed = attributeFilter.extractUrl({
+		value: filterUrl,
+		apiObj: true
+	}) as ParsedApiFilter | null;
+	if (!parsed?.criterion || !Array.isArray(parsed.criterion)) {
+		return null;
+	}
+	const crit = [...parsed.criterion];
+	if (index >= crit.length) {
+		return null;
+	}
+	crit.splice(index, 1);
+	if (crit.length === 0) {
+		return { kind: "empty" };
+	}
+	if (
+		allowTypeParamSimplification &&
+		crit.length === 1 &&
+		crit[0].attributeName === "__typeName" &&
+		String(crit[0].operator).toLowerCase() === "eq"
+	) {
+		return { kind: "singleTypeName", typeName: String(crit[0].attributeValue) };
+	}
+	const url = attributeFilter.generateUrl({
+		value: { condition: parsed.condition, criterion: crit }
+	});
+	if (!url) {
+		return { kind: "empty" };
+	}
+	return { kind: "url", url };
+};
diff --git a/dashboard/src/utils/glossaryImportFlow.ts b/dashboard/src/utils/glossaryImportFlow.ts
new file mode 100644
index 000000000..a3f564050
--- /dev/null
+++ b/dashboard/src/utils/glossaryImportFlow.ts
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+import {
+	getGlossaryImport,
+	getGlossaryImportTmpl
+} from '@api/apiMethods/glossaryApiMethod';
+
+/**
+ * Same behavior as glossary branch of SideBarTree.downloadFile.
+ */
+export const downloadGlossaryImportTemplate = async (): Promise<void> => {
+	const apiResp = await getGlossaryImportTmpl({});
+	const text =
+		apiResp && typeof apiResp.data !== 'undefined'
+			? String(apiResp.data)
+			: '';
+	const blob = new Blob([text], { type: 'text/plain' });
+	const url = window.URL.createObjectURL(blob);
+	const link = document.createElement('a');
+	link.href = url;
+	link.setAttribute('download', 'template');
+	document.body.appendChild(link);
+	link.click();
+	document.body.removeChild(link);
+	window.URL.revokeObjectURL(url);
+};
+
+export const postGlossaryImportFormData = (
+	file: File,
+	onUploadProgress?: (progressPercent: number) => void
+) => {
+	const formData = new FormData();
+	formData.append('file', file);
+	return getGlossaryImport(formData, {
+		onUploadProgress: (progressEvent: { loaded: number; total: number }) => {
+			if (!onUploadProgress || !progressEvent.total) return;
+			const progressValue =
+				(progressEvent.loaded / progressEvent.total) * 100;
+			onUploadProgress(progressValue);
+		}
+	});
+};
diff --git a/dashboard/src/utils/metricsUtils.ts b/dashboard/src/utils/metricsUtils.ts
new file mode 100644
index 000000000..2b6b6bcf2
--- /dev/null
+++ b/dashboard/src/utils/metricsUtils.ts
@@ -0,0 +1,241 @@
+/*
+ * 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.
+ */
+
+export const sumEntityMetrics = (obj: Record<string, number> | undefined): number =>
+	Object.values(obj || {}).reduce((a, b) => a + (Number(b) || 0), 0);
+
+export const getEntityStatusTotals = (entity: Record<string, unknown> | undefined) => ({
+	active: sumEntityMetrics(entity?.entityActive as Record<string, number>),
+	shell: sumEntityMetrics(entity?.entityShell as Record<string, number>),
+	deleted: sumEntityMetrics(entity?.entityDeleted as Record<string, number>)
+});
+
+export interface EntityTypeDistributionItem {
+	name: string;
+	count: number;
+	active: number;
+	deleted: number;
+	/** Entity typedef names rolled into this bar (e.g. service type buckets). */
+	underlyingTypeNames?: string[];
+}
+
+export const getTaggedCount = (tag: Record<string, unknown> | undefined): number =>
+	sumEntityMetrics(tag?.tagEntities as Record<string, number>);
+
+/** tagEntities values summed — counts tag–entity associations, not unique entities */
+export const getTagEntityAssociationTotal = (tag: Record<string, unknown> | undefined): number =>
+	getTaggedCount(tag);
+
+/**
+ * Number of classification types that have at least one active entity (each key in
+ * tagEntities with count > 0). Does not double-count the same entity across types.
+ */
+export const getClassificationTypesInUseCount = (tag: Record<string, unknown> | undefined): number => {
+	const tagEntities = tag?.tagEntities as Record<string, number> | undefined;
+	if (!tagEntities || typeof tagEntities !== "object") return 0;
+	return Object.values(tagEntities).filter((c) => (Number(c) || 0) > 0).length;
+};
+
+/** Classification names that have at least one entity assignment per tag metrics. */
+export const getClassificationNamesInUseFromTag = (
+	tag: Record<string, unknown> | undefined
+): Set<string> => {
+	const tagEntities = tag?.tagEntities as Record<string, number> | undefined;
+	const names = new Set<string>();
+	if (!tagEntities || typeof tagEntities !== "object") return names;
+	for (const [name, count] of Object.entries(tagEntities)) {
+		if ((Number(count) || 0) > 0) {
+			names.add(name);
+		}
+	}
+	return names;
+};
+
+/**
+ * Defined classification names (from type defs) with no entity assignments in metrics.
+ */
+export const getUnusedClassificationNames = (
+	definedNames: string[],
+	tag: Record<string, unknown> | undefined
+): string[] => {
+	const inUse = getClassificationNamesInUseFromTag(tag);
+	return definedNames.filter((n) => !inUse.has(n)).sort((a, b) => a.localeCompare(b));
+};
+
+/** Parse stats from metrics general.stats (keys like "Notification:currentDay" -> { Notification: { currentDay } }) */
+export const parseMetricsStats = (stats: Record<string, unknown> | undefined): Record<string, Record<string, unknown>> => {
+	const result: Record<string, Record<string, unknown>> = {};
+	if (!stats || typeof stats !== "object") return result;
+	for (const key of Object.keys(stats)) {
+		const parts = key.split(":");
+		const group = parts[0];
+		const subKey = parts[1];
+		if (!group || !subKey) continue;
+		if (!result[group]) result[group] = {};
+		result[group][subKey] = stats[key];
+	}
+	return result;
+};
+
+export interface MessageConsumptionItem {
+	period: string;
+	count: number;
+	creates: number;
+	updates: number;
+	deletes: number;
+	failed: number;
+	avgTime: number;
+}
+
+const getNotificationValue = (
+	notification: Record<string, unknown>,
+	key: string,
+	field: "creates" | "updates" | "deletes" | "failed" | "avgTime"
+): number => {
+	const keyMap: Record<string, Record<string, string>> = {
+		total: { creates: "totalCreates", updates: "totalUpdates", deletes: "totalDeletes", failed: "totalFailed", avgTime: "totalAvgTime" },
+		currentHour: { creates: "currentHourEntityCreates", updates: "currentHourEntityUpdates", deletes: "currentHourEntityDeletes", failed: "currentHourFailed", avgTime: "currentHourAvgTime" },
+		previousHour: { creates: "previousHourEntityCreates", updates: "previousHourEntityUpdates", deletes: "previousHourEntityDeletes", failed: "previousHourFailed", avgTime: "previousHourAvgTime" },
+		currentDay: { creates: "currentDayEntityCreates", updates: "currentDayEntityUpdates", deletes: "currentDayEntityDeletes", failed: "currentDayFailed", avgTime: "currentDayAvgTime" },
+		previousDay: { creates: "previousDayEntityCreates", updates: "previousDayEntityUpdates", deletes: "previousDayEntityDeletes", failed: "previousDayFailed", avgTime: "previousDayAvgTime" }
+	};
+	const fullKey = keyMap[key]?.[field] ?? "";
+	return Number(notification[fullKey] ?? 0);
+};
+
+export interface GetMessageConsumptionDataOptions {
+	/** When false, omits the Total period (e.g. topic rows where total is shown as Processed). */
+	includeTotal?: boolean;
+}
+
+/** Extract message consumption data for bar chart from Notification stats */
+export const getMessageConsumptionData = (
+	notification: Record<string, unknown> | undefined,
+	options?: GetMessageConsumptionDataOptions
+): MessageConsumptionItem[] => {
+	if (!notification) return [];
+	const includeTotal = options?.includeTotal !== false;
+	const periods = [
+		{ key: "total", label: "Total" },
+		{ key: "currentHour", label: "Current Hour" },
+		{ key: "previousHour", label: "Previous Hour" },
+		{ key: "currentDay", label: "Current Day" },
+		{ key: "previousDay", label: "Previous Day" }
+	];
+	const selected = includeTotal ? periods : periods.filter((p) => p.key !== "total");
+	return selected.map(({ key, label }) => ({
+		period: label,
+		count: Number(notification[key] ?? 0),
+		creates: getNotificationValue(notification, key, "creates"),
+		updates: getNotificationValue(notification, key, "updates"),
+		deletes: getNotificationValue(notification, key, "deletes"),
+		failed: getNotificationValue(notification, key, "failed"),
+		avgTime: getNotificationValue(notification, key, "avgTime")
+	}));
+};
+
+/**
+ * Topic partition maps sometimes repeat `Notification:*` keys from the wire format.
+ * Strip the prefix so getMessageConsumptionData finds `currentHour`, `totalCreates`, etc.
+ */
+export const normalizeTopicMetricsRecord = (
+	topicDetail: Record<string, unknown> | undefined
+): Record<string, unknown> => {
+	if (!topicDetail || typeof topicDetail !== "object") return {};
+	const out: Record<string, unknown> = { ...topicDetail };
+	for (const key of Object.keys(topicDetail)) {
+		if (!key.startsWith("Notification:")) continue;
+		const shortKey = key.slice("Notification:".length);
+		if (shortKey && out[shortKey] === undefined) {
+			out[shortKey] = topicDetail[key];
+		}
+	}
+	return out;
+};
+
+/**
+ * True when the payload includes at least one period bucket count (hour/day series).
+ * `total` alone is not enough — legacy rows often only mirror processedMessageCount.
+ */
+export const topicRowHasPeriodMetrics = (topicDetail: Record<string, unknown> | undefined): boolean => {
+	const n = normalizeTopicMetricsRecord(topicDetail);
+	return (
+		n.currentHour !== undefined ||
+		n.previousHour !== undefined ||
+		n.currentDay !== undefined ||
+		n.previousDay !== undefined
+	);
+};
+
+const omitTopicDetailsFromNotification = (
+	notification: Record<string, unknown> | undefined
+): Record<string, unknown> => {
+	if (!notification || typeof notification !== "object") return {};
+	const { topicDetails: _omit, ...rest } = notification;
+	return rest;
+};
+
+/**
+ * One entry from `Notification.topicDetails` for getMessageConsumptionData.
+ * When the server omits per-period fields on partitions (legacy payload), merge in
+ * aggregate `Notification` (excluding `topicDetails`) so the chart matches /admin/metrics.
+ */
+export const buildTopicNotificationRecord = (
+	topicDetail: Record<string, unknown> | undefined,
+	options?: {
+		aggregateNotification?: Record<string, unknown> | undefined;
+		/** When true, fill period keys from aggregate if the topic row lacks them. */
+		useAggregateFallback?: boolean;
+	}
+): Record<string, unknown> | undefined => {
+	if (!topicDetail || typeof topicDetail !== "object") {
+		if (options?.useAggregateFallback && options?.aggregateNotification) {
+			return omitTopicDetailsFromNotification(options.aggregateNotification);
+		}
+		return undefined;
+	}
+	const normalized = normalizeTopicMetricsRecord(topicDetail);
+	if (!options?.useAggregateFallback || !options?.aggregateNotification) {
+		return normalized;
+	}
+	const base = omitTopicDetailsFromNotification(options.aggregateNotification);
+	return { ...base, ...normalized };
+};
+
+/** Chart periods without Total (Processed column shows the total). */
+export const getMessageConsumptionDataExcludingTotal = (
+	notification: Record<string, unknown> | undefined
+): MessageConsumptionItem[] =>
+	getMessageConsumptionData(notification, { includeTotal: false });
+
+export interface ClassificationDistributionItem {
+	name: string;
+	count: number;
+}
+
+/** Top classifications by entity count from tag.tagEntities */
+export const getClassificationDistribution = (
+	tag: Record<string, unknown> | undefined,
+	topN = 5
+): ClassificationDistributionItem[] => {
+	const tagEntities = tag?.tagEntities as Record<string, number> | undefined;
+	if (!tagEntities) return [];
+	return Object.entries(tagEntities)
+		.map(([name, count]) => ({ name, count: Number(count) || 0 }))
+		.sort((a, b) => b.count - a.count)
+		.slice(0, topN);
+};
diff --git a/dashboard/src/utils/scopedQuickSearchUtils.ts b/dashboard/src/utils/scopedQuickSearchUtils.ts
new file mode 100644
index 000000000..81a97c44e
--- /dev/null
+++ b/dashboard/src/utils/scopedQuickSearchUtils.ts
@@ -0,0 +1,466 @@
+/*
+ * 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.
+ */
+
+import type { TreeNode } from "@models/treeStructureType";
+import type {
+	ChildrenInterface,
+	ServiceTypeInterface,
+	TypeHeaderInterface
+} from "@models/entityTreeType";
+import { addOnEntities } from "./Enum";
+import { customSortBy, customSortByObjectKeys, isEmpty } from "./Utils";
+
+export type QuickSearchScope =
+	| "default"
+	| "entity"
+	| "classification"
+	| "glossary"
+	| "businessMetadata";
+
+export type ScopedOptionKind =
+	| "entity-service"
+	| "entity-type"
+	| "classification"
+	| "glossary-term"
+	| "business-metadata";
+
+export interface ScopedQuickSearchOption {
+	id: string;
+	title: string;
+	group: string;
+	kind: ScopedOptionKind;
+	entityTypeName?: string;
+	serviceUnderlyingTypeNames?: string[];
+	classificationName?: string;
+	termGuid?: string;
+	glossaryGuid?: string;
+	termId?: string;
+	termParent?: string;
+	bmGuid?: string;
+}
+
+interface MetricsEntitySnapshot {
+	entityActive?: Record<string, number>;
+	entityDeleted?: Record<string, number>;
+}
+
+interface GlossaryTermCategoryRow {
+	parentCategoryGuid?: string;
+	categoryGuid?: string;
+	displayText?: string;
+	termGuid?: string;
+}
+
+interface GlossaryApiRow {
+	name: string;
+	guid: string;
+	categories?: GlossaryTermCategoryRow[];
+	terms?: GlossaryTermCategoryRow[];
+}
+
+const DEFAULT_SERVICE = "other_types";
+
+const generateServiceTypeArr = (
+	entityCountArr: ServiceTypeInterface[],
+	serviceType: string,
+	children: ChildrenInterface,
+	entityCount: number
+) => {
+	const existing = entityCountArr.find(
+		(obj): obj is ServiceTypeInterface =>
+			typeof obj === "object" && obj !== null && serviceType in obj
+	);
+	if (existing) {
+		const bucket = (existing as Record<string, {
+			children: ChildrenInterface[];
+			totalCount: number;
+		}>)[serviceType];
+		if (bucket) {
+			bucket.children.push(children);
+			bucket.totalCount += entityCount;
+		}
+	} else {
+		entityCountArr.push({
+			[serviceType]: {
+				children: [children],
+				name: serviceType,
+				totalCount: entityCount
+			}
+		} as ServiceTypeInterface);
+	}
+};
+
+const pushRootEntityToTree = (
+	entities: ServiceTypeInterface[],
+	allEntityCategory: string | undefined
+) => {
+	const rootEntityChildren: ChildrenInterface = {
+		gType: "Entity",
+		guid: addOnEntities[0],
+		id: addOnEntities[0],
+		name: addOnEntities[0],
+		type: allEntityCategory,
+		text: addOnEntities[0]
+	};
+	const hasOther = entities.some((obj) => obj["other_types"] !== undefined);
+	if (hasOther) {
+		const idx = entities.findIndex((obj) => "other_types" in obj);
+		(entities[idx] as ServiceTypeInterface)["other_types"].children.push(
+			rootEntityChildren
+		);
+	} else {
+		entities.push({
+			other_types: {
+				name: "other_types",
+				children: [rootEntityChildren],
+				totalCount: 0
+			}
+		} as ServiceTypeInterface);
+	}
+	return entities;
+};
+
+/**
+ * Mirrors {@link EntitiesTree} group view (service type → entity typedefs).
+ */
+export const buildEntitiesTreeForQuickSearch = (
+	typeHeaderData: TypeHeaderInterface[] | null | undefined,
+	metricsEntity: MetricsEntitySnapshot | null | undefined,
+	allEntityCategory: string | undefined
+): TreeNode[] => {
+	if (!Array.isArray(typeHeaderData) || !typeHeaderData.length || !metricsEntity) {
+		return [];
+	}
+	const active = metricsEntity.entityActive || {};
+	const deleted = metricsEntity.entityDeleted || {};
+	const newArr: ServiceTypeInterface[] = [];
+
+	typeHeaderData.forEach((entity) => {
+		let { serviceType = DEFAULT_SERVICE, category, name, guid } = entity;
+		if (category !== "ENTITY") return;
+		const entityCount =
+			Number(active[name] ?? 0) + Number(deleted[name] ?? 0);
+		const modelName = entityCount ? `${name} (${entityCount})` : name;
+		const children: ChildrenInterface = {
+			text: modelName,
+			name,
+			type: category,
+			gType: "Entity",
+			guid,
+			id: guid
+		};
+		generateServiceTypeArr(newArr, serviceType, children, entityCount);
+	});
+
+	pushRootEntityToTree(newArr, allEntityCategory);
+
+	const child = (childs: ChildrenInterface[]) => {
+		if (!childs?.length) return [];
+		return customSortBy(
+			childs.map((obj) => ({
+				id: obj.name as string,
+				label: obj.text as string,
+				types: "child"
+			})),
+			["label"]
+		);
+	};
+
+	const sorted = customSortByObjectKeys(newArr);
+	return sorted.map((entity: ServiceTypeInterface) => {
+		const key = Object.keys(entity)[0];
+		const entityData = entity[key];
+		return {
+			id: entityData.name,
+			label:
+				entityData.totalCount === 0
+					? entityData.name
+					: `${entityData.name} (${entityData.totalCount})`,
+			children: child(entityData.children),
+			types: "parent"
+		};
+	});
+};
+
+const filterTreeNodes = (treeData: TreeNode[], searchTerm: string): TreeNode[] => {
+	const q = searchTerm.trim().toLowerCase();
+	if (!q) return treeData;
+	return treeData
+		.filter(
+			(node) =>
+				node.label?.toLowerCase().includes(q) ||
+				node.children?.some((child) => child.label?.toLowerCase().includes(q))
+		)
+		.map((node) => {
+			const parentMatches = node.label?.toLowerCase().includes(q) ?? false;
+			const kids = node.children?.length
+				? parentMatches
+					? node.children
+					: node.children.filter((c) => c.label?.toLowerCase().includes(q))
+				: undefined;
+			return { ...node, children: kids };
+		});
+};
+
+export const entityTreeToScopedOptions = (
+	tree: TreeNode[],
+	searchTerm: string
+): ScopedQuickSearchOption[] => {
+	const filtered = filterTreeNodes(tree, searchTerm);
+	const out: ScopedQuickSearchOption[] = [];
+	for (const parent of filtered) {
+		const underlying =
+			parent.children?.map((c) => c.id).filter(Boolean) ?? [];
+		out.push({
+			id: `svc:${parent.id}`,
+			title: parent.label,
+			group: "Entity",
+			kind: "entity-service",
+			serviceUnderlyingTypeNames: underlying
+		});
+		for (const child of parent.children ?? []) {
+			out.push({
+				id: `type:${child.id}`,
+				title: child.label,
+				group: "Entity",
+				kind: "entity-type",
+				entityTypeName: child.id
+			});
+		}
+	}
+	return out;
+};
+
+interface ClassificationDefRow {
+	name: string;
+	subTypes: string[];
+	guid: string;
+	superTypes: string[];
+}
+
+/** Depth-first classification list (same traversal as sidebar tree). */
+export const buildClassificationScopedOptions = (
+	classificationData: { classificationDefs: ClassificationDefRow[] } | null,
+	tagEntities: Record<string, number> | undefined,
+	searchTerm: string
+): ScopedQuickSearchOption[] => {
+	if (!classificationData?.classificationDefs?.length) return [];
+	const defs = classificationData.classificationDefs;
+	const byName = new Map(defs.map((d) => [d.name, d]));
+	const q = searchTerm.trim().toLowerCase();
+	const out: ScopedQuickSearchOption[] = [];
+	const seen = new Set<string>();
+
+	const visit = (typeName: string) => {
+		if (seen.has(typeName)) return;
+		seen.add(typeName);
+		const def = byName.get(typeName);
+		if (!def) return;
+		const count = tagEntities?.[typeName];
+		const label =
+			count !== undefined ? `${typeName} (${count})` : typeName;
+		if (!q || label.toLowerCase().includes(q) || typeName.toLowerCase().includes(q)) {
+			out.push({
+				id: `cls:${def.guid}:${typeName}`,
+				title: label,
+				group: "Classification",
+				kind: "classification",
+				classificationName: typeName
+			});
+		}
+		(def.subTypes ?? []).forEach((st) => visit(st));
+	};
+
+	defs
+		.filter((d) => isEmpty(d.superTypes))
+		.forEach((d) => visit(d.name));
+
+	return customSortBy(out, ["title"]);
+};
+
+/** Build glossary tree for “terms” mode (see {@link GlossaryTree} glossaryType true). */
+export const buildGlossaryTermsTreeForQuickSearch = (
+	glossaryData: GlossaryApiRow[] | null | undefined
+): TreeNode[] => {
+	if (!glossaryData?.length) return [];
+	const glossaryType = true;
+
+	const toServiceRows: Record<string, {
+		name: string;
+		children: ChildrenInterface[];
+		id: string;
+		types: string;
+		parent: string;
+		guid: string;
+	}>[] = glossaryData.map((glossary) => {
+		const categoryRelation =
+			glossary.categories?.filter((o) => o.parentCategoryGuid !== undefined) ??
+			[];
+
+		const getChildren = (glossaries: {
+			children: NonNullable<GlossaryApiRow["terms"]>;
+			parent: string;
+		}) => {
+			if (isEmpty(glossaries.children)) return [];
+			return glossaries.children
+				.map((glossariesType) => {
+					const getChild = () =>
+						categoryRelation
+							.map((obj) => {
+								if (obj.parentCategoryGuid === glossariesType.categoryGuid) {
+									return {
+										name: obj.displayText,
+										id: obj.displayText,
+										children: [] as ChildrenInterface[],
+										types: "child",
+										parent: glossaries.parent,
+										cGuid: glossaryType ? obj.termGuid : obj.categoryGuid,
+										guid: glossary.guid
+									};
+								}
+								return undefined;
+							})
+							.filter(Boolean) as ChildrenInterface[];
+					if (glossariesType.parentCategoryGuid === undefined) {
+						return {
+							name: glossariesType.displayText,
+							id: glossariesType.displayText,
+							children: getChild(),
+							types: "child",
+							parent: glossaries.parent,
+							cGuid: glossaryType
+								? glossariesType.termGuid
+								: glossariesType.categoryGuid,
+							guid: glossary.guid
+						} as ChildrenInterface;
+					}
+					return undefined;
+				})
+				.filter(Boolean) as ChildrenInterface[];
+		};
+
+		const children = getChildren({
+			children: glossary?.terms ?? [],
+			parent: glossary.name
+		});
+
+		return {
+			[glossary.name]: {
+				name: glossary.name,
+				children: children || [],
+				id: glossary.guid,
+				types: "parent",
+				parent: glossary.name,
+				guid: glossary.guid
+			}
+		};
+	});
+
+	const child = (childs: ChildrenInterface[]): TreeNode[] => {
+		if (!childs?.length) return [];
+		return customSortBy(
+			childs.map((obj) => ({
+				id: obj?.name as string,
+				label: obj?.name as string,
+				children:
+					obj?.children !== undefined
+						? child(obj.children.filter(Boolean) as ChildrenInterface[])
+						: [],
+				types: obj?.types,
+				parent: obj?.parent,
+				guid: obj?.guid,
+				cGuid: obj?.cGuid
+			})),
+			["label"]
+		);
+	};
+
+	const sorted = customSortByObjectKeys(toServiceRows as ServiceTypeInterface[]);
+	return sorted.map((entity: Record<string, {
+		name: string;
+		children: ChildrenInterface[];
+		types: string;
+		parent: string;
+		guid: string;
+	}>) => {
+		const g = entity[Object.keys(entity)[0]];
+		return {
+			id: g.name,
+			label: g.name,
+			children: child((g.children ?? []) as ChildrenInterface[]),
+			types: g.types,
+			parent: g.parent,
+			guid: g.guid
+		};
+	});
+};
+
+const collectGlossaryTermOptions = (
+	nodes: TreeNode[],
+	glossaryLabel: string,
+	out: ScopedQuickSearchOption[]
+) => {
+	for (const n of nodes) {
+		if (n.cGuid && n.types === "child" && n.id) {
+			out.push({
+				id: `term:${n.cGuid}`,
+				title: `${n.label} (${glossaryLabel})`,
+				group: "Glossary / Terms",
+				kind: "glossary-term",
+				termGuid: n.cGuid as string,
+				glossaryGuid: (n.guid as string) ?? "",
+				termId: n.id,
+				termParent: (n.parent as string) ?? glossaryLabel
+			});
+		}
+		if (n.children?.length) {
+			collectGlossaryTermOptions(n.children, glossaryLabel, out);
+		}
+	}
+};
+
+export const glossaryTreeToScopedOptions = (
+	tree: TreeNode[],
+	searchTerm: string
+): ScopedQuickSearchOption[] => {
+	const filtered = filterTreeNodes(tree, searchTerm);
+	const out: ScopedQuickSearchOption[] = [];
+	for (const parent of filtered) {
+		collectGlossaryTermOptions(parent.children ?? [], parent.label, out);
+	}
+	return customSortBy(out, ["title"]);
+};
+
+export const buildBusinessMetadataScopedOptions = (
+	businessMetadataDefs: Array<{ name: string; guid: string }> | undefined,
+	searchTerm: string
+): ScopedQuickSearchOption[] => {
+	if (!businessMetadataDefs?.length) return [];
+	const q = searchTerm.trim().toLowerCase();
+	return customSortBy(
+		businessMetadataDefs
+			.filter((d) => !q || d.name.toLowerCase().includes(q))
+			.map((d) => ({
+				id: `bm:${d.guid}`,
+				title: d.name,
+				group: "Business Metadata",
+				kind: "business-metadata" as const,
+				bmGuid: d.guid
+			})),
+		["title"]
+	);
+};
diff --git a/dashboard/src/utils/typeCatalogUtils.ts b/dashboard/src/utils/typeCatalogUtils.ts
new file mode 100644
index 000000000..078a36c79
--- /dev/null
+++ b/dashboard/src/utils/typeCatalogUtils.ts
@@ -0,0 +1,159 @@
+/*
+ * 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.
+ */
+
+import type { EntityTypeDistributionItem } from "./metricsUtils";
+
+/** Minimal typedef row from `/api/atlas/types/typedefs/headers` (see EntitiesTree). */
+export interface TypeHeaderCatalogRow {
+	name: string;
+	category: string;
+	serviceType?: string;
+	guid?: string;
+}
+
+export interface DashboardTypeCatalog {
+	classificationNames: string[];
+	/** Glossary-related entity typedef names (Atlas glossary model). */
+	glossaryTermRelatedTypeNames: string[];
+	businessMetadataNames: string[];
+	/** All ENTITY typedef names (sorted). */
+	entityTypeNames: string[];
+}
+
+const DEFAULT_SERVICE_TYPE = "other_types";
+
+const countForEntityType = (
+	entity: Record<string, unknown> | undefined,
+	typeName: string
+): { active: number; deleted: number } => {
+	const active = (entity?.entityActive as Record<string, number>) || {};
+	const deleted = (entity?.entityDeleted as Record<string, number>) || {};
+	return {
+		active: Number(active[typeName] ?? 0) || 0,
+		deleted: Number(deleted[typeName] ?? 0) || 0,
+	};
+};
+
+/**
+ * Service-type buckets aligned with the Entities sidebar (`serviceType` on each ENTITY typedef).
+ * Falls back to `{typeName}_` prefix grouping when headers are missing (e.g. hive_table → hive).
+ */
+export const getServiceTypeDistribution = (
+	entity: Record<string, unknown> | undefined,
+	typeHeaders: TypeHeaderCatalogRow[] | null | undefined,
+	topN = 5
+): EntityTypeDistributionItem[] => {
+	const active = (entity?.entityActive as Record<string, number>) || {};
+	const deleted = (entity?.entityDeleted as Record<string, number>) || {};
+	const map = new Map<
+		string,
+		{ active: number; deleted: number; typeNames: Set<string> }
+	>();
+
+	const add = (serviceKey: string, typeName: string) => {
+		const { active: a, deleted: d } = countForEntityType(entity, typeName);
+		const cur = map.get(serviceKey) ?? {
+			active: 0,
+			deleted: 0,
+			typeNames: new Set<string>(),
+		};
+		cur.active += a;
+		cur.deleted += d;
+		cur.typeNames.add(typeName);
+		map.set(serviceKey, cur);
+	};
+
+	if (Array.isArray(typeHeaders) && typeHeaders.length > 0) {
+		for (const row of typeHeaders) {
+			if (row.category !== "ENTITY") continue;
+			const st = (row.serviceType?.trim() || DEFAULT_SERVICE_TYPE) as string;
+			add(st, row.name);
+		}
+	} else {
+		const allTypes = new Set([...Object.keys(active), ...Object.keys(deleted)]);
+		allTypes.forEach((typeName) => {
+			const i = typeName.indexOf("_");
+			const serviceKey = i === -1 ? typeName : typeName.slice(0, i);
+			add(serviceKey, typeName);
+		});
+	}
+
+	const rows: EntityTypeDistributionItem[] = [...map.entries()].map(
+		([name, { active: a, deleted: d, typeNames }]) => ({
+			name,
+			active: a,
+			deleted: d,
+			count: a + d,
+			underlyingTypeNames: [...typeNames].sort(),
+		})
+	);
+
+	rows.sort((x, y) => y.count - x.count || x.name.localeCompare(y.name));
+
+	const top = rows.slice(0, topN);
+	if (top.length === topN) return top;
+
+	const used = new Set(top.map((r) => r.name));
+	const pad = rows
+		.filter((r) => !used.has(r.name))
+		.sort((a, b) => a.name.localeCompare(b.name));
+	while (top.length < topN && pad.length > 0) {
+		const next = pad.shift();
+		if (next) top.push(next);
+	}
+	return top;
+};
+
+/** Lists derived from type headers for search / future features. */
+export const buildDashboardTypeCatalog = (
+	typeHeaders: TypeHeaderCatalogRow[] | null | undefined
+): DashboardTypeCatalog => {
+	const empty: DashboardTypeCatalog = {
+		classificationNames: [],
+		glossaryTermRelatedTypeNames: [],
+		businessMetadataNames: [],
+		entityTypeNames: [],
+	};
+	if (!Array.isArray(typeHeaders) || typeHeaders.length === 0) return empty;
+
+	const classificationNames: string[] = [];
+	const businessMetadataNames: string[] = [];
+	const entityTypeNames: string[] = [];
+	const glossaryTermRelatedTypeNames: string[] = [];
+
+	for (const row of typeHeaders) {
+		const { name, category } = row;
+		if (!name) continue;
+		if (category === "CLASSIFICATION") classificationNames.push(name);
+		else if (category === "BUSINESS_METADATA") businessMetadataNames.push(name);
+		else if (category === "ENTITY") {
+			entityTypeNames.push(name);
+			if (name.toLowerCase().includes("glossary")) {
+				glossaryTermRelatedTypeNames.push(name);
+			}
+		}
+	}
+
+	const sortUnique = (arr: string[]) => [...new Set(arr)].sort((a, b) => a.localeCompare(b));
+
+	return {
+		classificationNames: sortUnique(classificationNames),
+		businessMetadataNames: sortUnique(businessMetadataNames),
+		entityTypeNames: sortUnique(entityTypeNames),
+		glossaryTermRelatedTypeNames: sortUnique(glossaryTermRelatedTypeNames),
+	};
+};
diff --git a/dashboard/src/views/Administrator/AdministratorLayout.tsx b/dashboard/src/views/Administrator/AdministratorLayout.tsx
index 302da4313..7e1e2abc8 100644
--- a/dashboard/src/views/Administrator/AdministratorLayout.tsx
+++ b/dashboard/src/views/Administrator/AdministratorLayout.tsx
@@ -19,7 +19,7 @@ import { LinkTab } from "@components/muiComponents";
 import { Stack, Tabs } from "@mui/material";
 import { Item, samePageLinkNavigation } from "@utils/Muiutils";
 import { isEmpty } from "@utils/Utils";
-import { useState } from "react";
+import { useState, useEffect } from "react";
 import { useLocation, useNavigate } from "react-router-dom";
 import BusinessMetadataTab from "./BusinessMetadataTab";
 import Enumerations from "./Enumerations";
@@ -44,6 +44,26 @@ const AdministratorLayout = () => {
     !isEmpty(activeTab) ? allTabs.findIndex((val) => val === activeTab) : 0
   );
 
+  useEffect(() => {
+    const tabIndex = !isEmpty(activeTab)
+      ? allTabs.findIndex((val) => val === activeTab)
+      : 0;
+    const resolvedIndex = tabIndex >= 0 ? tabIndex : 0;
+    setValue(resolvedIndex);
+
+    if (activeTab && activeTab !== "businessMetadata") {
+      setForm(false);
+    }
+    const createParam = searchParams.get("create");
+    if (createParam === "true" && activeTab === "businessMetadata") {
+      setForm(true);
+      setBMAttribute({});
+      const newParams = new URLSearchParams(location.search);
+      newParams.delete("create");
+      navigate({ pathname: "/administrator", search: newParams.toString() }, { replace: true });
+    }
+  }, [activeTab, location.search, navigate]);
+
   const handleChange = (event: React.SyntheticEvent, newValue: number) => {
     if (
       event.type !== "click" ||
diff --git a/dashboard/src/views/Administrator/Audits/AuditResults.tsx b/dashboard/src/views/Administrator/Audits/AuditResults.tsx
index 9deef0525..a287456f7 100644
--- a/dashboard/src/views/Administrator/Audits/AuditResults.tsx
+++ b/dashboard/src/views/Administrator/Audits/AuditResults.tsx
@@ -15,22 +15,13 @@
  * limitations under the License.
  */
 
-import {
-  Divider,
-  Grid,
-  Link,
-  List,
-  ListItem,
-  ListItemText,
-  Stack,
-  Typography,
-} from "@mui/material";
+import { Grid, Link, List, ListItem, ListItemText, Typography } from "@mui/material";
 import { auditAction, category } from "@utils/Enum";
-import { isArray, isEmpty, jsonParse } from "@utils/Utils";
+import { isEmpty, jsonParse } from "@utils/Utils";
 import CustomModal from "@components/Modal";
+import TypeDefAuditDetailModal from "@components/TypeDefAuditDetailModal";
 import { useState } from "react";
-import { getValues } from "@components/commonComponents";
-import { Item, StyledPaper } from "@utils/Muiutils";
+import { Item } from "@utils/Muiutils";
 import AuditsTab from "@views/DetailPage/EntityDetailTabs/AuditsTab";
 import ImportExportAudits from "./ImportExportAudits";
 
@@ -196,65 +187,12 @@ const AuditResults = ({ componentProps, row }: any) => {
         <ImportExportAudits auditObj={auditObj} />
       )}
 
-      <CustomModal
+      <TypeDefAuditDetailModal
         open={openModal}
         onClose={handleCloseModal}
-        title={`${category[currentResultObj.category]} Type Details: ${
-          currentResultObj.name
-        }`}
-        footer={false}
-        button1Handler={undefined}
-        button2Handler={undefined}
-      >
-        <StyledPaper variant="outlined">
-          {" "}
-          {!isEmpty(currentResultObj)
-            ? Object.entries(currentResultObj)
-                .sort()
-                .map(([keys, value]: [string, any]) => {
-                  return (
-                    <>
-                      <Stack
-                        direction="row"
-                        spacing={4}
-                        marginBottom={1}
-                        marginTop={1}
-                      >
-                        <div
-                          style={{
-                            flex: 1,
-                            wordBreak: "break-all",
-                            textAlign: "left",
-                            fontWeight: "600",
-                          }}
-                        >
-                          {`${keys} ${
-                            isArray(value) ? `(${value.length})` : ""
-                          }`}
-                        </div>
-                        <div
-                          style={{
-                            flex: 1,
-                            wordBreak: "break-all",
-                            textAlign: "left",
-                          }}
-                        >
-                          {getValues(
-                            value,
-                            undefined,
-                            undefined,
-                            undefined,
-                            "properties"
-                          )}
-                        </div>
-                      </Stack>
-                      <Divider />
-                    </>
-                  );
-                })
-            : "No Record Found"}
-        </StyledPaper>
-      </CustomModal>
+        detailObject={currentResultObj}
+        maxWidth="sm"
+      />
 
       {(operation == "PURGE" || operation == "AUTO_PURGE") && (
         <CustomModal
diff --git a/dashboard/src/views/BusinessMetadata/BusinessMetadataAtrributeForm.tsx b/dashboard/src/views/BusinessMetadata/BusinessMetadataAtrributeForm.tsx
index 6e161f68f..d32eb7017 100644
--- a/dashboard/src/views/BusinessMetadata/BusinessMetadataAtrributeForm.tsx
+++ b/dashboard/src/views/BusinessMetadata/BusinessMetadataAtrributeForm.tsx
@@ -898,6 +898,7 @@ const BusinessMetadataAttributeForm = ({
               maxWidth="sm"
               button2Handler={handleSubmit(onSubmit)}
               disableButton2={isSubmitting}
+              button2Loading={isSubmitting}
             >
               <Stack gap={2} paddingTop="2rem" paddingBottom="2rem">
                 <EnumCreateUpdate
diff --git a/dashboard/src/views/BusinessMetadata/BusinessMetadataForm.tsx b/dashboard/src/views/BusinessMetadata/BusinessMetadataForm.tsx
index 950a6b3ff..9d31691e5 100644
--- a/dashboard/src/views/BusinessMetadata/BusinessMetadataForm.tsx
+++ b/dashboard/src/views/BusinessMetadata/BusinessMetadataForm.tsx
@@ -42,6 +42,7 @@ import BusinessMetadataAttributeForm from "./BusinessMetadataAtrributeForm";
 import { setEditBMAttribute } from "@redux/slice/createBMSlice";
 import { cloneDeep } from "@utils/Helper";
 import { fetchBusinessMetaData } from "@redux/slice/typeDefSlices/typedefBusinessMetadataSlice";
+import { fetchEntityData } from "@redux/slice/typeDefSlices/typedefEntitySlice";
 import { defaultType } from "@utils/Enum";
 import { getTypeName } from "@utils/CommonViewFunction";
 
@@ -340,6 +341,7 @@ const BusinessMetaDataForm = ({
       let bmName = response?.data?.businessMetadataDefs?.[0]?.name;
       toastMssg(bmName);
       dispatchState(fetchBusinessMetaData());
+      dispatchState(fetchEntityData());
       setBMAttribute({});
       setForm(false);
     } catch (error) {
diff --git a/dashboard/src/views/Classification/AddTag.tsx b/dashboard/src/views/Classification/AddTag.tsx
index f06fbc6bb..1ec08ac9f 100644
--- a/dashboard/src/views/Classification/AddTag.tsx
+++ b/dashboard/src/views/Classification/AddTag.tsx
@@ -381,6 +381,7 @@ const AddTag = (props: {
       disableButton2={
         isEmpty(classificationData) ? true : isSubmitting
       }
+      button2Loading={isSubmitting}
       isDirty={
         isEmpty(classificationData)
           ? false
diff --git a/dashboard/src/views/Classification/AddTagAttributes.tsx b/dashboard/src/views/Classification/AddTagAttributes.tsx
index 107045a17..34d4392e8 100644
--- a/dashboard/src/views/Classification/AddTagAttributes.tsx
+++ b/dashboard/src/views/Classification/AddTagAttributes.tsx
@@ -145,6 +145,7 @@ const AddTagAttributes = ({ open, onClose }: any) => {
         button2Label="Add"
         button2Handler={handleSubmit(onSubmit)}
         disableButton2={isSubmitting}
+        button2Loading={isSubmitting}
       >
         <form onSubmit={handleSubmit(onSubmit)}>
           {/* <TagAtrributes control={control} /> */}
diff --git a/dashboard/src/views/Classification/ClassificationForm.tsx b/dashboard/src/views/Classification/ClassificationForm.tsx
index 170f9f16c..943cabdb6 100644
--- a/dashboard/src/views/Classification/ClassificationForm.tsx
+++ b/dashboard/src/views/Classification/ClassificationForm.tsx
@@ -48,6 +48,7 @@ import { paramsType } from "@models/detailPageType";
 import TagAtrributes from "./TagAttributes";
 import { fetchClassificationData } from "@redux/slice/typeDefSlices/typedefClassificationSlice";
 import { AntSwitch } from "@utils/Muiutils";
+import { refreshDashboardHomeData } from "@utils/refreshDashboardHome";
 
 const ClassificationForm = ({
   open,
@@ -202,7 +203,8 @@ const ClassificationForm = ({
           isAdd ? "created" : "updated"
         } successfully`
       );
-      fetchInitialData();
+      await fetchInitialData();
+      refreshDashboardHomeData(dispatchApi);
     } catch (error) {
       console.error(
         `Error while ${isAdd ? "creating" : "updating"} classification`,
@@ -223,6 +225,7 @@ const ClassificationForm = ({
         button1Handler={onClose}
         button2Label={isAdd ? "Create" : "Save"}
         disableButton2={isSubmitting}
+        button2Loading={isSubmitting}
         isDirty={isDirty}
         maxWidth="sm"
         button2Handler={handleSubmit(onSubmit)}
diff --git a/dashboard/src/views/Classification/DeleteTag.tsx b/dashboard/src/views/Classification/DeleteTag.tsx
index 71b4448f6..4bc2d7a19 100644
--- a/dashboard/src/views/Classification/DeleteTag.tsx
+++ b/dashboard/src/views/Classification/DeleteTag.tsx
@@ -77,6 +77,7 @@ const DeleteTag = (props: {
         maxWidth="sm"
         button2Handler={handleRemove}
         disableButton2={loader}
+        button2Loading={loader}
       >
         <Typography fontSize={15}>
           Are you sure you want to delete classification
diff --git a/dashboard/src/views/DashBoard.tsx b/dashboard/src/views/DashBoard.tsx
index 9b8dde430..c0b5a201e 100644
--- a/dashboard/src/views/DashBoard.tsx
+++ b/dashboard/src/views/DashBoard.tsx
@@ -15,65 +15,40 @@
  * limitations under the License.
  */
 
+import { Stack } from "@mui/material";
 import QuickSearch from "@components/GlobalSearch/QuickSearch";
-import { CustomButton } from "@components/muiComponents";
+import DashboardOverview from "./DashboardOverview/DashboardOverview";
 import { useAppSelector } from "@hooks/reducerHook";
-import { Stack } from "@mui/material";
-import { useState } from "react";
-import EntityForm from "./Entity/EntityForm";
-import AddIcon from "@mui/icons-material/Add";
 
 const DashBoard = () => {
-  const { sessionObj = "" }: any = useAppSelector(
-    (state: any) => state.session
-  );
-  const [entityModal, setEntityModal] = useState<boolean>(false);
-  const { data } = sessionObj || {};
-  const key = "atlas.entity.create.allowed";
-  const entityCreate = data?.[key] || "";
+	const dashboardRefreshVersion = useAppSelector((state) => state.dashboardRefresh.version);
 
-  const handleOpenEntityModal = () => {
-    setEntityModal(true);
-  };
-  const handleCloseEntityModal = () => {
-    setEntityModal(false);
-  };
-  return (
-    <Stack
-      alignItems="flex-start"
-      justifyContent="space-between"
-      position="relative"
-      height="100%"
-      flex="1"
-      padding="0"
-    >
-      <Stack direction="row" justifyContent="flex-end" width={"100%"}>
-        {entityCreate && (
-          <CustomButton
-            variant="contained"
-            size="small"
-            onClick={(_e: any) => handleOpenEntityModal()}
-            startIcon={<AddIcon />}
-          >
-            Create Entity
-          </CustomButton>
-        )}
-      </Stack>
-      <Stack
-        justifyContent="center"
-        flex="1"
-        alignItems={"center"}
-        height={"100%"}
-        width={"100%"}
-        className="dashboard-quick-search"
-      >
-        <QuickSearch />
-      </Stack>
-      {entityModal && (
-        <EntityForm open={entityModal} onClose={handleCloseEntityModal} />
-      )}
-    </Stack>
-  );
+	return (
+		<Stack
+			width="100%"
+			maxWidth="100%"
+			alignItems="stretch"
+			justifyContent="flex-start"
+			position="relative"
+			height="100%"
+			flex="1"
+			padding={0}
+			spacing={2}
+			sx={{ boxSizing: "border-box", overflow: "hidden" }}
+		>
+			<Stack
+				direction="row"
+				width="100%"
+				justifyContent="center"
+				sx={{ mb: 2, flexShrink: 0 }}
+			>
+				<QuickSearch key={dashboardRefreshVersion} />
+			</Stack>
+			<Stack width="100%" flex={1} sx={{ minWidth: 0 }}>
+				<DashboardOverview />
+			</Stack>
+		</Stack>
+	);
 };
 
 export default DashBoard;
diff --git a/dashboard/src/views/DashboardOverview/ClassificationCoverage.tsx b/dashboard/src/views/DashboardOverview/ClassificationCoverage.tsx
new file mode 100644
index 000000000..21fc18588
--- /dev/null
+++ b/dashboard/src/views/DashboardOverview/ClassificationCoverage.tsx
@@ -0,0 +1,394 @@
+/*
+ * 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.
+ */
+
+import { memo, useCallback, useEffect, useMemo, useState } from "react";
+import {
+	Paper,
+	Stack,
+	Typography,
+	Box,
+	List,
+	ListItem,
+	Link,
+	TextField,
+	InputAdornment,
+} from "@mui/material";
+import SearchIcon from "@mui/icons-material/Search";
+import { Link as RouterLink, useNavigate } from "react-router-dom";
+import CustomModal from "@components/Modal";
+import { numberFormatWithComma } from "@utils/Helper";
+import {
+	getClassificationTypesInUseCount,
+	getUnusedClassificationNames,
+} from "@utils/metricsUtils";
+import { navigateToTaggedSearch } from "@utils/dashboardSearchUtils";
+import { useAppDispatch, useAppSelector } from "@hooks/reducerHook";
+import { fetchClassificationData } from "@redux/slice/typeDefSlices/typedefClassificationSlice";
+
+interface ClassificationCoverageProps {
+	/** Defined classification types in the type system (from general.tagCount) */
+	classificationTypeDefinitions: number;
+	tag: Record<string, unknown> | undefined;
+	isLoading?: boolean;
+}
+
+const ClassificationCoverage = memo(
+	({
+		classificationTypeDefinitions,
+		tag,
+		isLoading,
+	}: ClassificationCoverageProps) => {
+		const navigate = useNavigate();
+		const dispatch = useAppDispatch();
+		const { classificationData, loadingClassification } = useAppSelector(
+			(state: { classification?: { classificationData?: { classificationDefs?: { name: string }[] } | null; loadingClassification?: boolean } }) =>
+				state.classification ?? {}
+		);
+
+		useEffect(() => {
+			if (!classificationData && !loadingClassification) {
+				void dispatch(fetchClassificationData());
+			}
+		}, [classificationData, loadingClassification, dispatch]);
+
+		const definedNames = useMemo(() => {
+			const defs =
+				classificationData?.classificationDefs as { name?: string }[] | undefined;
+			if (!Array.isArray(defs)) return [];
+			return defs.map((d) => d.name).filter((n): n is string => Boolean(n));
+		}, [classificationData]);
+
+		const typesInUse = useMemo(
+			() => getClassificationTypesInUseCount(tag),
+			[tag]
+		);
+		const unusedNames = useMemo(
+			() => getUnusedClassificationNames(definedNames, tag),
+			[definedNames, tag]
+		);
+		const unusedCount = unusedNames.length;
+
+		const typeUsageProgress =
+			classificationTypeDefinitions > 0
+				? (typesInUse / classificationTypeDefinitions) * 100
+				: 0;
+		const usagePercentRounded = Math.min(
+			100,
+			Math.round(Number.isFinite(typeUsageProgress) ? typeUsageProgress : 0)
+		);
+
+		const [unusedModalOpen, setUnusedModalOpen] = useState(false);
+		const [unusedListSearchQuery, setUnusedListSearchQuery] = useState("");
+
+		const handleClassificationsClick = useCallback(() => {
+			navigateToTaggedSearch(navigate);
+		}, [navigate]);
+
+		const handleOpenUnusedModal = useCallback(() => {
+			if (unusedCount > 0 && definedNames.length > 0) {
+				setUnusedListSearchQuery("");
+				setUnusedModalOpen(true);
+			}
+		}, [unusedCount, definedNames.length]);
+
+		const handleCloseUnusedModal = useCallback(() => {
+			setUnusedListSearchQuery("");
+			setUnusedModalOpen(false);
+		}, []);
+
+		const handleUnusedBarSegmentClick = useCallback(
+			(e: React.MouseEvent) => {
+				e.stopPropagation();
+				handleOpenUnusedModal();
+			},
+			[handleOpenUnusedModal]
+		);
+
+		const unusedNamesFiltered = useMemo(() => {
+			const q = unusedListSearchQuery.trim().toLowerCase();
+			if (!q) return unusedNames;
+			return unusedNames.filter((name) => name.toLowerCase().includes(q));
+		}, [unusedNames, unusedListSearchQuery]);
+
+		const showUnusedListSearch = unusedNames.length > 5;
+
+		if (isLoading) return null;
+
+		const usedBarPct = Math.min(Math.max(typeUsageProgress, 0), 100);
+		const defsReady = definedNames.length > 0 || !!classificationData;
+
+		return (
+			<Paper
+				elevation={1}
+				sx={{
+					padding: 2,
+					borderRadius: 2,
+					minHeight: 200,
+					height: "100%",
+					boxSizing: "border-box",
+					transition: "box-shadow 0.3s ease",
+					"&:hover": { boxShadow: 4 },
+				}}
+			>
+				<Box sx={{ pb: 2, borderBottom: "1px solid", borderColor: "divider" }}>
+					<Typography sx={{ fontSize: "1rem", fontWeight: 600, color: "#1a1a1a" }}>
+						Classification Types In Use
+					</Typography>
+				</Box>
+				<Stack spacing={1.5} sx={{ pt: 2 }}>
+					<Stack
+						direction="row"
+						justifyContent="space-between"
+						alignItems="center"
+						sx={{ width: "100%" }}
+					>
+						<Typography
+							sx={{
+								fontSize: "0.875rem",
+								fontWeight: 600,
+								color: "#1a1a1a",
+							}}
+						>
+							Classifications in use
+						</Typography>
+						<Typography
+							sx={{
+								fontSize: "0.875rem",
+								color: "#868e96",
+							}}
+						>
+							{usagePercentRounded}%
+						</Typography>
+					</Stack>
+					<Stack
+						direction="row"
+						sx={{
+							height: 10,
+							borderRadius: 5,
+							overflow: "hidden",
+							width: "100%",
+							backgroundColor: "#e9ecef",
+						}}
+						aria-label="Classification usage: green is in use, grey is not in use"
+					>
+						{usedBarPct > 0 ? (
+							<Box
+								component="button"
+								type="button"
+								onClick={handleClassificationsClick}
+								sx={{
+									width: `${usedBarPct}%`,
+									minWidth: 0,
+									border: "none",
+									padding: 0,
+									cursor: "pointer",
+									backgroundColor: "#16a34a",
+								}}
+								aria-label="Open classification search for types in use"
+							/>
+						) : null}
+						<Box
+							component="button"
+							type="button"
+							onClick={handleUnusedBarSegmentClick}
+							disabled={unusedCount === 0 || !defsReady}
+							sx={{
+								flex: 1,
+								minWidth: 0,
+								border: "none",
+								padding: 0,
+								cursor:
+									unusedCount > 0 && defsReady ? "pointer" : "default",
+								backgroundColor: "#e9ecef",
+							}}
+							aria-label={
+								unusedCount > 0 && defsReady
+									? `View ${unusedCount} classification types not in use`
+									: "No unused classification types to show"
+							}
+						/>
+					</Stack>
+					{defsReady && (
+						<Typography
+							component="p"
+							sx={{
+								fontSize: "0.875rem",
+								color: "#6c757d",
+								m: 0,
+							}}
+						>
+							<strong>Not in use:</strong>{" "}
+							{unusedCount > 0 ? (
+								<Link
+									component="button"
+									type="button"
+									onClick={handleOpenUnusedModal}
+									sx={{
+										fontSize: "0.875rem",
+										color: "primary.main",
+										cursor: "pointer",
+										textDecoration: "underline",
+										background: "none",
+										border: "none",
+										padding: 0,
+										verticalAlign: "baseline",
+										fontFamily: "inherit",
+									}}
+									aria-label={`Show ${unusedCount} classification types not in use`}
+								>
+									{numberFormatWithComma(unusedCount)}{" "}
+									{unusedCount === 1
+										? "classification type"
+										: "classification types"}
+								</Link>
+							) : (
+								<>
+									{numberFormatWithComma(unusedCount)}{" "}
+									{classificationTypeDefinitions > 0
+										? unusedCount === 1
+											? "classification type"
+											: "classification types"
+										: ""}
+								</>
+							)}
+						</Typography>
+					)}
+					{!defsReady && loadingClassification ? (
+						<Typography variant="caption" sx={{ color: "#868e96" }}>
+							Loading classification definitions…
+						</Typography>
+					) : null}
+					<Typography
+						component="button"
+						type="button"
+						onClick={handleClassificationsClick}
+						sx={{
+							fontSize: "0.875rem",
+							color: "#6c757d",
+							background: "none",
+							border: "none",
+							cursor: "pointer",
+							padding: 0,
+							textAlign: "left",
+							"&:hover": { color: "primary.main", textDecoration: "underline" },
+						}}
+						aria-label="Open classification search"
+					>
+						{numberFormatWithComma(typesInUse)} of{" "}
+						{numberFormatWithComma(classificationTypeDefinitions)}
+						classification types are in use (have at least one entity).
+					</Typography>
+				</Stack>
+
+				<CustomModal
+					open={unusedModalOpen}
+					onClose={handleCloseUnusedModal}
+					title="Classification types not in use"
+					maxWidth="sm"
+					button1Label="Close"
+					button1Handler={handleCloseUnusedModal}
+					button2Label=""
+					button2Handler={handleCloseUnusedModal}
+					hideButton2={true}
+				>
+					<Stack spacing={2} sx={{ pt: 0.5 }}>
+						<Typography
+							variant="body2"
+							sx={{ color: "#6c757d", lineHeight: 1.5 }}
+						>
+							These types are defined in Atlas but have no entity assignments in
+							the current metrics snapshot.
+						</Typography>
+						{showUnusedListSearch ? (
+							<TextField
+								size="small"
+								fullWidth
+								placeholder="Search classification name"
+								value={unusedListSearchQuery}
+								onChange={(e) => setUnusedListSearchQuery(e.target.value)}
+								inputProps={{
+									"aria-label": "Filter unused classifications by name",
+								}}
+								InputProps={{
+									startAdornment: (
+										<InputAdornment position="start">
+											<SearchIcon
+												sx={{ color: "#868e96", fontSize: "1.25rem" }}
+												aria-hidden
+											/>
+										</InputAdornment>
+									),
+								}}
+							/>
+						) : null}
+						<Box
+							sx={{
+								maxHeight: "min(45vh, 320px)",
+								overflowY: "auto",
+							}}
+						>
+							{unusedNamesFiltered.length === 0 ? (
+								<Typography variant="body2" color="text.secondary" sx={{ py: 2 }}>
+									{unusedListSearchQuery.trim()
+										? "No classifications match your search."
+										: "No unused classifications to list."}
+								</Typography>
+							) : (
+								<List disablePadding>
+									{unusedNamesFiltered.map((name) => (
+										<ListItem
+											key={name}
+											disablePadding
+											sx={{
+												py: 1.25,
+												borderBottom: "1px solid",
+												borderColor: "divider",
+												"&:last-child": { borderBottom: "none" },
+											}}
+										>
+											<Link
+												component={RouterLink}
+												to={{
+													pathname: `/tag/tagAttribute/${encodeURIComponent(name)}`,
+													search: new URLSearchParams({ tag: name }).toString(),
+												}}
+												onClick={handleCloseUnusedModal}
+												underline="hover"
+												color="primary"
+												sx={{
+													fontSize: "0.875rem",
+													fontWeight: 500,
+													cursor: "pointer",
+												}}
+											>
+												{name}
+											</Link>
+										</ListItem>
+									))}
+								</List>
+							)}
+						</Box>
+					</Stack>
+				</CustomModal>
+			</Paper>
+		);
+	}
+);
+
+ClassificationCoverage.displayName = "ClassificationCoverage";
+
+export default ClassificationCoverage;
diff --git a/dashboard/src/views/DashboardOverview/ClassificationDistributionCard.tsx b/dashboard/src/views/DashboardOverview/ClassificationDistributionCard.tsx
new file mode 100644
index 000000000..6da4704c7
--- /dev/null
+++ b/dashboard/src/views/DashboardOverview/ClassificationDistributionCard.tsx
@@ -0,0 +1,227 @@
+/*
+ * 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.
+ */
+
+import React, { memo, useCallback, useMemo } from "react";
+import { Paper, Stack, Typography, Box, Link } from "@mui/material";
+import {
+	BarChart,
+	Bar,
+	XAxis,
+	YAxis,
+	CartesianGrid,
+	Tooltip,
+	ResponsiveContainer,
+	Cell,
+	LabelList
+} from "recharts";
+import { useNavigate } from "react-router-dom";
+import { numberFormatWithComma } from "@utils/Helper";
+import {
+	getClassificationDistribution,
+	getTagEntityAssociationTotal,
+} from "@utils/metricsUtils";
+import { navigateToSearch, navigateToClassificationSearch } from "@utils/dashboardSearchUtils";
+import {
+	CHART_BAR_ACTIVE_BLUE,
+	CLASSIFICATION_DISTRIBUTION_CHART_MARGIN,
+} from "./dashboardChartPalette";
+
+const BAR_COLOR = CHART_BAR_ACTIVE_BLUE;
+
+interface ClassificationDistributionCardProps {
+	tag: Record<string, unknown> | undefined;
+	isLoading?: boolean;
+}
+
+const ClassificationDistributionCard = memo(({ tag, isLoading }: ClassificationDistributionCardProps) => {
+	const navigate = useNavigate();
+	const data = getClassificationDistribution(tag, 5);
+	const associationTotal = useMemo(() => getTagEntityAssociationTotal(tag), [tag]);
+
+	const handleBarClick = useCallback(
+		(entry: { name: string }) => {
+			navigateToClassificationSearch(navigate, entry.name);
+		},
+		[navigate]
+	);
+
+	const handleViewAll = useCallback(() => {
+		navigateToSearch(navigate, "all_classifications");
+	}, [navigate]);
+
+	const handleLabelClick = useCallback(
+		(tagName: string) => {
+			navigateToClassificationSearch(navigate, tagName);
+		},
+		[navigate]
+	);
+
+	const renderTooltip = useCallback((props: unknown) => {
+		const p = props as { active?: boolean; payload?: Array<{ payload?: { name: string; count: number } }> };
+		if (!p?.active || !p?.payload?.length) return null;
+		const row = p.payload[0]?.payload;
+		if (!row) return null;
+		return (
+			<Box sx={{ p: 1.5, bgcolor: "background.paper", borderRadius: 1, boxShadow: 2, minWidth: 140 }}>
+				<Typography variant="body2" fontWeight={600} sx={{ mb: 0.5 }}>
+					{row.name}
+				</Typography>
+				<Typography variant="caption" display="block">
+					Entities: {numberFormatWithComma(row.count)}
+				</Typography>
+			</Box>
+		);
+	}, []);
+
+	if (isLoading) return null;
+
+	return (
+		<Paper
+			elevation={1}
+			sx={{
+				padding: 2,
+				borderRadius: 2,
+				minHeight: 340,
+				minWidth: 0,
+				width: "100%",
+				height: "100%",
+				boxSizing: "border-box",
+				transition: "box-shadow 0.3s ease",
+				"&:hover": { boxShadow: 4 }
+			}}
+		>
+			<Box sx={{ pb: 2, borderBottom: "1px solid", borderColor: "divider" }}>
+				<Stack direction="row" justifyContent="space-between" alignItems="center">
+					<Typography sx={{ fontSize: "1rem", fontWeight: 600, color: "#1a1a1a" }}>
+						Classification Distribution
+					</Typography>
+					<Link
+						component="button"
+						onClick={handleViewAll}
+						sx={{ fontSize: "0.875rem", cursor: "pointer", textDecoration: "none", color: "primary.main" }}
+						aria-label="View all classifications"
+					>
+						View All
+					</Link>
+				</Stack>
+			</Box>
+			<Typography variant="body2" sx={{ color: "#6c757d", mt: 2, lineHeight: 1.4 }}>
+				<strong>Tag–entity associations (total):</strong>{" "}
+				{numberFormatWithComma(associationTotal)}
+			</Typography>
+			<Typography variant="caption" sx={{ color: "#868e96", display: "block", mt: 0.75, lineHeight: 1.4 }}>
+				The chart shows the top 5 classifications by number of entities in use.
+			</Typography>
+			{data.length === 0 ? (
+				<Stack alignItems="center" justifyContent="center" height={200}>
+					<Typography variant="body2" color="text.secondary">
+						No classification data available
+					</Typography>
+				</Stack>
+			) : (
+				<Box sx={{ mt: 2, minHeight: 260, height: 260, width: "100%", minWidth: 280 }}>
+					<ResponsiveContainer width="100%" height="100%" style={{ cursor: "pointer" }}>
+						<BarChart
+							data={data}
+							layout="vertical"
+							margin={{ ...CLASSIFICATION_DISTRIBUTION_CHART_MARGIN }}
+						>
+							<CartesianGrid strokeDasharray="3 3" stroke="#f0f0f0" />
+							<XAxis
+								type="number"
+								tickFormatter={(v) => numberFormatWithComma(v)}
+								height={36}
+								label={{
+									value: "Entity Count",
+									position: "bottom",
+									offset: 12,
+									style: { fontSize: 11, fill: "#6c757d" },
+								}}
+							/>
+							<YAxis
+								type="category"
+								dataKey="name"
+								width={52}
+								label={{
+									value: "Classification",
+									angle: -90,
+									position: "left",
+									offset: 2,
+									style: { fontSize: 10, fill: "#6c757d", textAnchor: "middle" },
+								}}
+								tick={(props: Record<string, unknown>) => {
+									const { x = 0, y = 0, payload } = props;
+									const p = payload as { value?: string; name?: string } | undefined;
+									const value = p?.value ?? p?.name ?? (typeof payload === "string" ? payload : "");
+									return (
+										<g
+											transform={`translate(${x},${y})`}
+											onClick={() => (value ? handleLabelClick(value) : undefined)}
+											style={{ cursor: value ? "pointer" : "default" }}
+											role={value ? "button" : undefined}
+											tabIndex={value ? 0 : undefined}
+											onKeyDown={
+												value
+													? (e: React.KeyboardEvent<SVGGElement>) => {
+															if (e.key === "Enter" || e.key === " ") {
+																e.preventDefault();
+																handleLabelClick(value);
+															}
+														}
+													: undefined
+											}
+										>
+											<text x={0} y={0} dy={4} textAnchor="end" fill="#333" fontSize={12}>
+												{value}
+											</text>
+										</g>
+									);
+								}}
+							/>
+							<Tooltip content={renderTooltip} cursor={{ fill: "transparent" }} />
+							<Bar
+								dataKey="count"
+								name="Entities"
+								fill={BAR_COLOR}
+								radius={[0, 4, 4, 0]}
+								onClick={(entry) => handleBarClick(entry)}
+								cursor="pointer"
+							>
+								<LabelList
+									dataKey="count"
+									position="right"
+									offset={10}
+									formatter={(v: number) => numberFormatWithComma(v)}
+									style={{
+										fontSize: 12,
+										fontWeight: 500,
+										fill: BAR_COLOR,
+									}}
+								/>
+								{data.map((_, index) => <Cell key={index} fill={BAR_COLOR} />)}
+							</Bar>
+						</BarChart>
+					</ResponsiveContainer>
+				</Box>
+			)}
+		</Paper>
+	);
+});
+
+ClassificationDistributionCard.displayName = "ClassificationDistributionCard";
+
+export default ClassificationDistributionCard;
diff --git a/dashboard/src/views/DashboardOverview/DashboardOverview.tsx b/dashboard/src/views/DashboardOverview/DashboardOverview.tsx
new file mode 100644
index 000000000..c7bfbd551
--- /dev/null
+++ b/dashboard/src/views/DashboardOverview/DashboardOverview.tsx
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ */
+
+import { useEffect, useState, useMemo, useCallback } from "react";
+import { Grid, Stack } from "@mui/material";
+import { useAppDispatch, useAppSelector } from "@hooks/reducerHook";
+import { fetchTypeHeaderData } from "@redux/slice/typeDefSlices/typeDefHeaderSlice";
+import { getLatestEntities } from "@api/apiMethods/searchApiMethod";
+import type { TypeHeaderInterface } from "@models/entityTreeType";
+import DashboardSkeleton from "./DashboardSkeleton";
+import EntityTypeBarChartSkeleton from "./EntityTypeBarChartSkeleton";
+import LatestEntitiesSkeleton from "./LatestEntitiesSkeleton";
+import OverviewCard from "./OverviewCard";
+import EntityStatusDonut from "./EntityStatusDonut";
+import ClassificationCoverage from "./ClassificationCoverage";
+import EntityTypeBarChart from "./EntityTypeBarChart";
+import LatestEntitiesList from "./LatestEntitiesList";
+import RecentActivity from "./RecentActivity";
+import KafkaTopicSummaryCard from "./KafkaTopicSummaryCard";
+import ClassificationDistributionCard from "./ClassificationDistributionCard";
+
+const DashboardOverview = () => {
+	const dispatch = useAppDispatch();
+	const { metricsData, loading: metricsLoading } = useAppSelector((state: { metrics: { metricsData: unknown; loading: boolean } }) => state.metrics);
+	const typeHeaderData = useAppSelector(
+		(state: { typeHeader?: { typeHeaderData?: TypeHeaderInterface[] | null } }) =>
+			state.typeHeader?.typeHeaderData ?? null
+	);
+	const dashboardRefreshVersion = useAppSelector((state) => state.dashboardRefresh.version);
+	const [latestEntities, setLatestEntities] = useState<unknown[]>([]);
+	const [latestLoading, setLatestLoading] = useState(true);
+	const [latestError, setLatestError] = useState<string | null>(null);
+
+	const metrics = metricsData as {
+		data?: {
+			general?: { entityCount?: number; tagCount?: number; stats?: Record<string, unknown> };
+			entity?: Record<string, unknown>;
+			tag?: Record<string, unknown>;
+		};
+	} | null;
+	const general = metrics?.data?.general;
+	const entity = metrics?.data?.entity;
+	const tag = metrics?.data?.tag;
+	const stats = general?.stats;
+	const entityCount = general?.entityCount ?? 0;
+	const tagCount = general?.tagCount ?? 0;
+
+	const isLoading = metricsLoading;
+
+	const fetchLatestEntities = useCallback(async () => {
+		setLatestLoading(true);
+		setLatestError(null);
+		try {
+			const resp = await getLatestEntities();
+			const entities = (resp as { data?: { entities?: unknown[] } })?.data?.entities ?? [];
+			setLatestEntities(Array.isArray(entities) ? entities : []);
+		} catch (err) {
+			setLatestError(err instanceof Error ? err.message : "Failed to load latest entities");
+			setLatestEntities([]);
+		} finally {
+			setLatestLoading(false);
+		}
+	}, []);
+
+	useEffect(() => {
+		fetchLatestEntities();
+	}, [dashboardRefreshVersion, fetchLatestEntities]);
+
+	useEffect(() => {
+		dispatch(fetchTypeHeaderData());
+	}, [dispatch]);
+
+	const latestEntitiesList = useMemo(() => {
+		if (!Array.isArray(latestEntities)) return [];
+		return latestEntities.slice(0, 7) as { guid?: string; typeName?: string; attributes?: { name?: string; qualifiedName?: string; __timestamp?: number } }[];
+	}, [latestEntities]);
+
+	return (
+		<Stack
+			spacing={3}
+			width="100%"
+			sx={{
+				maxWidth: "100%",
+				boxSizing: "border-box",
+				backgroundColor: "#f5f7f9",
+				padding: 3,
+				borderRadius: 2
+			}}
+		>
+			<Grid container spacing={3} sx={{ width: "100%", alignItems: "stretch" }}>
+				<Grid item xs={12} md={4}>
+					{isLoading ? <DashboardSkeleton /> : <OverviewCard entityCount={entityCount} tagCount={tagCount} />}
+				</Grid>
+				<Grid item xs={12} md={4}>
+					{isLoading ? <DashboardSkeleton /> : <EntityStatusDonut entity={entity} />}
+				</Grid>
+				<Grid item xs={12} md={4}>
+					{isLoading ? (
+						<DashboardSkeleton />
+					) : (
+						<ClassificationCoverage
+							classificationTypeDefinitions={tagCount}
+							tag={tag}
+						/>
+					)}
+				</Grid>
+				<Grid item xs={12} md={8} sx={{ display: "flex", minWidth: 0 }}>
+					{isLoading ? (
+						<EntityTypeBarChartSkeleton />
+					) : (
+						<EntityTypeBarChart entity={entity} typeHeaderData={typeHeaderData} />
+					)}
+				</Grid>
+				<Grid item xs={12} md={4} sx={{ display: "flex", minWidth: 0 }}>
+					{latestLoading ? (
+						<LatestEntitiesSkeleton />
+					) : (
+						<LatestEntitiesList entities={latestEntitiesList} error={latestError} />
+					)}
+				</Grid>
+				<Grid item xs={12} md={12} sx={{ display: "flex", minWidth: 0 }}>
+					<RecentActivity />
+				</Grid>
+				<Grid item xs={12} md={12} sx={{ display: "flex", minWidth: 0 }}>
+					{isLoading ? <EntityTypeBarChartSkeleton /> : <ClassificationDistributionCard tag={tag} isLoading={isLoading} />}
+				</Grid>
+				<Grid item xs={12} md={12} sx={{ display: "flex", minWidth: 0 }}>
+					{isLoading ? <EntityTypeBarChartSkeleton /> : <KafkaTopicSummaryCard stats={stats} isLoading={isLoading} />}
+				</Grid>
+			</Grid>
+		</Stack>
+	);
+};
+
+export default DashboardOverview;
diff --git a/dashboard/src/views/DashboardOverview/DashboardSkeleton.tsx b/dashboard/src/views/DashboardOverview/DashboardSkeleton.tsx
new file mode 100644
index 000000000..b37ec59d4
--- /dev/null
+++ b/dashboard/src/views/DashboardOverview/DashboardSkeleton.tsx
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+import { Paper, Stack } from "@mui/material";
+import SkeletonLoader from "@components/SkeletonLoader";
+
+const DashboardSkeleton = () => (
+	<Paper
+		elevation={1}
+		sx={{
+			padding: 2,
+			borderRadius: 2,
+			minHeight: 200,
+			transition: "box-shadow 0.3s ease",
+			"&:hover": { boxShadow: 4 }
+		}}
+	>
+		<Stack spacing={1}>
+			<SkeletonLoader animation="wave" variant="text" count={1} width="40%" height={28} />
+			<SkeletonLoader animation="wave" variant="rectangular" count={1} height={60} />
+		</Stack>
+	</Paper>
+);
+
+export default DashboardSkeleton;
diff --git a/dashboard/src/views/DashboardOverview/EntityStatusDonut.tsx b/dashboard/src/views/DashboardOverview/EntityStatusDonut.tsx
new file mode 100644
index 000000000..9eb93dc1e
--- /dev/null
+++ b/dashboard/src/views/DashboardOverview/EntityStatusDonut.tsx
@@ -0,0 +1,173 @@
+/*
+ * 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.
+ */
+
+import { memo, useCallback, useState } from "react";
+import { Paper, Stack, Typography, Box } from "@mui/material";
+import { PieChart, Pie, Cell, Tooltip, ResponsiveContainer, Sector } from "recharts";
+import { useNavigate } from "react-router-dom";
+import { numberFormatWithComma } from "@utils/Helper";
+import { getEntityStatusTotals } from "@utils/metricsUtils";
+import { navigateToSearch } from "@utils/dashboardSearchUtils";
+import { ENTITY_STATUS_DONUT_COLORS as COLORS } from "./dashboardChartPalette";
+
+interface EntityStatusDonutProps {
+	entity: Record<string, unknown> | undefined;
+	isLoading?: boolean;
+}
+
+const EntityStatusDonut = memo(({ entity, isLoading }: EntityStatusDonutProps) => {
+	const [activeIndex, setActiveIndex] = useState<number>(-1);
+	const navigate = useNavigate();
+	const totals = getEntityStatusTotals(entity);
+	const total = totals.active + totals.shell + totals.deleted;
+
+	const chartData = [
+		{ name: "Active", value: totals.active, color: COLORS.Active },
+		{ name: "Shell", value: totals.shell, color: COLORS.Shell },
+		{ name: "Deleted", value: totals.deleted, color: COLORS.Deleted }
+	].filter((d) => d.value > 0);
+
+	const getPercent = (val: number) => (total > 0 ? Math.round((val / total) * 100) : 0);
+
+	const handleStatusClick = useCallback(
+		(status: "Active" | "Shell" | "Deleted") => {
+			if (status === "Active") {
+				navigateToSearch(navigate, "entity_status");
+			} else if (status === "Deleted") {
+				navigateToSearch(navigate, "entity_status", {
+					includeDE: true,
+					entityFilters: {
+						condition: "AND",
+						criterion: [{ attributeName: "__state", operator: "eq", attributeValue: "DELETED" }]
+					}
+				});
+			} else if (status === "Shell") {
+				navigateToSearch(navigate, "entity_status", {
+					entityFilters: {
+						condition: "AND",
+						criterion: [{ attributeName: "__isIncomplete", operator: "eq", attributeValue: "true" }]
+					}
+				});
+			}
+		},
+		[navigate]
+	);
+
+	if (isLoading) return null;
+
+	const renderActiveShape = (props: unknown) => {
+		const p = props as { outerRadius?: number; innerRadius?: number; [k: string]: unknown };
+		return (
+			<Sector
+				{...p}
+				outerRadius={(p.outerRadius ?? 60) * 1.08}
+				innerRadius={p.innerRadius ?? 40}
+			/>
+		);
+	};
+
+	return (
+		<Paper
+			elevation={1}
+			sx={{
+				padding: 2,
+				borderRadius: 2,
+				minHeight: 200,
+				transition: "box-shadow 0.3s ease",
+				"&:hover": { boxShadow: 4 }
+			}}
+		>
+			<Box sx={{ pb: 2, borderBottom: "1px solid", borderColor: "divider" }}>
+				<Typography sx={{ fontSize: "1rem", fontWeight: 600, color: "#1a1a1a" }}>
+					Entity Status Overview
+				</Typography>
+			</Box>
+			<Stack direction="row" spacing={2} alignItems="center" height={160} sx={{ pt: 2 }}>
+				<Stack spacing={1.5} flex={1}>
+					{(["Active", "Shell", "Deleted"] as const).map((status) => (
+						<Box
+							key={status}
+							component="button"
+							type="button"
+							onClick={() => handleStatusClick(status)}
+							aria-label={`View ${status} entities`}
+							sx={{
+								display: "flex",
+								alignItems: "center",
+								gap: 1.5,
+								cursor: "pointer",
+								background: "none",
+								border: "none",
+								padding: 0,
+								margin: 0,
+								font: "inherit",
+								textAlign: "left",
+								"&:hover": { opacity: 0.85 }
+							}}
+						>
+							<Box
+								sx={{
+									width: 12,
+									height: 12,
+									borderRadius: "50%",
+									backgroundColor: COLORS[status],
+									flexShrink: 0
+								}}
+							/>
+							<Typography component="span" sx={{ fontSize: "0.875rem", color: "#374151" }}>
+								{status} {getPercent(totals[status.toLowerCase() as keyof typeof totals])}%
+							</Typography>
+						</Box>
+					))}
+				</Stack>
+				<ResponsiveContainer width="50%" height="100%" style={{ cursor: "pointer" }}>
+					<PieChart>
+						<Pie
+							data={chartData}
+							cx="50%"
+							cy="50%"
+							innerRadius={40}
+							outerRadius={60}
+							paddingAngle={2}
+							dataKey="value"
+							isAnimationActive
+							animationDuration={800}
+							animationEasing="ease-out"
+							activeIndex={activeIndex}
+							activeShape={renderActiveShape}
+							onMouseEnter={(_, index) => setActiveIndex(index)}
+							onMouseLeave={() => setActiveIndex(-1)}
+							onClick={(data) => handleStatusClick(data.name as "Active" | "Shell" | "Deleted")}
+						>
+							{chartData.map((entry, index) => (
+								<Cell key={`cell-${index}`} fill={entry.color} stroke="none" />
+							))}
+						</Pie>
+						<Tooltip
+							formatter={(value: number) => numberFormatWithComma(value)}
+							contentStyle={{ borderRadius: 8 }}
+						/>
+					</PieChart>
+				</ResponsiveContainer>
+			</Stack>
+		</Paper>
+	);
+});
+
+EntityStatusDonut.displayName = "EntityStatusDonut";
+
+export default EntityStatusDonut;
diff --git a/dashboard/src/views/DashboardOverview/EntityTypeBarChart.tsx b/dashboard/src/views/DashboardOverview/EntityTypeBarChart.tsx
new file mode 100644
index 000000000..433cf228f
--- /dev/null
+++ b/dashboard/src/views/DashboardOverview/EntityTypeBarChart.tsx
@@ -0,0 +1,327 @@
+/*
+ * 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.
+ */
+
+import React, { memo, useCallback, useMemo } from "react";
+import { Paper, Stack, Typography, Link, Box } from "@mui/material";
+import {
+	BarChart,
+	Bar,
+	XAxis,
+	YAxis,
+	CartesianGrid,
+	Tooltip,
+	ResponsiveContainer,
+	Cell,
+	LabelList,
+} from "recharts";
+import { useNavigate } from "react-router-dom";
+import { numberFormatWithComma } from "@utils/Helper";
+import type { EntityTypeDistributionItem } from "@utils/metricsUtils";
+import {
+	getServiceTypeDistribution,
+	type TypeHeaderCatalogRow,
+} from "@utils/typeCatalogUtils";
+import {
+	navigateToSearch,
+	navigateToServiceTypeEntitySearch,
+} from "@utils/dashboardSearchUtils";
+import {
+	CHART_BAR_ACTIVE_BLUE,
+	ENTITY_STATUS_DONUT_COLORS,
+	HORIZONTAL_BAR_CHART_MARGIN,
+} from "./dashboardChartPalette";
+
+const ACTIVE_COLOR = CHART_BAR_ACTIVE_BLUE;
+const DELETED_COLOR = ENTITY_STATUS_DONUT_COLORS.Deleted;
+
+interface EntityTypeBarChartProps {
+	entity: Record<string, unknown> | undefined;
+	typeHeaderData?: TypeHeaderCatalogRow[] | null;
+	isLoading?: boolean;
+}
+
+const payloadFromBarEvent = (item: unknown): EntityTypeDistributionItem | undefined => {
+	if (!item || typeof item !== "object") return undefined;
+	const rec = item as { payload?: EntityTypeDistributionItem };
+	return rec.payload;
+};
+
+const EntityTypeBarChart = memo(
+	({ entity, typeHeaderData, isLoading }: EntityTypeBarChartProps) => {
+		const navigate = useNavigate();
+		const data = useMemo(
+			() => getServiceTypeDistribution(entity, typeHeaderData, 5),
+			[entity, typeHeaderData]
+		);
+
+		const navigateForRow = useCallback(
+			(row: EntityTypeDistributionItem, includeDeleted: boolean) => {
+				const targets =
+					row.underlyingTypeNames?.length && row.underlyingTypeNames.length > 0
+						? row.underlyingTypeNames
+						: [row.name];
+				navigateToServiceTypeEntitySearch(navigate, targets, includeDeleted);
+			},
+			[navigate]
+		);
+
+		const handleActiveBarClick = useCallback(
+			(barProps: unknown) => {
+				const row = payloadFromBarEvent(barProps);
+				if (row) navigateForRow(row, false);
+			},
+			[navigateForRow]
+		);
+
+		const handleDeletedBarClick = useCallback(
+			(barProps: unknown) => {
+				const row = payloadFromBarEvent(barProps);
+				if (row) navigateForRow(row, true);
+			},
+			[navigateForRow]
+		);
+
+		const handleViewAll = useCallback(() => {
+			navigateToSearch(navigate, "all_entities");
+		}, [navigate]);
+
+		const handleLabelClick = useCallback(
+			(serviceLabel: string) => {
+				const row = data.find((d) => d.name === serviceLabel);
+				if (row) navigateForRow(row, false);
+			},
+			[data, navigateForRow]
+		);
+
+		const renderTooltip = useCallback((props: unknown) => {
+			const p = props as {
+				active?: boolean;
+				payload?: Array<{
+					payload?: EntityTypeDistributionItem;
+				}>;
+			};
+			if (!p?.active || !p?.payload?.length) return null;
+			const row = p.payload[0]?.payload;
+			if (!row) return null;
+			return (
+				<Box sx={{ p: 1.5, bgcolor: "background.paper", borderRadius: 1, boxShadow: 2, minWidth: 140 }}>
+					<Typography variant="body2" fontWeight={600} sx={{ mb: 0.5 }}>
+						{row.name}
+					</Typography>
+					<Typography variant="caption" display="block" color="primary">
+						Active: {numberFormatWithComma(row.active)}
+					</Typography>
+					<Typography variant="caption" display="block" sx={{ color: DELETED_COLOR }}>
+						Deleted: {numberFormatWithComma(row.deleted)}
+					</Typography>
+					<Typography variant="caption" display="block" fontWeight={600}>
+						Total: {numberFormatWithComma(row.count)}
+					</Typography>
+				</Box>
+			);
+		}, []);
+
+		if (isLoading) return null;
+
+		return (
+			<Paper
+				elevation={1}
+				sx={{
+					padding: 2,
+					borderRadius: 2,
+					minHeight: 340,
+					minWidth: 0,
+					width: "100%",
+					height: "100%",
+					boxSizing: "border-box",
+					transition: "box-shadow 0.3s ease",
+					"&:hover": { boxShadow: 4 },
+				}}
+			>
+				<Box sx={{ pb: 2, borderBottom: "1px solid", borderColor: "divider" }}>
+					<Stack direction="row" justifyContent="space-between" alignItems="center">
+						<Typography sx={{ fontSize: "1rem", fontWeight: 600, color: "#1a1a1a" }}>
+							Service Type Distribution
+						</Typography>
+						<Link
+							component="button"
+							onClick={handleViewAll}
+							sx={{
+								fontSize: "0.875rem",
+								cursor: "pointer",
+								textDecoration: "none",
+								color: "primary.main",
+							}}
+							aria-label="View all entities"
+						>
+							View All
+						</Link>
+					</Stack>
+				</Box>
+				{data.length === 0 ? (
+					<Stack alignItems="center" justifyContent="center" height={200}>
+						<Typography variant="body2" color="text.secondary">
+							No service type data available
+						</Typography>
+					</Stack>
+				) : (
+					<Box sx={{ mt: 2, minHeight: 260, height: 260, width: "100%", minWidth: 280 }}>
+						<Stack direction="row" spacing={2} sx={{ mb: 1, flexWrap: "wrap" }} aria-label="Chart legend">
+							<Stack direction="row" alignItems="center" spacing={0.75}>
+								<Box
+									sx={{
+										width: 10,
+										height: 10,
+										borderRadius: "50%",
+										backgroundColor: ACTIVE_COLOR,
+									}}
+									aria-hidden
+								/>
+								<Typography variant="caption" sx={{ color: "#6c757d", fontSize: "0.8125rem" }}>
+									Active
+								</Typography>
+							</Stack>
+							<Stack direction="row" alignItems="center" spacing={0.75}>
+								<Box
+									sx={{
+										width: 10,
+										height: 10,
+										borderRadius: "50%",
+										backgroundColor: DELETED_COLOR,
+									}}
+									aria-hidden
+								/>
+								<Typography variant="caption" sx={{ color: "#6c757d", fontSize: "0.8125rem" }}>
+									Deleted
+								</Typography>
+							</Stack>
+						</Stack>
+						<ResponsiveContainer width="100%" height="100%" style={{ cursor: "pointer" }}>
+							<BarChart data={data} layout="vertical" margin={{ ...HORIZONTAL_BAR_CHART_MARGIN }}>
+								<CartesianGrid strokeDasharray="3 3" stroke="#f0f0f0" />
+								<XAxis
+									type="number"
+									tickFormatter={(v) => numberFormatWithComma(v)}
+									height={36}
+									label={{
+										value: "Entity Count",
+										position: "bottom",
+										offset: 12,
+										style: { fontSize: 11, fill: "#6c757d" },
+									}}
+								/>
+								<YAxis
+									type="category"
+									dataKey="name"
+									width={88}
+									label={{
+										value: "Service Type",
+										angle: -90,
+										position: "left",
+										offset: 4,
+										style: { fontSize: 11, fill: "#6c757d", textAnchor: "middle" },
+									}}
+									tick={(props: Record<string, unknown>) => {
+										const { x = 0, y = 0, payload } = props;
+										const p = payload as { value?: string; name?: string } | undefined;
+										const value =
+											p?.value ??
+											p?.name ??
+											(typeof payload === "string" ? payload : "");
+										return (
+											<g
+												transform={`translate(${x},${y})`}
+												onClick={() => (value ? handleLabelClick(value) : undefined)}
+												style={{ cursor: value ? "pointer" : "default" }}
+												role={value ? "button" : undefined}
+												tabIndex={value ? 0 : undefined}
+												onKeyDown={
+													value
+														? (e: React.KeyboardEvent<SVGGElement>) => {
+																if (e.key === "Enter" || e.key === " ") {
+																	e.preventDefault();
+																	handleLabelClick(value);
+																}
+															}
+														: undefined
+												}
+											>
+												<text x={0} y={0} dy={4} textAnchor="end" fill="#333" fontSize={12}>
+													{value}
+												</text>
+											</g>
+										);
+									}}
+								/>
+								<Tooltip content={renderTooltip} cursor={{ fill: "transparent" }} />
+								<Bar
+									dataKey="active"
+									name="Active"
+									stackId="a"
+									fill={ACTIVE_COLOR}
+									radius={[0, 0, 0, 0]}
+									isAnimationActive
+									animationDuration={800}
+									animationEasing="ease-out"
+									onClick={handleActiveBarClick}
+									cursor="pointer"
+									activeBar={{ fill: ACTIVE_COLOR }}
+								>
+									{data.map((_, index) => (
+										<Cell key={`active-${index}`} fill={ACTIVE_COLOR} />
+									))}
+								</Bar>
+								<Bar
+									dataKey="deleted"
+									name="Deleted"
+									stackId="a"
+									fill={DELETED_COLOR}
+									radius={[0, 4, 4, 0]}
+									isAnimationActive
+									animationDuration={800}
+									animationEasing="ease-out"
+									onClick={handleDeletedBarClick}
+									cursor="pointer"
+									activeBar={{ fill: DELETED_COLOR }}
+								>
+									<LabelList
+										dataKey="count"
+										position="right"
+										offset={10}
+										formatter={(v: number) => numberFormatWithComma(v)}
+										style={{
+											fontSize: 12,
+											fontWeight: 500,
+											fill: ACTIVE_COLOR,
+										}}
+									/>
+									{data.map((_, index) => (
+										<Cell key={`deleted-${index}`} fill={DELETED_COLOR} />
+									))}
+								</Bar>
+							</BarChart>
+						</ResponsiveContainer>
+					</Box>
+				)}
+			</Paper>
+		);
+	}
+);
+
+EntityTypeBarChart.displayName = "EntityTypeBarChart";
+
+export default EntityTypeBarChart;
diff --git a/dashboard/src/views/DashboardOverview/EntityTypeBarChartSkeleton.tsx b/dashboard/src/views/DashboardOverview/EntityTypeBarChartSkeleton.tsx
new file mode 100644
index 000000000..3f2950b0b
--- /dev/null
+++ b/dashboard/src/views/DashboardOverview/EntityTypeBarChartSkeleton.tsx
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+import { Paper, Stack, Box } from "@mui/material";
+import SkeletonLoader from "@components/SkeletonLoader";
+
+const EntityTypeBarChartSkeleton = () => (
+	<Paper
+		elevation={1}
+		sx={{
+			padding: 2,
+			borderRadius: 2,
+			minHeight: 340,
+			minWidth: 0,
+			width: "100%",
+			flex: 1,
+			boxSizing: "border-box",
+			transition: "box-shadow 0.3s ease",
+			"&:hover": { boxShadow: 4 }
+		}}
+	>
+		<Box sx={{ pb: 2, borderBottom: "1px solid", borderColor: "divider" }}>
+			<Stack direction="row" justifyContent="space-between" alignItems="center">
+				<SkeletonLoader animation="wave" variant="text" count={1} width="50%" height={24} />
+				<SkeletonLoader animation="wave" variant="text" count={1} width={60} height={20} />
+			</Stack>
+		</Box>
+		<Stack direction="row" spacing={2} sx={{ mt: 2, mb: 1 }}>
+			<SkeletonLoader animation="wave" variant="text" count={1} width={40} height={16} />
+			<SkeletonLoader animation="wave" variant="text" count={1} width={50} height={16} />
+		</Stack>
+		<Stack spacing={1.5} sx={{ mt: 2 }}>
+			{[1, 2, 3, 4, 5].map((i) => (
+				<Stack key={i} direction="row" alignItems="center" spacing={2}>
+					<SkeletonLoader animation="wave" variant="text" count={1} width={100} height={20} />
+					<SkeletonLoader animation="wave" variant="rectangular" count={1} width={`${30 + i * 12}%`} height={24} sx={{ borderRadius: 1 }} />
+				</Stack>
+			))}
+		</Stack>
+	</Paper>
+);
+
+export default EntityTypeBarChartSkeleton;
diff --git a/dashboard/src/views/DashboardOverview/KafkaTopicSummaryCard.tsx b/dashboard/src/views/DashboardOverview/KafkaTopicSummaryCard.tsx
new file mode 100644
index 000000000..93c00f50b
--- /dev/null
+++ b/dashboard/src/views/DashboardOverview/KafkaTopicSummaryCard.tsx
@@ -0,0 +1,402 @@
+/*
+ * 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.
+ */
+
+import { Fragment, memo, useMemo, useState, useCallback } from "react";
+import {
+	Paper,
+	Stack,
+	Typography,
+	Table,
+	TableBody,
+	TableCell,
+	TableContainer,
+	TableHead,
+	TableRow,
+	Box,
+	IconButton,
+	Tooltip,
+	Collapse,
+} from "@mui/material";
+import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
+import ExpandLessIcon from "@mui/icons-material/ExpandLess";
+import { numberFormatWithComma } from "@utils/Helper";
+import { formatedDate } from "@utils/Utils";
+import {
+	parseMetricsStats,
+	getMessageConsumptionData,
+	getMessageConsumptionDataExcludingTotal,
+	buildTopicNotificationRecord,
+	topicRowHasPeriodMetrics,
+	type MessageConsumptionItem,
+} from "@utils/metricsUtils";
+import MessageConsumptionChart from "./MessageConsumptionChart";
+import {
+	CHART_BAR_ACTIVE_BLUE,
+	ENTITY_STATUS_DONUT_COLORS,
+} from "./dashboardChartPalette";
+
+const CREATES_COLOR = ENTITY_STATUS_DONUT_COLORS.Active;
+const UPDATES_COLOR = CHART_BAR_ACTIVE_BLUE;
+const DELETES_COLOR = ENTITY_STATUS_DONUT_COLORS.Deleted;
+
+interface TopicDetail {
+	topic: string;
+	processed: number;
+	failed: number;
+	lastProcessed: string | number;
+	/** Partition stats — same shape as aggregate Notification (per AtlasMetricsUtil). */
+	topicStats: Record<string, unknown>;
+}
+
+interface KafkaTopicSummaryCardProps {
+	stats: Record<string, unknown> | undefined;
+	isLoading?: boolean;
+}
+
+const getTopicConsumptionPanelId = (topic: string): string =>
+	`kafka-topic-msg-panel-${topic.replace(/[^a-zA-Z0-9_-]/g, "_")}`;
+
+const TotalProcessedTooltip = ({
+	total,
+}: {
+	total: MessageConsumptionItem | undefined;
+}) => {
+	if (!total) {
+		return (
+			<Typography variant="caption" component="span">
+				No breakdown available
+			</Typography>
+		);
+	}
+	return (
+		<Box sx={{ p: 1, minWidth: 160, bgcolor: "#fff" }}>
+			<Typography
+				variant="body2"
+				fontWeight={600}
+				sx={{ mb: 0.5, color: "#1a1a1a" }}
+			>
+				{total.period}
+			</Typography>
+			<Typography variant="caption" display="block" sx={{ color: CREATES_COLOR }}>
+				Creates: {numberFormatWithComma(total.creates)}
+			</Typography>
+			<Typography variant="caption" display="block" sx={{ color: UPDATES_COLOR }}>
+				Updates: {numberFormatWithComma(total.updates)}
+			</Typography>
+			<Typography variant="caption" display="block" sx={{ color: DELETES_COLOR }}>
+				Deletes: {numberFormatWithComma(total.deletes)}
+			</Typography>
+			<Typography variant="caption" display="block" sx={{ color: "#6c757d", mt: 0.5 }}>
+				Messages processed: {numberFormatWithComma(total.count)}
+			</Typography>
+			<Typography variant="caption" display="block" sx={{ color: "#6c757d" }}>
+				Avg time (ms): {numberFormatWithComma(total.avgTime)}
+			</Typography>
+		</Box>
+	);
+};
+
+const KafkaTopicSummaryCard = memo(({ stats, isLoading }: KafkaTopicSummaryCardProps) => {
+	const [sortKey, setSortKey] = useState<"topic" | "processed" | "failed">("topic");
+	const [sortOrder, setSortOrder] = useState<"asc" | "desc">("asc");
+	/** One expanded topic at a time to limit vertical growth. */
+	const [expandedTopic, setExpandedTopic] = useState<string | null>(null);
+
+	const parsed = useMemo(() => parseMetricsStats(stats), [stats]);
+	const notification = parsed?.Notification as Record<string, unknown> | undefined;
+	const topicDetails = notification?.topicDetails as
+		| Record<string, Record<string, unknown>>
+		| undefined;
+
+	const rows = useMemo((): TopicDetail[] => {
+		if (!topicDetails || typeof topicDetails !== "object") return [];
+		return Object.entries(topicDetails).map(([topic, data]) => {
+			const lp = data?.lastMessageProcessedTime;
+			const lastProcessed: string | number =
+				lp != null && typeof lp !== "object" ? (lp as string | number) : "-";
+			return {
+				topic,
+				processed: Number(data?.processedMessageCount ?? 0),
+				failed: Number(data?.failedMessageCount ?? 0),
+				lastProcessed,
+				topicStats: data ?? {},
+			};
+		});
+	}, [topicDetails]);
+
+	const sortedRows = useMemo(() => {
+		const list = [...rows];
+		const dir = sortOrder === "asc" ? 1 : -1;
+		return list.sort((a, b) => {
+			if (sortKey === "topic") {
+				const av = String(a.topic).toLowerCase();
+				const bv = String(b.topic).toLowerCase();
+				return (av < bv ? -1 : av > bv ? 1 : 0) * dir;
+			}
+			const av = a[sortKey];
+			const bv = b[sortKey];
+			return ((av as number) - (bv as number)) * dir;
+		});
+	}, [rows, sortKey, sortOrder]);
+
+	const consumptionByTopic = useMemo(() => {
+		const m = new Map<
+			string,
+			{ totalRow: MessageConsumptionItem | undefined; chartData: MessageConsumptionItem[] }
+		>();
+		for (const row of rows) {
+			const record = buildTopicNotificationRecord(row.topicStats, {
+				aggregateNotification: notification,
+				useAggregateFallback: !topicRowHasPeriodMetrics(row.topicStats),
+			});
+			const full = getMessageConsumptionData(record);
+			m.set(row.topic, {
+				totalRow: full.find((d) => d.period === "Total"),
+				chartData: getMessageConsumptionDataExcludingTotal(record),
+			});
+		}
+		return m;
+	}, [rows, notification]);
+
+	const handleSort = useCallback((key: "topic" | "processed" | "failed") => {
+		setSortKey(key);
+		setSortOrder((prev) => (prev === "asc" ? "desc" : "asc"));
+	}, []);
+
+	const handleToggleExpand = useCallback((topic: string) => {
+		setExpandedTopic((prev) => (prev === topic ? null : topic));
+	}, []);
+
+	const formatLastProcessed = (val: string | number): string => {
+		if (val === "-" || val == null) return "-";
+		if (typeof val === "number") return formatedDate({ date: val });
+		return String(val);
+	};
+
+	const hasExpanded = expandedTopic !== null;
+
+	if (isLoading) return null;
+
+	return (
+		<Paper
+			elevation={1}
+			sx={{
+				padding: 2,
+				borderRadius: 2,
+				minHeight: 280,
+				width: "100%",
+				boxSizing: "border-box",
+				transition: "box-shadow 0.3s ease",
+				"&:hover": { boxShadow: 4 },
+			}}
+		>
+			<Box sx={{ pb: 2, borderBottom: "1px solid", borderColor: "divider" }}>
+				<Typography sx={{ fontSize: "1rem", fontWeight: 600, color: "#1a1a1a" }}>
+					Kafka Topic Summary
+				</Typography>
+			</Box>
+			{rows.length === 0 ? (
+				<Stack alignItems="center" justifyContent="center" height={180}>
+					<Typography variant="body2" color="text.secondary">
+						No topic data available
+					</Typography>
+				</Stack>
+			) : (
+				<TableContainer sx={{ maxHeight: hasExpanded ? 560 : 220, mt: 1 }}>
+					<Table size="small" stickyHeader>
+						<TableHead>
+							<TableRow>
+								<TableCell
+									onClick={() => handleSort("topic")}
+									sx={{ cursor: "pointer", fontWeight: 600 }}
+									aria-label="Sort by topic"
+								>
+									Topic{" "}
+									{sortKey === "topic"
+										? sortOrder === "asc"
+											? "▲"
+											: "▼"
+										: ""}
+								</TableCell>
+								<TableCell
+									align="right"
+									onClick={() => handleSort("processed")}
+									sx={{ cursor: "pointer", fontWeight: 600 }}
+									aria-label="Sort by processed"
+								>
+									Processed{" "}
+									{sortKey === "processed"
+										? sortOrder === "asc"
+											? "▲"
+											: "▼"
+										: ""}
+								</TableCell>
+								<TableCell
+									align="right"
+									onClick={() => handleSort("failed")}
+									sx={{ cursor: "pointer", fontWeight: 600 }}
+									aria-label="Sort by failed"
+								>
+									Failed{" "}
+									{sortKey === "failed"
+										? sortOrder === "asc"
+											? "▲"
+											: "▼"
+										: ""}
+								</TableCell>
+								<TableCell align="right" sx={{ fontWeight: 600 }}>
+									Last Processed
+								</TableCell>
+							</TableRow>
+						</TableHead>
+						<TableBody>
+							{sortedRows.map((row) => {
+								const isExpanded = expandedTopic === row.topic;
+								const panelId = getTopicConsumptionPanelId(row.topic);
+								const cons = consumptionByTopic.get(row.topic);
+								const totalForHover = cons?.totalRow;
+								const chartData = cons?.chartData ?? [];
+								return (
+									<Fragment key={row.topic}>
+										<TableRow hover>
+											<TableCell sx={{ fontSize: "0.8125rem" }}>
+												<Stack direction="row" alignItems="center" spacing={0.5}>
+													<IconButton
+														size="small"
+														aria-label={
+															isExpanded
+																? `Collapse message consumption for ${row.topic}`
+																: `Expand message consumption for ${row.topic}`
+														}
+														aria-expanded={isExpanded}
+														aria-controls={panelId}
+														id={`${panelId}-trigger`}
+														onClick={(e) => {
+															e.stopPropagation();
+															handleToggleExpand(row.topic);
+														}}
+														onKeyDown={(e) => {
+															if (e.key === " " || e.key === "Enter") {
+																e.stopPropagation();
+															}
+														}}
+													>
+														{isExpanded ? (
+															<ExpandLessIcon fontSize="small" />
+														) : (
+															<ExpandMoreIcon fontSize="small" />
+														)}
+													</IconButton>
+													<Typography
+														component="span"
+														variant="body2"
+														sx={{ fontSize: "0.8125rem" }}
+													>
+														{row.topic}
+													</Typography>
+												</Stack>
+											</TableCell>
+											<TableCell align="right" sx={{ fontSize: "0.8125rem" }}>
+												<Tooltip
+													title={<TotalProcessedTooltip total={totalForHover} />}
+													arrow
+													enterDelay={200}
+													placement="top"
+													componentsProps={{
+														tooltip: {
+															sx: {
+																bgcolor: "#fff",
+																color: "#1a1a1a",
+																border: "1px solid",
+																borderColor: "rgba(0, 0, 0, 0.12)",
+																boxShadow: 2,
+															},
+														},
+														arrow: {
+															sx: {
+																color: "#fff",
+															},
+														},
+													}}
+												>
+													<Box
+														component="span"
+														tabIndex={0}
+														sx={{
+															cursor: "help",
+															borderBottom: "1px dotted",
+															borderColor: "text.secondary",
+														}}
+														aria-label="Total processed — hover for creates, updates, deletes"
+													>
+														{numberFormatWithComma(row.processed)}
+													</Box>
+												</Tooltip>
+											</TableCell>
+											<TableCell align="right" sx={{ fontSize: "0.8125rem" }}>
+												{numberFormatWithComma(row.failed)}
+											</TableCell>
+											<TableCell align="right" sx={{ fontSize: "0.8125rem" }}>
+												{formatLastProcessed(row.lastProcessed)}
+											</TableCell>
+										</TableRow>
+										{isExpanded ? (
+											<TableRow>
+												<TableCell
+													colSpan={4}
+													sx={{ p: 0, borderBottom: "none" }}
+												>
+													<Collapse in={isExpanded} timeout="auto" unmountOnExit>
+														<Box
+															id={panelId}
+															sx={{
+																py: 2,
+																px: 2,
+																bgcolor: "action.hover",
+																borderBottom: "1px solid",
+																borderColor: "divider",
+															}}
+														>
+															<Typography
+																variant="subtitle2"
+																sx={{ mb: 1, fontWeight: 600, color: "#1a1a1a" }}
+															>
+																Message consumption
+															</Typography>
+															<MessageConsumptionChart
+																data={chartData}
+																chartAriaLabel={`Message consumption for ${row.topic}`}
+															/>
+														</Box>
+													</Collapse>
+												</TableCell>
+											</TableRow>
+										) : null}
+									</Fragment>
+								);
+							})}
+						</TableBody>
+					</Table>
+				</TableContainer>
+			)}
+		</Paper>
+	);
+});
+
+KafkaTopicSummaryCard.displayName = "KafkaTopicSummaryCard";
+
+export default KafkaTopicSummaryCard;
diff --git a/dashboard/src/views/DashboardOverview/LatestEntitiesList.tsx b/dashboard/src/views/DashboardOverview/LatestEntitiesList.tsx
new file mode 100644
index 000000000..2d80a5a1f
--- /dev/null
+++ b/dashboard/src/views/DashboardOverview/LatestEntitiesList.tsx
@@ -0,0 +1,273 @@
+/*
+ * 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.
+ */
+
+import { memo, useCallback } from "react";
+import { Paper, Stack, Typography, Link, List, ListItem, Box } from "@mui/material";
+import { Link as RouterLink } from "react-router-dom";
+import moment from "moment";
+import { useNavigate } from "react-router-dom";
+import { navigateToLatestEntitiesSearch } from "@utils/dashboardSearchUtils";
+import type { LatestEntityRowModel } from "./latestEntitiesList.utils";
+import {
+	resolveLatestEntityDisplayName,
+	resolveLatestEntityGuid,
+	resolveLatestEntityTypeName
+} from "./latestEntitiesList.utils";
+
+interface EntityItem extends LatestEntityRowModel {
+	createTime?: number | Date | string;
+	attributes?: LatestEntityRowModel["attributes"] & {
+		__timestamp?: number | string | Record<string, unknown>;
+		createTime?: number | string;
+	};
+}
+
+interface LatestEntitiesListProps {
+	entities: EntityItem[];
+	isLoading?: boolean;
+	error?: string | null;
+}
+
+const INVALID_TS_LABEL = "Created today";
+
+const unwrapLongLike = (raw: unknown): unknown => {
+	if (raw == null || typeof raw !== "object" || Array.isArray(raw)) return raw;
+	const o = raw as Record<string, unknown>;
+	if (typeof o.$numberLong === "string" || typeof o.$numberLong === "number") {
+		return o.$numberLong;
+	}
+	if (typeof o.longValue === "string" || typeof o.longValue === "number") {
+		return o.longValue;
+	}
+	return raw;
+};
+
+/**
+ * Milliseconds since epoch, or null only when missing / unusable.
+ * Rejects 0 (epoch) to avoid "56 years ago". Accepts sec or ms numbers, ISO strings.
+ */
+const normalizeEntityTimestampMs = (raw: unknown): number | null => {
+	const v = unwrapLongLike(raw);
+	if (v == null) return null;
+	if (v instanceof Date) {
+		const t = v.getTime();
+		if (!Number.isFinite(t) || t <= 0) return null;
+		return moment(t).isValid() ? t : null;
+	}
+	if (typeof v === "string") {
+		const trimmed = v.trim();
+		if (trimmed === "") return null;
+		const n = Number(trimmed);
+		if (Number.isFinite(n) && n > 0) {
+			const ms = n < 1e12 ? n * 1000 : n;
+			if (moment(ms).isValid() && ms > 0) return ms;
+		}
+		const parsed = moment(trimmed);
+		if (parsed.isValid()) {
+			const ms = parsed.valueOf();
+			if (ms > 0) return ms;
+		}
+		return null;
+	}
+	if (typeof v === "number") {
+		if (!Number.isFinite(v) || v <= 0) return null;
+		const ms = v < 1e12 ? v * 1000 : v;
+		return moment(ms).isValid() && ms > 0 ? ms : null;
+	}
+	return null;
+};
+
+/** Use only `__timestamp` for relative "Created … ago" (not `createTime`, often 0 in API). */
+const getEntityTimestampRawForDisplay = (entity: EntityItem): unknown => {
+	const a = entity.attributes;
+	const top = entity as EntityItem & { __timestamp?: unknown };
+	return a?.__timestamp ?? top.__timestamp;
+};
+
+/** Valid timestamp only: seconds / minutes / hours for last 24h, then moment relative. */
+const formatCreatedRelativeFromMs = (ms: number): string => {
+	const now = Date.now();
+	const deltaMs = now - ms;
+	if (!Number.isFinite(deltaMs)) return INVALID_TS_LABEL;
+	if (deltaMs < 0) {
+		return `Created ${moment(ms).fromNow()}`;
+	}
+	const totalSec = Math.floor(deltaMs / 1000);
+	if (totalSec < 1) {
+		return "Created just now";
+	}
+	if (totalSec < 60) {
+		return totalSec === 1
+			? "Created 1 second ago"
+			: `Created ${totalSec} seconds ago`;
+	}
+	const totalMin = Math.floor(totalSec / 60);
+	if (totalMin < 60) {
+		return totalMin === 1
+			? "Created 1 minute ago"
+			: `Created ${totalMin} minutes ago`;
+	}
+	const totalHr = Math.floor(totalMin / 60);
+	if (totalHr < 24) {
+		return totalHr === 1
+			? "Created 1 hour ago"
+			: `Created ${totalHr} hours ago`;
+	}
+	return `Created ${moment(ms).fromNow()}`;
+};
+
+const formatRelativeTime = (raw: unknown): string => {
+	const ms = normalizeEntityTimestampMs(raw);
+	if (ms == null) return INVALID_TS_LABEL;
+	return formatCreatedRelativeFromMs(ms);
+};
+
+const LatestEntitiesList = memo(({ entities, isLoading, error }: LatestEntitiesListProps) => {
+	const navigate = useNavigate();
+
+	const handleViewAll = useCallback(() => {
+		navigateToLatestEntitiesSearch(navigate);
+	}, [navigate]);
+
+	if (isLoading) return null;
+
+	return (
+		<Paper
+			elevation={1}
+			sx={{
+				padding: 2,
+				borderRadius: 2,
+				minHeight: 340,
+				minWidth: 0,
+				width: "100%",
+				flex: 1,
+				boxSizing: "border-box",
+				transition: "box-shadow 0.3s ease",
+				"&:hover": { boxShadow: 4 }
+			}}
+		>
+			<Box sx={{ pb: 2, borderBottom: "1px solid", borderColor: "divider" }}>
+				<Stack direction="row" justifyContent="space-between" alignItems="center">
+					<Typography sx={{ fontSize: "1rem", fontWeight: 600, color: "#1a1a1a" }}>
+						Latest Entities Created
+					</Typography>
+					<Link
+						component="button"
+						onClick={handleViewAll}
+						sx={{
+							fontSize: "0.875rem",
+							cursor: "pointer",
+							textDecoration: "none",
+							color: "primary.main"
+						}}
+						aria-label="View all entities"
+					>
+						View All
+					</Link>
+				</Stack>
+			</Box>
+			{error ? (
+				<Stack alignItems="center" justifyContent="center" height={200} sx={{ pt: 2 }}>
+					<Typography variant="body2" color="error">
+						{error}
+					</Typography>
+				</Stack>
+			) : !entities || entities.length === 0 ? (
+				<Stack alignItems="center" justifyContent="center" height={200} sx={{ pt: 2 }}>
+					<Typography variant="body2" color="text.secondary">
+						No recent entities
+					</Typography>
+				</Stack>
+			) : (
+				<List disablePadding sx={{ pt: 2 }}>
+					{entities.slice(0, 7).map((entity) => {
+						const displayName = resolveLatestEntityDisplayName(entity);
+						const entityGuid = resolveLatestEntityGuid(entity);
+						const typeName = resolveLatestEntityTypeName(entity);
+						const timestamp = getEntityTimestampRawForDisplay(entity);
+						const detailHref = entityGuid
+							? `/detailPage/${entityGuid}`
+							: undefined;
+
+						return (
+							<ListItem
+								key={entityGuid || displayName}
+								disablePadding
+								sx={{
+									py: 1,
+									borderBottom: "1px solid",
+									borderColor: "divider",
+									"&:last-child": { borderBottom: "none" }
+								}}
+							>
+								<Stack width="100%" direction="row" justifyContent="space-between" alignItems="center">
+									<Stack direction="row" spacing={0.5} alignItems="center" flexWrap="wrap" flex={1} minWidth={0} mr={1}>
+										{detailHref ? (
+											<Link
+												component={RouterLink}
+												to={detailHref}
+												underline="hover"
+												color="primary"
+												sx={{
+													fontSize: "0.875rem",
+													overflow: "hidden",
+													textOverflow: "ellipsis",
+													cursor: "pointer",
+													maxWidth: "100%"
+												}}
+											>
+												{displayName}
+											</Link>
+										) : (
+											<Typography
+												component="span"
+												sx={{
+													fontSize: "0.875rem",
+													fontWeight: 500,
+													color: "text.primary"
+												}}
+											>
+												{displayName}
+											</Typography>
+										)}
+										<Typography
+											component="span"
+											sx={{
+												fontSize: "0.875rem",
+												color: "#6c757d",
+												flexShrink: 0
+											}}
+										>
+											({typeName})
+										</Typography>
+									</Stack>
+									<Typography sx={{ fontSize: "0.8125rem", color: "#6c757d", flexShrink: 0, ml: 1 }}>
+										{formatRelativeTime(timestamp)}
+									</Typography>
+								</Stack>
+							</ListItem>
+						);
+					})}
+				</List>
+			)}
+		</Paper>
+	);
+});
+
+LatestEntitiesList.displayName = "LatestEntitiesList";
+
+export default LatestEntitiesList;
diff --git a/dashboard/src/views/DashboardOverview/LatestEntitiesSkeleton.tsx b/dashboard/src/views/DashboardOverview/LatestEntitiesSkeleton.tsx
new file mode 100644
index 000000000..75e4f5960
--- /dev/null
+++ b/dashboard/src/views/DashboardOverview/LatestEntitiesSkeleton.tsx
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+import { Paper, Stack, Box } from "@mui/material";
+import SkeletonLoader from "@components/SkeletonLoader";
+
+const LatestEntitiesSkeleton = () => (
+	<Paper
+		elevation={1}
+		sx={{
+			padding: 2,
+			borderRadius: 2,
+			minHeight: 340,
+			minWidth: 0,
+			width: "100%",
+			flex: 1,
+			boxSizing: "border-box",
+			transition: "box-shadow 0.3s ease",
+			"&:hover": { boxShadow: 4 }
+		}}
+	>
+		<Box sx={{ pb: 2, borderBottom: "1px solid", borderColor: "divider" }}>
+			<Stack direction="row" justifyContent="space-between" alignItems="center">
+				<SkeletonLoader animation="wave" variant="text" count={1} width="60%" height={24} />
+				<SkeletonLoader animation="wave" variant="text" count={1} width={60} height={20} />
+			</Stack>
+		</Box>
+		<Stack spacing={1} sx={{ pt: 2 }}>
+			{[1, 2, 3, 4, 5, 6, 7].map((i) => (
+				<Stack key={i} direction="row" justifyContent="space-between" alignItems="center" sx={{ py: 0.5 }}>
+					<SkeletonLoader animation="wave" variant="text" count={1} width={`${70 + (i % 3) * 10}%`} height={20} />
+					<SkeletonLoader animation="wave" variant="text" count={1} width={80} height={18} />
+				</Stack>
+			))}
+		</Stack>
+	</Paper>
+);
+
+export default LatestEntitiesSkeleton;
diff --git a/dashboard/src/views/DashboardOverview/MessageConsumptionChart.tsx b/dashboard/src/views/DashboardOverview/MessageConsumptionChart.tsx
new file mode 100644
index 000000000..f2b98f687
--- /dev/null
+++ b/dashboard/src/views/DashboardOverview/MessageConsumptionChart.tsx
@@ -0,0 +1,257 @@
+/*
+ * 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.
+ */
+
+import { memo, useCallback } from "react";
+import { Stack, Typography, Box } from "@mui/material";
+import {
+	BarChart,
+	Bar,
+	XAxis,
+	YAxis,
+	CartesianGrid,
+	Tooltip,
+	ResponsiveContainer,
+	Cell,
+	LabelList,
+} from "recharts";
+import { numberFormatWithComma } from "@utils/Helper";
+import { type MessageConsumptionItem } from "@utils/metricsUtils";
+import {
+	CHART_BAR_ACTIVE_BLUE,
+	ENTITY_STATUS_DONUT_COLORS,
+} from "./dashboardChartPalette";
+
+const CREATES_COLOR = ENTITY_STATUS_DONUT_COLORS.Active;
+const UPDATES_COLOR = CHART_BAR_ACTIVE_BLUE;
+const DELETES_COLOR = ENTITY_STATUS_DONUT_COLORS.Deleted;
+
+interface MessageConsumptionChartProps {
+	/** Rows must already exclude the Total period when used from Kafka Topic Summary. */
+	data: MessageConsumptionItem[];
+	/** Optional accessible name for the chart region (embedded context). */
+	chartAriaLabel?: string;
+}
+
+const MessageConsumptionChart = memo(
+	({ data, chartAriaLabel }: MessageConsumptionChartProps) => {
+		const renderTooltip = useCallback(
+			(props: unknown) => {
+				const p = props as {
+					active?: boolean;
+					label?: string | number;
+					payload?: Array<{ payload?: MessageConsumptionItem }>;
+				};
+				if (!p?.active) return null;
+				const periodLabel =
+					p.label !== undefined && p.label !== null ? String(p.label) : "";
+				const rowFromLabel = periodLabel
+					? data.find((d) => d.period === periodLabel)
+					: undefined;
+				const row =
+					rowFromLabel ?? p.payload?.[0]?.payload ?? undefined;
+				if (!row) return null;
+				return (
+					<Box
+						sx={{
+							p: 1.5,
+							bgcolor: "background.paper",
+							borderRadius: 1,
+							boxShadow: 2,
+							minWidth: 160,
+						}}
+					>
+						<Typography variant="body2" fontWeight={600} sx={{ mb: 0.5 }}>
+							{row.period}
+						</Typography>
+						<Typography variant="caption" display="block" sx={{ color: CREATES_COLOR }}>
+							Creates: {numberFormatWithComma(row.creates)}
+						</Typography>
+						<Typography variant="caption" display="block" sx={{ color: UPDATES_COLOR }}>
+							Updates: {numberFormatWithComma(row.updates)}
+						</Typography>
+						<Typography variant="caption" display="block" sx={{ color: DELETES_COLOR }}>
+							Deletes: {numberFormatWithComma(row.deletes)}
+						</Typography>
+						<Typography variant="caption" display="block" sx={{ color: "#6c757d", mt: 0.5 }}>
+							Messages processed: {numberFormatWithComma(row.count)}
+						</Typography>
+						<Typography variant="caption" display="block" sx={{ color: "#6c757d" }}>
+							Avg time (ms): {numberFormatWithComma(row.avgTime)}
+						</Typography>
+					</Box>
+				);
+			},
+			[data]
+		);
+
+		if (data.length === 0) {
+			return (
+				<Stack alignItems="center" justifyContent="center" minHeight={200}>
+					<Typography variant="body2" color="text.secondary">
+						No message consumption data available
+					</Typography>
+				</Stack>
+			);
+		}
+
+		return (
+			<Box
+				role={chartAriaLabel ? "region" : undefined}
+				aria-label={chartAriaLabel}
+				sx={{ minHeight: 260, height: 260, width: "100%", minWidth: 280 }}
+			>
+				<Stack
+					direction="row"
+					spacing={2}
+					sx={{ mb: 1, flexWrap: "wrap" }}
+					aria-label="Chart legend"
+				>
+					<Stack direction="row" alignItems="center" spacing={0.75}>
+						<Box
+							sx={{
+								width: 10,
+								height: 10,
+								borderRadius: "50%",
+								backgroundColor: CREATES_COLOR,
+							}}
+							aria-hidden
+						/>
+						<Typography
+							variant="caption"
+							sx={{ color: "#6c757d", fontSize: "0.8125rem" }}
+						>
+							Creates
+						</Typography>
+					</Stack>
+					<Stack direction="row" alignItems="center" spacing={0.75}>
+						<Box
+							sx={{
+								width: 10,
+								height: 10,
+								borderRadius: "50%",
+								backgroundColor: UPDATES_COLOR,
+							}}
+							aria-hidden
+						/>
+						<Typography
+							variant="caption"
+							sx={{ color: "#6c757d", fontSize: "0.8125rem" }}
+						>
+							Updates
+						</Typography>
+					</Stack>
+					<Stack direction="row" alignItems="center" spacing={0.75}>
+						<Box
+							sx={{
+								width: 10,
+								height: 10,
+								borderRadius: "50%",
+								backgroundColor: DELETES_COLOR,
+							}}
+							aria-hidden
+						/>
+						<Typography
+							variant="caption"
+							sx={{ color: "#6c757d", fontSize: "0.8125rem" }}
+						>
+							Deletes
+						</Typography>
+					</Stack>
+				</Stack>
+				<ResponsiveContainer width="100%" height="100%">
+					<BarChart
+						data={data}
+						margin={{ top: 36, right: 28, left: 52, bottom: 36 }}
+					>
+						<CartesianGrid strokeDasharray="3 3" stroke="#f0f0f0" />
+						<XAxis
+							dataKey="period"
+							tick={{ fontSize: 11 }}
+							height={36}
+							label={{
+								value: "Period",
+								position: "bottom",
+								offset: 12,
+								style: { fontSize: 11, fill: "#6c757d" },
+							}}
+						/>
+						<YAxis
+							tickFormatter={(v) => numberFormatWithComma(v)}
+							width={48}
+							label={{
+								value: "Count",
+								angle: -90,
+								position: "left",
+								offset: 6,
+								style: { fontSize: 11, fill: "#6c757d", textAnchor: "middle" },
+							}}
+						/>
+						<Tooltip content={renderTooltip} cursor={{ fill: "transparent" }} />
+						<Bar
+							dataKey="creates"
+							name="Creates"
+							stackId="a"
+							fill={CREATES_COLOR}
+							radius={[0, 0, 0, 0]}
+						>
+							{data.map((_, index) => (
+								<Cell key={`creates-${index}`} fill={CREATES_COLOR} />
+							))}
+						</Bar>
+						<Bar
+							dataKey="updates"
+							name="Updates"
+							stackId="a"
+							fill={UPDATES_COLOR}
+							radius={[0, 0, 0, 0]}
+						>
+							{data.map((_, index) => (
+								<Cell key={`updates-${index}`} fill={UPDATES_COLOR} />
+							))}
+						</Bar>
+						<Bar
+							dataKey="deletes"
+							name="Deletes"
+							stackId="a"
+							fill={DELETES_COLOR}
+							radius={[0, 4, 4, 0]}
+						>
+							<LabelList
+								dataKey="count"
+								position="top"
+								offset={8}
+								formatter={(v: number) => numberFormatWithComma(v)}
+								style={{
+									fontSize: 11,
+									fontWeight: 600,
+									fill: "#374151",
+								}}
+							/>
+							{data.map((_, index) => (
+								<Cell key={`deletes-${index}`} fill={DELETES_COLOR} />
+							))}
+						</Bar>
+					</BarChart>
+				</ResponsiveContainer>
+			</Box>
+		);
+	}
+);
+
+MessageConsumptionChart.displayName = "MessageConsumptionChart";
+
+export default MessageConsumptionChart;
diff --git a/dashboard/src/views/DashboardOverview/OverviewCard.tsx b/dashboard/src/views/DashboardOverview/OverviewCard.tsx
new file mode 100644
index 000000000..41018055b
--- /dev/null
+++ b/dashboard/src/views/DashboardOverview/OverviewCard.tsx
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+
+import { Paper, Stack, Typography, Box } from "@mui/material";
+import { numberFormatWithComma } from "@utils/Helper";
+import { useNavigate } from "react-router-dom";
+import { navigateToSearch } from "@utils/dashboardSearchUtils";
+
+interface OverviewCardProps {
+	entityCount: number;
+	tagCount: number;
+	isLoading?: boolean;
+}
+
+const OverviewCard = ({ entityCount, tagCount, isLoading }: OverviewCardProps) => {
+	const navigate = useNavigate();
+
+	const handleEntitiesClick = () => {
+		navigateToSearch(navigate, "all_entities");
+	};
+
+	const handleClassificationsClick = () => {
+		navigateToSearch(navigate, "all_classifications");
+	};
+
+	if (isLoading) return null;
+
+	return (
+		<Paper
+			elevation={1}
+			sx={{
+				padding: 2,
+				borderRadius: 2,
+				minHeight: 200,
+				height: "100%",
+				boxSizing: "border-box",
+				transition: "box-shadow 0.3s ease",
+				"&:hover": { boxShadow: 4 }
+			}}
+		>
+			<Box sx={{ pb: 2, borderBottom: "1px solid", borderColor: "divider" }}>
+				<Typography sx={{ fontSize: "1rem", fontWeight: 600, color: "#1a1a1a" }}>
+					Overview
+				</Typography>
+			</Box>
+			<Stack direction="column" spacing={3} sx={{ pt: 2 }}>
+				<Stack alignItems="flex-start" spacing={0.5}>
+					<Typography
+						component="button"
+						sx={{
+							fontSize: "1.75rem",
+							fontWeight: 700,
+							background: "none",
+							border: "none",
+							cursor: "pointer",
+							padding: 0,
+							color: "#1a1a1a",
+							textAlign: "left",
+							lineHeight: 1.2,
+							"&:hover": { textDecoration: "underline", color: "primary.main" }
+						}}
+						onClick={handleEntitiesClick}
+						aria-label="View all entities"
+					>
+						{numberFormatWithComma(entityCount)}
+					</Typography>
+					<Typography sx={{ fontSize: "0.875rem", color: "#6c757d", textTransform: "capitalize" }}>
+						Entities
+					</Typography>
+				</Stack>
+				<Stack alignItems="flex-start" spacing={0.5}>
+					<Typography
+						component="button"
+						sx={{
+							fontSize: "1.75rem",
+							fontWeight: 700,
+							background: "none",
+							border: "none",
+							cursor: "pointer",
+							padding: 0,
+							color: "#1a1a1a",
+							textAlign: "left",
+							lineHeight: 1.2,
+							"&:hover": { textDecoration: "underline", color: "primary.main" }
+						}}
+						onClick={handleClassificationsClick}
+						aria-label="View all classifications"
+					>
+						{numberFormatWithComma(tagCount)}
+					</Typography>
+					<Typography sx={{ fontSize: "0.875rem", color: "#6c757d", textTransform: "capitalize" }}>
+						Classifications
+					</Typography>
+				</Stack>
+			</Stack>
+		</Paper>
+	);
+};
+
+export default OverviewCard;
diff --git a/dashboard/src/views/DashboardOverview/RecentActivity.tsx b/dashboard/src/views/DashboardOverview/RecentActivity.tsx
new file mode 100644
index 000000000..fdd5be150
--- /dev/null
+++ b/dashboard/src/views/DashboardOverview/RecentActivity.tsx
@@ -0,0 +1,408 @@
+/*
+ * 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.
+ */
+
+import { memo, useCallback, useEffect, useState } from "react";
+import { useAppSelector } from "@hooks/reducerHook";
+import { Paper, Stack, Typography, Link, Box, Chip, List, ListItem } from "@mui/material";
+import { RecentActivityListSkeleton } from "./RecentActivitySkeleton";
+import TypeDefAuditDetailModal from "@components/TypeDefAuditDetailModal";
+import { Link as RouterLink, useNavigate } from "react-router-dom";
+import { getAuditData } from "@api/apiMethods/detailpageApiMethod";
+import { category } from "@utils/Enum";
+import { extractTypeDefDetailObject } from "@utils/auditTypeDefUtils";
+import { dateFormat, isEmpty, jsonParse } from "@utils/Utils";
+
+export interface AuditRecord {
+	guid?: string;
+	userName?: string;
+	operation?: string;
+	params?: string;
+	result?: string;
+	startTime?: number;
+	endTime?: number;
+}
+
+const AUDIT_TABS = [
+	{ id: "typeCreated", label: "Created", operations: ["TYPE_DEF_CREATE"] },
+	{ id: "typeUpdated", label: "Updated", operations: ["TYPE_DEF_UPDATE"] },
+	{ id: "typeDeleted", label: "Deleted", operations: ["TYPE_DEF_DELETE"] },
+	{ id: "purge", label: "Purge", operations: ["PURGE", "AUTO_PURGE"] },
+	{ id: "import", label: "Import", operations: ["IMPORT"] },
+	{ id: "export", label: "Export", operations: ["EXPORT"] }
+] as const;
+
+interface ParsedAuditResult {
+	typeLabel: string;
+	entityName: string;
+	entityGuid?: string;
+	actionPhrase: string;
+	user: string;
+	dateStr: string;
+}
+
+const parseAuditRecord = (record: AuditRecord): ParsedAuditResult => {
+	const { operation, params, result, userName, endTime } = record;
+	const user = userName || "Unknown";
+	const dateStr = endTime ? dateFormat(endTime) : "";
+	let typeLabel = category[params as keyof typeof category] || params || "Type";
+	let actionPhrase = "";
+	let entityName = "";
+	let entityGuid = "";
+
+	if (operation === "PURGE" || operation === "AUTO_PURGE") {
+		try {
+			const guidStr = typeof result === "string" ? result.replace("[", "").replace("]", "").split(",")[0]?.trim() : "";
+			entityGuid = guidStr ?? "";
+			if (entityGuid) entityName = "View entity";
+		} catch {
+			/* ignore */
+		}
+		actionPhrase = "operation was performed";
+		return { typeLabel: operation === "AUTO_PURGE" ? "Auto purge" : "Purge", entityName, entityGuid, actionPhrase, user, dateStr };
+	}
+	if (operation === "EXPORT") {
+		return { typeLabel: "Export", entityName: "", entityGuid: "", actionPhrase: "operation was performed", user, dateStr };
+	}
+	if (operation === "IMPORT") {
+		return { typeLabel: "Import", entityName: "", entityGuid: "", actionPhrase: "operation was performed", user, dateStr };
+	}
+
+	if (operation === "TYPE_DEF_CREATE") {
+		actionPhrase = "was created";
+	} else if (operation === "TYPE_DEF_UPDATE") {
+		actionPhrase = "was updated";
+	} else if (operation === "TYPE_DEF_DELETE") {
+		actionPhrase = "was deleted";
+	} else {
+		return { typeLabel: operation || "", entityName: "", entityGuid: "", actionPhrase: "", user, dateStr };
+	}
+
+	try {
+		const resultObj = typeof result === "string" ? jsonParse(result) : result;
+		if (resultObj?.name) {
+			entityName = resultObj.name;
+			entityGuid = resultObj.guid ?? "";
+		} else if (resultObj && typeof resultObj === "object") {
+			const paramsKey = params?.split(",")[0]?.trim();
+			const arr = paramsKey ? resultObj[paramsKey] : resultObj[Object.keys(resultObj)[0]];
+			if (Array.isArray(arr) && arr[0]) {
+				entityName = arr[0].name ?? "";
+				entityGuid = arr[0].guid ?? "";
+			} else if (!Array.isArray(arr) && arr?.name) {
+				entityName = arr.name;
+				entityGuid = arr.guid ?? "";
+			}
+		}
+	} catch {
+		/* ignore */
+	}
+
+	return { typeLabel, entityName, entityGuid, actionPhrase, user, dateStr };
+};
+
+const getDetailUrl = (
+	operation: string | undefined,
+	params: string,
+	entityName: string,
+	entityGuid: string
+): string | null => {
+	if ((operation === "PURGE" || operation === "AUTO_PURGE") && entityGuid) {
+		return `/detailPage/${entityGuid}`;
+	}
+	if (!entityName && !entityGuid) return null;
+	/* Type Created/Updated/Deleted tabs - link to type details */
+	const param = params?.split(",")[0]?.trim();
+	if (param === "CLASSIFICATION") {
+		return `/tag/tagAttribute/${entityName}`;
+	}
+	if (param === "BUSINESS_METADATA" && entityGuid) {
+		return `/administrator/businessMetadata/${entityGuid}`;
+	}
+	if (["ENTITY", "ENUM", "RELATIONSHIP", "STRUCT"].includes(param ?? "")) {
+		return null;
+	}
+	return `/administrator?tabActive=typeSystem`;
+};
+
+const RecentActivity = memo(() => {
+	const dashboardRefreshVersion = useAppSelector((state) => state.dashboardRefresh.version);
+	const navigate = useNavigate();
+	const [activeTab, setActiveTab] = useState(0);
+	const [tabData, setTabData] = useState<Record<string, AuditRecord[]>>({
+		typeCreated: [],
+		typeUpdated: [],
+		typeDeleted: [],
+		purge: [],
+		import: [],
+		export: []
+	});
+	const [loading, setLoading] = useState<Record<string, boolean>>({
+		typeCreated: false,
+		typeUpdated: false,
+		typeDeleted: false,
+		purge: false,
+		import: false,
+		export: false
+	});
+
+	const fetchAudits = useCallback(async (tabId: string, operations: string[]) => {
+		setLoading((prev) => ({ ...prev, [tabId]: true }));
+		try {
+			const allResults: AuditRecord[] = [];
+			for (const op of operations) {
+				const auditFilters = {
+					condition: "AND" as const,
+					criterion: [
+						{
+							attributeName: "operation",
+							operator: "eq" as const,
+							attributeValue: op
+						}
+					]
+				};
+				const resp = await getAuditData({
+					auditFilters,
+					limit: 5,
+					offset: 0,
+					sortBy: "startTime",
+					sortOrder: "DESCENDING"
+				});
+				const data = (resp as { data?: AuditRecord[] })?.data ?? [];
+				if (Array.isArray(data)) allResults.push(...data);
+			}
+			allResults.sort((a, b) => (b.endTime ?? 0) - (a.endTime ?? 0));
+			setTabData((prev) => ({ ...prev, [tabId]: allResults.slice(0, 5) }));
+		} catch {
+			setTabData((prev) => ({ ...prev, [tabId]: [] }));
+		} finally {
+			setLoading((prev) => ({ ...prev, [tabId]: false }));
+		}
+	}, []);
+
+	useEffect(() => {
+		AUDIT_TABS.forEach((tab) => {
+			fetchAudits(tab.id, [...tab.operations]);
+		});
+	}, [fetchAudits, dashboardRefreshVersion]);
+
+	const handleViewAll = useCallback(() => {
+		navigate("/administrator?tabActive=audit");
+	}, [navigate]);
+
+	const handleTabChange = useCallback((_: React.SyntheticEvent, newValue: number) => {
+		setActiveTab(newValue);
+	}, []);
+
+	const currentTab = AUDIT_TABS[activeTab];
+	const records = tabData[currentTab?.id] ?? [];
+	const isLoading = loading[currentTab?.id] ?? false;
+
+	const [typeDetailOpen, setTypeDetailOpen] = useState(false);
+	const [typeDetailObject, setTypeDetailObject] = useState<Record<string, unknown> | null>(null);
+
+	const handleCloseTypeDetail = useCallback(() => {
+		setTypeDetailOpen(false);
+		setTypeDetailObject(null);
+	}, []);
+
+	const handleOpenTypeDetail = useCallback((obj: Record<string, unknown>) => {
+		setTypeDetailObject(obj);
+		setTypeDetailOpen(true);
+	}, []);
+
+	return (
+		<Paper
+			elevation={1}
+			sx={{
+				padding: 2,
+				borderRadius: 2,
+				minHeight: 280,
+				width: "100%",
+				boxSizing: "border-box",
+				transition: "box-shadow 0.3s ease",
+				"&:hover": { boxShadow: 4 }
+			}}
+		>
+			<Box sx={{ pb: 2, borderBottom: "1px solid", borderColor: "divider" }}>
+				<Stack direction="row" justifyContent="space-between" alignItems="center">
+					<Typography sx={{ fontSize: "1rem", fontWeight: 600, color: "#1a1a1a" }}>
+						Recent Activity
+					</Typography>
+					<Link
+						component="button"
+						onClick={handleViewAll}
+						sx={{
+							fontSize: "0.875rem",
+							cursor: "pointer",
+							textDecoration: "none",
+							color: "primary.main"
+						}}
+						aria-label="View all audits"
+					>
+						View All
+					</Link>
+				</Stack>
+			</Box>
+			<Stack direction="row" spacing={1} sx={{ mt: 1.5, flexWrap: "wrap", gap: 1 }}>
+				{AUDIT_TABS.map((tab, idx) => (
+					<Chip
+						key={tab.id}
+						label={tab.label}
+						onClick={(e) => handleTabChange(e as unknown as React.SyntheticEvent, idx)}
+						color={activeTab === idx ? "primary" : "default"}
+						variant={activeTab === idx ? "filled" : "outlined"}
+						sx={{
+							fontSize: "0.8125rem",
+							height: 32,
+							"&.MuiChip-filled": { fontWeight: 600 }
+						}}
+						aria-pressed={activeTab === idx}
+						aria-label={`${tab.label} tab`}
+					/>
+				))}
+			</Stack>
+			<Box sx={{ pt: 1 }}>
+				{isLoading ? (
+					<RecentActivityListSkeleton />
+				) : isEmpty(records) ? (
+					<Stack alignItems="center" justifyContent="center" height={180}>
+						<Typography variant="body2" color="text.secondary">
+							No records present
+						</Typography>
+					</Stack>
+				) : (
+					<List disablePadding>
+						{records.map((record, idx) => {
+							const parsed = parseAuditRecord(record);
+							const { typeLabel, entityName, entityGuid, actionPhrase, user, dateStr } = parsed;
+							const typeDefPayload = extractTypeDefDetailObject(
+								record,
+								entityName ?? "",
+								entityGuid ?? ""
+							);
+							const detailUrl = getDetailUrl(
+								record.operation ?? "",
+								record.params ?? "",
+								entityName ?? "",
+								entityGuid ?? ""
+							);
+
+							const openTypeModalIfNeeded = () => {
+								if (typeDefPayload) {
+									handleOpenTypeDetail(typeDefPayload);
+								}
+							};
+
+							const handleEntityNameKeyDown = (
+								e: React.KeyboardEvent
+							) => {
+								if (e.key !== "Enter" && e.key !== " ") return;
+								e.preventDefault();
+								openTypeModalIfNeeded();
+							};
+
+							return (
+								<ListItem
+									key={record.guid ?? idx}
+									disablePadding
+									sx={{
+										py: 1,
+										borderBottom: "1px solid",
+										borderColor: "divider",
+										"&:last-child": { borderBottom: "none" }
+									}}
+								>
+									<Typography component="span" sx={{ fontSize: "0.875rem", color: "#333" }}>
+										{entityName ? (
+											<>
+												{typeDefPayload ? (
+													<Link
+														component="button"
+														type="button"
+														onClick={openTypeModalIfNeeded}
+														onKeyDown={handleEntityNameKeyDown}
+														tabIndex={0}
+														aria-label={`Open ${typeLabel} type details for ${entityName}`}
+														sx={{
+															color: "primary.main",
+															textDecoration: "none",
+															background: "none",
+															border: "none",
+															cursor: "pointer",
+															padding: 0,
+															font: "inherit",
+															"&:hover": { textDecoration: "underline" },
+														}}
+													>
+														{entityName}
+													</Link>
+												) : detailUrl ? (
+													<Link
+														component={RouterLink}
+														to={detailUrl}
+														sx={{
+															color: "primary.main",
+															textDecoration: "none",
+															"&:hover": { textDecoration: "underline" }
+														}}
+													>
+														{entityName}
+													</Link>
+												) : (
+													entityName
+												)}
+												{" "}
+												{typeLabel} {actionPhrase} by{" "}
+												<Box component="span" sx={{ fontWeight: 700 }}>
+													{user}
+												</Box>{" "}
+												on{" "}
+												<Box component="span" sx={{ color: "#6c757d" }}>
+													{dateStr}
+												</Box>
+											</>
+										) : (
+											<>
+												{typeLabel} {actionPhrase} by{" "}
+												<Box component="span" sx={{ fontWeight: 700 }}>
+													{user}
+												</Box>{" "}
+												on{" "}
+												<Box component="span" sx={{ color: "#6c757d" }}>
+													{dateStr}
+												</Box>
+											</>
+										)}
+									</Typography>
+								</ListItem>
+							);
+						})}
+					</List>
+				)}
+			</Box>
+			<TypeDefAuditDetailModal
+				open={typeDetailOpen}
+				onClose={handleCloseTypeDetail}
+				detailObject={typeDetailObject}
+			/>
+		</Paper>
+	);
+});
+
+RecentActivity.displayName = "RecentActivity";
+
+export default RecentActivity;
diff --git a/dashboard/src/views/DashboardOverview/RecentActivitySkeleton.tsx b/dashboard/src/views/DashboardOverview/RecentActivitySkeleton.tsx
new file mode 100644
index 000000000..8ca10811f
--- /dev/null
+++ b/dashboard/src/views/DashboardOverview/RecentActivitySkeleton.tsx
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+import { Stack } from "@mui/material";
+import SkeletonLoader from "@components/SkeletonLoader";
+
+/** Shown inside Recent Activity while the active tab's audits are loading. */
+export const RecentActivityListSkeleton = () => (
+	<Stack spacing={1.5} sx={{ pt: 1 }}>
+		{[1, 2, 3, 4, 5].map((i) => (
+			<SkeletonLoader
+				key={i}
+				animation="wave"
+				variant="text"
+				count={1}
+				width={`${85 - i * 5}%`}
+				height={20}
+			/>
+		))}
+	</Stack>
+);
+
+export default RecentActivityListSkeleton;
diff --git a/dashboard/src/views/DashboardOverview/dashboardChartPalette.ts b/dashboard/src/views/DashboardOverview/dashboardChartPalette.ts
new file mode 100644
index 000000000..fb012a445
--- /dev/null
+++ b/dashboard/src/views/DashboardOverview/dashboardChartPalette.ts
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/** Matches Entity Status Overview donut — single source for dashboard charts */
+export const ENTITY_STATUS_DONUT_COLORS = {
+	Active: "#10b981",
+	Shell: "#f59e0b",
+	Deleted: "#ef4444",
+} as const;
+
+/** Active primary series / bar fill (aligned with Classification Distribution bars) */
+export const CHART_BAR_ACTIVE_BLUE = "#1976d2";
+
+/** Horizontal bar charts: Y-axis title + ticks; keep left tight to reduce card gutter */
+export const HORIZONTAL_BAR_CHART_MARGIN = {
+	top: 8,
+	right: 72,
+	left: 44,
+	bottom: 48,
+} as const;
+
+/** Tighter layout: short classification names — minimize dead space left of Y ticks */
+export const CLASSIFICATION_DISTRIBUTION_CHART_MARGIN = {
+	top: 8,
+	right: 72,
+	left: 12,
+	bottom: 48,
+} as const;
diff --git a/dashboard/src/views/DashboardOverview/latestEntitiesList.utils.ts b/dashboard/src/views/DashboardOverview/latestEntitiesList.utils.ts
new file mode 100644
index 000000000..118be6b15
--- /dev/null
+++ b/dashboard/src/views/DashboardOverview/latestEntitiesList.utils.ts
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+
+/** Shape of basic-search entity headers used by Latest Entities card. */
+export interface LatestEntityRowModel {
+	guid?: string;
+	name?: string;
+	typeName?: string;
+	displayText?: string;
+	attributes?: {
+		name?: string;
+		qualifiedName?: string;
+		__guid?: string;
+	};
+}
+
+/**
+ * Match Search name column: top-level name/displayText and attributes.name /
+ * qualifiedName (Atlas may return any of these).
+ */
+export const resolveLatestEntityDisplayName = (
+	entity: LatestEntityRowModel
+): string => {
+	const n =
+		entity.name ??
+		entity.attributes?.name ??
+		entity.attributes?.qualifiedName ??
+		entity.displayText ??
+		entity.guid;
+	return typeof n === "string" && n.trim() !== "" ? n.trim() : "Unknown";
+};
+
+export const resolveLatestEntityGuid = (
+	entity: LatestEntityRowModel
+): string | undefined => {
+	const g =
+		entity.guid ??
+		(typeof entity.attributes?.__guid === "string"
+			? entity.attributes.__guid
+			: undefined);
+	if (typeof g !== "string" || g.trim() === "") return undefined;
+	return g.trim();
+};
+
+export const resolveLatestEntityTypeName = (
+	entity: LatestEntityRowModel
+): string => {
+	const t = entity.typeName;
+	return typeof t === "string" && t.trim() !== "" ? t.trim() : "Entity";
+};
diff --git a/dashboard/src/views/DetailPage/BusinessMetadataDetails/BusinessMetadataDetailsLayout.tsx b/dashboard/src/views/DetailPage/BusinessMetadataDetails/BusinessMetadataDetailsLayout.tsx
index bb6f8f138..214c9faad 100644
--- a/dashboard/src/views/DetailPage/BusinessMetadataDetails/BusinessMetadataDetailsLayout.tsx
+++ b/dashboard/src/views/DetailPage/BusinessMetadataDetails/BusinessMetadataDetailsLayout.tsx
@@ -45,6 +45,7 @@ import { createEditBusinessMetadata } from "@api/apiMethods/typeDefApiMethods";
 import { cloneDeep } from "@utils/Helper";
 import { defaultAttrObj, defaultType } from "@utils/Enum";
 import { fetchBusinessMetaData } from "@redux/slice/typeDefSlices/typedefBusinessMetadataSlice";
+import { fetchEntityData } from "@redux/slice/typeDefSlices/typedefEntitySlice";
 import { getTypeName } from "@utils/CommonViewFunction";
 
 const BusinessMetadataDetailsLayout = () => {
@@ -241,6 +242,7 @@ const BusinessMetadataDetailsLayout = () => {
     try {
       await createEditBusinessMetadata("business_metadata", "PUT", data);
       dispatchState(fetchBusinessMetaData());
+      dispatchState(fetchEntityData());
       toast.success(
         "One or more Business Metadata attributes were updated successfully"
       );
diff --git a/dashboard/src/views/DetailPage/EntityDetailTabs/ClassificationsTab.tsx b/dashboard/src/views/DetailPage/EntityDetailTabs/ClassificationsTab.tsx
index c898692c5..0fdd395f6 100644
--- a/dashboard/src/views/DetailPage/EntityDetailTabs/ClassificationsTab.tsx
+++ b/dashboard/src/views/DetailPage/EntityDetailTabs/ClassificationsTab.tsx
@@ -78,6 +78,7 @@ const ClassificationsTab: React.FC<EntityDetailTabProps> = ({
   );
 
   const [openModal, setOpenModal] = useState<boolean>(false);
+  const [removeAssignmentLoading, setRemoveAssignmentLoading] = useState(false);
   const [tagModal, setTagModal] = useState<boolean>(false);
   const [updateTable, setUpdateTable] = useState(moment.now());
   const [rowdata, setRowData] = useState();
@@ -129,6 +130,7 @@ const ClassificationsTab: React.FC<EntityDetailTabProps> = ({
 
   const handleRemove = async () => {
     try {
+      setRemoveAssignmentLoading(true);
       await removeClassification(guid, currentValue.selectedValue);
       if (!isEmpty(guid)) {
         dispatchApi(fetchDetailPageData(guid as string));
@@ -145,6 +147,8 @@ const ClassificationsTab: React.FC<EntityDetailTabProps> = ({
       setOpenModal(false);
     } catch (error) {
       serverError(error, toastId);
+    } finally {
+      setRemoveAssignmentLoading(false);
     }
   };
 
@@ -381,6 +385,8 @@ const ClassificationsTab: React.FC<EntityDetailTabProps> = ({
           button1Handler={handleCloseModal}
           button2Label="Remove"
           button2Handler={handleRemove}
+          disableButton2={removeAssignmentLoading}
+          button2Loading={removeAssignmentLoading}
         >
           <Typography fontSize={15}>
             Remove: <b>{currentValue.selectedValue}</b> assignment from{" "}
diff --git a/dashboard/src/views/DetailPage/EntityDetailTabs/PropagationPropertyModal.tsx b/dashboard/src/views/DetailPage/EntityDetailTabs/PropagationPropertyModal.tsx
index 5ab64aef6..1ea05c701 100644
--- a/dashboard/src/views/DetailPage/EntityDetailTabs/PropagationPropertyModal.tsx
+++ b/dashboard/src/views/DetailPage/EntityDetailTabs/PropagationPropertyModal.tsx
@@ -421,6 +421,7 @@ const PropagationPropertyModal = ({
         button2Label="Update"
         button2Handler={() => onSubmit()}
         disableButton2={loading}
+        button2Loading={loading}
       >
         <Stack gap={2}>
           <Stack direction="row" alignItems="center" gap="0.5rem">
diff --git a/dashboard/src/views/DetailPage/GlossaryDetails/TermRelation.tsx b/dashboard/src/views/DetailPage/GlossaryDetails/TermRelation.tsx
index ba1381528..68d069ea7 100644
--- a/dashboard/src/views/DetailPage/GlossaryDetails/TermRelation.tsx
+++ b/dashboard/src/views/DetailPage/GlossaryDetails/TermRelation.tsx
@@ -219,6 +219,7 @@ const TermRelation = ({ glossaryTypeData }: any) => {
           button2Label={editModal ? "Update" : "Close"}
           button2Handler={editModal ? handleSubmit(onSubmit) : handleCloseModal}
           disableButton2={isSubmitting}
+          button2Loading={isSubmitting}
           maxWidth="md"
         >
           <form onSubmit={handleSubmit(onSubmit)}>
diff --git a/dashboard/src/views/Entity/EntityForm.tsx b/dashboard/src/views/Entity/EntityForm.tsx
index f075b943f..e6a66fa99 100644
--- a/dashboard/src/views/Entity/EntityForm.tsx
+++ b/dashboard/src/views/Entity/EntityForm.tsx
@@ -521,6 +521,7 @@ const EntityForm = ({
       button2Label={guid ? "Update" : "Create"}
       button2Handler={handleSubmit(onSubmit)}
       disableButton2={isSubmitting}
+      button2Loading={isSubmitting}
       isDirty={isDirty}
       maxWidth="md"
     >
diff --git a/dashboard/src/views/Glossary/AddUpdateCategoryForm.tsx b/dashboard/src/views/Glossary/AddUpdateCategoryForm.tsx
index 12a80b6de..bd9084861 100644
--- a/dashboard/src/views/Glossary/AddUpdateCategoryForm.tsx
+++ b/dashboard/src/views/Glossary/AddUpdateCategoryForm.tsx
@@ -146,6 +146,7 @@ const AddUpdateCategoryForm = (props: {
         button1Handler={onClose}
         button2Label={isAdd ? "Create" : "Update"}
         disableButton2={isSubmitting}
+        button2Loading={isSubmitting}
         maxWidth="sm"
         button2Handler={handleSubmit(onSubmit)}
       >
diff --git a/dashboard/src/views/Glossary/AddUpdateGlossaryForm.tsx b/dashboard/src/views/Glossary/AddUpdateGlossaryForm.tsx
index 4aa2248d1..5f4a22854 100644
--- a/dashboard/src/views/Glossary/AddUpdateGlossaryForm.tsx
+++ b/dashboard/src/views/Glossary/AddUpdateGlossaryForm.tsx
@@ -19,108 +19,370 @@ import CustomModal from "@components/Modal";
 import GlossaryForm from "./GlossaryForm";
 import { useForm } from "react-hook-form";
 import {
-  createGlossary,
-  editGlossary
+	createGlossary,
+	editGlossary
 } from "@api/apiMethods/glossaryApiMethod";
 import { isEmpty, serverError } from "@utils/Utils";
+import {
+	downloadGlossaryImportTemplate,
+	postGlossaryImportFormData
+} from "@utils/glossaryImportFlow";
+import { getApiErrorToastMessage } from "@utils/apiErrorToastMessage";
 import { toast } from "react-toastify";
-import { useRef } from "react";
+import { useCallback, useEffect, useRef, useState } from "react";
+import type { MouseEvent } from "react";
 import { useAppDispatch, useAppSelector } from "@hooks/reducerHook";
 import { fetchGlossaryData } from "@redux/slice/glossarySlice";
+import {
+	Button,
+	IconButton,
+	List,
+	ListItem,
+	ListItemText,
+	Stack,
+	ToggleButton,
+	ToggleButtonGroup
+} from "@mui/material";
+import FileDownloadIcon from "@mui/icons-material/FileDownload";
+import ArrowBackIosNewIcon from "@mui/icons-material/ArrowBackIosNew";
+import ImportLayout from "@views/SideBar/Import/ImportLayout";
+import { LightTooltip } from "@components/muiComponents";
+
+type GlossaryCreateTab = "create" | "import";
+
+const hasSelectedImportFile = (fileData: unknown): boolean => {
+	if (fileData == null) return false;
+	if (fileData instanceof File) return true;
+	if (typeof fileData === "object" && Object.keys(fileData as object).length > 0)
+		return true;
+	return false;
+};
 
 const AddUpdateGlossaryForm = (props: {
-  open: any;
-  onClose: any;
-  isAdd: any;
-  node: Record<string, any> | undefined;
+	open: any;
+	onClose: any;
+	isAdd: any;
+	node: Record<string, any> | undefined;
 }) => {
-  const { open, onClose, isAdd, node } = props;
-  const dispatch = useAppDispatch();
-  const toastId: any = useRef(null);
-  const { glossaryData }: any = useAppSelector((state: any) => state.glossary);
-  const { id } = node || {};
-  let defaultValue: Record<string, string> = {};
-  let glossaryObj: Record<string, string> = {};
-  if (!isAdd) {
-    glossaryObj = glossaryData.find((obj: { name: string }) => {
-      return obj.name == id;
-    });
-    const { name, shortDescription, longDescription } = glossaryObj || {};
-
-    defaultValue["name"] = name;
-    defaultValue["shortDescription"] = shortDescription;
-    defaultValue["longDescription"] = longDescription;
-  }
-  const {
-    control,
-    handleSubmit,
-    setValue,
-    formState: { isSubmitting }
-  } = useForm({
-    defaultValues: isAdd ? {} : defaultValue,
-    mode: "onChange",
-    shouldUnregister: true
-  });
-
-  const onSubmit = async (formValues: any) => {
-    let formData = { ...formValues };
-    const { guid, qualifiedName } = glossaryObj;
-    const {
-      name,
-      shortDescription,
-      longDescription
-    }: { name: string; shortDescription: string; longDescription: string } =
-      formData;
-    let data: Record<string, string> = {};
-    if (!isAdd) {
-      data["guid"] = guid;
-      data["qualifiedName"] = qualifiedName;
-    }
-    data["name"] = name;
-    data["shortDescription"] = !isEmpty(shortDescription)
-      ? shortDescription
-      : "";
-    data["longDescription"] = !isEmpty(longDescription) ? longDescription : "";
-
-    try {
-      if (isAdd) {
-        await createGlossary(data);
-      } else {
-        await editGlossary(guid, data);
-      }
-
-      await dispatch(fetchGlossaryData());
-      toast.dismiss(toastId.current);
-      toastId.current = toast.success(
-        `Glossary ${name} was ${isAdd ? "created" : "updated"} successfully`
-      );
-      onClose();
-    } catch (error) {
-      serverError(error, toastId);
-    }
-  };
-
-  return (
-    <>
-      <CustomModal
-        open={open}
-        onClose={onClose}
-        title={isAdd ? "Create Glossary" : "Edit Glossary"}
-        button1Label="Cancel"
-        button1Handler={onClose}
-        button2Label={isAdd ? "Create" : "Update"}
-        maxWidth="sm"
-        button2Handler={handleSubmit(onSubmit)}
-        disableButton2={isSubmitting}
-      >
-        <GlossaryForm
-          control={control}
-          handleSubmit={handleSubmit(onSubmit)}
-          setValue={setValue}
-        />
-      </CustomModal>
-    </>
-  );
+	const { open, onClose, isAdd, node } = props;
+	const dispatch = useAppDispatch();
+	const toastId: any = useRef(null);
+	const { glossaryData }: any = useAppSelector((state: any) => state.glossary);
+	const { id } = node || {};
+	let defaultValue: Record<string, string> = {};
+	let glossaryObj: Record<string, string> = {};
+	if (!isAdd) {
+		glossaryObj = glossaryData.find((obj: { name: string }) => {
+			return obj.name == id;
+		});
+		const { name, shortDescription, longDescription } = glossaryObj || {};
+
+		defaultValue["name"] = name;
+		defaultValue["shortDescription"] = shortDescription;
+		defaultValue["longDescription"] = longDescription;
+	}
+	const {
+		control,
+		handleSubmit,
+		setValue,
+		formState: { isSubmitting }
+	} = useForm({
+		defaultValues: isAdd ? {} : defaultValue,
+		mode: "onChange",
+		shouldUnregister: true
+	});
+
+	const [glossaryCreateTab, setGlossaryCreateTab] =
+		useState<GlossaryCreateTab>("create");
+	const [importFileData, setImportFileData] = useState<any>([]);
+	const [importProgress, setImportProgress] = useState(0);
+	const [importErrorDetails, setImportErrorDetails] = useState(false);
+	const [importData, setImportData] = useState<any>(null);
+	const [importUploading, setImportUploading] = useState(false);
+
+	const resetImportUi = useCallback(() => {
+		setGlossaryCreateTab("create");
+		setImportFileData([]);
+		setImportProgress(0);
+		setImportErrorDetails(false);
+		setImportData(null);
+		setImportUploading(false);
+	}, []);
+
+	const handleModalClose = useCallback(() => {
+		resetImportUi();
+		onClose();
+	}, [onClose, resetImportUi]);
+
+	useEffect(() => {
+		if (!open) {
+			resetImportUi();
+		}
+	}, [open, resetImportUi]);
+
+	const handleGlossaryCreateTabChange = (
+		_event: MouseEvent<HTMLElement>,
+		next: GlossaryCreateTab | null
+	) => {
+		if (next == null) return;
+		setGlossaryCreateTab(next);
+		if (next === "create") {
+			setImportFileData([]);
+			setImportProgress(0);
+			setImportErrorDetails(false);
+			setImportData(null);
+		}
+	};
+
+	const handleDownloadTemplate = async () => {
+		try {
+			await downloadGlossaryImportTemplate();
+		} catch {
+			toast.dismiss(toastId.current);
+			toastId.current = toast.error("Could not download template");
+		}
+	};
+
+	const handleImportUpload = async () => {
+		if (!hasSelectedImportFile(importFileData)) return;
+		setImportUploading(true);
+		try {
+			const importResp = await postGlossaryImportFormData(
+				importFileData,
+				(pct) => setImportProgress(pct)
+			);
+			if (importResp.data.failedImportInfoList == undefined) {
+				toast.dismiss(toastId.current);
+				toastId.current = toast.success(
+					`File: ${importFileData.name} imported successfully`
+				);
+				await dispatch(fetchGlossaryData());
+				handleModalClose();
+				return;
+			}
+			if (importResp.data.failedImportInfoList != undefined) {
+				toast.dismiss(toastId.current);
+				toastId.current = toast.error(
+					importResp.data.failedImportInfoList[0].remarks
+				);
+				setImportErrorDetails(true);
+			}
+			setImportData(importResp.data);
+		} catch (error) {
+			const message = getApiErrorToastMessage(error);
+			if (message === null) {
+				return;
+			}
+			toast.dismiss(toastId.current);
+			toastId.current = toast.error(message);
+		} finally {
+			setImportUploading(false);
+		}
+	};
+
+	const onSubmit = async (formValues: any) => {
+		let formData = { ...formValues };
+		const { guid, qualifiedName } = glossaryObj;
+		const {
+			name,
+			shortDescription,
+			longDescription
+		}: { name: string; shortDescription: string; longDescription: string } =
+			formData;
+		let data: Record<string, string> = {};
+		if (!isAdd) {
+			data["guid"] = guid;
+			data["qualifiedName"] = qualifiedName;
+		}
+		data["name"] = name;
+		data["shortDescription"] = !isEmpty(shortDescription)
+			? shortDescription
+			: "";
+		data["longDescription"] = !isEmpty(longDescription) ? longDescription : "";
+
+		try {
+			if (isAdd) {
+				await createGlossary(data);
+			} else {
+				await editGlossary(guid, data);
+			}
+
+			await dispatch(fetchGlossaryData());
+			toast.dismiss(toastId.current);
+			toastId.current = toast.success(
+				`Glossary ${name} was ${isAdd ? "created" : "updated"} successfully`
+			);
+			handleModalClose();
+		} catch (error) {
+			serverError(error, toastId);
+		}
+	};
+
+	const showImportError = isAdd && glossaryCreateTab === "import" && importErrorDetails;
+
+	const modalTitle = showImportError
+		? "Error Details"
+		: isAdd
+			? "Create Glossary"
+			: "Edit Glossary";
+
+	const titleIconNode =
+		showImportError ? (
+			<IconButton
+				aria-label="Back to import file"
+				onClick={(e) => {
+					e.stopPropagation();
+					setImportErrorDetails(false);
+				}}
+				size="small"
+				sx={{ color: (theme) => theme.palette.grey[500] }}
+			>
+				<LightTooltip title="Back to import file">
+					<ArrowBackIosNewIcon sx={{ fontSize: "1.25rem" }} />
+				</LightTooltip>
+			</IconButton>
+		) : undefined;
+
+	const isImportMode = isAdd && glossaryCreateTab === "import" && !importErrorDetails;
+
+	const button2Label = (() => {
+		if (!isAdd) return "Update";
+		if (glossaryCreateTab === "create") return "Create";
+		if (importErrorDetails) return "";
+		return "Upload";
+	})();
+
+	const button2Handler = (() => {
+		if (!isAdd || glossaryCreateTab === "create") return handleSubmit(onSubmit);
+		if (importErrorDetails) return () => {};
+		return handleImportUpload;
+	})();
+
+	const disableButton2 = (() => {
+		if (!isAdd) return isSubmitting;
+		if (glossaryCreateTab === "create") return isSubmitting;
+		if (importErrorDetails) return true;
+		return !hasSelectedImportFile(importFileData);
+	})();
+
+	const button2Loading =
+		isAdd && glossaryCreateTab === "import" && !importErrorDetails
+			? importUploading
+			: isSubmitting;
+
+	const hideButton2 = Boolean(
+		isAdd && glossaryCreateTab === "import" && importErrorDetails
+	);
+
+	return (
+		<>
+			<CustomModal
+				open={open}
+				onClose={handleModalClose}
+				title={modalTitle}
+				titleIcon={titleIconNode}
+				button1Label="Cancel"
+				button1Handler={handleModalClose}
+				button2Label={button2Label}
+				maxWidth="sm"
+				button2Handler={button2Handler}
+				disableButton2={disableButton2}
+				button2Loading={button2Loading}
+				hideButton2={hideButton2}
+			>
+				<Stack>
+					{isAdd && (
+						<Stack marginBottom="1rem">
+							<ToggleButtonGroup
+								exclusive
+								value={glossaryCreateTab}
+								onChange={handleGlossaryCreateTabChange}
+								size="small"
+								color="primary"
+								aria-label="Choose create glossary or import glossary terms"
+							>
+								<ToggleButton
+									value="create"
+									className="entity-form-toggle-btn"
+									data-cy="create-glossary-tab"
+								>
+									Create glossary
+								</ToggleButton>
+								<ToggleButton
+									value="import"
+									className="entity-form-toggle-btn"
+									data-cy="import-glossary-terms-tab"
+								>
+									Import glossary terms
+								</ToggleButton>
+							</ToggleButtonGroup>
+						</Stack>
+					)}
+					{(!isAdd || glossaryCreateTab === "create") && (
+						<GlossaryForm
+							control={control}
+							handleSubmit={handleSubmit(onSubmit)}
+							setValue={setValue}
+						/>
+					)}
+					{isImportMode && (
+						<Stack gap={2}>
+							<Button
+								variant="outlined"
+								color="primary"
+								startIcon={<FileDownloadIcon />}
+								onClick={handleDownloadTemplate}
+								aria-label="Download import template"
+							>
+								Download import template
+							</Button>
+							<ImportLayout
+								setFileData={setImportFileData}
+								progressVal={importProgress}
+								setProgress={setImportProgress}
+								selectedFile={
+									importFileData !== undefined &&
+									hasSelectedImportFile(importFileData)
+										? [importFileData]
+										: []
+								}
+								errorDetails={importErrorDetails}
+							/>
+						</Stack>
+					)}
+					{showImportError && importData?.failedImportInfoList && (
+						<Stack
+							sx={{
+								width: "100%",
+								minHeight: 200,
+								maxHeight: 400,
+								bgcolor: "background.paper"
+							}}
+						>
+							<List>
+								{importData.failedImportInfoList.map(
+									(
+										value: {
+											index: number;
+											remarks: string;
+										},
+										index: number
+									) => (
+										<ListItem key={value.index} disableGutters disablePadding>
+											<ListItemText
+												className="dropzone-listitem"
+												primary={`${index + 1}. ${value.remarks}`}
+											/>
+										</ListItem>
+									)
+								)}
+							</List>
+						</Stack>
+					)}
+				</Stack>
+			</CustomModal>
+		</>
+	);
 };
 
 export default AddUpdateGlossaryForm;
diff --git a/dashboard/src/views/Glossary/AddUpdateTermForm.tsx b/dashboard/src/views/Glossary/AddUpdateTermForm.tsx
index feea62032..f5ece0289 100644
--- a/dashboard/src/views/Glossary/AddUpdateTermForm.tsx
+++ b/dashboard/src/views/Glossary/AddUpdateTermForm.tsx
@@ -142,6 +142,7 @@ const AddUpdateTermForm = (props: {
         button1Handler={onClose}
         button2Label={isAdd ? "Create" : "Update"}
         disableButton2={isSubmitting}
+        button2Loading={isSubmitting}
         maxWidth="sm"
         button2Handler={handleSubmit(onSubmit)}
       >
diff --git a/dashboard/src/views/Glossary/AssignCategory.tsx b/dashboard/src/views/Glossary/AssignCategory.tsx
index 9e588ae3c..5a6f8f8b9 100644
--- a/dashboard/src/views/Glossary/AssignCategory.tsx
+++ b/dashboard/src/views/Glossary/AssignCategory.tsx
@@ -288,6 +288,7 @@ const AssignCategory = ({
         maxWidth="sm"
         button2Handler={assignCatgeory}
         disableButton2={loading}
+        button2Loading={loading}
       >
         <Stack>
           <TextField
diff --git a/dashboard/src/views/Glossary/AssignTerm.tsx b/dashboard/src/views/Glossary/AssignTerm.tsx
index 14eceb720..e4c2fc0ed 100644
--- a/dashboard/src/views/Glossary/AssignTerm.tsx
+++ b/dashboard/src/views/Glossary/AssignTerm.tsx
@@ -452,6 +452,7 @@ const AssignTerm = ({
         maxWidth="sm"
         button2Handler={relatedTerm ? handleSubmit(onSubmit) : assignTerm}
         disableButton2={isSubmitting}
+        button2Loading={isSubmitting}
         isDirty={!isEmpty(selectedNode)}
       >
         {relatedTerm ? (
diff --git a/dashboard/src/views/Glossary/DeleteGlossary.tsx b/dashboard/src/views/Glossary/DeleteGlossary.tsx
index 744447494..c4b5dcf60 100644
--- a/dashboard/src/views/Glossary/DeleteGlossary.tsx
+++ b/dashboard/src/views/Glossary/DeleteGlossary.tsx
@@ -26,6 +26,7 @@ import { Typography } from "@mui/material";
 import { fetchGlossaryData } from "@redux/slice/glossarySlice";
 import { isEmpty, serverError } from "@utils/Utils";
 import { useRef } from "react";
+import { useAsyncPending } from "@hooks/useAsyncPending";
 import { useLocation, useNavigate, useParams } from "react-router-dom";
 import { toast } from "react-toastify";
 
@@ -48,36 +49,39 @@ const DeleteGlossary = (props: {
   const navigate = useNavigate();
   const dispatchApi = useAppDispatch();
   const toastId: any = useRef(null);
+  const { pending: deleteInProgress, run: runDelete } = useAsyncPending();
 
   const fetchCurrentData = async () => {
     await dispatchApi(fetchGlossaryData());
   };
 
-  const handleRemove = async () => {
-    try {
-      gtype == "term"
-        ? await deleteGlossaryorType(cGuid)
-        : await deleteGlossaryorTerm(guid);
-      updatedData();
-      fetchCurrentData();
-      toast.success(
-        `${
-          gtype == "term" ? "Term" : "Glossary"
-        } ${id} was deleted successfully`
-      );
-      if (!isEmpty(glossaryGuid) || !isEmpty(glossaryType)) {
-        navigate(
-          {
-            pathname: "/"
-          },
-          { replace: true }
+  const handleRemove = () => {
+    void runDelete(async () => {
+      try {
+        gtype == "term"
+          ? await deleteGlossaryorType(cGuid)
+          : await deleteGlossaryorTerm(guid);
+        updatedData();
+        await fetchCurrentData();
+        toast.success(
+          `${
+            gtype == "term" ? "Term" : "Glossary"
+          } ${id} was deleted successfully`
         );
+        if (!isEmpty(glossaryGuid) || !isEmpty(glossaryType)) {
+          navigate(
+            {
+              pathname: "/"
+            },
+            { replace: true }
+          );
+        }
+        onClose();
+        setExpandNode(null);
+      } catch (error) {
+        serverError(error, toastId);
       }
-      onClose();
-      setExpandNode(null);
-    } catch (error) {
-      serverError(error, toastId);
-    }
+    });
   };
 
   return (
@@ -92,6 +96,8 @@ const DeleteGlossary = (props: {
         button2Label="Ok"
         maxWidth="sm"
         button2Handler={handleRemove}
+        disableButton2={deleteInProgress}
+        button2Loading={deleteInProgress}
       >
         <Typography fontSize={15}>
           Are you sure you want to delete{" "}
diff --git a/dashboard/src/views/SaveFilters/SaveFilters.tsx b/dashboard/src/views/SaveFilters/SaveFilters.tsx
index fed2fe27f..ac65237ec 100644
--- a/dashboard/src/views/SaveFilters/SaveFilters.tsx
+++ b/dashboard/src/views/SaveFilters/SaveFilters.tsx
@@ -206,6 +206,7 @@ const SaveFilters = ({
         maxWidth="sm"
         button2Handler={handleSubmit(onSubmit)}
         disableButton2={isSubmitting}
+        button2Loading={isSubmitting}
       >
         {" "}
         <form onSubmit={handleSubmit(onSubmit)}>
diff --git a/dashboard/src/views/SearchResult/SearchResult.tsx b/dashboard/src/views/SearchResult/SearchResult.tsx
index a026e1175..5d850d93a 100644
--- a/dashboard/src/views/SearchResult/SearchResult.tsx
+++ b/dashboard/src/views/SearchResult/SearchResult.tsx
@@ -71,6 +71,9 @@ interface Params {
   classification: any;
   termName: string | null;
   relationshipFilters?: string | null;
+  sortBy?: string;
+  sortOrder?: string;
+  excludeHeaderAttributes?: boolean;
 }
 
 let defaultColumnsName: Array<string> = [
@@ -155,6 +158,15 @@ const SearchResult = ({ classificationParams, glossaryTypeParams, hideFilters }:
           ? !searchParams.get("excludeST")
           : true,
         includeClassificationAttributes: true,
+        ...(!isEmpty(searchParams.get("sortBy")) && {
+          sortBy: searchParams.get("sortBy")
+        }),
+        ...(!isEmpty(searchParams.get("sortOrder")) && {
+          sortOrder: searchParams.get("sortOrder")
+        }),
+        ...(searchParams.get("excludeHeaderAttributes") === "true" && {
+          excludeHeaderAttributes: true
+        }),
         ...(isEmpty(classificationParams || glossaryTypeParams) && {
           entityFilters: !isEmpty(entityFilterParams)
             ? searchParamsAPiQuery(entityFilterParams)
@@ -1000,12 +1012,20 @@ const SearchResult = ({ classificationParams, glossaryTypeParams, hideFilters }:
 
     return hideColumns;
   };
+  const latestEntitiesSortBy = searchParams.get("sortBy");
+  const latestEntitiesSortOrder = searchParams.get("sortOrder");
   const getDefaultSort = useMemo(() => {
     if (isDslAggregate) {
       return [] as any[]; // no default sorting for DSL aggregates
     }
-    return [{ id: "name", asc: true }];
-  }, [isDslAggregate]);
+    if (
+      latestEntitiesSortBy === "__timestamp" &&
+      latestEntitiesSortOrder === "DESCENDING"
+    ) {
+      return [{ id: "__timestamp", desc: true }];
+    }
+    return [{ id: "name", desc: false }];
+  }, [isDslAggregate, latestEntitiesSortBy, latestEntitiesSortOrder]);
 
   return (
     <Stack position="relative" gap={"1rem"}>
diff --git a/dashboard/src/views/SideBar/SideBarTree/SideBarTree.tsx b/dashboard/src/views/SideBar/SideBarTree/SideBarTree.tsx
index 02f5e27b6..bc9e444c2 100644
--- a/dashboard/src/views/SideBar/SideBarTree/SideBarTree.tsx
+++ b/dashboard/src/views/SideBar/SideBarTree/SideBarTree.tsx
@@ -64,7 +64,7 @@ import { globalSearchFilterInitialQuery, isEmpty } from "@utils/Utils";
 import { attributeFilter } from "@utils/CommonViewFunction";
 import { cloneDeep } from "@utils/Helper";
 import LaunchOutlinedIcon from "@mui/icons-material/LaunchOutlined";
-import { getGlossaryImportTmpl } from "@api/apiMethods/glossaryApiMethod";
+import { downloadGlossaryImportTemplate } from "@utils/glossaryImportFlow";
 import { toast } from "react-toastify";
 import { EnumTypeDefData, TreeNode } from "@models/treeStructureType";
 import ImportDialog from "@components/ImportDialog";
@@ -969,33 +969,26 @@ const BarTreeView: FC<{
 
   const downloadFile = async () => {
     try {
-      let apiResp: any = {};
-      if (treeName == "Entities") {
-        apiResp = await getBusinessMetadataImportTmpl({});
-      } else if (treeName == "Glossary") {
-        apiResp = await getGlossaryImportTmpl({});
-      }
-      let text: string = "";
-      if (apiResp) {
-        text = apiResp.data;
+      if (treeName == "Glossary") {
+        await downloadGlossaryImportTemplate();
+        return;
       }
+      const apiResp: any = await getBusinessMetadataImportTmpl({});
+      const text: string = apiResp ? apiResp.data : "";
       const blob = new Blob([text], { type: "text/plain" });
 
       const url = window.URL.createObjectURL(blob);
 
       const link = document.createElement("a");
       link.href = url;
-      if (treeName == "Entities") {
-        link.setAttribute("download", "template_business_metadata");
-      } else if (treeName == "Glossary") {
-        link.setAttribute("download", "template");
-      }
+      link.setAttribute("download", "template_business_metadata");
 
       document.body.appendChild(link);
 
       link.click();
 
       document.body.removeChild(link);
+      window.URL.revokeObjectURL(url);
     } catch {
       /* ignore download error */
     }
diff --git a/dashboard/src/views/Statistics/ServerStats.tsx b/dashboard/src/views/Statistics/ServerStats.tsx
index 9f6974614..5f131c41c 100644
--- a/dashboard/src/views/Statistics/ServerStats.tsx
+++ b/dashboard/src/views/Statistics/ServerStats.tsx
@@ -118,12 +118,11 @@ const ServerStats = ({ selectedValue, currentMetricsData }: any) => {
 
   let notificationTableHeader = [
     "Count",
-    "Avg",
-    "Time (ms)",
+    "Avg time (ms)",
     "Creates",
     "Updates",
-    "Deletes"
-    // "Failed"
+    "Deletes",
+    "Failed"
   ];
 
   let topciOffsetTableHeader = [
diff --git a/dashboard/src/views/Statistics/Statistics.tsx b/dashboard/src/views/Statistics/Statistics.tsx
index 6204a6d08..51bb42077 100644
--- a/dashboard/src/views/Statistics/Statistics.tsx
+++ b/dashboard/src/views/Statistics/Statistics.tsx
@@ -23,6 +23,7 @@ import ClassificationStats from "./ClassificationStats";
 import {
   Autocomplete,
   Badge,
+  CircularProgress,
   IconButton,
   Stack,
   TextField
@@ -72,6 +73,7 @@ const Statistics = ({
     value: "Current"
   });
   const [loading, setLoading] = useState(true);
+  const [refreshBusy, setRefreshBusy] = useState(false);
 
   useEffect(() => {
     fetchMetricsStatsDetails();
@@ -117,12 +119,20 @@ const Statistics = ({
   };
 
   const handleRefresh = async () => {
-    await fetchMetricsStatsDetails();
-    await dispatch(fetchMetricEntity());
-    if (toastId.current) {
-      toast.dismiss(toastId.current);
+    if (refreshBusy) {
+      return;
+    }
+    setRefreshBusy(true);
+    try {
+      await fetchMetricsStatsDetails();
+      await dispatch(fetchMetricEntity());
+      if (toastId.current) {
+        toast.dismiss(toastId.current);
+      }
+      toastId.current = toast.success("Metric data is refreshed");
+    } finally {
+      setRefreshBusy(false);
     }
-    toastId.current = toast.success("Metric data is refreshed");
   };
 
   return (
@@ -137,14 +147,23 @@ const Statistics = ({
         postTitleIcon={
           <Stack justifyContent="center" alignItems="center">
             <LightTooltip title="Refresh Data">
-              <IconButton
-                size="small"
-                onClick={() => {
-                  handleRefresh();
-                }}
-              >
-                <Refresh />
-              </IconButton>
+              <span>
+                <IconButton
+                  size="small"
+                  onClick={() => {
+                    void handleRefresh();
+                  }}
+                  disabled={refreshBusy || loading}
+                  aria-busy={refreshBusy}
+                  aria-label="Refresh metrics data"
+                >
+                  {refreshBusy ? (
+                    <CircularProgress size={20} thickness={4} color="inherit" />
+                  ) : (
+                    <Refresh />
+                  )}
+                </IconButton>
+              </span>
             </LightTooltip>
           </Stack>
         }