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/08/24 12:51:13 UTC

(atlas) branch master updated: ATLAS-5342: Atlas React UI: Entity modification functionalities (Add Classifications, Terms, Labels, Business Metadata) remain active for DELETED entities (#697)

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 7c6d24ec03 ATLAS-5342: Atlas React UI: Entity modification functionalities (Add Classifications, Terms, Labels, Business Metadata) remain active for DELETED entities (#697)
7c6d24ec03 is described below

commit 7c6d24ec035da5775acd63140d3b81c54736a764
Author: Brijesh Bhalala <32...@users.noreply.github.com>
AuthorDate: Mon Aug 24 18:21:07 2026 +0530

    ATLAS-5342: Atlas React UI: Entity modification functionalities (Add Classifications, Terms, Labels, Business Metadata) remain active for DELETED entities (#697)
    
    * ATLAS-5342: Atlas React UI: Entity modification functionalities (Add Classifications, Terms, Labels, Business Metadata) remain active for DELETED entities
    
    * ATLAS-5342: Atlas React UI: Entity modification functionalities (Add Classifications, Terms, Labels, Business Metadata) remain active for DELETED entities
    
    * ATLAS-5342: Atlas React UI: Entity modification functionalities (Add Classifications, Terms, Labels, Business Metadata) remain active for DELETED entities
    
    * ATLAS-5342: Atlas React UI: Entity modification functionalities (Add Classifications, Terms, Labels, Business Metadata) remain active for DELETED entities
    
    * ATLAS-5342: Atlas React UI: Entity modification functionalities (Add Classifications, Terms, Labels, Business Metadata) remain active for DELETED entities
    
    * ATLAS-5342: Atlas React UI: Entity modification functionalities (Add Classifications, Terms, Labels, Business Metadata) remain active for DELETED entities
---
 dashboard/src/components/EntityDisplayImage.tsx    |  11 +-
 .../src/components/ShowMore/DrawerBodyChipView.tsx |   5 +-
 dashboard/src/components/ShowMore/ShowMoreView.tsx |  15 +-
 .../ShowMore/__tests__/DrawerBodyChipView.test.tsx |  38 ++++
 .../ShowMore/__tests__/ShowMoreView.test.tsx       |  51 ++++-
 .../__tests__/EntityDisplayImage.test.tsx          |  22 +-
 dashboard/src/styles/propertiesTab.scss            |   4 +
 dashboard/src/utils/EntityStatus.ts                |  27 +++
 dashboard/src/utils/__tests__/EntityStatus.test.ts |  43 ++++
 .../DashboardOverview/ClassificationCoverage.tsx   |   2 +-
 .../src/views/DetailPage/DetailPageAttributes.tsx  | 158 +++++++-------
 .../src/views/DetailPage/EntityDetailPage.tsx      |  96 +++++----
 .../EntityDetailTabs/AttributeProperties.tsx       |   4 +-
 .../EntityDetailTabs/ClassificationsTab.tsx        |   8 +-
 .../PropertiesTab/BMAttributes.tsx                 | 125 ++++++-----
 .../EntityDetailTabs/PropertiesTab/Labels.tsx      |  84 +++++---
 .../PropertiesTab/PropertiesTab.tsx                |   2 +-
 .../PropertiesTab/UserDefinedProperties.tsx        |  93 ++++----
 .../PropertiesTab/__tests__/BMAttributes.test.tsx  | 235 +++++++++++++++++++++
 .../PropertiesTab/__tests__/Labels.test.tsx        | 206 ++++++++++++++++++
 .../__tests__/UserDefinedProperties.test.tsx       | 226 ++++++++++++++++++++
 .../__tests__/AttributeProperties.test.tsx         |  58 +++++
 .../__tests__/ClassificationsTab.test.tsx          |  34 +++
 .../__tests__/DetailPageAttributes.test.tsx        |  65 ++++++
 .../src/views/__tests__/EntityDetailPage.test.tsx  |  65 +++++-
 25 files changed, 1394 insertions(+), 283 deletions(-)

diff --git a/dashboard/src/components/EntityDisplayImage.tsx b/dashboard/src/components/EntityDisplayImage.tsx
index d9223d1d25..a4d67c7e52 100644
--- a/dashboard/src/components/EntityDisplayImage.tsx
+++ b/dashboard/src/components/EntityDisplayImage.tsx
@@ -18,6 +18,7 @@
 import { useEffect, useState } from "react";
 import { Avatar, Skeleton } from "@mui/material";
 import { getEntityIconPath } from "../utils/Utils";
+import axios from "axios";
 
 const DisplayImage = ({
   entity,
@@ -36,10 +37,12 @@ const DisplayImage = ({
       let entityData = { ...entity, ...{ isProcess: isProcess } };
       let imagePath: any = getEntityIconPath({ entityData: entityData });
       try {
-        const response = await fetch(imagePath);
-        const contentType: any = response.headers.get("Content-Type");
+        const response = await axios.get(imagePath, {
+                    responseType: "blob"
+        });
+        const contentType: any = response.headers["content-type"];
 
-        if (contentType.startsWith("image/")) {
+        if (contentType && contentType.startsWith("image/")) {
           let cache = { [entityData.guid]: imagePath };
           setCheckEntityImage(cache);
           setImageUrl(getEntityIconPath({ entityData: entityData }));
@@ -48,7 +51,7 @@ const DisplayImage = ({
             getEntityIconPath({ entityData: entityData, errorUrl: imagePath })
           );
         }
-      } catch (error) {
+      } catch (_error) {
         setImageUrl(
           getEntityIconPath({ entityData: entityData, errorUrl: imagePath })
         );
diff --git a/dashboard/src/components/ShowMore/DrawerBodyChipView.tsx b/dashboard/src/components/ShowMore/DrawerBodyChipView.tsx
index 8d6c06c6f1..01dd38a220 100644
--- a/dashboard/src/components/ShowMore/DrawerBodyChipView.tsx
+++ b/dashboard/src/components/ShowMore/DrawerBodyChipView.tsx
@@ -37,6 +37,7 @@ import SearchIcon from "@mui/icons-material/Search";
 import ErrorRoundedIcon from "@mui/icons-material/ErrorRounded";
 import { Link as MuiLink } from "@mui/material";
 import { cloneDeep } from "@utils/Helper";
+import { isEntityModificationAllowed } from "@utils/EntityStatus";
 
 const CHIP_MAX_WIDTH = "200px";
 
@@ -328,11 +329,11 @@ const DrawerBodyChipView = ({
                         </EllipsisText>
                       }
                       onDelete={
-                        !isEmpty(removeApiMethod) && !isDeleteIcon
+                        isEntityModificationAllowed(currentEntity?.status) && !isEmpty(removeApiMethod) && !isDeleteIcon
                           ? () => {
                             handleDelete(obj[displayKey] || obj);
                           }
-                          : isDeleteIcon && obj.count > 1
+                          : isEntityModificationAllowed(currentEntity?.status) && isDeleteIcon && obj.count > 1
                             ? () => {
                               const searchParams = new URLSearchParams();
                               searchParams.set("tabActive", "classification");
diff --git a/dashboard/src/components/ShowMore/ShowMoreView.tsx b/dashboard/src/components/ShowMore/ShowMoreView.tsx
index d6543410ea..a21c0980d4 100644
--- a/dashboard/src/components/ShowMore/ShowMoreView.tsx
+++ b/dashboard/src/components/ShowMore/ShowMoreView.tsx
@@ -19,7 +19,7 @@ import Typography from "@mui/material/Typography";
 import Chip from "@mui/material/Chip";
 import MuiLink from "@mui/material/Link";
 import { LightTooltip } from "../muiComponents";
-import { useRef, useState } from "react";
+import { useEffect, useRef, useState } from "react";
 import { EllipsisText } from "../commonComponents";
 import { extractKeyValueFromEntity, isEmpty, serverError } from "@utils/Utils";
 import { useAppDispatch, useAppSelector } from "@hooks/reducerHook";
@@ -31,8 +31,9 @@ import ErrorRoundedIcon from "@mui/icons-material/ErrorRounded";
 import { fetchGlossaryData } from "@redux/slice/glossarySlice";
 import { fetchGlossaryDetails } from "@redux/slice/glossaryDetailsSlice";
 import ShowMoreDrawer from "./ShowMoreDrawer";
-import { openDrawer } from "@redux/slice/drawerSlice";
+import { openDrawer, closeDrawer } from "@redux/slice/drawerSlice";
 import { cloneDeep } from "@utils/Helper";
+import { isEntityModificationAllowed } from "@utils/EntityStatus";
 
 const CHIP_MAX_WIDTH = "200px";
 
@@ -73,6 +74,12 @@ const ShowMoreView = ({
   const gType = searchParams.get("gtype");
   const dispatchApi = useAppDispatch();
 
+  useEffect(() => {
+    return () => {
+      dispatchApi(closeDrawer());
+    };
+  }, [dispatchApi]);
+
   const { classificationData = {} }: any = useAppSelector(
     (state: any) => state.classification
   );
@@ -310,13 +317,13 @@ const ShowMoreView = ({
                   }
                   component="a"
                   onDelete={
-                    !isEmpty(removeApiMethod) && !isDeleteIcon
+                    !isEmpty(removeApiMethod) && !isDeleteIcon && isEntityModificationAllowed(currentEntity?.status)
                       ? () => {
                           // Handle undefined displayKey by extracting a string value
                           const deleteValue = obj[displayKey] || obj.displayText || obj.text || obj.name || '';
                           handleDelete(deleteValue);
                         }
-                      : isDeleteIcon && obj.count > 1
+                      : isDeleteIcon && obj.count > 1 && isEntityModificationAllowed(currentEntity?.status)
                       ? () => {
                           const searchParams = new URLSearchParams();
                           searchParams.set("tabActive", "classification");
diff --git a/dashboard/src/components/ShowMore/__tests__/DrawerBodyChipView.test.tsx b/dashboard/src/components/ShowMore/__tests__/DrawerBodyChipView.test.tsx
index b5a3775114..a1f9bbbf8e 100644
--- a/dashboard/src/components/ShowMore/__tests__/DrawerBodyChipView.test.tsx
+++ b/dashboard/src/components/ShowMore/__tests__/DrawerBodyChipView.test.tsx
@@ -980,6 +980,44 @@ describe('DrawerBodyChipView', () => {
 				expect(mockNavigate).toHaveBeenCalled();
 			}
 		});
+
+		it('should not show delete icon for DELETED entities', () => {
+			render(
+				<TestWrapper>
+					<DrawerBodyChipView
+						{...defaultProps}
+						currentEntity={{ ...mockCurrentEntity, status: 'DELETED' }}
+					/>
+				</TestWrapper>
+			);
+
+			const chips = screen.getAllByTestId('chip');
+			chips.forEach(chip => {
+				const deleteIcon = chip.querySelector('[data-testid="chip-delete-icon"]');
+				expect(deleteIcon).toBeNull();
+				const deleteButton = chip.querySelector('[data-testid="chip-delete-button"]');
+				expect(deleteButton).toBeNull();
+			});
+		});
+
+		it('should not show delete icon for PURGED entities', () => {
+			render(
+				<TestWrapper>
+					<DrawerBodyChipView
+						{...defaultProps}
+						currentEntity={{ ...mockCurrentEntity, status: 'PURGED' }}
+					/>
+				</TestWrapper>
+			);
+
+			const chips = screen.getAllByTestId('chip');
+			chips.forEach(chip => {
+				const deleteIcon = chip.querySelector('[data-testid="chip-delete-icon"]');
+				expect(deleteIcon).toBeNull();
+				const deleteButton = chip.querySelector('[data-testid="chip-delete-button"]');
+				expect(deleteButton).toBeNull();
+			});
+		});
 	});
 
 	describe('Modal Functionality', () => {
diff --git a/dashboard/src/components/ShowMore/__tests__/ShowMoreView.test.tsx b/dashboard/src/components/ShowMore/__tests__/ShowMoreView.test.tsx
index 5e61825804..d70bef79e5 100644
--- a/dashboard/src/components/ShowMore/__tests__/ShowMoreView.test.tsx
+++ b/dashboard/src/components/ShowMore/__tests__/ShowMoreView.test.tsx
@@ -151,6 +151,9 @@ jest.mock('@redux/slice/drawerSlice', () => ({
 	openDrawer: jest.fn((id: string) => ({
 		type: 'drawer/openDrawer',
 		payload: id
+	})),
+	closeDrawer: jest.fn(() => ({
+		type: 'drawer/closeDrawer'
 	}))
 }));
 
@@ -270,7 +273,7 @@ const { cloneDeep } = require('@utils/Helper');
 const { fetchDetailPageData } = require('@redux/slice/detailPageSlice');
 const { fetchGlossaryData } = require('@redux/slice/glossarySlice');
 const { fetchGlossaryDetails } = require('@redux/slice/glossaryDetailsSlice');
-const { openDrawer } = require('@redux/slice/drawerSlice');
+const { openDrawer, closeDrawer } = require('@redux/slice/drawerSlice');
 const { toast } = require('react-toastify');
 
 const TestWrapper: React.FC<React.PropsWithChildren<{}>> = ({ children }) => (
@@ -739,6 +742,45 @@ describe('ShowMoreView', () => {
 	});
 
 	describe('Delete Icon Functionality', () => {
+		it('should not show delete button when currentEntity status is DELETED', () => {
+			const dataWithCount = [
+				{ typeName: 'Tag1' }
+			];
+
+			render(
+				<TestWrapper>
+					<ShowMoreView
+						{...defaultProps}
+						data={dataWithCount}
+						removeApiMethod={jest.fn()}
+						currentEntity={{ guid: 'entity-guid-123', status: 'DELETED' }}
+					/>
+				</TestWrapper>
+			);
+
+			expect(screen.queryByTestId('chip-ondelete-button')).not.toBeInTheDocument();
+		});
+
+		it('should not show delete button when currentEntity status is PURGED', () => {
+			const dataWithCount = [
+				{ typeName: 'Tag1' }
+			];
+
+			render(
+				<TestWrapper>
+					<ShowMoreView
+						{...defaultProps}
+						data={dataWithCount}
+						removeApiMethod={jest.fn()}
+						currentEntity={{ guid: 'entity-guid-123', status: 'PURGED' }}
+					/>
+				</TestWrapper>
+			);
+
+			expect(screen.queryByTestId('chip-ondelete-button')).not.toBeInTheDocument();
+		});
+
+
 		it('should show count when isDeleteIcon is true and count > 1', () => {
 			const dataWithCount = [
 				{ typeName: 'Tag1', count: 2 },
@@ -1726,6 +1768,7 @@ describe('ShowMoreView', () => {
 				expect(removeApiMethod).toHaveBeenCalled();
 			}, { timeout: 3000 });
 		});
+	});
 
 	describe('Display Key Variations', () => {
 		it('should handle different displayKey values', () => {
@@ -1797,6 +1840,10 @@ describe('ShowMoreView', () => {
 			expect(screen.queryByTestId('custom-modal')).not.toBeInTheDocument();
 		});
 	});
-});
 
+	it('should dispatch closeDrawer on unmount', () => {
+		const { unmount } = render(<TestWrapper><ShowMoreView {...defaultProps} /></TestWrapper>);
+		unmount();
+		expect(closeDrawer).toHaveBeenCalled();
+	});
 });
diff --git a/dashboard/src/components/__tests__/EntityDisplayImage.test.tsx b/dashboard/src/components/__tests__/EntityDisplayImage.test.tsx
index 41f759ec1d..04dc1c5c6d 100644
--- a/dashboard/src/components/__tests__/EntityDisplayImage.test.tsx
+++ b/dashboard/src/components/__tests__/EntityDisplayImage.test.tsx
@@ -29,6 +29,7 @@
 import React from 'react'
 import { render, waitFor, act } from '@testing-library/react'
 import DisplayImage from '../EntityDisplayImage'
+import axios from 'axios'
 
 // Import Utils to spy on it
 import * as Utils from '../../utils/Utils'
@@ -41,18 +42,15 @@ jest.mock('../../utils/Utils', () => ({
 }))
 
 const mockFetch = (contentType: string | null, shouldReject?: boolean) => {
-	if (shouldReject) {
-		(global as any).fetch = jest.fn().mockRejectedValue(new Error('fetch failed'))
-		return
-	}
-	(global as any).fetch = jest.fn().mockResolvedValue({
-		ok: true,
-		headers: {
-			get: jest.fn((header: string) => {
-				return header === 'Content-Type' ? (contentType || '') : null
-			})
-		}
-	})
+        if (shouldReject) {
+                jest.spyOn(axios, 'get').mockRejectedValue(new Error('fetch failed'))
+                return
+        }
+        jest.spyOn(axios, 'get').mockResolvedValue({
+                headers: {
+                        "content-type": contentType || ''
+                }
+        })
 }
 
 describe('EntityDisplayImage', () => {
diff --git a/dashboard/src/styles/propertiesTab.scss b/dashboard/src/styles/propertiesTab.scss
index 3c9076a175..748c37198f 100644
--- a/dashboard/src/styles/propertiesTab.scss
+++ b/dashboard/src/styles/propertiesTab.scss
@@ -78,3 +78,7 @@
   .audit-attributes-item:nth-child(3) {
   flex: 0 0 100%;
 }
+
+.text-underline {
+  text-decoration: underline;
+}
diff --git a/dashboard/src/utils/EntityStatus.ts b/dashboard/src/utils/EntityStatus.ts
new file mode 100644
index 0000000000..a063bdc88f
--- /dev/null
+++ b/dashboard/src/utils/EntityStatus.ts
@@ -0,0 +1,27 @@
+/*
+ * 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 enum EntityStatus {
+  ACTIVE = "ACTIVE",
+  DELETED = "DELETED",
+  PURGED = "PURGED"
+}
+
+export const isEntityModificationAllowed = (status: EntityStatus | string | undefined): boolean => {
+  if (!status) return true;
+  return status !== EntityStatus.DELETED && status !== EntityStatus.PURGED;
+};
diff --git a/dashboard/src/utils/__tests__/EntityStatus.test.ts b/dashboard/src/utils/__tests__/EntityStatus.test.ts
new file mode 100644
index 0000000000..59ce1c0397
--- /dev/null
+++ b/dashboard/src/utils/__tests__/EntityStatus.test.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.
+ */
+
+import { EntityStatus, isEntityModificationAllowed } from '../EntityStatus';
+
+describe('isEntityModificationAllowed', () => {
+    it('should return true for ACTIVE status', () => {
+        expect(isEntityModificationAllowed(EntityStatus.ACTIVE)).toBe(true);
+        expect(isEntityModificationAllowed('ACTIVE')).toBe(true);
+    });
+
+    it('should return false for DELETED status', () => {
+        expect(isEntityModificationAllowed(EntityStatus.DELETED)).toBe(false);
+        expect(isEntityModificationAllowed('DELETED')).toBe(false);
+    });
+
+    it('should return false for PURGED status', () => {
+        expect(isEntityModificationAllowed(EntityStatus.PURGED)).toBe(false);
+        expect(isEntityModificationAllowed('PURGED')).toBe(false);
+    });
+
+    it('should return true for undefined status', () => {
+        expect(isEntityModificationAllowed(undefined)).toBe(true);
+    });
+
+    it('should return true for unknown status', () => {
+        expect(isEntityModificationAllowed('UNKNOWN_STATUS')).toBe(true);
+    });
+});
diff --git a/dashboard/src/views/DashboardOverview/ClassificationCoverage.tsx b/dashboard/src/views/DashboardOverview/ClassificationCoverage.tsx
index 03c27b94dc..faa54da6ae 100644
--- a/dashboard/src/views/DashboardOverview/ClassificationCoverage.tsx
+++ b/dashboard/src/views/DashboardOverview/ClassificationCoverage.tsx
@@ -289,7 +289,7 @@ const ClassificationCoverage = memo(
 						aria-label="Open classification search"
 					>
 						{numberFormatWithComma(typesInUse)} of{" "}
-						{numberFormatWithComma(classificationTypeDefinitions)}
+						{numberFormatWithComma(classificationTypeDefinitions)}{" "}
 						classification types are in use (have at least one entity).
 					</Typography>
 				</Stack>
diff --git a/dashboard/src/views/DetailPage/DetailPageAttributes.tsx b/dashboard/src/views/DetailPage/DetailPageAttributes.tsx
index 3bbe6fe402..c7e160b499 100644
--- a/dashboard/src/views/DetailPage/DetailPageAttributes.tsx
+++ b/dashboard/src/views/DetailPage/DetailPageAttributes.tsx
@@ -41,6 +41,7 @@ const getDescriptionForDisplay = (desc: unknown): string => {
 };
 import { useState } from "react";
 import { useAppSelector } from "@hooks/reducerHook";
+
 import { toast } from "react-toastify";
 import EditOutlinedIcon from "@mui/icons-material/EditOutlined";
 import { removeClassification } from "@api/apiMethods/classificationApiMethod";
@@ -57,6 +58,7 @@ import AddTagAttributes from "@views/Classification/AddTagAttributes";
 import AssignCategory from "@views/Glossary/AssignCategory";
 import AssignTerm from "@views/Glossary/AssignTerm";
 import ShowMoreText from "@components/ShowMore/ShowMoreText";
+import { isEntityModificationAllowed } from "@utils/EntityStatus";
 
 const DetailPageAttribute = ({
   data,
@@ -147,7 +149,7 @@ const DetailPageAttribute = ({
                 {name}{" "}
               </Typography>
             </LightTooltip>
-            {isEmpty(bmguid) && (
+            {isEmpty(bmguid) && !loading && isEntityModificationAllowed(data?.status) && (
               <LightTooltip title={"Edit Classification"}>
                 <CustomButton
                   variant="outlined"
@@ -315,23 +317,25 @@ const DetailPageAttribute = ({
                       >
                         Classifications
                       </Typography>
-                      <LightTooltip title={"Add Classifications"}>
-                        <IconButton
-                          component="label"
-                          role={undefined}
-                          tabIndex={-1}
-                          size="small"
-                          color="primary"
-                          onClick={() => {
-                            setOpenAddTagModal(true);
-                          }}
-                        >
-                          <AddCircleOutlineIcon
-                            className="mr-0"
-                            fontSize="small"
-                          />{" "}
-                        </IconButton>
-                      </LightTooltip>
+                      {!loading && isEntityModificationAllowed(data?.status) && (
+                        <LightTooltip title={"Add Classifications"}>
+                          <IconButton
+                            component="label"
+                            role={undefined}
+                            tabIndex={-1}
+                            size="small"
+                            color="primary"
+                            onClick={() => {
+                              setOpenAddTagModal(true);
+                            }}
+                          >
+                            <AddCircleOutlineIcon
+                              className="mr-0"
+                              fontSize="small"
+                            />{" "}
+                          </IconButton>
+                        </LightTooltip>
+                      )}
                     </Stack>
                     <Stack
                       data-cy="tagListTerm"
@@ -383,28 +387,30 @@ const DetailPageAttribute = ({
                       >
                         Terms
                       </Typography>
-                      <LightTooltip title={"Add Term"}>
-                        <IconButton
-                          component="label"
-                          role={undefined}
-                          tabIndex={-1}
-                          size="small"
-                          color="primary"
-                          onClick={() => {
-                            if (!hasAnyGlossaryTerms) {
-                              toast.dismiss();
-                              toast.info("There are no available terms");
-                              return;
-                            }
-                            setOpenAddTermModal(true);
-                          }}
-                        >
-                          <AddCircleOutlineIcon
-                            className="mr-0"
-                            fontSize="small"
-                          />{" "}
-                        </IconButton>
-                      </LightTooltip>
+                      {!loading && isEntityModificationAllowed(data?.status) && (
+                        <LightTooltip title={"Add Term"}>
+                          <IconButton
+                            component="label"
+                            role={undefined}
+                            tabIndex={-1}
+                            size="small"
+                            color="primary"
+                            onClick={() => {
+                              if (!hasAnyGlossaryTerms) {
+                                toast.dismiss();
+                                toast.info("There are no available terms");
+                                return;
+                              }
+                              setOpenAddTermModal(true);
+                            }}
+                          >
+                            <AddCircleOutlineIcon
+                              className="mr-0"
+                              fontSize="small"
+                            />{" "}
+                          </IconButton>
+                        </LightTooltip>
+                      )}
                     </Stack>
                     <Stack
                       data-cy="termList"
@@ -455,23 +461,25 @@ const DetailPageAttribute = ({
                       >
                         Categories
                       </Typography>
-                      <LightTooltip title={"Add Categories"}>
-                        <IconButton
-                          component="label"
-                          role={undefined}
-                          tabIndex={-1}
-                          size="small"
-                          color="primary"
-                          onClick={() => {
-                            setCategoryModal(true);
-                          }}
-                        >
-                          <AddCircleOutlineIcon
-                            className="mr-0"
-                            fontSize="small"
-                          />{" "}
-                        </IconButton>
-                      </LightTooltip>
+                      {!loading && isEntityModificationAllowed(data?.status) && (
+                        <LightTooltip title={"Add Categories"}>
+                          <IconButton
+                            component="label"
+                            role={undefined}
+                            tabIndex={-1}
+                            size="small"
+                            color="primary"
+                            onClick={() => {
+                              setCategoryModal(true);
+                            }}
+                          >
+                            <AddCircleOutlineIcon
+                              className="mr-0"
+                              fontSize="small"
+                            />{" "}
+                          </IconButton>
+                        </LightTooltip>
+                      )}
                     </Stack>
                     <Stack
                       data-cy="categoryList"
@@ -614,23 +622,25 @@ const DetailPageAttribute = ({
                         >
                           Attributes:
                         </Typography>
-                        <LightTooltip title={"Add Attributes"}>
-                          <IconButton
-                            component="label"
-                            role={undefined}
-                            tabIndex={-1}
-                            size="small"
-                            color="primary"
-                            onClick={() => {
-                              setAttributeModal(true);
-                            }}
-                          >
-                            <AddCircleOutlineIcon
-                              className="mr-0"
-                              fontSize="small"
-                            />{" "}
-                          </IconButton>
-                        </LightTooltip>
+                        {!loading && isEntityModificationAllowed(data?.status) && (
+                          <LightTooltip title={"Add Attributes"}>
+                            <IconButton
+                              component="label"
+                              role={undefined}
+                              tabIndex={-1}
+                              size="small"
+                              color="primary"
+                              onClick={() => {
+                                setAttributeModal(true);
+                              }}
+                            >
+                              <AddCircleOutlineIcon
+                                className="mr-0"
+                                fontSize="small"
+                              />{" "}
+                            </IconButton>
+                          </LightTooltip>
+                        )}
                       </Stack>
 
                       <Stack
diff --git a/dashboard/src/views/DetailPage/EntityDetailPage.tsx b/dashboard/src/views/DetailPage/EntityDetailPage.tsx
index 2b20e15a72..27c9b84c27 100644
--- a/dashboard/src/views/DetailPage/EntityDetailPage.tsx
+++ b/dashboard/src/views/DetailPage/EntityDetailPage.tsx
@@ -39,11 +39,13 @@ import { fetchDetailPageData } from "@redux/slice/detailPageSlice";
 import { normalizeSchemaElementsAttribute } from "@utils/schemaElementsAttributeUtils";
 import { SchemaTabCacheState } from "@models/schemaTabTypes";
 import React from "react";
+
 import AddTag from "@views/Classification/AddTag";
 import AssignTerm from "@views/Glossary/AssignTerm";
 import { removeTerm } from "@api/apiMethods/glossaryApiMethod";
 import AddCircleOutlineIcon from "@mui/icons-material/AddCircleOutline";
 import ShowMoreView from "@components/ShowMore/ShowMoreView";
+import { isEntityModificationAllowed } from "@utils/EntityStatus";
 
 const PropertiesTab = lazy(
   () => import("./EntityDetailTabs/PropertiesTab/PropertiesTab")
@@ -115,14 +117,14 @@ const EntityDetailPage: React.FC = () => {
   let entityObj =
     !isEmpty(entityDefObj) && !isEmpty(entity)
       ? entityDefObj.find((obj: { name: string }) => {
-          return obj.name == entity.typeName;
-        })
+        return obj.name == entity.typeName;
+      })
       : {};
   let superTypes = !isEmpty(entityDefObj)
     ? getNestedSuperTypes({
-        data: entityObj,
-        collection: entityDefObj
-      })
+      data: entityObj,
+      collection: entityDefObj
+    })
     : [];
   let isLineageRender: boolean | null = superTypes.find((type) => {
     if (type === "DataSet" || type === "Process") {
@@ -327,7 +329,7 @@ const EntityDetailPage: React.FC = () => {
         className="detail-page-paper"
         variant="outlined"
       >
-        {loading ? (
+        {loading || detailPageData === null ? (
           <Stack direction="row" spacing={2} alignItems="center">
             <SkeletonLoader
               count={1}
@@ -387,7 +389,7 @@ const EntityDetailPage: React.FC = () => {
           }}
         >
           <Stack>
-            {loading ? (
+            {loading || detailPageData === null ? (
               <Stack direction="column" spacing={2} alignItems="left">
                 <SkeletonLoader
                   count={1}
@@ -408,20 +410,22 @@ const EntityDetailPage: React.FC = () => {
                   >
                     Classifications
                   </Typography>
-                  <LightTooltip title={"Add Classifications"}>
-                    <IconButton
-                      component="label"
-                      role={undefined}
-                      tabIndex={-1}
-                      size="small"
-                      color="primary"
-                      onClick={() => {
-                        setOpenAddTagModal(true);
-                      }}
-                    >
-                      <AddCircleOutlineIcon className="mr-0" fontSize="small" />{" "}
-                    </IconButton>
-                  </LightTooltip>
+                  {!loading && isEntityModificationAllowed(entity?.status) && (
+                    <LightTooltip title={"Add Classifications"}>
+                      <IconButton
+                        component="label"
+                        role={undefined}
+                        tabIndex={-1}
+                        size="small"
+                        color="primary"
+                        onClick={() => {
+                          setOpenAddTagModal(true);
+                        }}
+                      >
+                        <AddCircleOutlineIcon className="mr-0" fontSize="small" />{" "}
+                      </IconButton>
+                    </LightTooltip>
+                  )}
                 </Stack>
 
                 <Stack
@@ -448,7 +452,7 @@ const EntityDetailPage: React.FC = () => {
 
           {!entity?.typeName?.includes("AtlasGlossary") && (
             <Stack>
-              {loading ? (
+              {loading || detailPageData === null ? (
                 <Stack direction="column" spacing={2} alignItems="flex-start">
                   <SkeletonLoader
                     count={1}
@@ -469,28 +473,30 @@ const EntityDetailPage: React.FC = () => {
                     >
                       Terms
                     </Typography>
-                    <LightTooltip title="Add Term">
-                      <IconButton
-                        component="label"
-                        role={undefined}
-                        tabIndex={-1}
-                        size="small"
-                        color="primary"
-                        onClick={() => {
-                          if (!hasAnyGlossaryTerms) {
-                            toast.dismiss();
-                            toast.info("There are no available terms");
-                            return;
-                          }
-                          setOpenAddTermModal(true);
-                        }}
-                      >
-                        <AddCircleOutlineIcon
-                          className="mr-0"
-                          fontSize="small"
-                        />
-                      </IconButton>
-                    </LightTooltip>
+                    {!loading && isEntityModificationAllowed(entity?.status) && (
+                      <LightTooltip title="Add Term">
+                        <IconButton
+                          component="label"
+                          role={undefined}
+                          tabIndex={-1}
+                          size="small"
+                          color="primary"
+                          onClick={() => {
+                            if (!hasAnyGlossaryTerms) {
+                              toast.dismiss();
+                              toast.info("There are no available terms");
+                              return;
+                            }
+                            setOpenAddTermModal(true);
+                          }}
+                        >
+                          <AddCircleOutlineIcon
+                            className="mr-0"
+                            fontSize="small"
+                          />
+                        </IconButton>
+                      </LightTooltip>
+                    )}
                   </Stack>
 
                   <Stack
@@ -589,7 +595,7 @@ const EntityDetailPage: React.FC = () => {
                 <LinkTab
                   label={
                     entity.typeName == "hive_db" ||
-                    entity.typeName == "hbase_namespace"
+                      entity.typeName == "hbase_namespace"
                       ? "Tables"
                       : "Table"
                   }
diff --git a/dashboard/src/views/DetailPage/EntityDetailTabs/AttributeProperties.tsx b/dashboard/src/views/DetailPage/EntityDetailTabs/AttributeProperties.tsx
index 8efb029e7b..de70ac7b2c 100644
--- a/dashboard/src/views/DetailPage/EntityDetailTabs/AttributeProperties.tsx
+++ b/dashboard/src/views/DetailPage/EntityDetailTabs/AttributeProperties.tsx
@@ -35,6 +35,8 @@ import { useAppSelector } from "@hooks/reducerHook";
 import { AntSwitch } from "@utils/Muiutils";
 import { cloneDeep } from "@utils/Helper";
 
+import { isEntityModificationAllowed } from "@utils/EntityStatus";
+
 const AttributeProperties = ({
   entity,
   referredEntities,
@@ -188,7 +190,7 @@ const AttributeProperties = ({
                     inputProps={{ "aria-label": "controlled" }}
                   />
                 </LightTooltip>
-                {entityUpdate && (
+                {entityUpdate && !loading && isEntityModificationAllowed(entity?.status) && (
                   <LightTooltip title={"Edit Entity"}>
                     <CustomButton
                       variant="outlined"
diff --git a/dashboard/src/views/DetailPage/EntityDetailTabs/ClassificationsTab.tsx b/dashboard/src/views/DetailPage/EntityDetailTabs/ClassificationsTab.tsx
index 6b215d9ed7..8c3954c039 100644
--- a/dashboard/src/views/DetailPage/EntityDetailTabs/ClassificationsTab.tsx
+++ b/dashboard/src/views/DetailPage/EntityDetailTabs/ClassificationsTab.tsx
@@ -42,6 +42,7 @@ import DeleteOutlinedIcon from "@mui/icons-material/DeleteOutlined";
 import { isEntityPurged } from "@utils/Enum";
 import CustomModal from "@components/Modal";
 import ErrorRoundedIcon from "@mui/icons-material/ErrorRounded";
+
 import { removeClassification } from "@api/apiMethods/classificationApiMethod";
 import { toast } from "react-toastify";
 import AttributeTable from "../AttributeTable";
@@ -50,6 +51,7 @@ import moment from "moment";
 import { useAppDispatch } from "@hooks/reducerHook";
 import { AntSwitch } from "@utils/Muiutils";
 import { fetchDetailPageData } from "@redux/slice/detailPageSlice";
+import { isEntityModificationAllowed } from "@utils/EntityStatus";
 
 const ClassificationsTab: React.FC<EntityDetailTabProps> = ({
   entity,
@@ -255,7 +257,7 @@ const ClassificationsTab: React.FC<EntityDetailTabProps> = ({
           let values = info.row.original;
           return (
             <Stack direction="row" gap={1}>
-              {(guid == values?.entityGuid ||
+              {!loading && isEntityModificationAllowed(entity?.status) && (guid == values?.entityGuid ||
                 (guid != values?.entityGuid &&
                   values.entityStatus == "DELETED")) && (
                   <LightTooltip title={"Delete Classification"}>
@@ -279,7 +281,7 @@ const ClassificationsTab: React.FC<EntityDetailTabProps> = ({
                     </CustomButton>
                   </LightTooltip>
                 )}
-              {guid == values?.entityGuid && (
+              {!loading && isEntityModificationAllowed(entity?.status) && guid == values?.entityGuid && (
                 <LightTooltip title={"Edit Classification"}>
                   <CustomButton
                     variant="outlined"
@@ -305,7 +307,7 @@ const ClassificationsTab: React.FC<EntityDetailTabProps> = ({
         enableSorting: false
       }
     ],
-    [updateTable]
+    [updateTable, entity]
   );
 
   return (
diff --git a/dashboard/src/views/DetailPage/EntityDetailTabs/PropertiesTab/BMAttributes.tsx b/dashboard/src/views/DetailPage/EntityDetailTabs/PropertiesTab/BMAttributes.tsx
index 2fb291ebdd..b9c20418a1 100644
--- a/dashboard/src/views/DetailPage/EntityDetailTabs/PropertiesTab/BMAttributes.tsx
+++ b/dashboard/src/views/DetailPage/EntityDetailTabs/PropertiesTab/BMAttributes.tsx
@@ -58,26 +58,34 @@ import { cloneDeep } from "@utils/Helper";
 import moment from "moment-timezone";
 import { fetchDetailPageData } from "@redux/slice/detailPageSlice";
 
+import { isEntityModificationAllowed } from "@utils/EntityStatus";
+
 const defaultField = {
   key: null,
   value: ""
 };
 
-const BMAttributes = ({ loading, bmAttributes, entity }: any) => {
+type BMAttributesProps = {
+  loading: boolean | undefined;
+  bmAttributes: Record<string, any>;
+  entity: any;
+};
+
+const BMAttributes = ({ loading, bmAttributes, entity }: BMAttributesProps) => {
   const dispatchApi = useAppDispatch();
-  const { guid }: any = useParams();
-  const toastId: any = useRef(null);
-  const { entityData }: any = useAppSelector((state: any) => state.entity);
+  const { guid } = useParams();
+  const toastId = useRef<number | string | null>(null);
+  const { entityData } = useAppSelector((state: any) => state.entity);
   const { entityDefs } = entityData || {};
   let filterEntityData = cloneDeep(entityDefs);
-  const { businessMetaData }: any = useAppSelector(
+  const { businessMetaData } = useAppSelector(
     (state: any) => state.businessMetaData
   );
   const { businessMetadataDefs } = businessMetaData || {};
 
   let businessAttributes = cloneDeep(bmAttributes);
   let bmAttributesData = Object.entries(businessAttributes).map(
-    ([key, value]: any) => {
+    ([key, value]: [string, any]) => {
       let foundBusinessMetadata = businessMetadataDefs.find(
         (obj: { name: any }) => obj.name == key
       );
@@ -211,7 +219,7 @@ const BMAttributes = ({ loading, bmAttributes, entity }: any) => {
     control
   });
 
-  const onSubmit = async (values: { businessMetadata: any }) => {
+  const onSubmit = async (values: { businessMetadata: any[] }) => {
     let formData = { ...values };
     const { businessMetadata } = formData;
     let data: Record<string, any> = {};
@@ -300,7 +308,7 @@ const BMAttributes = ({ loading, bmAttributes, entity }: any) => {
     handleSubmit(onSubmit)();
   };
 
-  const renderValues = (values: any) => {
+  const renderValues = (values: { value: any; typeName: string }) => {
     const { value, typeName } = values;
 
     if (
@@ -376,22 +384,24 @@ const BMAttributes = ({ loading, bmAttributes, entity }: any) => {
 
                       <Stack direction="row" alignItems="center" gap="0.5rem">
                         {addLabel ? (
-                          <CustomButton
-                            key="edit-Add-button"
-                            variant="outlined"
-                            color="success"
-                            size="small"
-                            onClick={(e: { stopPropagation: () => void }) => {
-                              e.stopPropagation();
-                              setExpanded("bmDataPanel");
-                              setAddLabel(false);
-                              if (!isEmpty(defaultFieldValues)) {
-                                reset({ businessMetadata: defaultFieldValues });
-                              }
-                            }}
-                          >
-                            {!isEmpty(bmAttributes) ? "Edit" : "Add"}
-                          </CustomButton>
+                          !loading && isEntityModificationAllowed(entity?.status) && (
+                            <CustomButton
+                              key="edit-Add-button"
+                              variant="outlined"
+                              color="success"
+                              size="small"
+                              onClick={(e: { stopPropagation: () => void }) => {
+                                e.stopPropagation();
+                                setExpanded("bmDataPanel");
+                                setAddLabel(false);
+                                if (!isEmpty(defaultFieldValues)) {
+                                  reset({ businessMetadata: defaultFieldValues });
+                                }
+                              }}
+                            >
+                              {!isEmpty(bmAttributes) ? "Edit" : "Add"}
+                            </CustomButton>
+                          )
                         ) : (
                           <>
                             <CustomButton
@@ -477,7 +487,7 @@ const BMAttributes = ({ loading, bmAttributes, entity }: any) => {
                                 </Stack>
                               </AccordionSummary>
 
-                              {Object.entries(obj).map(([key, value]: any) => {
+                              {Object.entries(obj).map(([key, value]: [string, any]) => {
                                 return (
                                   <>
                                     {key !=
@@ -536,41 +546,48 @@ const BMAttributes = ({ loading, bmAttributes, entity }: any) => {
                         justifyContent="center"
                       >
                         <span>
-                          No properties have been created yet. To add a
-                          property, click{" "}
-                          <Typography
-                            className="text-color-green cursor-pointer"
-                            component="span"
-                            onClick={(e: { stopPropagation: () => void }) => {
-                              e.stopPropagation();
-                              setAddLabel(false);
-                            }}
-                            style={{ textDecoration: "underline" }}
-                          >
-                            here
-                          </Typography>
+                          {!isEntityModificationAllowed(entity?.status) ? (
+                            "No properties have been created yet."
+                          ) : (
+                            <>
+                              No properties have been created yet. To add a
+                              property, click{" "}
+                              <Typography
+                                className="text-color-green cursor-pointer text-underline"
+                                component="span"
+                                onClick={(e: { stopPropagation: () => void }) => {
+                                  e.stopPropagation();
+                                  setAddLabel(false);
+                                }}
+                              >
+                                here
+                              </Typography>
+                            </>
+                          )}
                         </span>
                       </Stack>
                     )}
                   </>
                 ) : (
                   <>
-                    <LightTooltip title={"Add New Attribute"}>
-                      <CustomButton
-                        sx={{
-                          alignSelf: "flex-start"
-                        }}
-                        variant="outlined"
-                        size="small"
-                        onClick={(e: any) => {
-                          e.stopPropagation();
-                          append(defaultField);
-                        }}
-                        startIcon={<AddIcon fontSize="small" />}
-                      >
-                        Add New Attributes
-                      </CustomButton>
-                    </LightTooltip>
+                    {!loading && isEntityModificationAllowed(entity?.status) && (
+                      <LightTooltip title={"Add New Attribute"}>
+                        <CustomButton
+                          sx={{
+                            alignSelf: "flex-start"
+                          }}
+                          variant="outlined"
+                          size="small"
+                          onClick={(e: React.MouseEvent) => {
+                            e.stopPropagation();
+                            append(defaultField);
+                          }}
+                          startIcon={<AddIcon fontSize="small" />}
+                        >
+                          Add New Attributes
+                        </CustomButton>
+                      </LightTooltip>
+                    )}
                     {fields.map((field, index) => {
                       const keySelected = !isEmpty(
                         bmAttributesValues?.[index]?.key
diff --git a/dashboard/src/views/DetailPage/EntityDetailTabs/PropertiesTab/Labels.tsx b/dashboard/src/views/DetailPage/EntityDetailTabs/PropertiesTab/Labels.tsx
index 77b4f21b7c..85c5265e78 100644
--- a/dashboard/src/views/DetailPage/EntityDetailTabs/PropertiesTab/Labels.tsx
+++ b/dashboard/src/views/DetailPage/EntityDetailTabs/PropertiesTab/Labels.tsx
@@ -44,11 +44,20 @@ import { getLabels } from "@api/apiMethods/detailpageApiMethod";
 import { useAppDispatch } from "@hooks/reducerHook";
 import { fetchDetailPageData } from "@redux/slice/detailPageSlice";
 
-const filter = createFilterOptions<any>();
+import { isEntityModificationAllowed } from "@utils/EntityStatus";
 
-const Labels = ({ loading, labels }: any) => {
-  const { guid }: any = useParams();
-  const toastId: any = useRef(null);
+type LabelOption = string | { inputValue?: string; value?: string };
+const filter = createFilterOptions<LabelOption>();
+
+type LabelsProps = {
+  loading: boolean | undefined;
+  labels: string[];
+  entity: any;
+};
+
+const Labels = ({ loading, labels, entity }: LabelsProps) => {
+  const { guid } = useParams();
+  const toastId = useRef<number | string | null>(null);
   const dispatchApi = useAppDispatch();
   const [addLabel, setAddLabel] = useState<boolean>(true);
   const [expanded, setExpanded] = useState<string | false>(false);
@@ -100,7 +109,7 @@ const Labels = ({ loading, labels }: any) => {
     setLoader(false);
     setOpen(false);
   };
-  const onInputChange = (_event: any, value: string) => {
+  const onInputChange = (_event: React.SyntheticEvent, value: string) => {
     if (value) {
       setOpen(true);
       setLoader(true);
@@ -135,15 +144,15 @@ const Labels = ({ loading, labels }: any) => {
     return out;
   };
 
-  const onSubmit = async (values: any) => {
+  const onSubmit = async (values: Record<string, any>) => {
     const formData = { ...values };
     const payload = normalizeLabelsPayload(formData.labels);
     if (payload.length === 0 && (!labels || labels.length === 0)) {
       return;
     }
     try {
-      await getLabels(guid, payload);
-      toast.dismiss(toastId.current);
+      await getLabels(guid as string, payload);
+      if (toastId.current) { toast.dismiss(toastId.current); }
       toastId.current = toast.success(
         "One or more labels were updated successfully"
       );
@@ -154,7 +163,7 @@ const Labels = ({ loading, labels }: any) => {
 
       setAddLabel(true);
     } catch (error) {
-      toast.dismiss(toastId.current);
+      if (toastId.current) { toast.dismiss(toastId.current); }
       serverError(error, toastId);
     }
   };
@@ -189,19 +198,21 @@ const Labels = ({ loading, labels }: any) => {
 
                   <Stack direction="row" alignItems="center" gap="0.5rem">
                     {addLabel ? (
-                      <CustomButton
-                        key="edit-Add-button"
-                        variant="outlined"
-                        color="success"
-                        size="small"
-                        onClick={(e: { stopPropagation: () => void }) => {
-                          e.stopPropagation();
-                          setExpanded("labelsPanel");
-                          setAddLabel(false);
-                        }}
-                      >
-                        {!isEmpty(labels) ? "Edit" : "Add"}
-                      </CustomButton>
+                      !loading && isEntityModificationAllowed(entity?.status) && (
+                        <CustomButton
+                          key="edit-Add-button"
+                          variant="outlined"
+                          color="success"
+                          size="small"
+                          onClick={(e: { stopPropagation: () => void }) => {
+                            e.stopPropagation();
+                            setExpanded("labelsPanel");
+                            setAddLabel(false);
+                          }}
+                        >
+                          {!isEmpty(labels) ? "Edit" : "Add"}
+                        </CustomButton>
+                      )
                     ) : (
                       <>
                         <CustomButton
@@ -275,18 +286,23 @@ const Labels = ({ loading, labels }: any) => {
                     })
                   ) : (
                     <span>
-                      No labels have been created yet. To add a labels, click{" "}
-                      <Typography
-                        className="text-color-green cursor-pointer"
-                        component="span"
-                        onClick={(e: { stopPropagation: () => void }) => {
-                          e.stopPropagation();
-                          setAddLabel(false);
-                        }}
-                        style={{ textDecoration: "underline" }}
-                      >
-                        here
-                      </Typography>
+                      {!isEntityModificationAllowed(entity?.status) ? (
+                        "No labels have been created yet."
+                      ) : (
+                        <>
+                          No labels have been created yet. To add a labels, click{" "}
+                          <Typography
+                            component="span"
+                            onClick={(e: { stopPropagation: () => void }) => {
+                              e.stopPropagation();
+                              setAddLabel(false);
+                            }}
+                            className="text-color-green cursor-pointer text-underline"
+                          >
+                            here
+                          </Typography>
+                        </>
+                      )}
                     </span>
                   )}
                 </>
diff --git a/dashboard/src/views/DetailPage/EntityDetailTabs/PropertiesTab/PropertiesTab.tsx b/dashboard/src/views/DetailPage/EntityDetailTabs/PropertiesTab/PropertiesTab.tsx
index 0a47303208..8b8705a9ee 100644
--- a/dashboard/src/views/DetailPage/EntityDetailTabs/PropertiesTab/PropertiesTab.tsx
+++ b/dashboard/src/views/DetailPage/EntityDetailTabs/PropertiesTab/PropertiesTab.tsx
@@ -56,7 +56,7 @@ const PropertiesTab = (props: {
             customAttributes={customAttributes}
             entity={entity}
           />
-          <Labels loading={loading} labels={labels} />
+          <Labels loading={loading} labels={labels} entity={entity} />
 
           <BMAttributes
             loading={loading}
diff --git a/dashboard/src/views/DetailPage/EntityDetailTabs/PropertiesTab/UserDefinedProperties.tsx b/dashboard/src/views/DetailPage/EntityDetailTabs/PropertiesTab/UserDefinedProperties.tsx
index e198fb07e1..735dbc05ea 100644
--- a/dashboard/src/views/DetailPage/EntityDetailTabs/PropertiesTab/UserDefinedProperties.tsx
+++ b/dashboard/src/views/DetailPage/EntityDetailTabs/PropertiesTab/UserDefinedProperties.tsx
@@ -51,15 +51,23 @@ import { cloneDeep } from "@utils/Helper";
 import { fetchDetailPageData } from "@redux/slice/detailPageSlice";
 import { enrichEntityPayloadForRelationshipSave } from "@utils/entityPayloadEnrichmentUtils";
 
+import { isEntityModificationAllowed } from "@utils/EntityStatus";
+
 const defaultField = {
   key: "",
   value: ""
 };
 
-const UserDefinedProperties = ({ loading, customAttributes, entity }: any) => {
+type UserDefinedPropertiesProps = {
+  loading: boolean | undefined;
+  customAttributes: Record<string, any>;
+  entity: any;
+};
+
+const UserDefinedProperties = ({ loading, customAttributes, entity }: UserDefinedPropertiesProps) => {
   const dispatchApi = useAppDispatch();
-  const { guid }: any = useParams();
-  const toastId: any = useRef(null);
+  const { guid } = useParams();
+  const toastId = useRef<number | string | null>(null);
   const [addLabel, setAddLabel] = useState<boolean>(true);
   const [expanded, setExpanded] = useState<string | false>(false);
   let attributes = cloneDeep(customAttributes);
@@ -101,7 +109,7 @@ const UserDefinedProperties = ({ loading, customAttributes, entity }: any) => {
       }
     };
 
-  const structureAttributes = (list: any) => {
+  const structureAttributes = (list: { key: string; value: string }[]) => {
     const obj: Record<string, string> = {};
     if (!Array.isArray(list)) {
       return obj;
@@ -119,7 +127,7 @@ const UserDefinedProperties = ({ loading, customAttributes, entity }: any) => {
     return obj;
   };
 
-  const onSubmit = async (values: any) => {
+  const onSubmit = async (values: Record<string, any>) => {
     let formData = { ...values };
     let entityObj = cloneDeep(entity);
     let properties = structureAttributes(formData.customAttributes);
@@ -152,10 +160,10 @@ const UserDefinedProperties = ({ loading, customAttributes, entity }: any) => {
     handleSubmit(onSubmit)();
   };
 
-  const validateKeyUnique = (value: any, index: number): any => {
+  const validateKeyUnique = (value: string, index: number): string | boolean => {
     const items = getValues("customAttributes");
     const duplicate = items.some(
-      (item: { key: any }, i: any) => item.key === value && i !== index
+      (item: { key: string }, i: number) => item.key === value && i !== index
     );
     return duplicate ? "Key must be unique" : true;
   };
@@ -194,22 +202,24 @@ const UserDefinedProperties = ({ loading, customAttributes, entity }: any) => {
 
                     <Stack direction="row" alignItems="center" gap="0.5rem">
                       {addLabel ? (
-                        <CustomButton
-                          key="edit-Add-button"
-                          variant="outlined"
-                          color="success"
-                          size="small"
-                          onClick={(e: { stopPropagation: () => void }) => {
-                            e.stopPropagation();
-                            setExpanded("userDefinedPanel");
-                            setAddLabel(false);
-                            if (!isEmpty(defaultFieldValues)) {
-                              reset({ customAttributes: defaultFieldValues });
-                            }
-                          }}
-                        >
-                          {!isEmpty(customAttributes) ? "Edit" : "Add"}
-                        </CustomButton>
+                        !loading && isEntityModificationAllowed(entity?.status) && (
+                          <CustomButton
+                            key="edit-Add-button"
+                            variant="outlined"
+                            color="success"
+                            size="small"
+                            onClick={(e: { stopPropagation: () => void }) => {
+                              e.stopPropagation();
+                              setExpanded("userDefinedPanel");
+                              setAddLabel(false);
+                              if (!isEmpty(defaultFieldValues)) {
+                                reset({ customAttributes: defaultFieldValues });
+                              }
+                            }}
+                          >
+                            {!isEmpty(customAttributes) ? "Edit" : "Add"}
+                          </CustomButton>
+                        )
                       ) : (
                         <>
                           <CustomButton
@@ -267,7 +277,7 @@ const UserDefinedProperties = ({ loading, customAttributes, entity }: any) => {
                     {!isEmpty(customAttributes) ? (
                       Object.entries(customAttributes)
                         .sort()
-                        .map(([keys, value]: [string, any]) => {
+                        .map(([keys, value]: [string, string]) => {
                           return (
                             <>
                               <Stack
@@ -303,19 +313,24 @@ const UserDefinedProperties = ({ loading, customAttributes, entity }: any) => {
                         })
                     ) : (
                       <span>
-                        No properties have been created yet. To add a
-                        property,click{" "}
-                        <Typography
-                          className="text-color-green cursor-pointer"
-                          component="span"
-                          onClick={(e: { stopPropagation: () => void }) => {
-                            e.stopPropagation();
-                            setAddLabel(false);
-                          }}
-                          style={{ textDecoration: "underline" }}
-                        >
-                          here
-                        </Typography>
+                        {!isEntityModificationAllowed(entity?.status) ? (
+                          "No properties have been created yet."
+                        ) : (
+                          <>
+                            No properties have been created yet. To add a
+                            property,click{" "}
+                            <Typography
+                              className="text-color-green cursor-pointer text-underline"
+                              component="span"
+                              onClick={(e: { stopPropagation: () => void }) => {
+                                e.stopPropagation();
+                                setAddLabel(false);
+                              }}
+                            >
+                              here
+                            </Typography>
+                          </>
+                        )}
                       </span>
                     )}
                   </Stack>
@@ -323,7 +338,7 @@ const UserDefinedProperties = ({ loading, customAttributes, entity }: any) => {
               </>
             ) : (
               <>
-                {fields.map((item: any, index) => {
+                {fields.map((item: Record<string, any>, index) => {
                   return (
                     <Stack
                       gap="0.5rem"
@@ -402,7 +417,7 @@ const UserDefinedProperties = ({ loading, customAttributes, entity }: any) => {
                           size="small"
                           aria-label="add"
                           className="cursor-pointer"
-                          onClick={(e: any) => {
+                          onClick={(e: React.MouseEvent) => {
                             e.stopPropagation();
                             append(defaultField);
                           }}
diff --git a/dashboard/src/views/DetailPage/EntityDetailTabs/PropertiesTab/__tests__/BMAttributes.test.tsx b/dashboard/src/views/DetailPage/EntityDetailTabs/PropertiesTab/__tests__/BMAttributes.test.tsx
new file mode 100644
index 0000000000..6751e3b210
--- /dev/null
+++ b/dashboard/src/views/DetailPage/EntityDetailTabs/PropertiesTab/__tests__/BMAttributes.test.tsx
@@ -0,0 +1,235 @@
+/*
+ * 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 from 'react';
+import { render, screen, fireEvent, waitFor, act } from '@utils/test-utils';
+import '@testing-library/jest-dom';
+import BMAttributes from '../BMAttributes';
+import { ThemeProvider, createTheme } from '@mui/material/styles';
+
+const theme = createTheme();
+
+// Mock dependencies
+const mockDispatch = jest.fn();
+jest.mock('@hooks/reducerHook', () => ({
+  useAppDispatch: () => mockDispatch,
+  useAppSelector: jest.fn((selector) => {
+    const state = {
+      entity: {
+        entityData: {
+          entityDefs: [
+            {
+              name: 'DataSet',
+              businessAttributeDefs: {
+                'Group1': [
+                  { name: 'attr1', typeName: 'string' },
+                  { name: 'attr2', typeName: 'int' }
+                ]
+              }
+            }
+          ]
+        }
+      },
+      businessMetaData: {
+        businessMetaData: {
+          businessMetadataDefs: [
+            {
+              name: 'Group1',
+              attributeDefs: [
+                { name: 'attr1', typeName: 'string' },
+                { name: 'attr2', typeName: 'int' }
+              ]
+            }
+          ]
+        }
+      }
+    };
+    return selector(state);
+  })
+}));
+
+jest.mock('react-router-dom', () => ({
+  ...jest.requireActual('react-router-dom'),
+  useParams: () => ({ guid: 'test-guid-123' })
+}));
+
+const mockGetEntityBusinessMetadata = jest.fn();
+jest.mock('@api/apiMethods/detailpageApiMethod', () => ({
+  getEntityBusinessMetadata: (...args: any[]) => mockGetEntityBusinessMetadata(...args)
+}));
+
+jest.mock('react-toastify', () => ({
+  toast: {
+    dismiss: jest.fn(),
+    success: jest.fn(() => 'toast-id'),
+    error: jest.fn(() => 'toast-id')
+  }
+}));
+
+jest.mock('@utils/Utils', () => ({
+  ...jest.requireActual('@utils/Utils'),
+  serverError: jest.fn()
+}));
+
+jest.mock('@redux/slice/detailPageSlice', () => ({
+  fetchDetailPageData: jest.fn((guid: string) => ({ type: 'fetchDetailPageData', payload: guid }))
+}));
+
+// Mock BMAttributesFields to avoid complex form input mocks unless needed
+jest.mock('../BMAttributesFields', () => {
+  return function MockBMAttributesFields(props: any) {
+    return <div data-testid="bm-fields-mock">{props.obj?.name}</div>;
+  };
+});
+
+const TestWrapper: React.FC<React.PropsWithChildren<{}>> = ({ children }) => (
+  <ThemeProvider theme={theme}>{children}</ThemeProvider>
+);
+
+describe('BMAttributes Component', () => {
+  const defaultProps = {
+    loading: false,
+    bmAttributes: {
+      'Group1': {
+        'attr1': 'value1',
+        'attr2': 100
+      }
+    },
+    entity: { guid: 'test-guid-123', status: 'ACTIVE', typeName: 'DataSet' }
+  };
+
+  beforeEach(() => {
+    jest.clearAllMocks();
+  });
+
+  it('renders existing business metadata correctly', () => {
+    render(<TestWrapper><BMAttributes {...defaultProps} /></TestWrapper>);
+    
+    expect(screen.getByText('Business Metadata')).toBeInTheDocument();
+    expect(screen.getByText('Group1')).toBeInTheDocument();
+    expect(screen.getByText('attr1 (string)')).toBeInTheDocument();
+    expect(screen.getByText('attr2 (int)')).toBeInTheDocument();
+    // BMAttributes renders HTML for string values
+    expect(screen.getByText('value1')).toBeInTheDocument();
+    expect(screen.getByText('100')).toBeInTheDocument();
+  });
+
+  it('shows empty state message when empty', () => {
+    render(<TestWrapper><BMAttributes loading={false} bmAttributes={{}} entity={{ status: 'ACTIVE', typeName: 'DataSet' }} /></TestWrapper>);
+    
+    expect(screen.getByText(/No properties have been created yet/i)).toBeInTheDocument();
+  });
+
+  it('does not allow editing if entity is deleted', () => {
+    render(<TestWrapper><BMAttributes loading={false} bmAttributes={{}} entity={{ status: 'DELETED', typeName: 'DataSet' }} /></TestWrapper>);
+    
+    expect(screen.getByText(/No properties have been created yet/i)).toBeInTheDocument();
+    expect(screen.queryByText(/To add a property, click/i)).not.toBeInTheDocument();
+    expect(screen.queryByText('Add')).not.toBeInTheDocument();
+  });
+
+  it('does not allow editing if entity is purged', () => {
+    render(<TestWrapper><BMAttributes loading={false} bmAttributes={{}} entity={{ status: 'PURGED', typeName: 'DataSet' }} /></TestWrapper>);
+    
+    expect(screen.getByText(/No properties have been created yet/i)).toBeInTheDocument();
+    expect(screen.queryByText(/To add a property, click/i)).not.toBeInTheDocument();
+    expect(screen.queryByText('Add')).not.toBeInTheDocument();
+  });
+
+  it('hides edit button for deleted entity even when business metadata exists', () => {
+    render(<TestWrapper><BMAttributes {...defaultProps} entity={{ ...defaultProps.entity, status: 'DELETED' }} /></TestWrapper>);
+    
+    expect(screen.getByText('value1')).toBeInTheDocument();
+    expect(screen.queryByText('Edit')).not.toBeInTheDocument();
+  });
+
+  it('hides edit button for purged entity even when business metadata exists', () => {
+    render(<TestWrapper><BMAttributes {...defaultProps} entity={{ ...defaultProps.entity, status: 'PURGED' }} /></TestWrapper>);
+    
+    expect(screen.getByText('value1')).toBeInTheDocument();
+    expect(screen.queryByText('Edit')).not.toBeInTheDocument();
+  });
+
+  it('switches to edit mode on Edit button click', () => {
+    render(<TestWrapper><BMAttributes {...defaultProps} /></TestWrapper>);
+    
+    const editBtn = screen.getByText('Edit').closest('button')!;
+    fireEvent.click(editBtn);
+
+    expect(screen.getAllByTestId('bm-fields-mock')).toHaveLength(2);
+    expect(screen.getByText('attr1')).toBeInTheDocument();
+    expect(screen.getByText('attr2')).toBeInTheDocument();
+  });
+
+  it('adds new attribute dynamically', async () => {
+    render(<TestWrapper><BMAttributes {...defaultProps} /></TestWrapper>);
+    
+    fireEvent.click(screen.getByText('Edit').closest('button')!);
+    
+    const addAttrBtn = screen.getByRole('button', { name: /Add New Attribute/i });
+    fireEvent.click(addAttrBtn);
+    
+    // There should be 3 items now
+    const removeBtns = screen.getAllByTestId('RemoveOutlinedIcon');
+    expect(removeBtns).toHaveLength(3);
+  });
+
+  it('submits form successfully', async () => {
+    mockGetEntityBusinessMetadata.mockResolvedValueOnce({ data: {} });
+    
+    render(<TestWrapper><BMAttributes {...defaultProps} /></TestWrapper>);
+    
+    fireEvent.click(screen.getByText('Edit').closest('button')!);
+    
+    const saveBtn = screen.getAllByRole('button', { name: /save/i })[0];
+    await act(async () => { fireEvent.submit(saveBtn.closest('form')!); });
+    
+    await waitFor(() => {
+      expect(mockGetEntityBusinessMetadata).toHaveBeenCalledWith('test-guid-123', expect.any(Object));
+      expect(mockDispatch).toHaveBeenCalled();
+    });
+  });
+
+  it('handles API failure on save gracefully', async () => {
+    mockGetEntityBusinessMetadata.mockRejectedValueOnce(new Error('Network error'));
+    
+    render(<TestWrapper><BMAttributes {...defaultProps} /></TestWrapper>);
+    
+    fireEvent.click(screen.getByText('Edit').closest('button')!);
+    
+    const saveBtn = screen.getAllByRole('button', { name: /save/i })[0];
+    await act(async () => { fireEvent.submit(saveBtn.closest('form')!); });
+    
+    await waitFor(() => {
+      expect(mockGetEntityBusinessMetadata).toHaveBeenCalled();
+    });
+    
+    const { serverError } = require('@utils/Utils');
+    expect(serverError).toHaveBeenCalled();
+  });
+
+  it('hides Add button while loading', () => {
+    render(<TestWrapper><BMAttributes loading={true} bmAttributes={{}} entity={{ status: 'ACTIVE', typeName: 'DataSet' }} /></TestWrapper>);
+    expect(screen.queryByText('Add')).not.toBeInTheDocument();
+  });
+
+  it('hides Edit button while loading even when business metadata exists', () => {
+    render(<TestWrapper><BMAttributes {...defaultProps} loading={true} entity={{ ...defaultProps.entity, status: 'ACTIVE' }} /></TestWrapper>);
+    expect(screen.queryByText('Edit')).not.toBeInTheDocument();
+  });
+
+});
diff --git a/dashboard/src/views/DetailPage/EntityDetailTabs/PropertiesTab/__tests__/Labels.test.tsx b/dashboard/src/views/DetailPage/EntityDetailTabs/PropertiesTab/__tests__/Labels.test.tsx
new file mode 100644
index 0000000000..588d75300c
--- /dev/null
+++ b/dashboard/src/views/DetailPage/EntityDetailTabs/PropertiesTab/__tests__/Labels.test.tsx
@@ -0,0 +1,206 @@
+/*
+ * 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 from 'react';
+import { render, screen, fireEvent, waitFor, act } from '@utils/test-utils';
+import '@testing-library/jest-dom';
+import Labels from '../Labels';
+import { ThemeProvider, createTheme } from '@mui/material/styles';
+
+const theme = createTheme();
+
+// Mock dependencies
+const mockDispatch = jest.fn();
+jest.mock('@hooks/reducerHook', () => ({
+  useAppDispatch: () => mockDispatch
+}));
+
+jest.mock('react-router-dom', () => ({
+  ...jest.requireActual('react-router-dom'),
+  useParams: () => ({ guid: 'test-guid-123' })
+}));
+
+const mockGetLabels = jest.fn();
+const mockGetGlobalSearchResult = jest.fn();
+jest.mock('@api/apiMethods/detailpageApiMethod', () => ({
+  getLabels: (...args: any[]) => mockGetLabels(...args)
+}));
+jest.mock('@api/apiMethods/searchApiMethod', () => ({
+  getGlobalSearchResult: (...args: any[]) => mockGetGlobalSearchResult(...args)
+}));
+
+jest.mock('react-toastify', () => ({
+  toast: {
+    dismiss: jest.fn(),
+    success: jest.fn(() => 'toast-id'),
+    error: jest.fn(() => 'toast-id')
+  }
+}));
+
+jest.mock('@utils/Utils', () => ({
+  ...jest.requireActual('@utils/Utils'),
+  serverError: jest.fn()
+}));
+
+jest.mock('@redux/slice/detailPageSlice', () => ({
+  fetchDetailPageData: jest.fn((guid: string) => ({ type: 'fetchDetailPageData', payload: guid }))
+}));
+
+const TestWrapper: React.FC<React.PropsWithChildren<{}>> = ({ children }) => (
+  <ThemeProvider theme={theme}>{children}</ThemeProvider>
+);
+
+describe('Labels Component', () => {
+  const defaultProps = {
+    loading: false,
+    labels: ['Label1', 'Label2'],
+    entity: { status: 'ACTIVE' }
+  };
+
+  beforeEach(() => {
+    jest.clearAllMocks();
+  });
+
+  it('renders existing labels correctly', () => {
+    render(<TestWrapper><Labels {...defaultProps} /></TestWrapper>);
+    
+    // Labels are shown in an accordion that is expanded by default since labels exist
+    expect(screen.getByText('Labels')).toBeInTheDocument();
+    expect(screen.getByText('Label1')).toBeInTheDocument();
+    expect(screen.getByText('Label2')).toBeInTheDocument();
+  });
+
+  it('shows no labels message when empty', () => {
+    render(<TestWrapper><Labels loading={false} labels={[]} entity={{ status: 'ACTIVE' }} /></TestWrapper>);
+    
+    expect(screen.getByText(/No labels have been created yet/i)).toBeInTheDocument();
+  });
+
+  it('does not allow editing if entity is deleted', () => {
+    render(<TestWrapper><Labels loading={false} labels={[]} entity={{ status: 'DELETED' }} /></TestWrapper>);
+    
+    expect(screen.getByText(/No labels have been created yet/i)).toBeInTheDocument();
+    expect(screen.queryByText(/To add a labels, click/i)).not.toBeInTheDocument();
+    expect(screen.queryByText('Add')).not.toBeInTheDocument();
+  });
+
+  it('does not allow editing if entity is purged', () => {
+    render(<TestWrapper><Labels loading={false} labels={[]} entity={{ status: 'PURGED' }} /></TestWrapper>);
+    
+    expect(screen.getByText(/No labels have been created yet/i)).toBeInTheDocument();
+    expect(screen.queryByText(/To add a labels, click/i)).not.toBeInTheDocument();
+    expect(screen.queryByText('Add')).not.toBeInTheDocument();
+  });
+
+  it('hides edit button for deleted entity even when labels exist', () => {
+    render(<TestWrapper><Labels loading={false} labels={['Label1']} entity={{ status: 'DELETED' }} /></TestWrapper>);
+    
+    expect(screen.getByText('Label1')).toBeInTheDocument();
+    expect(screen.queryByText('Edit')).not.toBeInTheDocument();
+  });
+
+  it('hides edit button for purged entity even when labels exist', () => {
+    render(<TestWrapper><Labels loading={false} labels={['Label1']} entity={{ status: 'PURGED' }} /></TestWrapper>);
+    
+    expect(screen.getByText('Label1')).toBeInTheDocument();
+    expect(screen.queryByText('Edit')).not.toBeInTheDocument();
+  });
+
+  it('allows clicking edit to show autocomplete form', async () => {
+    render(<TestWrapper><Labels {...defaultProps} /></TestWrapper>);
+    
+    const editBtn = screen.getByText('Edit').closest('button')!;
+    fireEvent.click(editBtn);
+
+    expect(await screen.findByPlaceholderText('Select Label')).toBeInTheDocument();
+  });
+
+  it('allows clicking "here" to add label when empty', async () => {
+    render(<TestWrapper><Labels loading={false} labels={[]} entity={{ status: 'ACTIVE' }} /></TestWrapper>);
+    
+    const hereText = screen.getByText('here');
+    fireEvent.click(hereText);
+
+    expect(await screen.findByPlaceholderText('Select Label')).toBeInTheDocument();
+  });
+
+  it('calls API and dispatches action on save', async () => {
+    mockGetLabels.mockResolvedValueOnce({ data: {} });
+    
+    render(<TestWrapper><Labels {...defaultProps} /></TestWrapper>);
+    
+    // Click Edit
+    fireEvent.click(screen.getByText('Edit').closest('button')!);
+    
+    // Since autocomplete already has default value, let's just save
+    const saveBtn = screen.getAllByRole('button', { name: /save/i })[0];
+    await act(async () => { fireEvent.submit(saveBtn.closest('form')!); });
+    
+    await waitFor(() => {
+      expect(mockGetLabels).toHaveBeenCalledWith('test-guid-123', ['Label1', 'Label2']);
+      expect(mockDispatch).toHaveBeenCalled();
+    });
+  });
+
+  it('handles API failure on save gracefully', async () => {
+    mockGetLabels.mockRejectedValueOnce(new Error('Network error'));
+    
+    render(<TestWrapper><Labels {...defaultProps} /></TestWrapper>);
+    
+    // Click Edit
+    fireEvent.click(screen.getByText('Edit').closest('button')!);
+    
+    // Save
+    const saveBtn = screen.getAllByRole('button', { name: /save/i })[0];
+    await act(async () => { fireEvent.submit(saveBtn.closest('form')!); });
+    
+    await waitFor(() => {
+      expect(mockGetLabels).toHaveBeenCalled();
+    });
+    
+    // Error is handled via serverError util mock
+    const { serverError } = require('@utils/Utils');
+    expect(serverError).toHaveBeenCalled();
+  });
+  
+  it('fetches label suggestions on open', async () => {
+    mockGetGlobalSearchResult.mockResolvedValueOnce({ data: { suggestions: ['Label3', 'Label4'] } });
+    
+    render(<TestWrapper><Labels {...defaultProps} /></TestWrapper>);
+    
+    // Click Edit
+    fireEvent.click(screen.getByText('Edit').closest('button')!);
+    
+    const input = await screen.findByPlaceholderText('Select Label');
+    fireEvent.mouseDown(input);
+    
+    await waitFor(() => {
+      expect(mockGetGlobalSearchResult).toHaveBeenCalledWith('suggestions', expect.objectContaining({ params: { fieldName: '__labels' } }));
+    });
+  });
+
+  it('hides Add button while loading', () => {
+    render(<TestWrapper><Labels loading={true} labels={[]} entity={{ status: 'ACTIVE' }} /></TestWrapper>);
+    expect(screen.queryByText('Add')).not.toBeInTheDocument();
+  });
+
+  it('hides Edit button while loading even when labels exist', () => {
+    render(<TestWrapper><Labels loading={true} labels={['Label1']} entity={{ status: 'ACTIVE' }} /></TestWrapper>);
+    expect(screen.queryByText('Edit')).not.toBeInTheDocument();
+  });
+
+});
diff --git a/dashboard/src/views/DetailPage/EntityDetailTabs/PropertiesTab/__tests__/UserDefinedProperties.test.tsx b/dashboard/src/views/DetailPage/EntityDetailTabs/PropertiesTab/__tests__/UserDefinedProperties.test.tsx
new file mode 100644
index 0000000000..b7fdedd9fd
--- /dev/null
+++ b/dashboard/src/views/DetailPage/EntityDetailTabs/PropertiesTab/__tests__/UserDefinedProperties.test.tsx
@@ -0,0 +1,226 @@
+/*
+ * 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 from 'react';
+import { render, screen, fireEvent, waitFor, act } from '@utils/test-utils';
+import '@testing-library/jest-dom';
+import UserDefinedProperties from '../UserDefinedProperties';
+import { ThemeProvider, createTheme } from '@mui/material/styles';
+
+const theme = createTheme();
+
+// Mock dependencies
+const mockDispatch = jest.fn();
+jest.mock('@hooks/reducerHook', () => ({
+  useAppDispatch: () => mockDispatch
+}));
+
+jest.mock('react-router-dom', () => ({
+  ...jest.requireActual('react-router-dom'),
+  useParams: () => ({ guid: 'test-guid-123' })
+}));
+
+const mockCreateEntity = jest.fn();
+jest.mock('@api/apiMethods/entityFormApiMethod', () => ({
+  createEntity: (...args: any[]) => mockCreateEntity(...args)
+}));
+
+jest.mock('@utils/entityPayloadEnrichmentUtils', () => ({
+  enrichEntityPayloadForRelationshipSave: jest.fn(async (entity) => entity)
+}));
+
+jest.mock('react-toastify', () => ({
+  toast: {
+    dismiss: jest.fn(),
+    success: jest.fn(() => 'toast-id'),
+    error: jest.fn(() => 'toast-id')
+  }
+}));
+
+jest.mock('@utils/Utils', () => ({
+  ...jest.requireActual('@utils/Utils'),
+  serverError: jest.fn()
+}));
+
+jest.mock('@redux/slice/detailPageSlice', () => ({
+  fetchDetailPageData: jest.fn((guid: string) => ({ type: 'fetchDetailPageData', payload: guid }))
+}));
+
+const TestWrapper: React.FC<React.PropsWithChildren<{}>> = ({ children }) => (
+  <ThemeProvider theme={theme}>{children}</ThemeProvider>
+);
+
+describe('UserDefinedProperties Component', () => {
+  const defaultProps = {
+    loading: false,
+    customAttributes: { key1: 'value1', key2: 'value2' },
+    entity: { guid: 'test-guid-123', status: 'ACTIVE', customAttributes: {} }
+  };
+
+  beforeEach(() => {
+    jest.clearAllMocks();
+  });
+
+  it('renders existing properties correctly', () => {
+    render(<TestWrapper><UserDefinedProperties {...defaultProps} /></TestWrapper>);
+    
+    expect(screen.getByText('User-defined properties')).toBeInTheDocument();
+    expect(screen.getByText('key1')).toBeInTheDocument();
+    expect(screen.getByText('value1')).toBeInTheDocument();
+    expect(screen.getByText('key2')).toBeInTheDocument();
+    expect(screen.getByText('value2')).toBeInTheDocument();
+  });
+
+  it('shows empty state message when empty', () => {
+    render(<TestWrapper><UserDefinedProperties loading={false} customAttributes={{}} entity={{ status: 'ACTIVE' }} /></TestWrapper>);
+    
+    expect(screen.getByText(/No properties have been created yet/i)).toBeInTheDocument();
+  });
+
+  it('does not allow editing if entity is deleted', () => {
+    render(<TestWrapper><UserDefinedProperties loading={false} customAttributes={{}} entity={{ status: 'DELETED' }} /></TestWrapper>);
+    
+    expect(screen.getByText(/No properties have been created yet/i)).toBeInTheDocument();
+    expect(screen.queryByText(/To add a property,click/i)).not.toBeInTheDocument();
+    expect(screen.queryByText('Add')).not.toBeInTheDocument();
+  });
+
+  it('does not allow editing if entity is purged', () => {
+    render(<TestWrapper><UserDefinedProperties loading={false} customAttributes={{}} entity={{ status: 'PURGED' }} /></TestWrapper>);
+    
+    expect(screen.getByText(/No properties have been created yet/i)).toBeInTheDocument();
+    expect(screen.queryByText(/To add a property,click/i)).not.toBeInTheDocument();
+    expect(screen.queryByText('Add')).not.toBeInTheDocument();
+  });
+
+  it('hides edit button for deleted entity even when properties exist', () => {
+    render(<TestWrapper><UserDefinedProperties {...defaultProps} entity={{ ...defaultProps.entity, status: 'DELETED' }} /></TestWrapper>);
+    
+    expect(screen.getByText('value1')).toBeInTheDocument();
+    expect(screen.queryByText('Edit')).not.toBeInTheDocument();
+  });
+
+  it('hides edit button for purged entity even when properties exist', () => {
+    render(<TestWrapper><UserDefinedProperties {...defaultProps} entity={{ ...defaultProps.entity, status: 'PURGED' }} /></TestWrapper>);
+    
+    expect(screen.getByText('value1')).toBeInTheDocument();
+    expect(screen.queryByText('Edit')).not.toBeInTheDocument();
+  });
+
+  it('switches to edit mode on Edit button click', () => {
+    render(<TestWrapper><UserDefinedProperties {...defaultProps} /></TestWrapper>);
+    
+    const editBtn = screen.getByText('Edit').closest('button')!;
+    fireEvent.click(editBtn);
+
+    expect(screen.getByDisplayValue('key1')).toBeInTheDocument();
+    expect(screen.getByDisplayValue('value1')).toBeInTheDocument();
+  });
+
+  it('adds and removes fields dynamically', async () => {
+    render(<TestWrapper><UserDefinedProperties {...defaultProps} /></TestWrapper>);
+    
+    // Edit mode
+    fireEvent.click(screen.getByText('Edit').closest('button')!);
+    
+    // Should have 2 inputs initially for keys
+    let keyInputs = screen.getAllByPlaceholderText('key');
+    expect(keyInputs).toHaveLength(2);
+    
+    // Add new field
+    const addBtns = screen.getAllByTestId('AddOutlinedIcon');
+    fireEvent.click(addBtns[0]);
+    
+    keyInputs = screen.getAllByPlaceholderText('key');
+    expect(keyInputs).toHaveLength(3);
+    
+    // Remove field
+    const removeBtns = screen.getAllByTestId('RemoveOutlinedIcon');
+    fireEvent.click(removeBtns[0]); // Removing first
+    
+    keyInputs = screen.getAllByPlaceholderText('key');
+    expect(keyInputs).toHaveLength(2);
+  });
+
+  it('validates unique keys', async () => {
+    render(<TestWrapper><UserDefinedProperties {...defaultProps} /></TestWrapper>);
+    
+    fireEvent.click(screen.getByText('Edit').closest('button')!);
+    
+    const keyInputs = screen.getAllByPlaceholderText('key');
+    // Change second key to 'key1' to cause duplicate
+    fireEvent.change(keyInputs[1], { target: { value: 'key1' } });
+    
+    // Form submission
+    const saveBtn = screen.getAllByRole('button', { name: /save/i })[0];
+    await act(async () => { fireEvent.submit(saveBtn.closest('form')!); });
+    
+    await waitFor(() => {
+      expect(screen.getAllByText('Key must be unique')[0]).toBeInTheDocument();
+      expect(mockCreateEntity).not.toHaveBeenCalled();
+    });
+  });
+
+  it('submits form successfully', async () => {
+    mockCreateEntity.mockResolvedValueOnce({ data: {} });
+    
+    render(<TestWrapper><UserDefinedProperties {...defaultProps} /></TestWrapper>);
+    
+    fireEvent.click(screen.getByText('Edit').closest('button')!);
+    
+    const saveBtn = screen.getAllByRole('button', { name: /save/i })[0];
+    await act(async () => { fireEvent.submit(saveBtn.closest('form')!); });
+    
+    await waitFor(() => {
+      expect(mockCreateEntity).toHaveBeenCalledWith({
+        entity: expect.objectContaining({
+          customAttributes: { key1: 'value1', key2: 'value2' }
+        })
+      });
+      expect(mockDispatch).toHaveBeenCalled();
+    });
+  });
+
+  it('handles API failure on save gracefully', async () => {
+    mockCreateEntity.mockRejectedValueOnce(new Error('Network error'));
+    
+    render(<TestWrapper><UserDefinedProperties {...defaultProps} /></TestWrapper>);
+    
+    fireEvent.click(screen.getByText('Edit').closest('button')!);
+    
+    const saveBtn = screen.getAllByRole('button', { name: /save/i })[0];
+    await act(async () => { fireEvent.submit(saveBtn.closest('form')!); });
+    
+    await waitFor(() => {
+      expect(mockCreateEntity).toHaveBeenCalled();
+    });
+    
+    const { serverError } = require('@utils/Utils');
+    expect(serverError).toHaveBeenCalled();
+  });
+
+  it('hides Add button while loading', () => {
+    render(<TestWrapper><UserDefinedProperties loading={true} customAttributes={{}} entity={{ status: 'ACTIVE' }} /></TestWrapper>);
+    expect(screen.queryByText('Add')).not.toBeInTheDocument();
+  });
+
+  it('hides Edit button while loading even when properties exist', () => {
+    render(<TestWrapper><UserDefinedProperties {...defaultProps} loading={true} entity={{ ...defaultProps.entity, status: 'ACTIVE' }} /></TestWrapper>);
+    expect(screen.queryByText('Edit')).not.toBeInTheDocument();
+  });
+
+});
diff --git a/dashboard/src/views/DetailPage/EntityDetailTabs/__tests__/AttributeProperties.test.tsx b/dashboard/src/views/DetailPage/EntityDetailTabs/__tests__/AttributeProperties.test.tsx
index ba2b8fef87..f8a302595e 100644
--- a/dashboard/src/views/DetailPage/EntityDetailTabs/__tests__/AttributeProperties.test.tsx
+++ b/dashboard/src/views/DetailPage/EntityDetailTabs/__tests__/AttributeProperties.test.tsx
@@ -710,6 +710,64 @@ describe('AttributeProperties', () => {
 			expect(screen.queryByTestId('custom-button')).not.toBeInTheDocument();
 		});
 
+		it('should not show Edit button for DELETED entities', () => {
+			mockUseAppSelector.mockImplementation((selector: any) => {
+				const mockState = {
+					session: {
+						sessionObj: {
+							data: {
+								'atlas.entity.update.allowed': true,
+								'atlas.ui.editable.entity.types': '*'
+							}
+						}
+					}
+				};
+				return selector(mockState);
+			});
+
+			render(
+				<TestWrapper>
+					<AttributeProperties
+						entity={{ ...defaultMockEntity, status: 'DELETED' }}
+						referredEntities={defaultMockReferredEntities}
+						loading={false}
+						propertiesName="Technical"
+					/>
+				</TestWrapper>
+			);
+
+			expect(screen.queryByTestId('custom-button')).not.toBeInTheDocument();
+		});
+
+		it('should not show Edit button for PURGED entities', () => {
+			mockUseAppSelector.mockImplementation((selector: any) => {
+				const mockState = {
+					session: {
+						sessionObj: {
+							data: {
+								'atlas.entity.update.allowed': true,
+								'atlas.ui.editable.entity.types': '*'
+							}
+						}
+					}
+				};
+				return selector(mockState);
+			});
+
+			render(
+				<TestWrapper>
+					<AttributeProperties
+						entity={{ ...defaultMockEntity, status: 'PURGED' }}
+						referredEntities={defaultMockReferredEntities}
+						loading={false}
+						propertiesName="Technical"
+					/>
+				</TestWrapper>
+			);
+
+			expect(screen.queryByTestId('custom-button')).not.toBeInTheDocument();
+		});
+
 		it('should not show Edit button in audit details mode', () => {
 			render(
 				<TestWrapper>
diff --git a/dashboard/src/views/DetailPage/EntityDetailTabs/__tests__/ClassificationsTab.test.tsx b/dashboard/src/views/DetailPage/EntityDetailTabs/__tests__/ClassificationsTab.test.tsx
index f451599dfa..d4703a94f0 100644
--- a/dashboard/src/views/DetailPage/EntityDetailTabs/__tests__/ClassificationsTab.test.tsx
+++ b/dashboard/src/views/DetailPage/EntityDetailTabs/__tests__/ClassificationsTab.test.tsx
@@ -1001,6 +1001,40 @@ describe('ClassificationsTab', () => {
 	});
 
 	describe('Edge Cases', () => {
+		it('should not render action buttons when parent entity is DELETED', () => {
+			const deletedEntity = {
+				...mockEntity,
+				status: 'DELETED'
+			};
+
+			render(
+				<TestWrapper>
+					<ClassificationsTab entity={deletedEntity} loading={false} tags={mockTags} />
+				</TestWrapper>
+			);
+
+			// Delete and Edit buttons should not be rendered
+			const actionButtons = screen.queryAllByTestId(/custom-button-addTag/);
+			expect(actionButtons).toHaveLength(0);
+		});
+
+		it('should not render action buttons when parent entity is PURGED', () => {
+			const purgedEntity = {
+				...mockEntity,
+				status: 'PURGED'
+			};
+
+			render(
+				<TestWrapper>
+					<ClassificationsTab entity={purgedEntity} loading={false} tags={mockTags} />
+				</TestWrapper>
+			);
+
+			// Delete and Edit buttons should not be rendered
+			const actionButtons = screen.queryAllByTestId(/custom-button-addTag/);
+			expect(actionButtons).toHaveLength(0);
+		});
+
 		it('should handle empty tags prop', () => {
 			render(
 				<TestWrapper>
diff --git a/dashboard/src/views/DetailPage/__tests__/DetailPageAttributes.test.tsx b/dashboard/src/views/DetailPage/__tests__/DetailPageAttributes.test.tsx
index bc3893b94a..4775c09fbc 100644
--- a/dashboard/src/views/DetailPage/__tests__/DetailPageAttributes.test.tsx
+++ b/dashboard/src/views/DetailPage/__tests__/DetailPageAttributes.test.tsx
@@ -392,6 +392,71 @@ describe('DetailPageAttribute', () => {
 		fireEvent.click(screen.getByText('close-assign-cat'))
 	})
 
+	it('hides Add Classifications button for DELETED entities', () => {
+		mockGtype = 'term'
+		renderComp({ data: { ...baseData, status: 'DELETED' } })
+		expect(document.querySelector('[data-title="Add Classifications"]')).toBeNull()
+	})
+
+	it('hides Add Attributes button for DELETED entities', () => {
+		mockGtype = 'term'
+		renderComp({ data: { ...baseData, status: 'DELETED' } })
+		expect(document.querySelector('[data-title="Add Attributes"]')).toBeNull()
+	})
+
+	it('hides Edit Classification button for DELETED entities', () => {
+		mockGtype = 'term'
+		renderComp({ data: { ...baseData, status: 'DELETED' } })
+		expect(document.querySelector('[data-title="Edit Classification"]')).toBeNull()
+	})
+
+	it('hides Add Term button for DELETED entities', () => {
+		mockGtype = 'category'
+		mockParams.guid = 'gc'
+		renderComp({ data: { ...baseData, status: 'DELETED' } })
+		expect(document.querySelector('[data-title="Add Term"]')).toBeNull()
+	})
+
+	it('hides Add Categories button for DELETED entities', () => {
+		mockGtype = 'term'
+		mockParams.guid = 'gt'
+		renderComp({ data: { ...baseData, status: 'DELETED' } })
+		expect(document.querySelector('[data-title="Add Categories"]')).toBeNull()
+	})
+
+	it('hides Add Classifications button for PURGED entities', () => {
+		mockGtype = 'term'
+		renderComp({ data: { ...baseData, status: 'PURGED' } })
+		expect(document.querySelector('[data-title="Add Classifications"]')).toBeNull()
+	})
+
+	it('hides Add Attributes button for PURGED entities', () => {
+		mockGtype = 'term'
+		renderComp({ data: { ...baseData, status: 'PURGED' } })
+		expect(document.querySelector('[data-title="Add Attributes"]')).toBeNull()
+	})
+
+	it('hides Edit Classification button for PURGED entities', () => {
+		mockGtype = 'term'
+		renderComp({ data: { ...baseData, status: 'PURGED' } })
+		expect(document.querySelector('[data-title="Edit Classification"]')).toBeNull()
+	})
+
+	it('hides Add Term button for PURGED entities', () => {
+		mockGtype = 'category'
+		mockParams.guid = 'gc'
+		renderComp({ data: { ...baseData, status: 'PURGED' } })
+		expect(document.querySelector('[data-title="Add Term"]')).toBeNull()
+	})
+
+	it('hides Add Categories button for PURGED entities', () => {
+		mockGtype = 'term'
+		mockParams.guid = 'gt'
+		renderComp({ data: { ...baseData, status: 'PURGED' } })
+		expect(document.querySelector('[data-title="Add Categories"]')).toBeNull()
+	})
+
+
 	it('superTypes section loading and loaded', () => {
 		const { rerender } = render(
 			<MemoryRouter>
diff --git a/dashboard/src/views/__tests__/EntityDetailPage.test.tsx b/dashboard/src/views/__tests__/EntityDetailPage.test.tsx
index 2e95138d44..d985f6156d 100644
--- a/dashboard/src/views/__tests__/EntityDetailPage.test.tsx
+++ b/dashboard/src/views/__tests__/EntityDetailPage.test.tsx
@@ -164,6 +164,12 @@ const renderWithProviders = (ui: React.ReactElement) => {
 	return render(ui, { withRouter: false });
 };
 
+
+jest.mock('@components/muiComponents', () => ({
+	...jest.requireActual('@components/muiComponents'),
+	LightTooltip: ({ title, children }: any) => <span data-title={title}>{children}</span>
+}));
+
 describe('EntityDetailPage', () => {
 	const mockEntity = {
 		guid: 'test-guid',
@@ -216,6 +222,20 @@ describe('EntityDetailPage', () => {
 		expect(screen.getAllByTestId('skeleton-loader').length).toBeGreaterThan(0);
 	});
 
+	it('should render loading skeleton when detailPageData is null', () => {
+		const store = configureStore({
+			reducer: {
+				detailPage: (state = { detailPageData: null, loading: false }) => state,
+				entity: (state = { entityData: {} }) => state,
+				glossary: (state = { glossaryData: [] }) => state
+			}
+		});
+
+		renderWithProviders(<TestWrapper store={store} />);
+
+		expect(screen.getAllByTestId('skeleton-loader').length).toBeGreaterThan(0);
+	});
+
 	it('should display entity name and type', () => {
 		const store = createMockStore(mockDetailPageData, mockEntityData);
 		renderWithProviders(<TestWrapper store={store} />);
@@ -256,9 +276,9 @@ describe('EntityDetailPage', () => {
 		const store = createMockStore(mockDetailPageData, mockEntityData);
 		renderWithProviders(<TestWrapper store={store} />);
 
-		const addTagButton = screen.queryByLabelText(/add.*tag/i) || screen.queryByText(/add.*classification/i);
+		const addTagButton = document.querySelector('[data-title="Add Classifications"]');
 		if (addTagButton) {
-			fireEvent.click(addTagButton);
+			fireEvent.click(addTagButton.querySelector('.MuiIconButton-root') || addTagButton);
 			expect(screen.getByTestId('add-tag-modal')).toBeTruthy();
 		}
 	});
@@ -267,9 +287,9 @@ describe('EntityDetailPage', () => {
 		const store = createMockStore(mockDetailPageData, mockEntityData);
 		renderWithProviders(<TestWrapper store={store} />);
 
-		const addTagButton = screen.queryByLabelText(/add.*tag/i) || screen.queryByText(/add.*classification/i);
+		const addTagButton = document.querySelector('[data-title="Add Classifications"]');
 		if (addTagButton) {
-			fireEvent.click(addTagButton);
+			fireEvent.click(addTagButton.querySelector('.MuiIconButton-root') || addTagButton);
 			const closeButton = screen.getByText('Close Add Tag');
 			fireEvent.click(closeButton);
 			expect(screen.queryByTestId('add-tag-modal')).toBeNull();
@@ -277,16 +297,47 @@ describe('EntityDetailPage', () => {
 	});
 
 	it('should open assign term modal when assign term button is clicked', () => {
-		const store = createMockStore(mockDetailPageData, mockEntityData, [{ terms: [] }]);
+		const store = createMockStore(mockDetailPageData, mockEntityData, [{ terms: [{ termGuid: '123' }] }]);
 		renderWithProviders(<TestWrapper store={store} />);
 
-		const assignTermButton = screen.queryByLabelText(/assign.*term/i) || screen.queryByText(/assign.*term/i);
+		const assignTermButton = document.querySelector('[data-title="Add Term"]');
 		if (assignTermButton) {
-			fireEvent.click(assignTermButton);
+			fireEvent.click(assignTermButton.querySelector('.MuiIconButton-root') || assignTermButton);
 			expect(screen.getByTestId('assign-term-modal')).toBeTruthy();
 		}
 	});
 
+	it('should hide Add Classification and Add Term buttons for DELETED entities', () => {
+		const deletedEntity = {
+			...mockEntity,
+			status: 'DELETED'
+		};
+		const store = createMockStore({ entity: deletedEntity, referredEntities: {} }, mockEntityData, [{ terms: [] }]);
+		renderWithProviders(<TestWrapper store={store} />);
+
+		const addClassificationButton = document.querySelector('[data-title="Add Classifications"]');
+		const addTermButton = document.querySelector('[data-title="Add Term"]');
+
+		expect(addClassificationButton).toBeNull();
+		expect(addTermButton).toBeNull();
+	});
+
+	it('should hide Add Classification and Add Term buttons for PURGED entities', () => {
+		const purgedEntity = {
+			...mockEntity,
+			status: 'PURGED'
+		};
+		const store = createMockStore({ entity: purgedEntity, referredEntities: {} }, mockEntityData, [{ terms: [] }]);
+		renderWithProviders(<TestWrapper store={store} />);
+
+		const addClassificationButton = document.querySelector('[data-title="Add Classifications"]');
+		const addTermButton = document.querySelector('[data-title="Add Term"]');
+
+		expect(addClassificationButton).toBeNull();
+		expect(addTermButton).toBeNull();
+	});
+
+
 	it('should handle entity not found', () => {
 		const store = createMockStore({ entity: null }, mockEntityData);
 		renderWithProviders(<TestWrapper store={store} />);