Skip to content

Fixes #32413: gate CustomPropertiesPanel on type resource permissions - #33280

Open
Rohit0301 wants to merge 6 commits into
mainfrom
custom-properties-panel-fix-plan
Open

Rohit0301 wants to merge 6 commits into
mainfrom
custom-properties-panel-fix-plan

Conversation

@Rohit0301

Copy link
Copy Markdown
Contributor

Describe your changes:

Fixes #32413

The AI-mode Custom Properties panel (CustomPropertiesPanel) was gating all entity-type cards and the sidebar nav item on isAdminUser, ignoring the backend's policy-engine permission on the type resource. Non-admin users with a valid type-resource policy could call PUT /api/v1/metadata/types/{id} successfully via the API but saw an empty panel in the UI.

Additionally, CustomPropertiesDetailPage read permission[Operation.EditAll] directly (raw access, banned by openmetadata-permissions/no-raw-permission-access) and collapsed all three actions into one flag, mismatching the backend's per-operation authorization.

Changes (AI-mode panel only — legacy Settings route untouched):

  • CustomPropertiesLandingPage.tsx / CustomPropertiesPanel.tsx: Replace isAdminUser-based filter with userPermissions.hasViewPermissions(ResourceEntity.TYPE, permissions). Users with ViewAll or ViewBasic on type see all entity-type cards; others see nothing.
  • ProfilePage.tsx: Gate WORKSPACE_NAV_ITEMS (the "Custom Properties" sidebar entry) on the same permission, so users without type view access never see the nav item.
  • CustomPropertiesDetailPage.tsx: Replace raw permission[Operation.EditAll] with getDerivedPermissionFlags(permission) and split into three semantically correct flags — canCreate || canEditAll for Add, canEditAll for Edit, canDelete || canEditAll for Delete — matching what TypeResource evaluates on the backend.

Type of change:

  • Bug fix

High-level design:

The backend authorizes custom property management via MetadataOperation.CREATE on the type resource (TypeResource.addOrUpdateProperty). The type resource is entirely separate from data-entity resources (Table, Dashboard, etc.) — EditAll on Table does not grant any permission on type.

The fix has two layers:

  1. Visibility gate (ProfilePage + CustomPropertiesLandingPage + CustomPropertiesPanel): uses userPermissions.hasViewPermissions(ResourceEntity.TYPE, permissions) — the same utility already used for Services, Teams, and other settings categories — to control whether the nav item and entity cards render.
  2. Action gate (CustomPropertiesDetailPage): getEntityPermission(ResourceEntity.TYPE, entityType.id) already fetched the correctly-scoped OperationPermission; getDerivedPermissionFlags derives named flags from it without needing the resource type again. Three flags replace the single hasEditPermission boolean.

No legacy code (GlobalSettingsClassBase, SettingsRouter, CustomPropertiesPageV1) was changed.

Tests:

Use cases covered

  • Non-admin user with no type permissions → "Custom Properties" nav item absent from AI profile sidebar
  • Non-admin user with [Create, Delete, EditAll, ViewAll] on type → nav visible, all entity-type cards shown, Add + Edit + Delete buttons visible on Table detail page
  • Admin user → all existing CRUD flows unchanged (add String/Date/ERL, edit display name, delete via modal)
  • User with ViewAll only on type (read-only) → nav visible, landing shows cards, zero action buttons (documented in plan; manual-verified scenario)
  • User with EditAll on Table data resource but no type write permissions → no action buttons (data-resource grants do not bleed into type-resource checks)

Unit tests

  • Not added — permission derivation logic is covered by existing PermissionDerivation.test.ts; the UI wiring is exercised by the Playwright tests below.

Backend integration tests

  • Not applicable (no backend changes)

Ingestion integration tests

  • Not applicable (no ingestion changes)

