Skip to content
Merged
Changes from 1 commit
Commits
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
73 changes: 58 additions & 15 deletions DigitalLearningSolutions.Web/Helpers/CompetencyFilterHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public static IEnumerable<Competency> FilterCompetencies(IEnumerable<Competency>
var searchText = search.SearchText?.Trim() ?? string.Empty;
var filters = search.AppliedFilters?.Select(f => int.Parse(f.FilterValue)) ?? Enumerable.Empty<int>();
search.CompetencyFlags = competencyFlags.ToList();
ApplyResponseStatusFilters(ref filteredCompetencies, filters, searchText);
ResponseStatusFilters(ref filteredCompetencies, filters, searchText);
UpdateRequirementsFilterDropdownOptionsVisibility(search, filteredCompetencies);
ApplyRequirementsFilters(ref filteredCompetencies, filters);

Expand All @@ -30,6 +30,48 @@ public static IEnumerable<Competency> FilterCompetencies(IEnumerable<Competency>
return filteredCompetencies;
}

public static void ResponseStatusFilters(ref IEnumerable<Competency> competencies, IEnumerable<int> filters, string searchText = "")
{
var appliedResponseStatusFilters = filters.Where(IsResponseStatusFilter).ToList();

if (!appliedResponseStatusFilters.Any() && string.IsNullOrWhiteSpace(searchText))
{
return;
}

// Break search text into words
var wordsInSearchText = searchText?
.Split(' ', StringSplitOptions.RemoveEmptyEntries)
?? Array.Empty<string>();

bool MatchesSearch(Competency c) =>
wordsInSearchText.Length == 0
|| wordsInSearchText.All(w =>
(c.CompetencyGroup?.Contains(w, StringComparison.CurrentCultureIgnoreCase) ?? false)
|| (c.Description?.Contains(w, StringComparison.CurrentCultureIgnoreCase) ?? false)
|| (c.Name?.Contains(w, StringComparison.CurrentCultureIgnoreCase) ?? false));

// Define reusable filter checks
var filterChecks = new Dictionary<SelfAssessmentCompetencyFilter, Func<Competency, bool>>
{
[SelfAssessmentCompetencyFilter.RequiresSelfAssessment] = c => c.AssessmentQuestions.Any(q => q.ResultId == null),
[SelfAssessmentCompetencyFilter.SelfAssessed] = c => c.AssessmentQuestions.Any(q => q.ResultId != null && q.Requested == null && q.SignedOff == null),
[SelfAssessmentCompetencyFilter.ConfirmationRequested] = c => c.AssessmentQuestions.Any(q => q.Verified == null && q.Requested != null),
[SelfAssessmentCompetencyFilter.ConfirmationRejected] = c => c.AssessmentQuestions.Any(q => q.Verified.HasValue && q.SignedOff != true),
[SelfAssessmentCompetencyFilter.Verified] = c => c.AssessmentQuestions.Any(q => q.Verified.HasValue && q.SignedOff == true),
[SelfAssessmentCompetencyFilter.AwaitingConfirmation] = c => c.AssessmentQuestions.Any(q => q.Verified == null && q.Requested != null && q.UserIsVerifier == true),
[SelfAssessmentCompetencyFilter.PendingConfirmation] = c => c.AssessmentQuestions.Any(q => q.ResultId != null && q.Verified == null && q.Requested != null && q.UserIsVerifier == false),
[SelfAssessmentCompetencyFilter.Optional] = c => c.Optional
};

// Require ALL applied filters to match
bool MatchesFilters(Competency c) =>
!appliedResponseStatusFilters.Any()
|| appliedResponseStatusFilters.All(f => filterChecks[(SelfAssessmentCompetencyFilter)f](c));

// Final filtering
competencies = competencies.Where(c => MatchesSearch(c) && MatchesFilters(c));
}
private static void ApplyResponseStatusFilters(ref IEnumerable<Competency> competencies, IEnumerable<int> filters, string searchText = "")
{
var filteredCompetencies = competencies;
Expand All @@ -38,20 +80,21 @@ private static void ApplyResponseStatusFilters(ref IEnumerable<Competency> compe
if (appliedResponseStatusFilters.Any() || searchText.Length > 0)
{
var wordsInSearchText = searchText.Split().Where(w => w != string.Empty);
filteredCompetencies = from c in competencies
let searchTextMatchesGroup = wordsInSearchText.All(w => c.CompetencyGroup?.Contains(w, StringComparison.CurrentCultureIgnoreCase) ?? false)
let searchTextMatchesCompetencyDescription = wordsInSearchText.All(w => c.Description?.Contains(w, StringComparison.CurrentCultureIgnoreCase) ?? false)
let searchTextMatchesCompetencyName = wordsInSearchText.All(w => c.Name?.Contains(w, StringComparison.CurrentCultureIgnoreCase) ?? false)
let responseStatusFilterMatchesAll =
(filters.Contains((int)SelfAssessmentCompetencyFilter.RequiresSelfAssessment) && c.AssessmentQuestions.Any(q => q.ResultId == null))
|| (filters.Contains((int)SelfAssessmentCompetencyFilter.SelfAssessed) && c.AssessmentQuestions.Any(q => q.ResultId != null && q.Requested == null && q.SignedOff == null))
|| (filters.Contains((int)SelfAssessmentCompetencyFilter.ConfirmationRequested) && c.AssessmentQuestions.Any(q => q.Verified == null && q.Requested != null))
|| (filters.Contains((int)SelfAssessmentCompetencyFilter.ConfirmationRejected) && c.AssessmentQuestions.Any(q => q.Verified.HasValue && q.SignedOff != true))
|| (filters.Contains((int)SelfAssessmentCompetencyFilter.Verified) && c.AssessmentQuestions.Any(q => q.Verified.HasValue && q.SignedOff == true))
|| (filters.Contains((int)SelfAssessmentCompetencyFilter.Optional) && c.Optional)
where (wordsInSearchText.Count() == 0 || searchTextMatchesGroup || searchTextMatchesCompetencyDescription || searchTextMatchesCompetencyName)
&& (!appliedResponseStatusFilters.Any() || responseStatusFilterMatchesAll)
select c;
filteredCompetencies = from c in competencies
let searchTextMatchesGroup = wordsInSearchText.All(w => c.CompetencyGroup?.Contains(w, StringComparison.CurrentCultureIgnoreCase) ?? false)
let searchTextMatchesCompetencyDescription = wordsInSearchText.All(w => c.Description?.Contains(w, StringComparison.CurrentCultureIgnoreCase) ?? false)
let searchTextMatchesCompetencyName = wordsInSearchText.All(w => c.Name?.Contains(w, StringComparison.CurrentCultureIgnoreCase) ?? false)
let responseStatusFilterMatchesAll =
(filters.Contains((int)SelfAssessmentCompetencyFilter.RequiresSelfAssessment) && c.AssessmentQuestions.Any(q => q.ResultId == null))
|| (filters.Contains((int)SelfAssessmentCompetencyFilter.SelfAssessed) && c.AssessmentQuestions.Any(q => q.ResultId != null && q.Requested == null && q.SignedOff == null))
|| (filters.Contains((int)SelfAssessmentCompetencyFilter.ConfirmationRequested) && c.AssessmentQuestions.Any(q => q.Verified == null && q.Requested != null))
|| (filters.Contains((int)SelfAssessmentCompetencyFilter.ConfirmationRejected) && c.AssessmentQuestions.Any(q => q.Verified.HasValue && q.SignedOff != true))
|| (filters.Contains((int)SelfAssessmentCompetencyFilter.Verified) && c.AssessmentQuestions.Any(q => q.Verified.HasValue && q.SignedOff == true))
|| (filters.Contains((int)SelfAssessmentCompetencyFilter.Optional) && c.Optional)
where (wordsInSearchText.Count() == 0 || searchTextMatchesGroup || searchTextMatchesCompetencyDescription || searchTextMatchesCompetencyName)
&& (!appliedResponseStatusFilters.Any() || responseStatusFilterMatchesAll)
select c;

}
competencies = filteredCompetencies;
}
Expand Down
Loading