@page "/admin/{TableDisplayName}" @layout HopFrameLayout @rendermode InteractiveServer @implements IDisposable @using HopFrame.Core.Config @using HopFrame.Core.Callbacks @using HopFrame.Core.Services @using HopFrame.Web.Models @using HopFrame.Web.Plugins @using HopFrame.Web.Plugins.Events @using Microsoft.JSInterop @using Microsoft.EntityFrameworkCore @if (!DisplaySelection) { @_config?.DisplayName }

@_config?.DisplayName

@if (!DisplaySelection) { Refresh } @if (_hasCreatePolicy && DisplayActions) { Add Entry }
@if (DisplaySelection) { } @foreach (var property in _config!.Properties.Where(prop => prop.List).OrderBy(prop => prop.Order)) { } @if (DisplayActions && (_hasDeletePolicy || _hasUpdatePolicy)) { @if (_hasUpdatePolicy) { } @if (_hasDeletePolicy) { } }
@if (_totalPages > 1) {
Page of @_totalPages
}
@inject IContextExplorer Explorer @inject NavigationManager Navigator @inject IJSRuntime Js @inject IDialogService Dialogs @inject IHopFrameAuthHandler Handler @inject ICallbackEmitter Emitter @inject IPluginOrchestrator PluginOrchestrator @code { [Parameter] public required string TableDisplayName { get; set; } [Parameter] public bool DisplaySelection { get; set; } [Parameter] public bool DisplayActions { get; set; } = true; [Parameter] public RelationPickerDialogData? DialogData { get; set; } [Parameter] public DataGridSelectMode SelectionMode { get; set; } = DataGridSelectMode.Single; [Parameter] public int PerPage { get; set; } = 20; private TableConfig? _config; private ITableManager? _manager; private object[] _currentlyDisplayedModels = []; private int _currentPage; private int _totalPages; private string? _searchTerm; private bool _loading; private bool _hasUpdatePolicy; private bool _hasDeletePolicy; private bool _hasCreatePolicy; private bool _allSelected; protected override void OnInitialized() { _config ??= Explorer.GetTable(TableDisplayName); if (_config is null || (_config.Ignored && DialogData is null)) { Navigator.NavigateTo("/admin", true); } } protected override async Task OnInitializedAsync() { if (!await Handler.IsAuthenticatedAsync(_config?.ViewPolicy)) { Navigator.NavigateTo("/admin", true); return; } _hasUpdatePolicy = await Handler.IsAuthenticatedAsync(_config?.UpdatePolicy); _hasDeletePolicy = await Handler.IsAuthenticatedAsync(_config?.DeletePolicy); _hasCreatePolicy = await Handler.IsAuthenticatedAsync(_config?.CreatePolicy); _manager ??= Explorer.GetTableManager(_config!.PropertyName); _currentlyDisplayedModels = await _manager!.LoadPage(_currentPage, PerPage).ToArrayAsync(); _totalPages = await _manager.TotalPages(PerPage); } protected override async Task OnAfterRenderAsync(bool firstRender) { try { await Js.InvokeVoidAsync("removeBg"); } catch (Exception) { // ignored } } public void Dispose() { _searchCancel.Dispose(); } private CancellationTokenSource _searchCancel = new(); private async Task OnSearch(ChangeEventArgs eventArgs) { await _searchCancel.CancelAsync(); _searchTerm = eventArgs.Value?.ToString(); if (_searchTerm is null) return; _searchCancel = new(); await Task.Delay(500, _searchCancel.Token); var eventResult = await PluginOrchestrator.DispatchEvent(new SearchEvent(this) { SearchTerm = _searchTerm, Table = _config! }); if (eventResult.IsCanceled) return; _searchTerm = eventResult.SearchTerm; await Reload(); } private async Task Reload() { _loading = true; var eventResult = await PluginOrchestrator.DispatchEvent(new ReloadEvent(this) { Table = _config! }); if (eventResult.IsCanceled) { _loading = false; return; } if (!string.IsNullOrEmpty(_searchTerm)) { (var query, _totalPages) = await _manager!.Search(_searchTerm, 0, PerPage); _currentlyDisplayedModels = query.ToArray(); } else { await OnInitializedAsync(); } _loading = false; } private async Task ChangePage(int page) { var eventResult = await PluginOrchestrator.DispatchEvent(new PageChangeEvent(this) { CurrentPage = _currentPage, NewPage = page, TotalPages = _totalPages, Table = _config! }); if (eventResult.IsCanceled) return; page = eventResult.NewPage; if (page < 0 || page > _totalPages - 1) return; _currentPage = page; await Reload(); } private async Task DeleteEntry(object element) { if (!await Handler.IsAuthenticatedAsync(_config?.DeletePolicy)) { Navigator.NavigateTo("/admin", true); return; } var eventResult = await PluginOrchestrator.DispatchEvent(new DeleteEntryEvent(this) { Entity = element, Table = _config! }); if (eventResult.IsCanceled) return; var dialog = await Dialogs.ShowConfirmationAsync("Do you really want to delete this entry?"); var result = await dialog.Result; if (result.Cancelled) return; await _manager!.DeleteItem(element); await Emitter.DispatchCallback(CallbackTypes.DeleteEntry(_config!), element); await Reload(); } private async Task CreateOrEdit(object? element) { if (!await Handler.IsAuthenticatedAsync(element is null ? _config?.CreatePolicy : _config?.UpdatePolicy)) { Navigator.NavigateTo("/admin", true); return; } HopFrameTablePageEventArgs eventArgs; if (element is null) { eventArgs = new CreateEntryEvent(this) { Table = _config! }; } else { eventArgs = new UpdateEntryEvent(this) { Table = _config!, Entity = element }; } var eventResult = await PluginOrchestrator.DispatchEvent(eventArgs); if (eventResult.IsCanceled) return; var panel = await Dialogs.ShowPanelAsync(new EditorDialogData(_config!, element), new DialogParameters { TrapFocus = false }); var result = await panel.Result; var data = result.Data as EditorDialogData; if (result.Cancelled) return; if (element is null) { await _manager!.AddItem(data!.CurrentObject!); await Emitter.DispatchCallback(CallbackTypes.CreateEntry(_config!), data.CurrentObject!); } else { await _manager!.EditItem(data!.CurrentObject!); await Emitter.DispatchCallback(CallbackTypes.UpdateEntry(_config!), data.CurrentObject!); } await Reload(); } private void SelectItem(object item, bool selected) { var eventResult = PluginOrchestrator.DispatchEvent(new SelectEntryEvent(this) { Entity = item, Selected = selected, Table = _config! }).Result; if (eventResult.IsCanceled) return; selected = eventResult.Selected; if (!selected) DialogData!.SelectedObjects.Remove(item); else DialogData!.SelectedObjects.Add(item); } private void SelectAll() { var selected = _currentlyDisplayedModels.All(DialogData!.SelectedObjects.Contains); foreach (var displayedModel in _currentlyDisplayedModels) { SelectItem(displayedModel, !selected); } _allSelected = selected; } private async Task DisplayProperty(PropertyConfig config, object entry) { var display = await _manager!.DisplayProperty(entry, config); if (display.Length > config.DisplayLength) display = display[..config.DisplayLength] + "..."; return display; } }