Skip to content

Commit d23b44f

Browse files
author
Binon
committed
Get the resource collection filter working completely
1 parent 912d9e0 commit d23b44f

File tree

8 files changed

+126
-22
lines changed

8 files changed

+126
-22
lines changed

LearningHub.Nhs.WebUI/Controllers/SearchController.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public async Task<IActionResult> Index(SearchRequestViewModel search, bool noSor
113113
/// <param name="feedback">The feedback.</param>
114114
/// <returns>The actionResult.</returns>
115115
[HttpPost("results")]
116-
public async Task<IActionResult> IndexPost([FromQuery] SearchRequestViewModel search, int resourceCount, [FromForm] IEnumerable<string> filters, [FromForm] int? resourceAccessLevelId, [FromForm] IEnumerable<string> providerfilters, [FromForm] int? sortby, [FromForm] string groupId, [FromForm] int searchId, [FromQuery] string actionType, [FromQuery] string resourceCollectionFilter, string feedback)
116+
public async Task<IActionResult> IndexPost([FromQuery] SearchRequestViewModel search, int resourceCount, [FromForm] IEnumerable<string> filters, [FromForm] int? resourceAccessLevelId, [FromForm] IEnumerable<string> providerfilters, [FromForm] int? sortby, [FromForm] string groupId, [FromForm] int searchId, [FromQuery] string actionType, [FromForm] IEnumerable<string> resourceCollectionFilter, string feedback)
117117
{
118118
if (actionType == "feedback")
119119
{
@@ -145,14 +145,17 @@ public async Task<IActionResult> IndexPost([FromQuery] SearchRequestViewModel se
145145
var existingProviderFilters = (search.ProviderFilters ?? new List<string>()).OrderBy(t => t);
146146
var newProviderFilters = providerfilters.OrderBy(t => t);
147147
var filterProviderUpdated = !newProviderFilters.SequenceEqual(existingProviderFilters);
148+
var existingResourceCollectionFilter = (search.ResourceCollectionFilter ?? new List<string>()).OrderBy(t => t);
149+
var newResourceCollectionFilter = resourceCollectionFilter.OrderBy(t => t);
150+
var filterResourceCollectionUpdated = !newResourceCollectionFilter.SequenceEqual(existingResourceCollectionFilter);
148151

149-
// No sort or resource type filter updated or resource access level filter updated or provider filter applied
150-
if ((search.Sortby ?? 0) == sortby && !filterUpdated && !resourceAccessLevelFilterUpdated && !filterProviderUpdated)
152+
// No sort or resource type filter updated or resource access level filter updated or provider filter applied or resource collection filter applied
153+
if ((search.Sortby ?? 0) == sortby && !filterUpdated && !resourceAccessLevelFilterUpdated && !filterProviderUpdated && !filterResourceCollectionUpdated)
151154
{
152155
return await this.Index(search, noSortFilterError: true);
153156
}
154157

155-
if (search.ResourcePageIndex > 0 && (filterUpdated || resourceAccessLevelFilterUpdated || filterProviderUpdated))
158+
if (search.ResourcePageIndex > 0 && (filterUpdated || resourceAccessLevelFilterUpdated || filterProviderUpdated || filterResourceCollectionUpdated))
156159
{
157160
search.ResourcePageIndex = null;
158161
}
@@ -164,6 +167,7 @@ public async Task<IActionResult> IndexPost([FromQuery] SearchRequestViewModel se
164167
search.GroupId = groupId;
165168
search.SearchId = searchId;
166169
search.ResourceAccessLevelId = resourceAccessLevelId;
170+
search.ResourceCollectionFilter = resourceCollectionFilter;
167171

168172
var routeValues = new RouteValueDictionary(search)
169173
{

LearningHub.Nhs.WebUI/Models/Search/SearchRequestViewModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,6 @@ public class SearchRequestViewModel
7979
/// <summary>
8080
/// Gets or sets the show filter (all, catalogues, courses, resources).
8181
/// </summary>
82-
public string ResourceCollectionFilter { get; set; }
82+
public IEnumerable<string> ResourceCollectionFilter { get; set; }
8383
}
8484
}

LearningHub.Nhs.WebUI/Models/Search/SearchResultViewModel.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
namespace LearningHub.Nhs.WebUI.Models.Search
22
{
33
using System;
4+
using System.Collections.Generic;
45
using LearningHub.Nhs.Models.Paging;
56
using LearningHub.Nhs.Models.Search;
67

@@ -97,6 +98,6 @@ public class SearchResultViewModel
9798
/// <summary>
9899
/// Gets or sets the show filter (all, catalogues, courses, resources).
99100
/// </summary>
100-
public string ResourceCollectionFilter { get; set; }
101+
public List<SearchFilterModel> ResourceCollectionFilter { get; set; }
101102
}
102103
}

LearningHub.Nhs.WebUI/Services/SearchService.cs

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public async Task<SearchResultViewModel> PerformSearch(IPrincipal user, SearchRe
7575
{
7676
SearchId = searchRequest.SearchId.Value,
7777
SearchText = searchString,
78-
FilterText = searchRequest.Filters?.Any() == true ? $"&resource_type={string.Join("&resource_type=", searchRequest.Filters)}" : string.Empty,
78+
FilterText = this.BuildFilterText(searchRequest.Filters, searchRequest.ResourceCollectionFilter),
7979
ProviderFilterText = searchRequest.ProviderFilters?.Any() == true ? $"&provider_ids={string.Join("&provider_ids=", searchRequest.ProviderFilters)}" : string.Empty,
8080
SortColumn = selectedSortItem.Value,
8181
SortDirection = selectedSortItem?.SortDirection,
@@ -98,6 +98,7 @@ public async Task<SearchResultViewModel> PerformSearch(IPrincipal user, SearchRe
9898

9999
SearchViewModel resourceResult = null;
100100
SearchCatalogueViewModel catalogueResult = null;
101+
var resourceCollectionFilter = new List<SearchFilterModel>();
101102

102103
if (searchString != string.Empty)
103104
{
@@ -203,6 +204,28 @@ public async Task<SearchResultViewModel> PerformSearch(IPrincipal user, SearchRe
203204
}
204205
}
205206
}
207+
208+
// Process resource_collection facets
209+
var collectionFacet = resourceResult.Facets.FirstOrDefault(x => x.Id == "resource_collection");
210+
if (collectionFacet != null && collectionFacet.Filters != null)
211+
{
212+
foreach (var filteritem in collectionFacet.Filters.Select(x => x.DisplayName).Distinct())
213+
{
214+
var filter = collectionFacet.Filters.Where(x => x.DisplayName == filteritem).FirstOrDefault();
215+
216+
if (filter != null && !string.IsNullOrEmpty(filter.DisplayName))
217+
{
218+
var searchfilter = new SearchFilterModel()
219+
{
220+
DisplayName = filter.DisplayName,
221+
Count = filter.Count,
222+
Value = filter.DisplayName.ToLower(),
223+
Selected = searchRequest.ResourceCollectionFilter?.Contains(filter.DisplayName, StringComparer.OrdinalIgnoreCase) ?? false,
224+
};
225+
resourceCollectionFilter.Add(searchfilter);
226+
}
227+
}
228+
}
206229
}
207230

208231
resourceResult.SortItemList = searchSortItemList;
@@ -222,6 +245,7 @@ public async Task<SearchResultViewModel> PerformSearch(IPrincipal user, SearchRe
222245
ResourceSearchResult = resourceResult,
223246
CatalogueSearchResult = catalogueResult,
224247

248+
// SearchCollectionFilters = resourceCollectionFilters,
225249
ResourceResultPaging = new SearchResultPagingModel
226250
{
227251
CurrentPage = searchRequest.ResourcePageIndex ?? 0,
@@ -240,6 +264,8 @@ public async Task<SearchResultViewModel> PerformSearch(IPrincipal user, SearchRe
240264
SuggestedResource = suggestedResource,
241265
};
242266

267+
searchResultViewModel.ResourceCollectionFilter = resourceCollectionFilter;
268+
243269
return searchResultViewModel;
244270
}
245271

@@ -271,7 +297,7 @@ public async Task<int> RegisterSearchEventsAsync(SearchRequestViewModel search,
271297
GroupId = Guid.Parse(search.GroupId),
272298
SortDirection = "descending",
273299
SortColumn = sortBy.ToString(),
274-
FilterText = search.Filters?.Any() == true ? string.Join(",", search.Filters) : null,
300+
FilterText = this.BuildAnalyticsFilterText(search.Filters, search.ResourceCollectionFilter),
275301
ResourceAccessLevelFilterText = search.ResourceAccessLevelId.HasValue ? search.ResourceAccessLevelId.Value.ToString() : null,
276302
ProviderFilterText = search.ProviderFilters?.Any() == true ? string.Join(",", allproviders.Where(n => search.ProviderFilters.Contains(n.Id.ToString())).Select(x => x.Name).ToList()) : null,
277303
};
@@ -737,6 +763,52 @@ public async Task SendAutoSuggestionClickActionAsync(AutoSuggestionClickPayloadM
737763
}
738764
}
739765

766+
/// <summary>
767+
/// Builds the filter text combining resource type and resource collection filters.
768+
/// </summary>
769+
/// <param name="resourceTypeFilter">The resource type filters.</param>
770+
/// <param name="resourceCollectionFilter">The resource collection filters.</param>
771+
/// <returns>The combined filter text.</returns>
772+
private string BuildFilterText(IEnumerable<string> resourceTypeFilter, IEnumerable<string> resourceCollectionFilter)
773+
{
774+
var filterParts = new List<string>();
775+
776+
if (resourceTypeFilter?.Any() == true)
777+
{
778+
filterParts.Add($"&resource_type={string.Join("&resource_type=", resourceTypeFilter)}");
779+
}
780+
781+
if (resourceCollectionFilter?.Any() == true)
782+
{
783+
filterParts.Add($"&resource_collection={string.Join("&resource_collection=", resourceCollectionFilter)}");
784+
}
785+
786+
return string.Join(string.Empty, filterParts);
787+
}
788+
789+
/// <summary>
790+
/// Builds the analytics filter text combining resource type and resource collection filters for logging.
791+
/// </summary>
792+
/// <param name="resourceTypeFilter">The resource type filters.</param>
793+
/// <param name="resourceCollectionFilter">The resource collection filters.</param>
794+
/// <returns>The combined filter text for analytics.</returns>
795+
private string BuildAnalyticsFilterText(IEnumerable<string> resourceTypeFilter, IEnumerable<string> resourceCollectionFilter)
796+
{
797+
var filterParts = new List<string>();
798+
799+
if (resourceTypeFilter?.Any() == true)
800+
{
801+
filterParts.AddRange(resourceTypeFilter);
802+
}
803+
804+
if (resourceCollectionFilter?.Any() == true)
805+
{
806+
filterParts.AddRange(resourceCollectionFilter.Select(f => $"collection:{f}"));
807+
}
808+
809+
return filterParts.Any() ? string.Join(",", filterParts) : null;
810+
}
811+
740812
/// <summary>
741813
/// The RemoveHtmlTags.
742814
/// </summary>

LearningHub.Nhs.WebUI/Views/Search/_SearchFilter.cshtml

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
var pageUrl = Model.CatalogueId > 0 ? "/catalogue/" + Model.CatalogueUrl + "/search" : "/search/results";
1313
var actionUrl = QueryHelpers.AddQueryString(pageUrl, queryParams);
1414
var pageFragment = "#search-filters";
15+
var selectedResourceCollection = "all";
1516

1617
string FilterSummary()
1718
{
@@ -62,27 +63,33 @@
6263
<legend class="nhsuk-fieldset__legend">
6364
<strong>Show</strong>
6465
</legend>
66+
@foreach (var rc in Model.ResourceCollectionFilter)
67+
{
68+
if (rc.Selected)
69+
selectedResourceCollection = rc.Value;
70+
}
6571
<div class="nhsuk-radios nhsuk-radios--inline">
6672
<div class="nhsuk-radios__item">
67-
<input class="nhsuk-radios__input" id="show-all" name="resourceCollectionFilter" type="radio" value="all" checked="@((Model.ResourceCollectionFilter ?? "all") == "all")" onchange="this.form.submit()">
73+
<input class="nhsuk-radios__input" id="show-all" name="resourceCollectionFilter" type="radio" value="all" checked="@(selectedResourceCollection == "all") onchange="this.form.submit()">
6874
<label class="nhsuk-label nhsuk-radios__label" for="show-all">
6975
All
7076
</label>
71-
</div>
77+
</div>
7278
<div class="nhsuk-radios__item">
73-
<input class="nhsuk-radios__input" id="show-catalogues" name="resourceCollectionFilter" type="radio" value="catalogues" checked="@((Model.ResourceCollectionFilter ?? "all") == "catalogues")" onchange="this.form.submit()">
79+
<input class="nhsuk-radios__input" id="show-catalogues" name="resourceCollectionFilter" type="radio" value="catalogue" checked="@(selectedResourceCollection == "catalogue")" onchange="this.form.submit()">
7480
<label class="nhsuk-label nhsuk-radios__label" for="show-catalogues">
7581
Catalogues
7682
</label>
7783
</div>
7884
<div class="nhsuk-radios__item">
79-
<input class="nhsuk-radios__input" id="show-courses" name="resourceCollectionFilter" type="radio" value="courses" checked="@((Model.ResourceCollectionFilter ?? "all") == "courses")" ange="this.form.submit()">
85+
<input class="nhsuk-radios__input" id="show-courses" name="resourceCollectionFilter" type="radio" value="course" checked="@(selectedResourceCollection == "course")"
86+
onchange="this.form.submit()">
8087
<label class="nhsuk-label nhsuk-radios__label" for="show-courses">
8188
Courses
8289
</label>
8390
</div>
8491
<div class="nhsuk-radios__item">
85-
<input class="nhsuk-radios__input" id="show-resources" name="resourceCollectionFilter" type="radio" value="resources" checked="@((Model.ResourceCollectionFilter ?? "all") == "resources")" onchange="this.fsubmit()">
92+
<input class="nhsuk-radios__input" id="show-resources" name="resourceCollectionFilter" type="radio" value="resource" checked="@(selectedResourceCollection == "resource")" onchange="this.form.submit()">
8693
<label class="nhsuk-label nhsuk-radios__label" for="show-resources">
8794
Resources
8895
</label>

OpenAPI/LearningHub.Nhs.OpenApi.Models/ServiceModels/AzureSearch/SearchDocument.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,26 @@ public class SearchDocument
1818
/// </summary>
1919
[SearchableField(IsKey = true)]
2020
[JsonPropertyName("id")]
21-
public string Id { get; set; } = string.Empty;
21+
public string PrefixedId { get; set; } = string.Empty;
22+
23+
/// <summary>
24+
/// Gets the numeric ID extracted from the PrefixedId.
25+
/// </summary>
26+
[JsonIgnore]
27+
public string Id
28+
{
29+
get
30+
{
31+
if (string.IsNullOrWhiteSpace(PrefixedId))
32+
return "0";
33+
34+
var parts = PrefixedId.Split('_');
35+
if (parts.Length != 2)
36+
return "0";
37+
38+
return int.TryParse(parts[1], out int id) ? id.ToString() : "0";
39+
}
40+
}
2241

2342
/// <summary>
2443
/// Gets or sets the title.

OpenAPI/LearningHub.Nhs.OpenApi.Services/Helpers/Search/SearchFilterBuilder.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public static Dictionary<string, List<string>> CombineAndNormaliseFilters(string
2626
MergeFilterDictionary(filters, requestTypeFilters);
2727
// MergeFilterDictionary(filters, providerFilters);
2828

29-
NormalizeResourceTypeFilters(filters);
29+
NormaliseFilters(filters);
3030

3131
return filters;
3232
}
@@ -105,10 +105,10 @@ public static Dictionary<string, List<string>> ParseQueryStringFilters(string? q
105105
}
106106

107107
/// <summary>
108-
/// Normalizes resource type filter values by capitalizing the first letter.
108+
/// Normalizes resource type and resource collection filter values by capitalizing the first letter.
109109
/// </summary>
110110
/// <param name="filters">The filters dictionary to normalize.</param>
111-
public static void NormalizeResourceTypeFilters(Dictionary<string, List<string>>? filters)
111+
public static void NormaliseFilters(Dictionary<string, List<string>>? filters)
112112
{
113113
if (filters == null || !filters.ContainsKey("resource_type"))
114114
return;

OpenAPI/LearningHub.Nhs.OpenApi.Services/Services/AzureSearch/AzureSearchService.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ public async Task<SearchResultModel> GetSearchResultAsync(SearchRequestModel sea
140140

141141
return new Document
142142
{
143-
Id = doc.Id?.Substring(1),
143+
Id = doc.Id,
144144
Title = doc.Title,
145145
Description = doc.Description,
146146
ResourceType = doc.ResourceType?.Contains("SCORM e-learning resource") == true ? "scorm" : doc.ResourceType,
@@ -301,7 +301,7 @@ public async Task<SearchCatalogueResultModel> GetCatalogueSearchResultAsync(Cata
301301

302302
return new CatalogueDocument
303303
{
304-
Id = doc.Id?.Substring(1),
304+
Id = doc.Id,
305305
Name = doc.Title,
306306
Description = doc.Description,
307307
Click = new SearchClickModel { Payload = new SearchClickPayloadModel { HitNumber = 1 }, Url = "binon" }
@@ -576,9 +576,10 @@ public async Task<bool> SendResourceForSearchAsync(SearchResourceRequestModel se
576576
// Map SearchResourceRequestModel to PocSearchDocument
577577
var document = new Models.ServiceModels.AzureSearch.SearchDocument
578578
{
579-
Id = searchResourceRequestModel.Id.ToString(),
580-
Title = searchResourceRequestModel.Title ?? string.Empty,
581579
// TODO: [BY]
580+
// Id = searchResourceRequestModel.Id.ToString(),
581+
// Title = searchResourceRequestModel.Title ?? string.Empty,
582+
582583
//Description = searchResourceRequestModel.Description ?? string.Empty,
583584
//ResourceType = searchResourceRequestModel.ResourceType ?? string.Empty,
584585
//ContentType = searchResourceRequestModel.ContentType,
@@ -641,7 +642,7 @@ public async Task<SearchAllCatalogueResultModel> GetAllCatalogueSearchResultsAsy
641642

642643
return new CatalogueDocument
643644
{
644-
Id = doc.Id?.Substring(1),
645+
Id = doc.Id,
645646
Name = doc.Title,
646647
Description = doc.Description,
647648
Click = new SearchClickModel { Payload = new SearchClickPayloadModel { HitNumber = 1 }, Url = "binon" }

0 commit comments

Comments
 (0)