@@ -1,8 +1,12 @@
|
|||||||
namespace Moonlight.App.Database.Entities;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace Moonlight.App.Database.Entities;
|
||||||
|
|
||||||
public class Domain
|
public class Domain
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public SharedDomain SharedDomain { get; set; }
|
public SharedDomain SharedDomain { get; set; }
|
||||||
public User Owner { get; set; }
|
public User Owner { get; set; }
|
||||||
|
|||||||
11
Moonlight/App/Helpers/FieldCssHelper.cs
Normal file
11
Moonlight/App/Helpers/FieldCssHelper.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using Microsoft.AspNetCore.Components.Forms;
|
||||||
|
|
||||||
|
namespace Moonlight.App.Helpers;
|
||||||
|
|
||||||
|
public class FieldCssHelper : FieldCssClassProvider
|
||||||
|
{
|
||||||
|
public override string GetFieldCssClass(EditContext editContext, in FieldIdentifier fieldIdentifier)
|
||||||
|
{
|
||||||
|
return editContext.GetValidationMessages(fieldIdentifier).Any() ? "is-invalid" : "is-valid";
|
||||||
|
}
|
||||||
|
}
|
||||||
73
Moonlight/Shared/Components/Forms/SmartForm.razor
Normal file
73
Moonlight/Shared/Components/Forms/SmartForm.razor
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
@using Moonlight.App.Helpers
|
||||||
|
|
||||||
|
<div class="form">
|
||||||
|
<EditForm @ref="EditForm" Model="Model" OnValidSubmit="ValidSubmit" OnInvalidSubmit="InvalidSubmit">
|
||||||
|
<DataAnnotationsValidator></DataAnnotationsValidator>
|
||||||
|
@if (ErrorMessages.Any())
|
||||||
|
{
|
||||||
|
<div class="alert alert-danger p-10 mb-3">
|
||||||
|
@foreach (var msg in ErrorMessages)
|
||||||
|
{
|
||||||
|
<TL>@(msg)</TL>
|
||||||
|
<br/>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@(ChildContent)
|
||||||
|
</EditForm>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@code
|
||||||
|
{
|
||||||
|
[Parameter]
|
||||||
|
public object Model { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public EventCallback<EditContext> OnValidSubmit { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public EventCallback<EditContext> OnInvalidSubmit { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public EventCallback<EditContext> OnSubmit { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public RenderFragment ChildContent { get; set; }
|
||||||
|
|
||||||
|
private EditForm EditForm;
|
||||||
|
|
||||||
|
private List<string> ErrorMessages = new();
|
||||||
|
|
||||||
|
protected override void OnAfterRender(bool firstRender)
|
||||||
|
{
|
||||||
|
if (firstRender)
|
||||||
|
{
|
||||||
|
EditForm.EditContext!.SetFieldCssClassProvider(new FieldCssHelper());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ValidSubmit(EditContext context)
|
||||||
|
{
|
||||||
|
ErrorMessages.Clear();
|
||||||
|
await InvokeAsync(StateHasChanged);
|
||||||
|
|
||||||
|
await OnValidSubmit.InvokeAsync(context);
|
||||||
|
await OnSubmit.InvokeAsync(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task InvalidSubmit(EditContext context)
|
||||||
|
{
|
||||||
|
ErrorMessages.Clear();
|
||||||
|
context.Validate();
|
||||||
|
|
||||||
|
foreach (var message in context.GetValidationMessages())
|
||||||
|
{
|
||||||
|
ErrorMessages.Add(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
await InvokeAsync(StateHasChanged);
|
||||||
|
|
||||||
|
await OnInvalidSubmit.InvokeAsync(context);
|
||||||
|
await OnSubmit.InvokeAsync(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
59
Moonlight/Shared/Components/Forms/SmartSelect.razor
Normal file
59
Moonlight/Shared/Components/Forms/SmartSelect.razor
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
@typeparam TField
|
||||||
|
@inherits InputBase<TField>
|
||||||
|
|
||||||
|
<select class="form-select" @bind="Binding">
|
||||||
|
@foreach(var item in Items)
|
||||||
|
{
|
||||||
|
<option value="@(item!.GetHashCode())">@(DisplayField(item))</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
@code
|
||||||
|
{
|
||||||
|
[Parameter]
|
||||||
|
public TField[] Items { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public Func<TField, string> DisplayField { get; set; }
|
||||||
|
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string? FormatValueAsString(TField? value)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return DisplayField.Invoke(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool TryParseValueFromString(string? value, out TField result, out string? validationErrorMessage)
|
||||||
|
{
|
||||||
|
validationErrorMessage = "";
|
||||||
|
result = default(TField)!;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int Binding
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (Value == null)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return Value.GetHashCode();
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
var i = Items.FirstOrDefault(x => x!.GetHashCode() == value);
|
||||||
|
|
||||||
|
if (i != null)
|
||||||
|
{
|
||||||
|
Value = i;
|
||||||
|
ValueChanged.InvokeAsync(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,2 +1,55 @@
|
|||||||
@page "/test"
|
@page "/test"
|
||||||
|
@using Moonlight.App.Services.Interop
|
||||||
|
@using Moonlight.App.Database.Entities
|
||||||
|
@using Moonlight.App.Repositories.Domains
|
||||||
|
|
||||||
|
@inject ToastService ToastService
|
||||||
|
@inject SharedDomainRepository SharedDomainRepository
|
||||||
|
|
||||||
|
<LazyLoader Load="Load">
|
||||||
|
<SmartForm Model="Domain" OnValidSubmit="Callback">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">
|
||||||
|
<TL>Domain name</TL>
|
||||||
|
</label>
|
||||||
|
<InputText @bind-Value="Domain.Name" class="form-control"></InputText>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label">
|
||||||
|
<TL>Shared domain</TL>
|
||||||
|
</label>
|
||||||
|
<SmartSelect TField="SharedDomain"
|
||||||
|
@bind-Value="Domain.SharedDomain"
|
||||||
|
Items="SharedDomains"
|
||||||
|
DisplayField="@(x => x.Name)">
|
||||||
|
</SmartSelect>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<button type="submit" class="btn btn-primary">Save</button>
|
||||||
|
</div>
|
||||||
|
</SmartForm>
|
||||||
|
</LazyLoader>
|
||||||
|
|
||||||
|
@code
|
||||||
|
{
|
||||||
|
private App.Database.Entities.Domain Domain = new();
|
||||||
|
|
||||||
|
private SharedDomain[] SharedDomains;
|
||||||
|
|
||||||
|
private async Task Callback(EditContext obj)
|
||||||
|
{
|
||||||
|
Console.WriteLine(Domain.Name);
|
||||||
|
Console.WriteLine(Domain.SharedDomain.Name);
|
||||||
|
|
||||||
|
await ToastService.Success("SUCCESS");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task Load(LazyLoader arg)
|
||||||
|
{
|
||||||
|
SharedDomains = SharedDomainRepository
|
||||||
|
.Get()
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -393,3 +393,4 @@ Successfully updated user;Successfully updated user
|
|||||||
Discord id;Discord id
|
Discord id;Discord id
|
||||||
Discord username;Discord username
|
Discord username;Discord username
|
||||||
Discord discriminator;Discord discriminator
|
Discord discriminator;Discord discriminator
|
||||||
|
The Name field is required.;The Name field is required.
|
||||||
|
|||||||
Reference in New Issue
Block a user