Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
c3e32c6
added assessment history(needs further changes) and updated ragbar to…
vks333 May 8, 2025
c0761c4
replaced popover with tooltip, separation of concerns, RagComponent d…
vks333 May 12, 2025
eef6369
converted RagBar as component, updated pages where it was being used,…
vks333 May 14, 2025
f756304
added assessment history(needs further changes) and updated ragbar to…
vks333 May 8, 2025
92d5733
converted RagBar as component, updated pages where it was being used,…
vks333 May 14, 2025
2de9a63
tidied up, removed comments
vks333 May 15, 2025
9fbc846
ignoring unmapped LocationName property, as it was likely causing tes…
vks333 May 16, 2025
e034ff7
added Rag History tab on Assessment tab using assessment history conv…
vks333 May 20, 2025
ceded37
added assessment history(needs further changes) and updated ragbar to…
vks333 May 8, 2025
9b77c37
replaced popover with tooltip, separation of concerns, RagComponent d…
vks333 May 12, 2025
0d3c72d
converted RagBar as component, updated pages where it was being used,…
vks333 May 14, 2025
429be8d
added assessment history(needs further changes) and updated ragbar to…
vks333 May 8, 2025
fa06a0f
converted RagBar as component, updated pages where it was being used,…
vks333 May 14, 2025
192ec07
tidied up, removed comments
vks333 May 15, 2025
48c078b
ignoring unmapped LocationName property, as it was likely causing tes…
vks333 May 16, 2025
f2caaf8
added Rag History tab on Assessment tab using assessment history conv…
vks333 May 20, 2025
8b4141a
resolved merge issues
vks333 May 22, 2025
9914c08
removed comments
vks333 May 22, 2025
c6e8334
Code review amends
carlsixsmith-moj May 23, 2025
8197d2c
CFODEV-1184: added is loading flag and removed call to participant, …
PaulCooperWorkJustice May 27, 2025
da12d4d
Merge remote-tracking branch 'origin/develop' into CFODEV-1184
PaulCooperWorkJustice May 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,20 @@ public class ParticipantAssessmentDto
public required string ParticipantId { get; set; }
public required PathwayScore[] PathwayScore { get; set; }
public required DateTime CreatedDate { get; set; }
public DateTime? Completed { get; set; }
public int LocationId { get; set; }
public string LocationName { get; set; } = string.Empty;

