From 48f88cdc146e1ecd704462d2544f8c92ee051fdd Mon Sep 17 00:00:00 2001 From: Ibrahim Munir-Zubair Date: Tue, 6 Jul 2021 21:22:32 +0100 Subject: [PATCH 01/19] HEEDLS-546 Delegate registration by centre: WelcomeEmail page GET --- .../RegisterDelegateByCentreController.cs | 13 ++- .../WelcomeEmailViewModel.cs | 12 +++ .../WelcomeEmail.cshtml | 87 +++++++++++++++++++ 3 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/WelcomeEmailViewModel.cs create mode 100644 DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/WelcomeEmail.cshtml diff --git a/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs b/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs index c4e655a3c1..24a31eddcb 100644 --- a/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs +++ b/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs @@ -11,6 +11,7 @@ namespace DigitalLearningSolutions.Web.Controllers.Register using DigitalLearningSolutions.Web.ServiceFilter; using DigitalLearningSolutions.Web.ViewModels.Common; using DigitalLearningSolutions.Web.ViewModels.Register; + using DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -118,7 +119,17 @@ public IActionResult LearnerInformation(LearnerInformationViewModel model) data.SetLearnerInformation(model); TempData.Set(data); - return new OkResult(); + return RedirectToAction("WelcomeEmail"); + } + + [ServiceFilter(typeof(RedirectEmptySessionData))] + [HttpGet] + [Route("WelcomeEmail")] + public IActionResult WelcomeEmail() + { + var model = new WelcomeEmailViewModel(); + + return View(model); } private void SetCentreDelegateRegistrationData(int centreId) diff --git a/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/WelcomeEmailViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/WelcomeEmailViewModel.cs new file mode 100644 index 0000000000..8d9257cb04 --- /dev/null +++ b/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/WelcomeEmailViewModel.cs @@ -0,0 +1,12 @@ +namespace DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre +{ + using System; + + public class WelcomeEmailViewModel + { + public int? Day { get; set; } + public int? Month { get; set; } + public int? Year { get; set; } + public bool ShouldSendEmail { get; set; } + } +} diff --git a/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/WelcomeEmail.cshtml b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/WelcomeEmail.cshtml new file mode 100644 index 0000000000..0f27d29116 --- /dev/null +++ b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/WelcomeEmail.cshtml @@ -0,0 +1,87 @@ +@using DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre +@model WelcomeEmailViewModel + +@{ + var errorHasOccurred = !ViewData.ModelState.IsValid; + ViewData["Title"] = errorHasOccurred ? "Error: Register Delegate - Welcome Email" : "Register Delegate - Welcome Email"; + var exampleDate = DateTime.Today; +} + +@section NavMenuItems { + +} + +
+
+ @if (errorHasOccurred) { + + } + +

Welcome Email

