feat: add single-admin application onboarding and token rotation

This commit is contained in:
2026-09-27 10:18:31 +08:00
parent 98ff028228
commit 87aa710013
24 changed files with 1341 additions and 25 deletions

View File

@@ -2,7 +2,7 @@
const state = { token: '', authenticated: false, queue: '', base: location.origin, consoleConfig: null, retention: null, timer: null, connected: false, loading: false, selectedTask: null, actionMode: '', selectedSchedule: null, selectedWorkflow: null, workflowActionMode: '', workflowRecoveryMode: '', workflowRecoveryContext: null, selectedSubscription: null, subscriptionActionMode: '', selectedDelivery: null };
const $ = (id) => document.getElementById(id);
const text = (id, value) => { const el = $(id); if (el) el.textContent = value; };
const pageNames = { overview: '总览', tasks: '任务执行', schedules: '定时计划', workflows: '流程实例', subscriptions: '结果订阅', retention: '保留策略', archives: '归档作业' };
const pageNames = { overview: '总览', tasks: '任务执行', schedules: '定时计划', workflows: '流程实例', subscriptions: '结果订阅', retention: '保留策略', archives: '归档作业', applications: '应用接入' };
function showToast(message) {
const toast = $('toast'); toast.textContent = message; toast.classList.add('show');
@@ -30,6 +30,7 @@
window.scrollTo({ top: 0, behavior: 'smooth' });
if (next === 'retention' && state.authenticated) loadRetention();
if (next === 'archives' && state.authenticated) loadArchives();
if (next === 'applications' && state.authenticated) window.orbitApplications.load();
}
function redirectToLogin() {
const returnTo = `${location.pathname}${location.search}${location.hash}`;
@@ -670,6 +671,7 @@
if (state.loading) return; state.loading = true; $('refresh-button').classList.add('spinning');
try {
await loadHealth();
if (currentView() === 'applications') { await window.orbitApplications.load(); setConnection(true); text('last-updated', `刚刚更新 · ${formatTime(new Date())}`); return; }
if (!state.authenticated || !state.queue) { renderRuntimeStats(null, null, null, null); setConnection(true); text('last-updated', `服务在线 · ${formatTime(new Date())}`); return; }
const tasks = await request(`/v1/tasks?queue_id=${encodeURIComponent(state.queue)}&limit=20`); const taskItems = extractItems(tasks); renderTasks(taskItems);
const optional = await Promise.allSettled([