Skip to content

feat(ui): smart OrgSwitcher that filters by permission key - #21366

Merged
banana-three-join merged 3 commits into
meshery:masterfrom
rishiraj38:rishiraj/smart-org-switcher-5885
Aug 13, 2026
Merged

banana-three-join merged 3 commits into
meshery:masterfrom
rishiraj38:rishiraj/smart-org-switcher-5885

Conversation

@rishiraj38

@rishiraj38 rishiraj38 commented Aug 13, 2026 •

Copy link
Copy Markdown
Contributor

Description

When a user hits a 403 page, they currently see a generic error with no way to recover. This PR adds a smart OrgSwitcher that checks which of the user's other organizations have the required permission and offers a one-click switch.

The permission check uses useLazyGetUserKeysQuery from @meshery/schemas/mesheryApi (meshery routes all API calls through meshery server, not directly to cloud). The core filtering logic lives in sistent's useAccessibleOrgs hook — the meshery wrapper just passes the right trigger and org data.

Changes:

  • OrgSwitcher: queries keys per org in parallel, shows filtered dropdown with loading/empty states
  • CurrentSession: renders PermissionSessionContext showing user, org, role, and the missing key
  • DefaultError: conditionally renders session/options panel only when permissionKey is provided — system errors (org fetch, abilities) no longer show misleading permission UI
  • useAccessibleOrgs: thin wrapper passing mesheryApi trigger to sistent's shared hook

Related: layer5io/meshery-cloud#5971
Sistent PR: layer5io/sistent#1796

Screen.Recording.2026-08-13.at.3.03.52.PM.mov

Signed commits

  • Yes, I signed my commits.

Summary by CodeRabbit

  • New Features
    • Organization switching now displays only organizations accessible under the required permission.
    • Added loading and no-access states to the organization selector.
    • The current organization remains visible and is marked as unavailable for selection.
    • Permission-aware organization selection is supported on error pages.

On the 403 page, the org switcher now only shows organizations where
the user holds the required permission. Uses the shared useAccessibleOrgs
hook from @sistent/sistent with a thin wrapper wiring meshery's data sources.

- Loading state while checking per-org permissions
- Empty state when no accessible orgs found
- Current org shown as disabled (current) label in dropdown

Relates to layer5io/meshery-cloud#5885

Signed-off-by: Rishi Raj <[email protected]>
@github-actions github-actions Bot added the component/ui User Interface label Aug 13, 2026
@coderabbitai

coderabbitai Bot commented Aug 13, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7da19647-9f13-4938-849e-438357f9af44

📥 Commits

Reviewing files that changed from the base of the PR and between 9ac9a0e and a6de558.

📒 Files selected for processing (1)
  • ui/utils/hooks/useAccessibleOrgs.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • ui/utils/hooks/useAccessibleOrgs.ts

📝 Walkthrough

Walkthrough

OrgSwitcher now filters organizations by an optional permission key. It adds loading and no-access states, keeps the active organization visible as disabled, and receives the permission key from DefaultError.

Changes

Permission-aware organization switching

Layer / File(s) Summary
Accessible organization data
ui/utils/hooks/useAccessibleOrgs.ts
Adds useAccessibleOrgs, which supplies Meshery organization data and delegates permission filtering to Sistent.
Error-page switcher integration
ui/components/general/error-404/OrgSwitcher.tsx, ui/components/general/error-404/index.tsx
Passes permissionKey into OrgSwitcher, renders loading and no-access states, and selects organizations from the accessible list. The active organization remains visible as a disabled item.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Mergeability Score: ⚪ Minimal · up to a6de5

The organization switcher now shows only organizations matching the required permission; no actionable merge-blocking risk remains after normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant DefaultError
  participant OrgSwitcher
  participant useAccessibleOrgs
  participant Sistent
  participant OrganizationMutation
  DefaultError->>OrgSwitcher: pass permissionKey
  OrgSwitcher->>useAccessibleOrgs: request accessible organizations
  useAccessibleOrgs->>Sistent: evaluate organization permissions
  Sistent-->>useAccessibleOrgs: return accessible organizations and readiness state
  useAccessibleOrgs-->>OrgSwitcher: provide filtered organizations
  OrgSwitcher->>OrganizationMutation: select organization
  OrganizationMutation-->>OrgSwitcher: return selection result
