diff --git a/DigitalLearningSolutions.Data/DataServices/CourseDataService.cs b/DigitalLearningSolutions.Data/DataServices/CourseDataService.cs index 9f0ab58aec..df086021b6 100644 --- a/DigitalLearningSolutions.Data/DataServices/CourseDataService.cs +++ b/DigitalLearningSolutions.Data/DataServices/CourseDataService.cs @@ -139,7 +139,7 @@ int EnrolOnActivitySelfAssessment(int selfAssessmentId, int candidateId, int sup public IEnumerable GetDelegateAssessmentStatisticsAtCentre(string searchString, int centreId, string categoryName, string isActive, int? categoryId); bool IsSelfEnrollmentAllowed(int customisationId); - Customisation? GetCourse(int customisationId); + Customisation? GetCourse(int? customisationId); } public class CourseDataService : ICourseDataService @@ -2024,7 +2024,7 @@ public bool IsSelfEnrollmentAllowed(int customisationId) return selfRegister > 0; } - public Customisation? GetCourse(int customisationId) + public Customisation? GetCourse(int? customisationId) { return connection.Query( @"SELECT CustomisationID diff --git a/DigitalLearningSolutions.Data/Helpers/FilteringHelper.cs b/DigitalLearningSolutions.Data/Helpers/FilteringHelper.cs index 4ea7ae9ebe..a806df3f5d 100644 --- a/DigitalLearningSolutions.Data/Helpers/FilteringHelper.cs +++ b/DigitalLearningSolutions.Data/Helpers/FilteringHelper.cs @@ -66,8 +66,7 @@ public static string BuildFilterValueString(string group, string propertyName, s ? defaultFilterValue : AddNewFilterToFilterString(existingFilterString, newFilterToAdd); } - - public static string? GetCategoryAndTopicFilterString( + public static string? GetCategoryAndTopicFilterString( string? categoryFilterString, string? topicFilterString ) @@ -168,7 +167,59 @@ public static string GetFilterValueForRegistrationPrompt(int promptNumber, strin : answer; return BuildFilterValueString(group, group.Split('(')[0], propertyValue); } + public static string? GetValidFilters(string existingFilterString, string newFilterToAdd, IEnumerable availableFilters, HttpRequest request, string cookieName) + { + var cookieValue = request.Cookies[cookieName]; + if (string.IsNullOrEmpty(cookieValue) || cookieValue == EmptyFiltersCookieValue) + { + return existingFilterString; + } + var existingFilters = cookieValue.Split(FilterSeparator); + var validFilterValues = availableFilters + .SelectMany(filter => filter.FilterOptions) + .Select(option => option.FilterValue) + .ToHashSet(); + + var filteredResults = existingFilters + .Where(entry => IsFilterInvalid(entry, validFilterValues)) + .ToList(); + var newCookieValue = string.Join(FilterSeparator, filteredResults); + if (string.IsNullOrEmpty(newCookieValue)) return null; + newCookieValue = AddNewFilterToFilterString(newCookieValue, newFilterToAdd); + return RemoveDuplicateFilters( newFilterToAdd, newCookieValue); + } + private static bool IsFilterInvalid(string filterEntry, HashSet validFilterValues) + { + if (validFilterValues.Contains(filterEntry)) return true; + return false; + } + public static string RemoveDuplicateFilters(string newFilterToAdd, string? existingFilterString) + { + if (string.IsNullOrEmpty(existingFilterString)) + { + return existingFilterString ?? string.Empty; + } + var selectedFilters = existingFilterString.Split(FilteringHelper.FilterSeparator).ToList(); + if (!string.IsNullOrEmpty(newFilterToAdd)) + { + var filterHeader = newFilterToAdd.Split(FilteringHelper.Separator)[0]; + var dupfilters = selectedFilters.Where(x => x.Contains(filterHeader)); + if (dupfilters.Count() > 1) + { + foreach (var filter in selectedFilters) + { + if (filter.Contains(filterHeader)) + { + selectedFilters.Remove(filter); + existingFilterString = string.Join(FilteringHelper.FilterSeparator, selectedFilters); + break; + } + } + } + } + return existingFilterString; + } private static IEnumerable GetFilterOptionsForPromptWithOptions(Prompt prompt) { var group = GetFilterGroupForPrompt(prompt); diff --git a/DigitalLearningSolutions.Web/Controllers/TrackingSystem/Delegates/ActivityDelegatesController.cs b/DigitalLearningSolutions.Web/Controllers/TrackingSystem/Delegates/ActivityDelegatesController.cs index bfa04cd271..eea76c00d7 100644 --- a/DigitalLearningSolutions.Web/Controllers/TrackingSystem/Delegates/ActivityDelegatesController.cs +++ b/DigitalLearningSolutions.Web/Controllers/TrackingSystem/Delegates/ActivityDelegatesController.cs @@ -95,8 +95,7 @@ public IActionResult Index( sortBy ??= DefaultSortByOptions.Name.PropertyName; sortDirection ??= GenericSortingHelper.Ascending; - - existingFilterString = FilteringHelper.GetFilterString( + existingFilterString = FilteringHelper.GetFilterString( existingFilterString, newFilterToAdd, clearFilters, @@ -142,25 +141,7 @@ public IActionResult Index( if (!string.IsNullOrEmpty(existingFilterString)) { var selectedFilters = existingFilterString.Split(FilteringHelper.FilterSeparator).ToList(); - - if (!string.IsNullOrEmpty(newFilterToAdd)) - { - var filterHeader = newFilterToAdd.Split(FilteringHelper.Separator)[0]; - var dupfilters = selectedFilters.Where(x => x.Contains(filterHeader)); - if (dupfilters.Count() > 1) - { - foreach (var filter in selectedFilters) - { - if (filter.Contains(filterHeader)) - { - selectedFilters.Remove(filter); - existingFilterString = string.Join(FilteringHelper.FilterSeparator, selectedFilters); - break; - } - } - } - } - + existingFilterString = FilteringHelper.RemoveDuplicateFilters(newFilterToAdd, existingFilterString); if (selectedFilters.Count > 0) { foreach (var filter in selectedFilters) @@ -276,7 +257,10 @@ public IActionResult Index( var activityName = isCourseDelegate ? courseService.GetCourseNameAndApplication((int)customisationId).CourseName : selfAssessmentService.GetSelfAssessmentNameById((int)selfAssessmentId); - + if (!string.IsNullOrEmpty(existingFilterString)) + { + existingFilterString = FilteringHelper.GetValidFilters( existingFilterString, newFilterToAdd, availableFilters, Request, filterCookieName); + } if (isCourseDelegate) { var result = paginateService.Paginate( @@ -591,6 +575,7 @@ DelegateAccessRoute accessedVia return RedirectToAction("Index", "ActivityDelegates", routeData, returnPageQuery.Value.ItemIdToReturnTo); } } + } } diff --git a/DigitalLearningSolutions.Web/Services/CourseService.cs b/DigitalLearningSolutions.Web/Services/CourseService.cs index 9c255baf2e..530d34c22c 100644 --- a/DigitalLearningSolutions.Web/Services/CourseService.cs +++ b/DigitalLearningSolutions.Web/Services/CourseService.cs @@ -134,7 +134,7 @@ int diagCompletionThreshold int GetNumberOfActiveCoursesAtCentreFilteredByCategory(int centreId, int? categoryId); public IEnumerable GetApplicationsAvailableToCentre(int centreId); bool IsSelfEnrollmentAllowed(int customisationId); - Customisation? GetCourse(int customisationId); + Customisation? GetCourse(int? customisationId); } public class CourseService : ICourseService @@ -632,7 +632,7 @@ public bool IsSelfEnrollmentAllowed(int customisationId) return courseDataService.IsSelfEnrollmentAllowed(customisationId); } - public Customisation? GetCourse(int customisationId) + public Customisation? GetCourse(int? customisationId) { return courseDataService.GetCourse(customisationId); }