diff --git a/.github/workflows/continuous-integration-workflow.yml b/.github/workflows/continuous-integration-workflow.yml index f1609bb44..94fca85b0 100644 --- a/.github/workflows/continuous-integration-workflow.yml +++ b/.github/workflows/continuous-integration-workflow.yml @@ -9,99 +9,38 @@ jobs: runs-on: windows-latest steps: - uses: actions/checkout@v3 - - - name: Modify web.config files in all apps - shell: pwsh - run: | - $webConfigPaths = @( - "${{ github.workspace }}\AdminUI\LearningHub.Nhs.AdminUI\web.config", - "${{ github.workspace }}\WebAPI\LearningHub.Nhs.Api\web.config", - "${{ github.workspace }}\LearningHub.Nhs.WebUI\web.config" - ) - - foreach ($path in $webConfigPaths) { - if (Test-Path $path) { - Write-Host "Modifying $path" - [xml]$config = Get-Content $path - - if (-not $config.configuration.'system.webServer') { - $systemWebServer = $config.CreateElement("system.webServer") - $config.configuration.AppendChild($systemWebServer) | Out-Null - } else { - $systemWebServer = $config.configuration.'system.webServer' - } - - if (-not $systemWebServer.httpProtocol) { - $httpProtocol = $config.CreateElement("httpProtocol") - $systemWebServer.AppendChild($httpProtocol) | Out-Null - } else { - $httpProtocol = $systemWebServer.httpProtocol - } - - if (-not $httpProtocol.customHeaders) { - $customHeaders = $config.CreateElement("customHeaders") - $httpProtocol.AppendChild($customHeaders) | Out-Null - } else { - $customHeaders = $httpProtocol.customHeaders - } - - foreach ($name in @("X-Powered-By", "Server")) { - $removeNode = $config.CreateElement("remove") - $removeNode.SetAttribute("name", $name) - $customHeaders.AppendChild($removeNode) | Out-Null - } - - if (-not $systemWebServer.security) { - $security = $config.CreateElement("security") - $systemWebServer.AppendChild($security) | Out-Null - } else { - $security = $systemWebServer.security - } - - if (-not $security.requestFiltering) { - $requestFiltering = $config.CreateElement("requestFiltering") - $requestFiltering.SetAttribute("removeServerHeader", "true") - $security.AppendChild($requestFiltering) | Out-Null - } - - $config.Save($path) - } else { - Write-Host "File not found: $path" - } - } - + - name: Setup .NET Core SDK 8.0 uses: actions/setup-dotnet@v3 with: dotnet-version: 8.0.x - name: Add Azure artifact - run: dotnet nuget add source 'https://pkgs.dev.azure.com/e-LfH/_packaging/LearningHubFeed/nuget/v3/index.json' --name 'LearningHubFeed' --username 'kevin.whittaker' --password ${{ secrets.AZURE_DEVOPS_PAT }} --store-password-in-clear-text + run: | + dotnet nuget remove source LearningHubFeed || true + dotnet nuget add source 'https://pkgs.dev.azure.com/e-LfH/_packaging/LearningHubFeed/nuget/v3/index.json' --name 'LearningHubFeed' --username 'kevin.whittaker' --password ${{ secrets.AZURE_DEVOPS_PAT }} --store-password-in-clear-text - - name: Use Node 20 with Yarn + - name: Use Node 14 uses: actions/setup-node@v4 with: - node-version: '20' - cache: 'npm' - - - name: Upgrade npm to the latest version - run: npm install -g npm@6.14.8 + node-version: '14' + cache: 'npm' - - name: Typescript install WebUI - run: yarn install --network-timeout 600000 --frozen-lockfile + - name: npm install WebUI + run: npm install working-directory: ./LearningHub.Nhs.WebUI - - - name: Typescript build WebUI - run: yarn build:webpack + + - name: npm build WebUI + run: npm run build:webpack working-directory: ./LearningHub.Nhs.WebUI - - name: Typescript install AdminUI - run: yarn install + - name: npm install AdminUI + run: npm install working-directory: ./AdminUI/LearningHub.Nhs.AdminUI - - - name: Typescript build AdminUI - run: yarn build:webpack - working-directory: ./AdminUI/LearningHub.Nhs.AdminUI + + - name: npm build AdminUI + run: npm run build:webpack + working-directory: ./AdminUI/LearningHub.Nhs.AdminUI - name: Setup MSBuild uses: microsoft/setup-msbuild@v1.0.3 @@ -181,5 +120,4 @@ jobs: } # - name: Test - # run: dotnet test ${{ env.BuildParameters.TestProjects }} - + # run: dotnet test ${{ env.BuildParameters.TestProjects }} diff --git a/.gitignore b/.gitignore index fcd06e014..8cc7d8bbe 100644 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,6 @@ obj /AdminUI/LearningHub.Nhs.AdminUI/LearningHub.Nhs.AdminUI.csproj.user /WebAPI/LearningHub.Nhs.API/LearningHub.Nhs.Api.csproj.user /ReportAPI/LearningHub.Nhs.ReportApi/web.config +/AdminUI/LearningHub.Nhs.AdminUI/web.config +/LearningHub.Nhs.WebUI/web.config +/WebAPI/LearningHub.Nhs.API/web.config diff --git a/AdminUI/LearningHub.Nhs.AdminUI/Configuration/WebSettings.cs b/AdminUI/LearningHub.Nhs.AdminUI/Configuration/WebSettings.cs index f8e3c1565..5c8ab554f 100644 --- a/AdminUI/LearningHub.Nhs.AdminUI/Configuration/WebSettings.cs +++ b/AdminUI/LearningHub.Nhs.AdminUI/Configuration/WebSettings.cs @@ -27,6 +27,11 @@ public class WebSettings /// public string LearningHubApiUrl { get; set; } + /// + /// Gets or sets the OpenApiUrl. + /// + public string OpenApiUrl { get; set; } + /// /// Gets or sets the user api url. /// diff --git a/AdminUI/LearningHub.Nhs.AdminUI/Helpers/IOpenApiFacade.cs b/AdminUI/LearningHub.Nhs.AdminUI/Helpers/IOpenApiFacade.cs new file mode 100644 index 000000000..2bcded72b --- /dev/null +++ b/AdminUI/LearningHub.Nhs.AdminUI/Helpers/IOpenApiFacade.cs @@ -0,0 +1,59 @@ +namespace LearningHub.Nhs.AdminUI.Helpers +{ + using System.Threading.Tasks; + using LearningHub.Nhs.Models.Common; + + /// + /// Defines the . + /// + public interface IOpenApiFacade + { + /// + /// The GetAsync. + /// + /// The type. + /// The url. + /// The . + Task GetAsync(string url) + where T : class, new(); + + /// + /// The PostAsync. + /// + /// The type. + /// The url. + /// The body. + /// The . + Task PostAsync(string url, T body) + where T : class, new(); + + /// + /// The PostAsync. + /// + /// The type. + /// . + /// The url. + /// The body. + /// The . + Task PostAsync(string url, TBody body) + where T : class, new() + where TBody : class, new(); + + /// + /// The PutAsync. + /// + /// The url. + /// The . + Task PutAsync(string url); + + /// + /// The PutAsync. + /// + /// . + /// The url. + /// The body. + /// The . + Task PutAsync(string url, T body) + where T : class, new(); + } +} diff --git a/AdminUI/LearningHub.Nhs.AdminUI/Helpers/LearningActivityHelper.cs b/AdminUI/LearningHub.Nhs.AdminUI/Helpers/LearningActivityHelper.cs index caffaaa5d..b67989350 100644 --- a/AdminUI/LearningHub.Nhs.AdminUI/Helpers/LearningActivityHelper.cs +++ b/AdminUI/LearningHub.Nhs.AdminUI/Helpers/LearningActivityHelper.cs @@ -85,7 +85,15 @@ public static string GetResourceTypeVerb(this MyLearningDetailedItemViewModel my case ResourceTypeEnum.Article: return "Read"; case ResourceTypeEnum.Audio: - return "Played " + GetDurationText(myLearningDetailedItemViewModel.ActivityDurationSeconds * 1000); + if ((myLearningDetailedItemViewModel.ActivityDurationSeconds * 1000) > myLearningDetailedItemViewModel.ResourceDurationMilliseconds) + { + return "Played " + GetDurationText(myLearningDetailedItemViewModel.ResourceDurationMilliseconds); + } + else + { + return "Played " + GetDurationText(myLearningDetailedItemViewModel.ActivityDurationSeconds * 1000); + } + case ResourceTypeEnum.Embedded: return string.Empty; case ResourceTypeEnum.Equipment: @@ -113,7 +121,15 @@ public static string GetResourceTypeVerb(this MyLearningDetailedItemViewModel my } case ResourceTypeEnum.Video: - return "Played " + GetDurationText(myLearningDetailedItemViewModel.ActivityDurationSeconds * 1000); + if ((myLearningDetailedItemViewModel.ActivityDurationSeconds * 1000) > myLearningDetailedItemViewModel.ResourceDurationMilliseconds) + { + return "Played " + GetDurationText(myLearningDetailedItemViewModel.ResourceDurationMilliseconds); + } + else + { + return "Played " + GetDurationText(myLearningDetailedItemViewModel.ActivityDurationSeconds * 1000); + } + case ResourceTypeEnum.WebLink: return "Visited"; case ResourceTypeEnum.Html: diff --git a/AdminUI/LearningHub.Nhs.AdminUI/Helpers/OpenApiFacade.cs b/AdminUI/LearningHub.Nhs.AdminUI/Helpers/OpenApiFacade.cs new file mode 100644 index 000000000..6169d8e6b --- /dev/null +++ b/AdminUI/LearningHub.Nhs.AdminUI/Helpers/OpenApiFacade.cs @@ -0,0 +1,241 @@ +namespace LearningHub.Nhs.AdminUI.Helpers +{ + using System; + using System.Net.Http; + using System.Text; + using System.Threading.Tasks; + using LearningHub.Nhs.AdminUI.Interfaces; + using LearningHub.Nhs.Models.Common; + using Newtonsoft.Json; + + /// + /// Defines the . + /// + public class OpenApiFacade : IOpenApiFacade + { + /// + /// Defines the _client. + /// + private readonly IOpenApiHttpClient client; + + /// + /// Initializes a new instance of the class. + /// + /// The client. + public OpenApiFacade(IOpenApiHttpClient client) + { + this.client = client; + } + + /// + /// The GetAsync. + /// + /// . + /// The url. + /// The . + public async Task GetAsync(string url) + where T : class, new() + { + var client = await this.client.GetClientAsync(); + + var vm = new T(); + + var response = await client.GetAsync(url).ConfigureAwait(false); + + if (response.IsSuccessStatusCode) + { + var result = response.Content.ReadAsStringAsync().Result; + vm = JsonConvert.DeserializeObject(result); + + return vm; + } + else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized + || + response.StatusCode == System.Net.HttpStatusCode.Forbidden) + { + throw new Exception("AccessDenied"); + } + else + { + throw new Exception($"Exception HttpStatusCode={response.StatusCode}"); + } + } + + /// + /// The PostAsync. + /// + /// . + /// The url. + /// The body. + /// The . + public async Task PostAsync(string url, T body) + where T : class, new() + { + var client = await this.client.GetClientAsync(); + + var content = new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json"); + var response = await client.PostAsync(url, content).ConfigureAwait(false); + + if (response.IsSuccessStatusCode) + { + return; + } + else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized + || + response.StatusCode == System.Net.HttpStatusCode.Forbidden) + { + throw new Exception("AccessDenied"); + } + else + { + throw new Exception($"Exception HttpStatusCode={response.StatusCode}"); + } + } + + /// + /// The PostAsync. + /// + /// The return type. + /// The type of body parameter. + /// The url. + /// The body. + /// The . + public async Task PostAsync(string url, TBody body) + where TBody : class, new() + where T : class, new() + { + var client = await this.client.GetClientAsync(); + + var vm = new T(); + var content = new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json"); + var response = await client.PostAsync(url, content).ConfigureAwait(false); + + if (response.IsSuccessStatusCode) + { + var result = response.Content.ReadAsStringAsync().Result; + var apiResponse = JsonConvert.DeserializeObject(result); + if (apiResponse.Success) + { + return apiResponse; + } + else + { + string details = string.Empty; + if (apiResponse.ValidationResult != null) + { + if (apiResponse.ValidationResult.Details != null) + { + details = $"::ValidationResult: {string.Join(",", apiResponse.ValidationResult.Details)}"; + } + } + + throw new Exception($"PostAsync ApiResponse returned False: {details}"); + } + } + else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized + || + response.StatusCode == System.Net.HttpStatusCode.Forbidden) + { + throw new Exception("Access Denied"); + } + else + { + throw new Exception($"Exception HttpStatusCode={response.StatusCode}"); + } + } + + /// + /// The PutAsync. + /// + /// The url. + /// The . + public async Task PutAsync(string url) + { + var client = await this.client.GetClientAsync(); + + var response = await client.PutAsync(url, null).ConfigureAwait(false); + + if (response.IsSuccessStatusCode) + { + var result = response.Content.ReadAsStringAsync().Result; + var apiResponse = JsonConvert.DeserializeObject(result); + if (apiResponse.Success) + { + return apiResponse; + } + else + { + string details = string.Empty; + if (apiResponse.ValidationResult != null) + { + if (apiResponse.ValidationResult.Details != null) + { + details = $"::ValidationResult: {string.Join(",", apiResponse.ValidationResult.Details)}"; + } + } + + throw new Exception($"PutAsync ApiResponse returned False: {details}"); + } + } + else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized + || + response.StatusCode == System.Net.HttpStatusCode.Forbidden) + { + throw new Exception("Access Denied"); + } + else + { + throw new Exception($"Exception HttpStatusCode={response.StatusCode}"); + } + } + + /// + /// The PutAsync. + /// + /// . + /// The url. + /// The body. + /// The . + public async Task PutAsync(string url, T body) + where T : class, new() + { + var client = await this.client.GetClientAsync(); + + var content = new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json"); + var response = await client.PutAsync(url, content).ConfigureAwait(false); + + if (response.IsSuccessStatusCode) + { + var result = response.Content.ReadAsStringAsync().Result; + var apiResponse = JsonConvert.DeserializeObject(result); + if (apiResponse.Success) + { + return apiResponse; + } + else + { + string details = string.Empty; + if (apiResponse.ValidationResult != null) + { + if (apiResponse.ValidationResult.Details != null) + { + details = $"::ValidationResult: {string.Join(",", apiResponse.ValidationResult.Details)}"; + } + } + + throw new Exception($"PutAsync ApiResponse returned False: {details}"); + } + } + else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized + || + response.StatusCode == System.Net.HttpStatusCode.Forbidden) + { + throw new Exception("Access Denied"); + } + else + { + throw new Exception($"Exception HttpStatusCode={response.StatusCode}"); + } + } + } +} diff --git a/AdminUI/LearningHub.Nhs.AdminUI/Interfaces/IOpenApiHttpClient.cs b/AdminUI/LearningHub.Nhs.AdminUI/Interfaces/IOpenApiHttpClient.cs new file mode 100644 index 000000000..34c488767 --- /dev/null +++ b/AdminUI/LearningHub.Nhs.AdminUI/Interfaces/IOpenApiHttpClient.cs @@ -0,0 +1,17 @@ +namespace LearningHub.Nhs.AdminUI.Interfaces +{ + using System.Net.Http; + using System.Threading.Tasks; + + /// + /// The OpenApiHttpClient interface. + /// + public interface IOpenApiHttpClient + { + /// + /// The get client. + /// + /// The . + Task GetClientAsync(); + } +} diff --git a/AdminUI/LearningHub.Nhs.AdminUI/LearningHub.Nhs.AdminUI.csproj b/AdminUI/LearningHub.Nhs.AdminUI/LearningHub.Nhs.AdminUI.csproj index eba6b6ffa..a0de54f8f 100644 --- a/AdminUI/LearningHub.Nhs.AdminUI/LearningHub.Nhs.AdminUI.csproj +++ b/AdminUI/LearningHub.Nhs.AdminUI/LearningHub.Nhs.AdminUI.csproj @@ -1,16 +1,16 @@ - + - - net8.0 - 1.0.0.0 - 1.0.0.0 - 1.0.0 - 31abd8b9-4223-4ff3-896b-a46530c9e15c - /subscriptions/57c55d5f-78c1-4373-a021-ff8357548f51/resourceGroups/LearningHubNhsUk-AdminUI-Prod-RG/providers/microsoft.insights/components/LearningHubNhsUk-AdminUI-Prod - true - true - x64 - + + net8.0 + 1.0.0.0 + 1.0.0.0 + 1.0.0 + 31abd8b9-4223-4ff3-896b-a46530c9e15c + /subscriptions/57c55d5f-78c1-4373-a021-ff8357548f51/resourceGroups/LearningHubNhsUk-AdminUI-Prod-RG/providers/microsoft.insights/components/LearningHubNhsUk-AdminUI-Prod + true + true + x64 + diff --git a/AdminUI/LearningHub.Nhs.AdminUI/ServiceCollectionExtension.cs b/AdminUI/LearningHub.Nhs.AdminUI/ServiceCollectionExtension.cs index 81867365f..1039a3673 100644 --- a/AdminUI/LearningHub.Nhs.AdminUI/ServiceCollectionExtension.cs +++ b/AdminUI/LearningHub.Nhs.AdminUI/ServiceCollectionExtension.cs @@ -86,6 +86,7 @@ public static void ConfigureServices(this IServiceCollection services, IConfigur services.AddSingleton(configuration); services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); @@ -132,11 +133,19 @@ public static void ConfigureServices(this IServiceCollection services, IConfigur ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator, }); + services.AddHttpClient() + .ConfigurePrimaryHttpMessageHandler( + () => new HttpClientHandler + { + ServerCertificateCustomValidationCallback = + HttpClientHandler.DangerousAcceptAnyServerCertificateValidator, + }); } else { services.AddHttpClient(); services.AddHttpClient(); + services.AddHttpClient(); } services.AddTransient(); diff --git a/AdminUI/LearningHub.Nhs.AdminUI/Services/BaseService.cs b/AdminUI/LearningHub.Nhs.AdminUI/Services/BaseService.cs index ab2a377e8..c164b5691 100644 --- a/AdminUI/LearningHub.Nhs.AdminUI/Services/BaseService.cs +++ b/AdminUI/LearningHub.Nhs.AdminUI/Services/BaseService.cs @@ -12,6 +12,11 @@ public class BaseService /// private ILearningHubHttpClient learningHubHttpClient; + /// + /// Defines the openApiHttpClient. + /// + private IOpenApiHttpClient openApiHttpClient; + /// /// Initializes a new instance of the class. /// @@ -21,9 +26,25 @@ protected BaseService(ILearningHubHttpClient learningHubHttpClient) this.learningHubHttpClient = learningHubHttpClient; } + /// + /// Initializes a new instance of the class. + /// + /// The learningHubHttpClient. + /// The openApiHttpClient. + protected BaseService(ILearningHubHttpClient learningHubHttpClient, IOpenApiHttpClient openApiHttpClient) + { + this.learningHubHttpClient = learningHubHttpClient; + this.openApiHttpClient = openApiHttpClient; + } + /// /// Gets the LearningHubHttpClient. /// protected ILearningHubHttpClient LearningHubHttpClient => this.learningHubHttpClient; + + /// + /// Gets the OpenApiHttpClient. + /// + protected IOpenApiHttpClient OpenApiHttpClient => this.openApiHttpClient; } } diff --git a/AdminUI/LearningHub.Nhs.AdminUI/Services/CatalogueService.cs b/AdminUI/LearningHub.Nhs.AdminUI/Services/CatalogueService.cs index 1fa44df2b..2ac0088d9 100644 --- a/AdminUI/LearningHub.Nhs.AdminUI/Services/CatalogueService.cs +++ b/AdminUI/LearningHub.Nhs.AdminUI/Services/CatalogueService.cs @@ -19,19 +19,21 @@ public class CatalogueService : BaseService, ICatalogueService /// /// Defines the _facade. /// - private readonly ILearningHubApiFacade facade; + private readonly IOpenApiFacade facade; /// /// Initializes a new instance of the class. /// /// The learningHubHttpClient. - /// The learningHubApiFacade. + /// The Open Api Http Client. + /// The openApiFacade. public CatalogueService( ILearningHubHttpClient learningHubHttpClient, - ILearningHubApiFacade learningHubApiFacade) + IOpenApiHttpClient openApiHttpClient, + IOpenApiFacade openApiFacade) : base(learningHubHttpClient) { - this.facade = learningHubApiFacade; + this.facade = openApiFacade; } /// diff --git a/AdminUI/LearningHub.Nhs.AdminUI/Services/ContentService.cs b/AdminUI/LearningHub.Nhs.AdminUI/Services/ContentService.cs index d49cd8422..ec983fffd 100644 --- a/AdminUI/LearningHub.Nhs.AdminUI/Services/ContentService.cs +++ b/AdminUI/LearningHub.Nhs.AdminUI/Services/ContentService.cs @@ -27,15 +27,17 @@ public class ContentService : BaseService, IContentService /// private readonly IFileService fileService; private readonly IAzureMediaService azureMediaService; + private readonly IOpenApiHttpClient openApiHttpClient; /// /// Initializes a new instance of the class. /// /// The learningHubHttpClient. + /// The openApiHttpClient. /// The fileService. /// azureMediaService. - public ContentService(ILearningHubHttpClient learningHubHttpClient, IFileService fileService, IAzureMediaService azureMediaService) - : base(learningHubHttpClient) + public ContentService(ILearningHubHttpClient learningHubHttpClient, IOpenApiHttpClient openApiHttpClient, IFileService fileService, IAzureMediaService azureMediaService) + : base(learningHubHttpClient, openApiHttpClient) { this.fileService = fileService; this.azureMediaService = azureMediaService; @@ -48,7 +50,7 @@ public ContentService(ILearningHubHttpClient learningHubHttpClient, IFileService /// The . public async Task DiscardAsync(int pageId) { - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"content/discard/{pageId}"; var response = await client.PutAsync(request, null).ConfigureAwait(false); if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized || @@ -68,7 +70,7 @@ public async Task GetPageByIdAsync(int id, bool includeHidden = f { PageViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = !includeHidden ? $"content/page/{id}" : $"content/page-all/{id}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -97,7 +99,7 @@ public async Task GetPageSectionDetailByIdAsync(int { PageSectionDetailViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"content/page-section-detail/{id}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -126,7 +128,7 @@ public async Task GetEditablePageSectionDetailByIdAs { PageSectionDetailViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"content/editable-page-section-detail/{pageSectionId}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -154,7 +156,7 @@ public async Task GetPagesAsync() { PageResultViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"content/pages"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -181,7 +183,7 @@ public async Task GetPagesAsync() /// The . public async Task PublishAsync(int pageId) { - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"content/publish/{pageId}"; var response = await client.PutAsync(request, null).ConfigureAwait(false); if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized || @@ -214,7 +216,7 @@ public async Task UpdatePageImageSectionDetailAsync(int pageId, PageImageSection var json = JsonConvert.SerializeObject(model); var stringContent = new StringContent(json, Encoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"content/page-image-section-detail/{pageId}"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -232,7 +234,7 @@ public async Task UpdatePageImageSectionDetailAsync(int pageId, PageImageSection /// The . public async Task ChangeOrderAsync(UpdatePageSectionOrderModel requestViewModel) { - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = "content/change-order/"; var content = new StringContent( JsonConvert.SerializeObject(requestViewModel), @@ -259,7 +261,7 @@ public async Task ChangeOrderAsync(UpdatePageSectionOrderModel requestViewModel) /// The . public async Task CloneAsync(int pageSectionId) { - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"content/clone/{pageSectionId}"; var response = await client.PutAsync(request, null).ConfigureAwait(false); if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized || @@ -276,7 +278,7 @@ public async Task CloneAsync(int pageSectionId) /// The . public async Task HideAsync(int pageSectionId) { - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"content/hide/{pageSectionId}"; var response = await client.PutAsync(request, null).ConfigureAwait(false); if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized || @@ -293,7 +295,7 @@ public async Task HideAsync(int pageSectionId) /// The . public async Task UnHideAsync(int pageSectionId) { - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"content/unhide/{pageSectionId}"; var response = await client.PutAsync(request, null).ConfigureAwait(false); if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized || @@ -310,7 +312,7 @@ public async Task UnHideAsync(int pageSectionId) /// The . public async Task DeleteAsync(int pageSectionId) { - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"content/delete/{pageSectionId}"; var response = await client.PutAsync(request, null).ConfigureAwait(false); if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized || @@ -376,7 +378,7 @@ public async Task> GetFileTypeAsync() { List fileTypeList = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetFileTypes"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -459,7 +461,7 @@ public async Task SaveAttributeFileDetailsAsync(FileCreateRequestViewModel var json = JsonConvert.SerializeObject(fileCreateRequestViewModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"content/save-attribute-file"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -493,7 +495,7 @@ public async Task SaveVideoAssetAsync(FileCreateRequestViewModel fileCreate var json = JsonConvert.SerializeObject(fileCreateRequestViewModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"content/save-video-asset"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -593,7 +595,7 @@ public async Task GetFileChunkDetail(int fileChunkDeta { FileChunkDetailViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetFileChunkDetail/{fileChunkDetailId}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -624,7 +626,7 @@ public async Task SaveFileChunkDetailsAsync(FileChunkDetailViewModel fileCh var json = JsonConvert.SerializeObject(fileChunkDetailCreateRequestViewModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/SaveFileChunkDetail"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -682,7 +684,7 @@ public async Task RegisterChunkedFileAsync(FileChunkRegisterMo public async Task DeleteFileChunkDetailAsync(int fileChunkDetailId) { ApiResponse apiResponse = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/DeleteFileChunkDetail/{fileChunkDetailId}"; var response = await client.DeleteAsync(request).ConfigureAwait(false); @@ -814,7 +816,7 @@ public async Task UpdateVideoAssetAsync(VideoAssetViewModel model) var json = JsonConvert.SerializeObject(model); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"content/update-video-asset"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -844,7 +846,7 @@ public async Task UpdateVideoAssetAsync(VideoAssetViewModel model) /// The . public async Task CreatePageSectionAsync(PageSectionViewModel requestViewModel) { - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = "content/create-page-section/"; var content = new StringContent( JsonConvert.SerializeObject(requestViewModel), @@ -874,7 +876,7 @@ public async Task CreatePageSectionAsync(PageSectionViewModel requestViewMo /// The . public async Task UpdatePageSectionDetailAsync(PageSectionDetailViewModel updateViewModel) { - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = "content/update-page-section-detail/"; var content = new StringContent( JsonConvert.SerializeObject(updateViewModel), @@ -899,7 +901,7 @@ public async Task GetPageSectionDetailVideoAssetById { PageSectionDetailViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"content/page-section-detail-video/{id}"; var response = await client.GetAsync(request).ConfigureAwait(false); diff --git a/AdminUI/LearningHub.Nhs.AdminUI/Services/EventService.cs b/AdminUI/LearningHub.Nhs.AdminUI/Services/EventService.cs index 000fce940..db61e47e3 100644 --- a/AdminUI/LearningHub.Nhs.AdminUI/Services/EventService.cs +++ b/AdminUI/LearningHub.Nhs.AdminUI/Services/EventService.cs @@ -18,8 +18,9 @@ public class EventService : BaseService, IEventService /// Initializes a new instance of the class. /// /// The learningHubHttpClient. - public EventService(ILearningHubHttpClient learningHubHttpClient) - : base(learningHubHttpClient) + /// The openApiHttpClient. + public EventService(ILearningHubHttpClient learningHubHttpClient, IOpenApiHttpClient openApiHttpClient) + : base(learningHubHttpClient, openApiHttpClient) { } @@ -30,7 +31,7 @@ public async Task Create(Event eventEntity) var json = JsonConvert.SerializeObject(eventEntity); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Event/Create"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); diff --git a/AdminUI/LearningHub.Nhs.AdminUI/Services/HierarchyService.cs b/AdminUI/LearningHub.Nhs.AdminUI/Services/HierarchyService.cs index b408cb637..17b37999b 100644 --- a/AdminUI/LearningHub.Nhs.AdminUI/Services/HierarchyService.cs +++ b/AdminUI/LearningHub.Nhs.AdminUI/Services/HierarchyService.cs @@ -16,21 +16,21 @@ public class HierarchyService : BaseService, IHierarchyService /// /// Defines the _facade. /// - private readonly ILearningHubApiFacade facade; + private readonly IOpenApiFacade facade; /// /// Initializes a new instance of the class. /// /// The learning hub http client. - /// The learningHubApiFacade. + /// The openApiFacade. /// The logger. public HierarchyService( ILearningHubHttpClient learningHubHttpClient, - ILearningHubApiFacade learningHubApiFacade, + IOpenApiFacade openApiFacade, ILogger logger) : base(learningHubHttpClient) { - this.facade = learningHubApiFacade; + this.facade = openApiFacade; } /// diff --git a/AdminUI/LearningHub.Nhs.AdminUI/Services/OpenApiHttpClient.cs b/AdminUI/LearningHub.Nhs.AdminUI/Services/OpenApiHttpClient.cs new file mode 100644 index 000000000..5e8463cad --- /dev/null +++ b/AdminUI/LearningHub.Nhs.AdminUI/Services/OpenApiHttpClient.cs @@ -0,0 +1,39 @@ +namespace LearningHub.Nhs.AdminUI.Services +{ + using System.Net.Http; + using LearningHub.Nhs.AdminUI.Configuration; + using LearningHub.Nhs.AdminUI.Interfaces; + using LearningHub.Nhs.Caching; + using Microsoft.AspNetCore.Http; + using Microsoft.Extensions.Logging; + using Microsoft.Extensions.Options; + + /// + /// The open api http client. + /// + public class OpenApiHttpClient : BaseHttpClient, IOpenApiHttpClient + { + /// + /// Initializes a new instance of the class. + /// + /// The http context accessor. + /// The web settings. + /// The http client. + /// The logger. + /// The cache service. + public OpenApiHttpClient( + IHttpContextAccessor httpContextAccessor, + IOptions webSettings, + HttpClient client, + ILogger logger, + ICacheService cacheService) + : base(httpContextAccessor, webSettings.Value, client, logger, cacheService) + { + } + + /// + /// Gets the open api url. + /// + public override string ApiUrl => this.WebSettings.OpenApiUrl; + } +} diff --git a/AdminUI/LearningHub.Nhs.AdminUI/Services/ProviderService.cs b/AdminUI/LearningHub.Nhs.AdminUI/Services/ProviderService.cs index eeb6976f9..cfdc4050b 100644 --- a/AdminUI/LearningHub.Nhs.AdminUI/Services/ProviderService.cs +++ b/AdminUI/LearningHub.Nhs.AdminUI/Services/ProviderService.cs @@ -24,19 +24,20 @@ public class ProviderService : BaseService, IProviderService /// /// Defines the _facade. /// - private readonly ILearningHubApiFacade facade; + private readonly IOpenApiFacade facade; /// /// Initializes a new instance of the class. /// /// The cache service. /// Learning hub http client. - /// The learningHubApiFacade. - public ProviderService(ICacheService cacheService, ILearningHubHttpClient learningHubHttpClient, ILearningHubApiFacade learningHubApiFacade) + /// open api http client. + /// The openApiFacade. + public ProviderService(ICacheService cacheService, ILearningHubHttpClient learningHubHttpClient, IOpenApiHttpClient openApiHttpClient, IOpenApiFacade openApiFacade) : base(learningHubHttpClient) { this.cacheService = cacheService; - this.facade = learningHubApiFacade; + this.facade = openApiFacade; } /// diff --git a/AdminUI/LearningHub.Nhs.AdminUI/Services/ResourceService.cs b/AdminUI/LearningHub.Nhs.AdminUI/Services/ResourceService.cs index 4c6e3fe46..038681c64 100644 --- a/AdminUI/LearningHub.Nhs.AdminUI/Services/ResourceService.cs +++ b/AdminUI/LearningHub.Nhs.AdminUI/Services/ResourceService.cs @@ -24,8 +24,9 @@ public class ResourceService : BaseService, IResourceService /// Initializes a new instance of the class. /// /// The learningHubHttpClient. - public ResourceService(ILearningHubHttpClient learningHubHttpClient) - : base(learningHubHttpClient) + /// The openApiHttpClient. + public ResourceService(ILearningHubHttpClient learningHubHttpClient, IOpenApiHttpClient openApiHttpClient) + : base(learningHubHttpClient, openApiHttpClient) { } @@ -50,7 +51,7 @@ public async Task> GetResourc var filter = JsonConvert.SerializeObject(pagingRequestModel.Filter); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var json = JsonConvert.SerializeObject(pagingRequestModel); var stringContent = new StringContent(json, Encoding.UTF8, "application/json"); @@ -82,7 +83,7 @@ public async Task> GetResourceVersionEventsA { List viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetResourceVersionEvents/{resourceVersionId.ToString()}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -111,7 +112,7 @@ public async Task GetResourceVersionVa { ResourceVersionValidationResultViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetResourceVersionValidationResult/{resourceVersionId.ToString()}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -140,7 +141,7 @@ public async Task GetResourceVersionDevIdDetailsA { ResourceVersionDevIdViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetResourceVersionDevIdDetails/{resourceVersionId.ToString()}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -167,7 +168,7 @@ public async Task GetResourceVersionDevIdDetailsA /// The . public async Task DoesDevIdExistsAsync(string devId) { - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/DoesDevIdExists/{devId}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -198,7 +199,7 @@ public async Task UpdateDevIdDetailsAsync(ResourceVersionDevIdViewModel model) var json = JsonConvert.SerializeObject(model); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/UpdateDevId"; var response = await client.PutAsync(request, stringContent).ConfigureAwait(false); @@ -223,7 +224,7 @@ public async Task GetResourceVersionExtendedVi { ResourceVersionExtendedViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetResourceVersionExtendedViewModel/{resourceVersionId.ToString()}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -252,7 +253,7 @@ public async Task> GetResourceVersionsAsync(int r { List viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetResourceVersions/{resourceId.ToString()}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -283,7 +284,7 @@ public async Task RevertToDraft(int resourceVersion var json = JsonConvert.SerializeObject(new { resourceVersionId }); var stringContent = new StringContent(resourceVersionId.ToString(), Encoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/RevertToDraft"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -335,7 +336,7 @@ public async Task TransferResourceOwnership(int res var json = JsonConvert.SerializeObject(vm); var stringContent = new StringContent(json, Encoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/TransferResourceOwnership"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -382,7 +383,7 @@ public async Task UnpublishResourceVersionAsync(int var json = JsonConvert.SerializeObject(vm); var stringContent = new StringContent(json, Encoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/UnpublishResourceVersion"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -433,7 +434,7 @@ public async Task CreateResourceVersionEvent(int re var json = JsonConvert.SerializeObject(vm); var stringContent = new StringContent(json, Encoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/CreateResourceVersionEvent"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); diff --git a/AdminUI/LearningHub.Nhs.AdminUI/Services/UserGroupService.cs b/AdminUI/LearningHub.Nhs.AdminUI/Services/UserGroupService.cs index 45dff59de..0a941c761 100644 --- a/AdminUI/LearningHub.Nhs.AdminUI/Services/UserGroupService.cs +++ b/AdminUI/LearningHub.Nhs.AdminUI/Services/UserGroupService.cs @@ -32,15 +32,17 @@ public class UserGroupService : BaseService, IUserGroupService /// Initializes a new instance of the class. /// /// The learningHubHttpClient. + /// The Open Api Http Client. /// The http context accessor. /// The cacheService. /// The roleService. public UserGroupService( ILearningHubHttpClient learningHubHttpClient, + IOpenApiHttpClient openApiHttpClient, ICacheService cacheService, IRoleService roleService, IHttpContextAccessor contextAccessor) - : base(learningHubHttpClient) + : base(learningHubHttpClient, openApiHttpClient) { this.contextAccessor = contextAccessor; this.cacheService = cacheService; @@ -112,7 +114,7 @@ public async Task GetUserGroupAdminDetailbyIdAsyn { UserGroupAdminDetailViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"UserGroup/GetUserGroupAdminDetailById/{id}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -141,7 +143,7 @@ public async Task> GetUserGroupAdminRoleDetailByIdA { List viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"UserGroup/GetUserGroupAdminRoleDetailById/{id}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -171,7 +173,7 @@ public async Task CreateUserGroup(UserGroupAdminDet var json = JsonConvert.SerializeObject(userGroup); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"UserGroup/CreateUserGroup"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -214,7 +216,7 @@ public async Task UpdateUserGroup(UserGroupAdminDet var json = JsonConvert.SerializeObject(userGroup); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"UserGroup/UpdateUserGroup"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -258,7 +260,7 @@ public async Task DeleteUserGroup(int userGroupId) var json = JsonConvert.SerializeObject(userGroup); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"UserGroup/DeleteUserGroup"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -308,7 +310,7 @@ public async Task AddUsersToUserGroup(int userGroup var json = JsonConvert.SerializeObject(userUserGroups); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"UserGroup/AddUserUserGroups"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -359,7 +361,7 @@ public async Task AddUserGroupsToCatalogue(int cata var json = JsonConvert.SerializeObject(roleUserGroups); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"UserGroup/AddRoleUserGroups"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -403,7 +405,7 @@ public async Task DeleteUserUserGroup(int userUserG var json = JsonConvert.SerializeObject(userGroup); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"UserGroup/DeleteUserUserGroup"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -447,7 +449,7 @@ public async Task DeleteRoleUserGroup(int roleUserG var json = JsonConvert.SerializeObject(roleUserGroupUpdate); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"UserGroup/DeleteRoleUserGroup"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -502,7 +504,7 @@ public async Task> GetUserUserGroupPageAs var filter = JsonConvert.SerializeObject(pagingRequestModel.Filter); var presetFilter = JsonConvert.SerializeObject(pagingRequestModel.PresetFilter); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"UserGroup/GetUserUserGroupAdminFilteredPage" + $"/{pagingRequestModel.Page}" @@ -551,7 +553,7 @@ public async Task> GetRoleUserGroupPageAs var filter = JsonConvert.SerializeObject(pagingRequestModel.Filter); var presetFilter = JsonConvert.SerializeObject(pagingRequestModel.PresetFilter); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"UserGroup/GetRoleUserGroupAdminFilteredPage" + $"/{pagingRequestModel.Page}" @@ -598,7 +600,7 @@ private async Task> FetchRoleUserGroupDetailAsync() { List viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"UserGroup/GetUserGroupRoleDetail"; var response = await client.GetAsync(request).ConfigureAwait(false); diff --git a/AdminUI/LearningHub.Nhs.AdminUI/Services/UserService.cs b/AdminUI/LearningHub.Nhs.AdminUI/Services/UserService.cs index 7c64fd2c0..c84dbc2f2 100644 --- a/AdminUI/LearningHub.Nhs.AdminUI/Services/UserService.cs +++ b/AdminUI/LearningHub.Nhs.AdminUI/Services/UserService.cs @@ -31,10 +31,11 @@ public class UserService : BaseService, IUserService /// Initializes a new instance of the class. /// /// The learningHubHttpClient. + /// The openApiHttpClient . /// The CacheService . /// The userApiHttpClient . - public UserService(ILearningHubHttpClient learningHubHttpClient, ICacheService cacheService, IUserApiHttpClient userApiHttpClient) - : base(learningHubHttpClient) + public UserService(ILearningHubHttpClient learningHubHttpClient, IOpenApiHttpClient openApiHttpClient, ICacheService cacheService, IUserApiHttpClient userApiHttpClient) + : base(learningHubHttpClient, openApiHttpClient) { this.cacheService = cacheService; this.userApiHttpClient = userApiHttpClient; @@ -166,7 +167,7 @@ public async Task GetEmailAddressRegistrationStatusAsyn var filter = JsonConvert.SerializeObject(pagingRequestModel.Filter); var presetFilter = JsonConvert.SerializeObject(pagingRequestModel.PresetFilter); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"User/GetLHUserAdminBasicFilteredPage" + $"/{pagingRequestModel.Page}" @@ -274,7 +275,7 @@ public async Task> GetUserCon var modelString = JsonConvert.SerializeObject(pagingRequestModel); var content = new StringContent(modelString, Encoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetResourceAdminSearchFilteredPage"; @@ -459,7 +460,7 @@ public async Task AddUserGroupsToUser(int userId, s var json = JsonConvert.SerializeObject(userUserGroups); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"UserGroup/AddUserUserGroups"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -565,7 +566,7 @@ public async Task> GetUserLearni var filter = JsonConvert.SerializeObject(pagingRequestModel.Filter); var presetFilter = JsonConvert.SerializeObject(pagingRequestModel.PresetFilter); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"UserLearningRecord/GetUserLearningRecords" + $"/{pagingRequestModel.Page}" diff --git a/AdminUI/LearningHub.Nhs.AdminUI/appsettings.json b/AdminUI/LearningHub.Nhs.AdminUI/appsettings.json index b3a5c0f9c..95a04b8bc 100644 --- a/AdminUI/LearningHub.Nhs.AdminUI/appsettings.json +++ b/AdminUI/LearningHub.Nhs.AdminUI/appsettings.json @@ -17,6 +17,7 @@ "ELfhHubUrl": "", "LearningHubApiUrl": "", "UserApiUrl": "", + "OpenApiUrl": "", "LearningHubAdminUrl": "", "LogConfigDir": "D:\\learningHub\\NLog", "AuthenticationServiceUrl": "", diff --git a/AdminUI/LearningHub.Nhs.AdminUI/web.config b/AdminUI/LearningHub.Nhs.AdminUI/web.config deleted file mode 100644 index 6bcb74972..000000000 --- a/AdminUI/LearningHub.Nhs.AdminUI/web.config +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Directory.Build.props b/Directory.Build.props index 709a8ce13..c3a7f4e28 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -4,7 +4,7 @@ $(SolutionDir)StyleCop.ruleset - + \ No newline at end of file diff --git a/Directory.Packages.props b/Directory.Packages.props new file mode 100644 index 000000000..59413f8ea --- /dev/null +++ b/Directory.Packages.props @@ -0,0 +1,93 @@ + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/LearningHub.Nhs.WebUI.AutomatedUiTests/LearningHub.Nhs.WebUI.AutomatedUiTests.csproj b/LearningHub.Nhs.WebUI.AutomatedUiTests/LearningHub.Nhs.WebUI.AutomatedUiTests.csproj index d6bf3cd0d..1569f9734 100644 --- a/LearningHub.Nhs.WebUI.AutomatedUiTests/LearningHub.Nhs.WebUI.AutomatedUiTests.csproj +++ b/LearningHub.Nhs.WebUI.AutomatedUiTests/LearningHub.Nhs.WebUI.AutomatedUiTests.csproj @@ -1,37 +1,37 @@ - + - - net8.0 - enable - enable + + net8.0 + enable + enable - false + false - True - + True + - - - - - - - - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - + + + + + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + - - - + + + diff --git a/LearningHub.Nhs.WebUI.sln b/LearningHub.Nhs.WebUI.sln index 5aea6885f..55cce01f0 100644 --- a/LearningHub.Nhs.WebUI.sln +++ b/LearningHub.Nhs.WebUI.sln @@ -8,6 +8,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B5D48B6A-D4A7-494E-89C0-64428232D242}" ProjectSection(SolutionItems) = preProject Directory.Build.props = Directory.Build.props + Directory.Packages.props = Directory.Packages.props StyleCop.ruleset = StyleCop.ruleset EndProjectSection EndProject diff --git a/LearningHub.Nhs.WebUI/Configuration/Settings.cs b/LearningHub.Nhs.WebUI/Configuration/Settings.cs index ccb06c921..e300e80e3 100644 --- a/LearningHub.Nhs.WebUI/Configuration/Settings.cs +++ b/LearningHub.Nhs.WebUI/Configuration/Settings.cs @@ -31,6 +31,11 @@ public Settings() /// public string LearningHubApiUrl { get; set; } + /// + /// Gets or sets the OpenApiUrl. + /// + public string OpenApiUrl { get; set; } + /// /// Gets or sets the UserApiUrl. /// diff --git a/LearningHub.Nhs.WebUI/Controllers/Api/UserController.cs b/LearningHub.Nhs.WebUI/Controllers/Api/UserController.cs index 35294cc11..1f5330bbe 100644 --- a/LearningHub.Nhs.WebUI/Controllers/Api/UserController.cs +++ b/LearningHub.Nhs.WebUI/Controllers/Api/UserController.cs @@ -102,13 +102,13 @@ public async Task CheckUserRole() /// /// to check user password is correct. /// - /// The currentPassword. + /// The currentPassword. /// The . - [HttpGet] - [Route("ConfirmPassword/{currentPassword}")] - public async Task ConfirmPassword(string currentPassword) + [HttpPost] + [Route("ConfirmPassword")] + public async Task ConfirmPassword([FromBody] PasswordUpdateModel password) { - string passwordHash = this.userService.Base64MD5HashDigest(currentPassword); + string passwordHash = this.userService.Base64MD5HashDigest(password.PasswordHash); var userPersonalDetails = await this.userService.GetCurrentUserPersonalDetailsAsync(); if (userPersonalDetails != null && userPersonalDetails.PasswordHash == passwordHash) { diff --git a/LearningHub.Nhs.WebUI/Controllers/HomeController.cs b/LearningHub.Nhs.WebUI/Controllers/HomeController.cs index 7f40afe15..d5f53c00d 100644 --- a/LearningHub.Nhs.WebUI/Controllers/HomeController.cs +++ b/LearningHub.Nhs.WebUI/Controllers/HomeController.cs @@ -40,6 +40,7 @@ public class HomeController : BaseController private readonly IDashboardService dashboardService; private readonly IContentService contentService; private readonly IFeatureManager featureManager; + private readonly IUserGroupService userGroupService; private readonly Microsoft.Extensions.Configuration.IConfiguration configuration; /// @@ -55,6 +56,7 @@ public class HomeController : BaseController /// Dashboard service. /// Content service. /// featureManager. + /// userGroupService. /// config. public HomeController( IHttpClientFactory httpClientFactory, @@ -67,6 +69,7 @@ public HomeController( IDashboardService dashboardService, IContentService contentService, IFeatureManager featureManager, + IUserGroupService userGroupService, Microsoft.Extensions.Configuration.IConfiguration configuration) : base(hostingEnvironment, httpClientFactory, logger, settings.Value) { @@ -76,6 +79,7 @@ public HomeController( this.dashboardService = dashboardService; this.contentService = contentService; this.featureManager = featureManager; + this.userGroupService = userGroupService; this.configuration = configuration; } @@ -212,6 +216,7 @@ public async Task Index(string myLearningDashboard = "my-in-progr var learningTask = this.dashboardService.GetMyAccessLearningsAsync(myLearningDashboard, 1); var resourcesTask = this.dashboardService.GetResourcesAsync(resourceDashboard, 1); var cataloguesTask = this.dashboardService.GetCataloguesAsync(catalogueDashboard, 1); + var userGroupsTask = this.userGroupService.UserHasCatalogueContributionPermission(); var enrolledCoursesTask = Task.FromResult(new List()); var enableMoodle = Task.Run(() => this.featureManager.IsEnabledAsync(FeatureFlags.EnableMoodle)).Result; @@ -222,7 +227,7 @@ public async Task Index(string myLearningDashboard = "my-in-progr enrolledCoursesTask = this.dashboardService.GetEnrolledCoursesFromMoodleAsync(this.CurrentMoodleUserId, 1); } - await Task.WhenAll(learningTask, resourcesTask, cataloguesTask); + await Task.WhenAll(learningTask, resourcesTask, cataloguesTask, userGroupsTask); var model = new DashboardViewModel() { @@ -231,7 +236,8 @@ public async Task Index(string myLearningDashboard = "my-in-progr Catalogues = await cataloguesTask, EnrolledCourses = await enrolledCoursesTask, }; - + var userHasContributePermission = await userGroupsTask; + this.ViewBag.userHasContributePermission = userHasContributePermission; if (!string.IsNullOrEmpty(this.Request.Query["preview"]) && Convert.ToBoolean(this.Request.Query["preview"])) { return this.View("LandingPage", await this.GetLandingPageContent(Convert.ToBoolean(this.Request.Query["preview"]))); @@ -274,6 +280,10 @@ public async Task LoadPage(string dashBoardTray = "my-learning", Catalogues = new Nhs.Models.Dashboard.DashboardCatalogueResponseViewModel { Type = catalogueDashBoard }, }; + var enableMoodle = Task.Run(() => this.featureManager.IsEnabledAsync(FeatureFlags.EnableMoodle)).Result; + this.ViewBag.EnableMoodle = enableMoodle; + this.ViewBag.ValidMoodleUser = this.CurrentMoodleUserId > 0; + bool isAjax = this.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest"; if (isAjax) @@ -368,7 +378,7 @@ public IActionResult UserLogout() [AllowAnonymous] public IActionResult Logout() { - var redirectUri = $"{this.configuration["LearningHubAuthServiceConfig:Authority"]}/Home/SetIsPasswordUpdate?isLogout=true"; + var redirectUri = $"{this.configuration["LearningHubAuthServiceConfig:Authority"]}/Home/SetIsPasswordUpdate?isPasswordUpdate=false"; return this.Redirect(redirectUri); } diff --git a/LearningHub.Nhs.WebUI/Controllers/MyAccountController.cs b/LearningHub.Nhs.WebUI/Controllers/MyAccountController.cs index 6fd57f208..d1dadb902 100644 --- a/LearningHub.Nhs.WebUI/Controllers/MyAccountController.cs +++ b/LearningHub.Nhs.WebUI/Controllers/MyAccountController.cs @@ -458,7 +458,7 @@ public async Task UpdatePassword(ChangePasswordViewModel model) if (this.ModelState.IsValid) { await this.userService.UpdatePassword(model.NewPassword); - var redirectUri = $"{this.configuration["LearningHubAuthServiceConfig:Authority"]}/Home/SetIsPasswordUpdate?isLogout=false"; + var redirectUri = $"{this.configuration["LearningHubAuthServiceConfig:Authority"]}/Home/SetIsPasswordUpdate?isPasswordUpdate=true"; return this.Redirect(redirectUri); } else diff --git a/LearningHub.Nhs.WebUI/Controllers/SearchController.cs b/LearningHub.Nhs.WebUI/Controllers/SearchController.cs index ff1afba0d..a7b53fb11 100644 --- a/LearningHub.Nhs.WebUI/Controllers/SearchController.cs +++ b/LearningHub.Nhs.WebUI/Controllers/SearchController.cs @@ -81,7 +81,7 @@ public async Task Index(SearchRequestViewModel search, bool noSor if (filterApplied) { - await this.searchService.RegisterSearchEventsAsync(search, SearchFormActionTypeEnum.ApplyFilter, searchResult.ResourceSearchResult.TotalHits); + await this.searchService.RegisterSearchEventsAsync(search, SearchFormActionTypeEnum.ApplyFilter, searchResult.ResourceSearchResult?.TotalHits ?? 0); } if (noSortFilterError) diff --git a/LearningHub.Nhs.WebUI/Helpers/IOpenApiFacade.cs b/LearningHub.Nhs.WebUI/Helpers/IOpenApiFacade.cs new file mode 100644 index 000000000..a603461c7 --- /dev/null +++ b/LearningHub.Nhs.WebUI/Helpers/IOpenApiFacade.cs @@ -0,0 +1,59 @@ +namespace LearningHub.Nhs.WebUI.Helpers +{ + using System.Threading.Tasks; + using LearningHub.Nhs.Models.Common; + + /// + /// Defines the . + /// + public interface IOpenApiFacade + { + /// + /// The GetAsync. + /// + /// The type. + /// The url. + /// The . + Task GetAsync(string url) + where T : class, new(); + + /// + /// The PostAsync. + /// + /// The type. + /// The url. + /// The body. + /// The . + Task PostAsync(string url, T body) + where T : class, new(); + + /// + /// The PostAsync. + /// + /// The type. + /// . + /// The url. + /// The body. + /// The . + Task PostAsync(string url, TBody body) + where T : class, new() + where TBody : class, new(); + + /// + /// The PutAsync. + /// + /// The url. + /// The . + Task PutAsync(string url); + + /// + /// The PutAsync. + /// + /// . + /// The url. + /// The body. + /// The . + Task PutAsync(string url, T body) + where T : class, new(); + } +} diff --git a/LearningHub.Nhs.WebUI/Helpers/OpenApiFacade.cs b/LearningHub.Nhs.WebUI/Helpers/OpenApiFacade.cs new file mode 100644 index 000000000..32c529a0d --- /dev/null +++ b/LearningHub.Nhs.WebUI/Helpers/OpenApiFacade.cs @@ -0,0 +1,241 @@ +namespace LearningHub.Nhs.WebUI.Helpers +{ + using System; + using System.Net.Http; + using System.Text; + using System.Threading.Tasks; + using LearningHub.Nhs.Models.Common; + using LearningHub.Nhs.WebUI.Interfaces; + using Newtonsoft.Json; + + /// + /// Defines the . + /// + public class OpenApiFacade : IOpenApiFacade + { + /// + /// Defines the _client. + /// + private readonly IOpenApiHttpClient client; + + /// + /// Initializes a new instance of the class. + /// + /// The client. + public OpenApiFacade(IOpenApiHttpClient client) + { + this.client = client; + } + + /// + /// The GetAsync. + /// + /// . + /// The url. + /// The . + public async Task GetAsync(string url) + where T : class, new() + { + var client = await this.client.GetClientAsync(); + + var vm = new T(); + + var response = await client.GetAsync(url).ConfigureAwait(false); + + if (response.IsSuccessStatusCode) + { + var result = response.Content.ReadAsStringAsync().Result; + vm = JsonConvert.DeserializeObject(result); + + return vm; + } + else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized + || + response.StatusCode == System.Net.HttpStatusCode.Forbidden) + { + throw new Exception("AccessDenied"); + } + else + { + throw new Exception($"Exception HttpStatusCode={response.StatusCode}"); + } + } + + /// + /// The PostAsync. + /// + /// . + /// The url. + /// The body. + /// The . + public async Task PostAsync(string url, T body) + where T : class, new() + { + var client = await this.client.GetClientAsync(); + + var content = new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json"); + var response = await client.PostAsync(url, content).ConfigureAwait(false); + + if (response.IsSuccessStatusCode) + { + return; + } + else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized + || + response.StatusCode == System.Net.HttpStatusCode.Forbidden) + { + throw new Exception("AccessDenied"); + } + else + { + throw new Exception($"Exception HttpStatusCode={response.StatusCode}"); + } + } + + /// + /// The PostAsync. + /// + /// The return type. + /// The type of body parameter. + /// The url. + /// The body. + /// The . + public async Task PostAsync(string url, TBody body) + where TBody : class, new() + where T : class, new() + { + var client = await this.client.GetClientAsync(); + + var vm = new T(); + var content = new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json"); + var response = await client.PostAsync(url, content).ConfigureAwait(false); + + if (response.IsSuccessStatusCode) + { + var result = response.Content.ReadAsStringAsync().Result; + var apiResponse = JsonConvert.DeserializeObject(result); + if (apiResponse.Success) + { + return apiResponse; + } + else + { + string details = string.Empty; + if (apiResponse.ValidationResult != null) + { + if (apiResponse.ValidationResult.Details != null) + { + details = $"::ValidationResult: {string.Join(",", apiResponse.ValidationResult.Details)}"; + } + } + + throw new Exception($"PostAsync ApiResponse returned False: {details}"); + } + } + else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized + || + response.StatusCode == System.Net.HttpStatusCode.Forbidden) + { + throw new Exception("Access Denied"); + } + else + { + throw new Exception($"Exception HttpStatusCode={response.StatusCode}"); + } + } + + /// + /// The PutAsync. + /// + /// The url. + /// The . + public async Task PutAsync(string url) + { + var client = await this.client.GetClientAsync(); + + var response = await client.PutAsync(url, null).ConfigureAwait(false); + + if (response.IsSuccessStatusCode) + { + var result = response.Content.ReadAsStringAsync().Result; + var apiResponse = JsonConvert.DeserializeObject(result); + if (apiResponse.Success) + { + return apiResponse; + } + else + { + string details = string.Empty; + if (apiResponse.ValidationResult != null) + { + if (apiResponse.ValidationResult.Details != null) + { + details = $"::ValidationResult: {string.Join(",", apiResponse.ValidationResult.Details)}"; + } + } + + throw new Exception($"PutAsync ApiResponse returned False: {details}"); + } + } + else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized + || + response.StatusCode == System.Net.HttpStatusCode.Forbidden) + { + throw new Exception("Access Denied"); + } + else + { + throw new Exception($"Exception HttpStatusCode={response.StatusCode}"); + } + } + + /// + /// The PutAsync. + /// + /// . + /// The url. + /// The body. + /// The . + public async Task PutAsync(string url, T body) + where T : class, new() + { + var client = await this.client.GetClientAsync(); + + var content = new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json"); + var response = await client.PutAsync(url, content).ConfigureAwait(false); + + if (response.IsSuccessStatusCode) + { + var result = response.Content.ReadAsStringAsync().Result; + var apiResponse = JsonConvert.DeserializeObject(result); + if (apiResponse.Success) + { + return apiResponse; + } + else + { + string details = string.Empty; + if (apiResponse.ValidationResult != null) + { + if (apiResponse.ValidationResult.Details != null) + { + details = $"::ValidationResult: {string.Join(",", apiResponse.ValidationResult.Details)}"; + } + } + + throw new Exception($"PutAsync ApiResponse returned False: {details}"); + } + } + else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized + || + response.StatusCode == System.Net.HttpStatusCode.Forbidden) + { + throw new Exception("Access Denied"); + } + else + { + throw new Exception($"Exception HttpStatusCode={response.StatusCode}"); + } + } + } +} diff --git a/LearningHub.Nhs.WebUI/Helpers/ViewActivityHelper.cs b/LearningHub.Nhs.WebUI/Helpers/ViewActivityHelper.cs index 8d17307cf..f3bd9259c 100644 --- a/LearningHub.Nhs.WebUI/Helpers/ViewActivityHelper.cs +++ b/LearningHub.Nhs.WebUI/Helpers/ViewActivityHelper.cs @@ -84,7 +84,15 @@ public static string GetResourceTypeVerb(this ActivityDetailedItemViewModel acti case ResourceTypeEnum.Article: return "Read"; case ResourceTypeEnum.Audio: - return "Played " + GetDurationText(activityDetailedItemViewModel.ActivityDurationSeconds * 1000); + if ((activityDetailedItemViewModel.ActivityDurationSeconds * 1000) > activityDetailedItemViewModel.ResourceDurationMilliseconds) + { + return "Played " + GetDurationText(activityDetailedItemViewModel.ResourceDurationMilliseconds); + } + else + { + return "Played " + GetDurationText(activityDetailedItemViewModel.ActivityDurationSeconds * 1000); + } + case ResourceTypeEnum.Embedded: return string.Empty; case ResourceTypeEnum.Equipment: @@ -112,7 +120,15 @@ public static string GetResourceTypeVerb(this ActivityDetailedItemViewModel acti } case ResourceTypeEnum.Video: - return "Played " + GetDurationText(activityDetailedItemViewModel.ActivityDurationSeconds * 1000); + if ((activityDetailedItemViewModel.ActivityDurationSeconds * 1000) > activityDetailedItemViewModel.ResourceDurationMilliseconds) + { + return "Played " + GetDurationText(activityDetailedItemViewModel.ResourceDurationMilliseconds); + } + else + { + return "Played " + GetDurationText(activityDetailedItemViewModel.ActivityDurationSeconds * 1000); + } + case ResourceTypeEnum.WebLink: return "Visited"; case ResourceTypeEnum.Html: diff --git a/LearningHub.Nhs.WebUI/Interfaces/IOpenApiHttpClient.cs b/LearningHub.Nhs.WebUI/Interfaces/IOpenApiHttpClient.cs new file mode 100644 index 000000000..4c53a2c38 --- /dev/null +++ b/LearningHub.Nhs.WebUI/Interfaces/IOpenApiHttpClient.cs @@ -0,0 +1,17 @@ +namespace LearningHub.Nhs.WebUI.Interfaces +{ + using System.Net.Http; + using System.Threading.Tasks; + + /// + /// The OpenApiHttpClient interface. + /// + public interface IOpenApiHttpClient + { + /// + /// The get client. + /// + /// The . + Task GetClientAsync(); + } +} diff --git a/LearningHub.Nhs.WebUI/Interfaces/IUserGroupService.cs b/LearningHub.Nhs.WebUI/Interfaces/IUserGroupService.cs index a333e0c89..eadae3363 100644 --- a/LearningHub.Nhs.WebUI/Interfaces/IUserGroupService.cs +++ b/LearningHub.Nhs.WebUI/Interfaces/IUserGroupService.cs @@ -22,6 +22,12 @@ public interface IUserGroupService /// The . Task> GetRoleUserGroupDetailForUserAsync(int userId); + /// + /// The UserHasCatalogueContributionPermission. + /// + /// The . + Task UserHasCatalogueContributionPermission(); + /// /// Check if user has given permission. /// diff --git a/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute-resource/Contribute.vue b/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute-resource/Contribute.vue index f25aa0b7f..56c01dce8 100644 --- a/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute-resource/Contribute.vue +++ b/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute-resource/Contribute.vue @@ -432,7 +432,7 @@ return this.resourceDetails.resourceLicenceId > 0; }, locationTabComplete(): boolean { - return this.resourceDetails.resourceCatalogueId > 0; + return this.resourceDetails.resourceCatalogueId > 1; }, certificateTabComplete(): boolean { return this.resourceDetails.certificateEnabled !== null; diff --git a/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute-resource/ContributeAssessmentSettings.vue b/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute-resource/ContributeAssessmentSettings.vue index 088f74c90..bc7de0277 100644 --- a/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute-resource/ContributeAssessmentSettings.vue +++ b/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute-resource/ContributeAssessmentSettings.vue @@ -74,9 +74,7 @@ + :initialValue="endGuidance"/>

Tip

diff --git a/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute-resource/ContributeLocationTab.vue b/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute-resource/ContributeLocationTab.vue index a66944a40..5cb06877d 100644 --- a/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute-resource/ContributeLocationTab.vue +++ b/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute-resource/ContributeLocationTab.vue @@ -7,33 +7,57 @@

Primary catalogue

- +
- -
- + + + + +
+ +
+ +
+ + +
- \ No newline at end of file + diff --git a/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute/CatalogueSelect.vue b/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute/CatalogueSelect.vue index 379e9572a..8754e4e0c 100644 --- a/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute/CatalogueSelect.vue +++ b/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute/CatalogueSelect.vue @@ -26,8 +26,7 @@ A catalogue is a curated set of resources that has its own web page.

- You can contribute a resource as an editor of a catalogue or in your own name. - To contribute a resource in your own name, select Community contributions from the drop down menu. + You can contribute a resource as an editor of a catalogue.

You can manage all resources that you have contributed in the My contributions area. @@ -46,9 +45,11 @@ -

- You have selected a hidden catalogue. - If you publish this resource, learners will only be able to access it when the catalogue is made available by Learning Hub platform administrators. +
+
+ You have selected a hidden catalogue. + If you publish this resource, learners will only be able to access it when the catalogue is made available by Learning Hub platform administrators. +
@@ -88,9 +89,12 @@ }, }, created() { - if (this.value > 0) { + if (this.value > 1) { this.selectedCatalogue = this.userCatalogues.find(c => c.nodeId == this.value); } + else { + this.selectedCatalogue = new CatalogueModel({ nodeId: 0 }); + } } }) diff --git a/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute/ContentCommon.vue b/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute/ContentCommon.vue index 338817b8b..1d1534528 100644 --- a/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute/ContentCommon.vue +++ b/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute/ContentCommon.vue @@ -83,7 +83,7 @@
-

