You've already forked onecmonitor
mirror of
https://github.com/akpaevj/onecmonitor.git
synced 2026-06-13 21:18:17 +02:00
174 lines
4.9 KiB
Plaintext
174 lines
4.9 KiB
Plaintext
@inject NavigationManager NavigationManager
|
|
@inject IDbContextFactory<AppDbContext> ContextFactory
|
|
@inject ISnackbar SnackBar
|
|
@implements IDisposable
|
|
@attribute [CascadingTypeParameter(nameof(T))]
|
|
@using Microsoft.EntityFrameworkCore
|
|
@using OneSwiss.Server.Components.Layout
|
|
@using OneSwiss.Server.Extensions
|
|
@typeparam T where T : class, OneSwiss.Server.Models.IHasId, new()
|
|
|
|
<MudStack>
|
|
<MudForm @ref="Form" Model="Model!" Validation="Validation" Disabled="@(!Editable)">
|
|
@ChildContent
|
|
</MudForm>
|
|
<MudStack Row AlignItems="AlignItems.End" Class="mb-3" Breakpoint="Breakpoint.SmAndDown">
|
|
@if (Editable)
|
|
{
|
|
<MudSpacer/>
|
|
<MudButton Variant="Variant.Outlined" Size="Size.Small" Color="Color.Primary" OnClick="Save">Сохранить
|
|
</MudButton>
|
|
}
|
|
</MudStack>
|
|
</MudStack>
|
|
|
|
@code
|
|
{
|
|
private MudForm Form { get; set; } = null!;
|
|
|
|
public AppDbContext? Context { get; private set; }
|
|
public T? Model { get; set; }
|
|
|
|
/// <summary>
|
|
/// Идентификатор элемента
|
|
/// </summary>
|
|
[Parameter]
|
|
public Guid Id { get; set; }
|
|
|
|
/// <summary>
|
|
/// Объект может быть отредактирован и записан
|
|
/// </summary>
|
|
[Parameter]
|
|
public bool Editable { get; set; } = true;
|
|
|
|
/// <summary>
|
|
/// Содержимое формы редактирования
|
|
/// </summary>
|
|
[Parameter]
|
|
public RenderFragment? ChildContent { get; set; }
|
|
|
|
/// <summary>
|
|
/// Используется при получении сложной модели со связями
|
|
/// </summary>
|
|
[Parameter]
|
|
public Func<IQueryable<T>, IQueryable<T>>? ModelSelector { get; set; }
|
|
|
|
/// <summary>
|
|
/// Дополнительные действия перед проверкой модели
|
|
/// </summary>
|
|
[Parameter]
|
|
public EventCallback<T> BeforeValidation { get; set; }
|
|
|
|
/// <summary>
|
|
/// Дополнительные действия после проверки модели
|
|
/// </summary>
|
|
[Parameter]
|
|
public EventCallback<T> AfterValidation { get; set; }
|
|
|
|
/// <summary>
|
|
/// Дополнительные действия при сохранении модели, которая уже существует в БД
|
|
/// </summary>
|
|
[Parameter]
|
|
public EventCallback<T> OnUpdate { get; set; }
|
|
|
|
/// <summary>
|
|
/// Дополнительные действия после сохранения модели
|
|
/// </summary>
|
|
[Parameter]
|
|
public EventCallback<T> AfterSave { get; set; }
|
|
|
|
/// <summary>
|
|
/// Дополнительные действия при инициализации
|
|
/// </summary>
|
|
[Parameter]
|
|
public EventCallback<(T Model, AppDbContext Context)> OnInitialize { get; set; }
|
|
|
|
/// <summary>
|
|
/// Дополнительные действия при инициализации
|
|
/// </summary>
|
|
[Parameter]
|
|
public Func<object, string, Task<IEnumerable<string>>>? Validation { get; set; }
|
|
|
|
[CascadingParameter(Name = "NavMenu")] public NavMenu NavMenu { get; set; }
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
try
|
|
{
|
|
Context = await ContextFactory.CreateDbContextAsync();
|
|
|
|
Model = await GetSingleObject();
|
|
|
|
await OnInitialize.InvokeAsync((Model!, Context));
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
SnackBar.ShowError(e);
|
|
}
|
|
}
|
|
|
|
private async Task Save()
|
|
{
|
|
await BeforeValidation.InvokeAsync(Model);
|
|
|
|
await Form.Validate();
|
|
|
|
if (!Form.IsValid)
|
|
{
|
|
SnackBar.ShowError("Объект не записан");
|
|
return;
|
|
}
|
|
|
|
await AfterValidation.InvokeAsync(Model);
|
|
|
|
try
|
|
{
|
|
var model = await GetSingleObject(false);
|
|
|
|
if (model != null)
|
|
{
|
|
Context!.Entry(model).CurrentValues.SetValues(Model!);
|
|
await OnUpdate.InvokeAsync(model);
|
|
}
|
|
else
|
|
Context!.Entry(Model!).State = EntityState.Added;
|
|
|
|
await Context!.SaveChangesAsync();
|
|
|
|
await AfterSave.InvokeAsync(model ?? Model!);
|
|
|
|
SnackBar.ShowSuccess("Объект записан", false);
|
|
|
|
await NavMenu.NotifyStateHasChanged();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
SnackBar.ShowError(e);
|
|
}
|
|
}
|
|
|
|
private async Task<T?> GetSingleObject(bool createNew = true)
|
|
{
|
|
var item = await (ModelSelector == null
|
|
? Context!.Set<T>()
|
|
: ModelSelector
|
|
.Invoke(Context!.Set<T>()))
|
|
.SingleOrDefaultAsync();
|
|
|
|
if (item != null)
|
|
return item;
|
|
|
|
if (!createNew)
|
|
return null;
|
|
|
|
item = new T();
|
|
Context.Set<T>().Add(item);
|
|
|
|
return item;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Context?.Dispose();
|
|
}
|
|
} |