Files
Alessio d042863a56 feat: Implementazione completa sistema schedulazione con intervalli personalizzati
- Aggiunto supporto schedulazione con intervalli flessibili (secondi/minuti/ore/giorni/settimane/mesi)
- Esteso modello ProfileSchedule con campi IntervalValue e IntervalUnit
- Ottimizzato ScheduledJobService per controlli ogni 30s con esecuzione parallela
- Implementata interfaccia UI completa con anteprima real-time in italiano
- Aggiunta migrazione database AddIntervalSchedulingFields
- Implementati metodi calcolo NextExecutionTime per intervalli
- Aggiunta gestione tracking anti-duplicati e cleanup automatico
- Creata documentazione completa (6 file, 2500+ righe)

Modifiche tecniche:
- ProfileSchedule.cs: Nuovi campi e metodi CalculateNextInterval/GetScheduleDescription
- ScheduledJobService.cs: Ridotto check interval a 30s, aggiunto parallel processing
- ProfileScheduleService.cs: Supporto calcolo intervalli in UpdateNextExecutionTimeAsync
- Scheduling.razor: Aggiunta sezione UI per configurazione intervalli
- Scheduling.razor.cs: Implementato GetIntervalPreview() e gestione stato campi
2025-10-02 01:12:39 +02:00

201 lines
7.5 KiB
Plaintext

@inject ILogger<SystemTab> Logger
<div class="settings-section">
<h4>
<i class="fas fa-server text-primary me-2"></i>
Configurazione Sistema
</h4>
<p class="text-muted">
Impostazioni generali del sistema Data Coupler.
</p>
<div class="row">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h5 class="card-title mb-0">
<i class="fas fa-database text-info me-2"></i>
Database
</h5>
</div>
<div class="card-body">
<p class="card-text">Configurazione del database principale.</p>
<div class="mb-3">
<label class="form-label">Percorso Database:</label>
<input type="text" class="form-control" value="@GetDatabasePath()" readonly>
<div class="form-text">Percorso del database SQLite di sistema</div>
</div>
<div class="mb-3">
<label class="form-label">Statistiche Database:</label>
<div class="row">
<div class="col-6">
<div class="text-center p-2 bg-light rounded">
<div class="h5 mb-1">@databaseStats.TotalProfiles</div>
<small class="text-muted">Profili</small>
</div>
</div>
<div class="col-6">
<div class="text-center p-2 bg-light rounded">
<div class="h5 mb-1">@databaseStats.TotalCredentials</div>
<small class="text-muted">Credenziali</small>
</div>
</div>
</div>
</div>
<button class="btn btn-outline-primary btn-sm" @onclick="RefreshStats">
<i class="fas fa-refresh me-1"></i>
Aggiorna Statistiche
</button>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h5 class="card-title mb-0">
<i class="fas fa-cogs text-warning me-2"></i>
Performance
</h5>
</div>
<div class="card-body">
<p class="card-text">Impostazioni per ottimizzare le performance.</p>
<div class="mb-3">
<label for="batchSize" class="form-label">Dimensione Batch Predefinita:</label>
<input type="number" class="form-control" id="batchSize" @bind="systemSettings.DefaultBatchSize"
min="1" max="1000" step="1">
<div class="form-text">Numero di record da processare per volta</div>
</div>
<div class="mb-3">
<label for="timeout" class="form-label">Timeout Connessioni (secondi):</label>
<input type="number" class="form-control" id="timeout" @bind="systemSettings.DefaultTimeout"
min="10" max="300" step="5">
</div>
<button class="btn btn-primary btn-sm" @onclick="SaveSystemSettings">
<i class="fas fa-save me-1"></i>
Salva Impostazioni
</button>
</div>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-12">
<div class="card">
<div class="card-header">
<h5 class="card-title mb-0">
<i class="fas fa-info-circle text-success me-2"></i>
Informazioni Sistema
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-3">
<strong>Versione Applicazione:</strong><br>
<span class="badge bg-primary">1.0.0</span>
</div>
<div class="col-md-3">
<strong>Framework:</strong><br>
<span class="badge bg-info">.NET 9.0</span>
</div>
<div class="col-md-3">
<strong>Sistema Operativo:</strong><br>
<span class="badge bg-secondary">@Environment.OSVersion.Platform</span>
</div>
<div class="col-md-3">
<strong>Memoria Utilizzata:</strong><br>
<span class="badge bg-warning">@GetMemoryUsage()</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@code {
[Parameter] public EventCallback<(string message, string type)> OnShowToast { get; set; }
private DatabaseStats databaseStats = new();
private SystemSettings systemSettings = new()
{
DefaultBatchSize = 200,
DefaultTimeout = 30
};
protected override async Task OnInitializedAsync()
{
await RefreshStats();
}
private string GetDatabasePath()
{
// Implementazione semplificata - in un'implementazione reale
// questo dovrebbe venire dalla configurazione
var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
return Path.Combine(documentsPath, "DataCoupler", "credentials.db");
}
private string GetMemoryUsage()
{
var workingSet = Environment.WorkingSet;
return $"{workingSet / 1024 / 1024:F1} MB";
}
private async Task RefreshStats()
{
try
{
// Implementazione semplificata - in produzione collegarsi al database
databaseStats = new DatabaseStats
{
TotalProfiles = Random.Shared.Next(5, 50),
TotalCredentials = Random.Shared.Next(3, 20)
};
await OnShowToast.InvokeAsync(("Statistiche aggiornate", "success"));
StateHasChanged();
}
catch (Exception ex)
{
Logger.LogError(ex, "Errore aggiornamento statistiche");
await OnShowToast.InvokeAsync(("Errore aggiornamento statistiche", "error"));
}
}
private async Task SaveSystemSettings()
{
try
{
// Implementazione semplificata - in produzione salvare nel database o file di configurazione
await Task.Delay(500); // Simula operazione di salvataggio
await OnShowToast.InvokeAsync(("Impostazioni salvate con successo", "success"));
}
catch (Exception ex)
{
Logger.LogError(ex, "Errore salvataggio impostazioni");
await OnShowToast.InvokeAsync(("Errore salvataggio impostazioni", "error"));
}
}
private class DatabaseStats
{
public int TotalProfiles { get; set; }
public int TotalCredentials { get; set; }
}
private class SystemSettings
{
public int DefaultBatchSize { get; set; }
public int DefaultTimeout { get; set; }
}
}