<!--
One project: its worktrees side by side, its repositories and boards, its
notes and links, and the sessions run in its worktrees.
The middle level between the machine and a worktree's workbench. What is
shown about each worktree is the home's row with more of it — the path, the
exact commit, the upstream — because this is where worktrees are compared.
-->
<script lang="ts">
import { untrack } from "svelte";
import { levels } from "../../stores/levels.svelte.js";
import WorktreeRow from "./WorktreeRow.svelte";
import NewWorktreeForm from "./NewWorktreeForm.svelte";
import PlacedSessions from "./PlacedSessions.svelte";
import ProjectGitHub from "./ProjectGitHub.svelte";
import AnnotationsPanel from "../annotations/AnnotationsPanel.svelte";
interface Props {
project: string;
}
let { project }: Props = $props();
const found = $derived(levels.project(project));
const home = $derived(levels.home(project));
// The project named is the trigger; what loading it reads is not.
$effect(() => {
const name = project;
untrack(() => {
void levels.ensureLoaded();
void levels.loadProject(name);
});
});
</script>
<div class="project">
<h1>{project}</h1>
{#if levels.loaded && !found}
<p class="empty">There is no project {project} on this machine.</p>
{:else}
{#if found}
<p class="subtle"><code>{found.path}</code>{found.github ? ` · ${found.github}` : " · no GitHub origin"}</p>
{/if}
{#if levels.slotsError}
<p class="slots-error" role="alert">prj could not list its session slots: {levels.slotsError}</p>
{/if}
<section aria-label="Worktrees">
<div class="section-title">Worktrees</div>
<div class="worktrees">
{#each found?.worktrees ?? [] as worktree (worktree.id)}
<article class="worktree-card">
<WorktreeRow {worktree} detailed />
</article>
{/each}
</div>
<div class="new">
<NewWorktreeForm {project} />
</div>
</section>
<div class="columns">
<section aria-label="GitHub">
<div class="section-title">GitHub</div>
<ProjectGitHub {project} />
</section>
<section aria-label="Notes and links">
{#if found?.github}
<AnnotationsPanel about="project:{found.github}" writeInto={home?.id ?? null} />
{:else if found}
<p class="empty">
{project} has no GitHub origin, so notes and links cannot name it: add its GitHub
repository as <code>origin</code> in its main worktree.
</p>
{/if}
</section>
<section aria-label="Sessions">
<div class="section-title">Sessions in its worktrees</div>
<PlacedSessions place={{ project }} limit={30} />
</section>
</div>
{/if}
</div>
<style>
.project {
max-width: 1400px;
margin: 0 auto;
padding: var(--wb-spacing-24) var(--wb-spacing-20);
}
h1 {
font-size: var(--wb-font-size-18);
font-weight: 600;
margin: 0;
color: var(--vscode-editor-foreground);
}
code {
font-family: var(--vscode-editor-font-family, monospace);
}
section {
margin-top: var(--wb-spacing-20);
}
.worktrees {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
gap: var(--wb-spacing-12);
}
.worktree-card {
border: 1px solid var(--vscode-panel-border);
border-radius: var(--wsb-radius-lg);
background: var(--vscode-sideBar-background);
overflow: hidden;
}
.new {
margin-top: var(--wb-spacing-10);
}
.slots-error {
color: var(--wb-error);
font-size: var(--wb-font-size-12);
}
.columns {
display: grid;
grid-template-columns: minmax(240px, 1fr) minmax(280px, 1.5fr) minmax(320px, 2fr);
gap: var(--wb-spacing-24);
}
@media (max-width: 767px) {
.columns {
grid-template-columns: 1fr;
}
}
</style>