Files
aliasvault/apps/server/AliasVault.Client/Main/Components/Items/ItemsTable.razor
2026-07-24 12:43:45 +02:00

112 lines
4.6 KiB
Plaintext

@using AliasVault.RazorComponents.Tables
@using AliasVault.Client.Main.Models
@inject NavigationManager NavigationManager
<SortableTable Columns="@_tableColumns" SortColumn="@SortColumn" SortDirection="@CurrentSortDirection" OnSortChanged="HandleSortChanged">
@foreach (var credential in Credentials)
{
<SortableTableRow @key="credential.Id" Class="cursor-pointer group" OnClick="@(() => NavigateToCredential(credential.Id))" OnContextMenu="@((MouseEventArgs e) => OpenRowMenu(credential.Id, e))">
<SortableTableColumn Padding="false">
<div class="flex items-center space-x-2 py-2 pl-2">
<ItemIcon
ItemType="@credential.ItemType"
LogoDataUri="@credential.LogoDataUri"
CardNumber="@credential.CardNumber"
AltText="@credential.Service"
SizeClass="w-6 h-6" />
<span class="font-bold ml-2">@credential.Service</span>
</div>
</SortableTableColumn>
<SortableTableColumn Padding="false">@credential.Username</SortableTableColumn>
<SortableTableColumn Padding="false">@credential.Email</SortableTableColumn>
<SortableTableColumn Padding="false">@credential.CreatedAt.ToString("yyyy-MM-dd")</SortableTableColumn>
<SortableTableColumn Padding="false">
<div class="flex justify-end pr-2">
<ItemContextMenu @ref="_rowMenus[credential.Id]" ItemId="@credential.Id" ItemName="@credential.Service" OnMutated="OnMutated" />
</div>
</SortableTableColumn>
</SortableTableRow>
}
</SortableTable>
@code {
/// <summary>
/// Gets or sets the list of credentials to show.
/// </summary>
[Parameter]
public List<ItemListEntry> Credentials { get; set; } = [];
/// <summary>
/// Gets or sets the current sort column.
/// </summary>
[Parameter]
public string SortColumn { get; set; } = "CreatedAt";
/// <summary>
/// Gets or sets the current sort direction.
/// </summary>
[Parameter]
public SortDirection CurrentSortDirection { get; set; } = SortDirection.Descending;
/// <summary>
/// Gets or sets the callback for when the sort changes.
/// The parent component should handle sorting ALL items when this is invoked.
/// </summary>
[Parameter]
public EventCallback<(string Column, SortDirection Direction)> OnTableSortChanged { get; set; }
/// <summary>
/// Gets or sets the callback raised after an item was mutated via the row context menu (duplicated or deleted).
/// </summary>
[Parameter]
public EventCallback OnMutated { get; set; }
/// <summary>
/// Gets or sets the columns to show in the table.
/// </summary>
private readonly List<TableColumn> _tableColumns = [
new TableColumn { Title = "Service", PropertyName = "Service" },
new TableColumn { Title = "Username", PropertyName = "Username" },
new TableColumn { Title = "Email", PropertyName = "Email" },
new TableColumn { Title = "Created", PropertyName = "CreatedAt" },
new TableColumn { Title = string.Empty, Sortable = false }
];
/// <summary>
/// Context menu component references per row, used to open the menu via right-click.
/// </summary>
private readonly Dictionary<Guid, ItemContextMenu> _rowMenus = new();
/// <summary>
/// Handles the sort changed event from the table header click.
/// Notifies the parent component to apply sorting on all items.
/// </summary>
/// <param name="sort">The sort event.</param>
private async Task HandleSortChanged((string column, SortDirection direction) sort)
{
await OnTableSortChanged.InvokeAsync((sort.column, sort.direction));
}
/// <summary>
/// Navigates to the credential details page.
/// </summary>
/// <param name="credentialId">The ID of the credential to navigate to.</param>
private void NavigateToCredential(Guid credentialId)
{
NavigationManager.NavigateTo($"/items/{credentialId}");
}
/// <summary>
/// Opens the context menu for the given row at the right-click position.
/// </summary>
/// <param name="credentialId">The ID of the credential whose menu to open.</param>
/// <param name="e">The mouse event containing the cursor position.</param>
private void OpenRowMenu(Guid credentialId, MouseEventArgs e)
{
if (_rowMenus.TryGetValue(credentialId, out var menu))
{
menu.Open(e);
}
}
}