| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- @using RackPeek.Domain.Persistence
- @using RackPeek.Domain.Resources
- @typeparam TResource where TResource : RackPeek.Domain.Resources.Resource
- @inject IResourceCollection Repo
- <PageTitle>@Title</PageTitle>
- <h1 class="text-lg text-zinc-100" data-testid="@($"{TestId}-page-title")">
- @Title
- </h1>
- <div class="min-h-screen bg-zinc-950 text-zinc-200 font-mono p-6 space-y-6"
- data-testid="@($"{TestId}-page-root")">
- <div data-testid="@($"{TestId}-add-section")">
- <AddResourceComponent TResource="TResource"
- Placeholder=@($"{ResourceKind} name")
- OnCreated="OnCreated"/>
- </div>
- @if (ResourcesToRender is null)
- {
- <div class="text-zinc-500" data-testid="@($"{TestId}-loading")">
- loading @ResourceKind.ToLower()…
- </div>
- }
- else if (!ResourcesToRender.Any())
- {
- <div class="text-zinc-500" data-testid="@($"{TestId}-empty")">
- no @ResourceKind.ToLower() found
- </div>
- }
- else
- {
- <div class="space-y-4" data-testid="@($"{TestId}-list")">
- @foreach (var group in GroupResources(ResourcesToRender))
- {
- var groupKey = FormatGroupKey(group.Key);
- <div data-testid="@($"{TestId}-group-{groupKey}")">
- @if (ShouldGroup)
- {
- <div class="text-xs text-zinc-500 uppercase tracking-wider mb-2"
- data-testid="@($"{TestId}-group-title-{groupKey}")">
- @DisplayGroupKey(group.Key)
- </div>
- }
- <div class="space-y-4" data-testid="@($"{TestId}-group-list-{groupKey}")">
- @foreach (var item in group)
- {
- @ItemTemplate(item)
- }
- </div>
- </div>
- }
- </div>
- }
- </div>
- @code {
- [Parameter] public string Title { get; set; } = default!;
- [Parameter] public string TestId { get; set; } = default!;
- [Parameter] public IReadOnlyList<TResource>? Resources { get; set; }
- [Parameter] public RenderFragment AddSection { get; set; } = default!;
- [Parameter] public RenderFragment<TResource> ItemTemplate { get; set; } = default!;
- [Parameter] public bool ShouldGroup { get; set; }
- [Parameter] public Func<TResource, string?> GroupBy { get; set; } = _ => null;
- [Parameter] public EventCallback<string> OnCreated { get; set; }
- private IReadOnlyList<TResource>? _loadedResources;
-
- private IReadOnlyList<TResource>? ResourcesToRender => Resources ?? _loadedResources;
- public string ResourceKind { get; set; } = Resource.GetKind<TResource>();
-
- protected override async Task OnParametersSetAsync()
- {
- if (Resources is not null)
- return;
- if (_loadedResources is null)
- _loadedResources = await Repo.GetAllOfTypeAsync<TResource>();
- }
- private IEnumerable<IGrouping<string?, TResource>> GroupResources(IEnumerable<TResource> resources) =>
- resources.GroupBy(GroupBy).OrderByDescending(g => g.Count());
- private static string FormatGroupKey(string? key) =>
- string.IsNullOrWhiteSpace(key) ? "unassigned" : key.Replace(" ", "-");
- private static string DisplayGroupKey(string? key) =>
- string.IsNullOrWhiteSpace(key) ? "Unassigned" : key;
- }
|