Playwright (UI) tests

  • Added Playwright E2E tests
  • File: openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/AIMode/CustomPropertiesPanel.spec.ts
  • New describe blocks:
    • Custom Properties Panel — user without type permissions (dataConsumer storageState)
    • Custom Properties Panel — non-admin user with type permissions (creates policy/role/user via admin API in beforeAll, tears down in afterAll)

Manual testing performed

  1. Created a role with policy: Resources: type, Operations: [Create, Delete, EditAll, ViewAll], Effect: Allow
  2. Assigned role to a non-admin user; logged in as that user in AI mode
  3. Confirmed "Custom Properties" nav item appeared in the AI profile sidebar
  4. Opened landing page — all entity-type cards (Table, Dashboard, Pipeline, …) rendered
  5. Navigated to Table detail — Add, Edit, Delete buttons all visible; existing CRUD operations worked
  6. Logged in as a user with EditAll on Table + ViewAll on All (no type write) — nav visible, detail page accessible, zero action buttons confirmed
  7. Logged in as dataConsumer (no type permissions) — "Custom Properties" nav item absent

UI screen recording / screenshots:

TODO: attach screen recording — opening as draft until recording is added.

Checklist:

  • I have read the CONTRIBUTING document.
  • My PR title is Fixes <issue-number>: <short explanation>
  • My PR is linked to a GitHub issue via Fixes #32413 above.
  • I have commented on my code, particularly in hard-to-understand areas.
  • For JSON Schema changes: Not applicable.
  • For UI changes: screen recording TODO (opening as draft).
  • I have added tests (Playwright) and listed them above.
  • I have added a test that covers the exact scenario we are fixing.

Replace isAdminUser gate with userPermissions.hasViewPermissions(ResourceEntity.TYPE)
in CustomPropertiesLandingPage, CustomPropertiesPanel, and ProfilePage so non-admin
users holding a type-resource policy can access the AI-mode Custom Properties panel.

Split the single raw EditAll read in CustomPropertiesDetailPage into three derived
flags (canCreate, canDelete, canEditAll) via getDerivedPermissionFlags, matching the
backend's per-operation authorization on TypeResource.

Add Playwright permission tests: dataConsumer (no type access) sees no nav item;
non-admin with full type access sees all entity cards and all action buttons.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions github-actions Bot added the UI UI specific issues label Sep 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

@Rohit0301
Rohit0301 marked this pull request as ready for review September 14, 2026 11:58
@github-actions

Copy link
Copy Markdown
Contributor

🔄 Playwright impact map auto-refreshed

This PR touched specs or UI source that changed the source→spec routing map. I regenerated .github/playwright/impact-map.generated.json and pushed the diff to this branch.

- source entries: 775 → 775
- 0 added, 0 removed, 5 changed spec-list

Entries whose spec list changed:
  openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/CreateUser/CreateUser.component.tsx
  openmetadata-ui/src/main/resources/ui/src/pages/LoginPage/SignInPage.tsx
  openmetadata-ui/src/main/resources/ui/src/pages/ResetPassword/ResetPassword.component.tsx
  openmetadata-ui/src/main/resources/ui/src/pages/SignUp/BasicSignup.component.tsx
  openmetadata-ui/src/main/resources/ui/src/pages/TeamsPage/AddTeamForm.tsx

What is this file? It is the auto-generated half of Playwright's PR planner. It routes "if source X changes, run specs Y" by walking spec imports and cross-referencing getByTestId strings. Hand-authored routing in impact-map.json always wins on conflict.

What if I want to regenerate locally instead? Run this before pushing your next change to skip the bot commit:

python3 .github/scripts/generate_playwright_impact_map.py
git add .github/playwright/impact-map.generated.json
git commit --amend --no-edit  # or a separate commit

@github-actions

Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

@github-actions

github-actions Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

🔴 Playwright Results — workflow failed

Validated commit f25dd20400b217c7d5193ec87cb938fcb11a85d4 in Playwright run 34883470584, attempt 1.

✅ 4492 passed · ❌ 4 failed · 🟡 13 flaky · ⏭️ 1 skipped · 🧰 0 lifecycle flaky

