d042863a56
- 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
201 lines
7.5 KiB
Plaintext
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; }
|
|
}
|
|
}
|