v0.1.4-pre.015-fix.002

This commit is contained in:
2026-08-16 18:20:32 +02:00
parent 05c65a12f4
commit 9ad61b40e1
25 changed files with 776 additions and 210 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: crates/ksp-app-config-desk/frontend/main.html -->
<!-- version: 12 -->
<!-- version: 13 -->
<!DOCTYPE html>
<html lang="fr">
@@ -300,8 +300,8 @@
<section id="loggingPanel" hidden aria-label="Logging Config">
<div class="d-flex flex-wrap gap-2 align-items-center justify-content-between mb-3">
<div>
<h2 class="h5 mb-1">Logging editor — mutations/persistence</h2>
<p class="text-body-secondary small mb-0">Brouillon typé de <code>std.logging.json</code>, validé et persisté atomiquement par <code>ksp-config-lib</code>. Sauvegarder ou recharger le document ne reconfigure pas le runtime Logging déjà actif.</p>
<h2 class="h5 mb-1">Logging editor — mutations/persistence/hot reload</h2>
<p class="text-body-secondary small mb-0">Brouillon typé de <code>std.logging.json</code>, validé et persisté atomiquement par <code>ksp-config-lib</code>. <strong>Sauvegarder et appliquer</strong> hot-reload le runtime KSP sans redémarrage ; <strong>Recharger le document</strong> ne touche qu'au brouillon.</p>
</div>
<div class="d-flex gap-2">
<button id="refreshLoggingDocument" class="btn btn-outline-primary btn-sm" type="button">
@@ -412,7 +412,7 @@
<div class="d-flex align-items-center justify-content-between gap-2 mb-2">
<div>
<h3 class="h6 mb-0">Fichiers</h3>
<div class="form-text">0, 1 ou plusieurs sinks persistants. Les suppressions restent dans le brouillon jusqu'à Sauvegarder.</div>
<div class="form-text">0, 1 ou plusieurs sinks persistants. Les suppressions restent dans le brouillon jusqu'à Sauvegarder et appliquer.</div>
</div>
<button id="addLoggingFile" class="btn btn-outline-primary btn-sm" type="button" disabled>Ajouter un fichier</button>
</div>
@@ -438,9 +438,9 @@
</section>
<div class="alert alert-warning small py-2 mb-2" role="note">
<strong>Runtime actif :</strong> le subscriber <code>tracing</code> a été construit au démarrage de l'application. Les boutons <strong>Sauvegarder</strong> et <strong>Recharger le document</strong> agissent uniquement sur <code>std.logging.json</code>. Pour appliquer la source persistée en <code>pre.015</code>, il faut redémarrer l'application ; le hot reload sans redémarrage arrive en <code>pre.016</code>.
<strong>Runtime actif :</strong> <strong>Sauvegarder et appliquer</strong> persiste le candidat puis hot-reload immédiatement le subscriber KSP avec un environnement frais. En cas d'échec d'application, l'ancien runtime reste actif et la source précédente est restaurée. <strong>Recharger le document</strong> resynchronise uniquement le brouillon.
</div>
<div id="loggingSaveReport" class="small text-body-secondary mb-2">Aucune sauvegarde effectuée pendant ce lancement ; runtime actif inchangé.</div>
<div id="loggingSaveReport" class="small text-body-secondary mb-2">Aucune sauvegarde/application effectuée pendant ce lancement.</div>
<div id="loggingStatus" class="alert alert-primary mb-0" role="status" aria-live="polite">Chargement du document Logging typé...</div>
</section>
@@ -481,7 +481,7 @@
</div>
<div class="modal-body">
<p class="mb-2">Retirer le profil <code id="loggingProfileDeleteName" class="font-monospace"></code> du brouillon Logging ?</p>
<p class="text-body-secondary small mb-0">Le fichier n'est pas modifié tant que Sauvegarder n'est pas déclenché.</p>
<p class="text-body-secondary small mb-0">Le fichier n'est pas modifié tant que Sauvegarder et appliquer n'est pas déclenché.</p>
</div>
<div class="modal-footer">
<button class="btn btn-outline-secondary" type="button" data-bs-dismiss="modal">Annuler</button>

