Files
fs-onboarding/FoodsharingSiegen.Server/Controls/ProspectGrid.razor

104 lines
2.8 KiB
Plaintext

@using FoodsharingSiegen.Contracts.Enums
@using Microsoft.JSInterop
@implements IAsyncDisposable
@inject IJSRuntime JSRuntime
@code {
[Parameter] public List<Prospect>? Prospects { get; set; }
[Parameter] public ProspectStateFilter StateFilter { get; set; }
[Parameter] public Func<Task>? OnDataChanged { get; set; }
[Parameter] public EventCallback OnLoadMore { get; set; }
[Parameter] public bool IsLoadingMore { get; set; }
[Parameter] public bool HasMore { get; set; }
[Parameter] public string GridClass { get; set; } = string.Empty;
private IJSObjectReference? _module;
private DotNetObjectReference<ProspectGrid>? _dotNetHelper;
private string _gridId = $"prospect-grid-{Guid.NewGuid():N}";
private bool _isJsBound;
private bool _disposed;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (_disposed || !firstRender || _isJsBound) return;
try
{
_dotNetHelper ??= DotNetObjectReference.Create(this);
_module ??= await JSRuntime.InvokeAsync<IJSObjectReference>("import", "./js/prospect-grid.js");
await _module.InvokeVoidAsync("attachScrollLoader", _gridId, _dotNetHelper);
_isJsBound = true;
}
catch (JSDisconnectedException)
{
// Ignore browser disconnect during teardown.
}
catch (ObjectDisposedException)
{
// Ignore late render after the component is being torn down.
}
}
[JSInvokable]
public async Task OnScrollNearBottom()
{
if (OnLoadMore.HasDelegate && !IsLoadingMore && HasMore)
{
await OnLoadMore.InvokeAsync();
}
}
public async ValueTask DisposeAsync()
{
_disposed = true;
if (_module is not null)
{
try
{
await _module.InvokeVoidAsync("disposeScrollLoader", _gridId);
}
catch (JSDisconnectedException)
{
// ignored; the circuit is already disconnected
}
catch (ObjectDisposedException)
{
// ignored; the JS runtime is already disposed
}
}
_dotNetHelper?.Dispose();
_dotNetHelper = null;
_isJsBound = false;
}
}
<h6>@(Prospects?.Count ?? 0) Ergebnisse</h6>
@if (Prospects?.Any() == true)
{
<div id="@_gridId" class="prospect-grid @GridClass" style="max-height: calc(100vh - 250px); overflow-y: auto;">
@foreach (var prospect in Prospects)
{
<ProspectContainer @key="prospect.Id"
Prospect="prospect"
OnDataChanged="@OnDataChanged"
StateFilter="StateFilter"></ProspectContainer>
}
@if (IsLoadingMore)
{
<div class="d-flex justify-content-center py-3 text-muted">
<span class="me-2"><i class="fa-solid fa-spinner fa-spin"></i></span>
Weitere laden...
</div>
}
</div>
}