From 4c49f098bd702b0183d652d81403af8c92d1bf18 Mon Sep 17 00:00:00 2001
From: Karan Hotchandani <33024356+karanh37@users.noreply.github.com>
Date: Mon, 19 Aug 2024 15:29:07 +0530
Subject: [PATCH] fix import export permissions (#17482)
---
.../GlossaryHeader.component.tsx | 17 ++++++++-
.../GlossaryHeader/GlossaryHeader.test.tsx | 37 +++++++++++++++++++
.../EntityImport/EntityImport.component.tsx | 8 ++--
.../resources/ui/src/utils/SearchUtils.tsx | 13 +++++--
.../main/resources/ui/src/utils/ToastUtils.ts | 4 +-
5 files changed, 71 insertions(+), 8 deletions(-)
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryHeader/GlossaryHeader.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryHeader/GlossaryHeader.component.tsx
index 641089879f8..4c96562d960 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryHeader/GlossaryHeader.component.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryHeader/GlossaryHeader.component.tsx
@@ -120,6 +120,21 @@ const GlossaryHeader = ({
[globalPermissions]
);
+ const importExportPermissions = useMemo(
+ () =>
+ checkPermission(
+ Operation.All,
+ ResourceEntity.GLOSSARY_TERM,
+ globalPermissions
+ ) ||
+ checkPermission(
+ Operation.EditAll,
+ ResourceEntity.GLOSSARY_TERM,
+ globalPermissions
+ ),
+ [globalPermissions]
+ );
+
// To fetch the latest glossary data
// necessary to handle back click functionality to work properly in version page
const fetchCurrentGlossaryInfo = async () => {
@@ -298,7 +313,7 @@ const GlossaryHeader = ({
}, [selectedData]);
const manageButtonContent: ItemType[] = [
- ...(isGlossary
+ ...(isGlossary && importExportPermissions
? ([
{
label: (
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryHeader/GlossaryHeader.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryHeader/GlossaryHeader.test.tsx
index 00c123fe015..f3b7a3a683f 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryHeader/GlossaryHeader.test.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/Glossary/GlossaryHeader/GlossaryHeader.test.tsx
@@ -23,6 +23,25 @@ import { DEFAULT_ENTITY_PERMISSION } from '../../../utils/PermissionsUtils';
import { QueryVoteType } from '../../Database/TableQueries/TableQueries.interface';
import GlossaryHeader from './GlossaryHeader.component';
+const glossaryTermPermission = {
+ All: true,
+ Create: true,
+ Delete: true,
+ ViewAll: true,
+ EditAll: true,
+ EditDescription: true,
+ EditDisplayName: true,
+ EditCustomFields: true,
+};
+
+jest.mock('../../../context/PermissionProvider/PermissionProvider', () => ({
+ usePermissionProvider: jest.fn().mockImplementation(() => ({
+ permissions: {
+ glossaryTerm: glossaryTermPermission,
+ },
+ })),
+}));
+
jest.mock('react-router-dom', () => ({
useHistory: jest.fn(),
useParams: jest.fn().mockReturnValue({
@@ -195,6 +214,24 @@ describe('GlossaryHeader component', () => {
expect(screen.queryByText('label.style')).not.toBeInTheDocument();
});
+ it('should not render import and export dropdown menu items if no permission', async () => {
+ glossaryTermPermission.All = false;
+ glossaryTermPermission.EditAll = false;
+ render(
+
+ );
+
+ expect(screen.queryByTestId('manage-button')).not.toBeInTheDocument();
+ });
+
it('should render changeParentHierarchy and style dropdown menu items only for glossaryTerm', async () => {
render(
{
break;
case SearchIndex.GLOSSARY_TERM:
label = i18next.t('label.glossary-term-plural');
- GroupIcon = IconTable;
+ GroupIcon = GlossaryTermIcon;
break;
case SearchIndex.TAG:
@@ -219,11 +219,18 @@ export const getSuggestionElement = (
FqnPart.Service,
])}-${name}`.replaceAll(`"`, '');
- const displayText =
+ let displayText =
database && schema
? `${database}${FQN_SEPARATOR_CHAR}${schema}${FQN_SEPARATOR_CHAR}${name}`
: searchClassBase.getEntityName(entitySource);
+ if (index === SearchIndex.GLOSSARY_TERM) {
+ // Show Fqn for Glossary Term. Adding this to avoid confusion for nested terms
+ displayText =
+ entitySource.fullyQualifiedName ??
+ searchClassBase.getEntityName(entitySource);
+ }
+
const retn = (