private class Mapping : Profile
{
public Mapping()
{
CreateMap<ParticipantAssessment, ParticipantAssessmentDto>()
.ForMember(p => p.CreatedDate, options => options.MapFrom(source => source.Created))
.ForMember(p => p.PathwayScore, options => options.MapFrom(source => source.Scores));
.ForMember(p => p.PathwayScore, options => options.MapFrom(source => source.Scores))
.ForMember(p => p.Completed, options => options.MapFrom(source => source.Completed))
.ForMember(p => p.LocationId, options => options.MapFrom(source => source.LocationId))
.ForMember(p => p.LocationName, options => options.Ignore());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Cfo.Cats.Application.Common.Validators;
using Cfo.Cats.Application.Features.Assessments.DTOs;
using Cfo.Cats.Application.SecurityConstants;
using Cfo.Cats.Domain.ValueObjects;

namespace Cfo.Cats.Application.Features.Assessments.Queries;

Expand All @@ -27,13 +28,22 @@ public Handler(IUnitOfWork unitOfWork, IMapper mapper)

public async Task<Result<IEnumerable<ParticipantAssessmentDto>>> Handle(Query request, CancellationToken cancellationToken)
{
var query = _unitOfWork.DbContext.ParticipantAssessments
.Include(pa => pa.Scores)
.Where(pa => pa.ParticipantId == request.ParticipantId)
.AsNoTracking()
.ProjectTo<ParticipantAssessmentDto>(_mapper.ConfigurationProvider);
var query = (from pa in _unitOfWork.DbContext.ParticipantAssessments
join l in _unitOfWork.DbContext.Locations on pa.LocationId equals l.Id
where pa.ParticipantId == request.ParticipantId
select new ParticipantAssessmentDto
{
ParticipantId = pa.ParticipantId,
CreatedDate = pa.Created!.Value,
Completed = pa.Completed,
LocationId = pa.LocationId,
LocationName = l.Name, // Directly access LocationName
PathwayScore = pa.Scores.Select(s => new PathwayScore(s.Pathway, s.Score)).ToArray()
})
.AsNoTracking();

var result = await query.ToListAsync(cancellationToken);

return Result<IEnumerable<ParticipantAssessmentDto>>.Success(result);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
@using Cfo.Cats.Application.Features.Assessments.DTOs
@using Humanizer

@inherits CatsComponentBase

@if (ParticipantAssessments.Any() == true)
{
<MudDataGrid Items="@ParticipantAssessments" Striped="true" >
<Columns>

<TemplateColumn Title="Completed" Sortable="true" SortBy="x => x.Completed">
<CellTemplate>
<MudStack>
@if(context.Item.Completed.HasValue)
{
<MudText Typo="Typo.body2">@context.Item.Completed.Value.ToShortDateString()</MudText>
if (ConsentDate.HasValue)
{
<MudText Typo="Typo.body2">@($"{(context.Item.Completed.Value - ConsentDate.Value.ToDateTime(TimeOnly.MinValue)).Humanize()} (since consent)")</MudText>
}
}
</MudStack>
</CellTemplate>
</TemplateColumn>

<PropertyColumn Property="x => x.LocationName" Title="Location">
</PropertyColumn>

<TemplateColumn Title="RAG Bar">
<CellTemplate>
<Cfo.Cats.Server.UI.Pages.Participants.Components.RagBar Model="@context.Item" />
</CellTemplate>
</TemplateColumn>

</Columns>
<PagerContent>
<MudDataGridPager T="ParticipantAssessmentDto" />
</PagerContent>
</MudDataGrid>
}
else
{
<MudAlert Severity="Severity.Info">
No assessment history found
</MudAlert>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Cfo.Cats.Application.Features.Assessments.DTOs;

namespace Cfo.Cats.Server.UI.Pages.Assessment.AssessmentComponents;

public partial class AssessmentHistory
{
[Parameter, EditorRequired]
public IEnumerable<ParticipantAssessmentDto> ParticipantAssessments { get; set; } = Enumerable.Empty<ParticipantAssessmentDto>();
[Parameter, EditorRequired]
public DateOnly? ConsentDate { get; set; }
}
192 changes: 78 additions & 114 deletions src/Server.UI/Pages/Participants/Components/CaseAssessment.razor
Original file line number Diff line number Diff line change
@@ -1,133 +1,97 @@
@using Cfo.Cats.Application.Features.Assessments.DTOs
@using Cfo.Cats.Application.Features.Assessments.Queries
@using Cfo.Cats.Domain.Common.Enums

@inherits CatsComponentBase

<style>
.readonly-toggle {
pointer-events: none;
filter: grayscale(100%);
pointer-events: none;
filter: grayscale(100%);
}

.two-columns {
display: grid;
grid-template-columns: repeat(2, 1fr); /* Two columns */
gap: 10px; /* Adjust the gap between items as needed */
display: grid;
grid-template-columns: repeat(2, 1fr); /* Two columns */
gap: 10px; /* Adjust the gap between items as needed */
}

.toggle-item {
box-sizing: border-box; /* Ensure padding and borders are included in width/height */
padding: 10px; /* Add padding if needed */
justify-content: left !important;
box-sizing: border-box; /* Ensure padding and borders are included in width/height */
padding: 10px; /* Add padding if needed */
justify-content: left !important;
}

</style>

@if (_notFound)
{
<MudAlert>
<MudAlert Severity="Severity.Info" Variant="Variant.Outlined" Square="true" Class="my-2">No assessment found.</MudAlert>
</MudAlert>
}
<MudTabs Outlined="true" Border="true" Class="mt-2" >
<MudTabPanel Text="Latest">
<MudExpansionPanels MultiExpansion="true">


@if (_model is not null)
{
<MudExpansionPanels Class="pa-3 m-3" MultiExpansion="true">

@foreach (var pathway in _model.Pathways)
{
<MudExpansionPanel>
<TitleContent>
<div class="d-flex">
<MudIcon Icon="@pathway.Icon" Color="Color.Primary" class="mr-3"/>
<MudText>@pathway.Title</MudText>
</div>
</TitleContent>
<ChildContent>
<MudGrid Class="mb-4 px-10">

@foreach (var question in pathway.Questions())
{

<MudItem xs="4">
<Cfo.Cats.Server.UI.Pages.Assessment.AssessmentComponents.AssessmentQuestion Question="@question.Question" HelperText="@question.OtherInformation" />
</MudItem>

<MudItem xs="8">
@if (question is SingleChoiceQuestion atq)
{
<MudToggleGroup T="string" Class="readonly-toggle" SelectionMode="SelectionMode.SingleSelection" @bind-Value="@atq.Answer" CheckMark FixedContent Color="Color.Primary">
@foreach (var item in atq.Options)
{
<MudToggleItem Value="@item" Text="@item" />
}
</MudToggleGroup>

}

@if (question is MultipleChoiceQuestion amcq)
{
<MudToggleGroup T="string" Class="two-columns readonly-toggle" Vertical SelectionMode="SelectionMode.MultiSelection" @bind-Values="@amcq.Answers" CheckMark Color="Color.Primary" Outlined="false" Delimiters="false">
@foreach (var item in amcq.Options)
{
<MudToggleItem Class="toggle-item" Value="@item" Text="@item" UnselectedIcon="@Icons.Material.Filled.CheckBoxOutlineBlank" SelectedIcon="@Icons.Material.Filled.CheckBox" />
}
</MudToggleGroup>
}
</MudItem>
<MudDivider />
}
</MudGrid>
</ChildContent>
</MudExpansionPanel>
}

</MudExpansionPanels>
}



@code {

private Assessment? _model;
private bool _notFound = false;

[Parameter]
[EditorRequired]
public string ParticipantId { get; set; } = default!;

protected override async Task OnInitializedAsync()
{
if(_model is not null)
{
return;
}

try
{
var result = await GetNewMediator().Send(new GetAssessment.Query()
{
ParticipantId = ParticipantId
});

if(result.Succeeded)
@if(_loading)
{
_model = result.Data;
<Cfo.Cats.Server.UI.Pages.Dashboard.Components.LoadingCard Title="Assessments loading" />
}

}
finally
{
_notFound = _model is null;
}

}

protected override async Task OnAfterRenderAsync(bool firstRender)
{
await JS.InvokeVoidAsync("removeInlineStyle", ".two-columns");
}

}
else
{
@if (_model is null)
{
<MudAlert Severity="Severity.Info">
No assessment found
</MudAlert>
}
else
{
foreach (var pathway in _model.Pathways)
{
<MudExpansionPanel>
<TitleContent>
<div class="d-flex">
<MudIcon Icon="@pathway.Icon" Color="Color.Primary" class="mr-3" />
<MudText>@pathway.Title</MudText>
</div>
</TitleContent>
<ChildContent>
<MudGrid Class="mb-4 px-10">

@foreach (var question in pathway.Questions())
{
<MudItem xs="4">
<Cfo.Cats.Server.UI.Pages.Assessment.AssessmentComponents.AssessmentQuestion Question="@question.Question" HelperText="@question.OtherInformation" />
</MudItem>

<MudItem xs="8">
@if (question is SingleChoiceQuestion atq)
{
<MudToggleGroup T="string" Class="readonly-toggle" SelectionMode="SelectionMode.SingleSelection" @bind-Value="@atq.Answer" CheckMark FixedContent Color="Color.Primary">
@foreach (var item in atq.Options)
{
<MudToggleItem Value="@item" Text="@item" />
}
</MudToggleGroup>
}

@if (question is MultipleChoiceQuestion amcq)
{
<MudToggleGroup T="string" Class="two-columns readonly-toggle" Vertical SelectionMode="SelectionMode.MultiSelection" @bind-Values="@amcq.Answers" CheckMark Color="Color.Primary" Outlined="false" Delimiters="false">
@foreach (var item in amcq.Options)
{
<MudToggleItem Class="toggle-item" Value="@item" Text="@item" UnselectedIcon="@Icons.Material.Filled.CheckBoxOutlineBlank" SelectedIcon="@Icons.Material.Filled.CheckBox" />
}
</MudToggleGroup>
}
</MudItem>
<MudDivider />
}
</MudGrid>
</ChildContent>
</MudExpansionPanel>
}
}
}
</MudExpansionPanels>
</MudTabPanel>

<MudTabPanel Text="RAG History">
<Cfo.Cats.Server.UI.Pages.Assessment.AssessmentComponents.AssessmentHistory ParticipantAssessments="_participantAssessments" ConsentDate="ConsentDate" />
</MudTabPanel>

</MudTabs>
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using Cfo.Cats.Application.Features.Assessments.DTOs;
using Cfo.Cats.Application.Features.Assessments.Queries;
using Microsoft.JSInterop;

namespace Cfo.Cats.Server.UI.Pages.Participants.Components;

public partial class CaseAssessment
{
private Application.Features.Assessments.DTOs.Assessment? _model;
private IEnumerable<ParticipantAssessmentDto> _participantAssessments = Enumerable.Empty<ParticipantAssessmentDto>();

private bool _loading = true;

[Parameter]
[EditorRequired]
public string ParticipantId { get; set; } = default!;

[Parameter]
[EditorRequired]
public DateOnly? ConsentDate { get; set; }

protected override async Task OnInitializedAsync()
{
try
{
var result = await GetNewMediator().Send(new GetAssessment.Query()
{
ParticipantId = ParticipantId
});

if (result is { Succeeded: true, Data: not null })
{
_model = result.Data;
}

var query = new GetAssessmentScores.Query()
{
ParticipantId = ParticipantId
};

var assessmentHistoryResult = await GetNewMediator().Send(query);

if (assessmentHistoryResult is { Succeeded: true, Data: not null })
{
_participantAssessments = assessmentHistoryResult.Data
.Where(pa => pa.Completed.HasValue)
.OrderByDescending(pa => pa.CreatedDate);
}
}
finally
{
_loading = false;
}
}

protected override async Task OnAfterRenderAsync(bool firstRender)
{
await JS.InvokeVoidAsync("removeInlineStyle", ".two-columns");
}
}
Loading