Bug
After selecting the Fleet management perspective (or any plugin-registered perspective), the perspective becomes stuck and can no longer be changed via the perspective switcher.
Root Cause
Two issues in frontend/packages/console-app/src/components/detect-perspective/:
1. Hardcoded ACM default in useValuesForPerspectiveContext.ts
const acmPerspectiveExtension = usePerspectiveExtension(ACM_PERSPECTIVE_ID); // 'acm'
const existingPerspective = activePerspective || latestPerspective;
const perspective =
!!acmPerspectiveExtension && !existingPerspective
? ACM_PERSPECTIVE_ID
: existingPerspective || '';
If existingPerspective is momentarily empty during a perspective switch (e.g. async useLastPerspective loading), Console silently defaults back to acm instead of allowing the switch to complete. Console should not hardcode a preference for any specific plugin perspective.
2. setPerspective causes split-render between context and router
setPerspective updates two independent React contexts in one call:
setActivePerspective(newPerspective); // PerspectiveContext update
navigate(next || '/'); // RouterContext update
These may commit in separate render cycles. Plugins using both useActivePerspective() and useLocation() can observe a render where the perspective has changed but the pathname has not, triggering perspective-forcing logic that overrides the user's switch.
3. location dependency in DetectPerspective effect fires too often after react-router migration
After CONSOLE-5114 migrated from react-router-dom-v5-compat to react-router, the location object in DetectPerspective's effect is a new reference on every navigation, causing the ?perspective= URL param check to re-run more frequently. Combined with PR #15736 passing createPath(location) (full URL including ?perspective=) as the navigation target, a stale ?perspective= param can force the perspective back.
Side Effects on Plugins
Plugins that register perspectives with async feature flags face a trilemma -- all three options are broken:
required flag on perspective → infinite loading spinner (flag undefined until async call completes)
disallowed flag on perspective + perspective on routes → page reload loop (setPerspective → navigate(landingPage) → redirect loop)
disallowed flag + no perspective on routes → stuck perspective (plugin's perspective-sync hook fights the user's switch due to the split-render issue above)
Plugins should be able to register perspective-scoped routes with async flags without hitting any of these failure modes.
Environment
- OpenShift Console: release-4.22
- ACM/MCE: stolostron/console main branch
- Reproduces when any plugin registers a perspective with
disallowed flag gating
Steps to Reproduce
- Install ACM/MCE (or any plugin that registers a perspective)
- Switch to the Fleet management perspective
- Try to switch to Administrator or Developer perspective
- Perspective snaps back to Fleet management
Bug
After selecting the Fleet management perspective (or any plugin-registered perspective), the perspective becomes stuck and can no longer be changed via the perspective switcher.
Root Cause
Two issues in
frontend/packages/console-app/src/components/detect-perspective/:1. Hardcoded ACM default in
useValuesForPerspectiveContext.tsIf
existingPerspectiveis momentarily empty during a perspective switch (e.g. asyncuseLastPerspectiveloading), Console silently defaults back toacminstead of allowing the switch to complete. Console should not hardcode a preference for any specific plugin perspective.2.
setPerspectivecauses split-render between context and routersetPerspectiveupdates two independent React contexts in one call:These may commit in separate render cycles. Plugins using both
useActivePerspective()anduseLocation()can observe a render where the perspective has changed but the pathname has not, triggering perspective-forcing logic that overrides the user's switch.3.
locationdependency inDetectPerspectiveeffect fires too often after react-router migrationAfter CONSOLE-5114 migrated from
react-router-dom-v5-compattoreact-router, thelocationobject inDetectPerspective's effect is a new reference on every navigation, causing the?perspective=URL param check to re-run more frequently. Combined with PR #15736 passingcreatePath(location)(full URL including?perspective=) as the navigation target, a stale?perspective=param can force the perspective back.Side Effects on Plugins
Plugins that register perspectives with async feature flags face a trilemma -- all three options are broken:
requiredflag on perspective → infinite loading spinner (flag undefined until async call completes)disallowedflag on perspective +perspectiveon routes → page reload loop (setPerspective→navigate(landingPage)→ redirect loop)disallowedflag + noperspectiveon routes → stuck perspective (plugin's perspective-sync hook fights the user's switch due to the split-render issue above)Plugins should be able to register perspective-scoped routes with async flags without hitting any of these failure modes.
Environment
disallowedflag gatingSteps to Reproduce