Skip to content

CallGraph skeleton loader + compact ErrorBoundary fallback - #1490

Merged
Gbangbolaoluwagbemiga merged 2 commits into
HyperSafeD:mainfrom
oluwarantimini:fix/issues-1446-1448
Aug 27, 2026
Merged

CallGraph skeleton loader + compact ErrorBoundary fallback#1490
Gbangbolaoluwagbemiga merged 2 commits into
HyperSafeD:mainfrom
oluwarantimini:fix/issues-1446-1448

Conversation

@oluwarantimini

@oluwarantimini oluwarantimini commented Aug 27, 2026

Copy link
Copy Markdown

Summary

Closes #1446
Closes #1448
Closes #1449
Closes #1447

loading states.** Both next/dynamic(() => import(".../CallGraph")) call sites
(app/scan/page.tsx, app/dashboard/page.tsx) showed a plain "Loading call graph…" text string
while the chunk loaded. Replaces it with a proper skeleton (CallGraphSkeleton.tsx) — pulsing
placeholder blocks mirroring the real component's layout (title, stats line, legend row, graph
area) — so the page doesn't visibly reflow once the real content mounts. The skeleton lives in its
own new file rather than being exported from CallGraph.tsx: both call sites need to import it
statically so it renders before the dynamic chunk even starts loading, and a static import from
CallGraph.tsx itself would pull the whole SVG-heavy renderer into the eagerly-loaded bundle,
defeating the point of code-splitting it.
error boundaries.** ErrorBoundary's default fallback (no fallback prop given) is
min-h-screen flex items-center justify-center — a full-viewport overlay. That's right for a
boundary wrapping an entire page, but app/scan/page.tsx wraps three separate sections of a
larger page in their own ErrorBoundary (the sanctity score card, the findings list, the call
graph) — a render error in any one of those previously covered the whole screen with an unrelated
full-page error card instead of just replacing that section. Adds a compact prop for a small
inline fallback sized to its container, wired into all three of scan/page.tsx's boundaries. Also
wires up handleReset — defined on the class already but never called from either fallback before
this — as a "Try Again" button that re-renders just the failed subtree, added to both the new
compact fallback and the existing full-page one (which previously only offered "Reload Page").

Note on file pointers: both issues' "File Pointer" links were stale — frontend/components/ CallGraph.tsx is actually frontend/app/components/CallGraph.tsx, and frontend/pages/scan.tsx
(Pages Router) is actually frontend/app/scan/page.tsx (App Router). Verified against the actual
repo layout before making changes.

Test plan

  • Manual review of both changed components against the existing Tailwind/dark-mode conventions
    already used in this codebase
  • npx vitest run / npx tsc --noEmit — not run; npm install in frontend/ fails in this
    environment on an EBADPLATFORM error for an optional dependency (@commitlint/message wants
    linux, this environment is darwin) unrelated to this change
  • Manual review against each issue's acceptance criteria

Closes HyperSafeD#1446

Replaces the plain "Loading call graph…" text used as the loading:
fallback for both next/dynamic(() => import("../components/CallGraph"))
call sites (app/scan/page.tsx, app/dashboard/page.tsx) with a proper
skeleton — pulsing placeholder blocks mirroring the real component's
layout (title, stats line, legend row, graph area) — so the page doesn't
visibly reflow once the real content mounts, and there's a shape on
screen during the load rather than just a text string.

The skeleton lives in its own new file, CallGraphSkeleton.tsx, rather
than being exported from CallGraph.tsx itself: both call sites need to
import it statically (so it renders immediately, before the dynamic
chunk even starts loading), and a static import from CallGraph.tsx would
pull the whole SVG-heavy call-graph renderer into the eagerly-loaded
bundle, defeating the point of code-splitting it via next/dynamic in the
first place.

Note: the issue's file pointer said frontend/components/CallGraph.tsx —
the actual file is at frontend/app/components/CallGraph.tsx (Next.js App
Router layout).
Closes HyperSafeD#1448

ErrorBoundary's only fallback (when no explicit `fallback` prop is
given) was `min-h-screen flex items-center justify-center` — a
full-viewport overlay. That's fine for a boundary wrapping an entire
page, but app/scan/page.tsx wraps three separate *sections* of a larger
page in their own ErrorBoundary (SanctityScore, the findings list, the
call graph) — a render error in any one of those would have covered the
whole screen with an unrelated full-page error card instead of just
replacing that section.

Adds a `compact` prop: a small inline card sized to its container instead
of the viewport, wired into all three scan/page.tsx ErrorBoundary usages
(done in the previous commit, alongside the file it touches). Also wires
up `handleReset` — defined on the class already but never called from
either fallback before this — as a "Try Again" button that re-renders
just the failed subtree, alongside "Reload Page", instead of reload being
the only recovery option. The full-page default fallback (still used
elsewhere without `compact`) gets the same "Try Again" button added for
the same reason.

Note: the issue's file pointer said frontend/pages/scan.tsx (Pages
Router) — the actual file is frontend/app/scan/page.tsx (App Router).
@drips-wave

drips-wave Bot commented Aug 27, 2026

Copy link
Copy Markdown

@oluwarantimini Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Gbangbolaoluwagbemiga
Gbangbolaoluwagbemiga merged commit ee1ad0a into HyperSafeD:main Aug 27, 2026
14 of 23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants