Skip to content

dashboard: add Map and Tower Finder external links to sidebar - #139

Merged
Babissimo merged 2 commits into
mainfrom
dashboard/sidebar-external-links
Jul 29, 2026
Merged

dashboard: add Map and Tower Finder external links to sidebar#139
Babissimo merged 2 commits into
mainfrom
dashboard/sidebar-external-links

Conversation

@Babissimo

Copy link
Copy Markdown
Contributor

What

Adds two external links to the Dashboard section of the dashboard sidebar:

Both render as real anchors that open in a new tab (target="_blank", rel="noopener noreferrer"), each with a trailing external-link glyph flush to the row's right edge to signal they leave the app.

Why

The dashboard had no way to reach the org's other two cloud surfaces; a node owner landing here had to already know the URLs. This lets the dashboard act as the hub between the three tools. See ClickUp 86caxgq7z (Server Home Page), option 2.

Notes

  • External nav items are branched off internal router NavLinks; added map/radio/externalLink Feather icons and a small NavItem/NavSection type so the mixed internal-route / external-URL shapes stay type-clean.
  • Only the user nav gets these (the admin nav has no Dashboard group); mirroring to admin was explicitly out of scope.
  • Verified: vite build and tsc --noEmit pass; rendered the sidebar in isolation to confirm placement and that both links resolve to the correct external URLs.

🤖 Generated with Claude Code

The dashboard had no way to reach the other two cloud tools (map.retina.fm
and towers.retina.fm) — a node owner landing here had to know the URLs. Add
both to the Dashboard nav section as external links so the dashboard can act
as the hub between the three surfaces.

External items render as real anchors (target="_blank", rel="noopener
noreferrer") rather than router NavLinks, with a trailing external-link glyph
to signal they leave the app. Adds map/radio/externalLink Feather icons and a
NavItem/NavSection type so the mixed internal-route / external-URL item shapes
stay type-clean.

Advances ClickUp 86caxgq7z (Server Home Page, option 2).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@claude

claude Bot commented Jul 28, 2026

Copy link
Copy Markdown

Claude finished @Babissimo's task in 1m 22s —— View job


Code Review

Tasks

  • Gather context (diff, CLAUDE.md, changed files)
  • Review Sidebar.tsx changes
  • Review App.css changes
  • Check build/typecheck (see note below)
  • Post final review

Reviewed the diff (git diff origin/main...HEAD) for dashboard/src/components/Sidebar.tsx and dashboard/src/App.css. Overall this is a small, well-scoped change — clean implementation, no bugs found.

What's good

  • The NavItem/NavSection types are a nice touch given strict/noImplicitAny are off in dashboard/tsconfig.json — not strictly required, but they make the mixed internal/external shape self-documenting.
  • target="_blank" is correctly paired with rel="noopener noreferrer" (Sidebar.tsx:264) — avoids the reverse-tabnabbing issue.
  • key={item.href} for external items (Sidebar.tsx:261) is safe since both URLs are unique and static.
  • CSS addition is minimal and scoped; .nav-external { margin-left: auto } works correctly since .nav-item is already display: flex (App.css:216).

Minor / non-blocking observations

  1. CSS cascade fragility (App.css:239-250): .nav-item svg (18px) and .nav-external svg (14px) have equal specificity (0,1,1 each), so the 14px override only wins because .nav-external svg happens to be declared after .nav-item svg in the file. This works today but is easy to silently break if the rules get reordered later. Not urgent, but a slightly more specific selector (e.g. .nav-item .nav-external svg) would make the sizing win deterministic regardless of declaration order.
  2. Mirroring to admin nav: confirmed as intentionally out of scope per the PR description (admin nav has no "Dashboard" section), so no action needed here.

Verification

  • Logic was verified by reading the diff and full Sidebar.tsx/App.css files; the conditional render (item.external ? <a> : <NavLink>) correctly branches based on the new external flag and doesn't affect any existing internal routes.
  • I was not able to run vite build / tsc --noEmit myself in this sandboxed environment (npm ci requires interactive approval that isn't available here), so I relied on static reading of the code and the tsconfig (strict: false, noImplicitAny: false) to confirm the generic-string icon lookup (icons[item.icon]) type-checks as the PR author reported.

No blocking issues found — looks good to merge from a code standpoint.

`.nav-external svg` had equal specificity to `.nav-item svg`, so the 14px
override only won by virtue of being declared later in the file. Scope it under
`.nav-item` so the win is deterministic regardless of rule order.
@claude

claude Bot commented Jul 28, 2026

Copy link
Copy Markdown

Claude finished @Babissimo's task in 1m 7s —— View job


Code Review

Tasks

  • Gather context (diff, CLAUDE.md, changed files)
  • Review Sidebar.tsx changes
  • Review App.css changes
  • Check CI/build status
  • Post final review

Re-reviewed after the new commit (97f0693). This is a small, well-scoped, clean change — no bugs found.

Previous finding: resolved
The earlier review flagged a CSS cascade fragility issue: .nav-item svg (18px) and .nav-external svg (14px) had equal specificity, so the 14px override only won due to declaration order. Commit 97f0693 fixes this correctly — App.css:254 now uses .nav-item .nav-external svg (specificity 0,2,1), which deterministically wins over .nav-item svg (0,1,1) regardless of rule order. The explanatory comment above it (App.css:252-253) is a nice touch for future maintainers. ✅

What's good

  • target="_blank" correctly paired with rel="noopener noreferrer" (Sidebar.tsx:264) — avoids reverse-tabnabbing.
  • The NavItem/NavSection types (Sidebar.tsx:3-11) make the mixed internal-route/external-URL shape self-documenting.
  • key={item.href} for external items is safe since both URLs are static and unique.
  • .nav-item svg still applies flex-shrink: 0 to the external-link glyph too (since it's still a descendant svg of .nav-item), so the icon won't get squeezed — the more specific rule only overrides width/height as intended.
  • Admin nav mirroring was confirmed out of scope (no Dashboard section there) — no action needed.

Verification

  • Verified via static reading of the full diff (git diff origin/main...HEAD) and the complete Sidebar.tsx/App.css files.
  • CI (CI and Claude Code Review workflows) was still in progress at review time for the latest commit — could not confirm vite build/tsc --noEmit results directly in this sandboxed environment (no network access for npm ci), consistent with the prior review pass.

No blocking issues. Looks good to merge from a code standpoint.

@Babissimo

Copy link
Copy Markdown
Contributor Author
image

@Babissimo
Babissimo merged commit e8d405d into main Jul 29, 2026
12 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

Development

Successfully merging this pull request may close these issues.

2 participants