Skip to content

Commit 3e92629

Browse files
committed
TD-5307 Implements adding of linked frameworks and updating of task status
1 parent 376f95b commit 3e92629

File tree

9 files changed

+125
-40
lines changed

9 files changed

+125
-40
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace DigitalLearningSolutions.Data.Migrations
2+
{
3+
using FluentMigrator;
4+
[Migration(202504241517)]
5+
public class AddFieldIsPrimaryToSelfAssessmentFrameworksTable : AutoReversingMigration
6+
{
7+
public override void Up()
8+
{
9+
Alter.Table("SelfAssessmentFrameworks").AddColumn("IsPrimary").AsBoolean().NotNullable().WithDefaultValue(1);
10+
}
11+
}
12+
}

DigitalLearningSolutions.Data/DataServices/CompetencyAssessmentDataService.cs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ int categoryId
4646
bool UpdateBrandingTaskStatus(int assessmentId, bool taskStatus);
4747
bool UpdateVocabularyTaskStatus(int assessmentId, bool taskStatus);
4848
bool UpdateRoleProfileLinksTaskStatus(int assessmentId, bool taskStatus);
49+
bool UpdateFrameworkLinksTaskStatus(int assessmentId, bool taskStatus);
4950
//INSERT DATA
5051
int InsertCompetencyAssessment(int adminId, int centreId, string competencyAssessmentName);
5152
bool InsertSelfAssessmentFramework(int adminId, int selfAssessmentId, int frameworkId);
@@ -326,12 +327,16 @@ public bool UpdateCompetencyAssessmentVocabulary(int competencyAssessmentId, int
326327

327328
public bool InsertSelfAssessmentFramework(int adminId, int selfAssessmentId, int frameworkId)
328329
{
330+
bool isPrimary = Convert.ToInt32(connection.ExecuteScalar(
331+
@"SELECT Count(1) FROM SelfAssessmentFrameworks
332+
WHERE SelfAssessmentId = @selfAssessmentId AND IsPrimary = 1", new { selfAssessmentId })) == 0;
333+
329334
var numberOfAffectedRows = connection.Execute(
330-
@"INSERT INTO SelfAssessmentFrameworks (SelfAssessmentId, FrameworkId, CreatedByAdminId)
331-
SELECT @selfAssessmentId, @frameworkId, @adminId
335+
@"INSERT INTO SelfAssessmentFrameworks (SelfAssessmentId, FrameworkId, CreatedByAdminId, IsPrimary)
336+
SELECT @selfAssessmentId, @frameworkId, @adminId, @isPrimary
332337
WHERE NOT EXISTS (SELECT 1 FROM SelfAssessmentFrameworks WHERE SelfAssessmentId = @selfAssessmentId AND FrameworkId = @frameworkId)"
333338
,
334-
new { adminId, selfAssessmentId, frameworkId }
339+
new { adminId, selfAssessmentId, frameworkId, isPrimary }
335340
);
336341
if (numberOfAffectedRows < 1)
337342
{
@@ -477,9 +482,28 @@ public int[] GetLinkedFrameworkIds(int assessmentId)
477482
return [.. connection.Query<int>(
478483
@"SELECT FrameworkId
479484
FROM SelfAssessmentFrameworks
480-
WHERE (SelfAssessmentId = @assessmentId) AND (RemovedDate IS NULL)",
485+
WHERE (SelfAssessmentId = @assessmentId) AND (RemovedDate IS NULL)
486+
ORDER BY CAST(IsPrimary AS Int) DESC, ID",
481487
new { assessmentId }
482488
)];
483489
}
490+
491+
public bool UpdateFrameworkLinksTaskStatus(int assessmentId, bool taskStatus)
492+
{
493+
var numberOfAffectedRows = connection.Execute(
494+
@"UPDATE SelfAssessmentTaskStatus SET FrameworkLinksTaskStatus = @taskStatus
495+
WHERE SelfAssessmentId = @assessmentId",
496+
new { assessmentId, taskStatus }
497+
);
498+
if (numberOfAffectedRows < 1)
499+
{
500+
logger.LogWarning(
501+
"Not updating FrameworkLinksTaskStatus as db update failed. " +
502+
$"assessmentId: {assessmentId}, taskStatus: {taskStatus}"
503+
);
504+
return false;
505+
}
506+
return true;
507+
}
484508
}
485509
}

DigitalLearningSolutions.Web/Controllers/CompetencyAssessmentsController/CompetencyAssessments.cs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -389,8 +389,8 @@ public IActionResult SaveVocabulary(EditVocabularyViewModel model)
389389
competencyAssessmentService.UpdateVocabularyTaskStatus(model.ID, model.TaskStatus ?? false);
390390
return RedirectToAction("ManageCompetencyAssessment", new { competencyAssessmentId = model.ID });
391391
}
392-
[Route("/CompetencyAssessments/{competencyAssessmentId}/Frameworks/")]
393-
public IActionResult SelectFrameworkSources(int competencyAssessmentId)
392+
[Route("/CompetencyAssessments/{competencyAssessmentId}/Frameworks/{actionName}")]
393+
public IActionResult SelectFrameworkSources(int competencyAssessmentId, string actionName)
394394
{
395395
var adminId = GetAdminID();
396396
var frameworks = frameworkService.GetAllFrameworks(adminId);
@@ -406,12 +406,12 @@ public IActionResult SelectFrameworkSources(int competencyAssessmentId)
406406
}
407407
var selectedFrameworks = competencyAssessmentService.GetLinkedFrameworkIds(competencyAssessmentId);
408408
var competencyAssessmentTaskStatus = competencyAssessmentService.GetCompetencyAssessmentTaskStatus(competencyAssessmentId, null);
409-
var model = new SelectFrameworkSourcesViewModel(competencyAssessmentBase, frameworks, selectedFrameworks, competencyAssessmentTaskStatus.FrameworkLinksTaskStatus);
409+
var model = new SelectFrameworkSourcesViewModel(competencyAssessmentBase, frameworks, selectedFrameworks, competencyAssessmentTaskStatus.FrameworkLinksTaskStatus, actionName);
410410
return View(model);
411411
}
412412
[HttpPost]
413-
[Route("/CompetencyAssessments/{competencyAssessmentId}/Frameworks/")]
414-
public IActionResult SelectFrameworkSources(SelectFrameworkSourcesFormData model)
413+
[Route("/CompetencyAssessments/{competencyAssessmentId}/Frameworks/{actionName}")]
414+
public IActionResult SelectFrameworkSources(SelectFrameworkSourcesFormData model, string actionName)
415415
{
416416
var adminId = GetAdminID();
417417
var competencyAssessmentId = model.CompetencyAssessmentId;
@@ -430,12 +430,19 @@ public IActionResult SelectFrameworkSources(SelectFrameworkSourcesFormData model
430430
return StatusCode(403);
431431
}
432432
var selectedFrameworks = competencyAssessmentService.GetLinkedFrameworkIds(competencyAssessmentId);
433-
var competencyAssessmentTaskStatus = competencyAssessmentService.GetCompetencyAssessmentTaskStatus(competencyAssessmentId, null);
434-
var viewModel = new SelectFrameworkSourcesViewModel(competencyAssessmentBase, frameworks, selectedFrameworks, competencyAssessmentTaskStatus.FrameworkLinksTaskStatus);
433+
var viewModel = new SelectFrameworkSourcesViewModel(competencyAssessmentBase, frameworks, selectedFrameworks, model.TaskStatus, model.ActionName);
435434
return View("SelectFrameworkSources", viewModel);
436435
}
437-
competencyAssessmentService.InsertSelfAssessmentFramework(adminId, competencyAssessmentId, model.FrameworkId);
438-
return RedirectToAction("SelectFrameworkSources", new { competencyAssessmentId });
436+
if(actionName == "AddFramework")
437+
{
438+
competencyAssessmentService.InsertSelfAssessmentFramework(adminId, competencyAssessmentId, model.FrameworkId);
439+
return RedirectToAction("SelectFrameworkSources", new { competencyAssessmentId, actionName = "Summary" });
440+
}
441+
else
442+
{
443+
competencyAssessmentService.UpdateFrameworkLinksTaskStatus(model.CompetencyAssessmentId, model.TaskStatus ?? false);
444+
return RedirectToAction("ManageCompetencyAssessment", new { competencyAssessmentId = model.CompetencyAssessmentId });
445+
}
439446
}
440447
}
441448
}

