document.addEventListener('DOMContentLoaded', function () {
var state = {
items: [],
workspaceId: null,
loading: false,
error: '',
openId: null,
};
var list = document.getElementById('stream-sessions-list');
var summary = document.getElementById('stream-sessions-summary');
var refreshButton = document.getElementById('stream-sessions-refresh');
var statusFilter = document.getElementById('stream-sessions-status');
var modeFilter = document.getElementById('stream-sessions-mode');
function tKey(key, vars) {
if (!window.t) return key;
return t(key, vars);
}
function currentWorkspaceId() {
var workspace = window.getCurrentWorkspace ? window.getCurrentWorkspace() : null;
return workspace ? workspace.id : null;
}
function formatJson(value) {
if (value === null || value === undefined) return '';
if (typeof value === 'string') return value;
return JSON.stringify(value, null, 2);
}
function formatDateTime(value) {
if (!value) return '—';
return new Date(value).toLocaleString();
}
function renderEmpty(title, body) {
list.innerHTML = '
' + title + '
' + body + '
';
}
function render() {
summary.textContent = tKey('stream_sessions.summary', { count: state.items.length });
if (state.loading && state.items.length === 0) {
renderEmpty(tKey('stream_sessions.loading.title'), tKey('stream_sessions.loading.body'));
return;
}
if (state.error) {
renderEmpty(tKey('stream_sessions.error.title'), state.error);
return;
}
if (!state.items.length) {
renderEmpty(tKey('stream_sessions.empty.title'), tKey('stream_sessions.empty.body'));
return;
}
list.innerHTML = state.items.map(function(item) {
var open = state.openId === item.id;
var statusLabel = tKey('stream_sessions.status.' + item.status);
return [
'',
' ',
'
',
open
? '
' + tKey('stream_sessions.cursor') + '
' + formatJson(item.cursor) + '
'
: '',
'
'
].join('');
}).join('');
list.querySelectorAll('[data-action="toggle"]').forEach(function(button) {
button.addEventListener('click', function () {
var sessionId = this.getAttribute('data-session-id');
state.openId = state.openId === sessionId ? null : sessionId;
if (state.openId) {
void loadDetail(sessionId);
} else {
render();
}
});
});
list.querySelectorAll('[data-action="stop"]').forEach(function(button) {
button.addEventListener('click', async function () {
try {
var sessionId = this.getAttribute('data-session-id');
await window.CrankApi.stopStreamSession(state.workspaceId, sessionId);
if (window.CrankUi) {
window.CrankUi.success(tKey('stream_sessions.toast.stop.body'), tKey('stream_sessions.toast.stop.title'));
}
await load();
} catch (error) {
if (window.CrankUi) {
window.CrankUi.error(error.message || tKey('stream_sessions.toast.stop_error.body'), tKey('stream_sessions.toast.stop_error.title'));
}
}
});
});
}
async function loadDetail(sessionId) {
var detail = await window.CrankApi.getStreamSession(state.workspaceId, sessionId);
state.items = state.items.map(function(item) {
return item.id === sessionId ? detail : item;
});
render();
}
async function load() {
state.workspaceId = currentWorkspaceId();
if (!state.workspaceId) {
state.items = [];
state.error = tKey('stream_sessions.error.workspace');
render();
return;
}
state.loading = true;
state.error = '';
render();
try {
var response = await window.CrankApi.listStreamSessions(state.workspaceId, {
status: statusFilter.value || null,
mode: modeFilter.value || null,
page: 1,
page_size: 50,
});
state.items = response.items || [];
} catch (error) {
state.error = error.message || tKey('stream_sessions.error.load');
} finally {
state.loading = false;
render();
}
}
refreshButton.addEventListener('click', load);
statusFilter.addEventListener('change', load);
modeFilter.addEventListener('change', load);
document.addEventListener('workspace:changed', load);
void load();
});