Add instance tab session status indicator
Aggregate session states per instance so tabs reflect permission, compaction, and working activity.
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import { Component } from "solid-js"
|
import { Component, createMemo } from "solid-js"
|
||||||
import type { Instance } from "../types/instance"
|
import type { Instance } from "../types/instance"
|
||||||
|
import { getInstanceSessionIndicatorStatus } from "../stores/session-status"
|
||||||
import { FolderOpen, X } from "lucide-solid"
|
import { FolderOpen, X } from "lucide-solid"
|
||||||
|
|
||||||
interface InstanceTabProps {
|
interface InstanceTabProps {
|
||||||
@@ -26,6 +27,24 @@ function formatFolderName(path: string, instances: Instance[], currentInstance:
|
|||||||
}
|
}
|
||||||
|
|
||||||
const InstanceTab: Component<InstanceTabProps> = (props) => {
|
const InstanceTab: Component<InstanceTabProps> = (props) => {
|
||||||
|
const aggregatedStatus = createMemo(() => getInstanceSessionIndicatorStatus(props.instance.id))
|
||||||
|
const statusClassName = createMemo(() => {
|
||||||
|
const status = aggregatedStatus()
|
||||||
|
return status === "permission" ? "session-permission" : `session-${status}`
|
||||||
|
})
|
||||||
|
const statusTitle = createMemo(() => {
|
||||||
|
switch (aggregatedStatus()) {
|
||||||
|
case "permission":
|
||||||
|
return "Waiting on permission"
|
||||||
|
case "compacting":
|
||||||
|
return "Compacting"
|
||||||
|
case "working":
|
||||||
|
return "Working"
|
||||||
|
default:
|
||||||
|
return "Idle"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="group">
|
<div class="group">
|
||||||
<button
|
<button
|
||||||
@@ -40,7 +59,14 @@ const InstanceTab: Component<InstanceTabProps> = (props) => {
|
|||||||
{props.instance.folder.split("/").pop() || props.instance.folder}
|
{props.instance.folder.split("/").pop() || props.instance.folder}
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="tab-close ml-auto"
|
class={`status-indicator session-status ml-auto ${statusClassName()}`}
|
||||||
|
title={statusTitle()}
|
||||||
|
aria-label={`Instance status: ${statusTitle()}`}
|
||||||
|
>
|
||||||
|
<span class="status-dot" />
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="tab-close"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
props.onClose()
|
props.onClose()
|
||||||
|
|||||||
@@ -170,6 +170,47 @@ export function getSessionStatus(instanceId: string, sessionId: string): Session
|
|||||||
return session.status ?? deriveSessionStatusFromMessages(instanceId, sessionId)
|
return session.status ?? deriveSessionStatusFromMessages(instanceId, sessionId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type InstanceSessionIndicatorStatus = "permission" | SessionStatus
|
||||||
|
|
||||||
|
export function getInstanceSessionIndicatorStatus(instanceId: string): InstanceSessionIndicatorStatus {
|
||||||
|
const instanceSessions = sessions().get(instanceId)
|
||||||
|
if (!instanceSessions || instanceSessions.size === 0) {
|
||||||
|
return "idle"
|
||||||
|
}
|
||||||
|
|
||||||
|
let bestRank = 0
|
||||||
|
let best: InstanceSessionIndicatorStatus = "idle"
|
||||||
|
|
||||||
|
for (const session of instanceSessions.values()) {
|
||||||
|
let rank = 0
|
||||||
|
let status: InstanceSessionIndicatorStatus = "idle"
|
||||||
|
|
||||||
|
if (session.pendingPermission) {
|
||||||
|
status = "permission"
|
||||||
|
rank = 3
|
||||||
|
} else {
|
||||||
|
const sessionStatus = getSessionStatus(instanceId, session.id)
|
||||||
|
if (sessionStatus === "compacting") {
|
||||||
|
status = "compacting"
|
||||||
|
rank = 2
|
||||||
|
} else if (sessionStatus === "working") {
|
||||||
|
status = "working"
|
||||||
|
rank = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rank > bestRank) {
|
||||||
|
bestRank = rank
|
||||||
|
best = status
|
||||||
|
if (bestRank === 3) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return best
|
||||||
|
}
|
||||||
|
|
||||||
export function isSessionBusy(instanceId: string, sessionId: string): boolean {
|
export function isSessionBusy(instanceId: string, sessionId: string): boolean {
|
||||||
const status = getSessionStatus(instanceId, sessionId)
|
const status = getSessionStatus(instanceId, sessionId)
|
||||||
return status === "working" || status === "compacting"
|
return status === "working" || status === "compacting"
|
||||||
|
|||||||
Reference in New Issue
Block a user