@* Optional system fields that are not currently visible *@
@foreach (var field in OptionalSystemFields.Where(f => !VisibleFieldKeys.Contains(f.FieldKey)))
{
}
@* Optional sections (2FA, Attachments) *@
@if (!Show2FA && HasLoginFields)
{
}
@if (!ShowAttachments)
{
}
@* Custom field option - always available *@
}
@* Custom Field Modal *@
@code {
private IStringLocalizer Localizer => LocalizerFactory.Create("Components.Main.Items.AddFieldMenu", "AliasVault.Client");
///
/// Optional system fields for the current item type.
///
[Parameter]
public IEnumerable OptionalSystemFields { get; set; } = [];
///
/// Field keys that are currently visible.
///
[Parameter]
public HashSet VisibleFieldKeys { get; set; } = [];
///
/// Whether the 2FA section is currently visible.
///
[Parameter]
public bool Show2FA { get; set; }
///
/// Whether the attachments section is currently visible.
///
[Parameter]
public bool ShowAttachments { get; set; }
///
/// Whether the current item type has login fields (determines if 2FA option is shown).
///
[Parameter]
public bool HasLoginFields { get; set; }
///
/// Callback when a system field is added.
///
[Parameter]
public EventCallback OnAddSystemField { get; set; }
///
/// Callback when a custom field is added. Parameters: (label, fieldType).
///
[Parameter]
public EventCallback<(string Label, string FieldType)> OnAddCustomField { get; set; }
///
/// Current count of custom fields, used for auto-generating default labels.
///
[Parameter]
public int CustomFieldCount { get; set; }
///
/// Callback when 2FA section is added.
///
[Parameter]
public EventCallback OnAdd2FA { get; set; }
///
/// Callback when attachments section is added.
///
[Parameter]
public EventCallback OnAddAttachments { get; set; }
private bool IsOpen { get; set; }
private bool ShowCustomFieldModal { get; set; }
private string CustomFieldLabel { get; set; } = string.Empty;
private string CustomFieldType { get; set; } = "Text";
private void ToggleMenu()
{
IsOpen = !IsOpen;
}
private void CloseMenu()
{
IsOpen = false;
}
private async Task HandleAddSystemField(string fieldKey)
{
await OnAddSystemField.InvokeAsync(fieldKey);
CloseMenu();
}
private async Task HandleAdd2FA()
{
await OnAdd2FA.InvokeAsync();
CloseMenu();
}
private async Task HandleAddAttachments()
{
await OnAddAttachments.InvokeAsync();
CloseMenu();
}
private async Task OpenCustomFieldModal()
{
ShowCustomFieldModal = true;
// Auto-generate a default label based on existing custom field count
CustomFieldLabel = string.Format(Localizer["DefaultFieldLabel"].Value, CustomFieldCount + 1);
CustomFieldType = "Text";
CloseMenu();
// Wait for the modal to render, then focus and select the input text
await Task.Delay(50);
await JsInteropService.FocusAndSelectElementById("custom-field-label-input");
}
private Task CloseCustomFieldModal()
{
ShowCustomFieldModal = false;
CustomFieldLabel = string.Empty;
CustomFieldType = "Text";
return Task.CompletedTask;
}
private async Task HandleAddCustomField()
{
if (!string.IsNullOrWhiteSpace(CustomFieldLabel))
{
await OnAddCustomField.InvokeAsync((CustomFieldLabel.Trim(), CustomFieldType));
await CloseCustomFieldModal();
}
}
private string GetFieldLabel(string fieldKey)
{
// Map field keys to localized labels
return fieldKey switch
{
FieldKey.LoginUsername => Localizer["FieldLoginUsername"],
FieldKey.LoginPassword => Localizer["FieldLoginPassword"],
FieldKey.LoginEmail => Localizer["FieldLoginEmail"],
FieldKey.LoginUrl => Localizer["FieldLoginUrl"],
FieldKey.AliasFirstName => Localizer["FieldAliasFirstName"],
FieldKey.AliasLastName => Localizer["FieldAliasLastName"],
FieldKey.AliasGender => Localizer["FieldAliasGender"],
FieldKey.AliasBirthdate => Localizer["FieldAliasBirthdate"],
FieldKey.CardNumber => Localizer["FieldCardNumber"],
FieldKey.CardCardholderName => Localizer["FieldCardCardholderName"],
FieldKey.CardExpiryMonth => Localizer["FieldCardExpiryMonth"],
FieldKey.CardExpiryYear => Localizer["FieldCardExpiryYear"],
FieldKey.CardCvv => Localizer["FieldCardCvv"],
FieldKey.CardPin => Localizer["FieldCardPin"],
FieldKey.NotesContent => Localizer["FieldNotesContent"],
_ => fieldKey
};
}
private static MarkupString GetFieldIcon(FieldCategory category)
{
var svg = category switch
{
FieldCategory.Notes => """""",
FieldCategory.Card => """""",
_ => """"""
};
return new MarkupString(svg);
}
}