fix(web): scope Suspense to page body; guard formatConfig against null config
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -24,7 +24,9 @@ test("renders navigation and redirects to domains", async () => {
|
|||||||
)
|
)
|
||||||
// Sidebar nav also renders a "Domains" link label, so scope the assertion
|
// Sidebar nav also renders a "Domains" link label, so scope the assertion
|
||||||
// to the routed page content to unambiguously confirm the redirect + page.
|
// to the routed page content to unambiguously confirm the redirect + page.
|
||||||
|
// Suspense is now scoped inside <main>, so <main> mounts with the loading
|
||||||
|
// fallback first — await the lazy chunk resolving to the actual page text.
|
||||||
const main = await screen.findByRole("main")
|
const main = await screen.findByRole("main")
|
||||||
expect(within(main).getByText("Domains")).toBeInTheDocument()
|
expect(await within(main).findByText("Domains")).toBeInTheDocument()
|
||||||
expect(screen.getByRole("link", { name: /domains/i })).toBeInTheDocument()
|
expect(screen.getByRole("link", { name: /domains/i })).toBeInTheDocument()
|
||||||
})
|
})
|
||||||
|
|||||||
+7
-3
@@ -17,17 +17,22 @@ const ChannelsPage = lazy(() => import("@/pages/ChannelsPage").then((m) => ({ de
|
|||||||
|
|
||||||
// Every non-auth route shares the same guard + chrome; wrapping here keeps
|
// Every non-auth route shares the same guard + chrome; wrapping here keeps
|
||||||
// each <Route> below a one-liner instead of repeating both on every page.
|
// each <Route> below a one-liner instead of repeating both on every page.
|
||||||
|
// Suspense is scoped to just the page body (not Layout) so lazy-loading a
|
||||||
|
// route doesn't collapse the sidebar/header chrome to the fallback on nav.
|
||||||
function Protected({ children }: { children: ReactNode }) {
|
function Protected({ children }: { children: ReactNode }) {
|
||||||
return (
|
return (
|
||||||
<ProtectedRoute>
|
<ProtectedRoute>
|
||||||
<Layout>{children}</Layout>
|
<Layout>
|
||||||
|
<Suspense fallback={<div className="p-6 text-muted-foreground">Загрузка…</div>}>
|
||||||
|
{children}
|
||||||
|
</Suspense>
|
||||||
|
</Layout>
|
||||||
</ProtectedRoute>
|
</ProtectedRoute>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function App() {
|
export function App() {
|
||||||
return (
|
return (
|
||||||
<Suspense fallback={<div className="p-6 text-muted-foreground">Загрузка…</div>}>
|
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/login" element={<LoginPage />} />
|
<Route path="/login" element={<LoginPage />} />
|
||||||
<Route path="/register" element={<RegisterPage />} />
|
<Route path="/register" element={<RegisterPage />} />
|
||||||
@@ -39,6 +44,5 @@ export function App() {
|
|||||||
<Route path="/schedule" element={<Protected><SchedulePage /></Protected>} />
|
<Route path="/schedule" element={<Protected><SchedulePage /></Protected>} />
|
||||||
<Route path="/channels" element={<Protected><ChannelsPage /></Protected>} />
|
<Route path="/channels" element={<Protected><ChannelsPage /></Protected>} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</Suspense>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ const EMPTY_FORM: ChannelForm = { type: "telegram", chatId: "", botToken: "", ur
|
|||||||
// (Object.entries по всему config печатал бы любое поле, включая случайно
|
// (Object.entries по всему config печатал бы любое поле, включая случайно
|
||||||
// сохранённый секрет).
|
// сохранённый секрет).
|
||||||
function formatConfig(type: string, config: object): string {
|
function formatConfig(type: string, config: object): string {
|
||||||
const c = config as Record<string, unknown>
|
const c = (config ?? {}) as Record<string, unknown>
|
||||||
if (type === "telegram") return c.chat_id ? `chat_id: ${String(c.chat_id)}` : ""
|
if (type === "telegram") return c.chat_id ? `chat_id: ${String(c.chat_id)}` : ""
|
||||||
if (type === "webhook") return c.url ? `url: ${String(c.url)}` : ""
|
if (type === "webhook") return c.url ? `url: ${String(c.url)}` : ""
|
||||||
return ""
|
return ""
|
||||||
|
|||||||
Reference in New Issue
Block a user