View File

@@ -1,7 +1,7 @@
// file: crates/ksp-app-config-desk/frontend/ts/logging.ts
// version: 3
// version: 4
//! Typed Logging editor backed exclusively by ConfigManagement validation and persistence.
//! Typed Logging editor backed by ConfigManagement persistence and KSP-owned runtime hot reload.
import { Modal } from "bootstrap";
import type { LoggingDocumentCandidateDto } from "./bindings/ksp_app_config_desk/logging/LoggingDocumentCandidateDto";
@@ -503,8 +503,8 @@ async function saveLoggingDocument(): Promise<void> {
draft.logsDirectory = inputValue("#loggingLogsDirectoryInput");
draft.defaultProfile = selectedValue("#loggingDefaultProfileSelect");
setEditorEnabled(false);
setLoggingStatus("Validation et sauvegarde atomique du document Logging...");
frontendDebug("main", "Typed Logging document persistence requested", {
setLoggingStatus("Validation, sauvegarde atomique et application hot reload du Logging...");
frontendDebug("main", "Typed Logging document persistence and runtime apply requested", {
profileCount: draft.profiles.length,
defaultProfile: draft.defaultProfile,
fileCount: draft.profiles.reduce((count, profile) => count + profile.files.length, 0),
@@ -512,21 +512,28 @@ async function saveLoggingDocument(): Promise<void> {
try {
const result = await invokeKsp<LoggingDocumentSaveResultDto>("main", "save_logging_document", { candidate: draft });
renderDocument(result.document);
setText("#loggingSaveReport", `source_changed=${result.sourceChanged} · reload_required=${result.reloadRequired} · document persisté · runtime actif inchangé`);
setText(
"#loggingSaveReport",
`source_changed=${result.sourceChanged} · reload_required=${result.reloadRequired} · runtime_applied=${result.runtimeApplied} · generation=${result.loggingGeneration} · active_profile=${result.activeProfile}`,
);
setLoggingStatus(
result.sourceChanged
? "Document Logging validé et persisté. Le subscriber actif conserve la configuration du démarrage jusqu'au redémarrage de l'application ou au hot reload de pre.016."
: "Document Logging valide mais source inchangée. Le runtime actif n'a pas été reconfiguré.",
`Document Logging validé, persisté et appliqué sans redémarrage. Runtime génération ${result.loggingGeneration}, profil ${result.activeProfile}.`,
"success",
);
frontendDebug("main", "Typed Logging document persistence completed", {
frontendDebug("main", "Typed Logging document persistence and runtime apply completed", {
sourceChanged: result.sourceChanged,
reloadRequired: result.reloadRequired,
runtimeApplied: result.runtimeApplied,
loggingGeneration: result.loggingGeneration,
activeProfile: result.activeProfile,
profileCount: result.document.profiles.length,
});
} catch {
setEditorEnabled(true);
setLoggingStatus("Candidat Logging refusé. std.logging.json reste inchangé ; corrige le brouillon puis réessaie.", "danger");
setLoggingStatus(
"Sauvegarde/application Logging refusée. Le runtime précédent est conservé ; si la persistence avait commencé, la transaction restaure la source précédente ou remonte une erreur de rollback.",
"danger",
);
}
}
@@ -562,7 +569,7 @@ async function refreshLoggingDocument(source: "startup" | "user"): Promise<void>
const documentDto = await invokeKsp<LoggingDocumentDto>("main", "get_logging_document");
renderDocument(documentDto);
setLoggingStatus(
`${documentDto.profiles.length} profil(s) Logging chargé(s). Le brouillon est synchronisé avec la source persistée ; le runtime actif reste celui du démarrage.`,
`${documentDto.profiles.length} profil(s) Logging chargé(s). Le brouillon est synchronisé avec la source persistée ; cette action ne modifie pas le runtime actif.`,
"success",
);
frontendDebug("main", "Logging document reload completed", {