feat(electrobun): project status dots on group icons (SVG, per-project color by agent status)
This commit is contained in:
parent
41c3bc8e60
commit
ec12310801
4 changed files with 106 additions and 4 deletions
|
|
@ -9,6 +9,7 @@
|
|||
import SearchOverlay from "./SearchOverlay.svelte";
|
||||
import SplashScreen from "./SplashScreen.svelte";
|
||||
import ProjectWizard from "./ProjectWizard.svelte";
|
||||
import GroupStatusDots from "./GroupStatusDots.svelte";
|
||||
import { themeStore } from "./theme-store.svelte.ts";
|
||||
import { fontStore } from "./font-store.svelte.ts";
|
||||
import { keybindingStore } from "./keybinding-store.svelte.ts";
|
||||
|
|
@ -381,10 +382,11 @@
|
|||
aria-label="{group.name} (Ctrl+{i + 1})"
|
||||
title="{group.name} (Ctrl+{i + 1})"
|
||||
>
|
||||
<span class="group-circle" aria-hidden="true">{i + 1}</span>
|
||||
{#if group.hasNew}
|
||||
<span class="group-badge" aria-label="New activity"></span>
|
||||
{/if}
|
||||
<GroupStatusDots
|
||||
projects={group.projects ?? []}
|
||||
groupNumber={i + 1}
|
||||
isActive={getActiveGroupId() === group.id}
|
||||
/>
|
||||
</button>
|
||||
{/each}
|
||||
|
||||
|
|
|
|||
62
ui-electrobun/src/mainview/GroupStatusDots.svelte
Normal file
62
ui-electrobun/src/mainview/GroupStatusDots.svelte
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
<script lang="ts">
|
||||
import { getProjectAgentStatus } from './project-status';
|
||||
import { statusToColor } from './status-colors';
|
||||
|
||||
interface Props {
|
||||
projects: Array<{ id: string }>;
|
||||
groupNumber: number;
|
||||
isActive: boolean;
|
||||
size?: number;
|
||||
}
|
||||
|
||||
let { projects, groupNumber, isActive, size = 32 }: Props = $props();
|
||||
|
||||
function dotColor(projectId: string): string {
|
||||
return statusToColor(getProjectAgentStatus(projectId));
|
||||
}
|
||||
</script>
|
||||
|
||||
<svg
|
||||
viewBox="0 0 32 32"
|
||||
class="group-dots"
|
||||
width={size}
|
||||
height={size}
|
||||
role="img"
|
||||
aria-label="Group {groupNumber} with {projects.length} projects"
|
||||
>
|
||||
<!-- Border circle -->
|
||||
<circle
|
||||
cx="16"
|
||||
cy="16"
|
||||
r="15"
|
||||
fill="none"
|
||||
stroke={isActive ? 'var(--accent, var(--ctp-blue))' : 'var(--ctp-surface1)'}
|
||||
stroke-width="1"
|
||||
/>
|
||||
|
||||
<!-- Number text -->
|
||||
<text
|
||||
x="16"
|
||||
y="16"
|
||||
text-anchor="middle"
|
||||
dominant-baseline="central"
|
||||
font-size="11"
|
||||
font-weight="700"
|
||||
fill={isActive ? 'var(--ctp-text)' : 'var(--ctp-subtext0)'}
|
||||
>{groupNumber}</text>
|
||||
|
||||
<!-- Status dots -->
|
||||
{#each projects as project, i}
|
||||
{@const angle = (i / projects.length) * Math.PI * 2 - Math.PI / 2}
|
||||
{@const cx = 16 + 12 * Math.cos(angle)}
|
||||
{@const cy = 16 + 12 * Math.sin(angle)}
|
||||
<circle cx={cx} cy={cy} r="2.5" fill={dotColor(project.id)} />
|
||||
{/each}
|
||||
</svg>
|
||||
|
||||
<style>
|
||||
.group-dots {
|
||||
display: block;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
</style>
|
||||
24
ui-electrobun/src/mainview/project-status.ts
Normal file
24
ui-electrobun/src/mainview/project-status.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
* Reads agent status for a project from the global agent store.
|
||||
* Returns a ProjectStatus suitable for status dot coloring.
|
||||
*
|
||||
* Reading getSession() touches the _v version counter inside agent-store,
|
||||
* so Svelte 5 will re-evaluate any reactive context that calls this function
|
||||
* when sessions change.
|
||||
*/
|
||||
|
||||
import { getSession } from './agent-store.svelte';
|
||||
import type { ProjectStatus } from './status-colors';
|
||||
|
||||
export function getProjectAgentStatus(projectId: string): ProjectStatus {
|
||||
const session = getSession(projectId);
|
||||
if (!session) return 'inactive';
|
||||
|
||||
switch (session.status) {
|
||||
case 'running': return 'running';
|
||||
case 'done': return 'done';
|
||||
case 'error': return 'error';
|
||||
case 'idle': return 'inactive';
|
||||
default: return 'inactive';
|
||||
}
|
||||
}
|
||||
14
ui-electrobun/src/mainview/status-colors.ts
Normal file
14
ui-electrobun/src/mainview/status-colors.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/**
|
||||
* Pure function mapping project status to a CSS custom property color.
|
||||
*/
|
||||
|
||||
export type ProjectStatus = 'inactive' | 'running' | 'done' | 'error';
|
||||
|
||||
export function statusToColor(status: ProjectStatus): string {
|
||||
switch (status) {
|
||||
case 'running': return 'var(--ctp-green)';
|
||||
case 'done': return 'var(--ctp-peach)';
|
||||
case 'error': return 'var(--ctp-red)';
|
||||
default: return 'var(--ctp-overlay0)';
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue