Add state badges to session card headers
This commit is contained in:
parent
a93475f3ab
commit
298faecf72
1 changed files with 97 additions and 1 deletions
|
|
@ -100,6 +100,60 @@
|
|||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.state-badge {
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.state-ready {
|
||||
background: #6b7280;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.state-thinking {
|
||||
background: #3b82f6;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.state-thinking::after {
|
||||
content: '...';
|
||||
animation: dots 1.5s infinite;
|
||||
}
|
||||
|
||||
@keyframes dots {
|
||||
0%, 20% { content: '.'; }
|
||||
40% { content: '..'; }
|
||||
60%, 100% { content: '...'; }
|
||||
}
|
||||
|
||||
.state-permission {
|
||||
background: #f59e0b;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.state-question {
|
||||
background: #f59e0b;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.state-complete {
|
||||
background: #10b981;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.state-interrupted {
|
||||
background: #ef4444;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.session-cwd {
|
||||
|
|
@ -566,6 +620,7 @@
|
|||
output: '',
|
||||
outputRenderedLength: 0,
|
||||
expanded: false,
|
||||
state: 'ready',
|
||||
});
|
||||
renderSessions();
|
||||
});
|
||||
|
|
@ -602,6 +657,15 @@
|
|||
renderPrompts();
|
||||
});
|
||||
|
||||
es.addEventListener('state', (e) => {
|
||||
const data = JSON.parse(e.data);
|
||||
const session = state.sessions.get(data.session_id);
|
||||
if (session) {
|
||||
session.state = data.state;
|
||||
updateSessionCard(data.session_id);
|
||||
}
|
||||
});
|
||||
|
||||
state.eventSource = es;
|
||||
}
|
||||
|
||||
|
|
@ -615,6 +679,19 @@
|
|||
}
|
||||
};
|
||||
|
||||
function renderStateBadge(sessionState) {
|
||||
const labels = {
|
||||
ready: 'Ready',
|
||||
thinking: 'Thinking',
|
||||
permission: 'Permission Required',
|
||||
question: 'Question',
|
||||
complete: 'Complete',
|
||||
interrupted: 'Interrupted'
|
||||
};
|
||||
const label = labels[sessionState] || sessionState;
|
||||
return `<span class="state-badge state-${sessionState}">${label}</span>`;
|
||||
}
|
||||
|
||||
function renderSessions() {
|
||||
if (state.sessions.size === 0) {
|
||||
$sessions.innerHTML = '<div class="empty-state">No active sessions</div>';
|
||||
|
|
@ -625,7 +702,10 @@
|
|||
<div class="session ${s.expanded ? 'expanded' : ''}" data-session="${s.id}">
|
||||
<div class="session-header" onclick="toggleSession('${s.id}')">
|
||||
<div class="session-info">
|
||||
<div class="session-command">${escapeHtml(s.command || 'claude')}</div>
|
||||
<div class="session-command">
|
||||
<span>${escapeHtml(s.command || 'claude')}</span>
|
||||
${renderStateBadge(s.state || 'ready')}
|
||||
</div>
|
||||
<div class="session-cwd">${escapeHtml(s.cwd || '~')}</div>
|
||||
</div>
|
||||
<div class="session-toggle">▼</div>
|
||||
|
|
@ -655,6 +735,22 @@
|
|||
}
|
||||
}
|
||||
|
||||
function updateSessionCard(sessionId) {
|
||||
const session = state.sessions.get(sessionId);
|
||||
if (!session) return;
|
||||
|
||||
const $sessionCard = document.querySelector(`[data-session="${sessionId}"]`);
|
||||
if ($sessionCard) {
|
||||
const $commandDiv = $sessionCard.querySelector('.session-command');
|
||||
if ($commandDiv) {
|
||||
$commandDiv.innerHTML = `
|
||||
<span>${escapeHtml(session.command || 'claude')}</span>
|
||||
${renderStateBadge(session.state || 'ready')}
|
||||
`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function renderPrompts() {
|
||||
if (state.prompts.size === 0) {
|
||||
$prompts.innerHTML = '<div class="empty-state">No pending prompts</div>';
|
||||
|
|
|
|||
Loading…
Reference in a new issue