Skip to content

✨ Fix refresh + add CNCF project icons on files in Mission Explorer#4071

Merged
clubanderson merged 2 commits intomainfrom
fix/ux-source-pr-buttons
Apr 1, 2026
Merged

✨ Fix refresh + add CNCF project icons on files in Mission Explorer#4071
clubanderson merged 2 commits intomainfrom
fix/ux-source-pr-buttons

Conversation

@clubanderson
Copy link
Copy Markdown
Collaborator

Summary

Refresh button fix:

  • Rewrote onRefresh to call GitHub Contents API directly instead of going through toggleNode (which had stale closure issues causing collapse/expand without re-fetching)
  • Spinner animates during fetch, node stays expanded

CNCF project icons:

  • Files in the tree sidebar show the project's GitHub avatar when a CNCF project is detected from the filename (e.g., argocd-application.yaml → Argo CD logo)
  • 28 project patterns supported: argo, flux, karmada, prometheus, cert-manager, istio, ray, keda, crossplane, velero, falco, harbor, knative, strimzi, etc.
  • Falls back to generic file-type icons (orange YAML, green MD, blue JSON) when no project match

Test plan

  • Click refresh on sample-runbooks → spinner shows, files re-load (no collapse/expand)
  • argocd-application.yaml shows Argo CD avatar icon
  • fluxcd-helmrelease.yaml shows FluxCD avatar icon
  • karmada-propagation.yaml shows Karmada avatar icon
  • ray-cluster.yaml shows Ray Project avatar icon
  • multi-project.yaml has no specific project match → generic orange YAML icon

- Remove source, PR, and delete buttons from file rows in tree sidebar
  (delete stays on repo-level directory nodes only)
- Add Source and PR buttons in the MissionDetailView header alongside
  Share/View Raw/Import — opens GitHub view/edit in new tab
- Pass githubSourceUrl and githubEditUrl from MissionBrowser to detail view

Signed-off-by: Andrew Anderson <andy@clubanderson.com>
Refresh button:
- Rewrote onRefresh to fetch contents directly via GitHub Contents API
  instead of going through toggleNode (which had stale closure issues
  causing it to just collapse/expand without re-fetching)
- Shows loading spinner during fetch, keeps node expanded

Project icons on files:
- Detects CNCF project from filename using regex patterns (argo, flux,
  karmada, prometheus, cert-manager, istio, ray, etc.)
- Shows GitHub org avatar (32px) as the file icon when a project match
  is found, falls back to generic FileCode/FileText/FileJson icons

Signed-off-by: Andrew Anderson <andy@clubanderson.com>
Copilot AI review requested due to automatic review settings April 1, 2026 03:29
@kubestellar-prow kubestellar-prow bot added the dco-signoff: yes Indicates the PR's author has signed the DCO. label Apr 1, 2026
@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 clubanderson 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

@clubanderson clubanderson merged commit a826ce3 into main Apr 1, 2026
9 checks passed
@netlify
Copy link
Copy Markdown

netlify bot commented Apr 1, 2026

Deploy Preview for kubestellarconsole ready!

Name Link
🔨 Latest commit 9a9f145
🔍 Latest deploy log https://app.netlify.com/projects/kubestellarconsole/deploys/69cc9104aade070008aa5850
😎 Deploy Preview https://deploy-preview-4071.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 fix/ux-source-pr-buttons branch April 1, 2026 03:29
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 1, 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.

@kubestellar-prow kubestellar-prow bot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Apr 1, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 1, 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

Updates the Mission Explorer UI to improve GitHub tree refresh behavior and enrich file nodes with CNCF project visual cues, while also exposing GitHub “Source” and “PR” links from the mission detail panel.

Changes:

  • Reworked the tree node refresh handler to fetch GitHub contents directly (avoiding toggleNode stale-closure behavior) and keep a loading spinner active during refresh.
  • Added GitHub “Source” and “PR” buttons to MissionDetailView, derived from the selected GitHub path.
  • Added filename-based CNCF project detection to display GitHub org avatar icons for matching files in the tree.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
web/src/components/missions/MissionDetailView.tsx Adds optional GitHub Source/Edit URLs and renders header links.
web/src/components/missions/MissionBrowser.tsx Refactors refresh to direct GitHub Contents API calls; derives Source/Edit URLs from selected GitHub node id.
web/src/components/missions/browser/TreeNodeItem.tsx Adds filename→CNCF org detection and renders GitHub avatar icons for matching files; removes per-file GitHub action buttons.

