// file: crates/ksp-app-config-desk/frontend/ts/environment.ts // version: 1 //! Safe environment report panel backed exclusively by ConfigManagement::environment_report(). import DataTable from "datatables.net-bs5"; import "datatables.net-bs5/css/dataTables.bootstrap5.css"; import type { ConfigEnvironmentReportDto } from "./bindings/ksp_app_config_desk/environment/ConfigEnvironmentReportDto"; import { frontendDebug, frontendTrace } from "./frontend_log"; import { invokeKsp } from "./invoke"; interface EnvironmentDataTable { destroy(): unknown; } let environmentTable: EnvironmentDataTable | null = null; function setEnvironmentStatus(message: string, tone: "primary" | "success" | "warning" | "danger" = "primary"): void { const status = document.querySelector("#environmentStatus"); if (!status) { return; } status.className = `alert alert-${tone} mb-0`; status.textContent = message; frontendTrace("main", "Environment panel status replaced", { tone }); } function sensitivityLabel(value: string): string { if (value === "public") { return "Public"; } if (value === "internal") { return "Internal"; } if (value === "secret") { return "Secret"; } return value; } function sourceLabel(value: string): string { if (value === "process") { return "process"; } if (value === "dotenv") { return "dotenv"; } if (value === "fallback") { return "fallback"; } return "—"; } function safeValue(value: string | null): string { return value ?? "—"; } function appendCell(row: HTMLTableRowElement, text: string, className?: string): void { const cell = document.createElement("td"); cell.textContent = text; if (className) { cell.className = className; } row.append(cell); } function populateTableRows(reports: ConfigEnvironmentReportDto[]): void { const body = document.querySelector("#environmentReportTable tbody"); if (!body) { return; } body.replaceChildren(); for (const report of reports) { const row = document.createElement("tr"); appendCell(row, report.variableName, "font-monospace"); appendCell(row, report.namespace); appendCell(row, sensitivityLabel(report.sensitivity)); appendCell(row, safeValue(report.desiredSafeValue), "font-monospace text-break"); appendCell(row, safeValue(report.effectiveSafeValue), "font-monospace text-break"); appendCell(row, sourceLabel(report.effectiveSource)); appendCell(row, report.shadowedByProcessEnvironment ? "oui" : "non"); body.append(row); } frontendTrace("main", "Environment report table DOM replaced", { variableCount: reports.length }); } function initializeDataTable(): void { if (environmentTable) { environmentTable.destroy(); environmentTable = null; } environmentTable = new DataTable("#environmentReportTable", { order: [[0, "asc"]], pageLength: 10, language: { emptyTable: "Aucune variable KSP/KSPB présente dans process ou .env.", info: "_START_ à _END_ sur _TOTAL_ variable(s)", infoEmpty: "0 variable", lengthMenu: "Afficher _MENU_", search: "Filtrer :", zeroRecords: "Aucune variable correspondante.", }, }) as unknown as EnvironmentDataTable; frontendTrace("main", "DataTables Environment initialized"); } async function refreshEnvironmentReport(): Promise { frontendDebug("main", "Config environment report refresh requested"); setEnvironmentStatus("Chargement du rapport environnement sûr...", "primary"); try { const reports = await invokeKsp("main", "get_environment_report"); populateTableRows(reports); initializeDataTable(); const shadowedCount = reports.filter(report => report.shadowedByProcessEnvironment).length; setEnvironmentStatus(`${reports.length} variable(s) KSP/KSPB évaluée(s) par Config ; ${shadowedCount} valeur(s) .env shadowed.`, "success"); frontendDebug("main", "Config environment report refresh completed", { variableCount: reports.length, shadowedCount, }); } catch { setEnvironmentStatus("Le rapport environnement n'a pas pu être chargé par Config.", "danger"); } } function bindEnvironmentActions(): void { document.querySelector("#refreshEnvironment")?.addEventListener("click", () => { frontendTrace("main", "Environment refresh button clicked"); void refreshEnvironmentReport(); }); frontendTrace("main", "Environment panel handlers installed"); } export function initializeEnvironmentPanel(): void { bindEnvironmentActions(); void refreshEnvironmentReport(); }