Skip to content

Commit 5bb4378

Browse files
authored
Merge pull request #1484 from TechnologyEnhancedLearning/MergeRC-CI
Merge RC Changes into CI
2 parents 8af1ef3 + e37a067 commit 5bb4378

File tree

205 files changed

+11189
-2229
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

205 files changed

+11189
-2229
lines changed

.gitignore

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,13 @@ obj
5656
/AdminUI/LearningHub.Nhs.AdminUI/web.config
5757
/LearningHub.Nhs.WebUI/web.config
5858
/WebAPI/LearningHub.Nhs.API/web.config
59+
/.github/workflows/test.yml
60+
/LearningHub.Nhs.WebUI.BlazorClient/Properties/launchSettings.json
61+
/LearningHub.Nhs.WebUI.slnLaunch.user
62+
/LearningHub.Nhs.WebUI.BlazorClient/LearningHub.Nhs.WebUI.BlazorClient.csproj.user
63+
/LearningHub.Nhs.WebUI.BlazorClient/wwwroot/appsettings.Development.json
5964
/nuget.config
6065
/LearningHub.Nhs.WebUI.slnLaunch.user
6166
/LearningHub.Nhs.WebUI.BlazorClient/LearningHub.Nhs.WebUI.BlazorClient.csproj.user
6267
/LearningHub.Nhs.WebUI.BlazorClient/wwwroot/appsettings.Development.json
63-
/LearningHub.Nhs.WebUI.BlazorClient/Properties/launchSettings.json
64-
/.github/workflows/test.yml
68+
/LearningHub.Nhs.WebUI.BlazorClient/Properties/launchSettings.json

AdminUI/LearningHub.Nhs.AdminUI/LearningHub.Nhs.AdminUI.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk.Web">
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
22

33
<PropertyGroup>
44
<TargetFramework>net8.0</TargetFramework>
@@ -83,13 +83,13 @@
8383
<PackageReference Include="Azure.Storage.Blobs" Version="12.23.0" />
8484
<PackageReference Include="Azure.Storage.Files.Shares" Version="12.8.0" />
8585
<PackageReference Include="BuildWebCompiler" Version="1.12.405" />
86-
<PackageReference Include="elfhHub.Nhs.Models" Version="3.0.9" />
86+
<PackageReference Include="elfhHub.Nhs.Models" Version="3.0.14" />
8787
<PackageReference Include="FluentValidation" Version="11.11.0" />
8888
<PackageReference Include="FluentValidation.AspNetCore" Version="11.3.0" />
8989
<PackageReference Include="HtmlSanitizer" Version="6.0.453" />
9090
<PackageReference Include="IdentityModel" Version="4.6.0" />
9191
<PackageReference Include="LearningHub.Nhs.Caching" Version="2.0.2" />
92-
<PackageReference Include="LearningHub.Nhs.Models" Version="3.0.48" />
92+
<PackageReference Include="LearningHub.Nhs.Models" Version="4.0.2" />
9393
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.19.0" />
9494
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="6.0.36" />
9595
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.36" />

LearningHub.Nhs.WebUI.AutomatedUiTests/LearningHub.Nhs.WebUI.AutomatedUiTests.csproj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<TargetFramework>net8.0</TargetFramework>
@@ -11,7 +11,9 @@
1111
</PropertyGroup>
1212

1313
<ItemGroup>
14+
<PackageReference Include="elfhHub.Nhs.Models" Version="3.0.14" />
1415
<PackageReference Include="FluentAssertions" Version="6.12.0" />
16+
<PackageReference Include="LearningHub.Nhs.Models" Version="4.0.2" />
1517
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="3.1.13" />
1618
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
1719
<PackageReference Include="Selenium.Axe" Version="4.0.19" />
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
namespace LearningHub.Nhs.WebUI.Configuration
2+
{
3+
/// <summary>
4+
/// The Moodle Settings.
5+
/// </summary>
6+
public class MoodleApiConfig
7+
{
8+
/// <summary>
9+
/// Gets or sets the base url for the Moodle service.
10+
/// </summary>
11+
public string BaseUrl { get; set; } = null!;
12+
13+
/// <summary>
14+
/// Gets or sets the Web service Rest Format.
15+
/// </summary>
16+
public string MoodleWSRestFormat { get; set; } = null!;
17+
18+
/// <summary>
19+
/// Gets or sets the token.
20+
/// </summary>
21+
public string WSToken { get; set; } = null!;
22+
23+
/// <summary>
24+
/// Gets or sets the token.
25+
/// </summary>
26+
public string ApiPath { get; set; } = "webservice/rest/server.php";
27+
28+
/// <summary>
29+
/// Gets or sets the token.
30+
/// </summary>
31+
public string CoursePath { get; set; } = "course/view.php";
32+
}
33+
}