Comment on lines +1433 to +1450
// Fetch fresh contents directly (bypass toggleNode to avoid stale closure issues)
let children: TreeNode[] = []
if (child.source === 'github' && child.id !== 'github') {
const repoPath = child.path
const { data: ghEntries } = await api.get<Array<{ name: string; path: string; type: string; size?: number }>>(
`/api/github/repos/${repoPath}/contents`
)
children = (ghEntries || [])
.filter(e => e.type === 'dir' || isMissionFile(e.name))
.map(e => ({
id: `${child.id}/${e.name}`,
name: e.name,
path: `${repoPath.split('/').slice(0, 2).join('/')}/${e.path}`,
type: (e.type === 'dir' ? 'directory' : 'file') as TreeNode['type'],
source: 'github' as const,
loaded: e.type !== 'dir',
}))
}
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

onRefresh is wired up for both GitHub and Local nodes, but the implementation only re-fetches children for child.source === 'github'. For local watched paths this will always set children to [] and mark the node as empty/loaded, effectively wiping the listing. Either implement a local re-scan here (matching the intended behavior in the prop doc) or restrict onRefresh to GitHub until local browsing is supported.

Copilot uses AI. Check for mistakes.
Comment on lines +1456 to +1459
} catch {
setTreeNodes((prev) =>
updateNodeInTree(prev, child.id, { children: [], loaded: true, loading: false, isEmpty: true })
)
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

The refresh catch path marks the node as loaded: true + isEmpty: true and clears children, but it drops the more descriptive failure marker used in toggleNode (e.g., 'Failed to load — check network or GitHub rate limits'). Consider preserving existing children on failure and/or setting a description (and possibly a toast) so users can tell a refresh failed instead of thinking the folder is empty.

Copilot uses AI. Check for mistakes.
Comment on lines +1624 to +1629
const [owner, repo, ...rest] = parts
const filePath = rest.join('/')
return {
githubSourceUrl: `https://github.com/${owner}/${repo}/blob/main/${filePath}`,
githubEditUrl: `https://github.com/${owner}/${repo}/edit/main/${filePath}`,
}
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

The generated GitHub URLs hard-code main (/blob/main/... and /edit/main/...). This will be broken for repos whose default branch is not main (e.g., master, trunk, or a custom branch). Consider deriving the default branch from the GitHub API response (repo metadata) and using that here, or omit the links when the branch can’t be determined reliably.

Suggested change
const [owner, repo, ...rest] = parts
const filePath = rest.join('/')
return {
githubSourceUrl: `https://github.com/${owner}/${repo}/blob/main/${filePath}`,
githubEditUrl: `https://github.com/${owner}/${repo}/edit/main/${filePath}`,
}
// We cannot reliably determine the repository's default branch here,
// so avoid constructing GitHub URLs that might be broken.
return {}

Copilot uses AI. Check for mistakes.
Comment on lines +138 to +143
<img
src={`https://github.com/${projectOrg}.png?size=32`}
alt={projectOrg}
className="w-4 h-4 rounded-sm flex-shrink-0"
onError={(e) => { (e.target as HTMLImageElement).style.display = 'none' }}
/>
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

If the GitHub avatar request fails, the onError handler hides the <img> but doesn’t render a fallback icon, so the file ends up with no icon at all. It would be more robust to fall back to the existing generic file-type icon (YAML/MD/JSON) when the avatar can’t be loaded (and optionally add loading="lazy" / decoding="async" to reduce the impact of many avatar requests in large trees).

Copilot uses AI. Check for mistakes.
@clubanderson
Copy link
Copy Markdown
Collaborator Author

🔄 Auto-Applying Copilot Code Review

Copilot code review found 1 code suggestion(s) and 3 general comment(s).

@copilot Please apply all of the following code review suggestions:

  • web/src/components/missions/MissionBrowser.tsx (line 1629): // We cannot reliably determine the repository's default branch here, ...

Also address these general comments:

  • web/src/components/missions/MissionBrowser.tsx (line 1450): onRefresh is wired up for both GitHub and Local nodes, but the implementation only re-fetches children for `child.sour
  • web/src/components/missions/MissionBrowser.tsx (line 1459): The refresh catch path marks the node as loaded: true + isEmpty: true and clears children, but it drops the more d
  • web/src/components/missions/browser/TreeNodeItem.tsx (line 143): If the GitHub avatar request fails, the onError handler hides the <img> but doesn’t render a fallback icon, so the f

Push all fixes in a single commit. Run cd web && npm run build && npm run lint before committing.


Auto-generated by copilot-review-apply workflow.

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/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants