-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Started add alert page * Added basic functionality to add alert page * Finished off backend and UI to add an alert * Added CRM and UI tests * Added E2E test for adding an alert * Fixed inconsistency * Fixed issues from PR comments
- Loading branch information
Showing
23 changed files
with
842 additions
and
19 deletions.
There are no files selected for viewing
10 changes: 10 additions & 0 deletions
10
TeachingRecordSystem/src/TeachingRecordSystem.Core/Dqt/Queries/CreateSanctionQuery.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
namespace TeachingRecordSystem.Core.Dqt.Queries; | ||
|
||
public record CreateSanctionQuery : ICrmQuery<Guid> | ||
{ | ||
public required Guid ContactId { get; init; } | ||
public required Guid SanctionCodeId { get; init; } | ||
public required string Details { get; init; } | ||
public required string? Link { get; init; } | ||
public required DateOnly StartDate { get; init; } | ||
} |
23 changes: 23 additions & 0 deletions
23
...hingRecordSystem/src/TeachingRecordSystem.Core/Dqt/QueryHandlers/CreateSanctionHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
using Microsoft.PowerPlatform.Dataverse.Client; | ||
using TeachingRecordSystem.Core.Dqt.Queries; | ||
|
||
namespace TeachingRecordSystem.Core.Dqt.QueryHandlers; | ||
|
||
public class CreateSanctionHandler : ICrmQueryHandler<CreateSanctionQuery, Guid> | ||
{ | ||
public async Task<Guid> Execute(CreateSanctionQuery query, IOrganizationServiceAsync organizationService) | ||
{ | ||
var sanction = new dfeta_sanction() | ||
{ | ||
Id = Guid.NewGuid(), | ||
dfeta_PersonId = query.ContactId.ToEntityReference(Contact.EntityLogicalName), | ||
dfeta_SanctionCodeId = query.SanctionCodeId.ToEntityReference(dfeta_sanctioncode.EntityLogicalName), | ||
dfeta_SanctionDetails = query.Details, | ||
dfeta_DetailsLink = query.Link, | ||
dfeta_StartDate = query.StartDate.FromDateOnlyWithDqtBstFix(isLocalTime: true) | ||
}; | ||
|
||
var sanctionId = await organizationService.CreateAsync(sanction); | ||
return sanctionId; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
...ingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/AddAlert/AddAlertState.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
using System.Diagnostics.CodeAnalysis; | ||
using System.Text.Json.Serialization; | ||
|
||
namespace TeachingRecordSystem.SupportUi.Pages.Alerts.AddAlert; | ||
|
||
public class AddAlertState | ||
{ | ||
public Guid? AlertTypeId { get; set; } | ||
|
||
public string? Details { get; set; } | ||
|
||
public string? Link { get; set; } | ||
|
||
public DateOnly? StartDate { get; set; } | ||
|
||
[JsonIgnore] | ||
[MemberNotNullWhen(true, nameof(AlertTypeId), nameof(Details), nameof(StartDate))] | ||
public bool IsComplete => AlertTypeId.HasValue && !string.IsNullOrWhiteSpace(Details) && StartDate.HasValue; | ||
} |
41 changes: 41 additions & 0 deletions
41
TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/AddAlert/Confirm.cshtml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
@page "/alerts/add/confirm" | ||
@model TeachingRecordSystem.SupportUi.Pages.Alerts.AddAlert.ConfirmModel | ||
@{ | ||
ViewBag.Title = "Confirm alert information"; | ||
} | ||
|
||
@section BeforeContent { | ||
<govuk-back-link href="@LinkGenerator.AlertAdd(Model.PersonId, Model.JourneyInstance!.InstanceId)">Back</govuk-back-link> | ||
} | ||
|
||
<h1 class="govuk-heading-l">@ViewBag.Title</h1> | ||
|
||
<div class="govuk-grid-row"> | ||
<div class="govuk-grid-column-two-thirds-from-desktop"> | ||
<form method="post"> | ||
<govuk-summary-list> | ||
<govuk-summary-list-row> | ||
<govuk-summary-list-row-key>Alert type</govuk-summary-list-row-key> | ||
<govuk-summary-list-row-value data-testid="alert-type">@Model.AlertType</govuk-summary-list-row-value> | ||
</govuk-summary-list-row> | ||
<govuk-summary-list-row> | ||
<govuk-summary-list-row-key>Details</govuk-summary-list-row-key> | ||
<govuk-summary-list-row-value data-testid="details"><multi-line-text text="@Model.Details" /></govuk-summary-list-row-value> | ||
</govuk-summary-list-row> | ||
@if (!string.IsNullOrWhiteSpace(Model.Link)) | ||
{ | ||
<govuk-summary-list-row> | ||
<govuk-summary-list-row-key>Link</govuk-summary-list-row-key> | ||
<govuk-summary-list-row-value data-testid="link">@Model.Link</govuk-summary-list-row-value> | ||
</govuk-summary-list-row> | ||
} | ||
<govuk-summary-list-row> | ||
<govuk-summary-list-row-key>Start date</govuk-summary-list-row-key> | ||
<govuk-summary-list-row-value data-testid="start-date">@Model.StartDate!.Value.ToString("dd/MM/yyyy")</govuk-summary-list-row-value> | ||
</govuk-summary-list-row> | ||
</govuk-summary-list> | ||
|
||
<govuk-button type="submit">Confirm</govuk-button> | ||
</form> | ||
</div> | ||
</div> |
87 changes: 87 additions & 0 deletions
87
...ngRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/AddAlert/Confirm.cshtml.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.AspNetCore.Mvc.Filters; | ||
using Microsoft.AspNetCore.Mvc.RazorPages; | ||
using Microsoft.Xrm.Sdk.Query; | ||
using TeachingRecordSystem.Core.Dqt.Models; | ||
using TeachingRecordSystem.Core.Dqt.Queries; | ||
|
||
namespace TeachingRecordSystem.SupportUi.Pages.Alerts.AddAlert; | ||
|
||
[Journey(JourneyNames.AddAlert), RequireJourneyInstance] | ||
public class ConfirmModel : PageModel | ||
{ | ||
private readonly TrsLinkGenerator _linkGenerator; | ||
private readonly ICrmQueryDispatcher _crmQueryDispatcher; | ||
private readonly ReferenceDataCache _referenceDataCache; | ||
|
||
public ConfirmModel( | ||
TrsLinkGenerator linkGenerator, | ||
ICrmQueryDispatcher crmQueryDispatcher, | ||
ReferenceDataCache referenceDataCache) | ||
{ | ||
_linkGenerator = linkGenerator; | ||
_crmQueryDispatcher = crmQueryDispatcher; | ||
_referenceDataCache = referenceDataCache; | ||
} | ||
|
||
public JourneyInstance<AddAlertState>? JourneyInstance { get; set; } | ||
|
||
[FromQuery] | ||
public Guid PersonId { get; set; } | ||
|
||
public Guid? AlertTypeId { get; set; } | ||
|
||
public string? AlertType { get; set; } | ||
|
||
public string? Details { get; set; } | ||
|
||
public string? Link { get; set; } | ||
|
||
public DateOnly? StartDate { get; set; } | ||
|
||
public async Task<IActionResult> OnPost() | ||
{ | ||
await _crmQueryDispatcher.ExecuteQuery( | ||
new CreateSanctionQuery() | ||
{ | ||
ContactId = PersonId, | ||
SanctionCodeId = AlertTypeId!.Value, | ||
Details = Details!, | ||
Link = Link, | ||
StartDate = StartDate!.Value | ||
}); | ||
|
||
await JourneyInstance!.CompleteAsync(); | ||
|
||
TempData.SetFlashSuccess("Alert added"); | ||
|
||
return Redirect(_linkGenerator.PersonAlerts(PersonId)); | ||
} | ||
|
||
public override async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next) | ||
{ | ||
var person = await _crmQueryDispatcher.ExecuteQuery(new GetContactDetailByIdQuery(PersonId, new ColumnSet(Contact.Fields.Id))); | ||
if (person is null) | ||
{ | ||
context.Result = NotFound(); | ||
return; | ||
} | ||
|
||
if (!JourneyInstance!.State.IsComplete) | ||
{ | ||
context.Result = Redirect(_linkGenerator.AlertAdd(PersonId, JourneyInstance!.InstanceId)); | ||
return; | ||
} | ||
|
||
var sanctionCodeId = JourneyInstance!.State.AlertTypeId!.Value; | ||
var sanctionCode = await _referenceDataCache.GetSanctionCodeById(sanctionCodeId); | ||
|
||
AlertTypeId = sanctionCodeId; | ||
AlertType = sanctionCode.dfeta_name; | ||
Details = JourneyInstance!.State.Details; | ||
Link = JourneyInstance!.State.Link; | ||
StartDate = JourneyInstance!.State.StartDate; | ||
|
||
await next(); | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/AddAlert/Index.cshtml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
@page "/alerts/add" | ||
@model IndexModel | ||
@addTagHelper *, Joonasw.AspNetCore.SecurityHeaders | ||
@{ | ||
ViewBag.Title = "Add an alert"; | ||
} | ||
|
||
@section Styles { | ||
<link rel="stylesheet" href="~/Styles/Components/accessible-autocomplete.min.css" asp-append-version="true" /> | ||
} | ||
|
||
@section Scripts { | ||
<script src="~/Scripts/Components/accessible-autocomplete.min.js"></script> | ||
<script asp-add-nonce="true"> | ||
window.onload = function () { | ||
accessibleAutocomplete.enhanceSelectElement({ | ||
selectElement: document.querySelector('#@nameof(Model.AlertTypeId)') | ||
}) | ||
} | ||
</script> | ||
} | ||
|
||
@section BeforeContent { | ||
<govuk-back-link href="@LinkGenerator.PersonAlerts(Model.PersonId)">Back</govuk-back-link> | ||
} | ||
|
||
<h1 class="govuk-heading-l">@ViewBag.Title</h1> | ||
|
||
<div class="govuk-grid-row"> | ||
<div class="govuk-grid-column-two-thirds-from-desktop"> | ||
<form method="post"> | ||
<govuk-select asp-for="AlertTypeId" label-class="govuk-label--m"> | ||
<govuk-select-item value=""></govuk-select-item> | ||
@foreach (var alertType in Model.AlertTypes!) | ||
{ | ||
<govuk-select-item value="@alertType.AlertTypeId">@alertType.Name</govuk-select-item> | ||
} | ||
</govuk-select> | ||
|
||
<govuk-textarea asp-for="Details" label-class="govuk-label--m"/> | ||
|
||
<govuk-input asp-for="Link" label-class="govuk-label--m"/> | ||
|
||
<govuk-date-input asp-for="StartDate"> | ||
<govuk-date-input-fieldset> | ||
<govuk-date-input-fieldset-legend class="govuk-fieldset__legend--m" /> | ||
</govuk-date-input-fieldset> | ||
</govuk-date-input> | ||
|
||
<govuk-button type="submit">Continue</govuk-button> | ||
</form> | ||
</div> | ||
</div> | ||
|
122 changes: 122 additions & 0 deletions
122
...hingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Alerts/AddAlert/Index.cshtml.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
using System.ComponentModel.DataAnnotations; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.AspNetCore.Mvc.Filters; | ||
using Microsoft.AspNetCore.Mvc.RazorPages; | ||
using Microsoft.Xrm.Sdk.Query; | ||
using TeachingRecordSystem.Core.Dqt.Models; | ||
using TeachingRecordSystem.Core.Dqt.Queries; | ||
using TeachingRecordSystem.SupportUi.Pages.Common; | ||
|
||
namespace TeachingRecordSystem.SupportUi.Pages.Alerts.AddAlert; | ||
|
||
[Journey(JourneyNames.AddAlert), ActivatesJourney, RequireJourneyInstance] | ||
public class IndexModel : PageModel | ||
{ | ||
private readonly TrsLinkGenerator _linkGenerator; | ||
private readonly ICrmQueryDispatcher _crmQueryDispatcher; | ||
private readonly ReferenceDataCache _referenceDataCache; | ||
|
||
public IndexModel( | ||
TrsLinkGenerator linkGenerator, | ||
ICrmQueryDispatcher crmQueryDispatcher, | ||
ReferenceDataCache referenceDataCache) | ||
{ | ||
_linkGenerator = linkGenerator; | ||
_crmQueryDispatcher = crmQueryDispatcher; | ||
_referenceDataCache = referenceDataCache; | ||
} | ||
|
||
public JourneyInstance<AddAlertState>? JourneyInstance { get; set; } | ||
|
||
[FromQuery] | ||
public Guid PersonId { get; set; } | ||
|
||
[BindProperty] | ||
[Display(Name = "Alert type")] | ||
public Guid? AlertTypeId { get; set; } | ||
|
||
[BindProperty] | ||
[Display(Description = "You can enter up to 4000 characters")] | ||
public string? Details { get; set; } | ||
|
||
[BindProperty] | ||
[Display(Description = "Optional")] | ||
public string? Link { get; set; } | ||
|
||
[BindProperty] | ||
[Display(Name = "Start date")] | ||
public DateOnly? StartDate { get; set; } | ||
|
||
public AlertType[]? AlertTypes { get; set; } | ||
|
||
public async Task<IActionResult> OnPost() | ||
{ | ||
if (AlertTypeId is null) | ||
{ | ||
ModelState.AddModelError(nameof(AlertTypeId), "Add an alert type"); | ||
} | ||
|
||
if (string.IsNullOrWhiteSpace(Details)) | ||
{ | ||
ModelState.AddModelError(nameof(Details), "Add details"); | ||
} | ||
|
||
if (!string.IsNullOrEmpty(Link) && | ||
(!Uri.TryCreate(Link, UriKind.Absolute, out var uri) || | ||
(uri.Scheme != "http" && uri.Scheme != "https"))) | ||
{ | ||
ModelState.AddModelError(nameof(Link), "Enter a valid URL"); | ||
} | ||
|
||
if (StartDate is null) | ||
{ | ||
ModelState.AddModelError(nameof(StartDate), "Add a start date"); | ||
} | ||
|
||
if (!ModelState.IsValid) | ||
{ | ||
return this.PageWithErrors(); | ||
} | ||
|
||
await JourneyInstance!.UpdateStateAsync(s => | ||
{ | ||
s.AlertTypeId = AlertTypeId; | ||
s.Details = Details; | ||
s.Link = Link; | ||
s.StartDate = StartDate; | ||
}); | ||
|
||
return Redirect(_linkGenerator.AlertAddConfirm(PersonId, JourneyInstance!.InstanceId)); | ||
} | ||
|
||
public override async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next) | ||
{ | ||
var person = await _crmQueryDispatcher.ExecuteQuery(new GetContactDetailByIdQuery(PersonId, new ColumnSet(Contact.Fields.Id))); | ||
if (person is null) | ||
{ | ||
context.Result = NotFound(); | ||
return; | ||
} | ||
|
||
var sanctionCodes = await _referenceDataCache.GetSanctionCodes(); | ||
AlertTypes = sanctionCodes | ||
.Select(MapSanctionCode) | ||
.OrderBy(a => a.Name) | ||
.ToArray(); | ||
|
||
AlertTypeId ??= JourneyInstance!.State.AlertTypeId; | ||
Details ??= JourneyInstance!.State.Details; | ||
Link ??= JourneyInstance!.State.Link; | ||
StartDate ??= JourneyInstance!.State.StartDate; | ||
|
||
await next(); | ||
} | ||
|
||
private AlertType MapSanctionCode(dfeta_sanctioncode sanctionCode) => | ||
new AlertType() | ||
{ | ||
AlertTypeId = sanctionCode.dfeta_sanctioncodeId!.Value, | ||
Value = sanctionCode.dfeta_Value, | ||
Name = sanctionCode.dfeta_name | ||
}; | ||
} |
8 changes: 8 additions & 0 deletions
8
TeachingRecordSystem/src/TeachingRecordSystem.SupportUi/Pages/Common/AlertType.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
namespace TeachingRecordSystem.SupportUi.Pages.Common; | ||
|
||
public record AlertType | ||
{ | ||
public required Guid AlertTypeId { get; init; } | ||
public required string Name { get; init; } | ||
public required string Value { get; init; } | ||
} |
Oops, something went wrong.