+

@@ -243,7 +243,7 @@
- + @@ -314,11 +314,11 @@ return this.$store.state.userProviders; }, resourceCatalogueCount(): number { - if (!this.$store.state.userCatalogues) { + if (!this.$store.state.userCatalogues) { return 0; } else { return this.$store.state.userCatalogues.length; - } + } }, userIsAuthor(): boolean { return this.authors.filter(a => a.isContributor).length > 0; diff --git a/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute/contributeState.ts b/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute/contributeState.ts index e4bdf763a..0ccb4ce69 100644 --- a/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute/contributeState.ts +++ b/LearningHub.Nhs.WebUI/Scripts/vuesrc/contribute/contributeState.ts @@ -114,7 +114,7 @@ const setCommonContentState = function (state: State) { && state.resourceDetail.resourceAccessibilityEnum !== ResourceAccessibility.None && state.resourceDetail.description !== '' && (state.resourceDetail.resourceLicenceId > 0 || state.resourceDetail.resourceType === ResourceType.WEBLINK) - && state.resourceDetail.resourceCatalogueId > 0 + && state.resourceDetail.resourceCatalogueId > 1 && state.resourceDetail.resourceAuthors.length > 0 && state.resourceDetail.certificateEnabled !== null && state.resourceDetail.resourceKeywords.length > 0; diff --git a/LearningHub.Nhs.WebUI/Scripts/vuesrc/data/user.ts b/LearningHub.Nhs.WebUI/Scripts/vuesrc/data/user.ts index 9f50357fc..e38fd4a08 100644 --- a/LearningHub.Nhs.WebUI/Scripts/vuesrc/data/user.ts +++ b/LearningHub.Nhs.WebUI/Scripts/vuesrc/data/user.ts @@ -67,15 +67,15 @@ const IsSystemAdmin = async function (): Promise { }; const IsValidUser = async function (currentPassword: string): Promise { - var IsValidUser = `/api/User/ConfirmPassword/${currentPassword}`; - return await AxiosWrapper.axios.get(IsValidUser) - .then(response => { - return response.data; - }) - .catch(e => { - console.log('IsValidUser:' + e); - throw e; + try { + const response = await AxiosWrapper.axios.post('/api/User/ConfirmPassword', { + PasswordHash: currentPassword }); + return response.data; + } catch (e) { + console.error('IsValidUser:', e); + throw e; + } }; const getCurrentUserBasicDetails = async function (): Promise { diff --git a/LearningHub.Nhs.WebUI/Services/ActivityService.cs b/LearningHub.Nhs.WebUI/Services/ActivityService.cs index a494bea91..185dc3a2c 100644 --- a/LearningHub.Nhs.WebUI/Services/ActivityService.cs +++ b/LearningHub.Nhs.WebUI/Services/ActivityService.cs @@ -21,9 +21,10 @@ public class ActivityService : BaseService, IActivityService /// Initializes a new instance of the class. ///
/// Learning hub http client. + /// OpenApiHttpClient http client. /// Logger. - public ActivityService(ILearningHubHttpClient learningHubHttpClient, ILogger logger) - : base(learningHubHttpClient, logger) + public ActivityService(ILearningHubHttpClient learningHubHttpClient, IOpenApiHttpClient openApiHttpClient, ILogger logger) + : base(learningHubHttpClient, openApiHttpClient, logger) { } diff --git a/LearningHub.Nhs.WebUI/Services/AzureMediaService.cs b/LearningHub.Nhs.WebUI/Services/AzureMediaService.cs index 6068bc067..f2877b9eb 100644 --- a/LearningHub.Nhs.WebUI/Services/AzureMediaService.cs +++ b/LearningHub.Nhs.WebUI/Services/AzureMediaService.cs @@ -71,7 +71,7 @@ public async Task CreateMediaInputAsset(IFormFile file) string filename = Regex.Replace(file.FileName, "[^a-zA-Z0-9.]", string.Empty); var destContainer = new BlobContainerClient(new Uri(uploadSasUrl)); - var destBlob = destContainer.GetBlockBlobClient(filename.IsNullOrEmpty() ? "file.txt" : filename); + var destBlob = destContainer.GetBlockBlobClient(string.IsNullOrEmpty(filename) ? "file.txt" : filename); await destBlob.UploadAsync(file.OpenReadStream()); return asset.Name; diff --git a/LearningHub.Nhs.WebUI/Services/BaseService.cs b/LearningHub.Nhs.WebUI/Services/BaseService.cs index 87d4cfc79..ddcbad86f 100644 --- a/LearningHub.Nhs.WebUI/Services/BaseService.cs +++ b/LearningHub.Nhs.WebUI/Services/BaseService.cs @@ -11,6 +11,7 @@ public abstract class BaseService { private readonly ILogger logger; private readonly ILearningHubHttpClient learningHubHttpClient; + private readonly IOpenApiHttpClient openApiHttpClient; /// /// Initializes a new instance of the class. @@ -23,11 +24,29 @@ protected BaseService(ILearningHubHttpClient learningHubHttpClient, ILogger l this.logger = logger; } + /// + /// Initializes a new instance of the class. + /// + /// The learningHubHttpClient. + /// The openApiHttpClient. + /// The logger. + protected BaseService(ILearningHubHttpClient learningHubHttpClient, IOpenApiHttpClient openApiHttpClient, ILogger logger) + { + this.learningHubHttpClient = learningHubHttpClient; + this.openApiHttpClient = openApiHttpClient; + this.logger = logger; + } + /// /// Gets the LearningHubHttpClient. /// protected ILearningHubHttpClient LearningHubHttpClient => this.learningHubHttpClient; + /// + /// Gets the OpenApiHttpClient. + /// + protected IOpenApiHttpClient OpenApiHttpClient => this.openApiHttpClient; + /// /// Gets the Logger. /// diff --git a/LearningHub.Nhs.WebUI/Services/BoomarkService.cs b/LearningHub.Nhs.WebUI/Services/BoomarkService.cs index 5a26148cc..15d5509f9 100644 --- a/LearningHub.Nhs.WebUI/Services/BoomarkService.cs +++ b/LearningHub.Nhs.WebUI/Services/BoomarkService.cs @@ -19,16 +19,17 @@ public class BoomarkService : BaseService, IBookmarkService /// Initializes a new instance of the class. /// /// The learningHubHttpClient. + /// The openApiHttpClient. /// The logger. - public BoomarkService(ILearningHubHttpClient learningHubHttpClient, ILogger logger) - : base(learningHubHttpClient, logger) + public BoomarkService(ILearningHubHttpClient learningHubHttpClient, IOpenApiHttpClient openApiHttpClient, ILogger logger) + : base(learningHubHttpClient, openApiHttpClient, logger) { } /// public async Task Create(UserBookmarkViewModel bookmarkViewModel) { - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = "bookmark/Create"; var content = new StringContent( JsonConvert.SerializeObject(bookmarkViewModel), @@ -56,7 +57,7 @@ public async Task Create(UserBookmarkViewModel bookmarkViewModel) /// public async Task Edit(UserBookmarkViewModel bookmarkViewModel) { - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = "bookmark/Edit"; var content = new StringContent( JsonConvert.SerializeObject(bookmarkViewModel), @@ -84,7 +85,7 @@ public async Task Edit(UserBookmarkViewModel bookmarkViewModel) /// public async Task DeleteFolder(int bookmarkId) { - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"bookmark/deletefolder/{bookmarkId}"; var response = await client.DeleteAsync(request).ConfigureAwait(false); if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized @@ -98,7 +99,7 @@ public async Task DeleteFolder(int bookmarkId) /// public async Task> GetAllByParent(int? parentId, bool? all = false) { - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"bookmark/GetAllByParent/{parentId}?all={all}"; var response = await client.GetAsync(request).ConfigureAwait(false); if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized @@ -120,7 +121,7 @@ public async Task> GetAllByParent(int? parent /// public async Task Toggle(UserBookmarkViewModel bookmarkViewModel) { - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = "bookmark/toggle"; var content = new StringContent( JsonConvert.SerializeObject(bookmarkViewModel), diff --git a/LearningHub.Nhs.WebUI/Services/CardService.cs b/LearningHub.Nhs.WebUI/Services/CardService.cs index d0795c0ad..d3aac0616 100644 --- a/LearningHub.Nhs.WebUI/Services/CardService.cs +++ b/LearningHub.Nhs.WebUI/Services/CardService.cs @@ -19,9 +19,10 @@ public class CardService : BaseService, ICardService /// Initializes a new instance of the class. /// /// The Learning Hub Http Client. + /// The Open Api Http Client. /// The logger. - public CardService(ILearningHubHttpClient learningHubHttpClient, ILogger logger) - : base(learningHubHttpClient, logger) + public CardService(ILearningHubHttpClient learningHubHttpClient, IOpenApiHttpClient openApiHttpClient, ILogger logger) + : base(learningHubHttpClient, openApiHttpClient, logger) { } @@ -34,7 +35,7 @@ public async Task GetMyContributionsTotalsAsync( { MyContributionsTotalsViewModel totals = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetMyContributionsTotals/{catalogueId.ToString()}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -63,7 +64,7 @@ public async Task> GetContributionsAsync( { List myContributionCards = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var json = JsonConvert.SerializeObject(resourceContributionsRequestViewModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); @@ -94,7 +95,7 @@ public async Task GetMyResourceViewModelAsync() { MyResourceViewModel myresourcecards = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetMyResourceViewModel"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -123,7 +124,7 @@ public async Task GetResourceCardExtendedViewMode { ResourceCardExtendedViewModel resourceCardExtendedViewModel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/ResourceCardExtendedViewModel/{id.ToString()}"; var response = await client.GetAsync(request).ConfigureAwait(false); diff --git a/LearningHub.Nhs.WebUI/Services/CatalogueService.cs b/LearningHub.Nhs.WebUI/Services/CatalogueService.cs index a8a6d3055..3833a4e28 100644 --- a/LearningHub.Nhs.WebUI/Services/CatalogueService.cs +++ b/LearningHub.Nhs.WebUI/Services/CatalogueService.cs @@ -25,10 +25,11 @@ public class CatalogueService : BaseService, ICatalogueService /// Initializes a new instance of the class. /// /// The learning hub http client. + /// The Open Api Http Client. /// The logger. /// The cacheService. - public CatalogueService(ILearningHubHttpClient learningHubHttpClient, ILogger logger, ICacheService cacheService) - : base(learningHubHttpClient, logger) + public CatalogueService(ILearningHubHttpClient learningHubHttpClient, IOpenApiHttpClient openApiHttpClient, ILogger logger, ICacheService cacheService) + : base(learningHubHttpClient, openApiHttpClient, logger) { this.cacheService = cacheService; } @@ -41,7 +42,7 @@ public async Task> GetCataloguesForUserAsync() { List viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Catalogue/GetForCurrentUser"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -70,7 +71,7 @@ public async Task GetCatalogueAsync(string reference) { CatalogueViewModel viewmodel = new CatalogueViewModel { }; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"catalogue/catalogue/{reference}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -98,7 +99,7 @@ public async Task GetCatalogueAsync(int catalogueNodeVersion { CatalogueViewModel viewmodel = new CatalogueViewModel { }; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"catalogue/catalogues/{catalogueNodeVersionId}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -126,7 +127,7 @@ public async Task GetCatalogueRecordedAsync(string reference { CatalogueViewModel viewmodel = new CatalogueViewModel { }; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"catalogue/catalogue-recorded/{reference}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -154,7 +155,7 @@ public async Task GetResourcesAsync(Catalogu { CatalogueResourceResponseViewModel viewmodel = new CatalogueResourceResponseViewModel { }; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var json = JsonConvert.SerializeObject(requestViewModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); @@ -185,7 +186,7 @@ public async Task CanCurrentUserEditCatalogue(int catalogueId) { var request = $"Catalogue/CanCurrentUserEditCatalogue/{catalogueId}"; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var response = await client.GetAsync(request).ConfigureAwait(false); var catalogueIsEditable = false; @@ -213,7 +214,7 @@ public async Task AccessDetailsAsync(string ref { var request = $"Catalogue/AccessDetails/{reference}"; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var response = await client.GetAsync(request).ConfigureAwait(false); var accessDetails = new CatalogueAccessDetailsViewModel(); @@ -241,7 +242,7 @@ public async Task GetLatestCatalogueAccessReque { var request = $"Catalogue/GetLatestCatalogueAccessRequest/{catalogueNodeId}"; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var response = await client.GetAsync(request).ConfigureAwait(false); var car = new CatalogueAccessRequestViewModel(); @@ -275,7 +276,7 @@ public async Task RequestAccessAsync(string referen { var request = $"Catalogue/RequestAccess/{reference}/{accessType}"; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var content = new StringContent(JsonConvert.SerializeObject(vm), Encoding.UTF8, "application/json"); var response = await client.PostAsync(request, content).ConfigureAwait(false); var catalogueAccessRequested = false; @@ -308,7 +309,7 @@ public async Task InviteUserAsync(RestrictedCatalog { var request = $"Catalogue/InviteUser"; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var content = new StringContent(JsonConvert.SerializeObject(vm), Encoding.UTF8, "application/json"); var response = await client.PostAsync(request, content).ConfigureAwait(false); var catalogueAccessRequested = false; @@ -344,7 +345,7 @@ public async Task> GetRestricted var json = JsonConvert.SerializeObject(requestModel); var stringContent = new StringContent(json, Encoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Catalogue/GetRestrictedCatalogueAccessRequests"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -377,7 +378,7 @@ public async Task GetRestrictedCatalogueSum { var viewmodel = new RestrictedCatalogueSummaryViewModel(); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"catalogue/GetRestrictedCatalogueSummary/{catalogueNodeId}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -412,7 +413,7 @@ public async Task GetRestrictedCatalogueUsers var json = JsonConvert.SerializeObject(requestModel); var stringContent = new StringContent(json, Encoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Catalogue/GetRestrictedCatalogueUsers"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -446,7 +447,7 @@ public async Task AcceptAccessRequestAsync(int acce { var request = $"Catalogue/AcceptAccessRequest/{accessRequestId}"; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var content = new StringContent(JsonConvert.SerializeObject(new { })); var response = await client.PostAsync(request, content).ConfigureAwait(false); var catalogueAccessRequested = new LearningHubValidationResult(); @@ -478,7 +479,7 @@ public async Task RejectAccessRequestAsync(int acce { var request = $"Catalogue/RejectAccessRequest/{accessRequestId}"; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var content = new StringContent(JsonConvert.SerializeObject(new CatalogueAccessRejectionViewModel { RejectionReason = rejectionReason }), Encoding.UTF8, "application/json"); var response = await client.PostAsync(request, content).ConfigureAwait(false); var vr = new LearningHubValidationResult(); @@ -507,7 +508,7 @@ public async Task DismissAccessRequestAsync(int cat { var request = $"Catalogue/DismissAccessRequest/{catalogueNodeId}"; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var content = new StringContent(JsonConvert.SerializeObject(new { })); var response = await client.PostAsync(request, content).ConfigureAwait(false); var vr = new LearningHubValidationResult(false); @@ -536,7 +537,7 @@ public async Task GetCatalogueAccessRequestAsyn { var request = $"Catalogue/AccessRequest/{catalogueAccessRequestId}"; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var response = await client.GetAsync(request).ConfigureAwait(false); var catalogueAccessRequest = new CatalogueAccessRequestViewModel(); @@ -570,7 +571,7 @@ public async Task RemoveUserFromRestrictedAccessUse var json = JsonConvert.SerializeObject(userGroup); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"UserGroup/DeleteUserUserGroup"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -611,7 +612,7 @@ public async Task RemoveUserFromRestrictedAccessUse public async Task GetAllCatalogueAsync(string filterChar) { AllCatalogueResponseViewModel viewmodel = new AllCatalogueResponseViewModel { }; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"catalogue/allcatalogues/{filterChar}"; var response = await client.GetAsync(request).ConfigureAwait(false); diff --git a/LearningHub.Nhs.WebUI/Services/ContentService.cs b/LearningHub.Nhs.WebUI/Services/ContentService.cs index 92fe7a7dd..b6d1f9296 100644 --- a/LearningHub.Nhs.WebUI/Services/ContentService.cs +++ b/LearningHub.Nhs.WebUI/Services/ContentService.cs @@ -18,10 +18,11 @@ public class ContentService : BaseService, IContentService /// Initializes a new instance of the class. /// /// Learning hub http client. + /// The Open Api Http Client. /// Logger. /// azureMediaService. - public ContentService(ILearningHubHttpClient learningHubHttpClient, ILogger logger, IAzureMediaService azureMediaService) - : base(learningHubHttpClient, logger) + public ContentService(ILearningHubHttpClient learningHubHttpClient, IOpenApiHttpClient openApiHttpClient, ILogger logger, IAzureMediaService azureMediaService) + : base(learningHubHttpClient, openApiHttpClient, logger) { this.azureMediaService = azureMediaService; } @@ -36,7 +37,7 @@ public async Task GetPageByIdAsync(int id, bool preview) { PageViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var response = await client.GetAsync($"content/page/{id}?publishedOnly={!preview}&preview={preview}").ConfigureAwait(false); @@ -63,7 +64,7 @@ public async Task GetPageSectionDetailVideoAssetById { PageSectionDetailViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var response = await client.GetAsync($"content/page-section-detail-video/{id}").ConfigureAwait(false); diff --git a/LearningHub.Nhs.WebUI/Services/ContributeService.cs b/LearningHub.Nhs.WebUI/Services/ContributeService.cs index a61487e4e..68a2b4cf6 100644 --- a/LearningHub.Nhs.WebUI/Services/ContributeService.cs +++ b/LearningHub.Nhs.WebUI/Services/ContributeService.cs @@ -39,9 +39,10 @@ public class ContributeService : BaseService, IContributeServ /// Azure media service. /// MKIO media service. /// Learning hub http client. + /// The Open Api Http Client. /// Logger. - public ContributeService(IFileService fileService, IResourceService resourceService, IAzureMediaService azureMediaService, ILearningHubHttpClient learningHubHttpClient, ILogger logger, IAzureMediaService mediaService) - : base(learningHubHttpClient, logger) + public ContributeService(IFileService fileService, IResourceService resourceService, IAzureMediaService azureMediaService, ILearningHubHttpClient learningHubHttpClient, IOpenApiHttpClient openApiHttpClient, ILogger logger, IAzureMediaService mediaService) + : base(learningHubHttpClient, openApiHttpClient, logger) { this.fileService = fileService; this.resourceService = resourceService; @@ -62,7 +63,7 @@ public async Task CreateNewResourceVersionAsync(int var json = JsonConvert.SerializeObject(model); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/CreateNewResourceVersion"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -96,7 +97,7 @@ public async Task CreateResourceAuthorAsync(ResourceAuthorViewModel resourc var json = JsonConvert.SerializeObject(resourceAuthorViewModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/AddResourceVersionAuthor"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -130,7 +131,7 @@ public async Task CreateResourceKeywordAsync(ResourceKeywordViewModel resou var json = JsonConvert.SerializeObject(resourceKeywordViewModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/AddResourceVersionKeyword"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -163,7 +164,7 @@ public async Task DeleteArticleFileAsync(FileDeleteRequestModel model) var json = JsonConvert.SerializeObject(model); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/DeleteArticleFile"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -193,7 +194,7 @@ public async Task DeleteArticleFileAsync(FileDeleteRequestModel model) /// The . public async Task DeleteFileChunkDetailAsync(int fileChunkDetailId) { - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/DeleteFileChunkDetail/{fileChunkDetailId}"; var response = await client.DeleteAsync(request).ConfigureAwait(false); @@ -224,7 +225,7 @@ public async Task DeleteResourceAttributeFileAsync(FileDeleteRequestModel var json = JsonConvert.SerializeObject(model); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/DeleteResourceAttributeFile"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -257,7 +258,7 @@ public async Task DeleteResourceAuthorAsync(AuthorDeleteRequestModel model var json = JsonConvert.SerializeObject(model); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/DeleteResourceVersionAuthor"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -290,7 +291,7 @@ public async Task DeleteResourceKeywordAsync(KeywordDeleteRequestModel mod var json = JsonConvert.SerializeObject(model); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/DeleteResourceVersionKeyword"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -320,7 +321,7 @@ public async Task DeleteResourceKeywordAsync(KeywordDeleteRequestModel mod /// The . public async Task DeleteResourceVersionAsync(int resourceVersionId) { - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/DeleteResourceVersion/{resourceVersionId}"; var response = await client.DeleteAsync(request).ConfigureAwait(false); @@ -356,7 +357,7 @@ public async Task GetFileChunkDetail(int fileChunkDeta { FileChunkDetailViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetFileChunkDetail/{fileChunkDetailId}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -799,7 +800,7 @@ public async Task SaveArticleAttachedFileDetailsAsync(FileCreateRequestView var json = JsonConvert.SerializeObject(fileCreateRequestViewModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/SaveArticleAttachedFileDetails"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -833,7 +834,7 @@ public async Task SaveArticleDetailAsync(ArticleUpdateRequestViewModel arti var json = JsonConvert.SerializeObject(articleViewModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/UpdateArticleDetail"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -867,7 +868,7 @@ public async Task SaveFileChunkDetailsAsync(FileChunkDetailViewModel fileCh var json = JsonConvert.SerializeObject(fileChunkDetailCreateRequestViewModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/SaveFileChunkDetail"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -901,7 +902,7 @@ public async Task SaveFileDetailsAsync(FileCreateRequestViewModel fileCreat var json = JsonConvert.SerializeObject(fileCreateRequestViewModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/SaveFileDetails"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -935,7 +936,7 @@ public async Task SaveGenericFileDetailAsync(GenericFileUpdateRequestViewMo var json = JsonConvert.SerializeObject(genericFileViewModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/UpdateGenericFileDetail"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -969,7 +970,7 @@ public async Task SaveScormDetailAsync(ScormUpdateRequestViewModel scormUpd var json = JsonConvert.SerializeObject(scormUpdateRequestViewModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/UpdateScormDetail"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -1003,7 +1004,7 @@ public async Task SaveHtmlDetailAsync(HtmlResourceUpdateRequestViewModel ht var json = JsonConvert.SerializeObject(htmlResource); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/UpdateHtmlDetail"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -1037,7 +1038,7 @@ public async Task SaveImageDetailAsync(ImageUpdateRequestViewModel imageVie var json = JsonConvert.SerializeObject(imageViewModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/UpdateImageDetail"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -1071,7 +1072,7 @@ public async Task SaveResourceAttributeFileDetailsAsync(FileCreateRequestVi var json = JsonConvert.SerializeObject(fileCreateRequestViewModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/SaveResourceAttributeFileDetails"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -1128,7 +1129,7 @@ public async Task SaveWeblinkDetailAsync(WebLinkViewModel weblinkViewModel) var json = JsonConvert.SerializeObject(weblinkViewModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/UpdateWeblinkDetail"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -1162,7 +1163,7 @@ public async Task SaveCaseDetailAsync(CaseViewModel caseViewModel) var json = JsonConvert.SerializeObject(caseViewModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/UpdateCaseDetail"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -1196,7 +1197,7 @@ public async Task SaveAssessmentDetailAsync(AssessmentViewModel assessmentV var json = JsonConvert.SerializeObject(assessmentViewModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/UpdateAssessmentDetail"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -1230,7 +1231,7 @@ public async Task SubmitResourceVersionForPublishAs var json = JsonConvert.SerializeObject(publishViewModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/SubmitResourceVersionForPublish"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -1335,7 +1336,7 @@ private async Task CreateResourceAsync(ResourceDetailViewModel resourceDeta var json = JsonConvert.SerializeObject(resourceDetailViewModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/CreateResource"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -1368,7 +1369,7 @@ private async Task UpdateResourceVersionAsync(ResourceDetailViewModel resourceDe var json = JsonConvert.SerializeObject(resourceDetailViewModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/UpdateResourceVersion"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); diff --git a/LearningHub.Nhs.WebUI/Services/CountryService.cs b/LearningHub.Nhs.WebUI/Services/CountryService.cs index 2c0c7e120..e1afd4b35 100644 --- a/LearningHub.Nhs.WebUI/Services/CountryService.cs +++ b/LearningHub.Nhs.WebUI/Services/CountryService.cs @@ -20,13 +20,15 @@ public class CountryService : BaseService, ICountryService /// Initializes a new instance of the class. /// /// Learning hub http client. + /// The Open Api Http Client. /// User api http client. /// Logger. public CountryService( ILearningHubHttpClient learningHubHttpClient, + IOpenApiHttpClient openApiHttpClient, IUserApiHttpClient userApiHttpClient, ILogger logger) - : base(learningHubHttpClient, logger) + : base(learningHubHttpClient, openApiHttpClient, logger) { this.userApiHttpClient = userApiHttpClient; } diff --git a/LearningHub.Nhs.WebUI/Services/DashboardService.cs b/LearningHub.Nhs.WebUI/Services/DashboardService.cs index 55f5153bf..607d4f2be 100644 --- a/LearningHub.Nhs.WebUI/Services/DashboardService.cs +++ b/LearningHub.Nhs.WebUI/Services/DashboardService.cs @@ -26,10 +26,11 @@ public class DashboardService : BaseService, IDashboardService /// Initializes a new instance of the class. /// /// learningHubHttpClient. + /// The Open Api Http Client. /// logger. /// MoodleHttpClient. - public DashboardService(ILearningHubHttpClient learningHubHttpClient, ILogger logger, IMoodleHttpClient moodleHttpClient) - : base(learningHubHttpClient, logger) + public DashboardService(ILearningHubHttpClient learningHubHttpClient, IOpenApiHttpClient openApiHttpClient, ILogger logger, IMoodleHttpClient moodleHttpClient) + : base(learningHubHttpClient, openApiHttpClient, logger) { this.moodleHttpClient = moodleHttpClient; } @@ -44,7 +45,7 @@ public async Task GetMyAccessLearningsAsyn { DashboardMyLearningResponseViewModel viewmodel = new DashboardMyLearningResponseViewModel { }; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"dashboard/myaccesslearning/{dashboardType}/{pageNumber}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -73,7 +74,7 @@ public async Task GetCataloguesAsync(string { DashboardCatalogueResponseViewModel viewmodel = new DashboardCatalogueResponseViewModel { }; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"dashboard/catalogues/{dashboardType}/{pageNumber}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -102,7 +103,7 @@ public async Task GetResourcesAsync(string d { DashboardResourceResponseViewModel viewmodel = new DashboardResourceResponseViewModel { }; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"dashboard/resources/{dashboardType}/{pageNumber}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -149,7 +150,7 @@ public async Task RecordDashBoardEventAsync(DashboardEventViewModel dashboardEve }; var content = new System.Net.Http.StringContent(JsonConvert.SerializeObject(eventEntity), Encoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"event/Create"; var response = await client.PostAsync(request, content).ConfigureAwait(false); diff --git a/LearningHub.Nhs.WebUI/Services/DetectJsLogService.cs b/LearningHub.Nhs.WebUI/Services/DetectJsLogService.cs index da62c5cbd..e9bf607ce 100644 --- a/LearningHub.Nhs.WebUI/Services/DetectJsLogService.cs +++ b/LearningHub.Nhs.WebUI/Services/DetectJsLogService.cs @@ -14,9 +14,10 @@ public class DetectJsLogService : BaseService, IDetectJsLogS /// Initializes a new instance of the class. /// /// Learning hub http client. + /// The Open Api Http Client. /// Logger. - public DetectJsLogService(ILearningHubHttpClient learningHubHttpClient, ILogger logger) - : base(learningHubHttpClient, logger) + public DetectJsLogService(ILearningHubHttpClient learningHubHttpClient, IOpenApiHttpClient openApiHttpClient, ILogger logger) + : base(learningHubHttpClient, openApiHttpClient, logger) { } diff --git a/LearningHub.Nhs.WebUI/Services/GradeService.cs b/LearningHub.Nhs.WebUI/Services/GradeService.cs index fb0a42074..37df9b048 100644 --- a/LearningHub.Nhs.WebUI/Services/GradeService.cs +++ b/LearningHub.Nhs.WebUI/Services/GradeService.cs @@ -19,13 +19,15 @@ public class GradeService : BaseService, IGradeService /// Initializes a new instance of the class. /// /// Learning hub http client. + /// The Open Api Http Client. /// User api http client. /// Logger. public GradeService( ILearningHubHttpClient learningHubHttpClient, + IOpenApiHttpClient openApiHttpClient, IUserApiHttpClient userApiHttpClient, ILogger logger) - : base(learningHubHttpClient, logger) + : base(learningHubHttpClient, openApiHttpClient, logger) { this.userApiHttpClient = userApiHttpClient; } diff --git a/LearningHub.Nhs.WebUI/Services/HierarchyService.cs b/LearningHub.Nhs.WebUI/Services/HierarchyService.cs index 4bd8f7734..6bed5fd27 100644 --- a/LearningHub.Nhs.WebUI/Services/HierarchyService.cs +++ b/LearningHub.Nhs.WebUI/Services/HierarchyService.cs @@ -16,21 +16,23 @@ public class HierarchyService : BaseService, IHierarchyService /// /// Defines the _facade. /// - private readonly ILearningHubApiFacade facade; + private readonly IOpenApiFacade facade; /// /// Initializes a new instance of the class. /// /// The learning hub http client. - /// The learningHubApiFacade. + /// The Open Api Http Client. + /// The openApiFacade. /// The logger. public HierarchyService( ILearningHubHttpClient learningHubHttpClient, - ILearningHubApiFacade learningHubApiFacade, + IOpenApiHttpClient openApiHttpClient, + IOpenApiFacade openApiFacade, ILogger logger) - : base(learningHubHttpClient, logger) + : base(learningHubHttpClient, openApiHttpClient, logger) { - this.facade = learningHubApiFacade; + this.facade = openApiFacade; } /// diff --git a/LearningHub.Nhs.WebUI/Services/InternalSystemService.cs b/LearningHub.Nhs.WebUI/Services/InternalSystemService.cs index d578d9523..bb19a0f38 100644 --- a/LearningHub.Nhs.WebUI/Services/InternalSystemService.cs +++ b/LearningHub.Nhs.WebUI/Services/InternalSystemService.cs @@ -16,9 +16,10 @@ public class InternalSystemService : BaseService, IIntern /// Initializes a new instance of the class. /// /// Learning hub http client. + /// The Open Api Http Client. /// Logger. - public InternalSystemService(ILearningHubHttpClient learningHubHttpClient, ILogger logger) - : base(learningHubHttpClient, logger) + public InternalSystemService(ILearningHubHttpClient learningHubHttpClient, IOpenApiHttpClient openApiHttpClient, ILogger logger) + : base(learningHubHttpClient, openApiHttpClient, logger) { } diff --git a/LearningHub.Nhs.WebUI/Services/JobRoleService.cs b/LearningHub.Nhs.WebUI/Services/JobRoleService.cs index bbf9f4402..766d05e60 100644 --- a/LearningHub.Nhs.WebUI/Services/JobRoleService.cs +++ b/LearningHub.Nhs.WebUI/Services/JobRoleService.cs @@ -22,13 +22,15 @@ public class JobRoleService : BaseService, IJobRoleService /// Initializes a new instance of the class. /// /// Learning hub http client. + /// The Open Api Http Client. /// User api http client. /// Logger. public JobRoleService( ILearningHubHttpClient learningHubHttpClient, + IOpenApiHttpClient openApiHttpClient, IUserApiHttpClient userApiHttpClient, ILogger logger) - : base(learningHubHttpClient, logger) + : base(learningHubHttpClient, openApiHttpClient, logger) { this.userApiHttpClient = userApiHttpClient; } diff --git a/LearningHub.Nhs.WebUI/Services/LocationService.cs b/LearningHub.Nhs.WebUI/Services/LocationService.cs index 2ba678ab0..04423a0b6 100644 --- a/LearningHub.Nhs.WebUI/Services/LocationService.cs +++ b/LearningHub.Nhs.WebUI/Services/LocationService.cs @@ -19,13 +19,15 @@ public class LocationService : BaseService, ILocationService /// Initializes a new instance of the class. /// /// Learning hub http client. + /// The Open Api Http Client. /// User api http client. /// Logger. public LocationService( ILearningHubHttpClient learningHubHttpClient, + IOpenApiHttpClient openApiHttpClient, IUserApiHttpClient userApiHttpClient, ILogger logger) - : base(learningHubHttpClient, logger) + : base(learningHubHttpClient, openApiHttpClient, logger) { this.userApiHttpClient = userApiHttpClient; } diff --git a/LearningHub.Nhs.WebUI/Services/LoginWizardService.cs b/LearningHub.Nhs.WebUI/Services/LoginWizardService.cs index 306d69304..06fd7e428 100644 --- a/LearningHub.Nhs.WebUI/Services/LoginWizardService.cs +++ b/LearningHub.Nhs.WebUI/Services/LoginWizardService.cs @@ -24,13 +24,15 @@ public class LoginWizardService : BaseService, ILoginWizardS /// Initializes a new instance of the class. /// /// Learning hub http client. + /// The Open Api Http Client. /// User api http client. /// Logger. public LoginWizardService( ILearningHubHttpClient learningHubHttpClient, + IOpenApiHttpClient openApiHttpClient, IUserApiHttpClient userApiHttpClient, ILogger logger) - : base(learningHubHttpClient, logger) + : base(learningHubHttpClient, openApiHttpClient, logger) { this.userApiHttpClient = userApiHttpClient; } diff --git a/LearningHub.Nhs.WebUI/Services/MyLearningService.cs b/LearningHub.Nhs.WebUI/Services/MyLearningService.cs index c6f9f2ffb..1e1662201 100644 --- a/LearningHub.Nhs.WebUI/Services/MyLearningService.cs +++ b/LearningHub.Nhs.WebUI/Services/MyLearningService.cs @@ -20,9 +20,10 @@ public class MyLearningService : BaseService, IMyLearningServ /// Initializes a new instance of the class. /// /// The learningHubHttpClient. + /// The Open Api Http Client. /// The logger. - public MyLearningService(ILearningHubHttpClient learningHubHttpClient, ILogger logger) - : base(learningHubHttpClient, logger) + public MyLearningService(ILearningHubHttpClient learningHubHttpClient, IOpenApiHttpClient openApiHttpClient, ILogger logger) + : base(learningHubHttpClient, openApiHttpClient, logger) { } @@ -38,7 +39,7 @@ public async Task GetActivityDetailed(MyLearningReq var json = JsonConvert.SerializeObject(requestModel); var stringContent = new StringContent(json, Encoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"MyLearning/GetActivityDetailed"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -67,7 +68,7 @@ public async Task GetActivityDetailed(MyLearningReq public async Task> GetPlayedSegments(int resourceId, int majorVersion) { List viewModel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"MyLearning/GetPlayedSegments/{resourceId}/{majorVersion}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -98,7 +99,7 @@ public async Task> GetPlayedSegments(int resourceId public async Task> GetResourceCertificateDetails(int resourceReferenceId, int? majorVersion = 0, int? minorVersion = 0, int? userId = 0) { Tuple viewModel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"MyLearning/GetResourceCertificateDetails/{resourceReferenceId}/{majorVersion}/{minorVersion}/{userId}"; var response = await client.GetAsync(request).ConfigureAwait(false); diff --git a/LearningHub.Nhs.WebUI/Services/NavigationPermissionService.cs b/LearningHub.Nhs.WebUI/Services/NavigationPermissionService.cs index 95e74022e..e381b0403 100644 --- a/LearningHub.Nhs.WebUI/Services/NavigationPermissionService.cs +++ b/LearningHub.Nhs.WebUI/Services/NavigationPermissionService.cs @@ -11,14 +11,19 @@ public class NavigationPermissionService : INavigationPermissionService { private readonly IResourceService resourceService; + private readonly IUserGroupService userGroupService; /// /// Initializes a new instance of the class. /// /// Resource service. - public NavigationPermissionService(IResourceService resourceService) + /// UserGroup service. + public NavigationPermissionService( + IResourceService resourceService, + IUserGroupService userGroupService) { this.resourceService = resourceService; + this.userGroupService = userGroupService; } /// @@ -52,7 +57,7 @@ public async Task GetNavigationModelAsync(IPrincipal user, bool } else if (user.IsInRole("BlueUser")) { - return this.AuthenticatedBlueUser(controllerName); + return await this.AuthenticatedBlueUser(controllerName); } else { @@ -114,11 +119,11 @@ private NavigationModel AuthenticatedAdministrator(string controllerName) /// /// The controller name. /// The . - private NavigationModel AuthenticatedBlueUser(string controllerName) + private async Task AuthenticatedBlueUser(string controllerName) { return new NavigationModel() { - ShowMyContributions = true, + ShowMyContributions = await this.userGroupService.UserHasCatalogueContributionPermission(), ShowMyLearning = true, ShowMyBookmarks = true, ShowSearch = controllerName != "search" && controllerName != string.Empty, diff --git a/LearningHub.Nhs.WebUI/Services/NotificationService.cs b/LearningHub.Nhs.WebUI/Services/NotificationService.cs index d41ef30d6..e836edcd9 100644 --- a/LearningHub.Nhs.WebUI/Services/NotificationService.cs +++ b/LearningHub.Nhs.WebUI/Services/NotificationService.cs @@ -22,9 +22,10 @@ public class NotificationService : BaseService, INotificati /// Initializes a new instance of the class. /// /// Learning hub http client. + /// The Open Api Http Client. /// Logger. - public NotificationService(ILearningHubHttpClient learningHubHttpClient, ILogger logger) - : base(learningHubHttpClient, logger) + public NotificationService(ILearningHubHttpClient learningHubHttpClient, IOpenApiHttpClient openApiHttpClient, ILogger logger) + : base(learningHubHttpClient, openApiHttpClient, logger) { } @@ -95,7 +96,7 @@ public async Task> GetPagedAsync(Pagin { PagedResultSet viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var content = new StringContent(JsonConvert.SerializeObject(pagingRequestModel), Encoding.UTF8, "application/json"); @@ -124,7 +125,7 @@ public async Task GetUserNotificationIdAsync(int id) { UserNotification viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"UserNotification/GetById/{id}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -153,7 +154,7 @@ public async Task GetUserNotificationDetailsAsync(int id) { UserNotification viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"UserNotification/GetByIdAndUserId/{id}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -182,7 +183,7 @@ public async Task GetUserUnreadNotificationCountAsync(int userid) { int count = 0; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"UserNotification/GetUserUnreadNotificationCount/{userid}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -212,7 +213,7 @@ private async Task PutAsync(UserNotification notification) var json = JsonConvert.SerializeObject(notification); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"UserNotification/PutAsync"; var response = await client.PutAsync(request, stringContent).ConfigureAwait(false); @@ -245,7 +246,7 @@ private async Task PostAsync(UserNotification notification) var json = JsonConvert.SerializeObject(notification); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"UserNotification/PostAsync"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); diff --git a/LearningHub.Nhs.WebUI/Services/OpenApiHttpClient.cs b/LearningHub.Nhs.WebUI/Services/OpenApiHttpClient.cs new file mode 100644 index 000000000..54c3b7bb2 --- /dev/null +++ b/LearningHub.Nhs.WebUI/Services/OpenApiHttpClient.cs @@ -0,0 +1,41 @@ +namespace LearningHub.Nhs.WebUI.Services +{ + using System.Net.Http; + using LearningHub.Nhs.Caching; + using LearningHub.Nhs.WebUI.Configuration; + using LearningHub.Nhs.WebUI.Interfaces; + using Microsoft.AspNetCore.Http; + using Microsoft.Extensions.Logging; + using Microsoft.Extensions.Options; + + /// + /// The open api http client. + /// + public class OpenApiHttpClient : BaseHttpClient, IOpenApiHttpClient + { + /// + /// Initializes a new instance of the class. + /// + /// The http context accessor. + /// The web settings. + /// The auth config. + /// The http client. + /// The logger. + /// The cache service. + public OpenApiHttpClient( + IHttpContextAccessor httpContextAccessor, + IOptions webSettings, + LearningHubAuthServiceConfig authConfig, + HttpClient client, + ILogger logger, + ICacheService cacheService) + : base(httpContextAccessor, webSettings.Value, authConfig, client, logger, cacheService) + { + } + + /// + /// Gets the open api url. + /// + public override string ApiUrl => this.WebSettings.OpenApiUrl; + } +} diff --git a/LearningHub.Nhs.WebUI/Services/PartialFileUploadService.cs b/LearningHub.Nhs.WebUI/Services/PartialFileUploadService.cs index 7a7a33616..5ef45d685 100644 --- a/LearningHub.Nhs.WebUI/Services/PartialFileUploadService.cs +++ b/LearningHub.Nhs.WebUI/Services/PartialFileUploadService.cs @@ -34,12 +34,14 @@ public class PartialFileUploadService : BaseService, I /// /// The Settings. /// The learning hub http client. + /// The Open Api Http Client. /// The logger. public PartialFileUploadService( IOptions settings, ILearningHubHttpClient learningHubHttpClient, + IOpenApiHttpClient openApiHttpClient, ILogger logger) - : base(learningHubHttpClient, logger) + : base(learningHubHttpClient, openApiHttpClient, logger) { this.settings = settings.Value; } diff --git a/LearningHub.Nhs.WebUI/Services/ProviderService.cs b/LearningHub.Nhs.WebUI/Services/ProviderService.cs index 44a91495b..ee6119c60 100644 --- a/LearningHub.Nhs.WebUI/Services/ProviderService.cs +++ b/LearningHub.Nhs.WebUI/Services/ProviderService.cs @@ -22,9 +22,10 @@ public class ProviderService : BaseService, IProviderService /// /// The cache service. /// Learning hub http client. + /// The Open Api Http Client. /// Logger. - public ProviderService(ICacheService cacheService, ILearningHubHttpClient learningHubHttpClient, ILogger logger) - : base(learningHubHttpClient, logger) + public ProviderService(ICacheService cacheService, ILearningHubHttpClient learningHubHttpClient, IOpenApiHttpClient openApiHttpClient, ILogger logger) + : base(learningHubHttpClient, openApiHttpClient, logger) { this.cacheService = cacheService; } @@ -47,7 +48,7 @@ public async Task> GetProvidersForUserAsync(int userId) { List viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Provider/GetProvidersByUserId/{userId}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -76,7 +77,7 @@ public async Task> GetProvidersForResourceAsync(int reso { List viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Provider/GetProvidersByResource/{resourceVersionId}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -111,7 +112,7 @@ private async Task> GetAllProviders() { List viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Provider/all"; var response = await client.GetAsync(request).ConfigureAwait(false); diff --git a/LearningHub.Nhs.WebUI/Services/RatingService.cs b/LearningHub.Nhs.WebUI/Services/RatingService.cs index f08361096..fa72f4264 100644 --- a/LearningHub.Nhs.WebUI/Services/RatingService.cs +++ b/LearningHub.Nhs.WebUI/Services/RatingService.cs @@ -19,9 +19,10 @@ public class RatingService : BaseService, IRatingService /// Initializes a new instance of the class. /// /// Learning hub http client. + /// The Open Api Http Client. /// Logger. - public RatingService(ILearningHubHttpClient learningHubHttpClient, ILogger logger) - : base(learningHubHttpClient, logger) + public RatingService(ILearningHubHttpClient learningHubHttpClient, IOpenApiHttpClient openApiHttpClient, ILogger logger) + : base(learningHubHttpClient, openApiHttpClient, logger) { } diff --git a/LearningHub.Nhs.WebUI/Services/RegionService.cs b/LearningHub.Nhs.WebUI/Services/RegionService.cs index 6a48fcf5d..f05fc22eb 100644 --- a/LearningHub.Nhs.WebUI/Services/RegionService.cs +++ b/LearningHub.Nhs.WebUI/Services/RegionService.cs @@ -19,10 +19,11 @@ public class RegionService : BaseService, IRegionService /// Initializes a new instance of the class. /// /// Learning hub http client. + /// The Open Api Http Client. /// Logger. /// User Api http client. - public RegionService(ILearningHubHttpClient learningHubHttpClient, ILogger logger, IUserApiHttpClient userApiHttpClient) - : base(learningHubHttpClient, logger) + public RegionService(ILearningHubHttpClient learningHubHttpClient, IOpenApiHttpClient openApiHttpClient, ILogger logger, IUserApiHttpClient userApiHttpClient) + : base(learningHubHttpClient, openApiHttpClient, logger) { this.userApiHttpClient = userApiHttpClient; } diff --git a/LearningHub.Nhs.WebUI/Services/ResourceService.cs b/LearningHub.Nhs.WebUI/Services/ResourceService.cs index 02a233ea0..ec8eaee30 100644 --- a/LearningHub.Nhs.WebUI/Services/ResourceService.cs +++ b/LearningHub.Nhs.WebUI/Services/ResourceService.cs @@ -34,11 +34,12 @@ public class ResourceService : BaseService, IResourceService /// Initializes a new instance of the class. /// /// Learning hub http client. + /// The Open Api Http Client. /// Azure media services. /// Logger. /// Settings. - public ResourceService(ILearningHubHttpClient learningHubHttpClient, IAzureMediaService azureMediaService, ILogger logger, IOptions settings) - : base(learningHubHttpClient, logger) + public ResourceService(ILearningHubHttpClient learningHubHttpClient, IOpenApiHttpClient openApiHttpClient, IAzureMediaService azureMediaService, ILogger logger, IOptions settings) + : base(learningHubHttpClient, openApiHttpClient, logger) { this.settings = settings.Value; this.azureMediaService = azureMediaService; @@ -55,7 +56,7 @@ public async Task AcceptSensitiveContentAsync(int r var stringContent = new StringContent(resourceVersionId.ToString(), Encoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/AcceptSensitiveContent"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -87,7 +88,7 @@ public async Task GetArticleDetailsByIdAsync(int resourceVersi { ArticleViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetArticleDetails/{resourceVersionId}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -116,7 +117,7 @@ public async Task GetAudioDetailsByIdAsync(int resourceVersionId { AudioViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetAudioDetails/{resourceVersionId}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -145,7 +146,7 @@ public async Task GetByIdAsync(int id) { ResourceHeaderViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetResourceHeaderViewModelAsync/{id}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -173,7 +174,7 @@ public async Task> GetFileTypeAsync() { List fileTypeList = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetFileTypes"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -202,7 +203,7 @@ public async Task GetGenericFileDetailsByIdAsync(int resou { GenericFileViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetGenericFileDetails/{resourceVersionId}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -231,7 +232,7 @@ public async Task GetHtmlDetailsByIdAsync(int resourceVer { HtmlResourceViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetHtmlDetails/{resourceVersionId}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -260,7 +261,7 @@ public async Task GetScormDetailsByIdAsync(int resourceVersionId { ScormViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetScormDetails/{resourceVersionId}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -288,7 +289,7 @@ public async Task GetExternalContentDetailsAsyn { ExternalContentDetailsViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetExternalContentDetailsById/{resourceVersionId}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -317,7 +318,7 @@ public async Task RecordExternalReferenceUserAgreementAsync(ExternalRefere var json = JsonConvert.SerializeObject(model); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/RecordExternalReferenceUserAgreement"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -349,7 +350,7 @@ public async Task GetImageDetailsByIdAsync(int resourceVersionId { ImageViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetImageDetails/{resourceVersionId}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -378,7 +379,7 @@ public async Task GetInformationByIdAsync(int id) { ResourceInformationViewModel resourceInfo = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetResourceInformationViewModelAsync/{id}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -407,7 +408,7 @@ public async Task GetItemByIdAsync(int id) { ResourceItemViewModel resourceItem = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetResourceItemViewModelAsync/{id}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -453,7 +454,7 @@ public async Task> GetLicencesAsync() { List licences = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetResourceLicences"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -482,7 +483,7 @@ public async Task GetLocationsByIdAsync(int id) { CatalogueLocationsViewModel resourceLocations = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetCatalogueLocations/{id}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -511,7 +512,7 @@ public async Task GetResourceVersionAsync(int resourceV { ResourceDetailViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetResourceVersion/{resourceVersionId}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -540,7 +541,7 @@ public async Task GetResourceVersionViewModelAsync(int { ResourceVersionViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetResourceVersionViewModel/{resourceVersionId.ToString()}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -569,7 +570,7 @@ public async Task GetResourceVersionExtendedAs { ResourceVersionExtendedViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetResourceVersionExtendedViewModel/{resourceVersionId.ToString()}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -609,7 +610,7 @@ public async Task GetVideoDetailsByIdAsync(int resourceVersionId { VideoViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetVideoDetails/{resourceVersionId}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -648,7 +649,7 @@ public async Task GetWeblinkDetailsByIdAsync(int resourceVersi { WebLinkViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetWeblinkDetails/{resourceVersionId}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -677,7 +678,7 @@ public async Task GetCaseDetailsByIdAsync(int resourceVersionId) { CaseViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetCaseDetails/{resourceVersionId.ToString()}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -706,7 +707,7 @@ public async Task GetAssessmentDetailsByIdAsync(int resourc { AssessmentViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetAssessmentDetails/{resourceVersionId.ToString()}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -735,7 +736,7 @@ public async Task GetAssessmentContent(int resourceVersionI { AssessmentViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetAssessmentContent/{resourceVersionId.ToString()}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -764,7 +765,7 @@ public async Task GetAssessmentProgressByResourceVe { AssessmentProgressViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetAssessmentProgress/resource/{resourceVersionId.ToString()}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -793,7 +794,7 @@ public async Task GetAssessmentProgressByActivity(i { AssessmentProgressViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetAssessmentProgress/activity/{assessmentResourceActivityId.ToString()}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -822,7 +823,7 @@ public async Task> GetFileStatusDetailsAsync(int[] fileIds) { List viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); string queryString = string.Join("&", fileIds.Select(fileId => $"fileIds={fileId}")); var request = $"Resource/GetFileStatusDetails?{queryString}"; @@ -855,7 +856,7 @@ public async Task UnpublishResourceVersionAsync(int var json = JsonConvert.SerializeObject(rv); var stringContent = new StringContent(json, Encoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/UnpublishResourceVersion"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -884,7 +885,7 @@ public async Task UnpublishResourceVersionAsync(int /// The . public async Task UserHasPublishedResourcesAsync() { - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/HasPublishedResources"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -916,7 +917,7 @@ public async Task DuplicateResourceAsync(DuplicateR var json = JsonConvert.SerializeObject(model); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/DuplicateResource"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -963,7 +964,7 @@ public async Task DuplicateBlocksAsync(DuplicateBlo var json = JsonConvert.SerializeObject(model); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/DuplicateBlocks"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -1007,7 +1008,7 @@ public async Task> GetMyContri { var json = JsonConvert.SerializeObject(model); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var response = await client.PostAsync("Resource/GetMyContributions", stringContent).ConfigureAwait(false); @@ -1030,7 +1031,7 @@ public async Task> GetMyContri /// The . public async Task> GetAllPublishedResourceAsync() { - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var response = await client.GetAsync("Resource/GetAllPublishedResource").ConfigureAwait(false); @@ -1056,7 +1057,7 @@ public async Task GetResourceVersionVa { ResourceVersionValidationResultViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetResourceVersionValidationResult/{resourceVersionId.ToString()}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -1085,7 +1086,7 @@ public async Task GetResourceVersionExtendedVi { ResourceVersionExtendedViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetResourceVersionExtendedViewModel/{resourceVersionId.ToString()}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -1116,7 +1117,7 @@ public async Task RevertToDraft(int resourceVersion var json = JsonConvert.SerializeObject(new { resourceVersionId }); var stringContent = new StringContent(resourceVersionId.ToString(), Encoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/RevertToDraft"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -1160,7 +1161,7 @@ public async Task CreateResourceVersionProviderAsyn var json = JsonConvert.SerializeObject(model); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/AddResourceProvider"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -1206,7 +1207,7 @@ public async Task CreateResourceVersionValidationResultAsync(ResourceVersionVali var json = JsonConvert.SerializeObject(validationResultViewModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/CreateResourceVersionValidationResult"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -1237,7 +1238,7 @@ public async Task DeleteResourceVersionProviderAsyn var json = JsonConvert.SerializeObject(model); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/DeleteResourceProvider"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -1278,7 +1279,7 @@ public async Task DeleteResourceVersionProviderAsyn public async Task DeleteAllResourceVersionProviderAsync(int resourceVersionId) { var content = new StringContent(JsonConvert.SerializeObject(new { })); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/DeleteAllResourceProvider/{resourceVersionId}"; var response = await client.PostAsync(request, content).ConfigureAwait(false); @@ -1320,7 +1321,7 @@ public async Task> GetObsoleteResourceFile(int resourceVersionId, b { List filePaths = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Resource/GetObsoleteResourceFile/{resourceVersionId}/{deletedResource}"; var response = await client.GetAsync(request).ConfigureAwait(false); diff --git a/LearningHub.Nhs.WebUI/Services/RoadMapService.cs b/LearningHub.Nhs.WebUI/Services/RoadMapService.cs index 210a06096..e63f9b9c1 100644 --- a/LearningHub.Nhs.WebUI/Services/RoadMapService.cs +++ b/LearningHub.Nhs.WebUI/Services/RoadMapService.cs @@ -16,9 +16,10 @@ public class RoadMapService : BaseService, IRoadMapService /// Initializes a new instance of the class. /// /// Learing hub http client. + /// The Open Api Http Client. /// Logger. - public RoadMapService(ILearningHubHttpClient learningHubHttpClient, ILogger logger) - : base(learningHubHttpClient, logger) + public RoadMapService(ILearningHubHttpClient learningHubHttpClient, IOpenApiHttpClient openApiHttpClient, ILogger logger) + : base(learningHubHttpClient, openApiHttpClient, logger) { } diff --git a/LearningHub.Nhs.WebUI/Services/RoleService.cs b/LearningHub.Nhs.WebUI/Services/RoleService.cs index cfc3c8ff8..c4f37af65 100644 --- a/LearningHub.Nhs.WebUI/Services/RoleService.cs +++ b/LearningHub.Nhs.WebUI/Services/RoleService.cs @@ -21,9 +21,10 @@ public class RoleService : BaseService, IRoleService /// /// The cache service. /// Learning hub http client. + /// The Open Api Http Client. /// Logger. - public RoleService(ICacheService cacheService, ILearningHubHttpClient learningHubHttpClient, ILogger logger) - : base(learningHubHttpClient, logger) + public RoleService(ICacheService cacheService, ILearningHubHttpClient learningHubHttpClient, IOpenApiHttpClient openApiHttpClient, ILogger logger) + : base(learningHubHttpClient, openApiHttpClient, logger) { this.cacheService = cacheService; } diff --git a/LearningHub.Nhs.WebUI/Services/SearchService.cs b/LearningHub.Nhs.WebUI/Services/SearchService.cs index 40feaf6fb..578a5861f 100644 --- a/LearningHub.Nhs.WebUI/Services/SearchService.cs +++ b/LearningHub.Nhs.WebUI/Services/SearchService.cs @@ -34,11 +34,12 @@ public class SearchService : BaseService, ISearchService /// Initializes a new instance of the class. /// /// Learning hub http client. + /// The Open Api Http Client. /// Provider service. /// Logger. /// Settings. - public SearchService(ILearningHubHttpClient learningHubHttpClient, IProviderService providerService, ILogger logger, IOptions settings) - : base(learningHubHttpClient, logger) + public SearchService(ILearningHubHttpClient learningHubHttpClient, IOpenApiHttpClient openApiHttpClient, IProviderService providerService, ILogger logger, IOptions settings) + : base(learningHubHttpClient, openApiHttpClient, logger) { this.settings = settings.Value; this.providerService = providerService; @@ -345,7 +346,7 @@ public async Task CreateResourceSearchActionAsync(SearchActionResourceModel try { int createId = 0; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var json = JsonConvert.SerializeObject(searchActionResourceModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); @@ -388,7 +389,7 @@ public async Task CreateCatalogueSearchActionAsync(SearchActionCatalogueMod try { int createId = 0; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var json = JsonConvert.SerializeObject(searchActionCatalogueModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); @@ -427,7 +428,7 @@ public async Task CreateSearchTermEventAsync(SearchRequestModel searchReque try { int createId = 0; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var json = JsonConvert.SerializeObject(searchRequestModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); @@ -467,7 +468,7 @@ public async Task GetSearchResultAsync(SearchRequestModel searc try { - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); searchRequestModel.SearchText = this.DecodeProblemCharacters(searchRequestModel.SearchText); @@ -510,8 +511,8 @@ public async Task SubmitFeedbackAsync(SearchFeedBackModel model) { int createId = 0; - var client = await this.LearningHubHttpClient.GetClientAsync(); - var request = this.settings.LearningHubApiUrl + "Search/SubmitFeedback"; + var client = await this.OpenApiHttpClient.GetClientAsync(); + var request = $"Search/SubmitFeedback"; var content = new StringContent(JsonConvert.SerializeObject(model), Encoding.UTF8, "application/json"); var response = await client.PostAsync(request, content).ConfigureAwait(false); @@ -547,7 +548,7 @@ public async Task GetCatalogueSearchResultAsync(Catalo try { - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); catalogueSearchRequestModel.SearchText = this.DecodeProblemCharacters(catalogueSearchRequestModel.SearchText); @@ -593,7 +594,7 @@ public async Task CreateCatalogueSearchTermEventAsync(CatalogueSearchReques try { int createId = 0; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var json = JsonConvert.SerializeObject(catalogueSearchRequestModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); @@ -637,7 +638,7 @@ public async Task GetAllCatalogueSearchResultAsync( try { - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); catalogueSearchRequestModel.SearchText = this.DecodeProblemCharacters(catalogueSearchRequestModel.SearchText); @@ -680,7 +681,7 @@ public async Task GetAllCatalogueSearchResultAsync( /// The auto suggestion list. public async Task GetAutoSuggestionList(string term) { - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Search/GetAutoSuggestionResult/{term}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -707,7 +708,7 @@ public async Task SendAutoSuggestionClickActionAsync(AutoSuggestionClickPayloadM { try { - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var json = JsonConvert.SerializeObject(clickPayloadModel); var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json"); diff --git a/LearningHub.Nhs.WebUI/Services/SpecialtyService.cs b/LearningHub.Nhs.WebUI/Services/SpecialtyService.cs index adc3f41bb..4df5f36e7 100644 --- a/LearningHub.Nhs.WebUI/Services/SpecialtyService.cs +++ b/LearningHub.Nhs.WebUI/Services/SpecialtyService.cs @@ -19,13 +19,15 @@ public class SpecialtyService : BaseService, ISpecialtyService /// Initializes a new instance of the class. /// /// Learning hub http client. + /// The Open Api Http Client. /// User api http client. /// . public SpecialtyService( ILearningHubHttpClient learningHubHttpClient, + IOpenApiHttpClient openApiHttpClient, IUserApiHttpClient userApiHttpClient, ILogger logger) - : base(learningHubHttpClient, logger) + : base(learningHubHttpClient, openApiHttpClient, logger) { this.userApiHttpClient = userApiHttpClient; } diff --git a/LearningHub.Nhs.WebUI/Services/TermsAndConditionsService.cs b/LearningHub.Nhs.WebUI/Services/TermsAndConditionsService.cs index db00925e6..6c7220499 100644 --- a/LearningHub.Nhs.WebUI/Services/TermsAndConditionsService.cs +++ b/LearningHub.Nhs.WebUI/Services/TermsAndConditionsService.cs @@ -22,13 +22,15 @@ public class TermsAndConditionsService : BaseService, /// Initializes a new instance of the class. /// /// Learning hub http client. + /// The Open Api Http Client. /// User api http client. /// Logger. public TermsAndConditionsService( ILearningHubHttpClient learningHubHttpClient, + IOpenApiHttpClient openApiHttpClient, IUserApiHttpClient userApiHttpClient, ILogger logger) - : base(learningHubHttpClient, logger) + : base(learningHubHttpClient, openApiHttpClient, logger) { this.userApiHttpClient = userApiHttpClient; } diff --git a/LearningHub.Nhs.WebUI/Services/UserGroupService.cs b/LearningHub.Nhs.WebUI/Services/UserGroupService.cs index 6790a3143..22729e5df 100644 --- a/LearningHub.Nhs.WebUI/Services/UserGroupService.cs +++ b/LearningHub.Nhs.WebUI/Services/UserGroupService.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Threading.Tasks; using LearningHub.Nhs.Caching; + using LearningHub.Nhs.Models.Enums; using LearningHub.Nhs.Models.Extensions; using LearningHub.Nhs.Models.User; using LearningHub.Nhs.WebUI.Interfaces; @@ -25,17 +26,19 @@ public class UserGroupService : BaseService, IUserGroupService /// Initializes a new instance of the class. /// /// The learning hub http client. + /// The Open Api Http Client. /// The logger. /// The http context accessor. /// The cacheService. /// roleService. public UserGroupService( ILearningHubHttpClient learningHubHttpClient, + IOpenApiHttpClient openApiHttpClient, ILogger logger, IHttpContextAccessor contextAccessor, ICacheService cacheService, IRoleService roleService) - : base(learningHubHttpClient, logger) + : base(learningHubHttpClient, openApiHttpClient, logger) { this.contextAccessor = contextAccessor; this.cacheService = cacheService; @@ -56,6 +59,18 @@ public async Task> GetRoleUserGroupDetailForUserAsy return await this.cacheService.GetOrFetchAsync(cacheKey, () => this.FetchRoleUserGroupDetailForUserAsync(userId)); } + /// + public async Task UserHasCatalogueContributionPermission() + { + var userRoleGroups = await this.GetRoleUserGroupDetailAsync(); + if (userRoleGroups != null && userRoleGroups.Any(r => r.RoleEnum == RoleEnum.Editor)) + { + return true; + } + + return false; + } + /// public async Task UserHasPermissionAsync(string permissionCode) { @@ -76,7 +91,7 @@ private async Task> FetchRoleUserGroupDetailAsync() { List viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"UserGroup/GetUserGroupRoleDetail"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -100,7 +115,7 @@ private async Task> FetchRoleUserGroupDetailForUser { List viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"UserGroup/GetUserGroupRoleDetailByUserId/{userId}"; var response = await client.GetAsync(request).ConfigureAwait(false); diff --git a/LearningHub.Nhs.WebUI/Services/UserService.cs b/LearningHub.Nhs.WebUI/Services/UserService.cs index a0ba11d9a..04a2bf68f 100644 --- a/LearningHub.Nhs.WebUI/Services/UserService.cs +++ b/LearningHub.Nhs.WebUI/Services/UserService.cs @@ -54,6 +54,7 @@ public class UserService : BaseService, IUserService /// Initializes a new instance of the class. /// /// The learningHubHttpClient. + /// The Open Api Http Client. /// The userApiHttpClient. /// The logger. /// The settings. @@ -66,6 +67,7 @@ public class UserService : BaseService, IUserService /// The login wizard service service. public UserService( ILearningHubHttpClient learningHubHttpClient, + IOpenApiHttpClient openApiHttpClient, IUserApiHttpClient userApiHttpClient, ILogger logger, IOptions settings, @@ -76,7 +78,7 @@ public UserService( ILocationService locationService, IGradeService gradeService, ILoginWizardService loginWizardService) - : base(learningHubHttpClient, logger) + : base(learningHubHttpClient, openApiHttpClient, logger) { this.userApiHttpClient = userApiHttpClient; this.settings = settings.Value; @@ -94,7 +96,7 @@ public async Task> GetActiveContentAsync() { List viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = "User/GetActiveContent"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -334,7 +336,7 @@ public async Task GetCurrentUserProfileAsync() { UserProfile viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = "User/GetCurrentUserProfile"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -359,7 +361,7 @@ public async Task GetUserProfileAsync(int userId) { UserProfile viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"User/GetUserProfile/{userId}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -387,7 +389,7 @@ public async Task CreateUserProfileAsync(UserProfil var json = JsonConvert.SerializeObject(userProfile); var stringContent = new StringContent(json, Encoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"User/CreateUserProfile"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -422,7 +424,7 @@ public async Task UpdateUserProfileAsync(UserProfil var json = JsonConvert.SerializeObject(userProfile); var stringContent = new StringContent(json, Encoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"User/UpdateUserProfile"; var response = await client.PutAsync(request, stringContent).ConfigureAwait(false); @@ -623,7 +625,7 @@ public async Task GetLHUserByUserIdAsync(int id) { UserLHBasicViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"User/GetByUserId/{id}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -1094,7 +1096,7 @@ public async Task UpdateUserAsync(UserUpdateViewMod var json = JsonConvert.SerializeObject(userUpdateViewModel); var stringContent = new StringContent(json, Encoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"User/UpdateUser"; @@ -1130,7 +1132,7 @@ public async Task CreateUserAsync(UserCreateViewMod var json = JsonConvert.SerializeObject(newLhUser); var stringContent = new StringContent(json, Encoding.UTF8, "application/json"); - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"User/CreateUser"; var response = await client.PostAsync(request, stringContent).ConfigureAwait(false); @@ -1566,7 +1568,7 @@ public async Task ValidateEmailChangeTokenAsyn { EmailChangeValidationTokenResult tokenResult = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"User/ValidateEmailChangeToken/{Uri.EscapeUriString(token.EncodeParameter())}/{Uri.EscapeUriString(loctoken.EncodeParameter())}/{isUserRoleUpgrade}"; @@ -1595,7 +1597,7 @@ public async Task GetLastIssuedEmailChangeV { EmailChangeValidationTokenViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = "User/GetLastIssuedEmailChangeValidationToken"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -1620,7 +1622,7 @@ public async Task RegenerateEmailChangeVali { EmailChangeValidationTokenViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"User/ReGenerateEmailChangeValidationToken/{newPrimaryEmail}/{isUserRoleUpgrade}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -1645,7 +1647,7 @@ public async Task CanRequestPasswordResetAsync(string emailAddress, int pa { bool status = false; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"User/CanRequestPasswordReset/{emailAddress}/{passwordRequestLimitingPeriod}/{passwordRequestLimit}"; var response = await client.GetAsync(request).ConfigureAwait(false); @@ -1670,7 +1672,7 @@ public async Task GenerateEmailChangeValida { EmailChangeValidationTokenViewModel viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"User/GenerateEmailChangeValidationTokenAndSendEmail/{emailAddress}/{isUserRoleUpgrade}"; @@ -1694,7 +1696,7 @@ public async Task GenerateEmailChangeValida /// public async Task CancelEmailChangeValidationTokenAsync() { - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"User/CancelEmailChangeValidationToken"; @@ -1844,7 +1846,7 @@ public async Task> GetProvidersByUserIdAsync(int userId) { List viewmodel = null; - var client = await this.LearningHubHttpClient.GetClientAsync(); + var client = await this.OpenApiHttpClient.GetClientAsync(); var request = $"Provider/GetProvidersByUserId/{userId}"; var response = await client.GetAsync(request).ConfigureAwait(false); diff --git a/LearningHub.Nhs.WebUI/Startup/ServiceMappings.cs b/LearningHub.Nhs.WebUI/Startup/ServiceMappings.cs index fdab0fc8a..0a0c04c49 100644 --- a/LearningHub.Nhs.WebUI/Startup/ServiceMappings.cs +++ b/LearningHub.Nhs.WebUI/Startup/ServiceMappings.cs @@ -39,6 +39,14 @@ public static void AddLearningHubMappings(this IServiceCollection services, ICon HttpClientHandler.DangerousAcceptAnyServerCertificateValidator, }); + services.AddHttpClient() + .ConfigurePrimaryHttpMessageHandler( + () => new HttpClientHandler + { + ServerCertificateCustomValidationCallback = + HttpClientHandler.DangerousAcceptAnyServerCertificateValidator, + }); + services.AddHttpClient() .ConfigurePrimaryHttpMessageHandler( () => new HttpClientHandler @@ -65,6 +73,7 @@ public static void AddLearningHubMappings(this IServiceCollection services, ICon else { services.AddHttpClient(); + services.AddHttpClient(); services.AddHttpClient(); services.AddHttpClient(); services.AddHttpClient(); @@ -103,6 +112,7 @@ public static void AddLearningHubMappings(this IServiceCollection services, ICon services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); diff --git a/LearningHub.Nhs.WebUI/Styles/nhsuk/common.scss b/LearningHub.Nhs.WebUI/Styles/nhsuk/common.scss index 1c18cc3cc..e7e49e651 100644 --- a/LearningHub.Nhs.WebUI/Styles/nhsuk/common.scss +++ b/LearningHub.Nhs.WebUI/Styles/nhsuk/common.scss @@ -1,80 +1,6 @@ @use "../abstracts/all" as *; @use "nhsuk" as *; -.nhsuk-u-font-style-italic { - font-style: italic; -} - -.nhsuk-button--red { - background-color: $nhsuk-red !important; - - &:hover { - background-color: $nhsuk-red-hover !important; - border-color: $nhsuk-red-hover !important; - } -} - -.nhsuk-button--beta-login { - background-color: $nhsuk-blue; - box-shadow: 0 4px 0 #002f5c; -} - -.nhsuk-button--beta-login:hover { - background-color: $nhsuk-btn-blue-hover; -} - -// By default, the text on reverse (white) buttons turns white once clicked, rendering them invisible. -.nhsuk-button--reverse:visited { - color: $nhsuk-black -} - -.nhsuk-back-link { - padding: px2rem(20) 0; - margin-bottom: 0; -} - -.nhsuk-radios__divider { - text-align: left; - width: unset; -} - -.nhsuk-radios__item label { - font-family: $font-stack; -} - -/* Conditional radio buttons - Note: The nhsuk-radios__conditional element needs to be a SIBLING of the radio button input element - otherwise the CSS selector won't work. See Views/Bookmark/Move.cshtml for a usage example. - The NHSUK component (nhsuk-radios__conditional) requires JavaScript to work. These tweaks allow it to work without. -*/ -.nhsuk-radios__conditional { - display: none; - margin-left: -22px; - margin-top: 8px; -} - -.nhsuk-radios__input:checked ~ .nhsuk-radios__conditional { - display: block !important; -} - -/* jquery unbobtrusive validation style over */ -.nhsuk-error-summary__list li { - color: $nhsuk-red; -} - -.nhsuk-form-group.input-validation-error { - @extend .nhsuk-form-group--error; -} - -.nhsuk-input.input-validation-error { - @extend .nhsuk-input--error -} - -.nhsuk-input:focus { - border: 2px solid #212b32; - box-shadow: inset 0 0 0 2px; - outline: 4px solid #ffeb3b; /* 1 */ - outline-offset: 0; -} .display--hide { display: none !important; @@ -120,92 +46,6 @@ } -.nhsuk-bg-light-blue { - background-color: $nhsuk-light-blue-color; -} - -.nhsuk-bg-pale-blue { - background-color: $nhsuk-pale-blue-color; -} - -.nhsuk-bg-white { - background-color: $color_nhsuk-white; -} - -.nhsuk-width-container.search-width-container { - max-width: px2rem(752); - margin: 0 auto; - padding-left: px2rem(68); - padding-right: px2rem(68); -} - -#maincontent { - - button[class^='nhsuk-search__submit'] span.nhsuk-u-visually-hidden { - color: $color_nhsuk-grey-1; - background-color: $color_nhsuk-white; - } -} - -form label.nhsuk-u-visually-hidden { - color: $color_nhsuk-grey-1; - background-color: $color_nhsuk-white; -} - -/* One third column layout that switches to full width at the small desktop breakpoint (990px) instead of mobile. */ -.nhsuk-grid-column-one-third-small-desktop { - @extend .nhsuk-grid-column-one-third; - width: 33.3333333333% !important; - - @media (max-width: px2rem(990)) { - width: 100% !important; - } -} - - -/* Tweaks to styling for single card view. */ -@media(min-width: 768px) and (max-width: 990px) { - .nhsuk-card-group .nhsuk-grid-column-one-third-small-desktop { - max-width: 600px !important; - } - - .nhsuk-card-group--centred { - justify-content: center !important; - } -} - -.nhsuk-card-banner-container { - padding-bottom: 42.86%; - position: relative; -} - -.nhsuk-card-banner { - height: 100%; - object-fit: cover; - object-position: left; - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; -} - -.nhsuk-card-banner-empty { - background-color: $nhsuk-pale-blue-color; - border-bottom: 1px solid #d8dde0; -} - -.nhsuk-error-message.error-message--margin-bottom-1 { - margin-bottom: nhsuk-spacing(1); -} - -.nhsuk-u-margin-bottom-2point5 { - margin-bottom: 12px; - - @media(max-width: 641px) { - margin-bottom: 10px; - } -} .word-break__break-word { word-break: break-word; @@ -216,9 +56,7 @@ form label.nhsuk-u-visually-hidden { justify-content: space-between; } -.nhsuk-button--no-shrink { - white-space: nowrap; -} + .modal-footer--buttons { justify-content: space-between !important; @@ -233,14 +71,6 @@ form label.nhsuk-u-visually-hidden { box-shadow: 0 0 0 0.2rem $nhsuk-yellow !important; background-color: $govuk-focus-highlight-yellow; } -/*Add a background color to the radio button when focused */ -.nhsuk-radios__input:focus + .radioButton { - box-shadow: 0 0 0 3px $nhsuk-yellow; -} -/*Add a background color to the radio button when focused */ -.nhsuk-checkboxes__input:focus + .checkmark { - box-shadow: 0 0 0 4px $nhsuk-yellow; -} .accessible-link:focus { outline: none; diff --git a/LearningHub.Nhs.WebUI/Styles/nhsuk/layout.scss b/LearningHub.Nhs.WebUI/Styles/nhsuk/layout.scss index 4cb2822fe..0e2ac3ad5 100644 --- a/LearningHub.Nhs.WebUI/Styles/nhsuk/layout.scss +++ b/LearningHub.Nhs.WebUI/Styles/nhsuk/layout.scss @@ -5,126 +5,11 @@ body { overflow-wrap: break-word; } -.nhsuk-header { - padding: 0 px2rem(32); -} - -.nhsuk-width-container.app-width-container { - max-width: px2rem(1208); - margin: 0 auto; - padding-left: px2rem(32); - padding-right: px2rem(32); -} - -.nhsuk-header .nhsuk-width-container.app-width-container { - max-width: px2rem(1144); - margin: 0 auto; -} - -.nhsuk-width-container.app-width-container.beta-banner { - padding: px2rem(8) px2rem(32); - max-width: px2rem(1208); - margin: 0 auto; -} - -.nhsuk-header .nhsuk-header__container::after { - content: none; -} - -.nhsuk-header__navigation.app-width-container { - max-width: px2rem(1144); -} - -.app-width-container--full { - margin: 0; - max-width: none -} .app-main-wrapper--no-padding { padding: 0 } -.nhsuk-header__container.app-width-container { - display: flex; - justify-content: space-between; - gap: 0 px2rem(24); - padding: px2rem(16) 0; -} - -.nhsuk-header__content { - display: flex; - align-items: center; - min-height: px2rem(40); - margin-left: auto; -} - -.nhsuk-header__logo { - flex: 1 0 0; -} - -.nhsuk-header__logo .nhsuk-header__link--service { - display: inline-flex; -} - -.nhsuk-header__service-name { - font-size: px2rem(19); -} - -.nhsuk-account__login { - font-size: px2rem(14); - float: right; - position: relative; - z-index: 2; - display: flex; - justify-content: space-between; - align-items: center; - gap: px2rem(24); -} - -.nhsuk-header__notification-dot { - position: absolute; - top: px2rem(8); - right: px2rem(-10); - font-size: px2rem(11); - line-height: px2rem(18); - font-weight: 900; - background: $nhsuk-error-color; - color: white; - min-width: px2rem(18); - height: px2rem(18); - text-align: center; - border-radius: px2rem(9); - padding: px2rem(1) px2rem(3) 0; -} - -.nhsuk-header__menu { - display: none; -} - -.nhsuk-header__search .nhsuk-search__input { - width: px2rem(260); -} - -.nhsuk-header__search { - .nhsuk-search__input { - width: px2rem(260); - - &::-moz-placeholder { - opacity: 1; - } - } - - #search > label.nhsuk-u-visually-hidden { - background-color: $nhsuk-white; - } -} - -.nhsuk-account__login--link, -.nhsuk-account__login--link:visited, -.nhsuk-account__login--link:hover { - color: #fff; -} - .beta-banner { background-color: $color_nhsuk-grey-5; color: $nhsuk-text-color; @@ -155,42 +40,6 @@ body { font-size: px2rem(16); } -.nhsuk-footer { - padding: px2rem(48) 0; -} - - -#header-dropdown-menu-control { - opacity: 0; - position: absolute; -} - -#header-dropdown-menu-control:checked ~ .nhsuk-header__navigation:not(.js-show) { - display: block -} - -#header-mobile-search-control { - display: none; -} - -.nhsuk-header__break { - display: none; -} - -.nhsuk-header__mobile-only-nav { - display: none; -} - -.nhsuk-header__mobile-break { - display: none; -} - -.nhsuk-header__navigation-item--current { - a { - font-weight: bold; - } -} - button[data-toggle="modal"] { color: #005eb8; padding: 0; @@ -204,7 +53,7 @@ button[data-toggle="modal"] { } .autosuggestion-menu { - padding: 16px 16px 0px 16px; + padding: 16px 16px 0px 16px !important; background-color: $color_nhsuk-white; border-bottom: 1px solid $color_nhsuk-grey-4; border-radius: 0px 0px 4px 4px; @@ -254,347 +103,23 @@ button[data-toggle="modal"] { li.autosuggestion-option:last-of-type { border-bottom: none !important; } -/* large desktop */ -@media (min-width: px2rem(990)) { - - .nhsuk-header__navigation-item--current a { - border-bottom: 4px solid $nhsuk-grey-lighter; - font-weight: normal; - } - - .nhsuk-header__navigation-link { - position: relative; - } - - .nhsuk-header__navigation-item:last-child { - margin-right: 16px; - } -} /* small desktop */ @media (max-width: px2rem(989)) { - - .nhsuk-header__container { - flex-wrap: wrap; - } - - .nhsuk-header { - padding: 0; - } - - .nhsuk-header__container.app-width-container { - flex-wrap: wrap; - gap: 0 0; - padding: px2rem(16) px2rem(32); - } - - .nhsuk-header__link--service { - align-items: center; - -ms-flex-align: center; - margin-bottom: 0; - width: auto; - } - - .nhsuk-header__service-name { - padding-left: px2rem(16); - } - - .nhsuk-header__logo { - order: 0; - } - - .nhsuk-account__login { - order: 1; - margin-left: auto; - margin-right: 0px; - } - - .nhsuk-header__break { - display: block; - width: 100%; - height: px2rem(24); - order: 2 - } - - .nhsuk-header__search { - order: 3; - flex-grow: 1; - margin-left: 0; - margin-right: px2rem(24); - } - - .nhsuk-header__menu { - display: block; - position: relative; - order: 4; - flex: 0 0 px2rem(74); - } - - .nhsuk-header__navigation-list .nhsuk-header__navigation-item, - .nhsuk-header__navigation .nhsuk-header__navigation-title { - border-top: 1px solid $color_nhsuk-grey-4; - } - - .nhsuk-header__menu-toggle { - text-align: center; - margin: 0; - right: 0; - font-weight: 600; - } - - .nhsuk-header__search-form { - display: flex; - } - - .nhsuk-header__search .nhsuk-search__input { - flex: 1 0 0; - } - - #header-dropdown-menu-control:checked ~ .nhsuk-header__navigation:not(.js-show) { - display: block; - } - - .nhsuk-header__notification-dot { - position: absolute; - top: px2rem(15); - left: px2rem(115); - font-size: px2rem(11); - line-height: px2rem(18); - font-weight: 900; - background: $nhsuk-error-color; - color: $nhsuk-white; - min-width: px2rem(18); - width: fit-content; - height: px2rem(18); - text-align: center; - border-radius: px2rem(9); - } - - .nhsuk-header__navigation-item--current .nhsuk-header__notification-dot { - left: px2rem(125); - } - - .nhsuk-header__menu-notification-dot { - position: absolute; - top: px2rem(-5); - right: px2rem(-6); - background: $nhsuk-error-color; - width: px2rem(12); - height: px2rem(12); - border-radius: px2rem(6); - box-shadow: 0 0 0 2px white; - z-index: 10; - } - .autosuggestion-menu { top: 100%; } } - /* tablet */ @media (max-width: px2rem(768)) { - - .nhsuk-width-container.app-width-container, - .nhsuk-width-container.app-width-container.beta-banner { - padding-left: px2rem(16); - padding-right: px2rem(16); - } - - .nhsuk-back-link { - padding: 0.5rem 0; - } - - .nhsuk-header__menu .nhsuk-header__not-mobile { - display: none; - } - .autosuggestion-menu { top: 100%; } - - .nhsuk-header__not-mobile { - display: none; - } - - .nhsuk-header__mobile-only-nav { - display: flex; - order: 1; - justify-content: space-around; - gap: 0 px2rem(16); - align-items: flex-start; - flex-wrap: wrap; - width: px2rem(166); - } - - .nhsuk-header__mobile-only-nav .nhsuk-header__menu { - margin-right: px2rem(12); - } - - .nhsuk-header__mobile-only-nav .nhsuk-header__search-toggle { - margin-left: px2rem(12); - } - - .nhsuk-header__break { - display: none; - } - - .nhsuk-header__mobile-break { - display: block; - width: 100%; - height: 0; - } - - .nhsuk-header__link--service { - flex-direction: column; - align-items: flex-start; - } - - .nhsuk-header__notification-dot { - top: px2rem(13); - left: px2rem(100); - } - - .nhsuk-header__service-name { - padding: px2rem(12) 0 0; - } - - .nhsuk-header__search-toggle { - position: relative; - height: px2rem(40); - order: 2; - padding: px2rem(7) px2rem(10) 0; - margin: 0 - } - - .nhsuk-header__search .nhsuk-search__submit { - padding-top: nhsuk-spacing(1); - } - - .nhsuk-header__menu { - order: 3; - } - - .nhsuk-header__search { - order: 4; - width: 100%; - flex-grow: 1; - margin: px2rem(16) px2rem(-16) 0; - border-bottom: 1px solid $color_nhsuk-grey-4; - } - - #header-mobile-search-control { - display: block; - opacity: 0; - position: absolute; - } - - #header-mobile-search-control:checked ~ .nhsuk-header__search .nhsuk-header__search-wrap { - display: block; - } - - .nhsuk-width-container.nhsuk-header__container.app-width-container { - padding-bottom: 0; - } } /* mobile */ @media (max-width: px2rem(640)) { - - .nhsuk-header__not-mobile { - display: none; - } - - .nhsuk-header__logo { - max-width: none; - } - - .nhsuk-header__mobile-only-nav { - display: flex; - order: 1; - justify-content: space-around; - gap: 0 px2rem(16); - align-items: flex-start; - flex-wrap: wrap; - width: px2rem(166); - } - - .nhsuk-header__pre-login .nhsuk-header__mobile-only-nav { - align-items: center; - justify-content: flex-end; - padding-bottom: px2rem(16); - } - - .nhsuk-header__mobile-only-nav .nhsuk-header__menu { - margin-right: px2rem(12); - } - - .nhsuk-header__mobile-only-nav .nhsuk-header__search-toggle { - margin-left: px2rem(12); - } - - .nhsuk-header__break { - display: none; - } - - .nhsuk-header__mobile-break { - display: block; - width: 100%; - height: 0; - } - - .nhsuk-header__link--service { - flex-direction: column; - align-items: flex-start; - } - - .nhsuk-header__notification-dot { - top: px2rem(13); - left: px2rem(100); - } - - .nhsuk-header__service-name { - padding: px2rem(12) 0 0; - } - - .nhsuk-header__search-toggle { - position: relative; - height: px2rem(40); - order: 2; - padding: px2rem(7) px2rem(10) 0; - margin: 0 - } - - .nhsuk-header__search .nhsuk-search__submit { - padding-top: nhsuk-spacing(1); - } - - .nhsuk-header__menu { - order: 3; - } - - .nhsuk-header__search { - order: 4; - width: 100%; - flex-grow: 1; - margin: px2rem(16) px2rem(-16) 0; - border-bottom: 1px solid $color_nhsuk-grey-4; - } - - #header-mobile-search-control { - display: block; - opacity: 0; - position: absolute; - } - - #header-mobile-search-control:checked ~ .nhsuk-header__search .nhsuk-header__search-wrap { - display: block; - } - - .nhsuk-width-container.nhsuk-header__container.app-width-container { - padding-bottom: 0; - } - .autosuggestion-menu { top: 100%; } -} \ No newline at end of file +} diff --git a/LearningHub.Nhs.WebUI/Styles/nhsuk/nhsuk-overrides.scss b/LearningHub.Nhs.WebUI/Styles/nhsuk/nhsuk-overrides.scss new file mode 100644 index 000000000..22c319751 --- /dev/null +++ b/LearningHub.Nhs.WebUI/Styles/nhsuk/nhsuk-overrides.scss @@ -0,0 +1,672 @@ +@use "../abstracts/all" as *; +@use "nhsuk" as *; + +.nhsuk-u-font-style-italic { + font-style: italic; +} + +.nhsuk-button--red { + background-color: $nhsuk-red !important; + + &:hover { + background-color: $nhsuk-red-hover !important; + border-color: $nhsuk-red-hover !important; + } +} + +.nhsuk-button--beta-login { + background-color: $nhsuk-blue; + box-shadow: 0 4px 0 #002f5c; +} + +.nhsuk-button--beta-login:hover { + background-color: $nhsuk-btn-blue-hover; +} + +// By default, the text on reverse (white) buttons turns white once clicked, rendering them invisible. +.nhsuk-button--reverse:visited { + color: $nhsuk-black +} + +.nhsuk-back-link { + padding: px2rem(20) 0; + margin-bottom: 0; +} + +.nhsuk-radios__divider { + text-align: left; + width: unset; +} + +.nhsuk-radios__item label { + font-family: $font-stack; +} + +/* Conditional radio buttons - Note: The nhsuk-radios__conditional element needs to be a SIBLING of the radio button input element + otherwise the CSS selector won't work. See Views/Bookmark/Move.cshtml for a usage example. + The NHSUK component (nhsuk-radios__conditional) requires JavaScript to work. These tweaks allow it to work without. +*/ +.nhsuk-radios__conditional { + display: none; + margin-left: -22px; + margin-top: 8px; +} + +.nhsuk-radios__input:checked ~ .nhsuk-radios__conditional { + display: block !important; +} + +/* jquery unbobtrusive validation style over */ +.nhsuk-error-summary__list li { + color: $nhsuk-red; +} + +.nhsuk-form-group.input-validation-error { + @extend .nhsuk-form-group--error; +} + +.nhsuk-input.input-validation-error { + @extend .nhsuk-input--error +} + +.nhsuk-input:focus { + border: 2px solid #212b32; + box-shadow: inset 0 0 0 2px; + outline: 4px solid #ffeb3b; /* 1 */ + outline-offset: 0; +} + +.nhsuk-bg-light-blue { + background-color: $nhsuk-light-blue-color; +} + +.nhsuk-bg-pale-blue { + background-color: $nhsuk-pale-blue-color; +} + +.nhsuk-bg-white { + background-color: $color_nhsuk-white; +} + +.nhsuk-width-container.search-width-container { + max-width: px2rem(752); + margin: 0 auto; + padding-left: px2rem(68); + padding-right: px2rem(68); +} + +#maincontent { + button[class^='nhsuk-search__submit'] span.nhsuk-u-visually-hidden { + color: $color_nhsuk-grey-1; + background-color: $color_nhsuk-white; + } +} + +form label.nhsuk-u-visually-hidden { + color: $color_nhsuk-grey-1; + background-color: $color_nhsuk-white; +} + +/* One third column layout that switches to full width at the small desktop breakpoint (990px) instead of mobile. */ +.nhsuk-grid-column-one-third-small-desktop { + @extend .nhsuk-grid-column-one-third; + width: 33.3333333333% !important; + + @media (max-width: px2rem(990)) { + width: 100% !important; + } +} + + +/* Tweaks to styling for single card view. */ +@media(min-width: 768px) and (max-width: 990px) { + .nhsuk-card-group .nhsuk-grid-column-one-third-small-desktop { + max-width: 600px !important; + } + + .nhsuk-card-group--centred { + justify-content: center !important; + } +} + +.nhsuk-card-banner-container { + padding-bottom: 42.86%; + position: relative; +} + +.nhsuk-card-banner { + height: 100%; + object-fit: cover; + object-position: left; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; +} + +.nhsuk-card-banner-empty { + background-color: $nhsuk-pale-blue-color; + border-bottom: 1px solid #d8dde0; +} + +.nhsuk-error-message.error-message--margin-bottom-1 { + margin-bottom: nhsuk-spacing(1); +} + +.nhsuk-u-margin-bottom-2point5 { + margin-bottom: 12px; + + @media(max-width: 641px) { + margin-bottom: 10px; + } +} + +.nhsuk-button--no-shrink { + white-space: nowrap; +} + +/*Add a background color to the radio button when focused */ +.nhsuk-radios__input:focus + .radioButton { + box-shadow: 0 0 0 3px $nhsuk-yellow; +} +/*Add a background color to the radio button when focused */ +.nhsuk-checkboxes__input:focus + .checkmark { + box-shadow: 0 0 0 4px $nhsuk-yellow; +} + + + +// Below taken from layout.scss +// Overrides largely due to +// - Highly customised header +// - Use of full browser width hero images and full width colour bands +// - Beta banner +// +// Header customisation not needed with current frontend package +// - FGC 19/06/25 + + +.nhsuk-width-container.app-width-container { + max-width: px2rem(1208); + margin: 0 auto; + padding-left: px2rem(32); + padding-right: px2rem(32); +} + +// Header items +.nhsuk-header { + padding: 0 px2rem(32); +} + +.nhsuk-header .nhsuk-width-container.app-width-container { + max-width: px2rem(1144); + margin: 0 auto; +} + +.nhsuk-width-container.app-width-container.beta-banner { + padding: px2rem(8) px2rem(32); + max-width: px2rem(1208); + margin: 0 auto; +} + +.nhsuk-header .nhsuk-header__container::after { + content: none; +} + +.nhsuk-header__navigation.app-width-container { + max-width: px2rem(1144); +} + +.nhsuk-header__container.app-width-container { + display: flex; + justify-content: space-between; + gap: 0 px2rem(24); + padding: px2rem(16) 0; +} + +.nhsuk-header__logo { + flex: 1 0 0; +} + +.nhsuk-header__logo .nhsuk-header__link--service { + display: inline-flex; +} + +.nhsuk-header__service-name { + font-size: px2rem(19); +} + +.nhsuk-header__notification-dot { + position: absolute; + top: px2rem(8); + right: px2rem(-10); + font-size: px2rem(11); + line-height: px2rem(18); + font-weight: 900; + background: $nhsuk-error-color; + color: white; + min-width: px2rem(18); + height: px2rem(18); + text-align: center; + border-radius: px2rem(9); + padding: px2rem(1) px2rem(3) 0; +} + +.nhsuk-header__menu { + display: none; +} + +.nhsuk-header__search .nhsuk-search__input { + width: px2rem(260); +} + +.nhsuk-header__search { + .nhsuk-search__input { + width: px2rem(260); + + &::-moz-placeholder { + opacity: 1; + } + } + + #search > label.nhsuk-u-visually-hidden { + background-color: $nhsuk-white; + } +} + +#header-dropdown-menu-control { + opacity: 0; + position: absolute; +} + + +#header-dropdown-menu-control:checked ~ .nhsuk-header__navigation:not(.js-show) { + display: block +} + +#header-mobile-search-control { + display: none; +} + +.nhsuk-header__break { + display: none; +} + +.nhsuk-header__mobile-only-nav { + display: none; +} + +.nhsuk-header__mobile-break { + display: none; +} + +.nhsuk-header__navigation-item--current { + a { + font-weight: bold; + } +} + +.nhsuk-account__login { + // also a header item + font-size: px2rem(14); + float: right; + position: relative; + z-index: 2; + display: flex; + justify-content: space-between; + align-items: center; + gap: px2rem(24); +} + +.nhsuk-account__login--link, +.nhsuk-account__login--link:visited, +.nhsuk-account__login--link:hover { + // all header items + color: #fff; +} + + +// End of header items + + +.nhsuk-width-container.app-width-container--full { + // used to allow placement of hero (full width) images + margin: 0; + max-width: none +} + +.app-main-wrapper--no-padding { + // allowing hero image to touch headers + padding: 0 +} + +.nhsuk-footer { + padding: px2rem(48) 0; +} + + + +/* large desktop */ +@media (min-width: px2rem(990)) { + // entirely headers + + .nhsuk-header__navigation-item--current a { + border-bottom: 4px solid $nhsuk-grey-lighter; + font-weight: normal; + } + + .nhsuk-header__navigation-link { + position: relative; + } + + .nhsuk-header__navigation-item:last-child { + margin-right: 16px; + } +} + +/* small desktop */ +@media (max-width: px2rem(989)) { + + //entirely headers + + .nhsuk-header__container { + flex-wrap: wrap; + } + + .nhsuk-header { + padding: 0; + } + + .nhsuk-header__container.app-width-container { + flex-wrap: wrap; + gap: 0 0; + padding: px2rem(16) px2rem(32); + } + + .nhsuk-header__link--service { + align-items: center; + -ms-flex-align: center; + margin-bottom: 0; + width: auto; + } + + .nhsuk-header__service-name { + padding-left: px2rem(16); + } + + .nhsuk-header__logo { + order: 0; + } + + .nhsuk-account__login { + // also part of the header + order: 1; + margin-left: auto; + margin-right: 0px; + } + + .nhsuk-header__break { + display: block; + width: 100%; + height: px2rem(24); + order: 2 + } + + .nhsuk-header__search { + order: 3; + flex-grow: 1; + margin-left: 0; + margin-right: px2rem(24); + } + + .nhsuk-header__menu { + display: block; + position: relative; + order: 4; + flex: 0 0 px2rem(74); + } + + .nhsuk-header__navigation-list .nhsuk-header__navigation-item, + .nhsuk-header__navigation .nhsuk-header__navigation-title { + border-top: 1px solid $color_nhsuk-grey-4; + } + + .nhsuk-header__menu-toggle { + text-align: center; + margin: 0; + right: 0; + font-weight: 600; + } + + .nhsuk-header__search-form { + display: flex; + } + + .nhsuk-header__search .nhsuk-search__input { + flex: 1 0 0; + } + + #header-dropdown-menu-control:checked ~ .nhsuk-header__navigation:not(.js-show) { + display: block; + } + + .nhsuk-header__notification-dot { + position: absolute; + top: px2rem(15); + left: px2rem(115); + font-size: px2rem(11); + line-height: px2rem(18); + font-weight: 900; + background: $nhsuk-error-color; + color: $nhsuk-white; + min-width: px2rem(18); + width: fit-content; + height: px2rem(18); + text-align: center; + border-radius: px2rem(9); + } + + .nhsuk-header__navigation-item--current .nhsuk-header__notification-dot { + left: px2rem(125); + } + + .nhsuk-header__menu-notification-dot { + position: absolute; + top: px2rem(-5); + right: px2rem(-6); + background: $nhsuk-error-color; + width: px2rem(12); + height: px2rem(12); + border-radius: px2rem(6); + box-shadow: 0 0 0 2px white; + z-index: 10; + } +} + +@media (max-width: px2rem(768)) { + .nhsuk-width-container.app-width-container, + .nhsuk-width-container.app-width-container.beta-banner { + padding-left: px2rem(16); + padding-right: px2rem(16); + } + + // entirely headers from this point + + .nhsuk-back-link { + padding: 0.5rem 0; + } + + .nhsuk-header__menu .nhsuk-header__not-mobile { + display: none; + } + + .nhsuk-header__not-mobile { + display: none; + } + + .nhsuk-header__mobile-only-nav { + display: flex; + order: 1; + justify-content: space-around; + gap: 0 px2rem(16); + align-items: flex-start; + flex-wrap: wrap; + width: px2rem(166); + } + + .nhsuk-header__mobile-only-nav .nhsuk-header__menu { + margin-right: px2rem(12); + } + + .nhsuk-header__mobile-only-nav .nhsuk-header__search-toggle { + margin-left: px2rem(12); + } + + .nhsuk-header__break { + display: none; + } + + .nhsuk-header__mobile-break { + display: block; + width: 100%; + height: 0; + } + + .nhsuk-header__link--service { + flex-direction: column; + align-items: flex-start; + } + + .nhsuk-header__notification-dot { + top: px2rem(13); + left: px2rem(100); + } + + .nhsuk-header__service-name { + padding: px2rem(12) 0 0; + } + + .nhsuk-header__search-toggle { + position: relative; + height: px2rem(40); + order: 2; + padding: px2rem(7) px2rem(10) 0; + margin: 0 + } + + .nhsuk-header__search .nhsuk-search__submit { + padding-top: nhsuk-spacing(1); + } + + .nhsuk-header__menu { + order: 3; + } + + .nhsuk-header__search { + order: 4; + width: 100%; + flex-grow: 1; + margin: px2rem(16) px2rem(-16) 0; + border-bottom: 1px solid $color_nhsuk-grey-4; + } +} + +@media (max-width: px2rem(640)) { + + //entirely headers + + .nhsuk-header__not-mobile { + display: none; + } + + .nhsuk-header__logo { + max-width: none; + } + + .nhsuk-header__mobile-only-nav { + display: flex; + order: 1; + justify-content: space-around; + gap: 0 px2rem(16); + align-items: flex-start; + flex-wrap: wrap; + width: px2rem(166); + } + + .nhsuk-header__pre-login .nhsuk-header__mobile-only-nav { + align-items: center; + justify-content: flex-end; + padding-bottom: px2rem(16); + } + + .nhsuk-header__mobile-only-nav .nhsuk-header__menu { + margin-right: px2rem(12); + } + + .nhsuk-header__mobile-only-nav .nhsuk-header__search-toggle { + margin-left: px2rem(12); + } + + .nhsuk-header__break { + display: none; + } + + .nhsuk-header__mobile-break { + display: block; + width: 100%; + height: 0; + } + + .nhsuk-header__link--service { + flex-direction: column; + align-items: flex-start; + } + + .nhsuk-header__notification-dot { + top: px2rem(13); + left: px2rem(100); + } + + .nhsuk-header__service-name { + padding: px2rem(12) 0 0; + } + + .nhsuk-header__search-toggle { + position: relative; + height: px2rem(40); + order: 2; + padding: px2rem(7) px2rem(10) 0; + margin: 0 + } + + .nhsuk-header__search .nhsuk-search__submit { + padding-top: nhsuk-spacing(1); + } + + .nhsuk-header__menu { + order: 3; + } + + .nhsuk-header__search { + order: 4; + width: 100%; + flex-grow: 1; + margin: px2rem(16) px2rem(-16) 0; + border-bottom: 1px solid $color_nhsuk-grey-4; + } + + #header-mobile-search-control { + display: block; + opacity: 0; + position: absolute; + } + + #header-mobile-search-control:checked ~ .nhsuk-header__search .nhsuk-header__search-wrap { + display: block; + } + + .nhsuk-width-container.nhsuk-header__container.app-width-container { + padding-bottom: 0; + } +} diff --git a/LearningHub.Nhs.WebUI/Styles/sections/_all.scss b/LearningHub.Nhs.WebUI/Styles/sections/_all.scss index 22c55622d..a127ade9d 100644 --- a/LearningHub.Nhs.WebUI/Styles/sections/_all.scss +++ b/LearningHub.Nhs.WebUI/Styles/sections/_all.scss @@ -140,268 +140,272 @@ div.contribute { } div.contribute { - h2 { - .warningTriangle { - padding-left: 10px; - vertical-align: middle; - } - } - - h3 { - .warningTriangle { - padding-left: 10px; - vertical-align: middle; - } - } - - div.common-content { - div.form-group { - margin-bottom: 0; + h2 { + .warningTriangle { + padding-left: 10px; + vertical-align: middle; + } } - .bg-grey-white { - padding: 17px 25px 30px 25px; - color: $nhsuk-black; + h3 { + .warningTriangle { + padding-left: 10px; + vertical-align: middle; + } } - } - div.white-background { - background-color: $nhsuk-white; - min-height: 420px; - } - - .limit-width { - width: 100%; - max-width: 850px; - margin-left: 40px; - padding-right: 50px; - } + div.common-content { + div.form-group { + margin-bottom: 0; + } - div.contribute-header { - .draftText { - color: $nhsuk-green; - margin-top: 0; + .bg-grey-white { + padding: 17px 25px 30px 25px; + color: $nhsuk-black; + } } - .error-message { - color: $nhsuk-red; - font-weight: bold; + div.white-background { + background-color: $nhsuk-white; + min-height: 420px; } - .warning-banner { - display: flex; - flex-flow: row; - justify-content: space-between; - padding: 1.5rem 1.5rem 0.8rem 1.5rem; - border-bottom: 1px solid $nhsuk-grey-light; - border-top: 1px solid $nhsuk-grey-light; - - div.warningTriangle { - font-size: 40px; - } - - div.info { - padding-left: 12px; - } - - div.dismiss { - text-align: end; - padding-top: .5rem; - padding-right: 2rem; - - button { - font-size: 2.5rem; - color: $nhsuk-grey; - } - } - - .warning-banner-left { - display: flex; - justify-content: space-between; + .limit-width { width: 100%; - max-width: 800px; + max-width: 850px; margin-left: 40px; - } + padding-right: 50px; } - } - .warningTriangle { - color: #ffb81c; - font-size: 2rem; + div.contribute-header { + .draftText { + color: $nhsuk-green; + margin-top: 0; + } - &.large { - font-size: 4rem !important; - } - } + .error-message { + color: $nhsuk-red; + font-weight: bold; + } - button.delete-button { - text-decoration: none; - color: $nhsuk-grey-placeholder; - font-size: 1.6rem; + .warning-banner { + display: flex; + flex-flow: row; + justify-content: space-between; + padding: 1.5rem 1.5rem 0.8rem 1.5rem; + border-bottom: 1px solid $nhsuk-grey-light; + border-top: 1px solid $nhsuk-grey-light; + + div.warningTriangle { + font-size: 40px; + } - i { - margin-right: 4px; - font-size: 1.8rem; - } - } + div.info { + padding-left: 12px; + } - button.publish-button { - color: $nhsuk-white; - background-color: $nhsuk-green; - font-size: 19px; - text-align: center !important; - border: 1px solid $nhsuk-green !important; - min-height: 50px; - min-width: 115px; - padding: 0px 25px 0px 25px; - border-radius: 5px; - } + div.dismiss { + text-align: end; + padding-top: .5rem; + padding-right: 2rem; - button.publish-button:disabled { - background-color: $nhsuk-grey; - border-color: $nhsuk-grey !important; - } + button { + font-size: 2.5rem; + color: $nhsuk-grey; + } + } - button.btn-outline-custom:disabled { - color: $nhsuk-grey !important; - border-color: $nhsuk-grey !important; - } + .warning-banner-left { + display: flex; + justify-content: space-between; + width: 100%; + max-width: 800px; + margin-left: 40px; + } + } + } - button.btn-outline-custom:disabled:hover { - background-color: $nhsuk-white !important; - } + .warningTriangle { + color: #ffb81c; + font-size: 2rem; - div.resource-area-container, div.common-content { - div.resource-area-header { - background-color: $nhsuk-grey; - color: $nhsuk-grey-white; - border-top-left-radius: .5rem; - border-top-right-radius: .5rem; - font-family: $font-stack-bold; - padding: 1.4rem 2rem 1.0rem 2rem; - display: flex; - justify-content: space-between; + &.large { + font-size: 4rem !important; + } + } - a, - button { + button.delete-button { text-decoration: none; - font-size: 19px; - font-family: $font-stack; - color: $nhsuk-grey-white !important; - padding-top: 0; + color: $nhsuk-grey-placeholder; + font-size: 1.6rem; i { - margin-left: 4px; + margin-right: 4px; + font-size: 1.8rem; } - } } - div.resource-area-body { - background-color: $nhsuk-grey-white; - border-bottom-left-radius: .5rem; - border-bottom-right-radius: .5rem; - min-height: 300px; - padding: 20px 10px 20px 10px; + button.publish-button { + color: $nhsuk-white; + background-color: $nhsuk-green; + font-size: 19px; + text-align: center !important; + border: 1px solid $nhsuk-green !important; + min-height: 50px; + min-width: 115px; + padding: 0px 25px 0px 25px; + border-radius: 5px; } - .radio-options { - height: 12px !important; - width: 12px !important; - border: 1px solid $nhsuk-black; - color: $nhsuk-black; + button.publish-button:disabled { + background-color: $nhsuk-grey; + border-color: $nhsuk-grey !important; } - .radio-options-text { - margin-right: 20px; + button.btn-outline-custom:disabled { + color: $nhsuk-grey !important; + border-color: $nhsuk-grey !important; } - .author-details, .file-details, .licence-details { - display: flex; - justify-content: space-between; - background-color: $nhsuk-white; - border-radius: 5px; - padding: 25px; + button.btn-outline-custom:disabled:hover { + background-color: $nhsuk-white !important; + } - button, - a { - font-size: 16px; - color: $nhsuk-red; - text-decoration: none; - display: flex; - justify-content: space-between; + div.resource-area-container, div.common-content { + div.resource-area-header { + background-color: $nhsuk-grey; + color: $nhsuk-grey-white; + border-top-left-radius: .5rem; + border-top-right-radius: .5rem; + font-family: $font-stack-bold; + padding: 1.4rem 2rem 1.0rem 2rem; + display: flex; + justify-content: space-between; - i { - padding-left: 10px; - padding-top: 3px; + a, + button { + text-decoration: none; + font-size: 19px; + font-family: $font-stack; + color: $nhsuk-grey-white !important; + padding-top: 0; + + i { + margin-left: 4px; + } + } } - } - .divider { - color: $nhsuk-grey-light; - } - } + div.resource-area-body { + background-color: $nhsuk-grey-white; + border-bottom-left-radius: .5rem; + border-bottom-right-radius: .5rem; + min-height: 300px; + padding: 20px 10px 20px 10px; + } - .author-details { - border: solid 1px $nhsuk-grey-light; - padding: 22px 15px 10px 15px; + .radio-options { + height: 12px !important; + width: 12px !important; + border: 1px solid $nhsuk-black; + color: $nhsuk-black; + } - i { - color: $nhsuk-grey; - margin-right: 1rem; - } - } + .radio-options-text { + margin-right: 20px; + } - .keyword-container { - display: flex; - flex-wrap: wrap; + .author-details, .file-details, .licence-details { + display: flex; + justify-content: space-between; + background-color: $nhsuk-white; + border-radius: 5px; + padding: 25px; + + button, + a { + font-size: 16px; + color: $nhsuk-red; + text-decoration: none; + display: flex; + justify-content: space-between; + + i { + padding-left: 10px; + padding-top: 3px; + } + } - .keyword-tag { - background-color: $nhsuk-grey-white; - border-radius: 20px; - margin-bottom: 10px; - padding: 8px 10px 3px 15px; + .divider { + color: $nhsuk-grey-light; + } + } - button { - color: $nhsuk-red; - font-size: 2rem; + .author-details { + border: solid 1px $nhsuk-grey-light; + padding: 22px 15px 10px 15px; + + i { + color: $nhsuk-grey; + margin-right: 1rem; + } } - } - } - span.optional { - font-family: $font-stack; - } + .keyword-label { + font-weight: normal; + } + + .keyword-container { + display: flex; + flex-wrap: wrap; + + .keyword-tag { + background-color: $nhsuk-grey-white; + border-radius: 20px; + margin-bottom: 10px; + padding: 8px 10px 3px 15px; + + button { + color: $nhsuk-red; + font-size: 2rem; + } + } + } + + span.optional { + font-family: $font-stack; + } - textarea { - width: 100%; + textarea { + width: 100%; + } } - } - .authored-date label { - font-size: 1.6rem; - } + .authored-date label { + font-size: 1.6rem; + } - div.publish-warning { - display: flex; - flex-direction: row; + div.publish-warning { + display: flex; + flex-direction: row; - .triangle { - margin-right: 10px; - display: flex; - align-items: center; + .triangle { + margin-right: 10px; + display: flex; + align-items: center; - i { - padding-top: 5px; - } + i { + padding-top: 5px; + } + } } - } - div.highlighted-info { - background-color: rgba(255, 184, 28, 0.05); - border: 1px solid #FFB81C; - padding: 15px 24px; - margin: 15px 15px 0 15px; - } + div.highlighted-info { + background-color: rgba(255, 184, 28, 0.05); + border: 1px solid #FFB81C; + padding: 15px 24px; + margin: 15px 15px 0 15px; + } } @media (max-width: 768px) { diff --git a/LearningHub.Nhs.WebUI/Views/Account/CreateAccountValidAccountAlreadyExists.cshtml b/LearningHub.Nhs.WebUI/Views/Account/CreateAccountValidAccountAlreadyExists.cshtml index a4b62e4fd..1ebfc59d4 100644 --- a/LearningHub.Nhs.WebUI/Views/Account/CreateAccountValidAccountAlreadyExists.cshtml +++ b/LearningHub.Nhs.WebUI/Views/Account/CreateAccountValidAccountAlreadyExists.cshtml @@ -25,7 +25,7 @@
+ class="nhsuk-button nhsuk-u-margin-right-3 nhsuk-u-margin-bottom-4">Learning Hub Log in OpenAthens Log in
diff --git a/LearningHub.Nhs.WebUI/Views/Catalogue/Index.cshtml b/LearningHub.Nhs.WebUI/Views/Catalogue/Index.cshtml index c3dbb7e45..03ef6c173 100644 --- a/LearningHub.Nhs.WebUI/Views/Catalogue/Index.cshtml +++ b/LearningHub.Nhs.WebUI/Views/Catalogue/Index.cshtml @@ -9,16 +9,15 @@ ViewData["Title"] = "Catalogue"; - bool CanManage() - { - return IsInRole(RoleEnum.LocalAdmin); - } + bool CanManage() + { + return IsInRole(RoleEnum.LocalAdmin); + } - bool Unlocked() - { - return IsInRole(RoleEnum.LocalAdmin) || IsInRole(RoleEnum.Editor) || IsInRole(RoleEnum.Reader) ; - //// || this.User.IsInRole("Administrator") - } + bool Unlocked() + { + return IsInRole(RoleEnum.LocalAdmin) || IsInRole(RoleEnum.Editor) || IsInRole(RoleEnum.Reader) || this.User.IsInRole("Administrator"); + } bool IsInRole(RoleEnum role) { diff --git a/LearningHub.Nhs.WebUI/Views/Home/Dashboard.cshtml b/LearningHub.Nhs.WebUI/Views/Home/Dashboard.cshtml index 4a7b55c08..e8481a4c7 100644 --- a/LearningHub.Nhs.WebUI/Views/Home/Dashboard.cshtml +++ b/LearningHub.Nhs.WebUI/Views/Home/Dashboard.cshtml @@ -5,7 +5,15 @@ @{ ViewData["Title"] = "Learning Hub - Home"; - var isReadOnly = User.IsInRole("ReadOnly") || User.IsInRole("BasicUser"); + var isReadOnly = false; + if (User.IsInRole("ReadOnly") || User.IsInRole("BasicUser")) + { + isReadOnly = true; + } + else if (User.IsInRole("BlueUser") && !this.ViewBag.userHasContributePermission) + { + isReadOnly = true; + } } @section styles { diff --git a/LearningHub.Nhs.WebUI/Views/Search/_SearchBar.cshtml b/LearningHub.Nhs.WebUI/Views/Search/_SearchBar.cshtml index a0139e3eb..da4a475e9 100644 --- a/LearningHub.Nhs.WebUI/Views/Search/_SearchBar.cshtml +++ b/LearningHub.Nhs.WebUI/Views/Search/_SearchBar.cshtml @@ -48,8 +48,8 @@ function autocomplete(input, minLength) { if (input != null) { input.addEventListener("input", function () { - var val = this.value; - if (val.length < minLength) { + var val = this.value.trimStart(); + if (val.length < minLength || val.trim() === "") { closeAllLists(); return false; } diff --git a/LearningHub.Nhs.WebUI/Views/Shared/Components/NavigationItems/Searchbar.cshtml b/LearningHub.Nhs.WebUI/Views/Shared/Components/NavigationItems/Searchbar.cshtml index 8f7f8a738..f3a69f8e6 100644 --- a/LearningHub.Nhs.WebUI/Views/Shared/Components/NavigationItems/Searchbar.cshtml +++ b/LearningHub.Nhs.WebUI/Views/Shared/Components/NavigationItems/Searchbar.cshtml @@ -72,8 +72,8 @@ function autocomplete(input, minLength) { if (input != null) { input.addEventListener("input", function () { - var val = this.value; - if (val.length < minLength) { + var val = this.value.trimStart(); + if (val.length < minLength || val.trim() === "") { closeAllLists(); return false; } diff --git a/LearningHub.Nhs.WebUI/Views/Shared/Tenant/LearningHub/_Layout.cshtml b/LearningHub.Nhs.WebUI/Views/Shared/Tenant/LearningHub/_Layout.cshtml index c16fa837c..6b679b67e 100644 --- a/LearningHub.Nhs.WebUI/Views/Shared/Tenant/LearningHub/_Layout.cshtml +++ b/LearningHub.Nhs.WebUI/Views/Shared/Tenant/LearningHub/_Layout.cshtml @@ -21,6 +21,7 @@ +