Added edit modal
This commit is contained in:
59
src/HopFrame.Web/Components/Dialogs/HopFrameEditor.razor
Normal file
59
src/HopFrame.Web/Components/Dialogs/HopFrameEditor.razor
Normal file
@@ -0,0 +1,59 @@
|
||||
@implements IDialogContentComponent<EditorDialogData>
|
||||
|
||||
@using HopFrame.Web.Models
|
||||
@using HopFrame.Core.Services
|
||||
@using HopFrame.Web.Helpers
|
||||
|
||||
<FluentDialogBody>
|
||||
@foreach (var property in Content.Config.Properties) {
|
||||
if (!_currentlyEditing && !property.Creatable) continue;
|
||||
|
||||
<div style="margin-bottom: 20px">
|
||||
@if (property.Info.PropertyType.IsNumeric()) {
|
||||
<FluentNumberField
|
||||
TValue="double"
|
||||
Label="@property.Name"
|
||||
Value="@(Convert.ToDouble(property.Info.GetValue(Content.CurrentObject)))"
|
||||
Style="width: 100%;"
|
||||
Disabled="@(!property.Editable)"
|
||||
/>
|
||||
} else if (property.Info.PropertyType == typeof(bool)) {
|
||||
<FluentSwitch
|
||||
Label="@property.Name"
|
||||
Value="@(Convert.ToBoolean(property.Info.GetValue(Content.CurrentObject)))"
|
||||
/>
|
||||
}
|
||||
else {
|
||||
<FluentTextField
|
||||
Label="@property.Name"
|
||||
Value="@_manager?.DisplayProperty(Content.CurrentObject, property.Info, Content.Config)"
|
||||
Style="width: 100%;"
|
||||
Disabled="@(!property.Editable)"
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</FluentDialogBody>
|
||||
|
||||
@inject IContextExplorer Explorer
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public required EditorDialogData Content { get; set; }
|
||||
|
||||
[CascadingParameter]
|
||||
public required FluentDialog Dialog { get; set; }
|
||||
|
||||
private ITableManager? _manager;
|
||||
private bool _currentlyEditing;
|
||||
|
||||
protected override void OnInitialized() {
|
||||
if (Dialog.Instance is null) return;
|
||||
_currentlyEditing = Content.CurrentObject is not null;
|
||||
Dialog.Instance.Parameters.Title = Content.CurrentObject is null ? "Add entry" : "Edit entry";
|
||||
Dialog.Instance.Parameters.PreventScroll = true;
|
||||
Dialog.Instance.Parameters.Width = "500px";
|
||||
Dialog.Instance.Parameters.PrimaryAction = "Save";
|
||||
_manager = Explorer.GetTableManager(Content.Config.PropertyName);
|
||||
}
|
||||
}
|
||||
@@ -4,30 +4,38 @@
|
||||
|
||||
@using HopFrame.Core.Config
|
||||
@using HopFrame.Core.Services
|
||||
@using HopFrame.Web.Models
|
||||
@using Microsoft.JSInterop
|
||||
@using System.Text.Json
|
||||
|
||||
<FluentDialogProvider />
|
||||
|
||||
<div style="display: flex; flex-direction: column; height: 100%">
|
||||
<FluentToolbar Class="hopframe-toolbar">
|
||||
<h3>@_config?.PropertyName</h3>
|
||||
<FluentSpacer />
|
||||
<FluentSearch @oninput="OnSearch" @onchange="OnSearch" />
|
||||
<FluentButton>Add Entry</FluentButton>
|
||||
<FluentButton OnClick="async () => { await CreateOrEdit(null); }">Add Entry</FluentButton>
|
||||
</FluentToolbar>
|
||||
|
||||
<div style="overflow-y: auto; flex-grow: 1">
|
||||
<FluentDataGrid Items="_currentlyDisplayedModels?.AsQueryable()">
|
||||
@{ var dataIndex = 0; }
|
||||
@foreach (var property in _config!.Properties.Where(prop => prop.List)) {
|
||||
<PropertyColumn Title="@property.Name" Property="o => _manager!.DisplayProperty(o, property.Info, _config)" Style="min-width: max-content; min-height: 43px" Sortable="@property.Sortable"/>
|
||||
<PropertyColumn
|
||||
Title="@property.Name" Property="o => _manager!.DisplayProperty(o, property.Info, _config)"
|
||||
Style="min-width: max-content; min-height: 43px;"
|
||||
Sortable="@property.Sortable"
|
||||
/>
|
||||
}
|
||||
|
||||
<TemplateColumn Title="Actions" Align="@Align.End" Style="min-height: 43px; min-width: max-content">
|
||||
@{ var currentElement = _currentlyDisplayedModels!.ElementAt(dataIndex); }
|
||||
<FluentButton aria-label="Edit entry">
|
||||
@{ var currentElement = _currentlyDisplayedModels!.ElementAtOrDefault(dataIndex); }
|
||||
<FluentButton aria-label="Edit entry" OnClick="async () => { await CreateOrEdit(currentElement); }">
|
||||
<FluentIcon Value="@(new Icons.Regular.Size16.Edit())"/>
|
||||
</FluentButton>
|
||||
|
||||
<FluentButton aria-label="Delete entry" OnClick="async () => { await DeleteEntry(currentElement); }">
|
||||
<FluentButton aria-label="Delete entry" OnClick="async () => { await DeleteEntry(currentElement!); }">
|
||||
<FluentIcon Value="@(new Icons.Regular.Size16.Delete())" Color="Color.Warning"/>
|
||||
</FluentButton>
|
||||
|
||||
@@ -38,7 +46,7 @@
|
||||
</TemplateColumn>
|
||||
</FluentDataGrid>
|
||||
|
||||
@if (_currentlyDisplayedModels?.Any() == true) {
|
||||
@if (_totalPages > 1) {
|
||||
<div class="hopframe-paginator">
|
||||
<FluentButton BackgroundColor="transparent" OnClick="() => ChangePage(_currentPage - 1)">
|
||||
<FluentIcon Value="@(new Icons.Regular.Size20.ArrowPrevious())" Color="Color.Neutral" />
|
||||
@@ -78,6 +86,7 @@
|
||||
@inject IContextExplorer Explorer
|
||||
@inject NavigationManager Navigator
|
||||
@inject IJSRuntime Js
|
||||
@inject IDialogService Dialogs
|
||||
|
||||
@code {
|
||||
|
||||
@@ -106,7 +115,9 @@
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender) {
|
||||
await Js.InvokeVoidAsync("removeBg");
|
||||
try {
|
||||
await Js.InvokeVoidAsync("removeBg");
|
||||
}catch (Exception) {}
|
||||
}
|
||||
|
||||
private CancellationTokenSource _searchCancel = new();
|
||||
@@ -132,6 +143,10 @@
|
||||
}
|
||||
|
||||
private async Task DeleteEntry(object element) { //TODO: display confirmation
|
||||
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);
|
||||
|
||||
if (!string.IsNullOrEmpty(_searchTerm)) {
|
||||
@@ -141,4 +156,8 @@
|
||||
OnInitialized();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CreateOrEdit(object? element) {
|
||||
var panel = await Dialogs.ShowPanelAsync<HopFrameEditor>(new EditorDialogData(_config!, element), new());
|
||||
}
|
||||
}
|
||||
22
src/HopFrame.Web/Helpers/TypeExtensions.cs
Normal file
22
src/HopFrame.Web/Helpers/TypeExtensions.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
namespace HopFrame.Web.Helpers;
|
||||
|
||||
internal static class TypeExtensions {
|
||||
public static bool IsNumeric(this Type o) {
|
||||
switch (Type.GetTypeCode(o)) {
|
||||
case TypeCode.Byte:
|
||||
case TypeCode.SByte:
|
||||
case TypeCode.UInt16:
|
||||
case TypeCode.UInt32:
|
||||
case TypeCode.UInt64:
|
||||
case TypeCode.Int16:
|
||||
case TypeCode.Int32:
|
||||
case TypeCode.Int64:
|
||||
case TypeCode.Decimal:
|
||||
case TypeCode.Double:
|
||||
case TypeCode.Single:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
8
src/HopFrame.Web/Models/EditorDialogData.cs
Normal file
8
src/HopFrame.Web/Models/EditorDialogData.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using HopFrame.Core.Config;
|
||||
|
||||
namespace HopFrame.Web.Models;
|
||||
|
||||
public sealed class EditorDialogData(TableConfig config, object? current = null) {
|
||||
public object? CurrentObject { get; } = current;
|
||||
public TableConfig Config { get; } = config;
|
||||
}
|
||||
@@ -9,3 +9,4 @@
|
||||
@using Icons = Microsoft.FluentUI.AspNetCore.Components.Icons
|
||||
@using Microsoft.FluentUI.AspNetCore.Components.Extensions
|
||||
@using HopFrame.Web.Components.Layout
|
||||
@using HopFrame.Web.Components.Dialogs
|
||||
|
||||
Reference in New Issue
Block a user