LearningHub.Nhs.WebUI/Controllers/AccountController.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -999,7 +999,7 @@ public async Task<IActionResult> CreateAccountWorkPlace(AccountCreationViewModel
999999
if (!string.IsNullOrWhiteSpace(accountCreation.LocationId))
10001000
{
10011001
var selectedLocation = await this.locationService.GetByIdAsync(int.Parse(accountCreation.LocationId));
1002-
return this.View(new AccountCreationListViewModel { WorkPlaceList = new List<LocationBasicViewModel> { selectedLocation }, FilterText = selectedLocation.Name, AccountCreationPaging = new AccountCreationPagingModel { TotalItems = 1, PageSize = UserRegistrationContentPageSize, HasItems = selectedLocation != null, CurrentPage = 1 }, LocationId = accountCreation.LocationId, ReturnToConfirmation = accountCreationViewModel.ReturnToConfirmation });
1002+
return this.View(new AccountCreationListViewModel { WorkPlaceList = new List<LocationBasicViewModel> { selectedLocation }, FilterText = selectedLocation.NameWithoutSubName, AccountCreationPaging = new AccountCreationPagingModel { TotalItems = 1, PageSize = UserRegistrationContentPageSize, HasItems = selectedLocation != null, CurrentPage = 1 }, LocationId = accountCreation.LocationId, ReturnToConfirmation = accountCreationViewModel.ReturnToConfirmation });
10031003
}
10041004

10051005
accountCreationViewModel.PrimarySpecialtyId = accountCreation.PrimarySpecialtyId;

LearningHub.Nhs.WebUI/Controllers/Api/MyLearningController.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,34 @@ public async Task<ActionResult> GetActivityDetailed([FromBody] MyLearningRequest
4444
return this.Ok(activity);
4545
}
4646

47+
/// <summary>
48+
/// Gets the detailed activity data.
49+
/// </summary>
50+
/// <param name="requestModel">The request model - filter settings.</param>
51+
/// <returns>The <see cref="Task"/>.</returns>
52+
[HttpPost]
53+
[Route("GetUserRecentMyLearningActivities")]
54+
public async Task<ActionResult> GetUserRecentMyLearningActivities([FromBody] MyLearningRequestModel requestModel)
55+
{
56+
var activity = await this.myLearningService.GetUserRecentMyLearningActivities(requestModel);
57+
58+
return this.Ok(activity);
59+
}
60+
61+
/// <summary>
62+
/// Gets the detailed activity data.
63+
/// </summary>
64+
/// <param name="requestModel">The request model - filter settings.</param>
65+
/// <returns>The <see cref="Task"/>.</returns>
66+
[HttpPost]
67+
[Route("GetUserLearningHistory")]
68+
public async Task<ActionResult> GetUserLearningHistory([FromBody] MyLearningRequestModel requestModel)
69+
{
70+
var activity = await this.myLearningService.GetUserLearningHistory(requestModel);
71+
72+
return this.Ok(activity);
73+
}
74+
4775
/// <summary>
4876
/// Gets the played segment data for the progress modal in My Learning screen.
4977
/// </summary>

LearningHub.Nhs.WebUI/Controllers/ContributeController.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public class ContributeController : BaseController
2828
private readonly IFileService fileService;
2929
private readonly IResourceService resourceService;
3030
private readonly IUserService userService;
31+
private readonly IUserGroupService userGroupService;
3132

3233
/// <summary>
3334
/// Initializes a new instance of the <see cref="ContributeController"/> class.
@@ -37,6 +38,7 @@ public class ContributeController : BaseController
3738
/// <param name="logger">Logger.</param>
3839
/// <param name="settings">Settings.</param>
3940
/// <param name="userService">User service.</param>
41+
/// <param name="userGroupService"> userGroupService.</param>
4042
/// <param name="fileService">File service.</param>
4143
/// <param name="resourceService">Resource service.</param>
4244
/// <param name="azureMediaService">Azure media service.</param>
@@ -48,6 +50,7 @@ public ContributeController(
4850
ILogger<ContributeController> logger,
4951
IOptions<Settings> settings,
5052
IUserService userService,
53+
IUserGroupService userGroupService,
5154
IFileService fileService,
5255
IResourceService resourceService,
5356
IAzureMediaService azureMediaService,
@@ -58,6 +61,7 @@ public ContributeController(
5861
this.authConfig = authConfig;
5962

6063
this.userService = userService;
64+
this.userGroupService = userGroupService;
6165
this.fileService = fileService;
6266
this.resourceService = resourceService;
6367
this.azureMediaService = azureMediaService;
@@ -167,7 +171,8 @@ public async Task<IActionResult> CreateVersion(int resourceId)
167171
[Route("my-contributions/{selectedTab}/{catalogueId}/{nodeId}")]
168172
public async Task<IActionResult> MyContributions()
169173
{
170-
if ((this.User.IsInRole("ReadOnly") || this.User.IsInRole("BasicUser")) && !await this.resourceService.UserHasPublishedResourcesAsync())
174+
bool catalogueContributionPermission = await this.userGroupService.UserHasCatalogueContributionPermission();
175+
if ((this.User.IsInRole("ReadOnly") || this.User.IsInRole("BasicUser")) || (!catalogueContributionPermission && (!await this.resourceService.UserHasPublishedResourcesAsync())))
171176
{
172177
return this.RedirectToAction("AccessDenied", "Home");
173178
}

LearningHub.Nhs.WebUI/Controllers/HomeController.cs

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ namespace LearningHub.Nhs.WebUI.Controllers
1111
using LearningHub.Nhs.Models.Content;
1212
using LearningHub.Nhs.Models.Enums.Content;
1313
using LearningHub.Nhs.Models.Extensions;
14+
using LearningHub.Nhs.Models.Moodle.API;
1415
using LearningHub.Nhs.WebUI.Configuration;
1516
using LearningHub.Nhs.WebUI.Filters;
1617
using LearningHub.Nhs.WebUI.Helpers;
@@ -202,39 +203,31 @@ public IActionResult HomepageWithAuthentication()
202203
/// <summary>
203204
/// Index.
204205
/// </summary>
206+
/// <param name="dashboardTrayLearningResourceType">The resource type.</param>
205207
/// <param name="myLearningDashboard">The my learning dashboard type.</param>
206208
/// <param name="resourceDashboard">The resource dashboard type.</param>
207209
/// <param name="catalogueDashboard">The catalogue dashboard type.</param>
208210
/// <returns>Home page.</returns>
209-
public async Task<IActionResult> Index(string myLearningDashboard = "my-in-progress", string resourceDashboard = "popular-resources", string catalogueDashboard = "popular-catalogues")
211+
public async Task<IActionResult> Index(string dashboardTrayLearningResourceType = "all", string myLearningDashboard = "my-in-progress", string resourceDashboard = "my-recent-completed", string catalogueDashboard = "popular-catalogues")
210212
{
211213
if (this.User?.Identity.IsAuthenticated == true)
212214
{
213215
this.Logger.LogInformation("User is authenticated: User is {fullname} and userId is: {lhuserid}", this.User.Identity.GetCurrentName(), this.User.Identity.GetCurrentUserId());
214216
if (this.User.IsInRole("Administrator") || this.User.IsInRole("BlueUser") || this.User.IsInRole("ReadOnly") || this.User.IsInRole("BasicUser"))
215217
{
216-
var learningTask = this.dashboardService.GetMyAccessLearningsAsync(myLearningDashboard, 1);
218+
var learningTask = this.dashboardService.GetMyCoursesAndElearning(dashboardTrayLearningResourceType, myLearningDashboard, 1);
217219
var resourcesTask = this.dashboardService.GetResourcesAsync(resourceDashboard, 1);
218220
var cataloguesTask = this.dashboardService.GetCataloguesAsync(catalogueDashboard, 1);
219221
var userGroupsTask = this.userGroupService.UserHasCatalogueContributionPermission();
220222

221-
var enrolledCoursesTask = Task.FromResult(new List<MoodleCourseResponseViewModel>());
222-
var enableMoodle = Task.Run(() => this.featureManager.IsEnabledAsync(FeatureFlags.EnableMoodle)).Result;
223-
this.ViewBag.EnableMoodle = enableMoodle;
224-
this.ViewBag.ValidMoodleUser = this.CurrentMoodleUserId > 0;
225-
if (enableMoodle && myLearningDashboard == "my-enrolled-courses")
226-
{
227-
enrolledCoursesTask = this.dashboardService.GetEnrolledCoursesFromMoodleAsync(this.CurrentMoodleUserId, 1);
228-
}
229-
230223
await Task.WhenAll(learningTask, resourcesTask, cataloguesTask, userGroupsTask);
231224

232225
var model = new DashboardViewModel()
233226
{
234227
MyLearnings = await learningTask,
235228
Resources = await resourcesTask,
236229
Catalogues = await cataloguesTask,
237-
EnrolledCourses = await enrolledCoursesTask,
230+
DashboardTrayLearningResourceType = dashboardTrayLearningResourceType,
238231
};
239232
var userHasContributePermission = await userGroupsTask;
240233
this.ViewBag.userHasContributePermission = userHasContributePermission;
@@ -261,15 +254,16 @@ public async Task<IActionResult> Index(string myLearningDashboard = "my-in-progr
261254
/// <summary>
262255
/// Load the specified dashobard page.
263256
/// </summary>
257+
/// <param name="dashboardTrayLearningResourceType">dashboardTrayLearningResourceType.</param>
264258
/// <param name="dashBoardTray">dashBoardTray.</param>
265259
/// <param name="myLearningDashBoard">myLearningDashBoard.</param>
266260
/// <param name="resourceDashBoard">resourceDashBoard.</param>
267261
/// <param name="catalogueDashBoard">catalogueDashBoard.</param>
268262
/// <param name="pageNumber">pageNumber.</param>
269263
/// <returns>Dashboard page.</returns>
270264
[Authorize]
271-
[Route("/Home/loadpage/{dashBoardTray}/{myLearningDashBoard}/{resourceDashBoard}/{catalogueDashBoard}/{pageNumber:int}")]
272-
public async Task<IActionResult> LoadPage(string dashBoardTray = "my-learning", string myLearningDashBoard = "in-progress", string resourceDashBoard = "popular-resources", string catalogueDashBoard = "recent-catalogues", int pageNumber = 1)
265+
[Route("/Home/loadpage/{dashboardTrayLearningResourceType}/{dashBoardTray}/{myLearningDashBoard}/{resourceDashBoard}/{catalogueDashBoard}/{pageNumber:int}")]
266+
public async Task<IActionResult> LoadPage(string dashboardTrayLearningResourceType = "all", string dashBoardTray = "my-learning", string myLearningDashBoard = "in-progress", string resourceDashBoard = "popular-resources", string catalogueDashBoard = "recent-catalogues", int pageNumber = 1)
273267
{
274268
if (this.User.IsInRole("Administrator") || this.User.IsInRole("BlueUser") || this.User.IsInRole("ReadOnly") || this.User.IsInRole("BasicUser"))
275269
{
@@ -278,21 +272,18 @@ public async Task<IActionResult> LoadPage(string dashBoardTray = "my-learning",
278272
MyLearnings = new Nhs.Models.Dashboard.DashboardMyLearningResponseViewModel { Type = myLearningDashBoard },
279273
Resources = new Nhs.Models.Dashboard.DashboardResourceResponseViewModel { Type = resourceDashBoard },
280274
Catalogues = new Nhs.Models.Dashboard.DashboardCatalogueResponseViewModel { Type = catalogueDashBoard },
275+
DashboardTrayLearningResourceType = dashboardTrayLearningResourceType,
281276
};
282277

283-
var enableMoodle = Task.Run(() => this.featureManager.IsEnabledAsync(FeatureFlags.EnableMoodle)).Result;
284-
this.ViewBag.EnableMoodle = enableMoodle;
285-
this.ViewBag.ValidMoodleUser = this.CurrentMoodleUserId > 0;
286-
287278
bool isAjax = this.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest";
288279

289280
if (isAjax)
290281
{
291282
switch (dashBoardTray)
292283
{
293284
case "my-learning":
294-
model.MyLearnings = await this.dashboardService.GetMyAccessLearningsAsync(myLearningDashBoard, pageNumber);
295-
return this.PartialView("_MyAccessedLearningTray", model);
285+
model.MyLearnings = await this.dashboardService.GetMyCoursesAndElearning(dashboardTrayLearningResourceType, myLearningDashBoard, pageNumber);
286+
return this.PartialView("_MyCoursesAndElearning", model);
296287
case "resources":
297288
model.Resources = await this.dashboardService.GetResourcesAsync(resourceDashBoard, pageNumber);
298289
return this.PartialView("_ResourceTray", model);
@@ -303,13 +294,14 @@ public async Task<IActionResult> LoadPage(string dashBoardTray = "my-learning",
303294
}
304295
else
305296
{
306-
var learningTask = this.dashboardService.GetMyAccessLearningsAsync(myLearningDashBoard, dashBoardTray == "my-learning" ? pageNumber : 1);
297+
var learningTask = this.dashboardService.GetMyCoursesAndElearning(dashboardTrayLearningResourceType, myLearningDashBoard, dashBoardTray == "my-learning" ? pageNumber : 1);
307298
var resourcesTask = this.dashboardService.GetResourcesAsync(resourceDashBoard, dashBoardTray == "resources" ? pageNumber : 1);
308299
var cataloguesTask = this.dashboardService.GetCataloguesAsync(catalogueDashBoard, dashBoardTray == "catalogues" ? pageNumber : 1);
309300
await Task.WhenAll(learningTask, resourcesTask, cataloguesTask);
310301
model.MyLearnings = await learningTask;
311302
model.Resources = await resourcesTask;
312303
model.Catalogues = await cataloguesTask;
304+
model.DashboardTrayLearningResourceType = dashboardTrayLearningResourceType;
313305
return this.View("Dashboard", model);
314306
}
315307
}
@@ -449,5 +441,28 @@ private async Task<LandingPageViewModel> GetLandingPageContent(bool preview = fa
449441
return new LandingPageViewModel { PageSectionDetailViewModels = new List<PageSectionDetailViewModel>(), PageViewModel = new PageViewModel { PageSections = new List<PageSectionViewModel> { } } };
450442
}
451443
}
444+
445+
/// <summary>
446+
/// Asynchronously retrieves the state of the Moodle feature and the current Moodle user ID.
447+
/// </summary>
448+
/// <remarks>The method checks if the Moodle feature is enabled and retrieves the current Moodle
449+
/// user ID. If the user ID is not already set, it attempts to obtain it asynchronously from the dashboard
450+
/// service.</remarks>
451+
/// <returns>A tuple containing a boolean indicating whether the Moodle feature is enabled and an integer representing
452+
/// the current Moodle user ID.</returns>
453+
private async Task<(bool enableMoodle, int currentMoodleUserId)> GetMoodleFeatureStateAsync()
454+
{
455+
var enableMoodle = Task.Run(() => this.featureManager.IsEnabledAsync(FeatureFlags.EnableMoodle)).Result;
456+
this.ViewBag.EnableMoodle = enableMoodle;
457+
int currentMoodleUserId = this.CurrentMoodleUserId;
458+
459+
if (currentMoodleUserId == 0)
460+
{
461+
currentMoodleUserId = await this.dashboardService.GetMoodleUserIdAsync(this.CurrentUserId);
462+
}
463+
464+
this.ViewBag.ValidMoodleUser = currentMoodleUserId > 0;
465+
return (enableMoodle, currentMoodleUserId);
466+
}
452467
}
453468
}

0 commit comments

Comments
 (0)