238 lines
8.2 KiB
TypeScript
238 lines
8.2 KiB
TypeScript
// file: kb_app/frontend/ts/demo_ws_manager.ts
|
||
|
||
import * as bootstrap from "bootstrap";
|
||
import "simplebar";
|
||
import ResizeObserver from "resize-observer-polyfill";
|
||
import { invoke } from "@tauri-apps/api/core";
|
||
import { listen } from "@tauri-apps/api/event";
|
||
import { debug, takeoverConsole } from "@fltsci/tauri-plugin-tracing";
|
||
|
||
(window as Window & typeof globalThis & { bootstrap?: typeof bootstrap }).bootstrap = bootstrap;
|
||
(window as Window & typeof globalThis & { ResizeObserver?: typeof ResizeObserver }).ResizeObserver = ResizeObserver;
|
||
|
||
type DemoWsManagerEndpointSummary = {
|
||
name: string;
|
||
resolvedUrl: string;
|
||
provider: string;
|
||
roles: string[];
|
||
connectionState: string;
|
||
activeSubscriptionCount: number;
|
||
};
|
||
|
||
type DemoWsManagerSnapshotPayload = {
|
||
endpointCount: number;
|
||
startedCount: number;
|
||
endpoints: DemoWsManagerEndpointSummary[];
|
||
};
|
||
|
||
const endpointCountText = document.querySelector<HTMLSpanElement>("#demoWsManagerEndpointCountText");
|
||
const startedCountText = document.querySelector<HTMLSpanElement>("#demoWsManagerStartedCountText");
|
||
const roleSelect = document.querySelector<HTMLSelectElement>("#demoWsManagerRoleSelect");
|
||
const tableBody = document.querySelector<HTMLTableSectionElement>("#demoWsManagerTableBody");
|
||
const logTextarea = document.querySelector<HTMLTextAreaElement>("#demoWsManagerLogTextarea");
|
||
const startAllButton = document.querySelector<HTMLButtonElement>("#demoWsManagerStartAllButton");
|
||
const stopAllButton = document.querySelector<HTMLButtonElement>("#demoWsManagerStopAllButton");
|
||
const refreshButton = document.querySelector<HTMLButtonElement>("#demoWsManagerRefreshButton");
|
||
const startRoleButton = document.querySelector<HTMLButtonElement>("#demoWsManagerStartRoleButton");
|
||
const stopRoleButton = document.querySelector<HTMLButtonElement>("#demoWsManagerStopRoleButton");
|
||
const clearLogButton = document.querySelector<HTMLButtonElement>("#demoWsManagerClearLogButton");
|
||
|
||
function appendLogLine(line: string): void {
|
||
if (!logTextarea) {
|
||
return;
|
||
}
|
||
const prefix = logTextarea.value.length > 0 ? "\n" : "";
|
||
logTextarea.value += `${prefix}${line}`;
|
||
logTextarea.scrollTop = logTextarea.scrollHeight;
|
||
}
|
||
|
||
function renderSnapshot(snapshot: DemoWsManagerSnapshotPayload): void {
|
||
if (endpointCountText) {
|
||
endpointCountText.textContent = String(snapshot.endpointCount);
|
||
}
|
||
if (startedCountText) {
|
||
startedCountText.textContent = String(snapshot.startedCount);
|
||
}
|
||
if (!tableBody) {
|
||
return;
|
||
}
|
||
|
||
tableBody.innerHTML = "";
|
||
|
||
for (const endpoint of snapshot.endpoints) {
|
||
const row = document.createElement("tr");
|
||
row.innerHTML = `
|
||
<td>
|
||
<div class="fw-semibold">${endpoint.name}</div>
|
||
<div class="small text-body-secondary">${endpoint.resolvedUrl}</div>
|
||
</td>
|
||
<td>${endpoint.provider}</td>
|
||
<td>${endpoint.roles.join(", ")}</td>
|
||
<td>${endpoint.connectionState}</td>
|
||
<td>${endpoint.activeSubscriptionCount}</td>
|
||
`;
|
||
tableBody.appendChild(row);
|
||
}
|
||
}
|
||
|
||
async function refreshSnapshot(): Promise<void> {
|
||
try {
|
||
const snapshot = await invoke<DemoWsManagerSnapshotPayload>("demo_ws_manager_get_snapshot");
|
||
renderSnapshot(snapshot);
|
||
appendLogLine("[ui] refreshed manager snapshot");
|
||
} catch (error) {
|
||
appendLogLine(`[ui] snapshot error: ${String(error)}`);
|
||
}
|
||
}
|
||
|
||
async function loadRoles(): Promise<void> {
|
||
if (!roleSelect) {
|
||
return;
|
||
}
|
||
|
||
roleSelect.innerHTML = "";
|
||
|
||
try {
|
||
const roles = await invoke<string[]>("demo_ws_manager_list_roles");
|
||
for (const role of roles) {
|
||
const option = document.createElement("option");
|
||
option.value = role;
|
||
option.textContent = role;
|
||
roleSelect.appendChild(option);
|
||
}
|
||
} catch (error) {
|
||
appendLogLine(`[ui] list roles error: ${String(error)}`);
|
||
}
|
||
}
|
||
|
||
async function startAll(): Promise<void> {
|
||
try {
|
||
const snapshot = await invoke<DemoWsManagerSnapshotPayload>("demo_ws_manager_start_all");
|
||
renderSnapshot(snapshot);
|
||
} catch (error) {
|
||
appendLogLine(`[ui] start all error: ${String(error)}`);
|
||
}
|
||
}
|
||
|
||
async function stopAll(): Promise<void> {
|
||
try {
|
||
const snapshot = await invoke<DemoWsManagerSnapshotPayload>("demo_ws_manager_stop_all");
|
||
renderSnapshot(snapshot);
|
||
} catch (error) {
|
||
appendLogLine(`[ui] stop all error: ${String(error)}`);
|
||
}
|
||
}
|
||
|
||
async function startRole(): Promise<void> {
|
||
if (!roleSelect || roleSelect.value.trim().length === 0) {
|
||
appendLogLine("[ui] no role selected");
|
||
return;
|
||
}
|
||
|
||
try {
|
||
const snapshot = await invoke<DemoWsManagerSnapshotPayload>("demo_ws_manager_start_role", {
|
||
role: roleSelect.value,
|
||
});
|
||
renderSnapshot(snapshot);
|
||
} catch (error) {
|
||
appendLogLine(`[ui] start role error: ${String(error)}`);
|
||
}
|
||
}
|
||
|
||
async function stopRole(): Promise<void> {
|
||
if (!roleSelect || roleSelect.value.trim().length === 0) {
|
||
appendLogLine("[ui] no role selected");
|
||
return;
|
||
}
|
||
|
||
try {
|
||
const snapshot = await invoke<DemoWsManagerSnapshotPayload>("demo_ws_manager_stop_role", {
|
||
role: roleSelect.value,
|
||
});
|
||
renderSnapshot(snapshot);
|
||
} catch (error) {
|
||
appendLogLine(`[ui] stop role error: ${String(error)}`);
|
||
}
|
||
}
|
||
|
||
document.addEventListener("DOMContentLoaded", async () => {
|
||
void takeoverConsole();
|
||
debug("demo_ws_manager window loaded");
|
||
|
||
const sidebarToggle = document.querySelector<HTMLButtonElement>('#sidebarToggle');
|
||
if (sidebarToggle) {
|
||
// restaurer l’état depuis localStorage
|
||
if (localStorage.getItem('sidebar-toggle') === 'true') {
|
||
document.body.classList.add('sidenav-toggled');
|
||
}
|
||
|
||
sidebarToggle.addEventListener('click', (event) => {
|
||
event.preventDefault();
|
||
document.body.classList.toggle('sidenav-toggled');
|
||
localStorage.setItem('sidebar-toggle', document.body.classList.contains('sidenav-toggled') ? 'true' : 'false');
|
||
});
|
||
}
|
||
|
||
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]');
|
||
Array.from(tooltipTriggerList).map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl));
|
||
const toastElList = document.querySelectorAll('.toast');
|
||
Array.from(toastElList).map(toastEl => new bootstrap.Toast(toastEl));
|
||
const popoverTriggerList = document.querySelectorAll('[data-bs-toggle="popover"]');
|
||
Array.from(popoverTriggerList).map(popoverTriggerEl => new bootstrap.Popover(popoverTriggerEl));
|
||
|
||
const gobackto = location.pathname + location.search;
|
||
|
||
document.querySelectorAll<HTMLAnchorElement>('a[data-setlang]').forEach((a) => {
|
||
const href = a.getAttribute("href");
|
||
if (!href) return; // pas de href => on ignore
|
||
|
||
const url = new URL(href, location.origin);
|
||
url.searchParams.set("gobackto", gobackto);
|
||
|
||
// conserve une URL relative (path + query)
|
||
a.setAttribute("href", url.pathname + "?" + url.searchParams.toString());
|
||
});
|
||
|
||
if (startAllButton) {
|
||
startAllButton.addEventListener("click", () => {
|
||
void startAll();
|
||
});
|
||
}
|
||
if (stopAllButton) {
|
||
stopAllButton.addEventListener("click", () => {
|
||
void stopAll();
|
||
});
|
||
}
|
||
if (refreshButton) {
|
||
refreshButton.addEventListener("click", () => {
|
||
void refreshSnapshot();
|
||
});
|
||
}
|
||
if (startRoleButton) {
|
||
startRoleButton.addEventListener("click", () => {
|
||
void startRole();
|
||
});
|
||
}
|
||
if (stopRoleButton) {
|
||
stopRoleButton.addEventListener("click", () => {
|
||
void stopRole();
|
||
});
|
||
}
|
||
if (clearLogButton && logTextarea) {
|
||
clearLogButton.addEventListener("click", () => {
|
||
logTextarea.value = "";
|
||
});
|
||
}
|
||
|
||
await listen<string>("kb-demo-ws-manager-log", (event) => {
|
||
appendLogLine(event.payload);
|
||
});
|
||
|
||
await listen<DemoWsManagerSnapshotPayload>("kb-demo-ws-manager-snapshot", (event) => {
|
||
renderSnapshot(event.payload);
|
||
});
|
||
|
||
await loadRoles();
|
||
await refreshSnapshot();
|
||
});
|