diff --git a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/RightEntityPanelFlow.spec.ts b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/RightEntityPanelFlow.spec.ts
index 2c490fe4d80..33460ec27cb 100644
--- a/openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/RightEntityPanelFlow.spec.ts
+++ b/openmetadata-ui/src/main/resources/ui/playwright/e2e/Flow/RightEntityPanelFlow.spec.ts
@@ -59,25 +59,24 @@ test.afterAll('Cleanup shared test data', async ({ browser }) => {
await afterAction();
});
-async function openEntitySummaryPanel(page: Page, entityType: string) {
- await page.getByRole('button', { name: 'Data Assets' }).click();
- const dataAssetDropdownRequest = page.waitForResponse(
- '/api/v1/search/aggregate?index=dataAsset&field=entityType.keyword*'
- );
- await page
- .getByTestId('drop-down-menu')
- .getByTestId('search-input')
- .fill(entityType.toLowerCase());
- await dataAssetDropdownRequest;
- await page.getByTestId(`${entityType.toLowerCase()}-checkbox`).check();
- await page.getByTestId('update-btn').click();
+async function openEntitySummaryPanel(page: Page, entityName: string) {
+ const searchResponse = page.waitForResponse('/api/v1/search/query*');
+
+ await page.getByTestId('searchBox').fill(entityName);
+ await searchResponse;
+
+ await page.getByTestId('searchBox').press('Enter');
+ await page.waitForSelector('[data-testid="loader"]', {
+ state: 'detached',
+ });
await page.waitForLoadState('networkidle');
- const firstEntityCard = page
+ const entityCard = page
.locator('[data-testid="table-data-card"]')
+ .filter({ hasText: entityName })
.first();
- if (await firstEntityCard.isVisible()) {
- await firstEntityCard.click();
+ if (await entityCard.isVisible()) {
+ await entityCard.click();
await page.waitForLoadState('networkidle');
}
}
@@ -93,25 +92,7 @@ async function navigateToExploreAndSelectTable(page: Page) {
.catch(() => {
// Loader might not appear, continue
});
- await openEntitySummaryPanel(page, 'table');
-
- // Wait for loader to disappear
- await page
- .waitForSelector('[data-testid="loader"]', {
- state: 'detached',
- timeout: 15000,
- })
- .catch(() => {
- // Loader might not appear, continue
- });
-
- await page.waitForSelector('.highlight-card', {
- timeout: 15000,
- });
-
- const summaryPanel = page.locator('.entity-summary-panel-container');
-
- await expect(summaryPanel).toBeVisible({ timeout: 15000 });
+ await openEntitySummaryPanel(page, testEntity.entity.name);
}
async function waitForPatchResponse(page: Page) {
@@ -203,15 +184,12 @@ test.describe('Right Entity Panel - Admin User Flow', () => {
await adminPage
.locator('[data-testid="edit-icon-tier"]')
.scrollIntoViewIfNeeded();
- await adminPage.waitForSelector('[data-testid="edit-icon-tier"]', {
- state: 'visible',
- });
await adminPage.locator('[data-testid="edit-icon-tier"]').click();
- const tierCard = adminPage.locator('.ant-popover');
+ await adminPage.locator('[data-testid="cards"]').scrollIntoViewIfNeeded();
- await expect(tierCard).toBeVisible();
+ await expect(adminPage.locator('[data-testid="cards"]')).toBeVisible();
const tier1Radio = adminPage.getByTestId('radio-btn-Tier1');
await tier1Radio.click();
@@ -236,15 +214,16 @@ test.describe('Right Entity Panel - Admin User Flow', () => {
await adminPage
.locator('[data-testid="edit-icon-tags"]')
.scrollIntoViewIfNeeded();
- await adminPage.waitForSelector('[data-testid="edit-icon-tags"]', {
- state: 'visible',
- });
await adminPage.locator('[data-testid="edit-icon-tags"]').click();
- const tagsPopover = adminPage.locator('.ant-popover');
+ await adminPage
+ .locator('[data-testid="selectable-list"]')
+ .scrollIntoViewIfNeeded();
- await expect(tagsPopover).toBeVisible();
+ await expect(
+ adminPage.locator('[data-testid="selectable-list"]')
+ ).toBeVisible();
const tagOption = adminPage.getByTitle('None');
if (await tagOption.isVisible()) {
@@ -277,9 +256,13 @@ test.describe('Right Entity Panel - Admin User Flow', () => {
await adminPage.locator('[data-testid="edit-glossary-terms"]').click();
- const glossaryPopover = adminPage.locator('.ant-popover');
+ await adminPage
+ .locator('[data-testid="selectable-list"]')
+ .scrollIntoViewIfNeeded();
- await expect(glossaryPopover).toBeVisible();
+ await expect(
+ adminPage.locator('[data-testid="selectable-list"]')
+ ).toBeVisible();
const firstTerm = adminPage.locator('.ant-list-item').first();
await firstTerm.click();
@@ -299,49 +282,73 @@ test.describe('Right Entity Panel - Admin User Flow', () => {
await expect(domainsSection).toBeVisible();
- const domainEditButton = domainsSection.locator(
- '[data-testid="add-domain"]'
- );
- if (await domainEditButton.isVisible()) {
- await domainEditButton.click();
+ await domainsSection
+ .locator('[data-testid="add-domain"]')
+ .scrollIntoViewIfNeeded();
+ await adminPage.waitForSelector('[data-testid="add-domain"]', {
+ state: 'visible',
+ });
+ await adminPage.locator('[data-testid="add-domain"]').click();
+ const tree = adminPage.getByTestId('domain-selectable-tree');
- const tree = adminPage.getByTestId('domain-selectable-tree');
+ await expect(tree).toBeVisible();
- await expect(tree).toBeVisible();
+ const firstNode = tree
+ .locator('[data-testid="tag-TestDomain"]')
+ .waitFor({ state: 'visible' });
+ await firstNode;
+ await tree.locator('[data-testid="tag-TestDomain"]').click();
+ const updateBtn = adminPage.getByRole('button', { name: 'Update' });
+ if (await updateBtn.isVisible()) {
+ await updateBtn.click();
+ await waitForPatchResponse(adminPage);
- const firstNode = tree
- .locator('[data-testid="tag-TestDomain"]')
- .waitFor({ state: 'visible' });
- await firstNode;
- await tree.locator('[data-testid="tag-TestDomain"]').click();
- const updateBtn = adminPage.getByRole('button', { name: 'Update' });
- if (await updateBtn.isVisible()) {
- await updateBtn.click();
- await waitForPatchResponse(adminPage);
-
- await expect(
- adminPage.getByText(/Domains updated successfully/i)
- ).toBeVisible();
- }
+ await expect(
+ adminPage.getByText(/Domains updated successfully/i)
+ ).toBeVisible();
}
});
test('Tab Navigation - Schema Tab', async ({ adminPage }) => {
- const summaryPanel = adminPage.locator('.entity-summary-panel-container');
- const schemaTab = summaryPanel.getByRole('menuitem', { name: /schema/i });
+ const schemaTab = adminPage.locator('[data-testid="schema-tab"]');
- if (await schemaTab.isVisible()) {
- await schemaTab.click();
- await adminPage.waitForSelector('[data-testid="loader"]', {
- state: 'detached',
- });
+ await schemaTab.click();
+ await adminPage.waitForSelector('[data-testid="loader"]', {
+ state: 'detached',
+ });
- const tabContent = summaryPanel.locator(
- '.entity-summary-panel-tab-content'
+ const tabContent = adminPage.locator(
+ '[data-testid="entity-details-section"]'
+ );
+
+ await expect(tabContent).toBeVisible();
+
+ testEntity.children.forEach(async (child) => {
+ const fieldCard = adminPage.locator(
+ `[data-testid="field-card-${child.name}"]`
);
- await expect(tabContent).toBeVisible();
- }
+ await expect(fieldCard).toBeVisible();
+
+ const dataTypeBadge = fieldCard.locator(
+ `[data-testid="data-type-badge-${child.dataType}"]`
+ );
+
+ await expect(dataTypeBadge).toBeVisible();
+
+ const fieldName = fieldCard.locator(
+ `[data-testid="field-name-${child.name}"]`
+ );
+
+ await expect(fieldName).toHaveText(child.name);
+
+ const fieldDescription = fieldCard.locator(
+ `[data-testid="field-description-${child.name}"]`
+ );
+
+ await expect(fieldDescription).toBeVisible();
+ await expect(fieldDescription).toContainText(child.description);
+ });
});
test('Tab Navigation - Lineage Tab', async ({ adminPage }) => {
@@ -507,9 +514,13 @@ test.describe('Right Entity Panel - Data Steward User Flow', () => {
await dataStewardPage.locator('[data-testid="edit-icon-tier"]').click();
- const tierCard = dataStewardPage.locator('.ant-popover');
+ await dataStewardPage
+ .locator('[data-testid="cards"]')
+ .scrollIntoViewIfNeeded();
- await expect(tierCard).toBeVisible();
+ await expect(
+ dataStewardPage.locator('[data-testid="cards"]')
+ ).toBeVisible();
const tier2Radio = dataStewardPage.getByTestId('radio-btn-Tier2');
await tier2Radio.click();
@@ -538,15 +549,20 @@ test.describe('Right Entity Panel - Data Steward User Flow', () => {
await dataStewardPage
.locator('[data-testid="edit-icon-tags"]')
.scrollIntoViewIfNeeded();
+
await dataStewardPage.waitForSelector('[data-testid="edit-icon-tags"]', {
state: 'visible',
});
await dataStewardPage.locator('[data-testid="edit-icon-tags"]').click();
- const tagsPopover = dataStewardPage.locator('.ant-popover');
+ await dataStewardPage
+ .locator('[data-testid="selectable-list"]')
+ .scrollIntoViewIfNeeded();
- await expect(tagsPopover).toBeVisible();
+ await expect(
+ dataStewardPage.locator('[data-testid="selectable-list"]')
+ ).toBeVisible();
const tagOption = dataStewardPage.getByTitle('PII.Sensitive');
if (await tagOption.isVisible()) {
@@ -588,10 +604,17 @@ test.describe('Right Entity Panel - Data Steward User Flow', () => {
.locator('[data-testid="edit-glossary-terms"]')
.click();
- const glossaryPopover = dataStewardPage.locator('.ant-popover');
+ await dataStewardPage
+ .locator('[data-testid="selectable-list"]')
+ .scrollIntoViewIfNeeded();
- await expect(glossaryPopover).toBeVisible();
+ await expect(
+ dataStewardPage.locator('[data-testid="selectable-list"]')
+ ).toBeVisible();
+ await dataStewardPage.waitForSelector('.ant-list-item', {
+ state: 'visible',
+ });
const firstTerm = dataStewardPage.locator('.ant-list-item').first();
await firstTerm.click();
@@ -607,13 +630,9 @@ test.describe('Right Entity Panel - Data Steward User Flow', () => {
test('Data Steward - Should NOT have permissions for Domains', async ({
dataStewardPage,
}) => {
- const summaryPanel = dataStewardPage.locator(
- '.entity-summary-panel-container'
- );
-
- await expect(summaryPanel.getByTestId('add-domain')).not.toBeVisible();
+ await expect(dataStewardPage.getByTestId('add-domain')).not.toBeVisible();
await expect(
- summaryPanel.getByTestId('edit-data-products')
+ dataStewardPage.getByTestId('edit-data-products')
).not.toBeVisible();
});
@@ -754,7 +773,7 @@ test.describe('Right Entity Panel - Data Consumer User Flow', () => {
}
});
- test('Data Consumer - Should NOT have edit permissions for Owners', async ({
+ test('Data Consumer - Owners Section - Add and Update', async ({
dataConsumerPage,
}) => {
const summaryPanel = dataConsumerPage.locator(
@@ -763,7 +782,36 @@ test.describe('Right Entity Panel - Data Consumer User Flow', () => {
const ownersSection = summaryPanel.locator('.owners-section');
await expect(ownersSection).toBeVisible();
- await expect(summaryPanel.getByTestId('edit-owners')).not.toBeVisible();
+
+ const editButton = ownersSection.getByTestId('edit-owners');
+ if (await editButton.isVisible()) {
+ await editButton.click();
+
+ const popover = dataConsumerPage.getByTestId('select-owner-tabs');
+
+ await expect(popover).toBeVisible();
+
+ await dataConsumerPage.getByRole('tab', { name: 'Users' }).click();
+
+ const firstOwner = dataConsumerPage.getByRole('listitem', {
+ name: 'admin',
+ exact: true,
+ });
+ if (await firstOwner.isVisible()) {
+ await firstOwner.click();
+ const updateBtn = dataConsumerPage.getByRole('button', {
+ name: 'Update',
+ });
+ if (await updateBtn.isVisible()) {
+ await updateBtn.click();
+ await waitForPatchResponse(dataConsumerPage);
+
+ await expect(
+ dataConsumerPage.getByText(/Owners updated successfully/i)
+ ).toBeVisible();
+ }
+ }
+ }
});
test('Data Consumer - Tier Section - Add and Update', async ({
@@ -785,9 +833,13 @@ test.describe('Right Entity Panel - Data Consumer User Flow', () => {
await dataConsumerPage.locator('[data-testid="edit-icon-tier"]').click();
- const tierCard = dataConsumerPage.locator('.ant-popover');
+ await dataConsumerPage
+ .locator('[data-testid="cards"]')
+ .scrollIntoViewIfNeeded();
- await expect(tierCard).toBeVisible();
+ await expect(
+ dataConsumerPage.locator('[data-testid="cards"]')
+ ).toBeVisible();
const tier3Radio = dataConsumerPage.getByTestId('radio-btn-Tier3');
await tier3Radio.click();
@@ -822,9 +874,16 @@ test.describe('Right Entity Panel - Data Consumer User Flow', () => {
await dataConsumerPage.locator('[data-testid="edit-icon-tags"]').click();
- const tagsPopover = dataConsumerPage.locator('.ant-popover');
+ await dataConsumerPage.locator('loader').waitFor({
+ state: 'detached',
+ });
+ await dataConsumerPage
+ .locator('[data-testid="selectable-list"]')
+ .scrollIntoViewIfNeeded();
- await expect(tagsPopover).toBeVisible();
+ await expect(
+ dataConsumerPage.locator('[data-testid="selectable-list"]')
+ ).toBeVisible();
const tagOption = dataConsumerPage.getByTitle('PersonalData.Personal');
if (await tagOption.isVisible()) {
@@ -868,9 +927,13 @@ test.describe('Right Entity Panel - Data Consumer User Flow', () => {
.locator('[data-testid="edit-glossary-terms"]')
.click();
- const glossaryPopover = dataConsumerPage.locator('.ant-popover');
+ await dataConsumerPage
+ .locator('[data-testid="selectable-list"]')
+ .scrollIntoViewIfNeeded();
- await expect(glossaryPopover).toBeVisible();
+ await expect(
+ dataConsumerPage.locator('[data-testid="selectable-list"]')
+ ).toBeVisible();
const firstTerm = dataConsumerPage.locator('.ant-list-item').first();
await firstTerm.click();
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataAssetSummaryPanelV1/DataAssetSummaryPanelV1.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataAssetSummaryPanelV1/DataAssetSummaryPanelV1.tsx
index 0e7034ff10f..911c8e675ab 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/DataAssetSummaryPanelV1/DataAssetSummaryPanelV1.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/DataAssetSummaryPanelV1/DataAssetSummaryPanelV1.tsx
@@ -268,19 +268,38 @@ export const DataAssetSummaryPanelV1 = ({
break;
}
};
- const { editDomainPermission, editOwnerPermission, editTierPermission } =
- useMemo(
- () => ({
- editDomainPermission: entityPermissions?.EditAll && !dataAsset.deleted,
- editOwnerPermission:
- (entityPermissions?.EditAll || entityPermissions?.EditOwners) &&
- !dataAsset.deleted,
- editTierPermission:
- (entityPermissions?.EditAll || entityPermissions?.EditTier) &&
- !dataAsset.deleted,
- }),
- [entityPermissions, dataAsset]
- );
+ const {
+ editDomainPermission,
+ editOwnerPermission,
+ editTierPermission,
+ editTagsPermission,
+ editDataProductPermission,
+ editDescriptionPermission,
+ editGlossaryTermsPermission,
+ } = useMemo(
+ () => ({
+ editDomainPermission: entityPermissions?.EditAll && !dataAsset.deleted,
+ editDescriptionPermission:
+ (entityPermissions?.EditAll || entityPermissions?.EditDescription) &&
+ !dataAsset.deleted,
+ editGlossaryTermsPermission:
+ (entityPermissions?.EditGlossaryTerms || entityPermissions?.EditAll) &&
+ !dataAsset.deleted,
+ editOwnerPermission:
+ (entityPermissions?.EditAll || entityPermissions?.EditOwners) &&
+ !dataAsset.deleted,
+ editTierPermission:
+ (entityPermissions?.EditAll || entityPermissions?.EditTier) &&
+ !dataAsset.deleted,
+ editTagsPermission:
+ (entityPermissions?.EditAll || entityPermissions?.EditTags) &&
+ !dataAsset.deleted,
+ editDataProductPermission:
+ entityPermissions?.EditAll && !dataAsset.deleted,
+ }),
+ [entityPermissions, dataAsset]
+ );
+
const init = useCallback(async () => {
// Do not reset permissions to null when id is temporarily missing during re-renders
if (!dataAsset.id || isTourPage) {
@@ -380,9 +399,7 @@ export const DataAssetSummaryPanelV1 = ({
)}