From ab69e328d92f77b5cc1fc3ad53c622276b5c31d6 Mon Sep 17 00:00:00 2001 From: sherif-olaboye <123654949+sherif-olaboye@users.noreply.github.com> Date: Fri, 29 May 2026 17:02:52 +0100 Subject: [PATCH 1/6] TD-7276 Issue showing console 500' error when try to set competency role requirements --- .../CompetencyAssessmentDataService.cs | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/DigitalLearningSolutions.Data/DataServices/CompetencyAssessmentDataService.cs b/DigitalLearningSolutions.Data/DataServices/CompetencyAssessmentDataService.cs index b6ff269935..cc10791b12 100644 --- a/DigitalLearningSolutions.Data/DataServices/CompetencyAssessmentDataService.cs +++ b/DigitalLearningSolutions.Data/DataServices/CompetencyAssessmentDataService.cs @@ -1426,11 +1426,34 @@ public int InsertAssessmentQuestionRoleRequirementForSelfAssessment(int assessme { var numberOfAffectedRows = connection.Execute( @"INSERT INTO CompetencyAssessmentQuestionRoleRequirements - (SelfAssessmentID, CompetencyID, AssessmentQuestionID, LevelValue, LevelRAG) - SELECT sas.SelfAssessmentID, sas.CompetencyID, caq.AssessmentQuestionID, @levelValue AS LevelValue, @levelRAG AS LevelRAG - FROM SelfAssessmentStructure AS sas INNER JOIN - CompetencyAssessmentQuestions AS caq ON sas.CompetencyID = caq.CompetencyID - WHERE (sas.SelfAssessmentID = @assessmentId) AND (caq.AssessmentQuestionID = @assessmentQuestionId);" + ( + SelfAssessmentID, + CompetencyID, + AssessmentQuestionID, + LevelValue, + LevelRAG + ) + SELECT DISTINCT + sas.SelfAssessmentID, + sas.CompetencyID, + caq.AssessmentQuestionID, + @levelValue, + @levelRAG + FROM SelfAssessmentStructure AS sas + INNER JOIN CompetencyAssessmentQuestions AS caq + ON sas.CompetencyID = caq.CompetencyID + WHERE + sas.SelfAssessmentID = @assessmentId + AND caq.AssessmentQuestionID = @assessmentQuestionId + AND NOT EXISTS + ( + SELECT 1 + FROM CompetencyAssessmentQuestionRoleRequirements existing + WHERE existing.SelfAssessmentID = sas.SelfAssessmentID + AND existing.CompetencyID = sas.CompetencyID + AND existing.AssessmentQuestionID = caq.AssessmentQuestionID + AND existing.LevelValue = @levelValue + );" , new { assessmentId, assessmentQuestionId, levelValue, levelRAG } ); From b092a370f0cd51578b7212bde37995bf68fdd8d8 Mon Sep 17 00:00:00 2001 From: sherif-olaboye <123654949+sherif-olaboye@users.noreply.github.com> Date: Mon, 1 Jun 2026 16:05:43 +0100 Subject: [PATCH 2/6] TD-7342 Issue skipping navigating to the Select proficiencies to assess screen after selecting the framework from source --- .../CompetencyAssessments.cs | 11 ++++++-- .../SelectFrameworkSourcesViewModel.cs | 2 +- .../SelectFrameworkSources.cshtml | 27 ++++++++++++------- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/DigitalLearningSolutions.Web/Controllers/CompetencyAssessmentsController/CompetencyAssessments.cs b/DigitalLearningSolutions.Web/Controllers/CompetencyAssessmentsController/CompetencyAssessments.cs index b353490b19..a599e16c08 100644 --- a/DigitalLearningSolutions.Web/Controllers/CompetencyAssessmentsController/CompetencyAssessments.cs +++ b/DigitalLearningSolutions.Web/Controllers/CompetencyAssessmentsController/CompetencyAssessments.cs @@ -438,6 +438,11 @@ public IActionResult SelectFrameworkSources(SelectFrameworkSourcesFormData model competencyAssessmentService.InsertSelfAssessmentFramework(adminId, competencyAssessmentId, model.FrameworkId.Value); return RedirectToAction("SelectFrameworkSources", new { competencyAssessmentId, actionName = "Summary" }); } + else if (actionName == "ViewSelected") + { + competencyAssessmentService.InsertSelfAssessmentFramework(adminId, competencyAssessmentId, model.FrameworkId.Value); + return RedirectToAction("ViewSelectedCompetencies", new { competencyAssessmentId }); + } else { competencyAssessmentService.UpdateFrameworkLinksTaskStatus(model.CompetencyAssessmentId, model.TaskStatus ?? false, null); @@ -484,7 +489,7 @@ public IActionResult ViewSelectedCompetencies(int competencyAssessmentId) var linkedFrameworks = competencyAssessmentService.GetLinkedFrameworksForCompetencyAssessment(competencyAssessmentId); if (!linkedFrameworks.Any()) { - return RedirectToAction("AddCompetenciesSelectFramework", new { competencyAssessmentId }); + return RedirectToAction("SelectFrameworkSources", new { competencyAssessmentId, actionName = "ViewSelected" }); } var adminId = GetAdminID(); var competencyAssessmentBase = competencyAssessmentService.GetCompetencyAssessmentBaseById(competencyAssessmentId, adminId); @@ -496,7 +501,8 @@ public IActionResult ViewSelectedCompetencies(int competencyAssessmentId) return View(model); } [Route("/Self-Assessment/{competencyAssessmentId}/Competencies/Add/SelectFramework")] - public IActionResult AddCompetenciesSelectFramework(int competencyAssessmentId) + [Route("/Self-Assessment/{competencyAssessmentId}/{actionName}/Competencies/Add/SelectFramework")] + public IActionResult AddCompetenciesSelectFramework(int competencyAssessmentId, string? actionName) { var linkedFrameworks = competencyAssessmentService.GetLinkedFrameworksForCompetencyAssessment(competencyAssessmentId); if (!linkedFrameworks.Any()) @@ -513,6 +519,7 @@ public IActionResult AddCompetenciesSelectFramework(int competencyAssessmentId) } [HttpPost] [Route("/Self-Assessment/{competencyAssessmentId}/Competencies/Add/SelectFramework")] + [Route("/Self-Assessment/{competencyAssessmentId}/{actionName}/Competencies/Add/SelectFramework")] public IActionResult AddCompetenciesSelectFramework(AddCompetenciesSelectFrameworkFormData formdata) { if (!ModelState.IsValid) diff --git a/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/SelectFrameworkSourcesViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/SelectFrameworkSourcesViewModel.cs index 8d1adea226..45ab4395e2 100644 --- a/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/SelectFrameworkSourcesViewModel.cs +++ b/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/SelectFrameworkSourcesViewModel.cs @@ -23,7 +23,7 @@ public SelectFrameworkSourcesViewModel(CompetencyAssessmentBase competencyAssess Frameworks = [.. frameworks .Where(f => !excludedIds.Contains(f.ID)) .OrderBy(f => f.FrameworkName)]; - AdditionalFrameworks = [.. additionalFrameworksIds.Select(id => frameworks.First(f => f.ID == id))]; + AdditionalFrameworks = [.. additionalFrameworksIds.Select(id => frameworks.FirstOrDefault(f => f.ID == id))]; ActionName = actionName; } public IEnumerable Frameworks { get; set; } diff --git a/DigitalLearningSolutions.Web/Views/CompetencyAssessments/SelectFrameworkSources.cshtml b/DigitalLearningSolutions.Web/Views/CompetencyAssessments/SelectFrameworkSources.cshtml index 277228e2f2..34e76e560d 100644 --- a/DigitalLearningSolutions.Web/Views/CompetencyAssessments/SelectFrameworkSources.cshtml +++ b/DigitalLearningSolutions.Web/Views/CompetencyAssessments/SelectFrameworkSources.cshtml @@ -73,16 +73,19 @@ } } - @if (Model.AdditionalFrameworks.Count() > 0) + @if (Model?.AdditionalFrameworks != null && Model.AdditionalFrameworks.Any()) { - for (int i = 0; i < Model.AdditionalFrameworks.Count(); i++) + int i = 0; + foreach (var framework in Model.AdditionalFrameworks) { + if (framework == null) continue; // Safety check in case an item in the list is null +
Additional framework @(i + 1)
- @Model.AdditionalFrameworks.ElementAt(i).FrameworkName + @framework.FrameworkName
@if (Model.UserRole > 1) { @@ -90,28 +93,32 @@ }
+ i++; } } + else + { +

No additional frameworks available.

+ } } -@if (Model.ActionName == "AddFramework") +@if (Model.ActionName == "AddFramework" || Model.ActionName == "ViewSelected") {
From 6505e53638c35baf576167304e06c1f93d6998f1 Mon Sep 17 00:00:00 2001 From: sherif-olaboye <123654949+sherif-olaboye@users.noreply.github.com> Date: Mon, 1 Jun 2026 16:14:12 +0100 Subject: [PATCH 3/6] TD-7342 Issue skipping navigating to the Select proficiencies to assess screen after selecting the framework from source --- .../Views/CompetencyAssessments/SelectFrameworkSources.cshtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DigitalLearningSolutions.Web/Views/CompetencyAssessments/SelectFrameworkSources.cshtml b/DigitalLearningSolutions.Web/Views/CompetencyAssessments/SelectFrameworkSources.cshtml index 34e76e560d..b6d7b9e7dd 100644 --- a/DigitalLearningSolutions.Web/Views/CompetencyAssessments/SelectFrameworkSources.cshtml +++ b/DigitalLearningSolutions.Web/Views/CompetencyAssessments/SelectFrameworkSources.cshtml @@ -78,7 +78,7 @@ int i = 0; foreach (var framework in Model.AdditionalFrameworks) { - if (framework == null) continue; // Safety check in case an item in the list is null + if (framework == null) continue;
From b3a5ee4494763a08b124618fd909cfa25bdc336f Mon Sep 17 00:00:00 2001 From: sherif-olaboye <123654949+sherif-olaboye@users.noreply.github.com> Date: Mon, 1 Jun 2026 16:30:53 +0100 Subject: [PATCH 4/6] TD-7342 Issue skipping navigating to the Select proficiencies to assess screen after selecting the framework from source --- .../Views/CompetencyAssessments/SelectFrameworkSources.cshtml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/DigitalLearningSolutions.Web/Views/CompetencyAssessments/SelectFrameworkSources.cshtml b/DigitalLearningSolutions.Web/Views/CompetencyAssessments/SelectFrameworkSources.cshtml index b6d7b9e7dd..d0af8f724a 100644 --- a/DigitalLearningSolutions.Web/Views/CompetencyAssessments/SelectFrameworkSources.cshtml +++ b/DigitalLearningSolutions.Web/Views/CompetencyAssessments/SelectFrameworkSources.cshtml @@ -112,10 +112,6 @@ i++; } } - else - { -

No additional frameworks available.

- } } @if (Model.ActionName == "AddFramework" || Model.ActionName == "ViewSelected") From 555f0a59ff2e2cb21939ef431b84861780553a16 Mon Sep 17 00:00:00 2001 From: sherif-olaboye <123654949+sherif-olaboye@users.noreply.github.com> Date: Tue, 2 Jun 2026 12:44:17 +0100 Subject: [PATCH 5/6] TD-7112 Remove the Log in button in DLS --- .../Extensions/ConfigurationExtensions.cs | 9 +++++++-- .../Views/Shared/_NavMenuItems.cshtml | 3 +++ DigitalLearningSolutions.Web/appsettings.json | 3 ++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/DigitalLearningSolutions.Data/Extensions/ConfigurationExtensions.cs b/DigitalLearningSolutions.Data/Extensions/ConfigurationExtensions.cs index 61dc157340..3ff77ba9bb 100644 --- a/DigitalLearningSolutions.Data/Extensions/ConfigurationExtensions.cs +++ b/DigitalLearningSolutions.Data/Extensions/ConfigurationExtensions.cs @@ -11,7 +11,8 @@ public static class ConfigurationExtensions private const string LearningHubOpenApiKey = "LearningHubOpenAPIKey"; private const string LearningHubOpenApiBaseUrl = "LearningHubOpenAPIBaseUrl"; private const string PricingPageEnabled = "FeatureManagement:PricingPage"; - + private const string ShowDlsLoginButton = "FeatureManagement:ShowDlsLoginButton"; + private const string LearningHubAuthBaseUrl = "BaseUrl"; private const string LearningHubAuthLoginEndpoint = "LoginEndpoint"; private const string LearningHubAuthLinkingEndpoint = "LinkingEndpoint"; @@ -118,7 +119,11 @@ public static bool IsPricingPageEnabled(this IConfiguration config) bool.TryParse(config[PricingPageEnabled], out bool isEnabled); return isEnabled; } - + public static bool IsDlsLoginButtonShown(this IConfiguration config) + { + bool.TryParse(config[ShowDlsLoginButton], out bool isEnabled); + return isEnabled; + } public static int GetLearningHubSsoHashTolerance(this IConfiguration config) { int.TryParse(config[$"{LearningHubSsoSectionKey}:{LearningHubSsoToleranceKey}"], out int ssoHashTolerance); diff --git a/DigitalLearningSolutions.Web/Views/Shared/_NavMenuItems.cshtml b/DigitalLearningSolutions.Web/Views/Shared/_NavMenuItems.cshtml index 9db232ee6f..761c227872 100644 --- a/DigitalLearningSolutions.Web/Views/Shared/_NavMenuItems.cshtml +++ b/DigitalLearningSolutions.Web/Views/Shared/_NavMenuItems.cshtml @@ -32,11 +32,14 @@ } else { + @if (Configuration.IsDlsLoginButtonShown()) + {
  • Log in
  • + }
  • Register diff --git a/DigitalLearningSolutions.Web/appsettings.json b/DigitalLearningSolutions.Web/appsettings.json index dc87d7cd1e..0ecd7161f1 100644 --- a/DigitalLearningSolutions.Web/appsettings.json +++ b/DigitalLearningSolutions.Web/appsettings.json @@ -21,7 +21,8 @@ "PricingPage": true, "ShowSelfAssessmentProgressButtons": false, "LoginWithLearningHub": true, - "TableauSelfAssessmentDashboards": true + "TableauSelfAssessmentDashboards": true, + "ShowDlsLoginButton": false }, "LearningHubOpenAPIBaseUrl": "https://uks-learninghubnhsuk-openapi-test.azurewebsites.net", "LearningHubOpenAPIKey": "", From 9ba260cfb2ce1258be8da7f1ae90a67b8b4be4fa Mon Sep 17 00:00:00 2001 From: sherif-olaboye <123654949+sherif-olaboye@users.noreply.github.com> Date: Tue, 2 Jun 2026 15:44:43 +0100 Subject: [PATCH 6/6] TD-7343 Added auto focus to the check box --- .../CompetencyAssessments.cs | 3 +++ .../AddCompetenciesViewFormData.cs | 5 +---- .../AddCompetenciesViewModel.cs | 2 +- .../AddCompetencies.cshtml | 19 ++++++++++++++++++- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/DigitalLearningSolutions.Web/Controllers/CompetencyAssessmentsController/CompetencyAssessments.cs b/DigitalLearningSolutions.Web/Controllers/CompetencyAssessmentsController/CompetencyAssessments.cs index b353490b19..5c57c433fe 100644 --- a/DigitalLearningSolutions.Web/Controllers/CompetencyAssessmentsController/CompetencyAssessments.cs +++ b/DigitalLearningSolutions.Web/Controllers/CompetencyAssessmentsController/CompetencyAssessments.cs @@ -579,6 +579,9 @@ public IActionResult AddComptencies(AddCompetenciesFormData model, int competenc competency.CompetencyFlags = competencyFlags.Where(f => f.CompetencyId == competency.CompetencyID); } var models = new AddCompetenciesViewModel(competencyAssessmentBase, groupedCompetencies, ungroupedCompetencies, frameworkId, framework.FrameworkName, model.SelectedCompetencyIds); + ModelState.Clear(); + ModelState.AddModelError("SelectedCompetencyIds", $"You must select at least one {models.VocabularySingular}"); + ViewBag.RequiredCheckboxMessage = "You must select at least one "+ models.VocabularySingular; return View("AddCompetencies", models); } if (model.SelectedCompetencyIds != null) diff --git a/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/AddCompetenciesViewFormData.cs b/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/AddCompetenciesViewFormData.cs index 07516407bf..0e6d2ed887 100644 --- a/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/AddCompetenciesViewFormData.cs +++ b/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/AddCompetenciesViewFormData.cs @@ -1,11 +1,8 @@ -using System.ComponentModel.DataAnnotations; - -namespace DigitalLearningSolutions.Web.ViewModels.CompetencyAssessments +namespace DigitalLearningSolutions.Web.ViewModels.CompetencyAssessments { public class AddCompetenciesFormData { public int ID { get; set; } - [Required(ErrorMessage = "Select at least one competency")] public int[] SelectedCompetencyIds { get; set; } public int FrameworkId { get; set; } } diff --git a/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/AddCompetenciesViewModel.cs b/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/AddCompetenciesViewModel.cs index 24433fe494..c1699ef52a 100644 --- a/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/AddCompetenciesViewModel.cs +++ b/DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/AddCompetenciesViewModel.cs @@ -28,7 +28,7 @@ public AddCompetenciesViewModel(CompetencyAssessmentBase competencyAssessmentBas public string VocabularyPlural { get; set; } public IEnumerable GroupedCompetencies { get; set; } public IEnumerable UngroupedCompetencies { get; set; } - [Required(ErrorMessage = "Select at least one competency")] + [Required] public int[] SelectedCompetencyIds { get; set; } public int FrameworkId { get; set; } public string? FrameworkName { get; set; } diff --git a/DigitalLearningSolutions.Web/Views/CompetencyAssessments/AddCompetencies.cshtml b/DigitalLearningSolutions.Web/Views/CompetencyAssessments/AddCompetencies.cshtml index 30a10c2ef8..89cea71d72 100644 --- a/DigitalLearningSolutions.Web/Views/CompetencyAssessments/AddCompetencies.cshtml +++ b/DigitalLearningSolutions.Web/Views/CompetencyAssessments/AddCompetencies.cshtml @@ -4,6 +4,8 @@ ViewData["Title"] = $"Add {@Model.VocabularyPlural.ToLower()} to self-assessment"; ViewData["Application"] = "Framework service"; var errorHasOccurred = !ViewData.ModelState.IsValid; + var noSelection = Model.SelectedCompetencyIds == null || !Model.SelectedCompetencyIds.Any(); + var isFirst = true; } @section NavMenuItems { @@ -40,6 +42,11 @@ Add @Model.VocabularyPlural.ToLower() to assessment +
    + + @ViewBag.RequiredCheckboxMessage + +
    @if (Model.GroupedCompetencies.Count() > 0) { @foreach (var competencyGroup in Model.GroupedCompetencies) @@ -62,8 +69,18 @@
    @foreach (var competency in competencyGroup.FrameworkCompetencies) { + var shouldAutofocus = noSelection && isFirst; + isFirst = false;
    - +