@namespace DnsmasqWebUI.Components.EffectiveConfig @using DnsmasqWebUI.Models.Dnsmasq @using DnsmasqWebUI.Models.Dnsmasq.EffectiveConfig @using DnsmasqWebUI.Infrastructure.Services.EffectiveConfig.Abstractions @using DnsmasqWebUI.Infrastructure.Services.UI.Notifications.Abstractions @inject IEffectiveConfigSaveService SaveService @inject INotificationService NotificationService @if (ShowModal) { } @code { public enum SaveUiState { Review, Saving, WriteFailed, ValidateFailed, ReloadFailed, RestoreInProgress, RestoreFailed } [Parameter] public bool ShowModal { get; set; } [Parameter] public IReadOnlyList PendingChanges { get; set; } = null!; [Parameter] public DnsmasqServiceStatus? Status { get; set; } [Parameter] public EventCallback OnClose { get; set; } [Parameter] public EventCallback OnSaveCompleted { get; set; } [Parameter] public EventCallback OnContinueEditingAfterSavedFailure { get; set; } [Parameter] public EventCallback OnCloseAndEndEdit { get; set; } [Parameter] public IEffectiveConfigEditSession Session { get; set; } = null!; private SaveUiState _saveState = SaveUiState.Review; private EffectiveConfigSaveResult? _saveResult; private EffectiveConfigRestoreResult? _restoreResult; protected override void OnParametersSet() { if (!ShowModal) { _saveState = SaveUiState.Review; _saveResult = null; _restoreResult = null; } } private async Task HandleReverted() { await InvokeAsync(StateHasChanged); } private async Task HandleSave() { if (Session.PendingChanges.Count == 0) return; if (Session.HasBlockingValidationErrors()) { NotificationService.ShowError("Fix validation errors before saving."); return; } _saveState = SaveUiState.Saving; _saveResult = null; _restoreResult = null; await InvokeAsync(StateHasChanged); var result = await Session.ApplyAsync(); _saveResult = result; if (result.Saved && result.Restarted) { var message = result.UserMessage ?? "Config saved and dnsmasq restarted."; NotificationService.ShowSuccess(message); _saveState = SaveUiState.Review; _saveResult = null; await OnClose.InvokeAsync(); await OnSaveCompleted.InvokeAsync(); return; } if (result.Saved && result.IsValidateFailed) _saveState = SaveUiState.ValidateFailed; else if (result.Saved && !result.Restarted) _saveState = SaveUiState.ReloadFailed; else if (!result.Saved) _saveState = SaveUiState.WriteFailed; else _saveState = SaveUiState.Review; await InvokeAsync(StateHasChanged); } private async Task HandleRestore(string backupPath) { if (string.IsNullOrEmpty(backupPath)) return; _saveState = SaveUiState.RestoreInProgress; _restoreResult = null; await InvokeAsync(StateHasChanged); var result = await SaveService.RestoreAsync(backupPath); _restoreResult = result; if (result.Restored && result.Restarted) { var message = result.UserMessage ?? "Backup restored and dnsmasq restarted."; NotificationService.ShowSuccess(message); _saveState = SaveUiState.Review; _saveResult = null; _restoreResult = null; await OnCloseAndEndEdit.InvokeAsync(); await OnSaveCompleted.InvokeAsync(); return; } _saveState = SaveUiState.RestoreFailed; await InvokeAsync(StateHasChanged); } private async Task HandleContinueEditing() { if (_saveState == SaveUiState.ValidateFailed || _saveState == SaveUiState.ReloadFailed) { await OnContinueEditingAfterSavedFailure.InvokeAsync(); return; } await OnClose.InvokeAsync(); } private async Task HandleCloseAndEndEdit() { await OnCloseAndEndEdit.InvokeAsync(); if (_saveState == SaveUiState.ValidateFailed || _saveState == SaveUiState.ReloadFailed) await OnSaveCompleted.InvokeAsync(); } }