Action needed: test(s) failed on every attempt against this PR’s validated commit — see Genuine Failures below. These are test failures, not CI budget or infrastructure issues.

Performance

Blocking targets: ✅ met · Optimization targets: 🟡 in progress

Shard-job maxima below are not the full workflow wall time; the linked run includes build, fixture, planning, and reporting.

🕒 Full workflow signal wall (to summary) 38m 19s

⏱️ Max setup 4m 12s · max shard execution 22m 0s · max shard-job elapsed before upload 25m 38s · reporting 29s

🌐 218.74 requests/attempt · 2.24 app boots/UI scenario · 33.41% common-shard skew

Optimization targets still in progress:

  • Common shard skew was 33.41% (convergence target: at most 15%).
  • Browser traffic was 218.74 requests per attempt (convergence target: fewer than 200).
  • Application boot ratio was 2.24 per UI scenario (10688 boots / 4770 scenarios; convergence target: at most 1).
Shard Passed Failed Flaky Skipped Lifecycle failed Lifecycle flaky
✅ Shard advanced-search-01 130 0 0 0 0 0
🟡 Shard chromium-01 168 0 2 0 0 0
✅ Shard chromium-02 147 0 0 0 0 0
🔴 Shard chromium-03 156 1 0 0 0 0
✅ Shard chromium-04 171 0 0 0 0 0
✅ Shard chromium-05 180 0 0 0 0 0
🟡 Shard chromium-06 136 0 1 0 0 0
✅ Shard chromium-07 198 0 0 0 0 0
✅ Shard chromium-08 172 0 0 0 0 0
✅ Shard chromium-09 164 0 0 0 0 0
🔴 Shard chromium-10 150 2 2 0 0 0
✅ Shard chromium-11 150 0 0 0 0 0
🟡 Shard chromium-12 188 0 2 0 0 0
🟡 Shard chromium-13 139 0 1 0 0 0
✅ Shard chromium-14 179 0 0 0 0 0
✅ Shard chromium-15 187 0 0 0 0 0
🔴 Shard chromium-16 150 1 1 0 0 0
✅ Shard chromium-17 159 0 0 1 0 0
✅ Shard chromium-18 163 0 0 0 0 0
🟡 Shard chromium-19 164 0 1 0 0 0
🟡 Shard chromium-20 146 0 2 0 0 0
✅ Shard chromium-21 177 0 0 0 0 0
🟡 Shard chromium-22 157 0 1 0 0 0
✅ Shard chromium-23 162 0 0 0 0 0
✅ Shard chromium-24 171 0 0 0 0 0
✅ Shard data-asset-rules-01 65 0 0 0 0 0
✅ Shard domain-isolation-01 16 0 0 0 0 0
✅ Shard global-state-01 34 0 0 0 0 0
✅ Shard import-export-01 66 0 0 0 0 0
✅ Shard import-export-02 49 0 0 0 0 0
✅ Shard import-export-03 35 0 0 0 0 0
✅ Shard ingestion-01 37 0 0 0 0 0
✅ Shard ingestion-02 57 0 0 0 0 0
✅ Shard reindex-01 28 0 0 0 0 0
✅ Shard search-01 12 0 0 0 0 0
✅ Shard search-rbac-01 29 0 0 0 0 0

Genuine Failures (failed on all attempts)

