Add repo-detail panel and /api/repo endpoint
New <repo-detail> component listens for repo:select and shows a repo's remotes, local branches (current + upstream), and recent commits. Backed by GET /api/repo (restricted to indexed repos) and read-only git readers LocalBranches/RecentCommits/RemoteDetails via repos.BuildDetail. <repo-list> highlights the selection; page docks the two panels left/right. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,8 @@ class RepoList extends HTMLElement {
|
||||
#refreshMs = 15000;
|
||||
#timer = null;
|
||||
#controller = null;
|
||||
#repos = [];
|
||||
#selected = null;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@@ -39,6 +41,8 @@ class RepoList extends HTMLElement {
|
||||
}
|
||||
|
||||
#select(repo) {
|
||||
this.#selected = repo.path;
|
||||
this.#renderRepos(this.#repos); // reflect selection highlight
|
||||
// Cross-component communication is via events only (AGENT.md §1.1).
|
||||
this.dispatchEvent(new CustomEvent('repo:select', {
|
||||
detail: repo, bubbles: true, composed: true,
|
||||
@@ -59,6 +63,7 @@ class RepoList extends HTMLElement {
|
||||
display: flex; align-items: center; gap: 12px;
|
||||
}
|
||||
li:hover { border-color: var(--border-strong); }
|
||||
li.selected { border-color: var(--fill-accent); background: var(--surface-2); }
|
||||
.name { font-weight: 600; }
|
||||
.branch { color: var(--color-fg-muted); }
|
||||
.spacer { margin-left: auto; }
|
||||
@@ -83,14 +88,16 @@ class RepoList extends HTMLElement {
|
||||
}
|
||||
|
||||
#renderRepos(repos) {
|
||||
this.#repos = repos || [];
|
||||
const body = this.shadowRoot.getElementById('body');
|
||||
if (!repos || repos.length === 0) {
|
||||
if (this.#repos.length === 0) {
|
||||
body.innerHTML = `<p class="empty">No repositories found. Check GIT_REPO_ROOTS.</p>`;
|
||||
return;
|
||||
}
|
||||
const ul = document.createElement('ul');
|
||||
for (const r of repos) {
|
||||
for (const r of this.#repos) {
|
||||
const li = document.createElement('li');
|
||||
if (r.path === this.#selected) li.classList.add('selected');
|
||||
li.innerHTML = `
|
||||
<span class="name">${this.#esc(r.name)}</span>
|
||||
<span class="branch">${this.#esc(r.branch || '—')}</span>
|
||||
|
||||
@@ -18,6 +18,9 @@ component pattern the rest of the UI follows.
|
||||
## History
|
||||
- 2026-09-19: created — first component; renders name, branch, ahead/behind, and
|
||||
a clean/dirty badge; establishes the shadow-DOM + self-fetch + event pattern.
|
||||
- 2026-09-19: added a selected-item highlight — the clicked repo keeps an
|
||||
accent border/background (the item that `<repo-detail>` is showing). Caches the
|
||||
last `/api/repos` payload so re-selecting re-renders without a refetch.
|
||||
|
||||
## Notes / gotchas
|
||||
- Uses shared design tokens (`--git-*`, `--surface-*`, `--radius*`) for all
|
||||
|
||||
Reference in New Issue
Block a user