Loading

Possibly related PRs

  • meshery/meshery#21076: Both changes propagate permissionKey values to permission-aware UI components.
  • meshery/meshery#21104: Both changes use the shared permission-key authorization pattern in UI components.
  • meshery/meshery#21226: Both changes pass permissionKey through DefaultError and error-page organization handling.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: filtering the OrgSwitcher by permission key.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

Commit SHA: adc39db8e317c97eb93222fb96288cb9cf5d68a1

END-TO-END TESTS

  • Testing started at: August 13th 2026, 10:27:29 am

📦 Test Result Summary

  • ✅ 68 passed
  • ❌ 1 failed
  • ⚠️ 0 flaked
  • ⏩ 17 skipped

⌛ Duration: 5 minutes and 22 seconds

Overall Result: 👎 Some tests failed.

[Show/Hide] Test Result Details
Test Provider Browser Test Case Tags Result
1 Local chromium-local-provider Aggregation Charts are displayed ✅
2 Local chromium-local-provider alias resolution relationship ✅
3 Local chromium-local-provider alias resolution relationship ✅
4 Local chromium-local-provider alias resolution relationship ✅
5 Local chromium-local-provider alias resolution relationship ✅
6 Local chromium-local-provider alias resolution relationship ✅
7 Local chromium-local-provider alias resolution relationship ✅
8 Local chromium-local-provider alias resolution relationship ✅
9 Local chromium-local-provider alias resolution relationship ✅
10 Local chromium-local-provider alias resolution relationship ✅
11 Local chromium-local-provider Apply a watch-scope and broker service override to a connected cluster controllers-config, cut:api-connection-controllers-config, client:ui ➖
12 Local chromium-local-provider Charts (Grafana) page loads ➖
13 Local chromium-local-provider Clear a per-connection override and the server-wide default applies again controllers-config, cut:api-connection-controllers-config, client:ui ➖
14 Local chromium-local-provider config patching correctness relationship ✅
15 Local chromium-local-provider config patching correctness relationship ✅
16 Local chromium-local-provider config patching correctness relationship ✅
17 Local chromium-local-provider config patching correctness relationship ✅
18 Local chromium-local-provider config patching correctness relationship ✅
19 Local chromium-local-provider config patching correctness relationship ✅
20 Local chromium-local-provider config patching correctness relationship ✅
21 Local chromium-local-provider config patching correctness relationship ✅
22 Local chromium-local-provider config patching correctness relationship ✅
23 Local chromium-local-provider Configure Existing Istio adapter through Mesh Adapter URL from Management page unstable ⚠️
24 Local chromium-local-provider Connect to Meshery Istio Adapter and configure it ➖
25 Local chromium-local-provider Create a Model ✅
26 Local chromium-local-provider Delete Kubernetes cluster connections connections, TC-1063, cut:ui-connections-table, client:ui ➖
27 Local chromium-local-provider Discover multiple kubeconfig contexts in the wizard connections, TC-1014, cut:ui-connection-wizard, client:ui ✅
28 Local chromium-local-provider Drop the reduced-reach statements in Operator mode controllers-config, cut:ui-controllers-editor, client:ui ➖
29 Local chromium-local-provider evaluation idempotency relationship ✅
30 Local chromium-local-provider evaluation idempotency relationship ✅
31 Local chromium-local-provider evaluation idempotency relationship ✅
32 Local chromium-local-provider evaluation idempotency relationship ✅
33 Local chromium-local-provider evaluation idempotency relationship ✅
34 Local chromium-local-provider evaluation idempotency relationship ✅
35 Local chromium-local-provider evaluation idempotency relationship ✅
36 Local chromium-local-provider evaluation idempotency relationship ✅
37 Local chromium-local-provider evaluation idempotency relationship ✅
38 Local chromium-local-provider Expose the LoadBalancer-only service fields only while the service type is LoadBalancer controllers-config, cut:ui-controllers-editor, client:ui ➖
39 Local chromium-local-provider Import a Model via CSV Import ✅
40 Local chromium-local-provider Import a Model via File Import ✅
41 Local chromium-local-provider Import a Model via Url Import ✅
42 Local chromium-local-provider Logout from current user session ✅
43 Local chromium-local-provider Metrics (Prometheus) page loads ✅
44 Local chromium-local-provider Open the Kubernetes connection wizard and show kubeconfig upload connections, cut:ui-connection-wizard, client:ui ✅
45 Local chromium-local-provider Performance dashboard controls ➖
46 Local chromium-local-provider Ping Istio Adapter unstable ⚠️
47 Local chromium-local-provider Reach the server-wide controllers editor from the header menu controllers-config, cut:ui-settings, client:ui ✅
48 Local chromium-local-provider Register and connect a Kubernetes cluster via kubeconfig upload connections, TC-1012, cut:ui-connection-wizard, client:ui ✅
49 Local chromium-local-provider Reject invalid documents and persist nothing controllers-config, cut:api-system-controllers-config, client:ui ➖
50 Local chromium-local-provider Render a control for every setting in the three sections controllers-config, cut:ui-controllers-editor, client:ui ✅
51 Local chromium-local-provider Resolve each field through override, then server-wide default, then built-in controllers-config, cut:api-connection-controllers-config, client:ui ➖
52 Local chromium-local-provider Return a field to Inherit and it leaves the stored document controllers-config, cut:ui-controllers-editor, client:ui ❌
53 Local chromium-local-provider Round-trip every documented wire path through the server-wide defaults controllers-config, cut:api-system-controllers-config, client:ui ➖
54 Local chromium-local-provider Search a Model and Export it ✅
55 Local chromium-local-provider should edit design in Design Configurator ✅
56 Local chromium-local-provider should identify relationships for All Relationships relationship ✅
57 Local chromium-local-provider should identify relationships for Container-Hierarchical-Parent-Alias-Relationship relationship ✅
58 Local chromium-local-provider should identify relationships for deployment-configmap-reference-relationship relationship ✅
59 Local chromium-local-provider should identify relationships for Hierarchical-Parent-Namespace-Relationship relationship ✅
60 Local chromium-local-provider should identify relationships for meshery-design relationship ✅
61 Local chromium-local-provider should identify relationships for pv-pvc-edge-non-binding-reference-relationship relationship ✅
62 Local chromium-local-provider should identify relationships for Service-To-Deployment-Network relationship ✅
63 Local chromium-local-provider should verify Design Configurator page elements ✅
64 Local chromium-local-provider State in Embedded mode which settings reach only Operator-mode connections controllers-config, cut:ui-controllers-editor, client:ui ➖
65 Local chromium-local-provider Store only the fields set through the server-wide editor controllers-config, cut:ui-controllers-editor, client:ui ✅
66 Local chromium-local-provider structural integrity relationship ✅
67 Local chromium-local-provider structural integrity relationship ✅
68 Local chromium-local-provider structural integrity relationship ✅
69 Local chromium-local-provider structural integrity relationship ✅
70 Local chromium-local-provider structural integrity relationship ✅
71 Local chromium-local-provider structural integrity relationship ✅
72 Local chromium-local-provider structural integrity relationship ✅
73 Local chromium-local-provider structural integrity relationship ✅
74 Local chromium-local-provider structural integrity relationship ✅
75 Local chromium-local-provider Test if Left Navigation Panel is displayed ✅
76 Local chromium-local-provider Test if Notification button is displayed ✅
77 Local chromium-local-provider Test if Profile button is displayed ✅
78 Local chromium-local-provider Toggle "Send Anonymous Performance Results" ✅
79 Local chromium-local-provider Toggle "Send Anonymous Usage Statistics" ✅
80 Local chromium-local-provider Transition a Kubernetes connection between lifecycle states connections, TC-1061, cut:ui-connections-table, client:ui ➖
81 Local chromium-local-provider Verify extension nav items use top-level layout ➖
82 Local chromium-local-provider Verify Meshery Adapter for Istio Section ➖
83 Local chromium-local-provider Verify Meshery Catalog Section Details ✅
84 Local chromium-local-provider Verify Meshery Design Embed Details ➖
85 Local chromium-local-provider Verify Meshery Docker Extension Details ✅
86 Local chromium-local-provider Verify Performance Analysis Details ➖
87 Local chromium-local-provider Verify that UI components are displayed connections, cut:ui-connections-table, client:ui ✅
88 Local local-setup authenticate as Local provider ✅

❌ Failed Test Details

The following tests failed. Click on each to see the failure reason:

❌ Return a field to Inherit and it leaves the stored document (Local - chromium-local-provider)

File Location: /home/runner/work/meshery/meshery/ui/tests/e2e/controllers-config.testmap.ts

Error Message:

Error: �[2mexpect(�[22m�[31mlocator�[39m�[2m).�[22mtoBeVisible�[2m(�[22m�[2m)�[22m failed

Locator: getByText('Server-wide controllers configuration defaults saved').first()
Expected: visible
Timeout: 60000ms
Error: element(s) not found

Call log:
�[2m  - Expect "toBeVisible" with timeout 60000ms�[22m
�[2m  - waiting for getByText('Server-wide controllers configuration defaults saved').first()�[22m

Code Snippet:

   at controllers-config.testmap.ts:276

�[0m �[90m 274 |�[39m   �[36mawait�[39m expect(
 �[90m 275 |�[39m     page�[33m.�[39mgetByText(�[32m'Server-wide controllers configuration defaults saved'�[39m)�[33m.�[39mfirst()�[33m,�[39m
�[31m�[1m>�[22m�[39m�[90m 276 |�[39m   )�[33m.�[39mtoBeVisible()�[33m;�[39m
 �[90m     |�[39m     �[31m�[1m^�[22m�[39m
 �[90m 277 |�[39m   �[36mawait�[39m resettled�[33m;�[39m
 �[90m 278 |�[39m   �[36mreturn�[39m response�[33m.�[39mjson()�[33m;�[39m
 �[90m 279 |�[39m }�[0m

🔗 Relationship Tests

[Show/Hide] Relationship Test Details (18 tests)
Kind Type SubType From To Model Design Name Status
edge binding permission ClusterRole ServiceAccount kubernetes Understanding Relationships ❌
edge binding permission Role ServiceAccount kubernetes Understanding Relationships ❌
edge non-binding network Service Deployment kubernetes service-to-deployment-network ✅
edge non-binding network Service Deployment kubernetes meshery-design-fixture.json ✅
edge non-binding reference ClusterRoleBinding ClusterRole kubernetes meshery-design-fixture.json ❌
hierarchical parent alias Container Deployment kubernetes container-hierarchical-parent-alias-relationship ✅
hierarchical parent alias Container Deployment kubernetes deployment-configmap-reference-relationship ✅
hierarchical parent alias Container Deployment kubernetes service-to-deployment-network ✅
hierarchical parent alias Container Deployment kubernetes meshery-design-fixture.json ✅
hierarchical parent alias Container Deployment kubernetes Understanding Relationships ✅
hierarchical parent alias Container Pod kubernetes container-hierarchical-parent-alias-relationship ✅
hierarchical parent inventory * Namespace kubernetes hierarchical-parent-namespace-relationship ✅
hierarchical parent inventory * Namespace kubernetes service-to-deployment-network ✅
hierarchical parent inventory * Namespace kubernetes pv-pvc-edge-non-binding-reference-relationship ✅
hierarchical parent inventory * Namespace kubernetes Understanding Relationships ✅
hierarchical sibling matchlabels ClusterRole ClusterRole kubernetes meshery-design-fixture.json ✅
hierarchical sibling matchlabels Deployment Deployment kubernetes meshery-design-fixture.json ✅
hierarchical sibling matchlabels Service Service kubernetes meshery-design-fixture.json ✅

@banana-three-join
banana-three-join merged commit d50ce26 into meshery:master Aug 13, 2026
8 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/ui User Interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Ensure that Meshery UI benefits from PR #1793

2 participants