Started CreateApplication.razor

This commit is contained in:
2024-09-06 10:05:59 +03:00
parent 70c989bee2
commit 53d5758527
28 changed files with 208 additions and 105 deletions

View File

@@ -7,11 +7,9 @@ namespace ApplicationLayer.Services.VisaApplications.Models;
public class PermissionToDestCountryModel
{
/// Date when permission to destination country expires
[Required]
public DateTime ExpirationDate { get; set; }
/// Issuing authority
[Required]
[MaxLength(ConfigurationConstraints.IssuerNameLength)]
public string Issuer { get; set; } = null!;
}

View File

@@ -7,11 +7,9 @@ namespace ApplicationLayer.Services.VisaApplications.Models;
public class ReentryPermitModel
{
/// Number of re-entry permit
[Required]
[MaxLength(ConfigurationConstraints.ReentryPermitNumberLength)]
public string Number { get; set; } = null!;
/// Date when re-entry permit expires
[Required]
public DateTime ExpirationDate { get; set; }
}

View File

@@ -16,6 +16,8 @@
[Parameter, EditorRequired] public Expression<Func<TItem, TMember>> EnumProperty { get; set; } = null!;
[Parameter] public Action? OnChanged { get; set; }
private Dictionary<TMember, string> enumValues = new();
private PropertyInfo modelMemberInfo = null!;
private TMember selected;
@@ -32,13 +34,18 @@
}
protected override void OnAfterRender(bool firstRender)
{
var current = (TMember)modelMemberInfo.GetValue(Model)!;
if (!current.Equals(selected))
{
OnValueChanged();
}
}
private void OnValueChanged()
{
modelMemberInfo.SetValue(Model, selected);
OnChanged?.Invoke();
}
}

View File

@@ -1,5 +1,4 @@
@using BlazorWebAssemblyVisaApiClient.Infrastructure.Services
@using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.DateTimeProvider
@using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.DateTimeProvider
@using VisaApiClient
<div>
@@ -22,7 +21,7 @@
<div >
<label>
Issue date:<br/>
<InputDate DisplayName="Issue date" class="rounded" @bind-Value="Passport.IssueDate" max="DateTimeProvider.Now()"/>
<InputDate DisplayName="Issue date" class="rounded" @bind-Value="Passport.IssueDate" max="@formattedDate"/>
</label><br/>
<ValidationMessage For="() => Passport.IssueDate"></ValidationMessage>
</div><br/>
@@ -30,14 +29,14 @@
<div >
<label>
Expiration date:<br/>
<InputDate DisplayName="Expiration date" class="rounded" @bind-Value="Passport.ExpirationDate" min="DateTimeProvider.Now()"/>
<InputDate DisplayName="Expiration date" class="rounded" @bind-Value="Passport.ExpirationDate" min="@formattedDate"/>
</label><br/>
<ValidationMessage For="() => Passport.ExpirationDate"></ValidationMessage>
</div>
</div>
@code {
private string now = DateTime.Now.ToString("yyyy-MM-dd");
private string formattedDate = null!;
[Parameter, EditorRequired] public PassportModel Passport { get; set; } = null!;
@@ -47,6 +46,7 @@
{
Passport.IssueDate = DateTime.Now;
Passport.ExpirationDate = DateTime.Now;
formattedDate = DateTimeProvider.FormattedNow();
}
}

View File

@@ -1,5 +1,4 @@
@using BlazorWebAssemblyVisaApiClient.FluentValidation.Applicants.Models
@using BlazorWebAssemblyVisaApiClient.Validation.Applicants.Models
<div>
<div >
<label >

View File

