feat: Aggiunto sistema completo di gestione profili per Data Coupler
- Creata nuova libreria Components con componenti Blazor riutilizzabili * ProfileSelector: dropdown per selezione profili salvati * ProfileSaver: componente per salvare configurazioni correnti come profili * ProfileManagement: modale per gestione profili salvati * ProfileQuickActions: bottoni azioni rapide per operazioni sui profili - Esteso CredentialManager con entità e servizi per DataCouplerProfile * Aggiunto modello DataCouplerProfile con configurazioni mapping e metadati * Implementata migrazione Entity Framework per memorizzazione profili * Creato DataCouplerProfileService per operazioni CRUD * Aggiunto CredentialDbContextFactory per operazioni database design-time - Migliorato componente principale DataCoupler con integrazione profili * Integrata funzionalità caricamento/salvataggio profili * Aggiunto selettore profili nella parte superiore dell'interfaccia * Mantenuta retrocompatibilità con funzionalità esistenti * Migliorata esperienza utente con gestione configurazioni salvate - Aggiornata struttura progetto e dipendenze * Aggiunto progetto Components alla soluzione * Aggiornati riferimenti progetti e import * Rimosso progetto obsoleto TestDatabaseFix Questo aggiornamento migliora significativamente il flusso di lavoro permettendo agli utenti di salvare, caricare e gestire configurazioni complete di accoppiamento dati come
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using CredentialManager.Models;
|
||||
|
||||
namespace Components;
|
||||
|
||||
public partial class ProfileManagement
|
||||
{
|
||||
[Parameter] public bool ShowModal { get; set; }
|
||||
[Parameter] public List<DataCouplerProfile>? Profiles { get; set; }
|
||||
[Parameter] public EventCallback OnCloseModal { get; set; }
|
||||
[Parameter] public EventCallback<DataCouplerProfile> OnProfileLoaded { get; set; }
|
||||
[Parameter] public EventCallback<int> OnProfileDeleted { get; set; }
|
||||
[Parameter] public bool IsLoading { get; set; }
|
||||
|
||||
private string SearchTerm { get; set; } = "";
|
||||
private string Message { get; set; } = "";
|
||||
private string MessageType { get; set; } = "info";
|
||||
private bool ShowDeleteConfirm { get; set; } = false;
|
||||
private bool IsDeleting { get; set; } = false;
|
||||
private DataCouplerProfile? ProfileToDelete { get; set; }
|
||||
|
||||
private void FilterProfiles(ChangeEventArgs e)
|
||||
{
|
||||
SearchTerm = e.Value?.ToString() ?? "";
|
||||
}
|
||||
|
||||
private IEnumerable<DataCouplerProfile> GetFilteredProfiles()
|
||||
{
|
||||
if (Profiles == null)
|
||||
return Enumerable.Empty<DataCouplerProfile>();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(SearchTerm))
|
||||
return Profiles;
|
||||
|
||||
var searchLower = SearchTerm.ToLower();
|
||||
return Profiles.Where(p =>
|
||||
p.Name.ToLower().Contains(searchLower) ||
|
||||
(!string.IsNullOrEmpty(p.Description) && p.Description.ToLower().Contains(searchLower))
|
||||
);
|
||||
}
|
||||
|
||||
private string GetTypeLabel(string type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
"database" => "DB",
|
||||
"file" => "File",
|
||||
"rest" => "REST",
|
||||
_ => type.ToUpper()
|
||||
};
|
||||
}
|
||||
|
||||
private string GetProfileSummary(DataCouplerProfile profile)
|
||||
{
|
||||
var parts = new List<string>();
|
||||
|
||||
// Fonte
|
||||
if (!string.IsNullOrEmpty(profile.SourceTable))
|
||||
parts.Add($"da {profile.SourceTable}");
|
||||
else if (!string.IsNullOrEmpty(profile.SourceFilePath))
|
||||
parts.Add($"da {Path.GetFileName(profile.SourceFilePath)}");
|
||||
|
||||
// Destinazione
|
||||
if (!string.IsNullOrEmpty(profile.DestinationTable))
|
||||
parts.Add($"verso {profile.DestinationTable}");
|
||||
else if (!string.IsNullOrEmpty(profile.DestinationEndpoint))
|
||||
parts.Add($"verso {profile.DestinationEndpoint}");
|
||||
|
||||
return string.Join(" ", parts);
|
||||
}
|
||||
|
||||
private async Task CloseModal()
|
||||
{
|
||||
SearchTerm = "";
|
||||
Message = "";
|
||||
await OnCloseModal.InvokeAsync();
|
||||
}
|
||||
|
||||
private async Task LoadProfile(DataCouplerProfile profile)
|
||||
{
|
||||
Message = $"Caricamento profilo '{profile.Name}'...";
|
||||
MessageType = "info";
|
||||
|
||||
await OnProfileLoaded.InvokeAsync(profile);
|
||||
|
||||
Message = $"Profilo '{profile.Name}' caricato con successo!";
|
||||
MessageType = "success";
|
||||
|
||||
// Chiudi il modal dopo un breve delay
|
||||
await Task.Delay(1000);
|
||||
await CloseModal();
|
||||
}
|
||||
|
||||
private void ConfirmDelete(DataCouplerProfile profile)
|
||||
{
|
||||
ProfileToDelete = profile;
|
||||
ShowDeleteConfirm = true;
|
||||
Message = "";
|
||||
}
|
||||
|
||||
private void CancelDelete()
|
||||
{
|
||||
ProfileToDelete = null;
|
||||
ShowDeleteConfirm = false;
|
||||
}
|
||||
|
||||
private async Task DeleteProfile()
|
||||
{
|
||||
if (ProfileToDelete == null)
|
||||
return;
|
||||
|
||||
IsDeleting = true;
|
||||
|
||||
try
|
||||
{
|
||||
await OnProfileDeleted.InvokeAsync(ProfileToDelete.Id);
|
||||
|
||||
Message = $"Profilo '{ProfileToDelete.Name}' eliminato con successo.";
|
||||
MessageType = "success";
|
||||
|
||||
ShowDeleteConfirm = false;
|
||||
ProfileToDelete = null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Message = $"Errore nell'eliminazione: {ex.Message}";
|
||||
MessageType = "danger";
|
||||
}
|
||||
finally
|
||||
{
|
||||
IsDeleting = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetMessage(string message, string type = "info")
|
||||
{
|
||||
Message = message;
|
||||
MessageType = type;
|
||||
}
|
||||
|
||||
public void ClearMessage()
|
||||
{
|
||||
Message = "";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user