DigitalLearningSolutions.Web/Services/CompetencyAssessmentService.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,13 @@ public interface ICompetencyAssessmentService
3434
bool UpdateCompetencyAssessmentVocabulary(int assessmentId, int adminId, string vocabulary);
3535
bool UpdateVocabularyTaskStatus(int assessmentId, bool taskStatus);
3636
bool UpdateRoleProfileLinksTaskStatus(int assessmentId, bool taskStatus);
37+
bool UpdateFrameworkLinksTaskStatus(int assessmentId, bool taskStatus);
3738

3839
//INSERT DATA
3940
int InsertCompetencyAssessment(int adminId, int centreId, string competencyAssessmentName, int? frameworkId);
4041
bool InsertSelfAssessmentFramework(int adminId, int assessmentId, int frameworkId);
4142
int[] GetLinkedFrameworkIds(int assessmentId);
43+
4244
}
4345
public class CompetencyAssessmentService : ICompetencyAssessmentService
4446
{
@@ -83,7 +85,7 @@ public int InsertCompetencyAssessment(int adminId, int centreId, string competen
8385
{
8486
competencyAssessmentDataService.InsertSelfAssessmentFramework(adminId, assessmentId, framework.ID);
8587
competencyAssessmentDataService.UpdateCompetencyAssessmentDescription(adminId, assessmentId, framework.Description);
86-
competencyAssessmentDataService.UpdateCompetencyAssessmentBranding(assessmentId, (int)framework.BrandID, (int)framework.CategoryID, adminId);
88+
competencyAssessmentDataService.UpdateCompetencyAssessmentBranding(assessmentId, adminId, (int)framework.BrandID, (int)framework.CategoryID);
8789
competencyAssessmentDataService.UpdateCompetencyAssessmentVocabulary(assessmentId, adminId, framework.Vocabulary);
8890
}
8991
}
@@ -161,5 +163,10 @@ public bool InsertSelfAssessmentFramework(int adminId, int assessmentId, int fra
161163
{
162164
return competencyAssessmentDataService.InsertSelfAssessmentFramework(adminId, assessmentId, frameworkId);
163165
}
166+
167+
public bool UpdateFrameworkLinksTaskStatus(int assessmentId, bool taskStatus)
168+
{
169+
return competencyAssessmentDataService.UpdateFrameworkLinksTaskStatus(assessmentId, taskStatus);
170+
}
164171
}
165172
}

DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/SelectFrameworkSourcesFormData.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,7 @@ public class SelectFrameworkSourcesFormData
66
[Required]
77
public int FrameworkId { get; set; }
88
public int CompetencyAssessmentId { get; set; }
9+
public bool? TaskStatus { get; set; }
10+
public string? ActionName { get; set; }
911
}
1012
}

DigitalLearningSolutions.Web/ViewModels/CompetencyAssessments/SelectFrameworkSourcesViewModel.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,22 @@ namespace DigitalLearningSolutions.Web.ViewModels.CompetencyAssessments
88
public class SelectFrameworkSourcesViewModel : SelectFrameworkSourcesFormData
99
{
1010
public SelectFrameworkSourcesViewModel() { }
11-
public SelectFrameworkSourcesViewModel(CompetencyAssessmentBase competencyAssessmentBase, IEnumerable<BrandedFramework> frameworks, int[] selectedFrameworksIds, bool? taskStatus)
11+
public SelectFrameworkSourcesViewModel(CompetencyAssessmentBase competencyAssessmentBase, IEnumerable<BrandedFramework> frameworks, int[] selectedFrameworksIds, bool? taskStatus, string actionName)
1212
{
1313
ID = competencyAssessmentBase.ID;
1414
CompetencyAssessmentName = competencyAssessmentBase.CompetencyAssessmentName;
1515
UserRole = competencyAssessmentBase.UserRole;
1616
TaskStatus = taskStatus;
1717
Frameworks = frameworks.OrderBy(f => f.FrameworkName);
18-
SelectedFrameworks = [.. frameworks.Where(f => selectedFrameworksIds.Contains(f.ID))];
18+
SelectedFrameworks = [.. selectedFrameworksIds.Select(id => frameworks.First(f => f.ID == id))];
19+
ActionName = actionName;
1920
}
2021
public IEnumerable<BrandedFramework> Frameworks { get; set; }
2122
public IEnumerable<BrandedFramework> SelectedFrameworks { get; set; }
2223
public IEnumerable<NRPRoles> Roles { get; set; }
2324
public int ID { get; set; }
2425
public string CompetencyAssessmentName { get; set; }
2526
public int UserRole { get; set; }
26-
public bool? TaskStatus { get; set; }
2727
public string? GroupName { get; set; }
2828
public string? SubGroupName { get; set; }
2929
public string? RoleName { get; set; }

DigitalLearningSolutions.Web/Views/CompetencyAssessments/EditRoleProfileLinks.cshtml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@
119119
<input type="hidden" asp-for="RoleName" />
120120
<input type="hidden" asp-for="SubGroupName" />
121121
<input type="hidden" asp-for="GroupName" />
122+
<input type="hidden" asp-for="TaskStatus" />
122123
<button class="nhsuk-button" type="submit">
123124
Submit
124125
</button>
@@ -170,6 +171,7 @@ else if (Model.ActionName == "EditSubGroup" && Model.ProfessionalGroupId != null
170171
<input type="hidden" asp-for="RoleName" />
171172
<input type="hidden" asp-for="SubGroupName" />
172173
<input type="hidden" asp-for="GroupName" />
174+
<input type="hidden" asp-for="TaskStatus" />
173175
<button class="nhsuk-button" type="submit">
174176
Submit
175177
</button>
@@ -220,6 +222,7 @@ else if (Model.ActionName == "EditRole" && Model.SubGroupId != null)
220222
<input type="hidden" asp-for="RoleName" />
221223
<input type="hidden" asp-for="SubGroupName" />
222224
<input type="hidden" asp-for="GroupName" />
225+
<input type="hidden" asp-for="TaskStatus" />
223226
<button class="nhsuk-button" type="submit">
224227
Submit
225228
</button>

DigitalLearningSolutions.Web/Views/CompetencyAssessments/ManageCompetencyAssessment.cshtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
<ul class="nhsuk-task-list nhsuk-u-margin-bottom-0">
5858
<li class="nhsuk-task-list__item nhsuk-task-list__item--with-link">
5959
<div class="nhsuk-task-list__name-and-hint" aria-describedby="select-frameworks-status">
60-
<a class="nhsuk-link nhsuk-task-list__link" asp-action="SelectFrameworkSources" asp-route-competencyAssessmentId="@ViewContext.RouteData.Values["competencyAssessmentId"]">
60+
<a class="nhsuk-link nhsuk-task-list__link" asp-action="SelectFrameworkSources" asp-route-actionName="@(Model.CompetencyAssessmentTaskStatus.FrameworkLinksTaskStatus == null ? "AddFramework" : "Summary" )" asp-route-competencyAssessmentId="@ViewContext.RouteData.Values["competencyAssessmentId"]">
6161
Select competency framework sources
6262
</a>
6363
</div>

DigitalLearningSolutions.Web/Views/CompetencyAssessments/SelectFrameworkSources.cshtml

Lines changed: 52 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<link rel="stylesheet" href="@Url.Content("~/css/jodit.css")" asp-append-version="true">
88
<link rel="stylesheet" href="@Url.Content("~/css/frameworks/frameworksShared.css")" asp-append-version="true">
99
@section NavMenuItems {
10-
<partial name="~/Views/Frameworks/Shared/_NavMenuItems.cshtml" />
10+
<partial name="~/Views/Frameworks/Shared/_NavMenuItems.cshtml" />
1111
}
1212

1313
@section NavBreadcrumbs {
@@ -61,24 +61,54 @@
6161
}
6262
</dl>
6363
}
64-
<form method="post">
65-
<div class="nhsuk-form-group">
66-
<fieldset class="nhsuk-fieldset">
67-
<legend class="nhsuk-fieldset__legend nhsuk-fieldset__legend--l">
68-
<h1 class="nhsuk-fieldset__heading">Add a framework source</h1>
69-
</legend>
70-
<div class="nhsuk-radios">
71-
@foreach(var framework in Model.Frameworks)
72-
{
73-
<div class="nhsuk-radios__item">
74-
<input class="nhsuk-radios__input" type="radio" id="[email protected]" asp-for="FrameworkId" value="@framework.ID" />
75-
<label class="nhsuk-label nhsuk-radios__label" for="[email protected]">
76-
@framework.FrameworkName
77-
</label>
78-
</div>
79-
}
80-
</div>
81-
</fieldset>
82-
</div>
83-
<button class="nhsuk-button" type="submit">Add</button>
84-
</form>
64+
@if (Model.ActionName == "AddFramework")
65+
{
66+
<form method="post">
67+
<div class="nhsuk-form-group">
68+
<fieldset class="nhsuk-fieldset">
69+
<legend class="nhsuk-fieldset__legend nhsuk-fieldset__legend--l">
70+
<h1 class="nhsuk-fieldset__heading">Add a framework source</h1>
71+
</legend>
72+
<div class="nhsuk-radios">
73+
@foreach (var framework in Model.Frameworks)
74+
{
75+
<div class="nhsuk-radios__item">
76+
<input class="nhsuk-radios__input" type="radio" id="[email protected]" asp-for="FrameworkId" value="@framework.ID" />
77+
<label class="nhsuk-label nhsuk-radios__label" for="[email protected]">
78+
@framework.FrameworkName
79+
</label>
80+
</div>
81+
}
82+
</div>
83+
</fieldset>
84+
</div>
85+
<input type="hidden" asp-for="ActionName" />
86+
<input type="hidden" asp-for="TaskStatus" />
87+
<button class="nhsuk-button" type="submit">Add</button>
88+
</form>
89+
}
90+
@if (Model.ActionName == "Summary")
91+
{
92+
<a class="nhsuk-button nhsuk-button--secondary" role="button" asp-action="SelectFrameworkSources" asp-route-actionName="AddFramework" asp-route-competencyAssessmentId="@ViewContext.RouteData.Values["competencyAssessmentId"]">
93+
Add framework
94+
</a>
95+
<form method="post">
96+
<nhs-form-group>
97+
<vc:single-checkbox asp-for="@nameof(Model.TaskStatus)" label="Mark this task as complete" hint-text="You will still be able to make changes after marking this task as complete."></vc:single-checkbox>
98+
</nhs-form-group>
99+
<input type="hidden" asp-for="FrameworkId" value="0" />
100+
<input type="hidden" asp-for="ActionName" />
101+
<input type="hidden" asp-for="ID" />
102+
<button class="nhsuk-button" type="submit">
103+
Save
104+
</button>
105+
</form>
106+
}
107+
<div class="nhsuk-back-link">
108+
<a class="nhsuk-back-link__link" asp-action="ManageCompetencyAssessment" asp-route-competencyAssessmentId="@Model.ID">
109+
<svg class="nhsuk-icon nhsuk-icon__chevron-left" focusable='false' xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
110+
<path d="M13.41 12l5.3-5.29a1 1 0 1 0-1.42-1.42L12 10.59l-5.29-5.3a1 1 0 0 0-1.42 1.42l5.3 5.29-5.3 5.29a1 1 0 0 0 0 1.42 1 1 0 0 0 1.42 0l5.29-5.3 5.29 5.3a1 1 0 0 0 1.42 0 1 1 0 0 0 0-1.42z"></path>
111+
</svg>
112+
Cancel
113+
</a>
114+
</div>

0 commit comments

Comments
 (0)