|
1 | | -namespace LearningHub.Nhs.WebUI.Services |
| 1 | +namespace LearningHub.Nhs.WebUI.Services |
2 | 2 | { |
3 | 3 | using System; |
4 | 4 | using System.Collections.Generic; |
@@ -86,6 +86,226 @@ public async Task<SearchResultViewModel> PerformSearch(IPrincipal user, SearchRe |
86 | 86 | ResourceAccessLevelFilterText = searchRequest.ResourceAccessLevelId.HasValue && searchRequest.ResourceAccessLevelId != (int)ResourceAccessibilityEnum.None ? $"&resource_access_level={searchRequest.ResourceAccessLevelId.Value}" : string.Empty, |
87 | 87 | }; |
88 | 88 |
|
| 89 | + SearchViewModel resourceResult = null; |
| 90 | + var resourceCollectionFilter = new List<SearchFilterModel>(); |
| 91 | + |
| 92 | + if (searchString != string.Empty) |
| 93 | + { |
| 94 | + var resourceResultTask = this.GetSearchResultAsync(resourceSearchRequestModel); |
| 95 | + |
| 96 | + if (searchRequest.CatalogueId.HasValue) |
| 97 | + { |
| 98 | + // Search within a catalogue - resources only. |
| 99 | + await resourceResultTask; |
| 100 | + resourceResult = resourceResultTask.Result; |
| 101 | + } |
| 102 | + else |
| 103 | + { |
| 104 | + await Task.WhenAll(resourceResultTask); |
| 105 | + |
| 106 | + resourceResult = resourceResultTask.Result; |
| 107 | + |
| 108 | + // Did you mean suggestion when no hits found |
| 109 | + if (resourceResult?.TotalHits == 0 && (resourceResult?.Spell?.Suggestions?.Count > 0)) |
| 110 | + { |
| 111 | + didYouMeanEnabled = true; |
| 112 | + |
| 113 | + // pass the spell suggestion as new search text - resources |
| 114 | + if (resourceResult?.Spell?.Suggestions?.Count > 0) |
| 115 | + { |
| 116 | + resourceSearchRequestModel.SearchText = Regex.Replace(resourceResult?.Spell?.Suggestions?.FirstOrDefault().ToString(), "<.*?>", string.Empty); |
| 117 | + suggestedResource = resourceSearchRequestModel.SearchText; |
| 118 | + |
| 119 | + // calling findwise endpoint with new search text - resources |
| 120 | + resourceResultTask = this.GetSearchResultAsync(resourceSearchRequestModel); |
| 121 | + } |
| 122 | + |
| 123 | + await Task.WhenAll(resourceResultTask); |
| 124 | + |
| 125 | + resourceResult = resourceResultTask.Result; |
| 126 | + } |
| 127 | + } |
| 128 | + |
| 129 | + var searchfilters = new List<SearchFilterModel>(); |
| 130 | + var resourceAccessLevelFilters = new List<SearchFilterModel>(); |
| 131 | + |
| 132 | + var providerfilters = new List<SearchFilterModel>(); |
| 133 | + |
| 134 | + if (resourceResult != null && resourceResult.Facets != null && resourceResult.Facets.Length > 0) |
| 135 | + { |
| 136 | + var filters = resourceResult.Facets.Where(x => x.Id == "resource_type").First().Filters; |
| 137 | + |
| 138 | + foreach (var filteritem in filters.Select(x => x.DisplayName.ToLower()).Distinct()) |
| 139 | + { |
| 140 | + var filter = filters.Where(x => x.DisplayName == filteritem).FirstOrDefault(); |
| 141 | + |
| 142 | + if (filter != null && UtilityHelper.FindwiseResourceTypeDict.ContainsKey(filter.DisplayName)) |
| 143 | + { |
| 144 | + var resourceTypeEnum = UtilityHelper.FindwiseResourceTypeDict[filter.DisplayName]; |
| 145 | + var searchfilter = new SearchFilterModel() { DisplayName = UtilityHelper.GetPrettifiedResourceTypeName(resourceTypeEnum), Count = filter.Count, Value = filteritem, Selected = searchRequest.Filters?.Contains(filter.DisplayName) ?? false }; |
| 146 | + searchfilters.Add(searchfilter); |
| 147 | + } |
| 148 | + } |
| 149 | + |
| 150 | + if (user.IsInRole("BasicUser")) |
| 151 | + { |
| 152 | + var accessLevelFilters = resourceResult.Facets.Where(x => x.Id == "resource_access_level").First().Filters; |
| 153 | + |
| 154 | + var generalAccessValue = (int)ResourceAccessibilityEnum.GeneralAccess; |
| 155 | + var basicUserAudienceFilterItem = accessLevelFilters.Where(x => x.DisplayName == generalAccessValue.ToString()).FirstOrDefault(); |
| 156 | + var basicResourceAccesslevelCount = basicUserAudienceFilterItem?.Count ?? 0; |
| 157 | + var basicUserAudienceFilter = new SearchFilterModel() { DisplayName = ResourceAccessLevelHelper.GetPrettifiedResourceAccessLevelOptionDisplayName(ResourceAccessibilityEnum.GeneralAccess), Count = basicResourceAccesslevelCount, Value = generalAccessValue.ToString(), Selected = (searchRequest.ResourceAccessLevelId ?? 0) == generalAccessValue }; |
| 158 | + resourceAccessLevelFilters.Add(basicUserAudienceFilter); |
| 159 | + } |
| 160 | + |
| 161 | + filters = resourceResult.Facets.Where(x => x.Id == "provider_ids").First().Filters; |
| 162 | + |
| 163 | + if (filters.Length > 0) |
| 164 | + { |
| 165 | + var providers = await this.providerService.GetProviders(); |
| 166 | + var provider_ids = providers.Select(n => n.Id).ToList(); |
| 167 | + |
| 168 | + foreach (var filteritem in filters.Select(x => x.DisplayName.ToLower()).Distinct()) |
| 169 | + { |
| 170 | + var filter = filters.Where(x => x.DisplayName == filteritem).FirstOrDefault(); |
| 171 | + |
| 172 | + if (filter != null && provider_ids.Contains(Convert.ToInt32(filter.DisplayName))) |
| 173 | + { |
| 174 | + var provider = providers.Where(n => n.Id == Convert.ToInt32(filter.DisplayName)).FirstOrDefault(); |
| 175 | + |
| 176 | + var searchfilter = new SearchFilterModel() { DisplayName = provider.Name, Count = filter.Count, Value = filteritem, Selected = searchRequest.ProviderFilters?.Contains(filter.DisplayName) ?? false }; |
| 177 | + providerfilters.Add(searchfilter); |
| 178 | + } |
| 179 | + } |
| 180 | + } |
| 181 | + |
| 182 | + // Process resource_collection facets |
| 183 | + var collectionFacet = resourceResult.Facets.FirstOrDefault(x => x.Id == "resource_collection"); |
| 184 | + if (collectionFacet != null && collectionFacet.Filters != null) |
| 185 | + { |
| 186 | + foreach (var filteritem in collectionFacet.Filters.Select(x => x.DisplayName).Distinct()) |
| 187 | + { |
| 188 | + var filter = collectionFacet.Filters.Where(x => x.DisplayName == filteritem).FirstOrDefault(); |
| 189 | + |
| 190 | + if (filter != null && !string.IsNullOrEmpty(filter.DisplayName)) |
| 191 | + { |
| 192 | + var searchfilter = new SearchFilterModel() |
| 193 | + { |
| 194 | + DisplayName = filter.DisplayName, |
| 195 | + Count = filter.Count, |
| 196 | + Value = filter.DisplayName.ToLower(), |
| 197 | + Selected = searchRequest.ResourceCollectionFilter?.Contains(filter.DisplayName, StringComparer.OrdinalIgnoreCase) ?? false, |
| 198 | + }; |
| 199 | + resourceCollectionFilter.Add(searchfilter); |
| 200 | + } |
| 201 | + } |
| 202 | + |
| 203 | + if (resourceCollectionFilter.Any()) |
| 204 | + { |
| 205 | + // Sum of all counts |
| 206 | + var allCount = resourceCollectionFilter.Sum(x => x.Count); |
| 207 | + |
| 208 | + // If none selected ➜ All is selected |
| 209 | + // If ALL child filters are selected → All is selected |
| 210 | + var allSelected = |
| 211 | + !resourceCollectionFilter.Any(x => x.Selected) || |
| 212 | + resourceCollectionFilter.All(x => x.Selected); |
| 213 | + |
| 214 | + // Create the ALL filter |
| 215 | + var allFilter = new SearchFilterModel |
| 216 | + { |
| 217 | + DisplayName = "All", |
| 218 | + Value = "all", |
| 219 | + Count = allCount, |
| 220 | + Selected = allSelected, |
| 221 | + }; |
| 222 | + |
| 223 | + // Insert at top |
| 224 | + resourceCollectionFilter.Insert(0, allFilter); |
| 225 | + } |
| 226 | + } |
| 227 | + } |
| 228 | + |
| 229 | + resourceResult.SortItemList = searchSortItemList; |
| 230 | + resourceResult.SortItemSelected = selectedSortItem; |
| 231 | + resourceResult.SearchFilters = searchfilters; |
| 232 | + resourceResult.SearchResourceAccessLevelFilters = resourceAccessLevelFilters; |
| 233 | + resourceResult.SearchProviderFilters = providerfilters; |
| 234 | + } |
| 235 | + |
| 236 | + var searchResultViewModel = new SearchResultViewModel |
| 237 | + { |
| 238 | + SearchString = searchString, |
| 239 | + GroupId = groupId, |
| 240 | + FeedbackSubmitted = searchRequest.FeedbackSubmitted ?? false, |
| 241 | + ResourceCurrentPageIndex = searchRequest.ResourcePageIndex ?? 0, |
| 242 | + CatalogueCurrentPageIndex = searchRequest.CataloguePageIndex ?? 0, |
| 243 | + ResourceSearchResult = resourceResult, |
| 244 | + |
| 245 | + // SearchCollectionFilters = resourceCollectionFilters, |
| 246 | + ResourceResultPaging = new SearchResultPagingModel |
| 247 | + { |
| 248 | + CurrentPage = searchRequest.ResourcePageIndex ?? 0, |
| 249 | + PageSize = resourceSearchPageSize, |
| 250 | + TotalItems = resourceResult?.TotalHits ?? 0, |
| 251 | + }, |
| 252 | + |
| 253 | + CatalogueResultPaging = new SearchResultPagingModel |
| 254 | + { |
| 255 | + CurrentPage = searchRequest.CataloguePageIndex ?? 0, |
| 256 | + PageSize = catalogueSearchPageSize, |
| 257 | + }, |
| 258 | + DidYouMeanEnabled = didYouMeanEnabled, |
| 259 | + SuggestedCatalogue = suggestedCatalogue, |
| 260 | + SuggestedResource = suggestedResource, |
| 261 | + }; |
| 262 | + |
| 263 | + searchResultViewModel.ResourceCollectionFilter = resourceCollectionFilter; |
| 264 | + |
| 265 | + return searchResultViewModel; |
| 266 | + } |
| 267 | + |
| 268 | + /// <summary> |
| 269 | + /// Performs a search - either a combined resource and catalogue search, or just a resource search if |
| 270 | + /// searching within a catalogue. |
| 271 | + /// </summary> |
| 272 | + /// <param name="user">user.</param> |
| 273 | + /// <param name="searchRequest">The SearchRequestViewModel.</param> |
| 274 | + /// <returns>A <see cref="Task{TResult}"/> representing the result of the asynchronous operation.</returns> |
| 275 | + public async Task<SearchResultViewModel> PerformSearchInFindwise(IPrincipal user, SearchRequestViewModel searchRequest) |
| 276 | + { |
| 277 | + var searchSortType = 0; |
| 278 | + if (searchRequest.Sortby.HasValue && Enum.IsDefined(typeof(SearchSortTypeEnum), searchRequest.Sortby)) |
| 279 | + { |
| 280 | + searchSortType = searchRequest.Sortby.Value; |
| 281 | + } |
| 282 | + |
| 283 | + var searchString = searchRequest.Term?.Trim() ?? string.Empty; |
| 284 | + var searchSortItemList = SearchHelper.GetSearchSortList(); |
| 285 | + var selectedSortItem = searchSortItemList.Where(x => x.SearchSortType == (SearchSortTypeEnum)searchSortType).FirstOrDefault(); |
| 286 | + var groupId = Guid.Parse(searchRequest.GroupId); |
| 287 | + bool didYouMeanEnabled = false; |
| 288 | + var suggestedCatalogue = string.Empty; |
| 289 | + var suggestedResource = string.Empty; |
| 290 | + |
| 291 | + var resourceSearchPageSize = this.settings.FindwiseSettings.ResourceSearchPageSize; |
| 292 | + var catalogueSearchPageSize = this.settings.FindwiseSettings.CatalogueSearchPageSize; |
| 293 | + |
| 294 | + var resourceSearchRequestModel = new SearchRequestModel |
| 295 | + { |
| 296 | + SearchId = searchRequest.SearchId.Value, |
| 297 | + SearchText = searchString, |
| 298 | + FilterText = this.BuildFilterText(searchRequest.Filters, searchRequest.ResourceCollectionFilter), |
| 299 | + ProviderFilterText = searchRequest.ProviderFilters?.Any() == true ? $"&provider_ids={string.Join("&provider_ids=", searchRequest.ProviderFilters)}" : string.Empty, |
| 300 | + SortColumn = selectedSortItem.Value, |
| 301 | + SortDirection = selectedSortItem?.SortDirection, |
| 302 | + PageIndex = searchRequest.ResourcePageIndex ?? 0, |
| 303 | + PageSize = resourceSearchPageSize, |
| 304 | + GroupId = groupId, |
| 305 | + CatalogueId = searchRequest.CatalogueId, |
| 306 | + ResourceAccessLevelFilterText = searchRequest.ResourceAccessLevelId.HasValue && searchRequest.ResourceAccessLevelId != (int)ResourceAccessibilityEnum.None ? $"&resource_access_level={searchRequest.ResourceAccessLevelId.Value}" : string.Empty, |
| 307 | + }; |
| 308 | + |
89 | 309 | var catalogueSearchRequestModel = new CatalogueSearchRequestModel() |
90 | 310 | { |
91 | 311 | SearchId = searchRequest.SearchId.Value, |
|
0 commit comments