b9670ae426
- Creato modello FieldMappingEntry per gestione unificata di field mapping e default values - Aggiunta colonna DefaultValuesJson alla tabella DataCouplerProfile (max 4000 caratteri) - Implementata UI con toggle per selezionare modalità Mapping o Default - Supporto per 9 tipi di dati: string, int, long, decimal, double, float, boolean, datetime, datetimeoffset - Aggiornata logica TransformRecordToRestEntity per applicare valori default dopo field mapping - Implementata serializzazione/deserializzazione DefaultValues in DataCouplerProfileService - Sistema completo di salvataggio/caricamento valori default nei profili - Migrazione database AddDefaultValuesJsonToProfile creata e applicata
174 lines
6.2 KiB
C#
174 lines
6.2 KiB
C#
using Microsoft.AspNetCore.Components;
|
|
using CredentialManager.Models;
|
|
using CredentialManager.Services;
|
|
using System.ComponentModel.DataAnnotations;
|
|
|
|
namespace Components;
|
|
|
|
public partial class ProfileSaver
|
|
{
|
|
[Inject] private ICredentialService CredentialService { get; set; } = default!;
|
|
|
|
[Parameter] public bool CanSave { get; set; }
|
|
[Parameter] public string SourceType { get; set; } = "";
|
|
[Parameter] public int? SourceCredentialId { get; set; }
|
|
[Parameter] public string? SourceCredentialName { get; set; }
|
|
[Parameter] public string? SourceDatabaseName { get; set; }
|
|
[Parameter] public string? SourceSchema { get; set; }
|
|
[Parameter] public string? SourceTable { get; set; }
|
|
[Parameter] public string? SourceCustomQuery { get; set; }
|
|
[Parameter] public string? SourceFilePath { get; set; }
|
|
[Parameter] public string DestinationType { get; set; } = "";
|
|
[Parameter] public int? DestinationCredentialId { get; set; }
|
|
[Parameter] public string? DestinationCredentialName { get; set; }
|
|
[Parameter] public string? DestinationSchema { get; set; }
|
|
[Parameter] public string? DestinationTable { get; set; }
|
|
[Parameter] public string? DestinationEndpoint { get; set; }
|
|
[Parameter] public List<FieldMappingDto>? FieldMappings { get; set; }
|
|
[Parameter] public Dictionary<string, (object? Value, string? Type)>? DefaultValues { get; set; }
|
|
[Parameter] public List<ExternalIdRelationshipDto>? ExternalIdRelationships { get; set; }
|
|
[Parameter] public string? SourceKeyField { get; set; }
|
|
[Parameter] public bool UseRecordAssociations { get; set; }
|
|
[Parameter] public EventCallback<DataCouplerProfileDto> OnProfileSaved { get; set; }
|
|
|
|
private bool ShowSaveForm { get; set; } = false;
|
|
private bool IsSaving { get; set; } = false;
|
|
private string SaveMessage { get; set; } = "";
|
|
private string SaveMessageType { get; set; } = "info";
|
|
private ProfileFormModel ProfileData { get; set; } = new();
|
|
|
|
private void ShowSaveDialog()
|
|
{
|
|
ProfileData = new ProfileFormModel();
|
|
ShowSaveForm = true;
|
|
SaveMessage = "";
|
|
}
|
|
|
|
private void CancelSave()
|
|
{
|
|
ShowSaveForm = false;
|
|
SaveMessage = "";
|
|
ProfileData = new();
|
|
}
|
|
|
|
private async Task SaveProfile()
|
|
{
|
|
IsSaving = true;
|
|
SaveMessage = "";
|
|
|
|
try
|
|
{
|
|
// Recupera automaticamente il nome del database dalla connessione attiva
|
|
var sourceDatabaseName = await GetSourceDatabaseNameAsync();
|
|
|
|
var profileDto = new DataCouplerProfileDto
|
|
{
|
|
Name = ProfileData.Name,
|
|
Description = ProfileData.Description,
|
|
SourceType = SourceType,
|
|
SourceCredentialId = SourceCredentialId,
|
|
SourceCredentialName = SourceCredentialName,
|
|
SourceDatabaseName = sourceDatabaseName,
|
|
SourceSchema = SourceSchema,
|
|
SourceTable = SourceTable,
|
|
SourceCustomQuery = SourceCustomQuery,
|
|
SourceFilePath = SourceFilePath,
|
|
DestinationType = DestinationType,
|
|
DestinationCredentialId = DestinationCredentialId,
|
|
DestinationCredentialName = DestinationCredentialName,
|
|
DestinationSchema = DestinationSchema,
|
|
DestinationTable = DestinationTable,
|
|
DestinationEndpoint = DestinationEndpoint,
|
|
FieldMappings = FieldMappings,
|
|
DefaultValues = DefaultValues,
|
|
ExternalIdRelationships = ExternalIdRelationships,
|
|
SourceKeyField = SourceKeyField,
|
|
UseRecordAssociations = UseRecordAssociations
|
|
};
|
|
|
|
await OnProfileSaved.InvokeAsync(profileDto);
|
|
|
|
SaveMessage = $"Profilo '{ProfileData.Name}' salvato con successo!";
|
|
SaveMessageType = "success";
|
|
|
|
// Reset form after successful save
|
|
await Task.Delay(1500); // Show success message briefly
|
|
ShowSaveForm = false;
|
|
ProfileData = new();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
SaveMessage = $"Errore nel salvataggio: {ex.Message}";
|
|
SaveMessageType = "danger";
|
|
}
|
|
finally
|
|
{
|
|
IsSaving = false;
|
|
}
|
|
}
|
|
|
|
private string GetSourceSummary()
|
|
{
|
|
return SourceType switch
|
|
{
|
|
"database" => "Database",
|
|
"file" => "File Excel/CSV",
|
|
_ => "Non configurato"
|
|
};
|
|
}
|
|
|
|
private string GetDestinationSummary()
|
|
{
|
|
return DestinationType switch
|
|
{
|
|
"database" => "Database",
|
|
"rest" => "REST API",
|
|
_ => "Non configurato"
|
|
};
|
|
}
|
|
|
|
public void SetMessage(string message, string type = "info")
|
|
{
|
|
SaveMessage = message;
|
|
SaveMessageType = type;
|
|
}
|
|
|
|
private async Task<string?> GetSourceDatabaseNameAsync()
|
|
{
|
|
// Prima priorità: se SourceDatabaseName è già impostato come parametro, usa quello
|
|
if (!string.IsNullOrEmpty(SourceDatabaseName))
|
|
{
|
|
return SourceDatabaseName;
|
|
}
|
|
|
|
// Seconda priorità: se abbiamo un SourceCredentialId, recupera il database dalle credenziali
|
|
if (SourceCredentialId.HasValue)
|
|
{
|
|
try
|
|
{
|
|
var credential = await CredentialService.GetDatabaseCredentialAsync(SourceCredentialId.Value);
|
|
if (credential != null && !string.IsNullOrEmpty(credential.DatabaseName))
|
|
{
|
|
return credential.DatabaseName;
|
|
}
|
|
}
|
|
catch (Exception)
|
|
{
|
|
// Se non riesce a recuperare le credenziali, continua con null
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public class ProfileFormModel
|
|
{
|
|
[Required(ErrorMessage = "Il nome del profilo è obbligatorio")]
|
|
[StringLength(100, ErrorMessage = "Il nome non può superare i 100 caratteri")]
|
|
public string Name { get; set; } = "";
|
|
|
|
[StringLength(500, ErrorMessage = "La descrizione non può superare i 500 caratteri")]
|
|
public string? Description { get; set; }
|
|
}
|
|
}
|