Skip to content

Commit b53a1ba

Browse files
authored
Merge pull request #1592 from TechnologyEnhancedLearning/Develop/Fixes/TD-6652
Fixes for TD-6652
2 parents ee40571 + 9d1b38a commit b53a1ba

File tree

17 files changed

+310
-119
lines changed

17 files changed

+310
-119
lines changed

LearningHub.Nhs.WebUI/Controllers/AccountController.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,6 +1167,16 @@ public IActionResult InvalidUserAccount()
11671167
return this.View();
11681168
}
11691169

1170+
/// <summary>
1171+
/// The user does not have permissions to access a section of the Learning Hub.
1172+
/// </summary>
1173+
/// <returns>The <see cref="IActionResult"/>.</returns>
1174+
[HttpGet]
1175+
public IActionResult AccessRestricted()
1176+
{
1177+
return this.View();
1178+
}
1179+
11701180
/// <summary>
11711181
/// The user already has an already active session. Then prevent concurrent access to the Learning Hub.
11721182
/// </summary>

LearningHub.Nhs.WebUI/Controllers/ReportsController.cs

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,28 @@
55
using System.Linq;
66
using System.Net.Http;
77
using System.Threading.Tasks;
8-
using Azure;
98
using GDS.MultiPageFormData;
109
using GDS.MultiPageFormData.Enums;
1110
using LearningHub.Nhs.Caching;
1211
using LearningHub.Nhs.Models.Databricks;
13-
using LearningHub.Nhs.Models.Moodle;
14-
using LearningHub.Nhs.Models.MyLearning;
1512
using LearningHub.Nhs.Models.Paging;
1613
using LearningHub.Nhs.WebUI.Configuration;
1714
using LearningHub.Nhs.WebUI.Filters;
1815
using LearningHub.Nhs.WebUI.Helpers;
1916
using LearningHub.Nhs.WebUI.Interfaces;
20-
using LearningHub.Nhs.WebUI.Models;
21-
using LearningHub.Nhs.WebUI.Models.Account;
22-
using LearningHub.Nhs.WebUI.Models.DynamicCheckbox;
2317
using LearningHub.Nhs.WebUI.Models.Learning;
2418
using LearningHub.Nhs.WebUI.Models.Report;
2519
using Microsoft.AspNetCore.Authorization;
2620
using Microsoft.AspNetCore.Hosting;
2721
using Microsoft.AspNetCore.Mvc;
2822
using Microsoft.Extensions.Logging;
2923
using Microsoft.Extensions.Options;
30-
using NHSUKViewComponents.Web.ViewModels;
3124

