mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-24 04:33:17 +00:00
Route app root through dashboard shell
This commit is contained in:
@@ -463,6 +463,12 @@ instead of wiring product-surface components such as
|
||||
`frontend-modern/src/components/Storage/Storage.tsx` directly into the router,
|
||||
so hosted bootstrap ownership stays at the app boundary rather than leaking
|
||||
route concerns back into feature components.
|
||||
That same authenticated route shell also owns the canonical post-auth landing
|
||||
path. `frontend-modern/src/App.tsx` must send `/` through the dashboard page
|
||||
shell first, so existing operators land on the overview route and first-time
|
||||
operators hit the governed dashboard empty state that forwards them into
|
||||
Infrastructure Install, instead of carrying a root-only redirect to the
|
||||
infrastructure route that bypasses the shared landing contract.
|
||||
The Pro license settings surface now follows the same rule as well. Changes to
|
||||
`frontend-modern/src/components/Settings/ProLicensePanel.tsx` must carry this
|
||||
contract and the dedicated Pro-license proof file instead of remaining an
|
||||
|
||||
@@ -192,6 +192,11 @@ work extends shared components instead of creating new local variants.
|
||||
must name the canonical install workspace explicitly and expose the same
|
||||
first-host next step instead of falling back to passive “nothing here yet”
|
||||
wording.
|
||||
11. Keep the authenticated app root aligned with that same first-session path.
|
||||
`frontend-modern/src/App.tsx` must land `/` on the dashboard shell and let
|
||||
the governed dashboard empty state route first-time operators into
|
||||
Infrastructure Install, instead of preserving a separate root-only jump to
|
||||
`/infrastructure` that drifts from the rest of the onboarding contract.
|
||||
|
||||
## Current State
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ import { aiChatStore } from './stores/aiChat';
|
||||
import { useKeyboardShortcuts } from './hooks/useKeyboardShortcuts';
|
||||
import { useKioskMode } from '@/hooks/useKioskMode';
|
||||
import {
|
||||
DASHBOARD_PATH,
|
||||
buildRecoveryPath,
|
||||
buildInfrastructurePath,
|
||||
buildStoragePath,
|
||||
@@ -78,7 +79,8 @@ const SetupCompletionPreviewPage = lazy(() =>
|
||||
default: module.SetupCompletionPreview,
|
||||
})),
|
||||
);
|
||||
const ROOT_INFRASTRUCTURE_PATH = buildInfrastructurePath();
|
||||
const ROOT_DASHBOARD_PATH = DASHBOARD_PATH;
|
||||
const INFRASTRUCTURE_ROUTE_PATH = buildInfrastructurePath();
|
||||
const ROOT_WORKLOADS_PATH = buildWorkloadsPath();
|
||||
const STORAGE_PATH = buildStoragePath();
|
||||
const RECOVERY_ROUTE_PATH = buildRecoveryPath();
|
||||
@@ -378,13 +380,13 @@ function App() {
|
||||
<Route path="/cloud" component={CloudPricingPage} />
|
||||
<Route path="/cloud/signup" component={HostedSignupPage} />
|
||||
<Route path="/preview/setup-complete" component={SetupCompletionPreviewPage} />
|
||||
<Route path="/dashboard" component={DashboardPage} />
|
||||
<Route path="/" component={() => <Navigate href={ROOT_INFRASTRUCTURE_PATH} />} />
|
||||
<Route path={ROOT_DASHBOARD_PATH} component={DashboardPage} />
|
||||
<Route path="/" component={() => <Navigate href={ROOT_DASHBOARD_PATH} />} />
|
||||
<Route path={ROOT_WORKLOADS_PATH} component={WorkloadsView} />
|
||||
<Route path={STORAGE_PATH} component={StoragePage} />
|
||||
<Route path={RECOVERY_ROUTE_PATH} component={RecoveryRoute} />
|
||||
<Route path="/ceph" component={CephPage} />
|
||||
<Route path={ROOT_INFRASTRUCTURE_PATH} component={InfrastructurePage} />
|
||||
<Route path={INFRASTRUCTURE_ROUTE_PATH} component={InfrastructurePage} />
|
||||
|
||||
<Route path="/alerts/*" component={AlertsPage} />
|
||||
<Route path="/ai/*" component={AIIntelligencePage} />
|
||||
|
||||
@@ -5,9 +5,13 @@ import appRuntimeStateSource from '@/useAppRuntimeState.ts?raw';
|
||||
|
||||
describe('App architecture', () => {
|
||||
it('keeps App as the entry shell that delegates runtime and chrome ownership', () => {
|
||||
expect(appSource).toContain('DASHBOARD_PATH,');
|
||||
expect(appSource).toContain("import { AppLayout } from '@/AppLayout';");
|
||||
expect(appSource).toContain("import { useAppRuntimeState } from '@/useAppRuntimeState';");
|
||||
expect(appSource).toContain('const runtime = useAppRuntimeState();');
|
||||
expect(appSource).toContain('const ROOT_DASHBOARD_PATH = DASHBOARD_PATH;');
|
||||
expect(appSource).toContain('<Route path={ROOT_DASHBOARD_PATH} component={DashboardPage} />');
|
||||
expect(appSource).toContain('<Route path="/" component={() => <Navigate href={ROOT_DASHBOARD_PATH} />} />');
|
||||
expect(appSource).toContain("const StoragePage = lazy(() => import('./pages/Storage'));");
|
||||
expect(appSource).toContain("const OperationsPage = lazy(() => import('./pages/Operations'));");
|
||||
expect(appSource).not.toContain(
|
||||
|
||||
Reference in New Issue
Block a user