Features/AIMode/CustomPropertiesPanel.spec.tsCustom Properties nav item is not visible in sidebar (shard chromium-03)
Error: �[2mexpect(�[22m�[31mlocator�[39m�[2m).not.�[22mtoBeVisible�[2m(�[22m�[2m)�[22m failed  Locator:  getByTestId('profile-nav-custom-properties') Expected: not visible Received: visible Timeout:  15000ms  Call log: �[2m  - Expect "not toBeVisible" with timeout 15000ms�[22m �[2m  - waiting for getByTestId('profile-nav-custom-properties')�[22m �[2m    19 × locator resolved to <button type="button" data-testid="profile-nav-custom-properties" class="ai-profile-page__nav-item tw:mb-1 tw:flex tw:w-full tw:cursor-pointer tw:items-center tw:gap-2 tw:rounded-md tw:px-3 tw:py-2 tw:text-left tw:transition tw:duration-100 tw:hover:bg-utility-gray-200 tw:text-text-secondary tw:hover:bg-primary_hover">…</button>�[22m �[2m       - unexpected value "visible"�[22m 
Features/AIMode/CustomPropertiesPanel.spec.tssidebar shows Custom Properties nav and landing page shows entity cards (shard chromium-10)
Error: ENOENT: no such file or directory, open 'playwright/.auth/temp-type-permissions-user.json'
Features/AIMode/CustomPropertiesPanel.spec.tsdetail page shows Add, Edit, Delete buttons (shard chromium-10)
Error: ENOENT: no such file or directory, open 'playwright/.auth/temp-type-permissions-user.json'
Pages/Lineage/DataAssetLineage.spec.tsverify create lineage for entity - Worksheet (shard chromium-16)
Error: �[2mexpect(�[22m�[31mreceived�[39m�[2m).�[22mtoBeTruthy�[2m()�[22m  Received: �[31mfalse�[39m
🟡 13 flaky test(s) (passed on retry)
  • Features/ContextCenterArticles.spec.tsText formatting (shard chromium-01, 1 retry)
  • Features/ContextCenterArticles.spec.tsText formatting (shard chromium-01, 1 retry)
  • Features/DomainTierCertificationVoting.spec.tsDomain - Tier assign, update, and remove (shard chromium-06, 1 retry)
  • Features/UserProfileOnlineStatus.spec.tsShould show online status badge on user profile for active users (shard chromium-10, 1 retry)
  • Features/UserProfileOnlineStatus.spec.tsShould show "Active recently" for users active within last hour (shard chromium-10, 1 retry)
  • Pages/Lineage/DataAssetLineage.spec.tsverify create lineage for entity - File (shard chromium-12, 1 retry)
  • Pages/UserDetails.spec.tsAdmin user can edit teams from the user profile (shard chromium-12, 1 retry)
  • Flow/Tour.spec.tsTour should work from help section (shard chromium-13, 1 retry)
  • Flow/ConditionalPermissions.spec.tsUser with owner permission can only view owned Search Services (shard chromium-16, 1 retry)
  • Features/DomainFilterQueryFilter.spec.tsMulti-nested domain hierarchy: filters should scope correctly at every level (shard chromium-19, 1 retry)
  • Pages/Lineage/DataAssetLineage.spec.tsverify create lineage for entity - Stored Procedure (shard chromium-20, 1 retry)
  • Pages/Tag.spec.tsVerify Owner Add Delete (shard chromium-20, 1 retry)
  • Flow/ConditionalPermissions.spec.tsUser with owner permission can only view owned Storage Services (shard chromium-22, 1 retry)

📦 Download artifacts

How to debug locally
# Download playwright-test-results-<shard> artifact and unzip
npx playwright show-trace path/to/trace.zip    # view trace

Rohit0301 and others added 2 commits September 15, 2026 18:38
… use UserClass/PolicyClass/RolesClass helpers

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

🔄 Playwright impact map auto-refreshed

This PR touched specs or UI source that changed the source→spec routing map. I regenerated .github/playwright/impact-map.generated.json and pushed the diff to this branch.

- source entries: 775 → 775
- 0 added, 0 removed, 9 changed spec-list

Entries whose spec list changed:
  openmetadata-ui/src/main/resources/ui/playwright/support/access-control/PoliciesClass.ts
  openmetadata-ui/src/main/resources/ui/playwright/support/access-control/RolesClass.ts
  openmetadata-ui/src/main/resources/ui/playwright/support/user/UserClass.ts
  openmetadata-ui/src/main/resources/ui/playwright/utils/admin.ts
  openmetadata-ui/src/main/resources/ui/src/components/Settings/Users/CreateUser/CreateUser.component.tsx
  openmetadata-ui/src/main/resources/ui/src/pages/LoginPage/SignInPage.tsx
  openmetadata-ui/src/main/resources/ui/src/pages/ResetPassword/ResetPassword.component.tsx
  openmetadata-ui/src/main/resources/ui/src/pages/SignUp/BasicSignup.component.tsx
  openmetadata-ui/src/main/resources/ui/src/pages/TeamsPage/AddTeamForm.tsx

What is this file? It is the auto-generated half of Playwright's PR planner. It routes "if source X changes, run specs Y" by walking spec imports and cross-referencing getByTestId strings. Hand-authored routing in impact-map.json always wins on conflict.

What if I want to regenerate locally instead? Run this before pushing your next change to skip the bot commit:

python3 .github/scripts/generate_playwright_impact_map.py
git add .github/playwright/impact-map.generated.json
git commit --amend --no-edit  # or a separate commit

@gitar-bot

gitar-bot Bot commented Sep 15, 2026

Copy link
Copy Markdown
Code Review ⚠️ Changes requested 1 resolved / 3 findings

Fixes custom properties panel visibility and action gates to respect backend type resource permissions instead of only checking isAdminUser, but two issues must be resolved before merge.

canDelete is missing from the renderRow useCallback dependency array (line 265 of CustomPropertiesDetailPage.tsx), causing the Delete button to remain hidden for users with Delete permission but no EditAll/Create. Add canDelete and canCreate to the deps. Additionally, comments in the ViewAll-only Playwright test (lines 770–777) contradict the assertions and claim buttons are visible when they should be absent; update them to reflect read-only behavior.

⚠️ Bug: canDelete missing from renderRow useCallback deps

📄 openmetadata-ui/src/main/resources/ui/src/components/discovery/personal-space/Profile/panels/CustomPropertiesPanel/CustomPropertiesDetailPage.tsx:239-253

This commit changes the delete-button gate from canEditAll to canDelete (lines 239, 250), but renderRow's useCallback dependency array (line 265) still only lists [canEditAll, onEditProperty, t]canDelete is not included. permission starts as DEFAULT_ENTITY_PERMISSION (all false) and is populated asynchronously after getEntityPermission resolves. For a user granted Delete but not EditAll/Create, canEditAll never changes value across the async update, so the memoized renderRow is never recreated and captures the stale canDelete = false, hiding the Delete button despite valid permission. Add canDelete (and canCreate if used) to the dependency array.

Include canDelete in renderRow's useCallback dependency array so the row re-renders when delete permission resolves.
[canDelete, canEditAll, onEditProperty, t]
💡 Quality: Stale comments contradict assertions in ViewAll-only test

📄 openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/AIMode/CustomPropertiesPanel.spec.ts:770-777

In the ViewAll-only describe block the comments were copied from the full-access test and now contradict the code: line 770 says "User has Create → Add button visible" immediately before expect(...).not.toBeVisible(), and line 773 says "Edit and Delete buttons visible" before asserting they are not visible. Update the comments to reflect that a ViewAll-only user has no action buttons, to avoid misleading future readers.

✅ 1 resolved
Edge Case: Action-button gates don't match the endpoints they trigger

📄 openmetadata-ui/src/main/resources/ui/src/components/discovery/personal-space/Profile/panels/CustomPropertiesPanel/CustomPropertiesDetailPage.tsx:249-257 📄 openmetadata-ui/src/main/resources/ui/src/components/discovery/personal-space/Profile/panels/CustomPropertiesPanel/CustomPropertiesDetailPage.tsx:267-268
The Add button is gated on canCreate || canEditAll, but the Add flow calls addPropertyToEntityPUT /api/v1/metadata/types/{id}, which the backend authorizes strictly on MetadataOperation.CREATE (TypeResource.addOrUpdateProperty). Since EditAll does not imply Create in the policy engine, an EditAll-only user on type sees the Add button but gets a 403 on submit. Similarly, the Delete button is gated on canDelete || canEditAll, but delete is performed via updateTypePATCH /api/v1/metadata/types/{id} (removing the property from customProperties), which is authorized as an edit on the type entity — not the Delete operation (which deletes the whole type). A user holding only Delete on type (without edit rights) would see the button but the PATCH could 403. Consider aligning each gate with the operation its endpoint actually requires. The bundled E2E test grants all four operations at once, so it cannot catch these narrower mismatches.

🤖 Prompt for agents
Code Review: Fixes custom properties panel visibility and action gates to respect backend `type` resource permissions instead of only checking `isAdminUser`, but two issues must be resolved before merge.
  
  `canDelete` is missing from the `renderRow` useCallback dependency array (line 265 of CustomPropertiesDetailPage.tsx), causing the Delete button to remain hidden for users with Delete permission but no EditAll/Create. Add `canDelete` and `canCreate` to the deps. Additionally, comments in the ViewAll-only Playwright test (lines 770–777) contradict the assertions and claim buttons are visible when they should be absent; update them to reflect read-only behavior.

1. ⚠️ Bug: canDelete missing from renderRow useCallback deps
   Files: openmetadata-ui/src/main/resources/ui/src/components/discovery/personal-space/Profile/panels/CustomPropertiesPanel/CustomPropertiesDetailPage.tsx:239-253

   This commit changes the delete-button gate from `canEditAll` to `canDelete` (lines 239, 250), but `renderRow`'s `useCallback` dependency array (line 265) still only lists `[canEditAll, onEditProperty, t]` — `canDelete` is not included. `permission` starts as `DEFAULT_ENTITY_PERMISSION` (all false) and is populated asynchronously after `getEntityPermission` resolves. For a user granted `Delete` but not `EditAll`/`Create`, `canEditAll` never changes value across the async update, so the memoized `renderRow` is never recreated and captures the stale `canDelete = false`, hiding the Delete button despite valid permission. Add `canDelete` (and `canCreate` if used) to the dependency array.

   Fix (Include canDelete in renderRow's useCallback dependency array so the row re-renders when delete permission resolves.):
   [canDelete, canEditAll, onEditProperty, t]

2. 💡 Quality: Stale comments contradict assertions in ViewAll-only test
   Files: openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/AIMode/CustomPropertiesPanel.spec.ts:770-777

   In the ViewAll-only describe block the comments were copied from the full-access test and now contradict the code: line 770 says "User has Create → Add button visible" immediately before `expect(...).not.toBeVisible()`, and line 773 says "Edit and Delete buttons visible" before asserting they are not visible. Update the comments to reflect that a ViewAll-only user has no action buttons, to avoid misleading future readers.

Review coverage

Rules No rules evaluated

Functional validation Not enabled · Set up

Auto-approval Not enabled · Set up

Options

Display: compact → Counting what did not apply, without listing it.

Comment with these commands to change the behavior for this request:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Powered by Gitar — free for open source

Comment on lines +239 to +253
{(canEditAll || canDelete) && (
<Box direction="row" gap={1}>
<Button
aria-label={t('label.edit')}
color="tertiary"
iconLeading={Edit}
size="xs"
onPress={() => onEditProperty(property)}
/>
<Button
aria-label={t('label.delete')}
color="tertiary-destructive"
iconLeading={Delete}
size="xs"
onPress={() => setPropertyToDelete(property)}
/>
{canEditAll && (
<Button
aria-label={t('label.edit')}
color="tertiary"
iconLeading={Edit}
size="xs"
onPress={() => onEditProperty(property)}
/>
)}
{canDelete && (
<Button
aria-label={t('label.delete')}
color="tertiary-destructive"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Bug: canDelete missing from renderRow useCallback deps

This commit changes the delete-button gate from canEditAll to canDelete (lines 239, 250), but renderRow's useCallback dependency array (line 265) still only lists [canEditAll, onEditProperty, t]canDelete is not included. permission starts as DEFAULT_ENTITY_PERMISSION (all false) and is populated asynchronously after getEntityPermission resolves. For a user granted Delete but not EditAll/Create, canEditAll never changes value across the async update, so the memoized renderRow is never recreated and captures the stale canDelete = false, hiding the Delete button despite valid permission. Add canDelete (and canCreate if used) to the dependency array.

Include canDelete in renderRow's useCallback dependency array so the row re-renders when delete permission resolves.:

[canDelete, canEditAll, onEditProperty, t]
  • Apply fix

Check the box to apply the fix or reply for a change | Was this helpful? React with 👍 / 👎

Comment on lines +770 to +777
// User has Create → Add button visible.
await expect(page.getByTestId('add-custom-property-btn')).not.toBeVisible();

// User has EditAll + Delete → Edit and Delete buttons visible on the seeded row.
const row = page.locator('tr').filter({ hasText: customPropertyName });
await expect(row).toBeVisible();
await expect(row.getByRole('button', { name: 'Edit' })).not.toBeVisible();
await expect(row.getByRole('button', { name: 'Delete' })).not.toBeVisible();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Quality: Stale comments contradict assertions in ViewAll-only test

In the ViewAll-only describe block the comments were copied from the full-access test and now contradict the code: line 770 says "User has Create → Add button visible" immediately before expect(...).not.toBeVisible(), and line 773 says "Edit and Delete buttons visible" before asserting they are not visible. Update the comments to reflect that a ViewAll-only user has no action buttons, to avoid misleading future readers.

Was this helpful? React with 👍 / 👎

@github-actions

Copy link
Copy Markdown
Contributor

❌ UI Checkstyle Failed

❌ ESLint + Prettier + Organise Imports (src)

One or more source files have linting or formatting issues.

Affected files
  • openmetadata-ui/src/main/resources/ui/src/components/discovery/personal-space/Profile/panels/CustomPropertiesPanel/CustomPropertiesDetailPage.test.tsx
    • openmetadata-ui/src/main/resources/ui/src/components/discovery/personal-space/Profile/panels/CustomPropertiesPanel/CustomPropertiesLandingPage.test.tsx

❌ Playwright - Guardrails + ESLint + Prettier + Organise Imports

Either a Playwright test file has linting/formatting issues, or a guardrail check failed: ESLint rule unit tests, a new guardrail violation, a stale suppression entry (its violation was fixed but the baseline was not pruned), a blanket eslint-disable, or a stale generated rule table. For the guardrail cases run yarn lint:playwright:suppressions in openmetadata-ui/src/main/resources/ui and commit the pruned eslint-suppressions.json, then yarn test:eslint-rules && node scripts/generate-playwright-rule-table.mjs --check.

Affected files
  • openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/AIMode/CustomPropertiesPanel.spec.ts

🔍 ESLint findings in this PR's files — 0 error(s), 1 warning(s)

Errors block the build. Warnings do not yet — they are rules whose backlog is still
being worked down, listed so this PR does not add to it. See docs/ui-code-quality-gate.md.

0 error(s), 1 warning(s) across 1 changed file(s).

Count Rule
1 react-hooks/exhaustive-deps
All findings
Location Rule Message
🟡 src/components/discovery/personal-space/Profile/panels/CustomPropertiesPanel/CustomPropertiesDetailPage.tsx:265:5 react-hooks/exhaustive-deps React Hook useCallback has a missing dependency: 'canDelete'. Either include it or remove the dependency array.

Fix locally (fast - only checks files changed in this branch):

make ui-checkstyle-changed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

safe to test Add this label to run secure Github workflows on PRs UI UI specific issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Custom Properties settings are gated on isAdminUser in the UI while the backend authorizes them through policies on the type resource

1 participant