68 lines
2.1 KiB
JavaScript
68 lines
2.1 KiB
JavaScript
/**
|
|
* Sidebar — session list + health indicator
|
|
*/
|
|
|
|
import { state, selectSession, deleteSession, createSession } from '../app.js';
|
|
import { api } from '../api.js';
|
|
import { openSessionForm } from './session-form.js';
|
|
|
|
let listEl;
|
|
let healthDot;
|
|
let healthText;
|
|
|
|
export function initSidebar() {
|
|
const sidebar = document.getElementById('sidebar');
|
|
|
|
sidebar.innerHTML = `
|
|
<div class="sidebar-header">
|
|
<h3>Sessions</h3>
|
|
<button class="btn btn-sm btn-primary" id="btn-new-session">+ New</button>
|
|
</div>
|
|
<div class="session-list" id="session-list"></div>
|
|
<div class="sidebar-footer">
|
|
<span class="status-dot disconnected" id="health-dot"></span>
|
|
<span id="health-text">Connecting...</span>
|
|
</div>
|
|
`;
|
|
|
|
listEl = document.getElementById('session-list');
|
|
healthDot = document.getElementById('health-dot');
|
|
healthText = document.getElementById('health-text');
|
|
|
|
document.getElementById('btn-new-session').addEventListener('click', openSessionForm);
|
|
|
|
// Health updates
|
|
api.on('health', (e) => {
|
|
const ok = e.detail.status === 'ok';
|
|
healthDot.className = `status-dot ${ok ? 'connected' : 'disconnected'}`;
|
|
healthText.textContent = ok ? 'Connected' : 'Disconnected';
|
|
});
|
|
}
|
|
|
|
export function renderSessions() {
|
|
if (!listEl) return;
|
|
|
|
listEl.innerHTML = '';
|
|
for (const sid of state.sessions) {
|
|
const item = document.createElement('div');
|
|
item.className = `session-item${sid === state.activeSessionId ? ' active' : ''}`;
|
|
item.innerHTML = `
|
|
<span class="status-dot idle"></span>
|
|
<span class="truncate">${sid.substring(0, 12)}...</span>
|
|
<button class="delete-btn" title="Delete session">×</button>
|
|
`;
|
|
|
|
item.querySelector('.truncate').addEventListener('click', () => selectSession(sid));
|
|
item.querySelector('.delete-btn').addEventListener('click', (e) => {
|
|
e.stopPropagation();
|
|
if (confirm('Delete this session?')) deleteSession(sid);
|
|
});
|
|
|
|
listEl.appendChild(item);
|
|
}
|
|
|
|
if (state.sessions.length === 0) {
|
|
listEl.innerHTML = '<div class="text-muted text-sm" style="padding:20px 10px;text-align:center">No sessions yet</div>';
|
|
}
|
|
}
|