+ +
+
+
+ + +
+ +
+
+ + Deliver email on or after: + +
+ For example, @exampleDate.Day @exampleDate.Month @exampleDate.Year +
+ +
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+
+ + +
+ + +
+
From 2d171a73c627cb6abd0e5e05feec55609cf335c4 Mon Sep 17 00:00:00 2001 From: Ibrahim Munir-Zubair Date: Wed, 7 Jul 2021 11:43:33 +0100 Subject: [PATCH 02/19] HEEDLS-546 Add date validation to WelcomeEmail POST; display date fields and errors correctly on page --- .../ControllerHelpers/DateValidator.cs | 41 +++++++-- .../RegisterDelegateByCentreController.cs | 26 +++++- .../WelcomeEmailViewModel.cs | 3 +- .../WelcomeEmail.cshtml | 83 +++++++++++-------- 4 files changed, 111 insertions(+), 42 deletions(-) diff --git a/DigitalLearningSolutions.Web/ControllerHelpers/DateValidator.cs b/DigitalLearningSolutions.Web/ControllerHelpers/DateValidator.cs index 15a3bae30f..81c0df903a 100644 --- a/DigitalLearningSolutions.Web/ControllerHelpers/DateValidator.cs +++ b/DigitalLearningSolutions.Web/ControllerHelpers/DateValidator.cs @@ -39,6 +39,35 @@ public ValidationResult(int day, int month, int year) public int? Year { get; } } + public static ValidationResult ValidateRequiredDate(int? day, int? month, int? year, string name) + { + day ??= 0; + month ??= 0; + year ??= 0; + + try + { + var newDate = new DateTime(year.Value, month.Value, day.Value); + if (newDate <= DateTime.Today) + { + return new ValidationResult(day.Value, month.Value, year.Value) + { + DateValid = false, + DayValid = false, + MonthValid = false, + YearValid = false, + ErrorMessage = "Email delivery date must be in the future" + }; + } + + return new ValidationResult(day.Value, month.Value, year.Value); + } + catch (ArgumentOutOfRangeException) + { + return GetValidationError(day.Value, month.Value, year.Value, name); + } + } + public static ValidationResult ValidateDate(int day, int month, int year) { if (day == 0 && month == 0 && year == 0) @@ -70,11 +99,11 @@ public static ValidationResult ValidateDate(int day, int month, int year) } catch (ArgumentOutOfRangeException) { - return GetValidationError(day, month, year); + return GetValidationError(day, month, year, "Complete by date"); } } - private static ValidationResult GetValidationError(int day, int month, int year) + private static ValidationResult GetValidationError(int day, int month, int year, string name) { var error = new ValidationResult(day, month, year) { DateValid = false }; @@ -93,7 +122,7 @@ private static ValidationResult GetValidationError(int day, int month, int year) error.YearValid = false; } - error.ErrorMessage = ConstructErrorMessage(day, month, year); + error.ErrorMessage = ConstructErrorMessage(day, month, year, name); return error; } @@ -113,7 +142,7 @@ private static bool YearIsValid(int year) return year > 1752 && year < 10000; } - private static string ConstructErrorMessage(int day, int month, int year) + private static string ConstructErrorMessage(int day, int month, int year, string name) { List emptyElements = new List(); @@ -134,10 +163,10 @@ private static string ConstructErrorMessage(int day, int month, int year) if (emptyElements.Any()) { - return "Complete by date must include a " + string.Join(" and ", emptyElements); + return name + " must include a " + string.Join(" and ", emptyElements); } - return "Complete by date must be a real date"; + return name + " must be a real date"; } } } diff --git a/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs b/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs index 24a31eddcb..d59151e9be 100644 --- a/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs +++ b/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs @@ -5,6 +5,7 @@ namespace DigitalLearningSolutions.Web.Controllers.Register using System.Linq; using DigitalLearningSolutions.Data.DataServices; using DigitalLearningSolutions.Data.Services; + using DigitalLearningSolutions.Web.ControllerHelpers; using DigitalLearningSolutions.Web.Extensions; using DigitalLearningSolutions.Web.Helpers; using DigitalLearningSolutions.Web.Models; @@ -128,7 +129,19 @@ public IActionResult LearnerInformation(LearnerInformationViewModel model) public IActionResult WelcomeEmail() { var model = new WelcomeEmailViewModel(); - + + return View(model); + } + + [ServiceFilter(typeof(RedirectEmptySessionData))] + [HttpPost] + [Route("WelcomeEmail")] + public IActionResult WelcomeEmail(WelcomeEmailViewModel model) + { + var data = TempData.Peek()!; + + ValidateWelcomeEmail(model); + return View(model); } @@ -172,6 +185,17 @@ private void ValidateEmailAddress(PersonalInformationViewModel model) } } + private void ValidateWelcomeEmail(WelcomeEmailViewModel model) + { + if (!model.ShouldSendEmail) + { + return; + } + + var validationResult = DateValidator.ValidateRequiredDate(model.Day, model.Month, model.Year, "Email delivery date"); + model.DateValidationResult = validationResult; + } + private IEnumerable GetEditCustomFieldsFromModel( LearnerInformationViewModel model, int centreId diff --git a/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/WelcomeEmailViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/WelcomeEmailViewModel.cs index 8d9257cb04..fd2653eb4f 100644 --- a/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/WelcomeEmailViewModel.cs +++ b/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/WelcomeEmailViewModel.cs @@ -1,6 +1,6 @@ namespace DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre { - using System; + using DigitalLearningSolutions.Web.ControllerHelpers; public class WelcomeEmailViewModel { @@ -8,5 +8,6 @@ public class WelcomeEmailViewModel public int? Month { get; set; } public int? Year { get; set; } public bool ShouldSendEmail { get; set; } + public DateValidator.ValidationResult DateValidationResult { get; set; } } } diff --git a/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/WelcomeEmail.cshtml b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/WelcomeEmail.cshtml index 0f27d29116..26417200b6 100644 --- a/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/WelcomeEmail.cshtml +++ b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/WelcomeEmail.cshtml @@ -2,9 +2,13 @@ @model WelcomeEmailViewModel @{ - var errorHasOccurred = !ViewData.ModelState.IsValid; - ViewData["Title"] = errorHasOccurred ? "Error: Register Delegate - Welcome Email" : "Register Delegate - Welcome Email"; - var exampleDate = DateTime.Today; + var errorHasOccurred = Model.DateValidationResult is { DateValid: false }; + ViewData["Title"] = errorHasOccurred ? "Error: Register Delegate - Welcome Email" : "Register Delegate - Welcome Email"; + var exampleDate = DateTime.Today; + var emailDateCss = "nhsuk-checkboxes__conditional" + (Model.ShouldSendEmail ? "" : " nhsuk-checkboxes__conditional--hidden"); + var dayErrorCss = Model.DateValidationResult is { DayValid: false } ? "nhsuk-input--error" : ""; + var monthErrorCss = Model.DateValidationResult is { MonthValid: false } ? "nhsuk-input--error" : ""; + var yearErrorCss = Model.DateValidationResult is { YearValid: false } ? "nhsuk-input--error" : ""; } @section NavMenuItems { @@ -14,64 +18,75 @@
@if (errorHasOccurred) { - + } -

Welcome Email

+

Welcome email

- +
-
-
+
+
Deliver email on or after: -
+
For example, @exampleDate.Day @exampleDate.Month @exampleDate.Year
-
+ @if (errorHasOccurred) { + + Error: @Model.DateValidationResult!.ErrorMessage + + } + +
- + +
- + +
- + +
From d6e698eee6f560e880f62a59409a3828b6f62612 Mon Sep 17 00:00:00 2001 From: Ibrahim Munir-Zubair Date: Wed, 7 Jul 2021 12:04:44 +0100 Subject: [PATCH 03/19] HEEDLS-546 Read/write between ViewModel and Data on WelcomeEmail GET/POST --- .../RegisterDelegateByCentreController.cs | 20 +++++++++++++++---- .../DelegateRegistrationByCentreData.cs | 16 +++++++++++++++ .../WelcomeEmailViewModel.cs | 14 ++++++++++++- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs b/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs index d59151e9be..8104f919d3 100644 --- a/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs +++ b/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs @@ -128,7 +128,9 @@ public IActionResult LearnerInformation(LearnerInformationViewModel model) [Route("WelcomeEmail")] public IActionResult WelcomeEmail() { - var model = new WelcomeEmailViewModel(); + var data = TempData.Peek()!; + + var model = new WelcomeEmailViewModel(data); return View(model); } @@ -140,7 +142,13 @@ public IActionResult WelcomeEmail(WelcomeEmailViewModel model) { var data = TempData.Peek()!; - ValidateWelcomeEmail(model); + if (!ValidateWelcomeEmail(model)) + { + return View(model); + } + + data.SetWelcomeEmail(model); + TempData.Set(data); return View(model); } @@ -185,15 +193,19 @@ private void ValidateEmailAddress(PersonalInformationViewModel model) } } - private void ValidateWelcomeEmail(WelcomeEmailViewModel model) + private bool ValidateWelcomeEmail(WelcomeEmailViewModel model) { if (!model.ShouldSendEmail) { - return; + model.Day = null; + model.Month = null; + model.Year = null; + return true; } var validationResult = DateValidator.ValidateRequiredDate(model.Day, model.Month, model.Year, "Email delivery date"); model.DateValidationResult = validationResult; + return validationResult.DateValid; } private IEnumerable GetEditCustomFieldsFromModel( diff --git a/DigitalLearningSolutions.Web/Models/DelegateRegistrationByCentreData.cs b/DigitalLearningSolutions.Web/Models/DelegateRegistrationByCentreData.cs index 0303c454f8..296146f023 100644 --- a/DigitalLearningSolutions.Web/Models/DelegateRegistrationByCentreData.cs +++ b/DigitalLearningSolutions.Web/Models/DelegateRegistrationByCentreData.cs @@ -1,7 +1,23 @@ namespace DigitalLearningSolutions.Web.Models { + using System; + using DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre; + public class DelegateRegistrationByCentreData : DelegateRegistrationData { public string? Alias { get; set; } + + public bool ShouldSendEmail { get; set; } + + public DateTime? WelcomeEmailDate { get; set; } + + public void SetWelcomeEmail(WelcomeEmailViewModel model) + { + ShouldSendEmail = model.ShouldSendEmail; + if (ShouldSendEmail) + { + WelcomeEmailDate = new DateTime(model.Year!.Value, model.Month!.Value, model.Day!.Value); + } + } } } diff --git a/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/WelcomeEmailViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/WelcomeEmailViewModel.cs index fd2653eb4f..0ee3135cda 100644 --- a/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/WelcomeEmailViewModel.cs +++ b/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/WelcomeEmailViewModel.cs @@ -1,13 +1,25 @@ namespace DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre { using DigitalLearningSolutions.Web.ControllerHelpers; + using DigitalLearningSolutions.Web.Models; public class WelcomeEmailViewModel { + public WelcomeEmailViewModel(DelegateRegistrationByCentreData data) + { + ShouldSendEmail = data.ShouldSendEmail; + if (ShouldSendEmail && data.WelcomeEmailDate != null) + { + Day = data.WelcomeEmailDate.Value.Day; + Month = data.WelcomeEmailDate.Value.Month; + Year = data.WelcomeEmailDate.Value.Year; + } + } + public int? Day { get; set; } public int? Month { get; set; } public int? Year { get; set; } public bool ShouldSendEmail { get; set; } - public DateValidator.ValidationResult DateValidationResult { get; set; } + public DateValidator.ValidationResult? DateValidationResult { get; set; } } } From 2239a712786405c799bb7ee491dba2633279e80e Mon Sep 17 00:00:00 2001 From: Ibrahim Munir-Zubair Date: Wed, 7 Jul 2021 13:14:23 +0100 Subject: [PATCH 04/19] HEEDLS-546 Add empty constructor to WelcomeEmail viewmodel Apparently you need an empty constructor for model binding to work? Took way too long to figure that one out --- .../RegisterDelegateByCentre/WelcomeEmailViewModel.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/WelcomeEmailViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/WelcomeEmailViewModel.cs index 0ee3135cda..c3206ff3a3 100644 --- a/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/WelcomeEmailViewModel.cs +++ b/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/WelcomeEmailViewModel.cs @@ -5,6 +5,8 @@ public class WelcomeEmailViewModel { + public WelcomeEmailViewModel() {} + public WelcomeEmailViewModel(DelegateRegistrationByCentreData data) { ShouldSendEmail = data.ShouldSendEmail; From 0b236c8007a44e119a9662aab3366bb3e1398237 Mon Sep 17 00:00:00 2001 From: Ibrahim Munir-Zubair Date: Wed, 7 Jul 2021 17:14:40 +0100 Subject: [PATCH 05/19] HEEDLS-546 Delegate registration by centre: Password page --- .../RegisterDelegateByCentreController.cs | 38 ++++++++++++++-- .../PasswordViewModel.cs | 17 +++++++ .../RegisterDelegateByCentre/Password.cshtml | 45 +++++++++++++++++++ 3 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/PasswordViewModel.cs create mode 100644 DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Password.cshtml diff --git a/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs b/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs index 8104f919d3..d89df2eddc 100644 --- a/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs +++ b/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs @@ -16,6 +16,7 @@ namespace DigitalLearningSolutions.Web.Controllers.Register using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; + using PasswordViewModel = ViewModels.RegisterDelegateByCentre.PasswordViewModel; [Authorize(Policy = CustomPolicies.UserCentreAdmin)] [Route("/TrackingSystem/Delegates/Register/{action}")] @@ -25,16 +26,19 @@ public class RegisterDelegateByCentreController : Controller private readonly CustomPromptHelper customPromptHelper; private readonly IJobGroupsDataService jobGroupsDataService; private readonly IUserService userService; + private readonly ICryptoService cryptoService; public RegisterDelegateByCentreController( IJobGroupsDataService jobGroupsDataService, IUserService userService, - CustomPromptHelper customPromptHelper + CustomPromptHelper customPromptHelper, + ICryptoService cryptoService ) { this.jobGroupsDataService = jobGroupsDataService; this.userService = userService; this.customPromptHelper = customPromptHelper; + this.cryptoService = cryptoService; } [Route("/TrackingSystem/Delegates/Register")] @@ -125,7 +129,6 @@ public IActionResult LearnerInformation(LearnerInformationViewModel model) [ServiceFilter(typeof(RedirectEmptySessionData))] [HttpGet] - [Route("WelcomeEmail")] public IActionResult WelcomeEmail() { var data = TempData.Peek()!; @@ -137,7 +140,6 @@ public IActionResult WelcomeEmail() [ServiceFilter(typeof(RedirectEmptySessionData))] [HttpPost] - [Route("WelcomeEmail")] public IActionResult WelcomeEmail(WelcomeEmailViewModel model) { var data = TempData.Peek()!; @@ -150,6 +152,36 @@ public IActionResult WelcomeEmail(WelcomeEmailViewModel model) data.SetWelcomeEmail(model); TempData.Set(data); + if (!data.ShouldSendEmail) + { + return RedirectToAction("Password"); + } + + return View(model); + } + + [ServiceFilter(typeof(RedirectEmptySessionData))] + [HttpGet] + public IActionResult Password() + { + var model = new PasswordViewModel(); + + return View(model); + } + + [ServiceFilter(typeof(RedirectEmptySessionData))] + [HttpPost] + public IActionResult Password(PasswordViewModel model) + { + if (!ModelState.IsValid) + { + return View(model); + } + + var data = TempData.Peek()!; + data.PasswordHash = cryptoService.GetPasswordHash(model.Password!); + TempData.Set(data); + return View(model); } diff --git a/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/PasswordViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/PasswordViewModel.cs new file mode 100644 index 0000000000..23416a26da --- /dev/null +++ b/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/PasswordViewModel.cs @@ -0,0 +1,17 @@ +namespace DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre +{ + using System.ComponentModel.DataAnnotations; + + public class PasswordViewModel + { + [Required(ErrorMessage = "Enter a password")] + [MinLength(8, ErrorMessage = "Password must be 8 characters or more")] + [MaxLength(100, ErrorMessage = "Password must be 100 characters or fewer")] + [RegularExpression( + @"(?=.*?[^\w\s])(?=.*?[0-9])(?=.*?[A-Za-z]).*", + ErrorMessage = "Password must contain at least 1 letter, 1 number and 1 symbol" + )] + [DataType(DataType.Password)] + public string? Password { get; set; } + } +} diff --git a/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Password.cshtml b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Password.cshtml new file mode 100644 index 0000000000..14356f4f58 --- /dev/null +++ b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Password.cshtml @@ -0,0 +1,45 @@ +@inject IConfiguration Configuration +@using DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre +@using Microsoft.Extensions.Configuration +@model PasswordViewModel + +@{ + var errorHasOccurred = !ViewData.ModelState.IsValid; + ViewData["Title"] = errorHasOccurred ? "Error: Register Delegate - Password" : "Register Delegate - Password"; + ViewData["Application"] = "Tracking System"; + ViewData["HeaderPath"] = $"{Configuration["AppRootPath"]}/TrackingSystem/Centre/Dashboard"; + ViewData["HeaderPathName"] = "Tracking System"; +} + +@section NavMenuItems { + +} + +
+
+ @if (errorHasOccurred) { + + } + +

Set password

+ +

You chose not to send a welcome email to the delegate.

+

Would you like to set a password instead?

+ + + + + + + + + +
+
From 15555ecb8a74a5f98228417bf646f3173fce493c Mon Sep 17 00:00:00 2001 From: Ibrahim Munir-Zubair Date: Wed, 7 Jul 2021 17:43:30 +0100 Subject: [PATCH 06/19] HEEDLS-546 Delegate registration by centre: Summary page --- .../RegisterDelegateByCentreController.cs | 50 +++++-- .../SummaryViewModel.cs | 39 +++++ .../RegisterDelegateByCentre/Summary.cshtml | 140 ++++++++++++++++++ 3 files changed, 219 insertions(+), 10 deletions(-) create mode 100644 DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/SummaryViewModel.cs create mode 100644 DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Summary.cshtml diff --git a/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs b/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs index d89df2eddc..b214d50bbc 100644 --- a/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs +++ b/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs @@ -16,17 +16,18 @@ namespace DigitalLearningSolutions.Web.Controllers.Register using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; - using PasswordViewModel = ViewModels.RegisterDelegateByCentre.PasswordViewModel; + using PasswordViewModel = DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre.PasswordViewModel; + using SummaryViewModel = DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre.SummaryViewModel; [Authorize(Policy = CustomPolicies.UserCentreAdmin)] [Route("/TrackingSystem/Delegates/Register/{action}")] public class RegisterDelegateByCentreController : Controller { private const string CookieName = "DelegateRegistrationByCentreData"; + private readonly ICryptoService cryptoService; private readonly CustomPromptHelper customPromptHelper; private readonly IJobGroupsDataService jobGroupsDataService; private readonly IUserService userService; - private readonly ICryptoService cryptoService; public RegisterDelegateByCentreController( IJobGroupsDataService jobGroupsDataService, @@ -152,12 +153,7 @@ public IActionResult WelcomeEmail(WelcomeEmailViewModel model) data.SetWelcomeEmail(model); TempData.Set(data); - if (!data.ShouldSendEmail) - { - return RedirectToAction("Password"); - } - - return View(model); + return RedirectToAction(data.ShouldSendEmail ? "Summary" : "Password"); } [ServiceFilter(typeof(RedirectEmptySessionData))] @@ -182,7 +178,17 @@ public IActionResult Password(PasswordViewModel model) data.PasswordHash = cryptoService.GetPasswordHash(model.Password!); TempData.Set(data); - return View(model); + return RedirectToAction("Summary"); + } + + [ServiceFilter(typeof(RedirectEmptySessionData))] + [HttpGet] + public IActionResult Summary() + { + var data = TempData.Peek()!; + var viewModel = new SummaryViewModel(data); + PopulateSummaryExtraFields(viewModel, data); + return View(viewModel); } private void SetCentreDelegateRegistrationData(int centreId) @@ -235,7 +241,12 @@ private bool ValidateWelcomeEmail(WelcomeEmailViewModel model) return true; } - var validationResult = DateValidator.ValidateRequiredDate(model.Day, model.Month, model.Year, "Email delivery date"); + var validationResult = DateValidator.ValidateRequiredDate( + model.Day, + model.Month, + model.Year, + "Email delivery date" + ); model.DateValidationResult = validationResult; return validationResult.DateValid; } @@ -256,6 +267,19 @@ int centreId ); } + private IEnumerable GetCustomFieldsFromData(DelegateRegistrationData data) + { + return customPromptHelper.GetCustomFieldViewModelsForCentre( + data.Centre!.Value, + data.Answer1, + data.Answer2, + data.Answer3, + data.Answer4, + data.Answer5, + data.Answer6 + ); + } + private void PopulateLearnerInformationExtraFields( LearnerInformationViewModel model, RegistrationData data @@ -267,5 +291,11 @@ RegistrationData data model.JobGroup ); } + + private void PopulateSummaryExtraFields(SummaryViewModel model, DelegateRegistrationData data) + { + model.JobGroup = jobGroupsDataService.GetJobGroupName((int)data.JobGroup!); + model.CustomFields = GetCustomFieldsFromData(data); + } } } diff --git a/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/SummaryViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/SummaryViewModel.cs new file mode 100644 index 0000000000..dcb0d97ae4 --- /dev/null +++ b/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/SummaryViewModel.cs @@ -0,0 +1,39 @@ +namespace DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre +{ + using System; + using System.Collections.Generic; + using System.Globalization; + using DigitalLearningSolutions.Web.Models; + using DigitalLearningSolutions.Web.ViewModels.Common; + using Microsoft.VisualStudio.Web.CodeGeneration.CommandLine; + + public class SummaryViewModel + { + public SummaryViewModel() { } + + public SummaryViewModel(DelegateRegistrationByCentreData data) + { + FirstName = data.FirstName; + LastName = data.LastName; + Email = data.Email; + Alias = data.Alias; + PasswordSet = data.PasswordHash != null; + if (data.WelcomeEmailDate.HasValue) + { + CultureInfo originalCulture = CultureInfo.CurrentCulture; + CultureInfo.CurrentCulture = new CultureInfo("en-GB"); + WelcomeEmailDate = data.WelcomeEmailDate.Value.ToShortDateString(); + CultureInfo.CurrentCulture = originalCulture; + } + } + + public string? FirstName { get; set; } + public string? LastName { get; set; } + public string? Email { get; set; } + public string? Alias { get; set; } + public bool PasswordSet { get; set; } + public string? WelcomeEmailDate { get; set; } + public string? JobGroup { get; set; } + public IEnumerable CustomFields { get; set; } = new List(); + } +} diff --git a/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Summary.cshtml b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Summary.cshtml new file mode 100644 index 0000000000..b6fd947120 --- /dev/null +++ b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Summary.cshtml @@ -0,0 +1,140 @@ +@inject IConfiguration Configuration +@using DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre +@using Microsoft.Extensions.Configuration +@model SummaryViewModel +@{ + var errorHasOccurred = !ViewData.ModelState.IsValid; + ViewData["Title"] = errorHasOccurred ? "Error: Register Delegate - Summary" : "Register Delegate - Summary"; + ViewData["Application"] = "Tracking System"; + ViewData["HeaderPath"] = $"{Configuration["AppRootPath"]}/TrackingSystem/Centre/Dashboard"; + ViewData["HeaderPathName"] = "Tracking System"; +} + +@section NavMenuItems { + +} + +
+
+
+