@@ -1,46 +0,0 @@
<h3>CustomValidation</h3>
@code {
private ValidationMessageStore? messageStore;
[CascadingParameter]
private EditContext? CurrentEditContext { get; set; }
protected override void OnInitialized()
{
if (CurrentEditContext is null)
{
throw new InvalidOperationException(
$"{nameof(CustomValidation)} requires a cascading " +
$"parameter of type {nameof(EditContext)}. " +
$"For example, you can use {nameof(CustomValidation)} " +
$"inside an {nameof(EditForm)}.");
}
messageStore = new(CurrentEditContext);
CurrentEditContext.OnValidationRequested += (_, _) =>
messageStore?.Clear();
CurrentEditContext.OnFieldChanged += (_, e) =>
messageStore?.Clear(e.FieldIdentifier);
}
public void DisplayErrors(Dictionary<string, List<string>> errors)
{
if (CurrentEditContext is not null)
{
foreach (var err in errors)
{
messageStore?.Add(CurrentEditContext.Field(err.Key), err.Value);
}
CurrentEditContext.NotifyValidationStateChanged();
}
}
public void ClearErrors()
{
messageStore?.Clear();
CurrentEditContext?.NotifyValidationStateChanged();
}
}

View File

@@ -0,0 +1,33 @@
@using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.DateTimeProvider
@using VisaApiClient
<div>
<label>
Destination Country:<br/>
<InputText DisplayName="Issuer of permission to destination Country" class="rounded"
@bind-Value="PermissionToDestCountry.Issuer"/>
</label><br/>
<ValidationMessage For="() => PermissionToDestCountry.Issuer"></ValidationMessage><br/>
<label>
Expiration date:<br/>
<InputDate DisplayName="Expiration date of permission to destination Country" class="rounded"
@bind-Value="PermissionToDestCountry.ExpirationDate"
max="@formattedDate"/>
</label><br/>
<ValidationMessage For="() => PermissionToDestCountry.ExpirationDate"></ValidationMessage>
</div>
@code {
private string formattedDate = null!;
[Parameter, EditorRequired] public PermissionToDestCountryModel PermissionToDestCountry { get; set; } = null!;
[Inject] IDateTimeProvider DateTimeProvider { get; set; } = null!;
protected override void OnInitialized()
{
formattedDate = DateTimeProvider.FormattedNow();
}
}

View File

@@ -9,7 +9,7 @@
[Parameter]
public RenderFragment? ChildContent { get; set; }
public string StatusText { get; set; } = string.Empty;
public string StatusText { get; private set; } = string.Empty;
public void SetMessage(string message)
{

View File

@@ -1,6 +1,7 @@
using AutoMapper;
using BlazorWebAssemblyVisaApiClient.FluentValidation.Applicants.Models;
using BlazorWebAssemblyVisaApiClient.Validation.Applicants.Models;
using VisaApiClient;
using PlaceOfWorkModel = BlazorWebAssemblyVisaApiClient.Validation.Applicants.Models.PlaceOfWorkModel;
namespace BlazorWebAssemblyVisaApiClient.Infrastructure.AutoMapper.Profiles
{
@@ -12,7 +13,7 @@ namespace BlazorWebAssemblyVisaApiClient.Infrastructure.AutoMapper.Profiles
CreateMap<RegisterRequestModel, RegisterRequest>(MemberList.Destination);
CreateMap<FluentValidation.Applicants.Models.PlaceOfWorkModel, VisaApiClient.PlaceOfWorkModel>(MemberList.Destination);
CreateMap<PlaceOfWorkModel, VisaApiClient.PlaceOfWorkModel>(MemberList.Destination);
}
}
}

View File

@@ -3,5 +3,7 @@
public class DateTimeProvider : IDateTimeProvider
{
public DateTime Now() => DateTime.Now;
public string FormattedNow() => Now().ToString("yyyy-MM-dd");
}
}

View File

@@ -3,5 +3,7 @@
public interface IDateTimeProvider
{
DateTime Now();
string FormattedNow();
}
}

View File

@@ -1,7 +1,6 @@
@page "/applications"
@using System.Net
@using System.Text
@using BlazorWebAssemblyVisaApiClient.Components
@using BlazorWebAssemblyVisaApiClient.Components.Auth
@using BlazorWebAssemblyVisaApiClient.Infrastructure.Helpers
@using VisaApiClient

View File

@@ -0,0 +1,78 @@
@page "/visaApplications/new"
@using BlazorWebAssemblyVisaApiClient.Validation.VisaApplications.Models
@using BlazorWebAssemblyVisaApiClient.Components.FormComponents.Applicants
@using VisaApiClient
@using BlazorWebAssemblyVisaApiClient.Components
@using BlazorWebAssemblyVisaApiClient.Components.FormComponents.VisaApplications
@using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.DateTimeProvider
@inherits BlazorWebAssemblyVisaApiClient.Components.Base.VisaClientComponentBase
<PageTitle>New Application</PageTitle>
<div class="horizontal-centered-content">
<h3>New application</h3>
<EditForm class="form" Model="requestModel" OnValidSubmit="TryCreate">
<ObjectGraphDataAnnotationsValidator/>
<div class="form-block">
<h5>Visa</h5>
<label>
Destination Country:<br/>
<InputText DisplayName="Destination Country" class="rounded" @bind-Value="requestModel.DestinationCountry"/>
</label><br/>
<ValidationMessage For="() => requestModel.DestinationCountry"></ValidationMessage><br/>
<label>
Category: <EnumInputList Model="requestModel"
EnumProperty="r => r.VisaCategory"
OnChanged="StateHasChanged"/>
</label><br/>
<ValidationMessage For="() => requestModel.VisaCategory"></ValidationMessage><br/>
<label>
Number of entries: <EnumInputList Model="requestModel" EnumProperty="r => r.RequestedNumberOfEntries"/>
</label><br/>
<ValidationMessage For="() => requestModel.RequestedNumberOfEntries"></ValidationMessage><br/>
<label>
For group: <InputCheckbox @bind-Value="requestModel.IsForGroup"/>
</label><br/>
<ValidationMessage For="() => requestModel.IsForGroup"></ValidationMessage><br/>
<label>
Valid for days:<br/>
<InputNumber DisplayName="Valid days" class="rounded" @bind-Value="requestModel.ValidDaysRequested"/>
</label>
<ValidationMessage For="() => requestModel.ValidDaysRequested"></ValidationMessage><br/>
</div>
<div class="form-block">
<fieldset disabled="@(requestModel.VisaCategory is not VisaCategory.Transit)">
<h5>Permission to destination Country</h5>
<PermissionToDestCountryInput PermissionToDestCountry="requestModel.PermissionToDestCountry" />
</fieldset>
</div><br/>
<input type="submit" class="btn-outline-primary" value="Register"/>
<Status @ref="status"/>
</EditForm>
</div>
@code {
private VisaApplicationCreateRequestModel requestModel = new();
private Status status = null!;
[Inject] IDateTimeProvider DateTimeProvider { get; set; } = null!;
protected override void OnInitialized()
{
requestModel.PermissionToDestCountry!.ExpirationDate = DateTimeProvider.Now();
}
private static void TryCreate()
{
}
}

View File

@@ -4,13 +4,12 @@
@using AutoMapper
@using VisaApiClient
@using BlazorWebAssemblyVisaApiClient.Components.FormComponents.Applicants
@using BlazorWebAssemblyVisaApiClient.FluentValidation.Applicants.Models
@using BlazorWebAssemblyVisaApiClient.Infrastructure.Services
@using global::FluentValidation
@using Newtonsoft.Json
@using Newtonsoft.Json.Linq
@using BlazorWebAssemblyVisaApiClient.Components
@using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.DateTimeProvider
@using BlazorWebAssemblyVisaApiClient.Validation.Applicants.Models
@inherits BlazorWebAssemblyVisaApiClient.Components.Base.VisaClientComponentBase
<PageTitle>Registration</PageTitle>
@@ -60,7 +59,7 @@
<ValidationMessage For="() => requestModel.CityOfBirth"></ValidationMessage><br/>
<label>
Birth date:<br/>
<InputDate DisplayName="Birth date" class="rounded" @bind-Value="requestModel.BirthDate" max="@DateTimeProvider.Now()"/>
<InputDate DisplayName="Birth date" class="rounded" @bind-Value="requestModel.BirthDate" max="@DateTimeProvider.FormattedNow()"/>
</label><br/>
<ValidationMessage For="() => requestModel.BirthDate"></ValidationMessage>
</div>

View File

@@ -1,5 +1,5 @@
using System.Reflection;
using BlazorWebAssemblyVisaApiClient.Infrastructure.Services;
using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.DateTimeProvider;
using FluentValidation;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

View File

@@ -1,7 +1,7 @@
using System.ComponentModel.DataAnnotations;
using VisaApiClient;
namespace BlazorWebAssemblyVisaApiClient.FluentValidation.Applicants.Models
namespace BlazorWebAssemblyVisaApiClient.Validation.Applicants.Models
{
/// Model of place of work with attributes required for validation to work
public class PlaceOfWorkModel

View File

@@ -3,7 +3,7 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using VisaApiClient;
namespace BlazorWebAssemblyVisaApiClient.FluentValidation.Applicants.Models
namespace BlazorWebAssemblyVisaApiClient.Validation.Applicants.Models
{
/// Model of request with attributes required for validation to work
public class RegisterApplicantRequestModel

View File

@@ -1,7 +1,7 @@
using System.ComponentModel.DataAnnotations;
using VisaApiClient;
namespace BlazorWebAssemblyVisaApiClient.FluentValidation.Applicants.Models
namespace BlazorWebAssemblyVisaApiClient.Validation.Applicants.Models
{
/// Model of request with attributes required for validation to work
public class RegisterRequestModel

View File

@@ -1,7 +1,7 @@
using FluentValidation;
using VisaApiClient;
namespace BlazorWebAssemblyVisaApiClient.FluentValidation.Applicants.Validators;
namespace BlazorWebAssemblyVisaApiClient.Validation.Applicants.Validators;
public class NameModelValidator : AbstractValidator<NameModel>
{

View File

@@ -1,9 +1,8 @@
using BlazorWebAssemblyVisaApiClient.Infrastructure.Services;
using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.DateTimeProvider;
using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.DateTimeProvider;
using FluentValidation;
using VisaApiClient;
namespace BlazorWebAssemblyVisaApiClient.FluentValidation.Applicants.Validators;
namespace BlazorWebAssemblyVisaApiClient.Validation.Applicants.Validators;
public class PassportModelValidator : AbstractValidator<PassportModel>
{

View File

@@ -1,7 +1,7 @@
using BlazorWebAssemblyVisaApiClient.FluentValidation.Applicants.Models;
using BlazorWebAssemblyVisaApiClient.Validation.Applicants.Models;
using FluentValidation;
namespace BlazorWebAssemblyVisaApiClient.FluentValidation.Applicants.Validators;
namespace BlazorWebAssemblyVisaApiClient.Validation.Applicants.Validators;
public class PlaceOfWorkModelValidator : AbstractValidator<PlaceOfWorkModel>
{

View File

@@ -1,11 +1,10 @@
using BlazorWebAssemblyVisaApiClient.FluentValidation.Applicants.Models;
using BlazorWebAssemblyVisaApiClient.Infrastructure.Services;
using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.DateTimeProvider;
using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.DateTimeProvider;
using BlazorWebAssemblyVisaApiClient.Validation.Applicants.Models;
using FluentValidation;
using VisaApiClient;
using PlaceOfWorkModel = BlazorWebAssemblyVisaApiClient.FluentValidation.Applicants.Models.PlaceOfWorkModel;
using PlaceOfWorkModel = BlazorWebAssemblyVisaApiClient.Validation.Applicants.Models.PlaceOfWorkModel;
namespace BlazorWebAssemblyVisaApiClient.FluentValidation.Applicants.Validators;
namespace BlazorWebAssemblyVisaApiClient.Validation.Applicants.Validators;
public class RegisterApplicantRequestValidator : AbstractValidator<RegisterApplicantRequestModel>
{

View File

@@ -1,7 +1,7 @@
using FluentValidation;
using VisaApiClient;
namespace BlazorWebAssemblyVisaApiClient.FluentValidation.Common;
namespace BlazorWebAssemblyVisaApiClient.Validation.Common;
public class AuthDataValidator : AbstractValidator<AuthData>
{

View File

@@ -1,8 +1,8 @@
using BlazorWebAssemblyVisaApiClient.FluentValidation.Applicants.Models;
using BlazorWebAssemblyVisaApiClient.Validation.Applicants.Models;
using FluentValidation;
using VisaApiClient;
namespace BlazorWebAssemblyVisaApiClient.FluentValidation.Common;
namespace BlazorWebAssemblyVisaApiClient.Validation.Common;
public class RegisterRequestModelValidator : AbstractValidator<RegisterRequestModel>
{

View File

@@ -1,4 +1,4 @@
namespace BlazorWebAssemblyVisaApiClient.FluentValidation;
namespace BlazorWebAssemblyVisaApiClient.Validation;
public static class ConfigurationConstraints
{

View File

@@ -0,0 +1,40 @@
using System.ComponentModel.DataAnnotations;
using VisaApiClient;
namespace BlazorWebAssemblyVisaApiClient.Validation.VisaApplications.Models
{
/// Model for request for data annotations validation to work
public class VisaApplicationCreateRequestModel
{
[ValidateComplexType]
public ReentryPermitModel? ReentryPermit { get; set; } = new();
[Required]
[MaxLength(ConfigurationConstraints.CountryNameLength)]
public string DestinationCountry { get; set; } = default!;
[Required]
public VisaCategory VisaCategory { get; set; }
[Required]
public bool IsForGroup { get; set; }
[Required]
public RequestedNumberOfEntries RequestedNumberOfEntries { get; set; }
[Required]
[Range(0, ConfigurationConstraints.MaxValidDays)]
public int ValidDaysRequested { get; set; }
[Required]
[ValidateComplexType]
public PastVisaModel[] PastVisas { get; set; } = default!;
[ValidateComplexType]
public PermissionToDestCountryModel? PermissionToDestCountry { get; set; } = new();
[Required]
[ValidateComplexType]
public PastVisitModel[] PastVisits { get; set; } = default!;
}
}

View File

@@ -1713,14 +1713,12 @@ namespace VisaApiClient
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")]
public partial class PermissionToDestCountryModel
{
[Newtonsoft.Json.JsonProperty("expirationDate", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
[Newtonsoft.Json.JsonProperty("expirationDate", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public System.DateTimeOffset ExpirationDate { get; set; } = default!;
[Newtonsoft.Json.JsonProperty("issuer", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required]
[System.ComponentModel.DataAnnotations.StringLength(200, MinimumLength = 1)]
public string Issuer { get; set; } = default!;
[Newtonsoft.Json.JsonProperty("issuer", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
[System.ComponentModel.DataAnnotations.StringLength(200)]
public string? Issuer { get; set; } = default!;
}
@@ -1775,13 +1773,11 @@ namespace VisaApiClient
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")]
public partial class ReentryPermitModel
{
[Newtonsoft.Json.JsonProperty("number", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required]
[System.ComponentModel.DataAnnotations.StringLength(25, MinimumLength = 1)]
public string Number { get; set; } = default!;
[Newtonsoft.Json.JsonProperty("number", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
[System.ComponentModel.DataAnnotations.StringLength(25)]
public string? Number { get; set; } = default!;
[Newtonsoft.Json.JsonProperty("expirationDate", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
[Newtonsoft.Json.JsonProperty("expirationDate", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public System.DateTimeOffset ExpirationDate { get; set; } = default!;
}
@@ -1898,9 +1894,8 @@ namespace VisaApiClient
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")]
public partial class VisaApplicationCreateRequest
{
[Newtonsoft.Json.JsonProperty("reentryPermit", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required]
public ReentryPermitModel ReentryPermit { get; set; } = new ReentryPermitModel();
[Newtonsoft.Json.JsonProperty("reentryPermit", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
public ReentryPermitModel ReentryPermit { get; set; } = default!;
[Newtonsoft.Json.JsonProperty("destinationCountry", Required = Newtonsoft.Json.Required.Always)]
[System.ComponentModel.DataAnnotations.Required]

File diff suppressed because one or more lines are too long