Skip to content

feat: add satellite icon for Ground Control dashboards in sidebar#5299

Merged
clubanderson merged 1 commit intomainfrom
feat/ground-control-icon
Apr 7, 2026
Merged

feat: add satellite icon for Ground Control dashboards in sidebar#5299
clubanderson merged 1 commit intomainfrom
feat/ground-control-icon

Conversation

@clubanderson
Copy link
Copy Markdown
Collaborator

Summary

  • Adds a small purple Satellite icon (from lucide-react) next to custom dashboard names in the sidebar when they are Ground Control dashboards
  • Uses safeGetJSON to read the kc-ground-control-dashboards localStorage mapping to identify Ground Control dashboards
  • Icon only appears when sidebar is expanded, consistent with other sidebar badges

Test plan

  • Create a Ground Control dashboard via Mission Control flow
  • Verify the Satellite icon appears next to the dashboard name in the sidebar
  • Verify regular custom dashboards do NOT show the icon
  • Verify the icon does not appear when sidebar is collapsed
  • Build passes (npm run build)
  • Lint passes (npm run lint)

Custom dashboards that are Ground Control dashboards now display a small
purple Satellite icon next to their name in the sidebar navigation. This
makes it easy to identify which dashboards were auto-generated by the
Ground Control orbit system vs. user-created custom dashboards.

Signed-off-by: Andrew Anderson <andy@clubanderson.com>
Copilot AI review requested due to automatic review settings April 7, 2026 19:22
@kubestellar-prow kubestellar-prow bot added the dco-signoff: yes Indicates the PR's author has signed the DCO. label Apr 7, 2026
@clubanderson clubanderson merged commit 42dfe7e into main Apr 7, 2026
1 check passed
@kubestellar-prow
Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign mikespreitzer for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@netlify
Copy link
Copy Markdown

netlify bot commented Apr 7, 2026

Deploy Preview for kubestellarconsole ready!

Name Link
🔨 Latest commit 9e3b051
🔍 Latest deploy log https://app.netlify.com/projects/kubestellarconsole/deploys/69d5595dae37230008c18a8f
😎 Deploy Preview https://deploy-preview-5299.console-deploy-preview.kubestellar.io
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@kubestellar-prow kubestellar-prow bot deleted the feat/ground-control-icon branch April 7, 2026 19:22
@kubestellar-prow kubestellar-prow bot added the size/S Denotes a PR that changes 10-29 lines, ignoring generated files. label Apr 7, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

👋 Hey @clubanderson — thanks for opening this PR!

🤖 This project is developed exclusively using AI coding assistants.

Please do not attempt to code anything for this project manually.
All contributions should be authored using an AI coding tool such as:

This ensures consistency in code style, architecture patterns, test coverage,
and commit quality across the entire codebase.


This is an automated message.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

Thank you for your contribution! Your PR has been merged.

Check out what's new:

Stay connected: Slack #kubestellar-dev | Multi-Cluster Survey

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a visual indicator in the left sidebar to distinguish “Ground Control” custom dashboards by showing a small Satellite icon next to their names (only when the sidebar is expanded), using a localStorage-backed mapping to detect which dashboards are Ground Control–generated.

Changes:

  • Adds Satellite icon rendering next to eligible custom dashboard names when sidebar is expanded.
  • Introduces isGroundControlItem() to detect Ground Control dashboards via kc-ground-control-dashboards localStorage mapping.
  • Adjusts sidebar item name layout to support truncation + inline icon + card count.

Comment on lines +52 to +57
/** Check if a sidebar item's href points to a Ground Control dashboard */
function isGroundControlItem(href: string): boolean {
if (!href.startsWith(CUSTOM_DASHBOARD_PREFIX)) return false
const dashboardId = href.slice(CUSTOM_DASHBOARD_PREFIX.length)
const gcMapping = safeGetJSON<Record<string, unknown>>(STORAGE_KEY_GROUND_CONTROL_DASHBOARDS) ?? {}
return dashboardId in gcMapping
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

safeGetJSON(...) can legally return a primitive (string/number/boolean) if localStorage contains valid JSON of the wrong shape. In that case dashboardId in gcMapping will throw (TypeError: right-hand side of 'in' should be an object) and crash the Sidebar render. Please guard that gcMapping is a non-null object (and ideally a plain record) before checking membership, and prefer Object.hasOwn(...)/hasOwnProperty over the in operator to avoid prototype-chain matches.

Suggested change
/** Check if a sidebar item's href points to a Ground Control dashboard */
function isGroundControlItem(href: string): boolean {
if (!href.startsWith(CUSTOM_DASHBOARD_PREFIX)) return false
const dashboardId = href.slice(CUSTOM_DASHBOARD_PREFIX.length)
const gcMapping = safeGetJSON<Record<string, unknown>>(STORAGE_KEY_GROUND_CONTROL_DASHBOARDS) ?? {}
return dashboardId in gcMapping
function isPlainRecord(value: unknown): value is Record<string, unknown> {
if (typeof value !== 'object' || value === null) return false
const prototype = Object.getPrototypeOf(value)
return prototype === Object.prototype || prototype === null
}
/** Check if a sidebar item's href points to a Ground Control dashboard */
function isGroundControlItem(href: string): boolean {
if (!href.startsWith(CUSTOM_DASHBOARD_PREFIX)) return false
const dashboardId = href.slice(CUSTOM_DASHBOARD_PREFIX.length)
const gcMapping = safeGetJSON<unknown>(STORAGE_KEY_GROUND_CONTROL_DASHBOARDS)
if (!isPlainRecord(gcMapping)) return false
return Object.hasOwn(gcMapping, dashboardId)

Copilot uses AI. Check for mistakes.
Comment on lines +55 to +57
const dashboardId = href.slice(CUSTOM_DASHBOARD_PREFIX.length)
const gcMapping = safeGetJSON<Record<string, unknown>>(STORAGE_KEY_GROUND_CONTROL_DASHBOARDS) ?? {}
return dashboardId in gcMapping
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isGroundControlItem() reads + parses the entire Ground Control mapping from localStorage on every call; in renderNavItem this happens once per sidebar item on every render. Consider reading/parsing the mapping once per render (e.g., in Sidebar() via useMemo/useState + storage listener) and then doing an O(1) lookup for each item to avoid repeated JSON.parse work and repeated console errors if localStorage access is blocked.

Copilot uses AI. Check for mistakes.
Comment on lines +49 to +54
/** Prefix for custom dashboard routes */
const CUSTOM_DASHBOARD_PREFIX = '/custom-dashboard/'

/** Check if a sidebar item's href points to a Ground Control dashboard */
function isGroundControlItem(href: string): boolean {
if (!href.startsWith(CUSTOM_DASHBOARD_PREFIX)) return false
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A new CUSTOM_DASHBOARD_PREFIX constant is introduced here, but the file still uses the literal '/custom-dashboard/' in other checks (e.g., for rename/title logic). To avoid divergence, please switch those other occurrences in this file to use CUSTOM_DASHBOARD_PREFIX as well.

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

Post-merge build verification passed

Both Go and frontend builds compiled successfully against merge commit 42dfe7e2909a3e1f8f2e1578a1ef32507e18d279.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

❌ Post-Merge Verification: failed

Commit: 42dfe7e2909a3e1f8f2e1578a1ef32507e18d279
Specs run: navbar-responsive.spec.ts smoke.spec.ts
Report: https://github.com/kubestellar/console/actions/runs/24100056272

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dco-signoff: yes Indicates the PR's author has signed the DCO. size/S Denotes a PR that changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants