mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-11 14:00:29 +00:00
Stop retired routes highlighting primary nav
This commit is contained in:
@@ -1733,6 +1733,12 @@ route-level data orchestration, section anchors, or Assistant prompt handoffs;
|
||||
they must not restore `frontend-modern/src/pages/Dashboard.tsx`,
|
||||
`frontend-modern/src/features/dashboardOverview/`, or deleted dashboard-only
|
||||
presentation helpers as compatibility paths.
|
||||
The primary navigation active-tab contract follows that retirement boundary:
|
||||
retired or unknown routes such as `/dashboard` must not be coerced into the
|
||||
Infrastructure tab just because Infrastructure is the authenticated landing
|
||||
surface. Shared desktop and mobile navigation must tolerate a missing active tab
|
||||
for those paths while still highlighting canonical active routes such as
|
||||
Infrastructure, Workloads, Storage, Recovery, Alerts, Patrol, and Settings.
|
||||
The recovery feature shell now also depends on the shared
|
||||
`frontend-modern/src/components/shared/Subtabs.tsx` primitive for its primary
|
||||
protected-items versus recovery-events workspace switch. The recovery lane may
|
||||
|
||||
@@ -74,6 +74,48 @@ describe('MobileNavBar', () => {
|
||||
expect(within(navList).queryByRole('button', { name: 'Pulse Patrol Patrol' })).toBeNull();
|
||||
});
|
||||
|
||||
it('allows retired shell routes to render without an active mobile tab', () => {
|
||||
const { container } = render(() => (
|
||||
<MobileNavBar
|
||||
activeTab={() => null}
|
||||
platformTabs={() => [
|
||||
{
|
||||
id: 'infrastructure',
|
||||
label: 'Infrastructure',
|
||||
route: '/infrastructure',
|
||||
settingsRoute: '/settings',
|
||||
tooltip: 'Infrastructure',
|
||||
enabled: true,
|
||||
live: true,
|
||||
icon: InfrastructureIcon,
|
||||
alwaysShow: true,
|
||||
},
|
||||
]}
|
||||
utilityTabs={() => [
|
||||
{
|
||||
id: 'settings',
|
||||
label: 'Settings',
|
||||
route: '/settings',
|
||||
tooltip: 'Settings',
|
||||
badge: null,
|
||||
count: undefined,
|
||||
breakdown: undefined,
|
||||
icon: SettingsIcon,
|
||||
},
|
||||
]}
|
||||
onPlatformClick={() => {}}
|
||||
onUtilityClick={() => {}}
|
||||
/>
|
||||
));
|
||||
|
||||
const buttons = container.querySelectorAll('button[data-tab-id]');
|
||||
expect(buttons).toHaveLength(2);
|
||||
buttons.forEach((button) => {
|
||||
expect(button).not.toHaveClass('bg-blue-50');
|
||||
expect(button).not.toHaveClass('text-blue-700');
|
||||
});
|
||||
});
|
||||
|
||||
it('orders tabs, renders alert badges, and shows fades from scroll state', async () => {
|
||||
const onPlatformClick = vi.fn();
|
||||
const onUtilityClick = vi.fn();
|
||||
|
||||
@@ -27,7 +27,7 @@ export type MobileNavBarUtilityTab = {
|
||||
};
|
||||
|
||||
export type MobileNavBarProps = {
|
||||
activeTab: () => string;
|
||||
activeTab: () => string | null;
|
||||
platformTabs: () => MobileNavBarPlatformTab[];
|
||||
utilityTabs: () => MobileNavBarUtilityTab[];
|
||||
onPlatformClick: (platform: MobileNavBarPlatformTab) => void;
|
||||
|
||||
@@ -3,7 +3,8 @@ import { getActiveTabForPath } from '../navigation';
|
||||
|
||||
describe('navigation routing helpers', () => {
|
||||
it('maps paths to the correct primary tab', () => {
|
||||
expect(getActiveTabForPath('/unknown')).toBe('infrastructure');
|
||||
expect(getActiveTabForPath('/unknown')).toBeNull();
|
||||
expect(getActiveTabForPath('/dashboard')).toBeNull();
|
||||
expect(getActiveTabForPath('/infrastructure')).toBe('infrastructure');
|
||||
expect(getActiveTabForPath('/workloads?type=pod')).toBe('workloads');
|
||||
expect(getActiveTabForPath('/storage')).toBe('storage');
|
||||
|
||||
@@ -9,7 +9,9 @@ export type AppTabId =
|
||||
| 'ai'
|
||||
| 'settings';
|
||||
|
||||
export function getActiveTabForPath(path: string): AppTabId {
|
||||
export type ActiveAppTabId = AppTabId | null;
|
||||
|
||||
export function getActiveTabForPath(path: string): ActiveAppTabId {
|
||||
if (path.startsWith(INFRASTRUCTURE_PATH)) return 'infrastructure';
|
||||
if (path.startsWith(WORKLOADS_PATH)) return 'workloads';
|
||||
if (path.startsWith('/storage')) return 'storage';
|
||||
@@ -19,5 +21,5 @@ export function getActiveTabForPath(path: string): AppTabId {
|
||||
if (path.startsWith(PATROL_PATH) || path.startsWith('/ai')) return 'ai';
|
||||
if (path.startsWith('/settings')) return 'settings';
|
||||
if (path.startsWith('/operations')) return 'settings';
|
||||
return 'infrastructure';
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user