3225
/// <summary>
3326
/// Defines the <see cref="ReportsController" />.
3427
/// </summary>
35-
// [ServiceFilter(typeof(LoginWizardFilter))]
28+
[ServiceFilter(typeof(LoginWizardFilter))]
29+
[ServiceFilter(typeof(ReporterPermissionFilter))]
3630
[Authorize]
3731
[Route("Reports")]
3832
public class ReportsController : BaseController
@@ -158,7 +152,7 @@ public async Task<IActionResult> CreateReportCourseSelection(ReportCreationCours
158152
{
159153
var reportCreation = await this.multiPageFormService.GetMultiPageFormData<DatabricksRequestModel>(MultiPageFormDataFeature.AddCustomWebForm("ReportWizardCWF"), this.TempData);
160154

161-
if (courseSelection != null)
155+
if (courseSelection.Courses != null)
162156
{
163157
if (courseSelection.Courses.Any())
164158
{
@@ -208,11 +202,19 @@ public async Task<IActionResult> CreateReportDateSelection()
208202
Skip = 1,
209203
});
210204

211-
DateTime startDate = DateTime.MinValue;
212-
var validDate = DateTime.TryParse(result.MinValidDate, out startDate);
213-
dateVM.StartDay = validDate ? startDate.Day : 0;
214-
dateVM.StartMonth = validDate ? startDate.Month : 0;
215-
dateVM.StartYear = validDate ? startDate.Year : 0;
205+
if (result != null)
206+
{
207+
var validDate = DateTime.TryParse(result.MinValidDate, out DateTime startDate);
208+
dateVM.DataStart = validDate ? startDate : null;
209+
dateVM.HintText = validDate
210+
? $"For example, {startDate.Day} {startDate.Month} {startDate.Year}"
211+
: $"For example, {DateTime.Now.Day} {DateTime.Now.Month} {DateTime.Now.Year}";
212+
}
213+
else
214+
{
215+
dateVM.DataStart = null;
216+
dateVM.HintText = $"For example, {DateTime.Now.Day} {DateTime.Now.Month} {DateTime.Now.Year}";
217+
}
216218
}
217219

218220
return this.View(dateVM);
@@ -232,6 +234,12 @@ public async Task<IActionResult> CreateReportSummary(ReportCreationDateSelection
232234
// validate date
233235
var reportCreation = await this.multiPageFormService.GetMultiPageFormData<DatabricksRequestModel>(MultiPageFormDataFeature.AddCustomWebForm("ReportWizardCWF"), this.TempData);
234236
reportCreation.TimePeriod = reportCreationDate.TimePeriod;
237+
238+
if (!this.ModelState.IsValid)
239+
{
240+
return this.View("CreateReportDateSelection", reportCreationDate);
241+
}
242+
235243
reportCreation.StartDate = reportCreationDate.GetStartDate();
236244
reportCreation.EndDate = reportCreationDate.GetEndDate();
237245
await this.multiPageFormService.SetMultiPageFormData(reportCreation, MultiPageFormDataFeature.AddCustomWebForm("ReportWizardCWF"), this.TempData);
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
namespace LearningHub.Nhs.WebUI.Filters
2+
{
3+
using System.Threading.Tasks;
4+
using LearningHub.Nhs.WebUI.Interfaces;
5+
using Microsoft.AspNetCore.Mvc;
6+
using Microsoft.AspNetCore.Mvc.Filters;
7+
using Microsoft.AspNetCore.Routing;
8+
9+
/// <summary>
10+
/// Defines the <see cref="ReporterPermissionFilter" />.
11+
/// </summary>
12+
public class ReporterPermissionFilter : ActionFilterAttribute
13+
{
14+
private readonly IReportService reportService;
15+
16+
/// <summary>
17+
/// Initializes a new instance of the <see cref="ReporterPermissionFilter"/> class.
18+
/// </summary>
19+
/// <param name="reportService">reportService.</param>
20+
public ReporterPermissionFilter(IReportService reportService)
21+
{
22+
this.reportService = reportService;
23+
}
24+
25+
/// <inheritdoc/>
26+
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
27+
{
28+
var controller = context.ActionDescriptor.RouteValues["Controller"];
29+
var action = context.ActionDescriptor.RouteValues["Action"];
30+
31+
// Run your cached permission check
32+
var hasPermission = await this.reportService.GetReporterPermission();
33+
34+
// If user does NOT have permission and they're not in safe routes
35+
if (!hasPermission
36+
&& !(controller == "Account" && action == "AccessRestricted")
37+
&& !(controller == "Home" && action == "Logout"))
38+
{
39+
context.Result = new RedirectToRouteResult(
40+
new RouteValueDictionary
41+
{
42+
{ "Controller", "Account" },
43+
{ "Action", "AccessRestricted" },
44+
});
45+
46+
return;
47+
}
48+
49+
await next();
50+
}
51+
}
52+
}

LearningHub.Nhs.WebUI/Helpers/CommonValidationErrorMessages.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ public static class CommonValidationErrorMessages
7575
/// </summary>
7676
public const string StartDate = "Enter a start date containing a day, month and a year";
7777

78+
/// <summary>
79+
/// Start date Required.
80+
/// </summary>
81+
public const string EndDate = "Enter an end date containing a day, month and a year";
82+
7883
/// <summary>
7984
/// Workplace Required.
8085
/// </summary>

LearningHub.Nhs.WebUI/Helpers/UtilityHelper.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,5 +522,21 @@ public static string GetPillColour(string filename)
522522

523523
return breadcrumbs;
524524
}
525+
526+
/// <summary>
527+
/// Returns sentence case of input string.
528+
/// </summary>
529+
/// <param name="input">input.</param>
530+
/// <returns>A sentence case string corresponding to the input string.</returns>
531+
public static string ConvertToSentenceCase(string input)
532+
{
533+
if (string.IsNullOrEmpty(input))
534+
{
535+
return input;
536+
}
537+
538+
input = input.ToLower();
539+
return char.ToUpper(input[0]) + input.Substring(1);
540+
}
525541
}
526542
}

LearningHub.Nhs.WebUI/Models/Report/ReportCreationCourseSelection.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Collections.Generic;
55
using System.Data;
66
using System.Linq;
7+
using LearningHub.Nhs.WebUI.Helpers;
78
using LearningHub.Nhs.WebUI.Models.DynamicCheckbox;
89
using NHSUKViewComponents.Web.ViewModels;
910

@@ -37,9 +38,9 @@ public List<DynamicCheckboxItemViewModel> BuildCourses(List<KeyValuePair<string,
3738
this.AllCources = allCourses.Select(r => new DynamicCheckboxItemViewModel
3839
{
3940
Value = r.Key.ToString(),
40-
Label = r.Value,
41+
Label = UtilityHelper.ConvertToSentenceCase(r.Value),
4142
}).ToList();
42-
this.AllCources.Insert(0, new DynamicCheckboxItemViewModel { Value = "all", Label = "All Courses", });
43+
this.AllCources.Insert(0, new DynamicCheckboxItemViewModel { Value = "all", Label = "All courses", });
4344
return this.AllCources;
4445
}
4546
}

LearningHub.Nhs.WebUI/Models/Report/ReportCreationDateSelection.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ public class ReportCreationDateSelection : IValidatableObject
6060
/// </summary>
6161
public bool EndDate { get; set; }
6262

63+
/// <summary>
64+
/// Gets or sets a value indicating whether gets or sets the HintText.
65+
/// </summary>
66+
public string HintText { get; set; }
67+
6368
/// <summary>
6469
/// Gets or sets the GetDate.
6570
/// </summary>
@@ -85,11 +90,7 @@ public IEnumerable<ValidationResult> Validate(ValidationContext validationContex
8590
if (this.TimePeriod == "Custom")
8691
{
8792
this.ValidateStartDate(validationResults);
88-
89-
if (this.EndDate)
90-
{
91-
this.ValidateEndDate(validationResults);
92-
}
93+
this.ValidateEndDate(validationResults);
9394
}
9495

9596
return validationResults;
@@ -126,6 +127,7 @@ public List<RadiosItemViewModel> PopulateDateRange()
126127
new RadiosItemViewModel("7", "7 days", false, null),
127128
new RadiosItemViewModel("30", "30 days", false, null),
128129
new RadiosItemViewModel("90", "90 days", false, null),
130+
new RadiosItemViewModel("Custom", "Custom date range", false, null),
129131
};
130132

131133
// if (string.IsNullOrWhiteSpace(this.TimePeriod))

LearningHub.Nhs.WebUI/Startup/ServiceMappings.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ public static void AddLearningHubMappings(this IServiceCollection services, ICon
120120
services.AddScoped<LoginWizardFilter>();
121121
services.AddScoped<SsoLoginFilterAttribute>();
122122
services.AddScoped<OfflineCheckFilter>();
123+
services.AddScoped<ReporterPermissionFilter>();
123124
}
124125
}
125126
}

LearningHub.Nhs.WebUI/Styles/nhsuk/pages/reporting.scss

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,10 @@
1919
width: auto;
2020
}
2121

22-
.nhsuk-summary-list__row {
23-
display: flex !important;
24-
align-items: flex-start; /* optional: aligns top of key/value */
25-
}
26-
27-
.nhsuk-summary-list__row {
28-
border-bottom: none;
29-
}
30-
31-
.nhsuk-summary-list__key, .nhsuk-summary-list__value, .nhsuk-summary-list__actions {
32-
border: none;
33-
}
34-
3522
.nhsuk-date-inline {
3623
display: flex;
3724
align-items: center;
38-
gap: 0.5rem; /* space between label and input */
25+
gap: 0.5rem;
3926
}
4027

4128
.nhsuk-date-inline .nhsuk-label {
@@ -44,13 +31,47 @@
4431
}
4532

4633
.nhsuk-button--with-border {
47-
border: 2px solid #005eb8;
48-
background-color: #ffffff;
49-
color: #005eb8;
34+
border: 2px solid #005eb8;
35+
background-color: #ffffff;
36+
color: #005eb8;
5037
}
5138

5239
.nhsuk-button--with-border:hover {
5340
background-color: #f0f8ff;
54-
border-color: #003087;
41+
border-color: #003087;
42+
}
43+
44+
.date-range-container {
45+
display: flex;
46+
flex-wrap: wrap;
47+
gap: 1rem;
48+
}
49+
50+
.date-range-item {
51+
flex: 0 1 auto;
52+
}
53+
54+
@media (max-width: 767px) {
55+
.date-range-container .nhsuk-label {
56+
min-width: 50px;
57+
}
58+
}
59+
60+
.nhsuk-radios__divider {
61+
text-align: center;
62+
width: 40px;
63+
}
64+
65+
.nhsuk-hint {
66+
margin-bottom: 0.5rem;
67+
}
68+
69+
.date-range-container .nhsuk-hint {
70+
display: block;
71+
max-height: 0;
72+
overflow: hidden;
73+
margin: 0;
74+
padding: 0;
75+
visibility: hidden;
5576
}
5677
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
@{
2+
ViewData["Title"] = "You do not have the required permissions to access this part of the Learning Hub";
3+
Layout = ViewData["Layout"].ToString();
4+
}
5+
6+
@section styles{
7+
<link rel="stylesheet" type="text/css" href="~/css/nhsuk/pages/staticpages.css" asp-append-version="true" />
8+
}
9+
10+
<div class="nhsuk-width-container app-width-container">
11+
<div class="nhsuk-main-wrapper ">
12+
<div class="nhsuk-grid-row">
13+
<div class="nhsuk-grid-column-full">
14+
<h1 class="nhsuk-heading-xl">Access restricted</h1>
15+
<div class="nhsuk-u-reading-width">
16+
<p>You do not have the required permissions to access this part of the Learning Hub yet.</p>
17+
</div>
18+
</div>
19+
</div>
20+
<div class="nhsuk-grid-row">
21+
<div class="nhsuk-grid-column-full">
22+
<div class="nhsuk-u-reading-width">
23+
<div>
24+
<p>If you think you should have access, please contact the support team.</p>
25+
</div>
26+
</div>
27+
</div>
28+
</div>
29+
</div>
30+
</div>
31+
32+

0 commit comments

Comments
 (0)