Summary

+
+ +
+
+
+ First name +
+
+ @Model.FirstName +
+
+ + Change first name + +
+
+
+
+ Last name +
+
+ @Model.LastName +
+
+ + Change last name + +
+
+
+
+ Email +
+
+ @Model.Email +
+
+ + Change email address + +
+
+
+
+ Alias +
+
+ @Model.Alias +
+
+ + Change alias + +
+
+
+
+ Job group +
+
+ @Model.JobGroup +
+
+ + Change job group + +
+
+ @foreach (var customField in Model.CustomFields) { +
+
+ @(customField.CustomPrompt + (customField.Mandatory ? "" : " (optional)")) +
+
+ @customField.Answer +
+
+ + Change @customField.CustomPrompt.ToLower() + +
+
+ } +
+
+ @(Model.WelcomeEmailDate != null ? "Welcome email date" : "Send welcome email") +
+
+ @(Model.WelcomeEmailDate ?? "No") +
+
+ + Change welcome email settings + +
+
+ @if (Model.WelcomeEmailDate == null) { +
+
+ Password set +
+
+ @(Model.PasswordSet ? "Yes" : "No") +
+
+ + Change password settings + +
+
+ } +
+ +
+ +
+ + @*// TODO: link to correct page*@ +
+
From 1f714758e083128e486d88790f03ab2edb126f28 Mon Sep 17 00:00:00 2001 From: Ibrahim Munir-Zubair Date: Wed, 7 Jul 2021 17:55:56 +0100 Subject: [PATCH 07/19] HEEDLS-546 Fix and tidy up welcome email date and password set --- .../Models/DelegateRegistrationByCentreData.cs | 13 +++++++++---- .../RegisterDelegateByCentre/SummaryViewModel.cs | 16 ++++++++-------- .../WelcomeEmailViewModel.cs | 8 ++++---- .../RegisterDelegateByCentre/Summary.cshtml | 12 ++++++------ 4 files changed, 27 insertions(+), 22 deletions(-) diff --git a/DigitalLearningSolutions.Web/Models/DelegateRegistrationByCentreData.cs b/DigitalLearningSolutions.Web/Models/DelegateRegistrationByCentreData.cs index 296146f023..8e587eb286 100644 --- a/DigitalLearningSolutions.Web/Models/DelegateRegistrationByCentreData.cs +++ b/DigitalLearningSolutions.Web/Models/DelegateRegistrationByCentreData.cs @@ -7,17 +7,22 @@ public class DelegateRegistrationByCentreData : DelegateRegistrationData { public string? Alias { get; set; } - public bool ShouldSendEmail { get; set; } - public DateTime? WelcomeEmailDate { get; set; } public void SetWelcomeEmail(WelcomeEmailViewModel model) { - ShouldSendEmail = model.ShouldSendEmail; - if (ShouldSendEmail) + if (model.ShouldSendEmail) { WelcomeEmailDate = new DateTime(model.Year!.Value, model.Month!.Value, model.Day!.Value); } + else + { + WelcomeEmailDate = null; + } } + + public bool ShouldSendEmail => WelcomeEmailDate.HasValue; + + public bool IsPasswordSet => PasswordHash != null; } } diff --git a/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/SummaryViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/SummaryViewModel.cs index dcb0d97ae4..a72b1aa5ea 100644 --- a/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/SummaryViewModel.cs +++ b/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/SummaryViewModel.cs @@ -1,28 +1,27 @@ -namespace DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre +namespace DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre { - using System; using System.Collections.Generic; using System.Globalization; using DigitalLearningSolutions.Web.Models; using DigitalLearningSolutions.Web.ViewModels.Common; - using Microsoft.VisualStudio.Web.CodeGeneration.CommandLine; public class SummaryViewModel { public SummaryViewModel() { } - + public SummaryViewModel(DelegateRegistrationByCentreData data) { FirstName = data.FirstName; LastName = data.LastName; Email = data.Email; Alias = data.Alias; - PasswordSet = data.PasswordHash != null; - if (data.WelcomeEmailDate.HasValue) + IsPasswordSet = data.IsPasswordSet; + ShouldSendEmail = data.ShouldSendEmail; + if (ShouldSendEmail) { CultureInfo originalCulture = CultureInfo.CurrentCulture; CultureInfo.CurrentCulture = new CultureInfo("en-GB"); - WelcomeEmailDate = data.WelcomeEmailDate.Value.ToShortDateString(); + WelcomeEmailDate = data.WelcomeEmailDate!.Value.ToShortDateString(); CultureInfo.CurrentCulture = originalCulture; } } @@ -31,7 +30,8 @@ public SummaryViewModel(DelegateRegistrationByCentreData data) public string? LastName { get; set; } public string? Email { get; set; } public string? Alias { get; set; } - public bool PasswordSet { get; set; } + public bool IsPasswordSet { get; set; } + public bool ShouldSendEmail { get; set; } public string? WelcomeEmailDate { get; set; } public string? JobGroup { get; set; } public IEnumerable CustomFields { get; set; } = new List(); diff --git a/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/WelcomeEmailViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/WelcomeEmailViewModel.cs index c3206ff3a3..60eaeba571 100644 --- a/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/WelcomeEmailViewModel.cs +++ b/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/WelcomeEmailViewModel.cs @@ -10,11 +10,11 @@ public WelcomeEmailViewModel() {} public WelcomeEmailViewModel(DelegateRegistrationByCentreData data) { ShouldSendEmail = data.ShouldSendEmail; - if (ShouldSendEmail && data.WelcomeEmailDate != null) + if (ShouldSendEmail) { - Day = data.WelcomeEmailDate.Value.Day; - Month = data.WelcomeEmailDate.Value.Month; - Year = data.WelcomeEmailDate.Value.Year; + Day = data.WelcomeEmailDate!.Value.Day; + Month = data.WelcomeEmailDate!.Value.Month; + Year = data.WelcomeEmailDate!.Value.Year; } } diff --git a/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Summary.cshtml b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Summary.cshtml index b6fd947120..0177364b33 100644 --- a/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Summary.cshtml +++ b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Summary.cshtml @@ -103,27 +103,27 @@ }
- @(Model.WelcomeEmailDate != null ? "Welcome email date" : "Send welcome email") + @(Model.ShouldSendEmail ? "Welcome email date" : "Send welcome email")
- @(Model.WelcomeEmailDate ?? "No") + @(Model.ShouldSendEmail ? Model.WelcomeEmailDate : "No")
- + Change welcome email settings
- @if (Model.WelcomeEmailDate == null) { + @if (!Model.ShouldSendEmail) {
Password set
- @(Model.PasswordSet ? "Yes" : "No") + @(Model.IsPasswordSet ? "Yes" : "No")
- + Change password settings
From 55da6b52a9bb6b185796e74014979f787f6ffd29 Mon Sep 17 00:00:00 2001 From: Ibrahim Munir-Zubair Date: Wed, 7 Jul 2021 18:04:27 +0100 Subject: [PATCH 08/19] HEEDLS-546 Change back link on Summary to return to correct previous page; wording change; return OK on Summary submit --- .../Register/RegisterDelegateByCentreController.cs | 7 +++++++ .../RegisterDelegateByCentre/SummaryViewModel.cs | 5 ++++- .../Views/RegisterDelegateByCentre/Summary.cshtml | 7 +++---- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs b/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs index b214d50bbc..d8047f2ce3 100644 --- a/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs +++ b/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs @@ -191,6 +191,13 @@ public IActionResult Summary() return View(viewModel); } + [ServiceFilter(typeof(RedirectEmptySessionData))] + [HttpPost] + public IActionResult Summary(SummaryViewModel model) + { + return new OkResult(); + } + private void SetCentreDelegateRegistrationData(int centreId) { var centreDelegateRegistrationData = new DelegateRegistrationByCentreData diff --git a/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/SummaryViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/SummaryViewModel.cs index a72b1aa5ea..bbe0d702c6 100644 --- a/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/SummaryViewModel.cs +++ b/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/SummaryViewModel.cs @@ -1,4 +1,4 @@ -namespace DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre +namespace DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre { using System.Collections.Generic; using System.Globalization; @@ -16,6 +16,7 @@ public SummaryViewModel(DelegateRegistrationByCentreData data) Email = data.Email; Alias = data.Alias; IsPasswordSet = data.IsPasswordSet; + PreviousAction = "Password"; ShouldSendEmail = data.ShouldSendEmail; if (ShouldSendEmail) { @@ -23,6 +24,7 @@ public SummaryViewModel(DelegateRegistrationByCentreData data) CultureInfo.CurrentCulture = new CultureInfo("en-GB"); WelcomeEmailDate = data.WelcomeEmailDate!.Value.ToShortDateString(); CultureInfo.CurrentCulture = originalCulture; + PreviousAction = "WelcomeEmail"; } } @@ -35,5 +37,6 @@ public SummaryViewModel(DelegateRegistrationByCentreData data) public string? WelcomeEmailDate { get; set; } public string? JobGroup { get; set; } public IEnumerable CustomFields { get; set; } = new List(); + public string PreviousAction { get; set; } } } diff --git a/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Summary.cshtml b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Summary.cshtml index 0177364b33..4934d9d3e9 100644 --- a/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Summary.cshtml +++ b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Summary.cshtml @@ -62,7 +62,7 @@
- Alias + Alias (optional)
@Model.Alias @@ -132,9 +132,8 @@
- +
- - @*// TODO: link to correct page*@ +
From 51297cc887860f92c34461f57585e97c0a297ac3 Mon Sep 17 00:00:00 2001 From: Ibrahim Munir-Zubair Date: Wed, 7 Jul 2021 18:25:33 +0100 Subject: [PATCH 09/19] HEEDLS-546 Make password non-required; clear password hash if welcome email set --- .../Register/RegisterDelegateByCentreController.cs | 4 +++- .../Models/DelegateRegistrationByCentreData.cs | 1 + .../ViewModels/RegisterDelegateByCentre/PasswordViewModel.cs | 1 - 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs b/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs index d8047f2ce3..7c48168400 100644 --- a/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs +++ b/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs @@ -175,7 +175,9 @@ public IActionResult Password(PasswordViewModel model) } var data = TempData.Peek()!; - data.PasswordHash = cryptoService.GetPasswordHash(model.Password!); + + data.PasswordHash = model.Password != null ? cryptoService.GetPasswordHash(model.Password) : null; + TempData.Set(data); return RedirectToAction("Summary"); diff --git a/DigitalLearningSolutions.Web/Models/DelegateRegistrationByCentreData.cs b/DigitalLearningSolutions.Web/Models/DelegateRegistrationByCentreData.cs index 8e587eb286..f7fa34c258 100644 --- a/DigitalLearningSolutions.Web/Models/DelegateRegistrationByCentreData.cs +++ b/DigitalLearningSolutions.Web/Models/DelegateRegistrationByCentreData.cs @@ -14,6 +14,7 @@ public void SetWelcomeEmail(WelcomeEmailViewModel model) if (model.ShouldSendEmail) { WelcomeEmailDate = new DateTime(model.Year!.Value, model.Month!.Value, model.Day!.Value); + PasswordHash = null; } else { diff --git a/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/PasswordViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/PasswordViewModel.cs index 23416a26da..dc6cf6c57e 100644 --- a/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/PasswordViewModel.cs +++ b/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/PasswordViewModel.cs @@ -4,7 +4,6 @@ public class PasswordViewModel { - [Required(ErrorMessage = "Enter a password")] [MinLength(8, ErrorMessage = "Password must be 8 characters or more")] [MaxLength(100, ErrorMessage = "Password must be 100 characters or fewer")] [RegularExpression( From 20c36c0c3bd6aaa55dbd7ba56c836816c44fc097 Mon Sep 17 00:00:00 2001 From: Ibrahim Munir-Zubair Date: Thu, 8 Jul 2021 16:30:29 +0100 Subject: [PATCH 10/19] HEEDLS-546 Create and use DateInput view component --- .../ViewComponents/DateInputViewComponent.cs | 54 +++++++++++++++ .../ViewComponents/DateInputViewModel.cs | 51 ++++++++++++++ .../WelcomeEmail.cshtml | 66 ++++--------------- .../Components/DateInput/Default.cshtml | 58 ++++++++++++++++ 4 files changed, 175 insertions(+), 54 deletions(-) create mode 100644 DigitalLearningSolutions.Web/ViewComponents/DateInputViewComponent.cs create mode 100644 DigitalLearningSolutions.Web/ViewModels/Common/ViewComponents/DateInputViewModel.cs create mode 100644 DigitalLearningSolutions.Web/Views/Shared/Components/DateInput/Default.cshtml diff --git a/DigitalLearningSolutions.Web/ViewComponents/DateInputViewComponent.cs b/DigitalLearningSolutions.Web/ViewComponents/DateInputViewComponent.cs new file mode 100644 index 0000000000..21e3b86a44 --- /dev/null +++ b/DigitalLearningSolutions.Web/ViewComponents/DateInputViewComponent.cs @@ -0,0 +1,54 @@ +namespace DigitalLearningSolutions.Web.ViewComponents +{ + using DigitalLearningSolutions.Web.ControllerHelpers; + using DigitalLearningSolutions.Web.ViewModels.Common.ViewComponents; + using Microsoft.AspNetCore.Mvc; + + public class DateInputViewComponent : ViewComponent + { + /// + /// Render DateInput view component. + /// + /// + /// + /// + /// + /// + /// DateValidator.ValidationResult + /// Leave blank for no hint. + /// + public IViewComponentResult Invoke( + string name, + string label, + string dayId, + string monthId, + string yearId, + DateValidator.ValidationResult validationResult, + string hintText + ) + { + var model = ViewData.Model; + + var dayProperty = model.GetType().GetProperty(dayId); + var monthProperty = model.GetType().GetProperty(monthId); + var yearProperty = model.GetType().GetProperty(yearId); + var dayValue = dayProperty?.GetValue(model)?.ToString(); + var monthValue = monthProperty?.GetValue(model)?.ToString(); + var yearValue = yearProperty?.GetValue(model)?.ToString(); + + var viewModel = new DateInputViewModel( + name, + label, + dayId, + monthId, + yearId, + dayValue, + monthValue, + yearValue, + validationResult, + string.IsNullOrEmpty(hintText) ? null : hintText + ); + return View(viewModel); + } + } +} diff --git a/DigitalLearningSolutions.Web/ViewModels/Common/ViewComponents/DateInputViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/Common/ViewComponents/DateInputViewModel.cs new file mode 100644 index 0000000000..18e9a3ac01 --- /dev/null +++ b/DigitalLearningSolutions.Web/ViewModels/Common/ViewComponents/DateInputViewModel.cs @@ -0,0 +1,51 @@ +namespace DigitalLearningSolutions.Web.ViewModels.Common.ViewComponents +{ + using DigitalLearningSolutions.Web.ControllerHelpers; + + public class DateInputViewModel + { + public readonly bool HasDayError; + public readonly bool HasMonthError; + public readonly bool HasYearError; + + public DateInputViewModel( + string name, + string label, + string? dayId, + string? monthId, + string? yearId, + string? dayValue, + string? monthValue, + string? yearValue, + DateValidator.ValidationResult? validationResult, + string? hintText = null + ) + { + Name = name; + Label = label; + DayId = dayId ?? "Day"; + MonthId = monthId ?? "Month"; + YearId = yearId ?? "Year"; + DayValue = dayValue; + MonthValue = monthValue; + YearValue = yearValue; + HintText = hintText; + ErrorMessage = validationResult?.ErrorMessage; + HasDayError = validationResult is { DayValid: false }; + HasMonthError = validationResult is { MonthValid: false }; + HasYearError = validationResult is { YearValid: false }; + } + + public string Name { get; set; } + public string Label { get; set; } + public string DayId { get; set; } + public string MonthId { get; set; } + public string YearId { get; set; } + public string? DayValue { get; set; } + public string? MonthValue { get; set; } + public string? YearValue { get; set; } + public string? HintText { get; set; } + public bool HasError => HasDayError || HasMonthError || HasYearError; + public string? ErrorMessage { get; set; } + } +} diff --git a/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/WelcomeEmail.cshtml b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/WelcomeEmail.cshtml index 26417200b6..ce5a80cb4e 100644 --- a/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/WelcomeEmail.cshtml +++ b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/WelcomeEmail.cshtml @@ -2,13 +2,10 @@ @model WelcomeEmailViewModel @{ - var errorHasOccurred = Model.DateValidationResult is { DateValid: false }; - ViewData["Title"] = errorHasOccurred ? "Error: Register Delegate - Welcome Email" : "Register Delegate - Welcome Email"; - var exampleDate = DateTime.Today; - var emailDateCss = "nhsuk-checkboxes__conditional" + (Model.ShouldSendEmail ? "" : " nhsuk-checkboxes__conditional--hidden"); - var dayErrorCss = Model.DateValidationResult is { DayValid: false } ? "nhsuk-input--error" : ""; - var monthErrorCss = Model.DateValidationResult is { MonthValid: false } ? "nhsuk-input--error" : ""; - var yearErrorCss = Model.DateValidationResult is { YearValid: false } ? "nhsuk-input--error" : ""; + var errorHasOccurred = Model.DateValidationResult is { DateValid: false }; + ViewData["Title"] = errorHasOccurred ? "Error: Register Delegate - Welcome Email" : "Register Delegate - Welcome Email"; + var exampleDate = DateTime.Today; + var emailDateCss = "nhsuk-checkboxes__conditional" + (Model.ShouldSendEmail ? "" : " nhsuk-checkboxes__conditional--hidden"); } @section NavMenuItems { @@ -44,53 +41,14 @@
-
- - Deliver email on or after: - -
- For example, @exampleDate.Day @exampleDate.Month @exampleDate.Year -
- - @if (errorHasOccurred) { - - Error: @Model.DateValidationResult!.ErrorMessage - - } - -
-
-
- - -
-
-
-
- - -
-
-
-
- - -
-
-
-
+
diff --git a/DigitalLearningSolutions.Web/Views/Shared/Components/DateInput/Default.cshtml b/DigitalLearningSolutions.Web/Views/Shared/Components/DateInput/Default.cshtml new file mode 100644 index 0000000000..28aa54de38 --- /dev/null +++ b/DigitalLearningSolutions.Web/Views/Shared/Components/DateInput/Default.cshtml @@ -0,0 +1,58 @@ +@using DigitalLearningSolutions.Web.ViewModels.Common.ViewComponents +@model DateInputViewModel + +@{ + var dayErrorCss = Model.HasDayError ? "nhsuk-input--error" : ""; + var monthErrorCss = Model.HasMonthError ? "nhsuk-input--error" : ""; + var yearErrorCss = Model.HasYearError ? "nhsuk-input--error" : ""; +} + +
+ + @Model.Label + + @if (Model.HintText != null) { +
+ @Model.HintText +
+ } + + @if (Model.HasError) { + + Error: @Model.ErrorMessage + + } + +
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
From 052b2bdd895c31b3d6b1e84c8ae511b95ac5e5df Mon Sep 17 00:00:00 2001 From: Ibrahim Munir-Zubair Date: Thu, 8 Jul 2021 17:02:32 +0100 Subject: [PATCH 11/19] HEEDLS-546 Add appropriate css classes to display error border --- .../WelcomeEmail.cshtml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/WelcomeEmail.cshtml b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/WelcomeEmail.cshtml index ce5a80cb4e..01aa7bdc37 100644 --- a/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/WelcomeEmail.cshtml +++ b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/WelcomeEmail.cshtml @@ -6,6 +6,7 @@ ViewData["Title"] = errorHasOccurred ? "Error: Register Delegate - Welcome Email" : "Register Delegate - Welcome Email"; var exampleDate = DateTime.Today; var emailDateCss = "nhsuk-checkboxes__conditional" + (Model.ShouldSendEmail ? "" : " nhsuk-checkboxes__conditional--hidden"); + var errorCss = errorHasOccurred ? "nhsuk-form-group--error nhsuk-u-padding-left-5" : ""; } @section NavMenuItems { @@ -40,15 +41,14 @@
-
- +
+
From 1873ffb82f50a05ee9fd50bc24f741a41bd6a665 Mon Sep 17 00:00:00 2001 From: Ibrahim Munir-Zubair Date: Thu, 8 Jul 2021 17:10:13 +0100 Subject: [PATCH 12/19] HEEDLS-546 Fix spacing on PersonalInformation page --- .../Views/RegisterDelegateByCentre/PersonalInformation.cshtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/PersonalInformation.cshtml b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/PersonalInformation.cshtml index 6bd762572e..3ac8bb9cb0 100644 --- a/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/PersonalInformation.cshtml +++ b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/PersonalInformation.cshtml @@ -16,7 +16,7 @@
-
+ @if (errorHasOccurred) { } From 8b4250c24aefd9eca14829310d1782b25078192e Mon Sep 17 00:00:00 2001 From: Ibrahim Munir-Zubair Date: Tue, 13 Jul 2021 18:23:49 +0100 Subject: [PATCH 13/19] HEEDLS-546 Fix bug where Alias was not set correctly; write DelegateRegistrationByCentreData tests --- .../DelegateRegistrationByCentreDataTests.cs | 77 +++++++++++++++++++ .../DelegateRegistrationByCentreData.cs | 15 +++- .../Models/RegistrationData.cs | 2 +- 3 files changed, 89 insertions(+), 5 deletions(-) create mode 100644 DigitalLearningSolutions.Web.Tests/Models/DelegateRegistrationByCentreDataTests.cs diff --git a/DigitalLearningSolutions.Web.Tests/Models/DelegateRegistrationByCentreDataTests.cs b/DigitalLearningSolutions.Web.Tests/Models/DelegateRegistrationByCentreDataTests.cs new file mode 100644 index 0000000000..7faa1b908d --- /dev/null +++ b/DigitalLearningSolutions.Web.Tests/Models/DelegateRegistrationByCentreDataTests.cs @@ -0,0 +1,77 @@ +namespace DigitalLearningSolutions.Web.Tests.Models +{ + using System; + using DigitalLearningSolutions.Web.Models; + using DigitalLearningSolutions.Web.ViewModels.Register; + using DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre; + using FluentAssertions; + using NUnit.Framework; + + internal class DelegateRegistrationByCentreDataTests + { + private const string FirstName = "Test"; + private const string LastName = "User"; + private const string Email = "test@email.com"; + private const string Alias = "testuser"; + private const int CentreId = 5; + + [Test] + public void SetPersonalInformation_sets_data_correctly() + { + // Given + var model = new PersonalInformationViewModel + { + FirstName = FirstName, + LastName = LastName, + Centre = CentreId, + Email = Email, + Alias = Alias + }; + var data = new DelegateRegistrationByCentreData(); + + // When + data.SetPersonalInformation(model); + + // Then + data.FirstName.Should().Be(FirstName); + data.LastName.Should().Be(LastName); + data.Email.Should().Be(Email); + data.Centre.Should().Be(CentreId); + data.Alias.Should().Be(Alias); + } + + [Test] + public void SetWelcomeEmail_with_ShouldSendEmail_false_sets_data_correctly() + { + // Given + var model = new WelcomeEmailViewModel { ShouldSendEmail = false, Day = 7, Month = 7, Year = 2200 }; + var data = new DelegateRegistrationByCentreData(); + + // When + data.SetWelcomeEmail(model); + + // Then + data.ShouldSendEmail.Should().BeFalse(); + data.WelcomeEmailDate.Should().BeNull(); + } + + [Test] + public void SetWelcomeEmail_with_ShouldSendEmail_true_sets_data_correctly() + { + // Given + var date = new DateTime(2200, 7, 7); + var model = new WelcomeEmailViewModel + { ShouldSendEmail = true, Day = date.Day, Month = date.Month, Year = date.Year }; + var data = new DelegateRegistrationByCentreData(); + + // When + data.SetWelcomeEmail(model); + + // Then + data.ShouldSendEmail.Should().BeTrue(); + data.WelcomeEmailDate.Should().Be(date); + data.IsPasswordSet.Should().BeFalse(); + data.PasswordHash.Should().BeNull(); + } + } +} diff --git a/DigitalLearningSolutions.Web/Models/DelegateRegistrationByCentreData.cs b/DigitalLearningSolutions.Web/Models/DelegateRegistrationByCentreData.cs index c7725a4a87..14109c8fbc 100644 --- a/DigitalLearningSolutions.Web/Models/DelegateRegistrationByCentreData.cs +++ b/DigitalLearningSolutions.Web/Models/DelegateRegistrationByCentreData.cs @@ -1,6 +1,7 @@ namespace DigitalLearningSolutions.Web.Models { using System; + using DigitalLearningSolutions.Web.ViewModels.Register; using DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre; public class DelegateRegistrationByCentreData : DelegateRegistrationData @@ -11,6 +12,16 @@ public DelegateRegistrationByCentreData(int centreId) : base(centreId) { } public DateTime? WelcomeEmailDate { get; set; } + public bool ShouldSendEmail => WelcomeEmailDate.HasValue; + + public bool IsPasswordSet => PasswordHash != null; + + public override void SetPersonalInformation(PersonalInformationViewModel model) + { + base.SetPersonalInformation(model); + Alias = model.Alias; + } + public void SetWelcomeEmail(WelcomeEmailViewModel model) { if (model.ShouldSendEmail) @@ -23,9 +34,5 @@ public void SetWelcomeEmail(WelcomeEmailViewModel model) WelcomeEmailDate = null; } } - - public bool ShouldSendEmail => WelcomeEmailDate.HasValue; - - public bool IsPasswordSet => PasswordHash != null; } } diff --git a/DigitalLearningSolutions.Web/Models/RegistrationData.cs b/DigitalLearningSolutions.Web/Models/RegistrationData.cs index 4359d8da4f..db6d36a18b 100644 --- a/DigitalLearningSolutions.Web/Models/RegistrationData.cs +++ b/DigitalLearningSolutions.Web/Models/RegistrationData.cs @@ -27,7 +27,7 @@ public RegistrationData(int? centreId) public string? PasswordHash { get; set; } - public void SetPersonalInformation(PersonalInformationViewModel model) + public virtual void SetPersonalInformation(PersonalInformationViewModel model) { Centre = model.Centre; Email = model.Email; From 884a8efcee266e30ac7e29f691e14aff24b3b5f0 Mon Sep 17 00:00:00 2001 From: Ibrahim Munir-Zubair Date: Wed, 14 Jul 2021 14:17:38 +0100 Subject: [PATCH 14/19] HEEDLS-546 Move RDbyC viewmodels into Register/RDbyC folder --- .../Models/DelegateRegistrationByCentreDataTests.cs | 2 +- .../Register/RegisterDelegateByCentreController.cs | 6 +++--- .../Models/DelegateRegistrationByCentreData.cs | 2 +- .../RegisterDelegateByCentre/PasswordViewModel.cs | 2 +- .../RegisterDelegateByCentre/SummaryViewModel.cs | 2 +- .../RegisterDelegateByCentre/WelcomeEmailViewModel.cs | 4 ++-- .../Views/RegisterDelegateByCentre/Password.cshtml | 7 ++++--- .../Views/RegisterDelegateByCentre/Summary.cshtml | 4 ++-- .../RegisterDelegateByCentre/WelcomeEmail.cshtml | 11 +++++++++-- 9 files changed, 24 insertions(+), 16 deletions(-) rename DigitalLearningSolutions.Web/ViewModels/{ => Register}/RegisterDelegateByCentre/PasswordViewModel.cs (83%) rename DigitalLearningSolutions.Web/ViewModels/{ => Register}/RegisterDelegateByCentre/SummaryViewModel.cs (92%) rename DigitalLearningSolutions.Web/ViewModels/{ => Register}/RegisterDelegateByCentre/WelcomeEmailViewModel.cs (83%) diff --git a/DigitalLearningSolutions.Web.Tests/Models/DelegateRegistrationByCentreDataTests.cs b/DigitalLearningSolutions.Web.Tests/Models/DelegateRegistrationByCentreDataTests.cs index 7faa1b908d..2d5c772b58 100644 --- a/DigitalLearningSolutions.Web.Tests/Models/DelegateRegistrationByCentreDataTests.cs +++ b/DigitalLearningSolutions.Web.Tests/Models/DelegateRegistrationByCentreDataTests.cs @@ -3,7 +3,7 @@ using System; using DigitalLearningSolutions.Web.Models; using DigitalLearningSolutions.Web.ViewModels.Register; - using DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre; + using DigitalLearningSolutions.Web.ViewModels.Register.RegisterDelegateByCentre; using FluentAssertions; using NUnit.Framework; diff --git a/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs b/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs index 2cf745a4fc..4728ffa9d2 100644 --- a/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs +++ b/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs @@ -12,13 +12,13 @@ namespace DigitalLearningSolutions.Web.Controllers.Register using DigitalLearningSolutions.Web.ServiceFilter; using DigitalLearningSolutions.Web.ViewModels.Common; using DigitalLearningSolutions.Web.ViewModels.Register; - using DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre; + using DigitalLearningSolutions.Web.ViewModels.Register.RegisterDelegateByCentre; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.FeatureManagement.Mvc; - using PasswordViewModel = DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre.PasswordViewModel; - using SummaryViewModel = DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre.SummaryViewModel; + using PasswordViewModel = DigitalLearningSolutions.Web.ViewModels.Register.RegisterDelegateByCentre.PasswordViewModel; + using SummaryViewModel = DigitalLearningSolutions.Web.ViewModels.Register.RegisterDelegateByCentre.SummaryViewModel; [FeatureGate(FeatureFlags.RefactoredTrackingSystem)] [Authorize(Policy = CustomPolicies.UserCentreAdmin)] diff --git a/DigitalLearningSolutions.Web/Models/DelegateRegistrationByCentreData.cs b/DigitalLearningSolutions.Web/Models/DelegateRegistrationByCentreData.cs index 14109c8fbc..a228a81007 100644 --- a/DigitalLearningSolutions.Web/Models/DelegateRegistrationByCentreData.cs +++ b/DigitalLearningSolutions.Web/Models/DelegateRegistrationByCentreData.cs @@ -2,7 +2,7 @@ { using System; using DigitalLearningSolutions.Web.ViewModels.Register; - using DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre; + using DigitalLearningSolutions.Web.ViewModels.Register.RegisterDelegateByCentre; public class DelegateRegistrationByCentreData : DelegateRegistrationData { diff --git a/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/PasswordViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/Register/RegisterDelegateByCentre/PasswordViewModel.cs similarity index 83% rename from DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/PasswordViewModel.cs rename to DigitalLearningSolutions.Web/ViewModels/Register/RegisterDelegateByCentre/PasswordViewModel.cs index dc6cf6c57e..8b6ea93ecd 100644 --- a/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/PasswordViewModel.cs +++ b/DigitalLearningSolutions.Web/ViewModels/Register/RegisterDelegateByCentre/PasswordViewModel.cs @@ -1,4 +1,4 @@ -namespace DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre +namespace DigitalLearningSolutions.Web.ViewModels.Register.RegisterDelegateByCentre { using System.ComponentModel.DataAnnotations; diff --git a/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/SummaryViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/Register/RegisterDelegateByCentre/SummaryViewModel.cs similarity index 92% rename from DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/SummaryViewModel.cs rename to DigitalLearningSolutions.Web/ViewModels/Register/RegisterDelegateByCentre/SummaryViewModel.cs index bbe0d702c6..07462b0dda 100644 --- a/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/SummaryViewModel.cs +++ b/DigitalLearningSolutions.Web/ViewModels/Register/RegisterDelegateByCentre/SummaryViewModel.cs @@ -1,4 +1,4 @@ -namespace DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre +namespace DigitalLearningSolutions.Web.ViewModels.Register.RegisterDelegateByCentre { using System.Collections.Generic; using System.Globalization; diff --git a/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/WelcomeEmailViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/Register/RegisterDelegateByCentre/WelcomeEmailViewModel.cs similarity index 83% rename from DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/WelcomeEmailViewModel.cs rename to DigitalLearningSolutions.Web/ViewModels/Register/RegisterDelegateByCentre/WelcomeEmailViewModel.cs index 60eaeba571..6375ba9e99 100644 --- a/DigitalLearningSolutions.Web/ViewModels/RegisterDelegateByCentre/WelcomeEmailViewModel.cs +++ b/DigitalLearningSolutions.Web/ViewModels/Register/RegisterDelegateByCentre/WelcomeEmailViewModel.cs @@ -1,11 +1,11 @@ -namespace DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre +namespace DigitalLearningSolutions.Web.ViewModels.Register.RegisterDelegateByCentre { using DigitalLearningSolutions.Web.ControllerHelpers; using DigitalLearningSolutions.Web.Models; public class WelcomeEmailViewModel { - public WelcomeEmailViewModel() {} + public WelcomeEmailViewModel() { } public WelcomeEmailViewModel(DelegateRegistrationByCentreData data) { diff --git a/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Password.cshtml b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Password.cshtml index 14356f4f58..56d28fa153 100644 --- a/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Password.cshtml +++ b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Password.cshtml @@ -1,5 +1,5 @@ @inject IConfiguration Configuration -@using DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre +@using DigitalLearningSolutions.Web.ViewModels.Register.RegisterDelegateByCentre @using Microsoft.Extensions.Configuration @model PasswordViewModel @@ -23,8 +23,9 @@

Set password

-

You chose not to send a welcome email to the delegate.

-

Would you like to set a password instead?

+

+ You chose not to send a welcome email to the delegate. Would you like to set a password instead? +

diff --git a/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Summary.cshtml b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Summary.cshtml index 4934d9d3e9..e0b536e1f2 100644 --- a/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Summary.cshtml +++ b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Summary.cshtml @@ -1,5 +1,5 @@ @inject IConfiguration Configuration -@using DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre +@using DigitalLearningSolutions.Web.ViewModels.Register.RegisterDelegateByCentre @using Microsoft.Extensions.Configuration @model SummaryViewModel @{ @@ -17,7 +17,7 @@
-

Summary

+

Summary

diff --git a/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/WelcomeEmail.cshtml b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/WelcomeEmail.cshtml index 01aa7bdc37..c987033b57 100644 --- a/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/WelcomeEmail.cshtml +++ b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/WelcomeEmail.cshtml @@ -1,4 +1,4 @@ -@using DigitalLearningSolutions.Web.ViewModels.RegisterDelegateByCentre +@using DigitalLearningSolutions.Web.ViewModels.Register.RegisterDelegateByCentre @model WelcomeEmailViewModel @{ @@ -35,7 +35,14 @@
- + From 8a8450b93b4a22e07870a23c99826f92d9e5e8bf Mon Sep 17 00:00:00 2001 From: Ibrahim Munir-Zubair Date: Wed, 14 Jul 2021 14:50:39 +0100 Subject: [PATCH 15/19] HEEDLS-546 Tidy up WelcomeEmailDate string formatting; use derived fields as appropriate --- .../RegisterDelegateByCentre/SummaryViewModel.cs | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/DigitalLearningSolutions.Web/ViewModels/Register/RegisterDelegateByCentre/SummaryViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/Register/RegisterDelegateByCentre/SummaryViewModel.cs index 07462b0dda..902cabff2e 100644 --- a/DigitalLearningSolutions.Web/ViewModels/Register/RegisterDelegateByCentre/SummaryViewModel.cs +++ b/DigitalLearningSolutions.Web/ViewModels/Register/RegisterDelegateByCentre/SummaryViewModel.cs @@ -1,7 +1,6 @@ namespace DigitalLearningSolutions.Web.ViewModels.Register.RegisterDelegateByCentre { using System.Collections.Generic; - using System.Globalization; using DigitalLearningSolutions.Web.Models; using DigitalLearningSolutions.Web.ViewModels.Common; @@ -16,15 +15,9 @@ public SummaryViewModel(DelegateRegistrationByCentreData data) Email = data.Email; Alias = data.Alias; IsPasswordSet = data.IsPasswordSet; - PreviousAction = "Password"; - ShouldSendEmail = data.ShouldSendEmail; - if (ShouldSendEmail) + if (data.ShouldSendEmail) { - CultureInfo originalCulture = CultureInfo.CurrentCulture; - CultureInfo.CurrentCulture = new CultureInfo("en-GB"); - WelcomeEmailDate = data.WelcomeEmailDate!.Value.ToShortDateString(); - CultureInfo.CurrentCulture = originalCulture; - PreviousAction = "WelcomeEmail"; + WelcomeEmailDate = data.WelcomeEmailDate!.Value.ToString("dd/MM/yyyy"); } } @@ -33,10 +26,10 @@ public SummaryViewModel(DelegateRegistrationByCentreData data) public string? Email { get; set; } public string? Alias { get; set; } public bool IsPasswordSet { get; set; } - public bool ShouldSendEmail { get; set; } public string? WelcomeEmailDate { get; set; } + public bool ShouldSendEmail => WelcomeEmailDate != null; public string? JobGroup { get; set; } public IEnumerable CustomFields { get; set; } = new List(); - public string PreviousAction { get; set; } + public string PreviousAction => ShouldSendEmail ? "WelcomeEmail" : "Password"; } } From f1c87ecee20ac0a0724ca3c30d3c4f230b46dc83 Mon Sep 17 00:00:00 2001 From: Ibrahim Munir-Zubair Date: Wed, 14 Jul 2021 15:00:34 +0100 Subject: [PATCH 16/19] HEEDLS-546 Rename PasswordVM to ConfirmPasswordVM; move PasswordVM from RDbyC to Common; update references --- .../Controllers/ResetPasswordControllerTests.cs | 16 ++++++++-------- .../Register/RegisterAdminController.cs | 4 ++-- .../Controllers/Register/RegisterController.cs | 4 ++-- .../RegisterDelegateByCentreController.cs | 1 - .../Controllers/ResetPasswordController.cs | 4 ++-- .../ConfirmPasswordViewModel.cs} | 10 ++++++++-- .../ViewModels/Common/PasswordViewModel.cs | 6 ------ .../MyAccount/ChangePasswordViewModel.cs | 2 +- .../Views/Register/Password.cshtml | 2 +- .../Views/RegisterAdmin/Password.cshtml | 2 +- .../RegisterDelegateByCentre/Password.cshtml | 2 +- .../Views/ResetPassword/Index.cshtml | 2 +- 12 files changed, 27 insertions(+), 28 deletions(-) rename DigitalLearningSolutions.Web/ViewModels/{Register/RegisterDelegateByCentre/PasswordViewModel.cs => Common/ConfirmPasswordViewModel.cs} (54%) diff --git a/DigitalLearningSolutions.Web.Tests/Controllers/ResetPasswordControllerTests.cs b/DigitalLearningSolutions.Web.Tests/Controllers/ResetPasswordControllerTests.cs index 9e38ced5d4..995f5e45e7 100644 --- a/DigitalLearningSolutions.Web.Tests/Controllers/ResetPasswordControllerTests.cs +++ b/DigitalLearningSolutions.Web.Tests/Controllers/ResetPasswordControllerTests.cs @@ -117,7 +117,7 @@ public async Task Post_to_index_should_invalidate_reset_hash_if_model_and_hash_v // When await unauthenticatedController.Index( - new PasswordViewModel { Password = "testPass-9", ConfirmPassword = "testPass-9" }); + new ConfirmPasswordViewModel { Password = "testPass-9", ConfirmPassword = "testPass-9" }); // Then A.CallTo(() => passwordResetService.InvalidateResetPasswordForEmailAsync("email")) @@ -133,7 +133,7 @@ public async Task Post_to_index_should_update_password_if_model_and_hash_valid() // When await unauthenticatedController.Index( - new PasswordViewModel { Password = "testPass-9", ConfirmPassword = "testPass-9" }); + new ConfirmPasswordViewModel { Password = "testPass-9", ConfirmPassword = "testPass-9" }); // Then A.CallTo(() => passwordService.ChangePasswordAsync("email", "testPass-9")) @@ -149,7 +149,7 @@ public async Task Post_to_index_should_return_success_page_if_model_and_hash_val // When var result = await unauthenticatedController.Index( - new PasswordViewModel { Password = "testPass-9", ConfirmPassword = "testPass-9" }); + new ConfirmPasswordViewModel { Password = "testPass-9", ConfirmPassword = "testPass-9" }); // Then result.Should().BeViewResult().WithViewName("Success"); @@ -165,7 +165,7 @@ public async Task Post_to_index_should_clear_temp_data_if_model_and_hash_valid() // When await unauthenticatedController.Index( - new PasswordViewModel { Password = "testPass-9", ConfirmPassword = "testPass-9" }); + new ConfirmPasswordViewModel { Password = "testPass-9", ConfirmPassword = "testPass-9" }); // Then unauthenticatedController.TempData.Peek().Should().BeNull(); @@ -182,7 +182,7 @@ public async Task Post_to_index_should_clear_temp_data_if_hash_invalid() // When await unauthenticatedController.Index( - new PasswordViewModel { Password = "testPass-9", ConfirmPassword = "testPass-9" }); + new ConfirmPasswordViewModel { Password = "testPass-9", ConfirmPassword = "testPass-9" }); // Then unauthenticatedController.TempData.Peek().Should().BeNull(); @@ -199,7 +199,7 @@ public async Task Post_to_index_should_preserve_temp_data_if_model_invalid() // When await unauthenticatedController.Index( - new PasswordViewModel { Password = "testPass-9", ConfirmPassword = "testPass-9" }); + new ConfirmPasswordViewModel { Password = "testPass-9", ConfirmPassword = "testPass-9" }); // Then unauthenticatedController.TempData.Peek().Should() @@ -216,7 +216,7 @@ public async Task Post_to_index_should_return_form_if_model_state_invalid() // When var result = await unauthenticatedController.Index( - new PasswordViewModel { Password = "testPass-9", ConfirmPassword = "testPass-9" }); + new ConfirmPasswordViewModel { Password = "testPass-9", ConfirmPassword = "testPass-9" }); // Then result.Should().BeViewResult().WithDefaultViewName(); @@ -231,7 +231,7 @@ public async Task Post_to_index_should_redirect_to_Error_if_reset_password_inval // When var result = await unauthenticatedController.Index( - new PasswordViewModel { Password = "testPass-9", ConfirmPassword = "testPass-9" }); + new ConfirmPasswordViewModel { Password = "testPass-9", ConfirmPassword = "testPass-9" }); // Then result.Should().BeRedirectToActionResult().WithActionName("Error").WithControllerName(null); diff --git a/DigitalLearningSolutions.Web/Controllers/Register/RegisterAdminController.cs b/DigitalLearningSolutions.Web/Controllers/Register/RegisterAdminController.cs index 2c407e42f2..c5e580ac01 100644 --- a/DigitalLearningSolutions.Web/Controllers/Register/RegisterAdminController.cs +++ b/DigitalLearningSolutions.Web/Controllers/Register/RegisterAdminController.cs @@ -122,12 +122,12 @@ public IActionResult LearnerInformation(LearnerInformationViewModel model) [HttpGet] public IActionResult Password() { - return View(new PasswordViewModel()); + return View(new ConfirmPasswordViewModel()); } [ServiceFilter(typeof(RedirectEmptySessionData))] [HttpPost] - public IActionResult Password(PasswordViewModel model) + public IActionResult Password(ConfirmPasswordViewModel model) { if (!ModelState.IsValid) { diff --git a/DigitalLearningSolutions.Web/Controllers/Register/RegisterController.cs b/DigitalLearningSolutions.Web/Controllers/Register/RegisterController.cs index 612830b3c6..fccf5adf6e 100644 --- a/DigitalLearningSolutions.Web/Controllers/Register/RegisterController.cs +++ b/DigitalLearningSolutions.Web/Controllers/Register/RegisterController.cs @@ -160,12 +160,12 @@ public IActionResult LearnerInformation(LearnerInformationViewModel model) [HttpGet] public IActionResult Password() { - return View(new PasswordViewModel()); + return View(new ConfirmPasswordViewModel()); } [ServiceFilter(typeof(RedirectEmptySessionData))] [HttpPost] - public IActionResult Password(PasswordViewModel model) + public IActionResult Password(ConfirmPasswordViewModel model) { if (!ModelState.IsValid) { diff --git a/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs b/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs index 4728ffa9d2..53b983ce6d 100644 --- a/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs +++ b/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs @@ -17,7 +17,6 @@ namespace DigitalLearningSolutions.Web.Controllers.Register using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.FeatureManagement.Mvc; - using PasswordViewModel = DigitalLearningSolutions.Web.ViewModels.Register.RegisterDelegateByCentre.PasswordViewModel; using SummaryViewModel = DigitalLearningSolutions.Web.ViewModels.Register.RegisterDelegateByCentre.SummaryViewModel; [FeatureGate(FeatureFlags.RefactoredTrackingSystem)] diff --git a/DigitalLearningSolutions.Web/Controllers/ResetPasswordController.cs b/DigitalLearningSolutions.Web/Controllers/ResetPasswordController.cs index a851a1bdaf..d7dc3a6acb 100644 --- a/DigitalLearningSolutions.Web/Controllers/ResetPasswordController.cs +++ b/DigitalLearningSolutions.Web/Controllers/ResetPasswordController.cs @@ -41,12 +41,12 @@ public async Task Index(string email, string code) return RedirectToAction("Error"); } - return View(new PasswordViewModel()); + return View(new ConfirmPasswordViewModel()); } [HttpPost] [ServiceFilter(typeof(RedirectEmptySessionData))] - public async Task Index(PasswordViewModel viewModel) + public async Task Index(ConfirmPasswordViewModel viewModel) { var resetPasswordData = TempData.Peek()!; diff --git a/DigitalLearningSolutions.Web/ViewModels/Register/RegisterDelegateByCentre/PasswordViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/Common/ConfirmPasswordViewModel.cs similarity index 54% rename from DigitalLearningSolutions.Web/ViewModels/Register/RegisterDelegateByCentre/PasswordViewModel.cs rename to DigitalLearningSolutions.Web/ViewModels/Common/ConfirmPasswordViewModel.cs index 8b6ea93ecd..14d0953fd1 100644 --- a/DigitalLearningSolutions.Web/ViewModels/Register/RegisterDelegateByCentre/PasswordViewModel.cs +++ b/DigitalLearningSolutions.Web/ViewModels/Common/ConfirmPasswordViewModel.cs @@ -1,9 +1,10 @@ -namespace DigitalLearningSolutions.Web.ViewModels.Register.RegisterDelegateByCentre +namespace DigitalLearningSolutions.Web.ViewModels.Common { using System.ComponentModel.DataAnnotations; - public class PasswordViewModel + public class ConfirmPasswordViewModel { + [Required(ErrorMessage = "Enter a password")] [MinLength(8, ErrorMessage = "Password must be 8 characters or more")] [MaxLength(100, ErrorMessage = "Password must be 100 characters or fewer")] [RegularExpression( @@ -12,5 +13,10 @@ public class PasswordViewModel )] [DataType(DataType.Password)] public string? Password { get; set; } + + [Required(ErrorMessage = "Repeat your password to confirm")] + [DataType(DataType.Password)] + [Compare("Password", ErrorMessage = "Password and re-typed password must match")] + public string? ConfirmPassword { get; set; } } } diff --git a/DigitalLearningSolutions.Web/ViewModels/Common/PasswordViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/Common/PasswordViewModel.cs index 60829b7e0d..7a92a54634 100644 --- a/DigitalLearningSolutions.Web/ViewModels/Common/PasswordViewModel.cs +++ b/DigitalLearningSolutions.Web/ViewModels/Common/PasswordViewModel.cs @@ -4,7 +4,6 @@ public class PasswordViewModel { - [Required(ErrorMessage = "Enter a password")] [MinLength(8, ErrorMessage = "Password must be 8 characters or more")] [MaxLength(100, ErrorMessage = "Password must be 100 characters or fewer")] [RegularExpression( @@ -13,10 +12,5 @@ public class PasswordViewModel )] [DataType(DataType.Password)] public string? Password { get; set; } - - [Required(ErrorMessage = "Repeat your password to confirm")] - [DataType(DataType.Password)] - [Compare("Password", ErrorMessage = "Password and re-typed password must match")] - public string? ConfirmPassword { get; set; } } } diff --git a/DigitalLearningSolutions.Web/ViewModels/MyAccount/ChangePasswordViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/MyAccount/ChangePasswordViewModel.cs index 1cab9a96f5..8ebb75b64c 100644 --- a/DigitalLearningSolutions.Web/ViewModels/MyAccount/ChangePasswordViewModel.cs +++ b/DigitalLearningSolutions.Web/ViewModels/MyAccount/ChangePasswordViewModel.cs @@ -3,7 +3,7 @@ using System.ComponentModel.DataAnnotations; using DigitalLearningSolutions.Web.ViewModels.Common; - public class ChangePasswordViewModel : PasswordViewModel + public class ChangePasswordViewModel : ConfirmPasswordViewModel { [Required(ErrorMessage = "Enter your password")] [DataType(DataType.Password)] diff --git a/DigitalLearningSolutions.Web/Views/Register/Password.cshtml b/DigitalLearningSolutions.Web/Views/Register/Password.cshtml index 293a4a4f34..524bb3d2fa 100644 --- a/DigitalLearningSolutions.Web/Views/Register/Password.cshtml +++ b/DigitalLearningSolutions.Web/Views/Register/Password.cshtml @@ -1,5 +1,5 @@ @using DigitalLearningSolutions.Web.ViewModels.Common -@model PasswordViewModel +@model ConfirmPasswordViewModel @{ var errorHasOccurred = !ViewData.ModelState.IsValid; diff --git a/DigitalLearningSolutions.Web/Views/RegisterAdmin/Password.cshtml b/DigitalLearningSolutions.Web/Views/RegisterAdmin/Password.cshtml index b71d8c1d14..707973a0ad 100644 --- a/DigitalLearningSolutions.Web/Views/RegisterAdmin/Password.cshtml +++ b/DigitalLearningSolutions.Web/Views/RegisterAdmin/Password.cshtml @@ -1,5 +1,5 @@ @using DigitalLearningSolutions.Web.ViewModels.Common -@model PasswordViewModel +@model ConfirmPasswordViewModel @{ var errorHasOccurred = !ViewData.ModelState.IsValid; diff --git a/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Password.cshtml b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Password.cshtml index 56d28fa153..e7de259076 100644 --- a/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Password.cshtml +++ b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/Password.cshtml @@ -1,5 +1,5 @@ @inject IConfiguration Configuration -@using DigitalLearningSolutions.Web.ViewModels.Register.RegisterDelegateByCentre +@using DigitalLearningSolutions.Web.ViewModels.Common @using Microsoft.Extensions.Configuration @model PasswordViewModel diff --git a/DigitalLearningSolutions.Web/Views/ResetPassword/Index.cshtml b/DigitalLearningSolutions.Web/Views/ResetPassword/Index.cshtml index 97367c8969..4f85d55a16 100644 --- a/DigitalLearningSolutions.Web/Views/ResetPassword/Index.cshtml +++ b/DigitalLearningSolutions.Web/Views/ResetPassword/Index.cshtml @@ -1,5 +1,5 @@ @using DigitalLearningSolutions.Web.ViewModels.Common -@model PasswordViewModel +@model ConfirmPasswordViewModel @{ var errorHasOccurred = !ViewData.ModelState.IsValid; From 2591d05018f18569c7a426f9bd2116810c24fb29 Mon Sep 17 00:00:00 2001 From: Ibrahim Munir-Zubair Date: Wed, 14 Jul 2021 15:47:36 +0100 Subject: [PATCH 17/19] HEEDLS-546 Review markups: minor formatting/refactoring --- .../Register/RegisterDelegateByCentreController.cs | 12 +++++------- .../Models/DelegateRegistrationByCentreData.cs | 3 +-- .../WelcomeEmailViewModel.cs | 10 ++++++++++ 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs b/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs index 53b983ce6d..0ee764206e 100644 --- a/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs +++ b/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs @@ -149,7 +149,9 @@ public IActionResult WelcomeEmail(WelcomeEmailViewModel model) { var data = TempData.Peek()!; - if (!ValidateWelcomeEmail(model)) + model.CleanDate(); + SetWelcomeEmailValidationResult(model); + if (model.DateValidationResult is { DateValid: false }) { return View(model); } @@ -256,14 +258,11 @@ private void ValidatePersonalInformation(PersonalInformationViewModel model) } } - private bool ValidateWelcomeEmail(WelcomeEmailViewModel model) + private void SetWelcomeEmailValidationResult(WelcomeEmailViewModel model) { if (!model.ShouldSendEmail) { - model.Day = null; - model.Month = null; - model.Year = null; - return true; + return; } var validationResult = DateValidator.ValidateRequiredDate( @@ -273,7 +272,6 @@ private bool ValidateWelcomeEmail(WelcomeEmailViewModel model) "Email delivery date" ); model.DateValidationResult = validationResult; - return validationResult.DateValid; } private IEnumerable GetEditCustomFieldsFromModel( diff --git a/DigitalLearningSolutions.Web/Models/DelegateRegistrationByCentreData.cs b/DigitalLearningSolutions.Web/Models/DelegateRegistrationByCentreData.cs index a228a81007..e0085c468c 100644 --- a/DigitalLearningSolutions.Web/Models/DelegateRegistrationByCentreData.cs +++ b/DigitalLearningSolutions.Web/Models/DelegateRegistrationByCentreData.cs @@ -8,12 +8,11 @@ public class DelegateRegistrationByCentreData : DelegateRegistrationData { public DelegateRegistrationByCentreData() { } public DelegateRegistrationByCentreData(int centreId) : base(centreId) { } - public string? Alias { get; set; } + public string? Alias { get; set; } public DateTime? WelcomeEmailDate { get; set; } public bool ShouldSendEmail => WelcomeEmailDate.HasValue; - public bool IsPasswordSet => PasswordHash != null; public override void SetPersonalInformation(PersonalInformationViewModel model) diff --git a/DigitalLearningSolutions.Web/ViewModels/Register/RegisterDelegateByCentre/WelcomeEmailViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/Register/RegisterDelegateByCentre/WelcomeEmailViewModel.cs index 6375ba9e99..1c72c8acdf 100644 --- a/DigitalLearningSolutions.Web/ViewModels/Register/RegisterDelegateByCentre/WelcomeEmailViewModel.cs +++ b/DigitalLearningSolutions.Web/ViewModels/Register/RegisterDelegateByCentre/WelcomeEmailViewModel.cs @@ -23,5 +23,15 @@ public WelcomeEmailViewModel(DelegateRegistrationByCentreData data) public int? Year { get; set; } public bool ShouldSendEmail { get; set; } public DateValidator.ValidationResult? DateValidationResult { get; set; } + + public void CleanDate() + { + if (!ShouldSendEmail) + { + Day = null; + Month = null; + Year = null; + } + } } } From 917092ffeec9b1d2ed4fc64fa9b24f2f39b56060 Mon Sep 17 00:00:00 2001 From: Ibrahim Munir-Zubair Date: Wed, 14 Jul 2021 16:18:55 +0100 Subject: [PATCH 18/19] HEEDLS-546 Move ids into variables/consts; use Id param instead of Name --- .../ViewComponents/DateInputViewComponent.cs | 6 +++--- .../Common/ViewComponents/DateInputViewModel.cs | 6 +++--- .../Views/RegisterDelegateByCentre/WelcomeEmail.cshtml | 10 ++++++---- .../Views/Shared/Components/DateInput/Default.cshtml | 6 +++--- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/DigitalLearningSolutions.Web/ViewComponents/DateInputViewComponent.cs b/DigitalLearningSolutions.Web/ViewComponents/DateInputViewComponent.cs index 21e3b86a44..462492afdc 100644 --- a/DigitalLearningSolutions.Web/ViewComponents/DateInputViewComponent.cs +++ b/DigitalLearningSolutions.Web/ViewComponents/DateInputViewComponent.cs @@ -9,7 +9,7 @@ public class DateInputViewComponent : ViewComponent /// /// Render DateInput view component. /// - /// + /// /// /// /// @@ -18,7 +18,7 @@ public class DateInputViewComponent : ViewComponent /// Leave blank for no hint. /// public IViewComponentResult Invoke( - string name, + string id, string label, string dayId, string monthId, @@ -37,7 +37,7 @@ string hintText var yearValue = yearProperty?.GetValue(model)?.ToString(); var viewModel = new DateInputViewModel( - name, + id, label, dayId, monthId, diff --git a/DigitalLearningSolutions.Web/ViewModels/Common/ViewComponents/DateInputViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/Common/ViewComponents/DateInputViewModel.cs index 18e9a3ac01..2e0ccde744 100644 --- a/DigitalLearningSolutions.Web/ViewModels/Common/ViewComponents/DateInputViewModel.cs +++ b/DigitalLearningSolutions.Web/ViewModels/Common/ViewComponents/DateInputViewModel.cs @@ -9,7 +9,7 @@ public class DateInputViewModel public readonly bool HasYearError; public DateInputViewModel( - string name, + string id, string label, string? dayId, string? monthId, @@ -21,7 +21,7 @@ public DateInputViewModel( string? hintText = null ) { - Name = name; + Id = id; Label = label; DayId = dayId ?? "Day"; MonthId = monthId ?? "Month"; @@ -36,7 +36,7 @@ public DateInputViewModel( HasYearError = validationResult is { YearValid: false }; } - public string Name { get; set; } + public string Id { get; set; } public string Label { get; set; } public string DayId { get; set; } public string MonthId { get; set; } diff --git a/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/WelcomeEmail.cshtml b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/WelcomeEmail.cshtml index c987033b57..00e5cbaf2c 100644 --- a/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/WelcomeEmail.cshtml +++ b/DigitalLearningSolutions.Web/Views/RegisterDelegateByCentre/WelcomeEmail.cshtml @@ -4,6 +4,8 @@ @{ var errorHasOccurred = Model.DateValidationResult is { DateValid: false }; ViewData["Title"] = errorHasOccurred ? "Error: Register Delegate - Welcome Email" : "Register Delegate - Welcome Email"; + const string dateInputId = "welcome-email-date"; + const string conditionalDateInputId = "conditional-welcome-email-date"; var exampleDate = DateTime.Today; var emailDateCss = "nhsuk-checkboxes__conditional" + (Model.ShouldSendEmail ? "" : " nhsuk-checkboxes__conditional--hidden"); var errorCss = errorHasOccurred ? "nhsuk-form-group--error nhsuk-u-padding-left-5" : ""; @@ -23,7 +25,7 @@ @@ -41,15 +43,15 @@ asp-for="ShouldSendEmail" type="checkbox" value="true" - aria-controls="conditional-welcome-email-date" + aria-controls="@conditionalDateInputId" aria-expanded="@Model.ShouldSendEmail">
-
- + +
@Model.Label @if (Model.HintText != null) { -
+
@Model.HintText
} @@ -23,7 +23,7 @@ } -
+
From 48b7f07e2985dcccf7c7d1d1b429b5e6ea4914bb Mon Sep 17 00:00:00 2001 From: Ibrahim Munir-Zubair Date: Thu, 15 Jul 2021 10:08:40 +0100 Subject: [PATCH 19/19] HEEDLS-546 Rename a WelcomeEmailVM function --- .../Controllers/Register/RegisterDelegateByCentreController.cs | 2 +- .../Register/RegisterDelegateByCentre/WelcomeEmailViewModel.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs b/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs index 0ee764206e..712f2c33a3 100644 --- a/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs +++ b/DigitalLearningSolutions.Web/Controllers/Register/RegisterDelegateByCentreController.cs @@ -149,7 +149,7 @@ public IActionResult WelcomeEmail(WelcomeEmailViewModel model) { var data = TempData.Peek()!; - model.CleanDate(); + model.ClearDateIfNotSendEmail(); SetWelcomeEmailValidationResult(model); if (model.DateValidationResult is { DateValid: false }) { diff --git a/DigitalLearningSolutions.Web/ViewModels/Register/RegisterDelegateByCentre/WelcomeEmailViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/Register/RegisterDelegateByCentre/WelcomeEmailViewModel.cs index 1c72c8acdf..39c183a020 100644 --- a/DigitalLearningSolutions.Web/ViewModels/Register/RegisterDelegateByCentre/WelcomeEmailViewModel.cs +++ b/DigitalLearningSolutions.Web/ViewModels/Register/RegisterDelegateByCentre/WelcomeEmailViewModel.cs @@ -24,7 +24,7 @@ public WelcomeEmailViewModel(DelegateRegistrationByCentreData data) public bool ShouldSendEmail { get; set; } public DateValidator.ValidationResult? DateValidationResult { get; set; } - public void CleanDate() + public void ClearDateIfNotSendEmail() { if (!ShouldSendEmail) {