From c1050c67034109dec00bae0e236076741b2fa5f5 Mon Sep 17 00:00:00 2001 From: Swapnamol Abraham Date: Tue, 18 Jun 2024 16:27:42 +0100 Subject: [PATCH 1/9] TD-4212, TD-4231, TD-4257 - Error log issues --- .../Controllers/CatalogueController.cs | 2 - .../Controllers/ResourceController.cs | 4 +- .../Services/ResourceService.cs | 25 +++--- .../Controllers/HierarchyController.cs | 4 +- .../Controllers/UserGroupController.cs | 12 +-- .../GetNodeContentsForCatalogueBrowse.sql | 11 ++- .../Hub/RoleUserGroupGetByUserGroupId.sql | 2 +- .../Hub/RoleUserGroupGetByUserId.sql | 4 +- .../Resources/GetDashboardResources.sql | 50 +++++------ .../Views/RoleUserGroupView.sql | 2 +- .../Hierarchy/INodeRepository.cs | 2 +- .../IRoleUserGroupRepository.cs | 4 +- .../Hierarchy/NodeRepository.cs | 7 +- .../LearningHubDbContext.cs | 2 + .../ResourceVersionRatingRepository.cs | 12 +-- .../RoleUserGroupRepository.cs | 8 +- .../IHierarchyService.cs | 2 +- .../IUserGroupService.cs | 4 +- .../CatalogueService.cs | 35 ++++---- .../HierarchyService.cs | 4 +- .../LearningHub.Nhs.Services.csproj | 2 +- .../MigrationService.cs | 2 +- .../LearningHub.Nhs.Services/RatingService.cs | 22 ++++- .../ResourceService.cs | 82 ++++++++++--------- .../UserGroupService.cs | 8 +- 25 files changed, 175 insertions(+), 137 deletions(-) diff --git a/LearningHub.Nhs.WebUI/Controllers/CatalogueController.cs b/LearningHub.Nhs.WebUI/Controllers/CatalogueController.cs index 67b4a5cb9..fb4d3def3 100644 --- a/LearningHub.Nhs.WebUI/Controllers/CatalogueController.cs +++ b/LearningHub.Nhs.WebUI/Controllers/CatalogueController.cs @@ -190,8 +190,6 @@ public async Task IndexAsync(string reference, string tab, int? n CatalogueAccessRequestViewModel catalogueAccessRequest = null; if (this.ViewBag.UserAuthenticated) { - var cacheKey = $"{this.CurrentUserId}:AllRolesWithPermissions"; - await this.cacheService.RemoveAsync(cacheKey); userGroups = await this.userGroupService.GetRoleUserGroupDetailAsync(); catalogueAccessRequest = await this.catalogueService.GetLatestCatalogueAccessRequestAsync(catalogue.NodeId); } diff --git a/LearningHub.Nhs.WebUI/Controllers/ResourceController.cs b/LearningHub.Nhs.WebUI/Controllers/ResourceController.cs index 7a1245acc..1a73a4130 100644 --- a/LearningHub.Nhs.WebUI/Controllers/ResourceController.cs +++ b/LearningHub.Nhs.WebUI/Controllers/ResourceController.cs @@ -123,7 +123,7 @@ public async Task Index(int resourceReferenceId, bool? acceptSens var resource = await this.resourceService.GetItemByIdAsync(resourceReferenceId); - if (resource.Id == 0 || (resource.Catalogue != null && resource.Catalogue.Hidden)) + if ((resource == null && resource.Id == 0) || (resource.Catalogue != null && resource.Catalogue.Hidden)) { this.ViewBag.SupportFormUrl = this.Settings.SupportUrls.SupportForm; return this.View("Unavailable"); @@ -147,7 +147,7 @@ public async Task Index(int resourceReferenceId, bool? acceptSens var hasCatalogueAccess = false; if (resource.Catalogue.RestrictedAccess && this.User.Identity.IsAuthenticated) { - var userGroups = await this.userGroupService.GetRoleUserGroupDetailForUserAsync(this.CurrentUserId); + var userGroups = await this.userGroupService.GetRoleUserGroupDetailAsync(); hasCatalogueAccess = userGroups.Any(x => x.CatalogueNodeId == resource.Catalogue.NodeId && (x.RoleEnum == RoleEnum.LocalAdmin || x.RoleEnum == RoleEnum.Editor || x.RoleEnum == RoleEnum.Reader)) || this.User.IsInRole("Administrator"); diff --git a/LearningHub.Nhs.WebUI/Services/ResourceService.cs b/LearningHub.Nhs.WebUI/Services/ResourceService.cs index ade01a5f8..dfc5d4d17 100644 --- a/LearningHub.Nhs.WebUI/Services/ResourceService.cs +++ b/LearningHub.Nhs.WebUI/Services/ResourceService.cs @@ -418,18 +418,21 @@ public async Task GetItemByIdAsync(int id) resourceItem = JsonConvert.DeserializeObject(result); - resourceItem.LicenseUrl = this.settings.ResourceLicenseUrl; - - // if resource type is video, add azure media content protection authentication token - if (resourceItem.ResourceTypeEnum == ResourceTypeEnum.Video && resourceItem.VideoDetails != null && resourceItem.VideoDetails.ResourceAzureMediaAsset != null && !string.IsNullOrEmpty(resourceItem.VideoDetails.ResourceAzureMediaAsset.FilePath)) - { - resourceItem.VideoDetails.ResourceAzureMediaAsset.AuthenticationToken = await this.azureMediaService.GetContentAuthenticationTokenAsync(resourceItem.VideoDetails.ResourceAzureMediaAsset.FilePath); - } - - // if resource type is audio, add azure media content protection authentication token - if (resourceItem.ResourceTypeEnum == ResourceTypeEnum.Audio && resourceItem.AudioDetails != null && resourceItem.AudioDetails.ResourceAzureMediaAsset != null && !string.IsNullOrEmpty(resourceItem.AudioDetails.ResourceAzureMediaAsset.FilePath)) + if (resourceItem != null) { - resourceItem.AudioDetails.ResourceAzureMediaAsset.AuthenticationToken = await this.azureMediaService.GetContentAuthenticationTokenAsync(resourceItem.AudioDetails.ResourceAzureMediaAsset.FilePath); + resourceItem.LicenseUrl = this.settings.ResourceLicenseUrl; + + // if resource type is video, add azure media content protection authentication token + if (resourceItem.ResourceTypeEnum == ResourceTypeEnum.Video && resourceItem.VideoDetails != null && resourceItem.VideoDetails.ResourceAzureMediaAsset != null && !string.IsNullOrEmpty(resourceItem.VideoDetails.ResourceAzureMediaAsset.FilePath)) + { + resourceItem.VideoDetails.ResourceAzureMediaAsset.AuthenticationToken = await this.azureMediaService.GetContentAuthenticationTokenAsync(resourceItem.VideoDetails.ResourceAzureMediaAsset.FilePath); + } + + // if resource type is audio, add azure media content protection authentication token + if (resourceItem.ResourceTypeEnum == ResourceTypeEnum.Audio && resourceItem.AudioDetails != null && resourceItem.AudioDetails.ResourceAzureMediaAsset != null && !string.IsNullOrEmpty(resourceItem.AudioDetails.ResourceAzureMediaAsset.FilePath)) + { + resourceItem.AudioDetails.ResourceAzureMediaAsset.AuthenticationToken = await this.azureMediaService.GetContentAuthenticationTokenAsync(resourceItem.AudioDetails.ResourceAzureMediaAsset.FilePath); + } } } else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized diff --git a/WebAPI/LearningHub.Nhs.API/Controllers/HierarchyController.cs b/WebAPI/LearningHub.Nhs.API/Controllers/HierarchyController.cs index fc7293109..ff6d5d560 100644 --- a/WebAPI/LearningHub.Nhs.API/Controllers/HierarchyController.cs +++ b/WebAPI/LearningHub.Nhs.API/Controllers/HierarchyController.cs @@ -41,9 +41,9 @@ public HierarchyController(IUserService userService, IHierarchyService hierarchy /// The node details. [HttpGet] [Route("GetNodeDetails/{nodeId}")] - public NodeViewModel GetNodeDetails(int nodeId) + public async Task GetNodeDetails(int nodeId) { - var retVal = this.hierarchyService.GetNodeDetails(nodeId); + var retVal = await this.hierarchyService.GetNodeDetails(nodeId); return retVal; } diff --git a/WebAPI/LearningHub.Nhs.API/Controllers/UserGroupController.cs b/WebAPI/LearningHub.Nhs.API/Controllers/UserGroupController.cs index 51da87d5f..158692a23 100644 --- a/WebAPI/LearningHub.Nhs.API/Controllers/UserGroupController.cs +++ b/WebAPI/LearningHub.Nhs.API/Controllers/UserGroupController.cs @@ -61,9 +61,9 @@ public async Task GetUserGroupAdminDetailById(int id) /// The . [HttpGet] [Route("GetUserGroupAdminRoleDetailById/{id}")] - public IActionResult GetUserGroupAdminRoleDetailById(int id) + public async Task GetUserGroupAdminRoleDetailById(int id) { - var retVal = this.userGroupService.GetUserGroupRoleDetailByUserGroupId(id); + var retVal = await this.userGroupService.GetUserGroupRoleDetailByUserGroupId(id); return this.Ok(retVal); } @@ -75,9 +75,9 @@ public IActionResult GetUserGroupAdminRoleDetailById(int id) /// The . [HttpGet] [Route("GetUserGroupRoleDetailByUserId/{userId}")] - public IActionResult GetRoleUserGroupDetailByUserId(int userId) + public async Task GetRoleUserGroupDetailByUserId(int userId) { - var retVal = this.userGroupService.GetRoleUserGroupDetailByUserId(userId); + var retVal = await this.userGroupService.GetRoleUserGroupDetailByUserId(userId); return this.Ok(retVal); } @@ -88,9 +88,9 @@ public IActionResult GetRoleUserGroupDetailByUserId(int userId) /// The . [HttpGet] [Route("GetUserGroupRoleDetail")] - public IActionResult GetRoleUserGroupDetail() + public async Task GetRoleUserGroupDetail() { - var retVal = this.userGroupService.GetRoleUserGroupDetailByUserId(this.CurrentUserId); + var retVal = await this.userGroupService.GetRoleUserGroupDetailByUserId(this.CurrentUserId); return this.Ok(retVal); } diff --git a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Hierarchy/GetNodeContentsForCatalogueBrowse.sql b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Hierarchy/GetNodeContentsForCatalogueBrowse.sql index 6c2c4fb8d..d3b4ff170 100644 --- a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Hierarchy/GetNodeContentsForCatalogueBrowse.sql +++ b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Hierarchy/GetNodeContentsForCatalogueBrowse.sql @@ -13,6 +13,7 @@ -- 11-05-2023 RS Removed Description and AuthoredBy as no longer required for screen. -- 15-05-2023 RS Added AuthoredBy back in following design decision change. -- 23-06-2023 RS Removed AverageRating and RatingCount as not required from this proc. That data comes separately from RatingService. +-- 05-06-2023 SA Modified the sp to fix the sql timeout issues. ------------------------------------------------------------------------------- CREATE PROCEDURE [hierarchy].[GetNodeContentsForCatalogueBrowse] ( @@ -23,6 +24,14 @@ AS BEGIN + IF @NodeId IS NULL + BEGIN + RAISERROR('NodeId cannot be null', 16, 1) + RETURN + END + + ;WITH CTENode AS(SELECT DISTINCT NodeId FROM hierarchy.NodeResourceLookup WHERE Deleted = 0) + SELECT ROW_NUMBER() OVER(ORDER BY DisplayOrder) AS Id, [Name], @@ -64,7 +73,7 @@ BEGIN INNER JOIN hierarchy.FolderNodeVersion fnv ON fnv.NodeVersionId = nv.Id INNER JOIN -- Exclude folders with no published resources. - (SELECT DISTINCT NodeId FROM hierarchy.NodeResourceLookup WHERE Deleted = 0) nrl ON cn.Id = nrl.NodeId + CTENode nrl ON cn.Id = nrl.NodeId WHERE nl.ParentNodeId = @NodeId AND nl.Deleted = 0 diff --git a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Hub/RoleUserGroupGetByUserGroupId.sql b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Hub/RoleUserGroupGetByUserGroupId.sql index 6972d468a..bcfc1aa4e 100644 --- a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Hub/RoleUserGroupGetByUserGroupId.sql +++ b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Hub/RoleUserGroupGetByUserGroupId.sql @@ -6,6 +6,7 @@ -- Modification History -- -- 21-01-2021 Killian Davies Initial Revision +-- 05-06-2023 SA Modified the sp to fix the sql timeout issues. ------------------------------------------------------------------------------- CREATE PROCEDURE [hub].[RoleUserGroupGetByUserGroupId] ( @@ -17,7 +18,6 @@ AS BEGIN SELECT - CAST([Sequence] AS int) AS [Key], RoleUserGroupId, UserGroupId, UserGroupName, diff --git a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Hub/RoleUserGroupGetByUserId.sql b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Hub/RoleUserGroupGetByUserId.sql index d906976cf..ff05f806c 100644 --- a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Hub/RoleUserGroupGetByUserId.sql +++ b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Hub/RoleUserGroupGetByUserId.sql @@ -6,6 +6,7 @@ -- Modification History -- -- 21-01-2021 Killian Davies Initial Revision +-- 05-06-2023 SA Modified the sp to fix the sql timeout issues. ------------------------------------------------------------------------------- CREATE PROCEDURE [hub].[RoleUserGroupGetByUserId] ( @@ -16,8 +17,7 @@ AS BEGIN - SELECT - CAST([Sequence] AS int) AS [Key], + SELECT RoleUserGroupId, rug.UserGroupId, UserGroupName, diff --git a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetDashboardResources.sql b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetDashboardResources.sql index 1618e5af4..b889ab6a7 100644 --- a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetDashboardResources.sql +++ b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetDashboardResources.sql @@ -19,6 +19,7 @@ -- 27 Feb 2024 SS Fixed missing In progress resources in the My Accessed Learning tray issue -- 2 May 2024 SA Fixed the issue on showing statuses on 'My accessed Learning' for resource type file -- 13 May 2024 SA TD-4115 +-- 31 May 2024 SA Query optimization to resolve the timeout issues ------------------------------------------------------------------------------- CREATE PROCEDURE [resources].[GetDashboardResources] @@ -83,8 +84,8 @@ BEGIN ,CAST(CASE WHEN cnv.RestrictedAccess = 1 AND auth.CatalogueNodeId IS NULL THEN 0 ELSE 1 END AS bit) AS HasAccess ,ub.Id AS BookMarkId ,CAST(ISNULL(ub.[Deleted], 1) ^ 1 AS BIT) AS IsBookmarked - ,rs.AverageRating - ,rs.RatingCount + ,rvrs.AverageRating + ,rvrs.RatingCount FROM @Resources tr JOIN resources.Resource r ON r.id = tr.ResourceId JOIN resources.resourceversion rv ON rv.ResourceId = r.Id AND rv.id = r.CurrentResourceVersionId AND rv.Deleted = 0 @@ -101,7 +102,6 @@ BEGIN LEFT JOIN ( SELECT DISTINCT CatalogueNodeId FROM [hub].[RoleUserGroupView] rug JOIN hub.UserUserGroup uug ON rug.UserGroupId = uug.UserGroupId WHERE rug.ScopeTypeId = 1 and rug.RoleId in (1,2,3) and uug.Deleted = 0 and uug.UserId = @userId) auth ON n.Id = auth.CatalogueNodeId - LEFT JOIN resources.ResourceVersionRatingSummary rs ON rs.ResourceVersionId = rv.Id WHERE rv.VersionStatusId = 2 ORDER BY tr.ResourceActivityCount DESC, rv.Title OFFSET @OffsetRows ROWS @@ -136,8 +136,8 @@ BEGIN ,CAST(CASE WHEN cnv.RestrictedAccess = 1 AND auth.CatalogueNodeId IS NULL THEN 0 ELSE 1 END AS bit) AS HasAccess ,ub.Id AS BookMarkId ,CAST(ISNULL(ub.[Deleted], 1) ^ 1 AS BIT) AS IsBookmarked - ,rs.AverageRating - ,rs.RatingCount + ,rvrs.AverageRating + ,rvrs.RatingCount INTO #ratedresources FROM Resources.Resource r JOIN resources.resourceversion rv ON rv.ResourceId = r.Id AND rv.id = r.CurrentResourceVersionId AND rv.Deleted = 0 @@ -154,7 +154,6 @@ BEGIN LEFT JOIN ( SELECT DISTINCT CatalogueNodeId FROM [hub].[RoleUserGroupView] rug JOIN hub.UserUserGroup uug ON rug.UserGroupId = uug.UserGroupId WHERE rug.ScopeTypeId = 1 and rug.RoleId in (1,2,3) and uug.Deleted = 0 and uug.UserId = @userId) auth ON n.Id = auth.CatalogueNodeId - INNER JOIN resources.ResourceVersionRatingSummary rs ON rs.ResourceVersionId = rv.Id WHERE rv.VersionStatusId = 2 ORDER BY rvrs.AverageRating DESC, rvrs.RatingCount DESC, rv.Title @@ -192,8 +191,8 @@ BEGIN ,CAST(CASE WHEN cnv.RestrictedAccess = 1 AND auth.CatalogueNodeId IS NULL THEN 0 ELSE 1 END AS bit) AS HasAccess ,ub.Id AS BookMarkId ,CAST(ISNULL(ub.[Deleted], 1) ^ 1 AS BIT) AS IsBookmarked - ,rs.AverageRating - ,rs.RatingCount + ,rvrs.AverageRating + ,rvrs.RatingCount INTO #recentresources FROM Resources.Resource r JOIN resources.resourceversion rv ON rv.ResourceId = r.Id AND rv.id = r.CurrentResourceVersionId AND rv.Deleted = 0 @@ -211,7 +210,6 @@ BEGIN LEFT JOIN ( SELECT DISTINCT CatalogueNodeId FROM [hub].[RoleUserGroupView] rug JOIN hub.UserUserGroup uug ON rug.UserGroupId = uug.UserGroupId WHERE rug.ScopeTypeId = 1 and rug.RoleId in (1,2,3) and uug.Deleted = 0 and uug.UserId = @userId) auth ON n.Id = auth.CatalogueNodeId - INNER JOIN resources.ResourceVersionRatingSummary rs ON rs.ResourceVersionId = rv.Id WHERE rv.VersionStatusId = 2 ORDER BY p.CreateDate DESC @@ -227,7 +225,7 @@ BEGIN INSERT INTO @MyActivity SELECT TOP (@MaxRows) ra.ResourceId, MAX(ra.Id) ResourceActivityId FROM - (SELECT a.* FROM activity.ResourceActivity a INNER JOIN (SELECT ResourceId, MAX(Id) as id FROM activity.ResourceActivity GROUP BY ResourceId) AS b ON a.ResourceId = b.ResourceId AND a.id = b.id order by a.Id desc OFFSET 0 ROWS) ra + (SELECT a.Id,a.ResourceId,a.ResourceVersionId,a.LaunchResourceActivityId,a.UserId,a.ActivityStatusId,a.ActivityStart FROM activity.ResourceActivity a INNER JOIN (SELECT ResourceId, MAX(Id) as id FROM activity.ResourceActivity GROUP BY ResourceId) AS b ON a.ResourceId = b.ResourceId AND a.id = b.id order by a.Id desc OFFSET 0 ROWS) ra JOIN [resources].[Resource] r ON ra.ResourceId = r.Id JOIN [resources].[ResourceVersion] rv ON rv.Id = ra.ResourceVersionId LEFT JOIN [resources].[AssessmentResourceVersion] arv ON arv.ResourceVersionId = ra.ResourceVersionId @@ -239,9 +237,8 @@ BEGIN (r.ResourceTypeId IN (1, 5, 8, 9,10, 12) AND ra.ActivityStatusId <> 3) OR (r.ResourceTypeId IN (2, 7) AND (mar.Id IS NULL OR (mar.Id IS NOT NULL AND mar.PercentComplete < 100) OR ra.ActivityStart < '2020-09-07 00:00:00 +00:00')) OR (r.ResourceTypeId = 6 AND (sa.CmiCoreLesson_status NOT IN (3, 5) AND (ra.ActivityStatusId NOT IN(3, 5)))) - OR (r.ResourceTypeId IN (9) AND ra.ActivityStatusId NOT IN (3)) - OR ((r.ResourceTypeId = 11 AND arv.AssessmentType = 2) AND ((ara.Id IS NOT NULL AND ara.score < arv.PassMark) OR ra.ActivityStatusId IN (7))) - OR ((r.ResourceTypeId = 11 AND arv.AssessmentType = 1) AND ra.ActivityStatusId IN (7)) + OR ((r.ResourceTypeId = 11 AND arv.AssessmentType = 2) AND ((ara.Id IS NOT NULL AND ara.score < arv.PassMark) OR ra.ActivityStatusId = 7)) + OR ((r.ResourceTypeId = 11 AND arv.AssessmentType = 1) AND ra.ActivityStatusId = 7) ) GROUP BY ra.ResourceId ORDER BY ResourceActivityId DESC @@ -271,8 +268,8 @@ BEGIN ,CAST(CASE WHEN cnv.RestrictedAccess = 1 AND auth.CatalogueNodeId IS NULL THEN 0 ELSE 1 END AS bit) AS HasAccess ,ub.Id AS BookMarkId ,CAST(ISNULL(ub.[Deleted], 1) ^ 1 AS BIT) AS IsBookmarked - ,rs.AverageRating - ,rs.RatingCount + ,rvrs.AverageRating + ,rvrs.RatingCount FROM @MyActivity ma JOIN activity.ResourceActivity ra ON ra.id = ma.ResourceActivityId JOIN resources.resourceversion rv ON rv.id = ra.ResourceVersionId AND rv.Deleted = 0 @@ -291,7 +288,6 @@ BEGIN LEFT JOIN ( SELECT DISTINCT CatalogueNodeId FROM [hub].[RoleUserGroupView] rug JOIN hub.UserUserGroup uug ON rug.UserGroupId = uug.UserGroupId WHERE rug.ScopeTypeId = 1 and rug.RoleId in (1,2,3) and uug.Deleted = 0 and uug.UserId = @userId) auth ON n.Id = auth.CatalogueNodeId - LEFT JOIN resources.ResourceVersionRatingSummary rs ON rs.ResourceVersionId = rv.Id ORDER BY ma.ResourceActivityId DESC OFFSET @OffsetRows ROWS FETCH NEXT @FetchRows ROWS ONLY @@ -303,7 +299,7 @@ BEGIN INSERT INTO @MyActivity SELECT TOP (@MaxRows) ra.ResourceId, MAX(ra.Id) ResourceActivityId FROM - (SELECT a.* FROM activity.ResourceActivity a INNER JOIN (SELECT ResourceId, MAX(Id) as id FROM activity.ResourceActivity GROUP BY ResourceId ) AS b ON a.ResourceId = b.ResourceId AND a.id = b.id order by a.Id desc OFFSET 0 ROWS) ra + (SELECT a.Id,a.ResourceId,a.ResourceVersionId,a.LaunchResourceActivityId,a.UserId,a.ActivityStatusId,a.ActivityStart FROM activity.ResourceActivity a INNER JOIN (SELECT ResourceId, MAX(Id) as id FROM activity.ResourceActivity GROUP BY ResourceId ) AS b ON a.ResourceId = b.ResourceId AND a.id = b.id order by a.Id desc OFFSET 0 ROWS) ra JOIN [resources].[Resource] r ON ra.ResourceId = r.Id JOIN [resources].[ResourceVersion] rv ON rv.Id = ra.ResourceVersionId LEFT JOIN [resources].[AssessmentResourceVersion] arv ON arv.ResourceVersionId = ra.ResourceVersionId @@ -312,10 +308,10 @@ BEGIN LEFT JOIN [activity].[ScormActivity] sa ON sa.ResourceActivityId = ra.Id WHERE ra.UserId = @UserId AND ( - (r.ResourceTypeId IN (2, 7) AND ra.ActivityStatusId IN (3) AND ((mar.Id IS NOT NULL AND mar.PercentComplete = 100) OR ra.ActivityStart < '2020-09-07 00:00:00 +00:00')) + (r.ResourceTypeId IN (2, 7) AND ra.ActivityStatusId = 3 AND ((mar.Id IS NOT NULL AND mar.PercentComplete = 100) OR ra.ActivityStart < '2020-09-07 00:00:00 +00:00')) OR (r.ResourceTypeId = 6 AND (sa.CmiCoreLesson_status IN(3,5) OR (ra.ActivityStatusId IN(3, 5)))) OR (r.ResourceTypeId = 11 AND ara.Score >= arv.PassMark OR ra.ActivityStatusId IN( 3, 5)) - OR (r.ResourceTypeId IN (1, 5, 8, 9, 10, 12) AND ra.ActivityStatusId IN (3))) + OR (r.ResourceTypeId IN (1, 5, 8, 9, 10, 12) AND ra.ActivityStatusId = 3)) GROUP BY ra.ResourceId ORDER BY ResourceActivityId DESC @@ -344,8 +340,8 @@ BEGIN ,CAST(CASE WHEN cnv.RestrictedAccess = 1 AND auth.CatalogueNodeId IS NULL THEN 0 ELSE 1 END AS bit) AS HasAccess ,ub.Id AS BookMarkId ,CAST(ISNULL(ub.[Deleted], 1) ^ 1 AS BIT) AS IsBookmarked - ,rs.AverageRating - ,rs.RatingCount + ,rvrs.AverageRating + ,rvrs.RatingCount FROM @MyActivity ma JOIN activity.ResourceActivity ra ON ra.id = ma.ResourceActivityId JOIN resources.resourceversion rv ON rv.id = ra.ResourceVersionId AND rv.Deleted = 0 @@ -364,7 +360,6 @@ BEGIN LEFT JOIN ( SELECT DISTINCT CatalogueNodeId FROM [hub].[RoleUserGroupView] rug JOIN hub.UserUserGroup uug ON rug.UserGroupId = uug.UserGroupId WHERE rug.ScopeTypeId = 1 and rug.RoleId in (1,2,3) and uug.Deleted = 0 and uug.UserId = @userId) auth ON n.Id = auth.CatalogueNodeId - LEFT JOIN resources.ResourceVersionRatingSummary rs ON rs.ResourceVersionId = rv.Id ORDER BY ma.ResourceActivityId DESC, rv.Title OFFSET @OffsetRows ROWS FETCH NEXT @FetchRows ROWS ONLY @@ -385,11 +380,11 @@ BEGIN LEFT JOIN [activity].[ScormActivity] sa ON sa.ResourceActivityId = ra.Id WHERE ra.UserId = @UserId AND rv.CertificateEnabled = 1 AND ( - (r.ResourceTypeId IN (2, 7) AND ra.ActivityStatusId IN (3) OR ra.ActivityStart < '2020-09-07 00:00:00 +00:00' OR mar.Id IS NOT NULL AND mar.PercentComplete = 100) + (r.ResourceTypeId IN (2, 7) AND ra.ActivityStatusId = 3 OR ra.ActivityStart < '2020-09-07 00:00:00 +00:00' OR mar.Id IS NOT NULL AND mar.PercentComplete = 100) OR (r.ResourceTypeId = 6 AND (sa.CmiCoreLesson_status IN(3,5) OR (ra.ActivityStatusId IN(3, 5)))) OR ((r.ResourceTypeId = 11 AND arv.AssessmentType = 2) AND (ara.Score >= arv.PassMark OR ra.ActivityStatusId IN(3, 5))) OR ((r.ResourceTypeId = 11 AND arv.AssessmentType =1) AND (ara.Score >= arv.PassMark AND ra.ActivityStatusId IN(3, 5))) - OR (r.ResourceTypeId IN (1, 5, 8, 9, 10, 12) AND ra.ActivityStatusId IN (3))) + OR (r.ResourceTypeId IN (1, 5, 8, 9, 10, 12) AND ra.ActivityStatusId = 3)) GROUP BY ra.ResourceId ORDER BY ResourceActivityId DESC @@ -418,8 +413,8 @@ BEGIN ,CAST(CASE WHEN cnv.RestrictedAccess = 1 AND auth.CatalogueNodeId IS NULL THEN 0 ELSE 1 END AS bit) AS HasAccess ,ub.Id AS BookMarkId ,CAST(ISNULL(ub.[Deleted], 1) ^ 1 AS BIT) AS IsBookmarked - ,rs.AverageRating - ,rs.RatingCount + ,rvrs.AverageRating + ,rvrs.RatingCount FROM @MyActivity ma JOIN activity.ResourceActivity ra ON ra.id = ma.ResourceActivityId JOIN resources.resourceversion rv ON rv.id = ra.ResourceVersionId AND rv.Deleted = 0 @@ -437,8 +432,7 @@ BEGIN WHERE rr.ResourceId = rv.ResourceId AND rr.Deleted = 0) LEFT JOIN ( SELECT DISTINCT CatalogueNodeId FROM [hub].[RoleUserGroupView] rug JOIN hub.UserUserGroup uug ON rug.UserGroupId = uug.UserGroupId - WHERE rug.ScopeTypeId = 1 and rug.RoleId in (1,2,3) and uug.Deleted = 0 and uug.UserId = @userId) auth ON n.Id = auth.CatalogueNodeId - LEFT JOIN resources.ResourceVersionRatingSummary rs ON rs.ResourceVersionId = rv.Id + WHERE rug.ScopeTypeId = 1 and rug.RoleId in (1,2,3) and uug.Deleted = 0 and uug.UserId = @userId) auth ON n.Id = auth.CatalogueNodeId ORDER BY ma.ResourceActivityId DESC, rv.Title OFFSET @OffsetRows ROWS FETCH NEXT @FetchRows ROWS ONLY diff --git a/WebAPI/LearningHub.Nhs.Database/Views/RoleUserGroupView.sql b/WebAPI/LearningHub.Nhs.Database/Views/RoleUserGroupView.sql index d56b1d8ee..f6dac03ec 100644 --- a/WebAPI/LearningHub.Nhs.Database/Views/RoleUserGroupView.sql +++ b/WebAPI/LearningHub.Nhs.Database/Views/RoleUserGroupView.sql @@ -7,13 +7,13 @@ -- Modification History -- -- 11-01-2021 Killian Davies Initial Revision +-- 05-06-2023 SA Modified the sp to fix the sql timeout issues. ------------------------------------------------------------------------------- CREATE VIEW [hub].[RoleUserGroupView] AS SELECT - ROW_NUMBER() OVER(ORDER BY rug.Id) AS [Sequence], rug.Id AS RoleUserGroupId, ug.Id AS UserGroupId, ug.[Name] AS UserGroupName, diff --git a/WebAPI/LearningHub.Nhs.Repository.Interface/Hierarchy/INodeRepository.cs b/WebAPI/LearningHub.Nhs.Repository.Interface/Hierarchy/INodeRepository.cs index a6a4ff91c..28b3a2d80 100644 --- a/WebAPI/LearningHub.Nhs.Repository.Interface/Hierarchy/INodeRepository.cs +++ b/WebAPI/LearningHub.Nhs.Repository.Interface/Hierarchy/INodeRepository.cs @@ -22,7 +22,7 @@ public interface INodeRepository : IGenericRepository /// /// The node id. /// The node details. - NodeViewModel GetNodeDetails(int nodeId); + Task GetNodeDetails(int nodeId); /// /// Gets the contents of a node for the catalogue landing page - i.e. published folders and published resources only. diff --git a/WebAPI/LearningHub.Nhs.Repository.Interface/IRoleUserGroupRepository.cs b/WebAPI/LearningHub.Nhs.Repository.Interface/IRoleUserGroupRepository.cs index 421f18dda..0a807c18d 100644 --- a/WebAPI/LearningHub.Nhs.Repository.Interface/IRoleUserGroupRepository.cs +++ b/WebAPI/LearningHub.Nhs.Repository.Interface/IRoleUserGroupRepository.cs @@ -47,13 +47,13 @@ public interface IRoleUserGroupRepository : IGenericRepository /// /// The userGroupId. /// A list of RoleUserGroupViewModel. - List GetRoleUserGroupViewModelsByUserGroupId(int userGroupId); + Task> GetRoleUserGroupViewModelsByUserGroupId(int userGroupId); /// /// Get list of RoleUserGroupViewModel for a supplied User Group. /// /// The userGroupId. /// A list of RoleUserGroupViewModel. - List GetRoleUserGroupViewModelsByUserId(int userId); + Task> GetRoleUserGroupViewModelsByUserId(int userId); } } diff --git a/WebAPI/LearningHub.Nhs.Repository/Hierarchy/NodeRepository.cs b/WebAPI/LearningHub.Nhs.Repository/Hierarchy/NodeRepository.cs index 2e3177eca..000feb742 100644 --- a/WebAPI/LearningHub.Nhs.Repository/Hierarchy/NodeRepository.cs +++ b/WebAPI/LearningHub.Nhs.Repository/Hierarchy/NodeRepository.cs @@ -41,12 +41,13 @@ public async Task GetByIdAsync(int id) /// /// The node id. /// The node details. - public NodeViewModel GetNodeDetails(int nodeId) + public async Task GetNodeDetails(int nodeId) { var param0 = new SqlParameter("@p0", SqlDbType.Int) { Value = nodeId }; - var retVal = this.DbContext.NodeViewModel.FromSqlRaw("hierarchy.GetNodeDetails @p0", param0).AsEnumerable().FirstOrDefault(); - return retVal; + var retVal = await this.DbContext.NodeViewModel.FromSqlRaw("hierarchy.GetNodeDetails @p0", param0).AsNoTracking().ToListAsync(); + NodeViewModel nodeViewModel = retVal.FirstOrDefault(); + return nodeViewModel; } /// diff --git a/WebAPI/LearningHub.Nhs.Repository/LearningHubDbContext.cs b/WebAPI/LearningHub.Nhs.Repository/LearningHubDbContext.cs index ef4775cd8..8d685dbd1 100644 --- a/WebAPI/LearningHub.Nhs.Repository/LearningHubDbContext.cs +++ b/WebAPI/LearningHub.Nhs.Repository/LearningHubDbContext.cs @@ -782,6 +782,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) { mapping.Map(modelBuilder); } + + modelBuilder.Entity().HasNoKey(); } } } diff --git a/WebAPI/LearningHub.Nhs.Repository/Resources/ResourceVersionRatingRepository.cs b/WebAPI/LearningHub.Nhs.Repository/Resources/ResourceVersionRatingRepository.cs index 0dc1ffbcc..388383615 100644 --- a/WebAPI/LearningHub.Nhs.Repository/Resources/ResourceVersionRatingRepository.cs +++ b/WebAPI/LearningHub.Nhs.Repository/Resources/ResourceVersionRatingRepository.cs @@ -31,7 +31,7 @@ public ResourceVersionRatingRepository(LearningHubDbContext dbContext, ITimezone /// The . public async Task GetUsersPreviousRatingForSameMajorVersionAsync(int resourceVersionId, int userId) { - var minorVersionIds = this.GetAllResourceVersionIdsForSameMajorVersion(resourceVersionId); + var minorVersionIds = await this.GetAllResourceVersionIdsForSameMajorVersion(resourceVersionId); return await this.DbContext.ResourceVersionRating.FirstOrDefaultAsync(x => minorVersionIds.Contains(x.ResourceVersionId) && x.UserId == userId && !x.Deleted); } @@ -43,7 +43,7 @@ public async Task GetUsersPreviousRatingForSameMajorVersi /// An array of integers, which are the count for each star value, starting at 1 star and ending with 5 stars. public async Task GetRatingCountsForResourceVersionAsync(int resourceVersionId) { - var minorVersionIds = this.GetAllResourceVersionIdsForSameMajorVersion(resourceVersionId); + var minorVersionIds = await this.GetAllResourceVersionIdsForSameMajorVersion(resourceVersionId); var allMajorVersionRatings = this.DbContext.ResourceVersionRating.Where(x => minorVersionIds.Contains(x.ResourceVersionId)); @@ -63,12 +63,12 @@ public async Task GetRatingCountsForResourceVersionAsync(int resourceVers /// /// The resource version id. /// A list of resoruce verison ids. - private List GetAllResourceVersionIdsForSameMajorVersion(int resourceVersionId) + private async Task> GetAllResourceVersionIdsForSameMajorVersion(int resourceVersionId) { - var majorVersionInfo = this.DbContext.ResourceVersion.Where(x => x.Id == resourceVersionId).Select(x => new { ResourceId = x.ResourceId, MajorVersion = x.MajorVersion }).FirstOrDefault(); + var majorVersionInfo = await this.DbContext.ResourceVersion.Where(x => x.Id == resourceVersionId).Select(x => new { ResourceId = x.ResourceId, MajorVersion = x.MajorVersion }).FirstOrDefaultAsync(); - var minorVersionIds = this.DbContext.ResourceVersion - .Where(x => x.ResourceId == majorVersionInfo.ResourceId && x.MajorVersion == majorVersionInfo.MajorVersion).Select(x => x.Id).ToList(); + var minorVersionIds = await this.DbContext.ResourceVersion + .Where(x => x.ResourceId == majorVersionInfo.ResourceId && x.MajorVersion == majorVersionInfo.MajorVersion).Select(x => x.Id).ToListAsync(); return minorVersionIds; } diff --git a/WebAPI/LearningHub.Nhs.Repository/RoleUserGroupRepository.cs b/WebAPI/LearningHub.Nhs.Repository/RoleUserGroupRepository.cs index 7579f5a57..906c335cc 100644 --- a/WebAPI/LearningHub.Nhs.Repository/RoleUserGroupRepository.cs +++ b/WebAPI/LearningHub.Nhs.Repository/RoleUserGroupRepository.cs @@ -96,11 +96,11 @@ public async Task> GetByRoleIdCatalogueIdWithUsers(int roleI /// /// The userGroupId. /// A list of RoleUserGroupViewModel. - public List GetRoleUserGroupViewModelsByUserGroupId(int userGroupId) + public async Task> GetRoleUserGroupViewModelsByUserGroupId(int userGroupId) { var param0 = new SqlParameter("@userGroupId", SqlDbType.Int) { Value = userGroupId }; - var vm = this.DbContext.RoleUserGroupViewModel.FromSqlRaw("hub.RoleUserGroupGetByUserGroupId @userGroupId", param0).ToList(); + var vm = await this.DbContext.RoleUserGroupViewModel.FromSqlRaw("hub.RoleUserGroupGetByUserGroupId @userGroupId", param0).AsNoTracking().ToListAsync(); return vm; } @@ -109,11 +109,11 @@ public List GetRoleUserGroupViewModelsByUserGroupId(int /// /// The userGroupId. /// A list of RoleUserGroupViewModel. - public List GetRoleUserGroupViewModelsByUserId(int userId) + public async Task> GetRoleUserGroupViewModelsByUserId(int userId) { var param0 = new SqlParameter("@userId", SqlDbType.Int) { Value = userId }; - var vm = this.DbContext.RoleUserGroupViewModel.FromSqlRaw("hub.RoleUserGroupGetByUserId @userId", param0).ToList(); + var vm = await this.DbContext.RoleUserGroupViewModel.FromSqlRaw("hub.RoleUserGroupGetByUserId @userId", param0).AsNoTracking().ToListAsync(); return vm; } } diff --git a/WebAPI/LearningHub.Nhs.Services.Interface/IHierarchyService.cs b/WebAPI/LearningHub.Nhs.Services.Interface/IHierarchyService.cs index 5cf2a1d15..7f996ee27 100644 --- a/WebAPI/LearningHub.Nhs.Services.Interface/IHierarchyService.cs +++ b/WebAPI/LearningHub.Nhs.Services.Interface/IHierarchyService.cs @@ -15,7 +15,7 @@ public interface IHierarchyService /// /// The node id. /// The node details. - NodeViewModel GetNodeDetails(int nodeId); + Task GetNodeDetails(int nodeId); /// /// Gets the basic details of all Nodes in a particular NodePath. diff --git a/WebAPI/LearningHub.Nhs.Services.Interface/IUserGroupService.cs b/WebAPI/LearningHub.Nhs.Services.Interface/IUserGroupService.cs index 338238c4c..01aac8335 100644 --- a/WebAPI/LearningHub.Nhs.Services.Interface/IUserGroupService.cs +++ b/WebAPI/LearningHub.Nhs.Services.Interface/IUserGroupService.cs @@ -48,14 +48,14 @@ public interface IUserGroupService /// /// The user group id. /// The list of . - List GetUserGroupRoleDetailByUserGroupId(int userGroupId); + Task> GetUserGroupRoleDetailByUserGroupId(int userGroupId); /// /// Returns a list of role user group detail view models for the supplied user id. /// /// The user group id. /// The list of . - List GetRoleUserGroupDetailByUserId(int userId); + Task> GetRoleUserGroupDetailByUserId(int userId); /// /// Create a user group. diff --git a/WebAPI/LearningHub.Nhs.Services/CatalogueService.cs b/WebAPI/LearningHub.Nhs.Services/CatalogueService.cs index d19885181..a074e2b99 100644 --- a/WebAPI/LearningHub.Nhs.Services/CatalogueService.cs +++ b/WebAPI/LearningHub.Nhs.Services/CatalogueService.cs @@ -926,24 +926,27 @@ public async Task AccessRequestAsync(int userId { var catalogueAccessRequest = this.catalogueAccessRequestRepository.GetAll().Include(x => x.UserProfile).SingleOrDefault(x => x.Id == catalogueAccessRequestId); string lastResponseMessage = null; - if (catalogueAccessRequest.Status == (int)CatalogueAccessRequestStatus.Pending) + if (catalogueAccessRequest != null) { - // Check for a previous access request which failed - // Will have the same userId and catalogueNodeId, not the same accessRequestId, a rejected status and a completed date. - var prevFailedRequest = this.catalogueAccessRequestRepository.GetAll() - .Where(x => x.UserId == catalogueAccessRequest.UserId && x.CatalogueNodeId == catalogueAccessRequest.CatalogueNodeId) - .Where(x => x.Id != catalogueAccessRequest.Id) - .Where(x => x.Status == (int)CatalogueAccessRequestStatus.Rejected && x.CompletedDate.HasValue) - .OrderByDescending(x => x.CompletedDate.Value) - .FirstOrDefault(); - lastResponseMessage = prevFailedRequest?.ResponseMessage; - } + if (catalogueAccessRequest.Status == (int)CatalogueAccessRequestStatus.Pending) + { + // Check for a previous access request which failed + // Will have the same userId and catalogueNodeId, not the same accessRequestId, a rejected status and a completed date. + var prevFailedRequest = this.catalogueAccessRequestRepository.GetAll() + .Where(x => x.UserId == catalogueAccessRequest.UserId && x.CatalogueNodeId == catalogueAccessRequest.CatalogueNodeId) + .Where(x => x.Id != catalogueAccessRequest.Id) + .Where(x => x.Status == (int)CatalogueAccessRequestStatus.Rejected && x.CompletedDate.HasValue) + .OrderByDescending(x => x.CompletedDate.Value) + .FirstOrDefault(); + lastResponseMessage = prevFailedRequest?.ResponseMessage; + } - var catalogue = this.catalogueNodeVersionRepository.GetBasicCatalogue(catalogueAccessRequest.CatalogueNodeId); - var canEdit = await this.IsUserLocalAdminAsync(userId, catalogue.NodeVersion.NodeId); - if (!canEdit) - { - throw new Exception($"User '{userId}' does not have access to manage catalogue '{catalogue.Url}'"); + var catalogue = this.catalogueNodeVersionRepository.GetBasicCatalogue(catalogueAccessRequest.CatalogueNodeId); + var canEdit = await this.IsUserLocalAdminAsync(userId, catalogue.NodeVersion.NodeId); + if (!canEdit) + { + throw new Exception($"User '{userId}' does not have access to manage catalogue '{catalogue.Url}'"); + } } var vm = this.mapper.Map(catalogueAccessRequest); diff --git a/WebAPI/LearningHub.Nhs.Services/HierarchyService.cs b/WebAPI/LearningHub.Nhs.Services/HierarchyService.cs index 4a422e983..5a2d6734d 100644 --- a/WebAPI/LearningHub.Nhs.Services/HierarchyService.cs +++ b/WebAPI/LearningHub.Nhs.Services/HierarchyService.cs @@ -212,9 +212,9 @@ public HierarchyService( /// /// The node id. /// The node details. - public NodeViewModel GetNodeDetails(int nodeId) + public async Task GetNodeDetails(int nodeId) { - var retVal = this.nodeRepository.GetNodeDetails(nodeId); + var retVal = await this.nodeRepository.GetNodeDetails(nodeId); return retVal; } diff --git a/WebAPI/LearningHub.Nhs.Services/LearningHub.Nhs.Services.csproj b/WebAPI/LearningHub.Nhs.Services/LearningHub.Nhs.Services.csproj index 1323eff8b..cde7e952e 100644 --- a/WebAPI/LearningHub.Nhs.Services/LearningHub.Nhs.Services.csproj +++ b/WebAPI/LearningHub.Nhs.Services/LearningHub.Nhs.Services.csproj @@ -13,7 +13,7 @@ - + diff --git a/WebAPI/LearningHub.Nhs.Services/MigrationService.cs b/WebAPI/LearningHub.Nhs.Services/MigrationService.cs index 471c4027c..ce61082af 100644 --- a/WebAPI/LearningHub.Nhs.Services/MigrationService.cs +++ b/WebAPI/LearningHub.Nhs.Services/MigrationService.cs @@ -182,7 +182,7 @@ public MigrationService( public async Task> GetMigrationSourcesAsync() { var migrationSources = await this.migrationSourceRepository.GetAll().ToListAsync(); - return this.mapper.Map>(migrationSources).AsEnumerable(); + return this.mapper.Map>(migrationSources ?? new List()).AsEnumerable(); } /// diff --git a/WebAPI/LearningHub.Nhs.Services/RatingService.cs b/WebAPI/LearningHub.Nhs.Services/RatingService.cs index 7a40a44ac..ead13ade2 100644 --- a/WebAPI/LearningHub.Nhs.Services/RatingService.cs +++ b/WebAPI/LearningHub.Nhs.Services/RatingService.cs @@ -116,8 +116,28 @@ public RatingService( public async Task GetRatingSummary(int userId, int entityVersionId) { var ratingSummary = await this.resourceVersionRatingSummaryRepository.GetByResourceVersionIdAsync(entityVersionId); + RatingSummaryViewModel ratingSummaryViewModel; - var ratingSummaryViewModel = this.mapper.Map(ratingSummary); + if (ratingSummary != null) + { + ratingSummaryViewModel = this.mapper.Map(ratingSummary); + } + else + { + ratingSummaryViewModel = new RatingSummaryViewModel + { + AverageRating = 0, + RatingCount = 0, + Rating1StarPercent = 0, + Rating2StarPercent = 0, + Rating3StarPercent = 0, + Rating4StarPercent = 0, + Rating5StarPercent = 0, + UserIsContributor = false, + UserCanRate = false, + UserRating = 0, + }; + } if (ratingSummaryViewModel.RatingCount > 0) { diff --git a/WebAPI/LearningHub.Nhs.Services/ResourceService.cs b/WebAPI/LearningHub.Nhs.Services/ResourceService.cs index e040a21c8..a298de4a8 100644 --- a/WebAPI/LearningHub.Nhs.Services/ResourceService.cs +++ b/WebAPI/LearningHub.Nhs.Services/ResourceService.cs @@ -1477,38 +1477,38 @@ public async Task> GetObsoleteResourceFile(int resourceVersionId, b var assessmentContentFiles = new List(); if (resource.AssessmentDetails is { EndGuidance: { } } && resource.AssessmentDetails.EndGuidance.Blocks != null) + { + if (deletedResource) { - if (deletedResource) - { - endGuidanceFiles = this.CheckBlockFile(extendedResourceVersion.AssessmentDetails.EndGuidance, resource.AssessmentDetails.EndGuidance); - } - else - { - endGuidanceFiles = this.CheckBlockFile(resource.AssessmentDetails.EndGuidance, extendedResourceVersion.AssessmentDetails.EndGuidance); - } + endGuidanceFiles = this.CheckBlockFile(extendedResourceVersion.AssessmentDetails.EndGuidance, resource.AssessmentDetails.EndGuidance); + } + else + { + endGuidanceFiles = this.CheckBlockFile(resource.AssessmentDetails.EndGuidance, extendedResourceVersion.AssessmentDetails.EndGuidance); + } - if (endGuidanceFiles.Any()) - { - retVal.AddRange(endGuidanceFiles); - } + if (endGuidanceFiles.Any()) + { + retVal.AddRange(endGuidanceFiles); } + } if (resource.AssessmentDetails is { AssessmentContent: { } } && resource.AssessmentDetails.AssessmentContent.Blocks != null) + { + if (deletedResource) { - if (deletedResource) - { - assessmentContentFiles = this.CheckBlockFile(extendedResourceVersion.AssessmentDetails.AssessmentContent, resource.AssessmentDetails.AssessmentContent); - } - else - { - assessmentContentFiles = this.CheckBlockFile(resource.AssessmentDetails.AssessmentContent, extendedResourceVersion.AssessmentDetails.AssessmentContent); - } + assessmentContentFiles = this.CheckBlockFile(extendedResourceVersion.AssessmentDetails.AssessmentContent, resource.AssessmentDetails.AssessmentContent); + } + else + { + assessmentContentFiles = this.CheckBlockFile(resource.AssessmentDetails.AssessmentContent, extendedResourceVersion.AssessmentDetails.AssessmentContent); + } - if (assessmentContentFiles.Any()) - { - retVal.AddRange(assessmentContentFiles); - } + if (assessmentContentFiles.Any()) + { + retVal.AddRange(assessmentContentFiles); } + } } else if (extendedResourceVersion.ResourceTypeEnum == ResourceTypeEnum.Case) { @@ -1532,11 +1532,11 @@ public async Task> GetObsoleteResourceFile(int resourceVersionId, b { if (resource.ResourceTypeEnum == ResourceTypeEnum.Scorm) { - retVal.Add(resource.ScormDetails.ContentFilePath); + retVal.Add(resource.ScormDetails.ContentFilePath); } else if (resource.ResourceTypeEnum == ResourceTypeEnum.Html) { - retVal.Add(resource.HtmlDetails.ContentFilePath); + retVal.Add(resource.HtmlDetails.ContentFilePath); } else if (resource.ResourceTypeEnum == ResourceTypeEnum.GenericFile) { @@ -1551,7 +1551,7 @@ public async Task> GetObsoleteResourceFile(int resourceVersionId, b retVal.Add(resource.AudioDetails?.File?.FilePath); if (resource.AudioDetails?.ResourceAzureMediaAsset?.FilePath != null) { - retVal.Add(resource.AudioDetails.ResourceAzureMediaAsset.FilePath); + retVal.Add(resource.AudioDetails.ResourceAzureMediaAsset.FilePath); } } else if (resource.ResourceTypeEnum == ResourceTypeEnum.Video) @@ -1559,20 +1559,20 @@ public async Task> GetObsoleteResourceFile(int resourceVersionId, b retVal.Add(resource.VideoDetails?.File?.FilePath); if (resource.VideoDetails?.ResourceAzureMediaAsset?.FilePath != null) { - retVal.Add(resource.VideoDetails.ResourceAzureMediaAsset.FilePath); + retVal.Add(resource.VideoDetails.ResourceAzureMediaAsset.FilePath); } } else if (resource.ResourceTypeEnum == ResourceTypeEnum.Article) { - var inputResourceFiles = resource.ArticleDetails.Files.ToList(); - if (inputResourceFiles.Any()) + var inputResourceFiles = resource.ArticleDetails.Files.ToList(); + if (inputResourceFiles.Any()) + { + foreach (var file in inputResourceFiles) { - foreach (var file in inputResourceFiles) - { - retVal.Add(file.FilePath); - } + retVal.Add(file.FilePath); } } + } else if (resource.ResourceTypeEnum == ResourceTypeEnum.Assessment) { if (deletedResource) @@ -1960,6 +1960,11 @@ public async Task GetResourceItemViewModelAsync(int resou var erv = await this.GetResourceVersionExtendedViewModelAsync(rv.Id, userId); + if (erv == null) + { + return null; + } + var retVal = new ResourceItemViewModel(erv); retVal.Id = resourceReferenceId; var bookmark = this.bookmarkRepository.GetAll().Where(b => b.ResourceReferenceId == resourceReferenceId && b.UserId == userId).FirstOrDefault(); @@ -4471,11 +4476,14 @@ private async Task UserCanEditResourceVersion(int userId, int resourceVers { return true; } - else + + var resourceVersion = await this.GetResourceVersionByIdAsync(resourceVersionId); + if (resourceVersion == null) { - var resourceVersion = await this.GetResourceVersionByIdAsync(resourceVersionId); - return await this.catalogueService.CanUserEditCatalogueAsync(currentUserId, (int)resourceVersion.ResourceCatalogueId); + return false; } + + return await this.catalogueService.CanUserEditCatalogueAsync(currentUserId, (int)resourceVersion.ResourceCatalogueId); } private async Task IsAudioVideoResource(int resourceVersionId, ResourceTypeEnum resourceType) diff --git a/WebAPI/LearningHub.Nhs.Services/UserGroupService.cs b/WebAPI/LearningHub.Nhs.Services/UserGroupService.cs index 985289733..40666f502 100644 --- a/WebAPI/LearningHub.Nhs.Services/UserGroupService.cs +++ b/WebAPI/LearningHub.Nhs.Services/UserGroupService.cs @@ -197,9 +197,9 @@ public async Task GetUserGroupAdminDetailByIdAsyn /// /// The user group id. /// The list of . - public List GetUserGroupRoleDetailByUserGroupId(int userGroupId) + public async Task> GetUserGroupRoleDetailByUserGroupId(int userGroupId) { - var vm = this.roleUserGroupRepository.GetRoleUserGroupViewModelsByUserGroupId(userGroupId); + var vm = await this.roleUserGroupRepository.GetRoleUserGroupViewModelsByUserGroupId(userGroupId); return vm; } @@ -209,9 +209,9 @@ public List GetUserGroupRoleDetailByUserGroupId(int user /// /// The user group id. /// The list of . - public List GetRoleUserGroupDetailByUserId(int userId) + public async Task> GetRoleUserGroupDetailByUserId(int userId) { - var vm = this.roleUserGroupRepository.GetRoleUserGroupViewModelsByUserId(userId); + var vm = await this.roleUserGroupRepository.GetRoleUserGroupViewModelsByUserId(userId); return vm; } From ccfd1e8d805b0dd70b642d9c197f1a815ec79cc4 Mon Sep 17 00:00:00 2001 From: Oluwatobi Awe Date: Tue, 25 Jun 2024 15:32:39 +0100 Subject: [PATCH 2/9] TD-4271 dashboard service optimisation. --- .../Controllers/HomeController.cs | 22 +++- .../LearningHub.Nhs.Database.sqlproj | 7 ++ .../Scripts/TD-4271_Dasboard_Index.sql | 18 +++ .../GetMyCertificatesDashboardResources.sql | 101 +++++++++++++++++ .../GetMyInProgressDashboardResources.sql | 105 ++++++++++++++++++ ...GetMyRecentCompletedDashboardResources.sql | 101 +++++++++++++++++ .../GetPopularDashboardResources.sql | 96 ++++++++++++++++ .../Resources/GetRatedDashboardResources.sql | 86 ++++++++++++++ .../Resources/GetRecentDashboardResources.sql | 84 ++++++++++++++ .../Resources/ResourceVersionRepository.cs | 32 +++++- .../ResourceService.cs | 1 + 11 files changed, 641 insertions(+), 12 deletions(-) create mode 100644 WebAPI/LearningHub.Nhs.Database/Scripts/Pre-Deploy/Scripts/TD-4271_Dasboard_Index.sql create mode 100644 WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetMyCertificatesDashboardResources.sql create mode 100644 WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetMyInProgressDashboardResources.sql create mode 100644 WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetMyRecentCompletedDashboardResources.sql create mode 100644 WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetPopularDashboardResources.sql create mode 100644 WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetRatedDashboardResources.sql create mode 100644 WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetRecentDashboardResources.sql diff --git a/LearningHub.Nhs.WebUI/Controllers/HomeController.cs b/LearningHub.Nhs.WebUI/Controllers/HomeController.cs index f524fe458..e575f13c5 100644 --- a/LearningHub.Nhs.WebUI/Controllers/HomeController.cs +++ b/LearningHub.Nhs.WebUI/Controllers/HomeController.cs @@ -203,11 +203,17 @@ public async Task Index(string myLearningDashboard = "my-in-progr this.Logger.LogInformation("User is authenticated: User is {fullname} and userId is: {lhuserid}", this.User.Identity.GetCurrentName(), this.User.Identity.GetCurrentUserId()); if (this.User.IsInRole("Administrator") || this.User.IsInRole("BlueUser") || this.User.IsInRole("ReadOnly") || this.User.IsInRole("BasicUser")) { + var learningTask = this.dashboardService.GetMyAccessLearningsAsync(myLearningDashboard, 1); + var resourcesTask = this.dashboardService.GetResourcesAsync(resourceDashboard, 1); + var cataloguesTask = this.dashboardService.GetCataloguesAsync(catalogueDashboard, 1); + + await Task.WhenAll(learningTask, resourcesTask, cataloguesTask); + var model = new DashboardViewModel() { - MyLearnings = await this.dashboardService.GetMyAccessLearningsAsync(myLearningDashboard, 1), - Resources = await this.dashboardService.GetResourcesAsync(resourceDashboard, 1), - Catalogues = await this.dashboardService.GetCataloguesAsync(catalogueDashboard, 1), + MyLearnings = await learningTask, + Resources = await resourcesTask, + Catalogues = await cataloguesTask, }; if (!string.IsNullOrEmpty(this.Request.Query["preview"]) && Convert.ToBoolean(this.Request.Query["preview"])) @@ -271,9 +277,13 @@ public async Task LoadPage(string dashBoardTray = "my-learning", } else { - model.MyLearnings = await this.dashboardService.GetMyAccessLearningsAsync(myLearningDashBoard, dashBoardTray == "my-learning" ? pageNumber : 1); - model.Resources = await this.dashboardService.GetResourcesAsync(resourceDashBoard, dashBoardTray == "resources" ? pageNumber : 1); - model.Catalogues = await this.dashboardService.GetCataloguesAsync(catalogueDashBoard, dashBoardTray == "catalogues" ? pageNumber : 1); + var learningTask = this.dashboardService.GetMyAccessLearningsAsync(myLearningDashBoard, dashBoardTray == "my-learning" ? pageNumber : 1); + var resourcesTask = this.dashboardService.GetResourcesAsync(resourceDashBoard, dashBoardTray == "resources" ? pageNumber : 1); + var cataloguesTask = this.dashboardService.GetCataloguesAsync(catalogueDashBoard, dashBoardTray == "catalogues" ? pageNumber : 1); + await Task.WhenAll(learningTask, resourcesTask, cataloguesTask); + model.MyLearnings = await learningTask; + model.Resources = await resourcesTask; + model.Catalogues = await cataloguesTask; return this.View("Dashboard", model); } } diff --git a/WebAPI/LearningHub.Nhs.Database/LearningHub.Nhs.Database.sqlproj b/WebAPI/LearningHub.Nhs.Database/LearningHub.Nhs.Database.sqlproj index 2613eb68c..78a7f9aa2 100644 --- a/WebAPI/LearningHub.Nhs.Database/LearningHub.Nhs.Database.sqlproj +++ b/WebAPI/LearningHub.Nhs.Database/LearningHub.Nhs.Database.sqlproj @@ -200,6 +200,9 @@ + + + @@ -514,6 +517,10 @@ + + + + diff --git a/WebAPI/LearningHub.Nhs.Database/Scripts/Pre-Deploy/Scripts/TD-4271_Dasboard_Index.sql b/WebAPI/LearningHub.Nhs.Database/Scripts/Pre-Deploy/Scripts/TD-4271_Dasboard_Index.sql new file mode 100644 index 000000000..fa8cbe9a3 --- /dev/null +++ b/WebAPI/LearningHub.Nhs.Database/Scripts/Pre-Deploy/Scripts/TD-4271_Dasboard_Index.sql @@ -0,0 +1,18 @@ + +CREATE INDEX IX_Resource_CurrentResourceVersionId ON resources.Resource (CurrentResourceVersionId) +GO +------------------------------ +CREATE INDEX IX_Resource_ResourceTypeId ON resources.Resource (ResourceTypeId) +GO +------------------------------ +CREATE INDEX IX_ResourceVersion_ResourceId ON resources.ResourceVersion (ResourceId) +GO +----------------------------- +CREATE INDEX IX_ResourceActivity_UserId_ActivityStatusId ON activity.ResourceActivity (UserId, ActivityStatusId) +GO +------------------------------- +CREATE INDEX IX_NodePath_CatalogueNodeId_Deleted ON hierarchy.NodePath (CatalogueNodeId, Deleted) +GO +------------------------------- +CREATE INDEX IX_UserBookmark_UserId_ResourceReferenceId_Deleted ON hub.UserBookmark (UserId, ResourceReferenceId, Deleted) +GO diff --git a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetMyCertificatesDashboardResources.sql b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetMyCertificatesDashboardResources.sql new file mode 100644 index 000000000..b75e45860 --- /dev/null +++ b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetMyCertificatesDashboardResources.sql @@ -0,0 +1,101 @@ +------------------------------------------------------------------------------- +-- Author OA +-- Created 24 JUN 2024 Nov 2020 +-- Purpose Break down the GetDashboardResources SP to smaller SP for a specific data type +-- +-- Modification History +-- +-- 24 Jun 2024 OA Initial Revision +------------------------------------------------------------------------------- + +CREATE PROCEDURE [resources].[GetMyCertificatesDashboardResources] + @UserId INT, + @PageNumber INT = 1, + @TotalRecords INT OUTPUT +AS +BEGIN + DECLARE @MaxPageNumber INT = 4 + + IF @PageNumber > 4 + BEGIN + SET @PageNumber = @MaxPageNumber + END + + DECLARE @FetchRows INT = 3 + DECLARE @MaxRows INT = @MaxPageNUmber * @FetchRows + DECLARE @OffsetRows INT = (@PageNumber - 1) * @FetchRows + + DECLARE @MyActivity TABLE (ResourceId [int] NOT NULL PRIMARY KEY, ResourceActivityId [int] NOT NULL); + DECLARE @Resources TABLE (ResourceId [int] NOT NULL PRIMARY KEY, ResourceActivityCount [int] NOT NULL); + + INSERT INTO @MyActivity + SELECT TOP (@MaxRows) ra.ResourceId, MAX(ra.Id) ResourceActivityId + FROM + activity.ResourceActivity ra + JOIN [resources].[Resource] r ON ra.ResourceId = r.Id + JOIN [resources].[ResourceVersion] rv ON rv.Id = ra.ResourceVersionId + LEFT JOIN [resources].[AssessmentResourceVersion] arv ON arv.ResourceVersionId = ra.ResourceVersionId + LEFT JOIN [activity].[AssessmentResourceActivity] ara ON ara.ResourceActivityId = ra.Id + LEFT JOIN [activity].[MediaResourceActivity] mar ON mar.ResourceActivityId = ra.Id + LEFT JOIN [activity].[ScormActivity] sa ON sa.ResourceActivityId = ra.Id + WHERE ra.UserId = @UserId AND rv.CertificateEnabled = 1 + AND ( + (r.ResourceTypeId IN (2, 7) AND ra.ActivityStatusId = 3 OR ra.ActivityStart < '2020-09-07 00:00:00 +00:00' OR mar.Id IS NOT NULL AND mar.PercentComplete = 100) + OR (r.ResourceTypeId = 6 AND (sa.CmiCoreLesson_status IN(3,5) OR (ra.ActivityStatusId IN(3, 5)))) + OR ((r.ResourceTypeId = 11 AND arv.AssessmentType = 2) AND (ara.Score >= arv.PassMark OR ra.ActivityStatusId IN(3, 5))) + OR ((r.ResourceTypeId = 11 AND arv.AssessmentType =1) AND (ara.Score >= arv.PassMark AND ra.ActivityStatusId IN(3, 5,7))) + OR (r.ResourceTypeId IN (1, 5, 8, 9, 10, 12) AND ra.ActivityStatusId = 3)) + GROUP BY ra.ResourceId + ORDER BY ResourceActivityId DESC + + SELECT r.Id AS ResourceId + ,( SELECT TOP 1 rr.OriginalResourceReferenceId + FROM [resources].[ResourceReference] rr + JOIN hierarchy.NodePath np on np.id = rr.NodePathId and np.NodeId = n.Id and np.Deleted = 0 + WHERE rr.ResourceId = rv.ResourceId AND rr.Deleted = 0 + ) AS ResourceReferenceID + ,r.CurrentResourceVersionId AS ResourceVersionId + ,r.ResourceTypeId AS ResourceTypeId + ,rv.Title + ,rv.Description + ,CASE + WHEN r.ResourceTypeId = 7 THEN + (SELECT vrv.DurationInMilliseconds from [resources].[VideoResourceVersion] vrv WHERE vrv.[ResourceVersionId] = r.CurrentResourceVersionId) + WHEN r.ResourceTypeId = 2 THEN + (SELECT vrv.DurationInMilliseconds from [resources].[AudioResourceVersion] vrv WHERE vrv.[ResourceVersionId] = r.CurrentResourceVersionId) + ELSE + NULL + END AS DurationInMilliseconds + ,CASE WHEN n.id = 1 THEN NULL ELSE cnv.Name END AS CatalogueName + ,cnv.Url AS Url + ,CASE WHEN n.id = 1 THEN NULL ELSE cnv.BadgeUrl END AS BadgeUrl + ,cnv.RestrictedAccess + ,CAST(CASE WHEN cnv.RestrictedAccess = 1 AND auth.CatalogueNodeId IS NULL THEN 0 ELSE 1 END AS bit) AS HasAccess + ,ub.Id AS BookMarkId + ,CAST(ISNULL(ub.[Deleted], 1) ^ 1 AS BIT) AS IsBookmarked + ,rvrs.AverageRating + ,rvrs.RatingCount +FROM @MyActivity ma +JOIN activity.ResourceActivity ra ON ra.id = ma.ResourceActivityId +JOIN resources.resourceversion rv ON rv.id = ra.ResourceVersionId AND rv.Deleted = 0 +JOIN Resources.Resource r ON r.Id = rv.ResourceId +JOIN hierarchy.Publication p ON rv.PublicationId = p.Id AND p.Deleted = 0 +JOIN resources.ResourceVersionRatingSummary rvrs ON rv.Id = rvrs.ResourceVersionId AND rvrs.Deleted = 0 +JOIN hierarchy.NodeResource nr ON r.Id = nr.ResourceId AND nr.Deleted = 0 +JOIN hierarchy.Node n ON n.Id = nr.NodeId AND n.Hidden = 0 AND n.Deleted = 0 +JOIN hierarchy.NodePath np ON np.NodeId = n.Id AND np.Deleted = 0 AND np.IsActive = 1 +JOIN hierarchy.NodeVersion nv ON nv.NodeId = np.CatalogueNodeId AND nv.VersionStatusId = 2 AND nv.Deleted = 0 +JOIN hierarchy.CatalogueNodeVersion cnv ON cnv.NodeVersionId = nv.Id AND cnv.Deleted = 0 +LEFT JOIN hub.UserBookmark ub ON ub.UserId = @UserId AND ub.ResourceReferenceId = (SELECT TOP 1 rr.OriginalResourceReferenceId + FROM [resources].[ResourceReference] rr + JOIN hierarchy.NodePath np on np.id = rr.NodePathId and np.NodeId = n.Id and np.Deleted = 0 + WHERE rr.ResourceId = rv.ResourceId AND rr.Deleted = 0) +LEFT JOIN ( SELECT DISTINCT CatalogueNodeId + FROM [hub].[RoleUserGroupView] rug JOIN hub.UserUserGroup uug ON rug.UserGroupId = uug.UserGroupId + WHERE rug.ScopeTypeId = 1 and rug.RoleId in (1,2,3) and uug.Deleted = 0 and uug.UserId = @userId) auth ON n.Id = auth.CatalogueNodeId +ORDER BY ma.ResourceActivityId DESC, rv.Title +OFFSET @OffsetRows ROWS +FETCH NEXT @FetchRows ROWS ONLY + + SELECT @TotalRecords = CASE WHEN COUNT(*) > 12 THEN @MaxRows ELSE COUNT(*) END FROM @MyActivity +END \ No newline at end of file diff --git a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetMyInProgressDashboardResources.sql b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetMyInProgressDashboardResources.sql new file mode 100644 index 000000000..22709e898 --- /dev/null +++ b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetMyInProgressDashboardResources.sql @@ -0,0 +1,105 @@ +------------------------------------------------------------------------------- +-- Author OA +-- Created 24 JUN 2024 Nov 2020 +-- Purpose Break down the GetDashboardResources SP to smaller SP for a specific data type +-- +-- Modification History +-- +-- 24 Jun 2024 OA Initial Revision +------------------------------------------------------------------------------- + +CREATE PROCEDURE [resources].[GetMyInProgressDashboardResources] + @UserId INT, + @PageNumber INT = 1, + @TotalRecords INT OUTPUT +AS +BEGIN + DECLARE @MaxPageNumber INT = 4 + + IF @PageNumber > 4 + BEGIN + SET @PageNumber = @MaxPageNumber + END + + DECLARE @FetchRows INT = 3 + DECLARE @MaxRows INT = @MaxPageNUmber * @FetchRows + DECLARE @OffsetRows INT = (@PageNumber - 1) * @FetchRows + + DECLARE @MyActivity TABLE (ResourceId [int] NOT NULL PRIMARY KEY, ResourceActivityId [int] NOT NULL); + DECLARE @Resources TABLE (ResourceId [int] NOT NULL PRIMARY KEY, ResourceActivityCount [int] NOT NULL); + + + INSERT INTO @MyActivity + SELECT TOP (@MaxRows) ra.ResourceId, MAX(ra.Id) ResourceActivityId + FROM + (SELECT a.Id,a.ResourceId,a.ResourceVersionId,a.LaunchResourceActivityId,a.UserId,a.ActivityStatusId,a.ActivityStart FROM activity.ResourceActivity a INNER JOIN (SELECT ResourceId, MAX(Id) as id FROM activity.ResourceActivity GROUP BY ResourceId) AS b ON a.ResourceId = b.ResourceId AND a.id = b.id order by a.Id desc OFFSET 0 ROWS) ra + JOIN [resources].[Resource] r ON ra.ResourceId = r.Id + JOIN [resources].[ResourceVersion] rv ON rv.Id = ra.ResourceVersionId + LEFT JOIN [resources].[AssessmentResourceVersion] arv ON arv.ResourceVersionId = ra.ResourceVersionId + LEFT JOIN [activity].[AssessmentResourceActivity] ara ON ara.ResourceActivityId = COALESCE(ra.LaunchResourceActivityId, ra.Id) + LEFT JOIN [activity].[MediaResourceActivity] mar ON mar.ResourceActivityId = COALESCE(ra.LaunchResourceActivityId, ra.Id) + LEFT JOIN [activity].[ScormActivity] sa ON sa.ResourceActivityId = ra.Id + WHERE ra.UserId = @UserId + AND ( + (r.ResourceTypeId IN (1, 5, 8, 9,10, 12) AND ra.ActivityStatusId <> 3) + OR (r.ResourceTypeId IN (2, 7) AND (mar.Id IS NULL OR (mar.Id IS NOT NULL AND mar.PercentComplete < 100) OR ra.ActivityStart < '2020-09-07 00:00:00 +00:00')) + OR (r.ResourceTypeId = 6 AND (sa.CmiCoreLesson_status NOT IN (3, 5) AND (ra.ActivityStatusId NOT IN(3, 5)))) + OR ((r.ResourceTypeId = 11 AND arv.AssessmentType = 2) AND ((ara.Id IS NOT NULL AND ara.score < arv.PassMark) OR ra.ActivityStatusId = 7)) + + OR ((r.ResourceTypeId = 11 AND arv.AssessmentType = 1) AND ra.ActivityStatusId = 7) + ) + GROUP BY ra.ResourceId + ORDER BY ResourceActivityId DESC + + SELECT ma.ResourceActivityId, r.Id AS ResourceId + ,( SELECT TOP 1 rr.OriginalResourceReferenceId + FROM [resources].[ResourceReference] rr + JOIN hierarchy.NodePath np on np.id = rr.NodePathId and np.NodeId = n.Id and np.Deleted = 0 + WHERE rr.ResourceId = rv.ResourceId AND rr.Deleted = 0 + ) AS ResourceReferenceID + ,r.CurrentResourceVersionId AS ResourceVersionId + ,r.ResourceTypeId AS ResourceTypeId + ,rv.Title + ,rv.Description + ,CASE + WHEN r.ResourceTypeId = 7 THEN + (SELECT vrv.DurationInMilliseconds from [resources].[VideoResourceVersion] vrv WHERE vrv.[ResourceVersionId] = r.CurrentResourceVersionId) + WHEN r.ResourceTypeId = 2 THEN + (SELECT vrv.DurationInMilliseconds from [resources].[AudioResourceVersion] vrv WHERE vrv.[ResourceVersionId] = r.CurrentResourceVersionId) + ELSE + NULL + END AS DurationInMilliseconds + ,CASE WHEN n.id = 1 THEN NULL ELSE cnv.Name END AS CatalogueName + ,cnv.Url AS Url + ,CASE WHEN n.id = 1 THEN NULL ELSE cnv.BadgeUrl END AS BadgeUrl + ,cnv.RestrictedAccess + ,CAST(CASE WHEN cnv.RestrictedAccess = 1 AND auth.CatalogueNodeId IS NULL THEN 0 ELSE 1 END AS bit) AS HasAccess + ,ub.Id AS BookMarkId + ,CAST(ISNULL(ub.[Deleted], 1) ^ 1 AS BIT) AS IsBookmarked + ,rvrs.AverageRating + ,rvrs.RatingCount + FROM @MyActivity ma + JOIN activity.ResourceActivity ra ON ra.id = ma.ResourceActivityId + JOIN resources.resourceversion rv ON rv.id = ra.ResourceVersionId AND rv.Deleted = 0 + JOIN Resources.Resource r ON r.Id = rv.ResourceId + JOIN hierarchy.Publication p ON rv.PublicationId = p.Id AND p.Deleted = 0 + JOIN resources.ResourceVersionRatingSummary rvrs ON rv.Id = rvrs.ResourceVersionId AND rvrs.Deleted = 0 + JOIN hierarchy.NodeResource nr ON r.Id = nr.ResourceId AND nr.Deleted = 0 + JOIN hierarchy.Node n ON n.Id = nr.NodeId AND n.Hidden = 0 AND n.Deleted = 0 + JOIN hierarchy.NodePath np ON np.NodeId = n.Id AND np.Deleted = 0 AND np.IsActive = 1 + JOIN hierarchy.NodeVersion nv ON nv.NodeId = np.CatalogueNodeId AND nv.VersionStatusId = 2 AND nv.Deleted = 0 + JOIN hierarchy.CatalogueNodeVersion cnv ON cnv.NodeVersionId = nv.Id AND cnv.Deleted = 0 + LEFT JOIN hub.UserBookmark ub ON ub.UserId = @UserId AND ub.ResourceReferenceId = (SELECT TOP 1 rr.OriginalResourceReferenceId + FROM [resources].[ResourceReference] rr + JOIN hierarchy.NodePath np on np.id = rr.NodePathId and np.NodeId = n.Id and np.Deleted = 0 + WHERE rr.ResourceId = rv.ResourceId AND rr.Deleted = 0) + LEFT JOIN ( SELECT DISTINCT CatalogueNodeId + FROM [hub].[RoleUserGroupView] rug JOIN hub.UserUserGroup uug ON rug.UserGroupId = uug.UserGroupId + WHERE rug.ScopeTypeId = 1 and rug.RoleId in (1,2,3) and uug.Deleted = 0 and uug.UserId = @userId) auth ON n.Id = auth.CatalogueNodeId + ORDER BY ma.ResourceActivityId DESC + OFFSET @OffsetRows ROWS + FETCH NEXT @FetchRows ROWS ONLY + + SELECT @TotalRecords = CASE WHEN COUNT(*) > 12 THEN @MaxRows ELSE COUNT(*) END FROM @MyActivity + +END \ No newline at end of file diff --git a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetMyRecentCompletedDashboardResources.sql b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetMyRecentCompletedDashboardResources.sql new file mode 100644 index 000000000..686ef7efe --- /dev/null +++ b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetMyRecentCompletedDashboardResources.sql @@ -0,0 +1,101 @@ +------------------------------------------------------------------------------- +-- Author OA +-- Created 24 JUN 2024 Nov 2020 +-- Purpose Break down the GetDashboardResources SP to smaller SP for a specific data type +-- +-- Modification History +-- +-- 24 Jun 2024 OA Initial Revision +------------------------------------------------------------------------------- + +CREATE PROCEDURE [resources].[GetMyRecentCompletedDashboardResources] + @UserId INT, + @PageNumber INT = 1, + @TotalRecords INT OUTPUT +AS +BEGIN + DECLARE @MaxPageNumber INT = 4 + + IF @PageNumber > 4 + BEGIN + SET @PageNumber = @MaxPageNumber + END + + DECLARE @FetchRows INT = 3 + DECLARE @MaxRows INT = @MaxPageNUmber * @FetchRows + DECLARE @OffsetRows INT = (@PageNumber - 1) * @FetchRows + + DECLARE @MyActivity TABLE (ResourceId [int] NOT NULL PRIMARY KEY, ResourceActivityId [int] NOT NULL); + DECLARE @Resources TABLE (ResourceId [int] NOT NULL PRIMARY KEY, ResourceActivityCount [int] NOT NULL); + + INSERT INTO @MyActivity + SELECT TOP (@MaxRows) ra.ResourceId, MAX(ra.Id) ResourceActivityId + FROM + (SELECT a.Id,a.ResourceId,a.ResourceVersionId,a.LaunchResourceActivityId,a.UserId,a.ActivityStatusId,a.ActivityStart FROM activity.ResourceActivity a INNER JOIN (SELECT ResourceId, MAX(Id) as id FROM activity.ResourceActivity GROUP BY ResourceId ) AS b ON a.ResourceId = b.ResourceId AND a.id = b.id order by a.Id desc OFFSET 0 ROWS) ra + JOIN [resources].[Resource] r ON ra.ResourceId = r.Id + JOIN [resources].[ResourceVersion] rv ON rv.Id = ra.ResourceVersionId + LEFT JOIN [resources].[AssessmentResourceVersion] arv ON arv.ResourceVersionId = ra.ResourceVersionId + LEFT JOIN [activity].[AssessmentResourceActivity] ara ON ara.ResourceActivityId = COALESCE(ra.LaunchResourceActivityId, ra.Id) + LEFT JOIN [activity].[MediaResourceActivity] mar ON mar.ResourceActivityId = COALESCE(ra.LaunchResourceActivityId, ra.Id) + LEFT JOIN [activity].[ScormActivity] sa ON sa.ResourceActivityId = ra.Id + WHERE ra.UserId = @UserId + AND ( + (r.ResourceTypeId IN (2, 7) AND ra.ActivityStatusId = 3 AND ((mar.Id IS NOT NULL AND mar.PercentComplete = 100) OR ra.ActivityStart < '2020-09-07 00:00:00 +00:00')) + OR (r.ResourceTypeId = 6 AND (sa.CmiCoreLesson_status IN(3,5) OR (ra.ActivityStatusId IN(3, 5)))) + OR (r.ResourceTypeId = 11 AND ara.Score >= arv.PassMark OR ra.ActivityStatusId IN( 3, 5)) + OR (r.ResourceTypeId IN (1, 5, 8, 9, 10, 12) AND ra.ActivityStatusId = 3)) + GROUP BY ra.ResourceId + ORDER BY ResourceActivityId DESC + + SELECT r.Id AS ResourceId + ,( SELECT TOP 1 rr.OriginalResourceReferenceId + FROM [resources].[ResourceReference] rr + JOIN hierarchy.NodePath np on np.id = rr.NodePathId and np.NodeId = n.Id and np.Deleted = 0 + WHERE rr.ResourceId = rv.ResourceId AND rr.Deleted = 0 + ) AS ResourceReferenceID + ,r.CurrentResourceVersionId AS ResourceVersionId + ,r.ResourceTypeId AS ResourceTypeId + ,rv.Title + ,rv.Description + ,CASE + WHEN r.ResourceTypeId = 7 THEN + (SELECT vrv.DurationInMilliseconds from [resources].[VideoResourceVersion] vrv WHERE vrv.[ResourceVersionId] = r.CurrentResourceVersionId) + WHEN r.ResourceTypeId = 2 THEN + (SELECT vrv.DurationInMilliseconds from [resources].[AudioResourceVersion] vrv WHERE vrv.[ResourceVersionId] = r.CurrentResourceVersionId) + ELSE + NULL + END AS DurationInMilliseconds + ,CASE WHEN n.id = 1 THEN NULL ELSE cnv.Name END AS CatalogueName + ,cnv.Url AS Url + ,CASE WHEN n.id = 1 THEN NULL ELSE cnv.BadgeUrl END AS BadgeUrl + ,cnv.RestrictedAccess + ,CAST(CASE WHEN cnv.RestrictedAccess = 1 AND auth.CatalogueNodeId IS NULL THEN 0 ELSE 1 END AS bit) AS HasAccess + ,ub.Id AS BookMarkId + ,CAST(ISNULL(ub.[Deleted], 1) ^ 1 AS BIT) AS IsBookmarked + ,rvrs.AverageRating + ,rvrs.RatingCount +FROM @MyActivity ma +JOIN activity.ResourceActivity ra ON ra.id = ma.ResourceActivityId +JOIN resources.resourceversion rv ON rv.id = ra.ResourceVersionId AND rv.Deleted = 0 +JOIN Resources.Resource r ON r.Id = rv.ResourceId +JOIN hierarchy.Publication p ON rv.PublicationId = p.Id AND p.Deleted = 0 +JOIN resources.ResourceVersionRatingSummary rvrs ON rv.Id = rvrs.ResourceVersionId AND rvrs.Deleted = 0 +JOIN hierarchy.NodeResource nr ON r.Id = nr.ResourceId AND nr.Deleted = 0 +JOIN hierarchy.Node n ON n.Id = nr.NodeId AND n.Hidden = 0 AND n.Deleted = 0 +JOIN hierarchy.NodePath np ON np.NodeId = n.Id AND np.Deleted = 0 AND np.IsActive = 1 +JOIN hierarchy.NodeVersion nv ON nv.NodeId = np.CatalogueNodeId AND nv.VersionStatusId = 2 AND nv.Deleted = 0 +JOIN hierarchy.CatalogueNodeVersion cnv ON cnv.NodeVersionId = nv.Id AND cnv.Deleted = 0 +LEFT JOIN hub.UserBookmark ub ON ub.UserId = @UserId AND ub.ResourceReferenceId = (SELECT TOP 1 rr.OriginalResourceReferenceId + FROM [resources].[ResourceReference] rr + JOIN hierarchy.NodePath np on np.id = rr.NodePathId and np.NodeId = n.Id and np.Deleted = 0 + WHERE rr.ResourceId = rv.ResourceId AND rr.Deleted = 0) +LEFT JOIN ( SELECT DISTINCT CatalogueNodeId + FROM [hub].[RoleUserGroupView] rug JOIN hub.UserUserGroup uug ON rug.UserGroupId = uug.UserGroupId + WHERE rug.ScopeTypeId = 1 and rug.RoleId in (1,2,3) and uug.Deleted = 0 and uug.UserId = @userId) auth ON n.Id = auth.CatalogueNodeId +ORDER BY ma.ResourceActivityId DESC, rv.Title +OFFSET @OffsetRows ROWS +FETCH NEXT @FetchRows ROWS ONLY + + SELECT @TotalRecords = CASE WHEN COUNT(*) > 12 THEN @MaxRows ELSE COUNT(*) END FROM @MyActivity + +END \ No newline at end of file diff --git a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetPopularDashboardResources.sql b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetPopularDashboardResources.sql new file mode 100644 index 000000000..f35761471 --- /dev/null +++ b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetPopularDashboardResources.sql @@ -0,0 +1,96 @@ +------------------------------------------------------------------------------- +-- Author OA +-- Created 24 JUN 2024 Nov 2020 +-- Purpose Break down the GetDashboardResources SP to smaller SP for a specific data type +-- +-- Modification History +-- +-- 24 Jun 2024 OA Initial Revision +------------------------------------------------------------------------------- + +CREATE PROCEDURE [resources].[GetPopularDashboardResources] + @UserId INT, + @PageNumber INT = 1, + @TotalRecords INT OUTPUT +AS +BEGIN + DECLARE @MaxPageNumber INT = 4 + + IF @PageNumber > 4 + BEGIN + SET @PageNumber = @MaxPageNumber + END + + DECLARE @FetchRows INT = 3 + DECLARE @MaxRows INT = @MaxPageNUmber * @FetchRows + DECLARE @OffsetRows INT = (@PageNumber - 1) * @FetchRows + + DECLARE @MyActivity TABLE (ResourceId [int] NOT NULL PRIMARY KEY, ResourceActivityId [int] NOT NULL); + DECLARE @Resources TABLE (ResourceId [int] NOT NULL PRIMARY KEY, ResourceActivityCount [int] NOT NULL); + + + INSERT INTO @Resources + SELECT TOP (@MaxRows) ra.ResourceId + ,Count(ra.ResourceVersionId) ResourceActivityCount + FROM resources.Resource r + JOIN resources.ResourceVersion rv On rv.id = r.CurrentResourceVersionId AND rv.VersionStatusId = 2 + JOIN activity.ResourceActivity ra ON ra.ResourceId = r.Id + JOIN hierarchy.NodeResource nr ON r.Id = nr.ResourceId AND nr.Deleted = 0 + JOIN hierarchy.Node n ON n.Id = nr.NodeId AND n.Hidden = 0 AND n.Deleted = 0 + JOIN hierarchy.NodePath np ON np.NodeId = n.Id AND np.Deleted = 0 AND np.IsActive = 1 + JOIN hierarchy.NodeVersion nv ON nv.NodeId = np.CatalogueNodeId AND nv.VersionStatusId = 2 AND nv.Deleted = 0 + JOIN hierarchy.CatalogueNodeVersion cnv ON cnv.NodeVersionId = nv.Id AND cnv.Deleted = 0 + GROUP BY ra.ResourceId + ORDER BY ResourceActivityCount DESC + SELECT + tr.ResourceId + ,( SELECT TOP 1 rr.OriginalResourceReferenceId + FROM [resources].[ResourceReference] rr + JOIN hierarchy.NodePath np on np.id = rr.NodePathId and np.NodeId = n.Id and np.Deleted = 0 + WHERE rr.ResourceId = rv.ResourceId AND rr.Deleted = 0 + ) AS ResourceReferenceID + ,r.CurrentResourceVersionId AS ResourceVersionId + ,r.ResourceTypeId AS ResourceTypeId + ,rv.Title + ,rv.Description + ,CASE + WHEN r.ResourceTypeId = 7 THEN + (SELECT vrv.DurationInMilliseconds from [resources].[VideoResourceVersion] vrv WHERE vrv.[ResourceVersionId] = r.CurrentResourceVersionId) + WHEN r.ResourceTypeId = 2 THEN + (SELECT vrv.DurationInMilliseconds from [resources].[AudioResourceVersion] vrv WHERE vrv.[ResourceVersionId] = r.CurrentResourceVersionId) + ELSE + NULL + END AS DurationInMilliseconds + ,CASE WHEN n.id = 1 THEN NULL ELSE cnv.Name END AS CatalogueName + ,cnv.Url AS Url + ,CASE WHEN n.id = 1 THEN NULL ELSE cnv.BadgeUrl END AS BadgeUrl + ,cnv.RestrictedAccess + ,CAST(CASE WHEN cnv.RestrictedAccess = 1 AND auth.CatalogueNodeId IS NULL THEN 0 ELSE 1 END AS bit) AS HasAccess + ,ub.Id AS BookMarkId + ,CAST(ISNULL(ub.[Deleted], 1) ^ 1 AS BIT) AS IsBookmarked + ,rvrs.AverageRating + ,rvrs.RatingCount + FROM @Resources tr + JOIN resources.Resource r ON r.id = tr.ResourceId + JOIN resources.resourceversion rv ON rv.ResourceId = r.Id AND rv.id = r.CurrentResourceVersionId AND rv.Deleted = 0 + JOIN resources.ResourceVersionRatingSummary rvrs ON r.CurrentResourceVersionId = rvrs.ResourceVersionId AND rvrs.Deleted = 0 + JOIN hierarchy.NodeResource nr ON r.Id = nr.ResourceId AND nr.Deleted = 0 + JOIN hierarchy.Node n ON n.Id = nr.NodeId AND n.Hidden = 0 AND n.Deleted = 0 + JOIN hierarchy.NodePath np ON np.NodeId = n.Id AND np.Deleted = 0 AND np.IsActive = 1 + JOIN hierarchy.NodeVersion nv ON nv.NodeId = np.CatalogueNodeId AND nv.VersionStatusId = 2 AND nv.Deleted = 0 + JOIN hierarchy.CatalogueNodeVersion cnv ON cnv.NodeVersionId = nv.Id AND cnv.Deleted = 0 + LEFT JOIN hub.UserBookmark ub ON ub.UserId = @UserId AND ub.ResourceReferenceId = (SELECT TOP 1 rr.OriginalResourceReferenceId + FROM [resources].[ResourceReference] rr + JOIN hierarchy.NodePath np on np.id = rr.NodePathId and np.NodeId = n.Id and np.Deleted = 0 + WHERE rr.ResourceId = rv.ResourceId AND rr.Deleted = 0) + LEFT JOIN ( SELECT DISTINCT CatalogueNodeId + FROM [hub].[RoleUserGroupView] rug JOIN hub.UserUserGroup uug ON rug.UserGroupId = uug.UserGroupId + WHERE rug.ScopeTypeId = 1 and rug.RoleId in (1,2,3) and uug.Deleted = 0 and uug.UserId = @userId) auth ON n.Id = auth.CatalogueNodeId + WHERE rv.VersionStatusId = 2 + ORDER BY tr.ResourceActivityCount DESC, rv.Title + OFFSET @OffsetRows ROWS + FETCH NEXT @FetchRows ROWS ONLY + + SELECT @TotalRecords = CASE WHEN COUNT(*) > 12 THEN @MaxRows ELSE COUNT(*) END FROM @Resources + +END \ No newline at end of file diff --git a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetRatedDashboardResources.sql b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetRatedDashboardResources.sql new file mode 100644 index 000000000..2e2539044 --- /dev/null +++ b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetRatedDashboardResources.sql @@ -0,0 +1,86 @@ +------------------------------------------------------------------------------- +-- Author OA +-- Created 24 JUN 2024 Nov 2020 +-- Purpose Break down the GetDashboardResources SP to smaller SP for a specific data type +-- +-- Modification History +-- +-- 24 Jun 2024 OA Initial Revision +------------------------------------------------------------------------------- + +CREATE PROCEDURE [resources].[GetRatedDashboardResources] + @UserId INT, + @PageNumber INT = 1, + @TotalRecords INT OUTPUT +AS +BEGIN + DECLARE @MaxPageNumber INT = 4 + + IF @PageNumber > 4 + BEGIN + SET @PageNumber = @MaxPageNumber + END + + DECLARE @FetchRows INT = 3 + DECLARE @MaxRows INT = @MaxPageNUmber * @FetchRows + DECLARE @OffsetRows INT = (@PageNumber - 1) * @FetchRows + + DECLARE @MyActivity TABLE (ResourceId [int] NOT NULL PRIMARY KEY, ResourceActivityId [int] NOT NULL); + DECLARE @Resources TABLE (ResourceId [int] NOT NULL PRIMARY KEY, ResourceActivityCount [int] NOT NULL); + + + SELECT TOP(@MaxRows) r.Id AS ResourceId + ,( SELECT TOP 1 rr.OriginalResourceReferenceId + FROM [resources].[ResourceReference] rr + JOIN hierarchy.NodePath np on np.id = rr.NodePathId and np.NodeId = n.Id and np.Deleted = 0 + WHERE rr.ResourceId = rv.ResourceId AND rr.Deleted = 0 + ) AS ResourceReferenceID + ,r.CurrentResourceVersionId AS ResourceVersionId + ,r.ResourceTypeId AS ResourceTypeId + ,rv.Title + ,rv.Description + ,CASE + WHEN r.ResourceTypeId = 7 THEN + (SELECT vrv.DurationInMilliseconds from [resources].[VideoResourceVersion] vrv WHERE vrv.[ResourceVersionId] = r.CurrentResourceVersionId) + WHEN r.ResourceTypeId = 2 THEN + (SELECT vrv.DurationInMilliseconds from [resources].[AudioResourceVersion] vrv WHERE vrv.[ResourceVersionId] = r.CurrentResourceVersionId) + ELSE + NULL + END AS DurationInMilliseconds + ,CASE WHEN n.id = 1 THEN NULL ELSE cnv.Name END AS CatalogueName + ,cnv.Url AS Url + ,CASE WHEN n.id = 1 THEN NULL ELSE cnv.BadgeUrl END AS BadgeUrl + ,cnv.RestrictedAccess + ,CAST(CASE WHEN cnv.RestrictedAccess = 1 AND auth.CatalogueNodeId IS NULL THEN 0 ELSE 1 END AS bit) AS HasAccess + ,ub.Id AS BookMarkId + ,CAST(ISNULL(ub.[Deleted], 1) ^ 1 AS BIT) AS IsBookmarked + ,rvrs.AverageRating + ,rvrs.RatingCount + INTO #ratedresources + FROM Resources.Resource r + JOIN resources.resourceversion rv ON rv.ResourceId = r.Id AND rv.id = r.CurrentResourceVersionId AND rv.Deleted = 0 + JOIN resources.ResourceVersionRatingSummary rvrs ON r.CurrentResourceVersionId = rvrs.ResourceVersionId AND rvrs.RatingCount > 0 + JOIN hierarchy.NodeResource nr ON r.Id = nr.ResourceId AND nr.Deleted = 0 + JOIN hierarchy.Node n ON n.Id = nr.NodeId AND n.Hidden = 0 AND n.Deleted = 0 + JOIN hierarchy.NodePath np ON np.NodeId = n.Id AND np.Deleted = 0 AND np.IsActive = 1 + JOIN hierarchy.NodeVersion nv ON nv.NodeId = np.CatalogueNodeId AND nv.VersionStatusId = 2 AND nv.Deleted = 0 + JOIN hierarchy.CatalogueNodeVersion cnv ON cnv.NodeVersionId = nv.Id AND cnv.Deleted = 0 + LEFT JOIN hub.UserBookmark ub ON ub.UserId = @UserId AND ub.ResourceReferenceId = (SELECT TOP 1 rr.OriginalResourceReferenceId + FROM [resources].[ResourceReference] rr + JOIN hierarchy.NodePath np on np.id = rr.NodePathId and np.NodeId = n.Id and np.Deleted = 0 + WHERE rr.ResourceId = rv.ResourceId AND rr.Deleted = 0) + LEFT JOIN ( SELECT DISTINCT CatalogueNodeId + FROM [hub].[RoleUserGroupView] rug JOIN hub.UserUserGroup uug ON rug.UserGroupId = uug.UserGroupId + WHERE rug.ScopeTypeId = 1 and rug.RoleId in (1,2,3) and uug.Deleted = 0 and uug.UserId = @userId) auth ON n.Id = auth.CatalogueNodeId + WHERE rv.VersionStatusId = 2 + ORDER BY rvrs.AverageRating DESC, rvrs.RatingCount DESC, rv.Title + + SELECT rr.* FROM #ratedresources rr + ORDER BY rr.AverageRating DESC, rr.RatingCount DESC, rr.Title + OFFSET @OffsetRows ROWS + FETCH NEXT @FetchRows ROWS ONLY + + SELECT @TotalRecords = CASE WHEN COUNT(*) > 12 THEN @MaxRows ELSE COUNT(*) END FROM #ratedresources + + +END \ No newline at end of file diff --git a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetRecentDashboardResources.sql b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetRecentDashboardResources.sql new file mode 100644 index 000000000..8aa063b42 --- /dev/null +++ b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetRecentDashboardResources.sql @@ -0,0 +1,84 @@ +------------------------------------------------------------------------------- +-- Author OA +-- Created 24 JUN 2024 Nov 2020 +-- Purpose Break down the GetDashboardResources SP to smaller SP for a specific data type +-- +-- Modification History +-- +-- 24 Jun 2024 OA Initial Revision +------------------------------------------------------------------------------- + +CREATE PROCEDURE [resources].[GetRecentDashboardResources] + @UserId INT, + @PageNumber INT = 1, + @TotalRecords INT OUTPUT +AS +BEGIN + DECLARE @MaxPageNumber INT = 4 + + IF @PageNumber > 4 + BEGIN + SET @PageNumber = @MaxPageNumber + END + + DECLARE @FetchRows INT = 3 + DECLARE @MaxRows INT = @MaxPageNUmber * @FetchRows + DECLARE @OffsetRows INT = (@PageNumber - 1) * @FetchRows + + DECLARE @MyActivity TABLE (ResourceId [int] NOT NULL PRIMARY KEY, ResourceActivityId [int] NOT NULL); + DECLARE @Resources TABLE (ResourceId [int] NOT NULL PRIMARY KEY, ResourceActivityCount [int] NOT NULL); + + SELECT TOP(@MaxRows) r.Id AS ResourceId + ,( SELECT TOP 1 rr.OriginalResourceReferenceId + FROM [resources].[ResourceReference] rr + JOIN hierarchy.NodePath np on np.id = rr.NodePathId and np.NodeId = n.Id and np.Deleted = 0 + WHERE rr.ResourceId = rv.ResourceId AND rr.Deleted = 0 + ) AS ResourceReferenceID + ,r.CurrentResourceVersionId AS ResourceVersionId + ,r.ResourceTypeId AS ResourceTypeId + ,rv.Title + ,rv.Description + ,CASE + WHEN r.ResourceTypeId = 7 THEN + (SELECT vrv.DurationInMilliseconds from [resources].[VideoResourceVersion] vrv WHERE vrv.[ResourceVersionId] = r.CurrentResourceVersionId) + WHEN r.ResourceTypeId = 2 THEN + (SELECT vrv.DurationInMilliseconds from [resources].[AudioResourceVersion] vrv WHERE vrv.[ResourceVersionId] = r.CurrentResourceVersionId) + ELSE + NULL + END AS DurationInMilliseconds + ,CASE WHEN n.id = 1 THEN NULL ELSE cnv.Name END AS CatalogueName + ,cnv.Url AS Url + ,CASE WHEN n.id = 1 THEN NULL ELSE cnv.BadgeUrl END AS BadgeUrl + ,cnv.RestrictedAccess + ,CAST(CASE WHEN cnv.RestrictedAccess = 1 AND auth.CatalogueNodeId IS NULL THEN 0 ELSE 1 END AS bit) AS HasAccess + ,ub.Id AS BookMarkId + ,CAST(ISNULL(ub.[Deleted], 1) ^ 1 AS BIT) AS IsBookmarked + ,rvrs.AverageRating + ,rvrs.RatingCount + INTO #recentresources + FROM Resources.Resource r + JOIN resources.resourceversion rv ON rv.ResourceId = r.Id AND rv.id = r.CurrentResourceVersionId AND rv.Deleted = 0 + JOIN hierarchy.Publication p ON rv.PublicationId = p.Id AND p.Deleted = 0 + JOIN resources.ResourceVersionRatingSummary rvrs ON rv.Id = rvrs.ResourceVersionId AND rvrs.Deleted = 0 + JOIN hierarchy.NodeResource nr ON r.Id = nr.ResourceId AND nr.Deleted = 0 + JOIN hierarchy.Node n ON n.Id = nr.NodeId AND n.Hidden = 0 AND n.Deleted = 0 + JOIN hierarchy.NodePath np ON np.NodeId = n.Id AND np.Deleted = 0 AND np.IsActive = 1 + JOIN hierarchy.NodeVersion nv ON nv.NodeId = np.CatalogueNodeId AND nv.VersionStatusId = 2 AND nv.Deleted = 0 + JOIN hierarchy.CatalogueNodeVersion cnv ON cnv.NodeVersionId = nv.Id AND cnv.Deleted = 0 + LEFT JOIN hub.UserBookmark ub ON ub.UserId = @UserId AND ub.ResourceReferenceId = (SELECT TOP 1 rr.OriginalResourceReferenceId + FROM [resources].[ResourceReference] rr + JOIN hierarchy.NodePath np on np.id = rr.NodePathId and np.NodeId = n.Id and np.Deleted = 0 + WHERE rr.ResourceId = rv.ResourceId AND rr.Deleted = 0) + LEFT JOIN ( SELECT DISTINCT CatalogueNodeId + FROM [hub].[RoleUserGroupView] rug JOIN hub.UserUserGroup uug ON rug.UserGroupId = uug.UserGroupId + WHERE rug.ScopeTypeId = 1 and rug.RoleId in (1,2,3) and uug.Deleted = 0 and uug.UserId = @userId) auth ON n.Id = auth.CatalogueNodeId + WHERE rv.VersionStatusId = 2 + ORDER BY p.CreateDate DESC + + SELECT rr.* FROM #recentresources rr + ORDER BY rr.ResourceVersionId DESC + OFFSET @OffsetRows ROWS + FETCH NEXT @FetchRows ROWS ONLY + + SELECT @TotalRecords = CASE WHEN COUNT(*) > 12 THEN @MaxRows ELSE COUNT(*) END FROM #recentresources +END \ No newline at end of file diff --git a/WebAPI/LearningHub.Nhs.Repository/Resources/ResourceVersionRepository.cs b/WebAPI/LearningHub.Nhs.Repository/Resources/ResourceVersionRepository.cs index 10bf4cddf..48d7bc0df 100644 --- a/WebAPI/LearningHub.Nhs.Repository/Resources/ResourceVersionRepository.cs +++ b/WebAPI/LearningHub.Nhs.Repository/Resources/ResourceVersionRepository.cs @@ -639,14 +639,34 @@ public List GetContributions(int userId, ResourceContri /// resources. public (int resourceCount, List resources) GetResources(string dashboardType, int pageNumber, int userId) { - var param0 = new SqlParameter("@dashboardType", SqlDbType.NVarChar, 30) { Value = dashboardType }; - var param1 = new SqlParameter("@userId", SqlDbType.Int) { Value = userId }; - var param2 = new SqlParameter("@pageNumber", SqlDbType.Int) { Value = pageNumber }; - var param3 = new SqlParameter("@totalRows", SqlDbType.Int) { Direction = ParameterDirection.Output }; + var param0 = new SqlParameter("@userId", SqlDbType.Int) { Value = userId }; + var param1 = new SqlParameter("@pageNumber", SqlDbType.Int) { Value = pageNumber }; + var param2 = new SqlParameter("@totalRows", SqlDbType.Int) { Direction = ParameterDirection.Output }; - var dashboardResources = this.DbContext.DashboardResourceDto.FromSqlRaw("resources.GetDashboardResources @dashboardType, @userId, @pageNumber, @totalRows output", param0, param1, param2, param3).ToList(); + var dashboardResources = new List(); + switch (dashboardType) + { + case "my-certificates": + dashboardResources = this.DbContext.DashboardResourceDto.FromSqlRaw("resources.GetMyCertificatesDashboardResources @userId, @pageNumber, @totalRows output", param0, param1, param2).ToList(); + break; + case "my-recent-completed": + dashboardResources = this.DbContext.DashboardResourceDto.FromSqlRaw("resources.GetMyRecentCompletedDashboardResources @userId, @pageNumber, @totalRows output", param0, param1, param2).ToList(); + break; + case "my-in-progress": + dashboardResources = this.DbContext.DashboardResourceDto.FromSqlRaw("resources.GetMyInProgressDashboardResources @userId, @pageNumber, @totalRows output", param0, param1, param2).ToList(); + break; + case "recent-resources": + dashboardResources = this.DbContext.DashboardResourceDto.FromSqlRaw("resources.GetRecentDashboardResources @userId, @pageNumber, @totalRows output", param0, param1, param2).ToList(); + break; + case "rated-resources": + dashboardResources = this.DbContext.DashboardResourceDto.FromSqlRaw("resources.GetRatedDashboardResources @userId, @pageNumber, @totalRows output", param0, param1, param2).ToList(); + break; + case "popular-resources": + dashboardResources = this.DbContext.DashboardResourceDto.FromSqlRaw("resources.GetPopularDashboardResources @userId, @pageNumber, @totalRows output", param0, param1, param2).ToList(); + break; + } - return (resourceCount: (int)param3.Value, resources: dashboardResources); + return (resourceCount: (int)param2.Value, resources: dashboardResources); } /// diff --git a/WebAPI/LearningHub.Nhs.Services/ResourceService.cs b/WebAPI/LearningHub.Nhs.Services/ResourceService.cs index 1d2469e88..808bd8448 100644 --- a/WebAPI/LearningHub.Nhs.Services/ResourceService.cs +++ b/WebAPI/LearningHub.Nhs.Services/ResourceService.cs @@ -1434,6 +1434,7 @@ where deletableCaseFiles.Contains(entry) { retVal.Add(scormResource?.File?.FilePath); } + break; case ResourceTypeEnum.Html: var htmlResource = await this.GetHtmlDetailsByIdAsync(resourceVersionId); From 2bb7a7b16b347b6fa1101251155ad17d79cff444 Mon Sep 17 00:00:00 2001 From: Oluwatobi Awe Date: Wed, 26 Jun 2024 12:31:23 +0100 Subject: [PATCH 3/9] removed manual Index for dashboard SP --- .../LearningHub.Nhs.Database.sqlproj | 1 - .../Scripts/TD-4271_Dasboard_Index.sql | 18 ------------------ 2 files changed, 19 deletions(-) delete mode 100644 WebAPI/LearningHub.Nhs.Database/Scripts/Pre-Deploy/Scripts/TD-4271_Dasboard_Index.sql diff --git a/WebAPI/LearningHub.Nhs.Database/LearningHub.Nhs.Database.sqlproj b/WebAPI/LearningHub.Nhs.Database/LearningHub.Nhs.Database.sqlproj index 78a7f9aa2..13479c06e 100644 --- a/WebAPI/LearningHub.Nhs.Database/LearningHub.Nhs.Database.sqlproj +++ b/WebAPI/LearningHub.Nhs.Database/LearningHub.Nhs.Database.sqlproj @@ -520,7 +520,6 @@ - diff --git a/WebAPI/LearningHub.Nhs.Database/Scripts/Pre-Deploy/Scripts/TD-4271_Dasboard_Index.sql b/WebAPI/LearningHub.Nhs.Database/Scripts/Pre-Deploy/Scripts/TD-4271_Dasboard_Index.sql deleted file mode 100644 index fa8cbe9a3..000000000 --- a/WebAPI/LearningHub.Nhs.Database/Scripts/Pre-Deploy/Scripts/TD-4271_Dasboard_Index.sql +++ /dev/null @@ -1,18 +0,0 @@ - -CREATE INDEX IX_Resource_CurrentResourceVersionId ON resources.Resource (CurrentResourceVersionId) -GO ------------------------------- -CREATE INDEX IX_Resource_ResourceTypeId ON resources.Resource (ResourceTypeId) -GO ------------------------------- -CREATE INDEX IX_ResourceVersion_ResourceId ON resources.ResourceVersion (ResourceId) -GO ------------------------------ -CREATE INDEX IX_ResourceActivity_UserId_ActivityStatusId ON activity.ResourceActivity (UserId, ActivityStatusId) -GO -------------------------------- -CREATE INDEX IX_NodePath_CatalogueNodeId_Deleted ON hierarchy.NodePath (CatalogueNodeId, Deleted) -GO -------------------------------- -CREATE INDEX IX_UserBookmark_UserId_ResourceReferenceId_Deleted ON hub.UserBookmark (UserId, ResourceReferenceId, Deleted) -GO From a18bdda4fdbee5048fc5218c46455ba18b554f4d Mon Sep 17 00:00:00 2001 From: Oluwatobi Awe Date: Thu, 27 Jun 2024 09:06:01 +0100 Subject: [PATCH 4/9] TD-4270 Archive Log Db --- .../LearningHub.Nhs.Database.sqlproj | 1 + .../Scripts/TD-4270_Archive_LogDb.sql | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 WebAPI/LearningHub.Nhs.Database/Scripts/Post-Deploy/Scripts/TD-4270_Archive_LogDb.sql diff --git a/WebAPI/LearningHub.Nhs.Database/LearningHub.Nhs.Database.sqlproj b/WebAPI/LearningHub.Nhs.Database/LearningHub.Nhs.Database.sqlproj index 2613eb68c..ff5bcd5aa 100644 --- a/WebAPI/LearningHub.Nhs.Database/LearningHub.Nhs.Database.sqlproj +++ b/WebAPI/LearningHub.Nhs.Database/LearningHub.Nhs.Database.sqlproj @@ -514,6 +514,7 @@ + diff --git a/WebAPI/LearningHub.Nhs.Database/Scripts/Post-Deploy/Scripts/TD-4270_Archive_LogDb.sql b/WebAPI/LearningHub.Nhs.Database/Scripts/Post-Deploy/Scripts/TD-4270_Archive_LogDb.sql new file mode 100644 index 000000000..9272b0f02 --- /dev/null +++ b/WebAPI/LearningHub.Nhs.Database/Scripts/Post-Deploy/Scripts/TD-4270_Archive_LogDb.sql @@ -0,0 +1,21 @@ +-- Define the date 6 months ago +DECLARE @SixMonthsAgo DATE = DATEADD(MONTH, -6, GETDATE()); + + +IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'LogArchive' AND schema_id = SCHEMA_ID('hub')) +BEGIN + SELECT TOP (0) * + INTO hub.LogArchive + FROM hub.Log; +END + + +INSERT INTO hub.LogArchive ([Application], [Logged], [Level], [Message], [Logger], [Callsite], [Exception], [UserId], [Username]) +SELECT [Application], [Logged], [Level], [Message], [Logger], [Callsite], [Exception], [UserId], [Username] +FROM hub.Log +WHERE [Logged] < @SixMonthsAgo; + + +DELETE FROM hub.Log WHERE [Logged] < @SixMonthsAgo; + + From 465f1f5db2eed49c919bee9a7a04312fcdb33242 Mon Sep 17 00:00:00 2001 From: Oluwatobi Awe Date: Thu, 27 Jun 2024 11:31:38 +0100 Subject: [PATCH 5/9] TD-4273 cache RoleUserGroupDetailForUser data --- .../Services/UserGroupService.cs | 44 +++++++++++-------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/LearningHub.Nhs.WebUI/Services/UserGroupService.cs b/LearningHub.Nhs.WebUI/Services/UserGroupService.cs index ae5b4dd80..6790a3143 100644 --- a/LearningHub.Nhs.WebUI/Services/UserGroupService.cs +++ b/LearningHub.Nhs.WebUI/Services/UserGroupService.cs @@ -51,12 +51,34 @@ public async Task> GetRoleUserGroupDetailAsync() /// public async Task> GetRoleUserGroupDetailForUserAsync(int userId) + { + var cacheKey = $"{userId}:AllRolesWithPermissions"; + return await this.cacheService.GetOrFetchAsync(cacheKey, () => this.FetchRoleUserGroupDetailForUserAsync(userId)); + } + + /// + public async Task UserHasPermissionAsync(string permissionCode) + { + var userGroupsTask = this.GetRoleUserGroupDetailAsync(); + var rolesTask = this.roleService.GetRolesAsync(); + + await Task.WhenAll(userGroupsTask, rolesTask); + + var userRoles = userGroupsTask.Result.Select(t => t.RoleId).Distinct(); + + return rolesTask.Result + .Where(r => userRoles.Contains(r.RoleId)) + .SelectMany(r => r.Permissions) + .Any(p => p == permissionCode); + } + + private async Task> FetchRoleUserGroupDetailAsync() { List viewmodel = null; var client = await this.LearningHubHttpClient.GetClientAsync(); - var request = $"UserGroup/GetUserGroupRoleDetailByUserId/{userId}"; + var request = $"UserGroup/GetUserGroupRoleDetail"; var response = await client.GetAsync(request).ConfigureAwait(false); if (response.IsSuccessStatusCode) @@ -74,29 +96,13 @@ public async Task> GetRoleUserGroupDetailForUserAsy return viewmodel; } - /// - public async Task UserHasPermissionAsync(string permissionCode) - { - var userGroupsTask = this.GetRoleUserGroupDetailAsync(); - var rolesTask = this.roleService.GetRolesAsync(); - - await Task.WhenAll(userGroupsTask, rolesTask); - - var userRoles = userGroupsTask.Result.Select(t => t.RoleId).Distinct(); - - return rolesTask.Result - .Where(r => userRoles.Contains(r.RoleId)) - .SelectMany(r => r.Permissions) - .Any(p => p == permissionCode); - } - - private async Task> FetchRoleUserGroupDetailAsync() + private async Task> FetchRoleUserGroupDetailForUserAsync(int userId) { List viewmodel = null; var client = await this.LearningHubHttpClient.GetClientAsync(); - var request = $"UserGroup/GetUserGroupRoleDetail"; + var request = $"UserGroup/GetUserGroupRoleDetailByUserId/{userId}"; var response = await client.GetAsync(request).ConfigureAwait(false); if (response.IsSuccessStatusCode) From f069fc2a5d3c4e293bb3d3ec9eb100a58a598b2d Mon Sep 17 00:00:00 2001 From: Oluwatobi Awe Date: Thu, 27 Jun 2024 11:36:11 +0100 Subject: [PATCH 6/9] LogDb script update --- .../Scripts/Post-Deploy/Scripts/TD-4270_Archive_LogDb.sql | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/WebAPI/LearningHub.Nhs.Database/Scripts/Post-Deploy/Scripts/TD-4270_Archive_LogDb.sql b/WebAPI/LearningHub.Nhs.Database/Scripts/Post-Deploy/Scripts/TD-4270_Archive_LogDb.sql index 9272b0f02..f7f1a1caf 100644 --- a/WebAPI/LearningHub.Nhs.Database/Scripts/Post-Deploy/Scripts/TD-4270_Archive_LogDb.sql +++ b/WebAPI/LearningHub.Nhs.Database/Scripts/Post-Deploy/Scripts/TD-4270_Archive_LogDb.sql @@ -1,5 +1,7 @@ -- Define the date 6 months ago -DECLARE @SixMonthsAgo DATE = DATEADD(MONTH, -6, GETDATE()); +DECLARE @SixMonthsAgo DATE; +SET @SixMonthsAgo = DATEADD(MONTH, -6, GETDATE()); +GO IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'LogArchive' AND schema_id = SCHEMA_ID('hub')) @@ -8,14 +10,17 @@ BEGIN INTO hub.LogArchive FROM hub.Log; END +GO INSERT INTO hub.LogArchive ([Application], [Logged], [Level], [Message], [Logger], [Callsite], [Exception], [UserId], [Username]) SELECT [Application], [Logged], [Level], [Message], [Logger], [Callsite], [Exception], [UserId], [Username] FROM hub.Log WHERE [Logged] < @SixMonthsAgo; +GO DELETE FROM hub.Log WHERE [Logged] < @SixMonthsAgo; +GO From 164e4e23da9a78475b82c7b9cc107497481b9474 Mon Sep 17 00:00:00 2001 From: Swapnamol Abraham Date: Thu, 27 Jun 2024 12:58:20 +0100 Subject: [PATCH 7/9] TD-4285: My Learning Dashboard Tray showing Wrong Counts --- .../Hub/RoleUserGroupGetByUserGroupId.sql | 1 + .../Hub/RoleUserGroupGetByUserId.sql | 1 + .../GetMyInProgressDashboardResources.sql | 21 ++++++++++++++++++- .../Views/RoleUserGroupView.sql | 1 + .../LearningHubDbContext.cs | 2 -- 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Hub/RoleUserGroupGetByUserGroupId.sql b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Hub/RoleUserGroupGetByUserGroupId.sql index bcfc1aa4e..4f65b529c 100644 --- a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Hub/RoleUserGroupGetByUserGroupId.sql +++ b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Hub/RoleUserGroupGetByUserGroupId.sql @@ -18,6 +18,7 @@ AS BEGIN SELECT + CAST([Sequence] AS int) AS [Key], RoleUserGroupId, UserGroupId, UserGroupName, diff --git a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Hub/RoleUserGroupGetByUserId.sql b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Hub/RoleUserGroupGetByUserId.sql index ff05f806c..09b16949d 100644 --- a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Hub/RoleUserGroupGetByUserId.sql +++ b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Hub/RoleUserGroupGetByUserId.sql @@ -18,6 +18,7 @@ AS BEGIN SELECT + CAST([Sequence] AS int) AS [Key], RoleUserGroupId, rug.UserGroupId, UserGroupName, diff --git a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetMyInProgressDashboardResources.sql b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetMyInProgressDashboardResources.sql index 22709e898..350a4f4f6 100644 --- a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetMyInProgressDashboardResources.sql +++ b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetMyInProgressDashboardResources.sql @@ -6,6 +6,7 @@ -- Modification History -- -- 24 Jun 2024 OA Initial Revision +-- 27 Jun 2024 SA My Learning Dashboard Tray showing Wrong Counts ------------------------------------------------------------------------------- CREATE PROCEDURE [resources].[GetMyInProgressDashboardResources] @@ -100,6 +101,24 @@ BEGIN OFFSET @OffsetRows ROWS FETCH NEXT @FetchRows ROWS ONLY - SELECT @TotalRecords = CASE WHEN COUNT(*) > 12 THEN @MaxRows ELSE COUNT(*) END FROM @MyActivity + SELECT @TotalRecords = CASE WHEN COUNT(ma.ResourceActivityId) > 12 THEN @MaxRows ELSE COUNT(*) END + FROM @MyActivity ma + JOIN activity.ResourceActivity ra ON ra.id = ma.ResourceActivityId + JOIN resources.resourceversion rv ON rv.id = ra.ResourceVersionId AND rv.Deleted = 0 + JOIN Resources.Resource r ON r.Id = rv.ResourceId + JOIN hierarchy.Publication p ON rv.PublicationId = p.Id AND p.Deleted = 0 + JOIN resources.ResourceVersionRatingSummary rvrs ON rv.Id = rvrs.ResourceVersionId AND rvrs.Deleted = 0 + JOIN hierarchy.NodeResource nr ON r.Id = nr.ResourceId AND nr.Deleted = 0 + JOIN hierarchy.Node n ON n.Id = nr.NodeId AND n.Hidden = 0 AND n.Deleted = 0 + JOIN hierarchy.NodePath np ON np.NodeId = n.Id AND np.Deleted = 0 AND np.IsActive = 1 + JOIN hierarchy.NodeVersion nv ON nv.NodeId = np.CatalogueNodeId AND nv.VersionStatusId = 2 AND nv.Deleted = 0 + JOIN hierarchy.CatalogueNodeVersion cnv ON cnv.NodeVersionId = nv.Id AND cnv.Deleted = 0 + LEFT JOIN hub.UserBookmark ub ON ub.UserId = @UserId AND ub.ResourceReferenceId = (SELECT TOP 1 rr.OriginalResourceReferenceId + FROM [resources].[ResourceReference] rr + JOIN hierarchy.NodePath np on np.id = rr.NodePathId and np.NodeId = n.Id and np.Deleted = 0 + WHERE rr.ResourceId = rv.ResourceId AND rr.Deleted = 0) + LEFT JOIN ( SELECT DISTINCT CatalogueNodeId + FROM [hub].[RoleUserGroupView] rug JOIN hub.UserUserGroup uug ON rug.UserGroupId = uug.UserGroupId + WHERE rug.ScopeTypeId = 1 and rug.RoleId in (1,2,3) and uug.Deleted = 0 and uug.UserId = @userId) auth ON n.Id = auth.CatalogueNodeId END \ No newline at end of file diff --git a/WebAPI/LearningHub.Nhs.Database/Views/RoleUserGroupView.sql b/WebAPI/LearningHub.Nhs.Database/Views/RoleUserGroupView.sql index f6dac03ec..b76083d5f 100644 --- a/WebAPI/LearningHub.Nhs.Database/Views/RoleUserGroupView.sql +++ b/WebAPI/LearningHub.Nhs.Database/Views/RoleUserGroupView.sql @@ -14,6 +14,7 @@ CREATE VIEW [hub].[RoleUserGroupView] AS SELECT + ROW_NUMBER() OVER(ORDER BY rug.Id) AS [Sequence], rug.Id AS RoleUserGroupId, ug.Id AS UserGroupId, ug.[Name] AS UserGroupName, diff --git a/WebAPI/LearningHub.Nhs.Repository/LearningHubDbContext.cs b/WebAPI/LearningHub.Nhs.Repository/LearningHubDbContext.cs index 8d685dbd1..ef4775cd8 100644 --- a/WebAPI/LearningHub.Nhs.Repository/LearningHubDbContext.cs +++ b/WebAPI/LearningHub.Nhs.Repository/LearningHubDbContext.cs @@ -782,8 +782,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) { mapping.Map(modelBuilder); } - - modelBuilder.Entity().HasNoKey(); } } } From 6e62d21a287c38e7290f9bbeff0db4850a00be4d Mon Sep 17 00:00:00 2001 From: Swapnamol Abraham Date: Thu, 27 Jun 2024 14:03:06 +0100 Subject: [PATCH 8/9] Removed unused temp tables --- .../GetMyInProgressDashboardResources.sql | 4 +--- ...GetMyRecentCompletedDashboardResources.sql | 22 +++++++++++++++++-- .../GetPopularDashboardResources.sql | 2 +- .../Resources/GetRatedDashboardResources.sql | 5 +---- .../Resources/GetRecentDashboardResources.sql | 4 +--- 5 files changed, 24 insertions(+), 13 deletions(-) diff --git a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetMyInProgressDashboardResources.sql b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetMyInProgressDashboardResources.sql index 350a4f4f6..7464de6e3 100644 --- a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetMyInProgressDashboardResources.sql +++ b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetMyInProgressDashboardResources.sql @@ -26,9 +26,7 @@ BEGIN DECLARE @MaxRows INT = @MaxPageNUmber * @FetchRows DECLARE @OffsetRows INT = (@PageNumber - 1) * @FetchRows - DECLARE @MyActivity TABLE (ResourceId [int] NOT NULL PRIMARY KEY, ResourceActivityId [int] NOT NULL); - DECLARE @Resources TABLE (ResourceId [int] NOT NULL PRIMARY KEY, ResourceActivityCount [int] NOT NULL); - + DECLARE @MyActivity TABLE (ResourceId [int] NOT NULL PRIMARY KEY, ResourceActivityId [int] NOT NULL); INSERT INTO @MyActivity SELECT TOP (@MaxRows) ra.ResourceId, MAX(ra.Id) ResourceActivityId diff --git a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetMyRecentCompletedDashboardResources.sql b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetMyRecentCompletedDashboardResources.sql index 686ef7efe..cb12b2a10 100644 --- a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetMyRecentCompletedDashboardResources.sql +++ b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetMyRecentCompletedDashboardResources.sql @@ -6,6 +6,7 @@ -- Modification History -- -- 24 Jun 2024 OA Initial Revision +-- 27 Jun 2024 SA Removed unused temp tables ------------------------------------------------------------------------------- CREATE PROCEDURE [resources].[GetMyRecentCompletedDashboardResources] @@ -26,7 +27,6 @@ BEGIN DECLARE @OffsetRows INT = (@PageNumber - 1) * @FetchRows DECLARE @MyActivity TABLE (ResourceId [int] NOT NULL PRIMARY KEY, ResourceActivityId [int] NOT NULL); - DECLARE @Resources TABLE (ResourceId [int] NOT NULL PRIMARY KEY, ResourceActivityCount [int] NOT NULL); INSERT INTO @MyActivity SELECT TOP (@MaxRows) ra.ResourceId, MAX(ra.Id) ResourceActivityId @@ -96,6 +96,24 @@ ORDER BY ma.ResourceActivityId DESC, rv.Title OFFSET @OffsetRows ROWS FETCH NEXT @FetchRows ROWS ONLY - SELECT @TotalRecords = CASE WHEN COUNT(*) > 12 THEN @MaxRows ELSE COUNT(*) END FROM @MyActivity +SELECT @TotalRecords = CASE WHEN COUNT(ma.ResourceActivityId) > 12 THEN @MaxRows ELSE COUNT(*) END +FROM @MyActivity ma +JOIN activity.ResourceActivity ra ON ra.id = ma.ResourceActivityId +JOIN resources.resourceversion rv ON rv.id = ra.ResourceVersionId AND rv.Deleted = 0 +JOIN Resources.Resource r ON r.Id = rv.ResourceId +JOIN hierarchy.Publication p ON rv.PublicationId = p.Id AND p.Deleted = 0 +JOIN resources.ResourceVersionRatingSummary rvrs ON rv.Id = rvrs.ResourceVersionId AND rvrs.Deleted = 0 +JOIN hierarchy.NodeResource nr ON r.Id = nr.ResourceId AND nr.Deleted = 0 +JOIN hierarchy.Node n ON n.Id = nr.NodeId AND n.Hidden = 0 AND n.Deleted = 0 +JOIN hierarchy.NodePath np ON np.NodeId = n.Id AND np.Deleted = 0 AND np.IsActive = 1 +JOIN hierarchy.NodeVersion nv ON nv.NodeId = np.CatalogueNodeId AND nv.VersionStatusId = 2 AND nv.Deleted = 0 +JOIN hierarchy.CatalogueNodeVersion cnv ON cnv.NodeVersionId = nv.Id AND cnv.Deleted = 0 +LEFT JOIN hub.UserBookmark ub ON ub.UserId = @UserId AND ub.ResourceReferenceId = (SELECT TOP 1 rr.OriginalResourceReferenceId + FROM [resources].[ResourceReference] rr + JOIN hierarchy.NodePath np on np.id = rr.NodePathId and np.NodeId = n.Id and np.Deleted = 0 + WHERE rr.ResourceId = rv.ResourceId AND rr.Deleted = 0) +LEFT JOIN ( SELECT DISTINCT CatalogueNodeId + FROM [hub].[RoleUserGroupView] rug JOIN hub.UserUserGroup uug ON rug.UserGroupId = uug.UserGroupId + WHERE rug.ScopeTypeId = 1 and rug.RoleId in (1,2,3) and uug.Deleted = 0 and uug.UserId = @userId) auth ON n.Id = auth.CatalogueNodeId END \ No newline at end of file diff --git a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetPopularDashboardResources.sql b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetPopularDashboardResources.sql index f35761471..c9904f0fc 100644 --- a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetPopularDashboardResources.sql +++ b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetPopularDashboardResources.sql @@ -6,6 +6,7 @@ -- Modification History -- -- 24 Jun 2024 OA Initial Revision +-- 27 Jun 2024 SA Removed unused temp tables ------------------------------------------------------------------------------- CREATE PROCEDURE [resources].[GetPopularDashboardResources] @@ -25,7 +26,6 @@ BEGIN DECLARE @MaxRows INT = @MaxPageNUmber * @FetchRows DECLARE @OffsetRows INT = (@PageNumber - 1) * @FetchRows - DECLARE @MyActivity TABLE (ResourceId [int] NOT NULL PRIMARY KEY, ResourceActivityId [int] NOT NULL); DECLARE @Resources TABLE (ResourceId [int] NOT NULL PRIMARY KEY, ResourceActivityCount [int] NOT NULL); diff --git a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetRatedDashboardResources.sql b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetRatedDashboardResources.sql index 2e2539044..56b994092 100644 --- a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetRatedDashboardResources.sql +++ b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetRatedDashboardResources.sql @@ -6,6 +6,7 @@ -- Modification History -- -- 24 Jun 2024 OA Initial Revision +-- 27 Jun 2024 SA Removed unused temp tables ------------------------------------------------------------------------------- CREATE PROCEDURE [resources].[GetRatedDashboardResources] @@ -25,10 +26,6 @@ BEGIN DECLARE @MaxRows INT = @MaxPageNUmber * @FetchRows DECLARE @OffsetRows INT = (@PageNumber - 1) * @FetchRows - DECLARE @MyActivity TABLE (ResourceId [int] NOT NULL PRIMARY KEY, ResourceActivityId [int] NOT NULL); - DECLARE @Resources TABLE (ResourceId [int] NOT NULL PRIMARY KEY, ResourceActivityCount [int] NOT NULL); - - SELECT TOP(@MaxRows) r.Id AS ResourceId ,( SELECT TOP 1 rr.OriginalResourceReferenceId FROM [resources].[ResourceReference] rr diff --git a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetRecentDashboardResources.sql b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetRecentDashboardResources.sql index 8aa063b42..5ba8fdd4a 100644 --- a/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetRecentDashboardResources.sql +++ b/WebAPI/LearningHub.Nhs.Database/Stored Procedures/Resources/GetRecentDashboardResources.sql @@ -6,6 +6,7 @@ -- Modification History -- -- 24 Jun 2024 OA Initial Revision +-- 27 Jun 2024 SA Removed unused temp tables ------------------------------------------------------------------------------- CREATE PROCEDURE [resources].[GetRecentDashboardResources] @@ -25,9 +26,6 @@ BEGIN DECLARE @MaxRows INT = @MaxPageNUmber * @FetchRows DECLARE @OffsetRows INT = (@PageNumber - 1) * @FetchRows - DECLARE @MyActivity TABLE (ResourceId [int] NOT NULL PRIMARY KEY, ResourceActivityId [int] NOT NULL); - DECLARE @Resources TABLE (ResourceId [int] NOT NULL PRIMARY KEY, ResourceActivityCount [int] NOT NULL); - SELECT TOP(@MaxRows) r.Id AS ResourceId ,( SELECT TOP 1 rr.OriginalResourceReferenceId FROM [resources].[ResourceReference] rr From 9565b5798983868b9181ca82f3aeaa5325c9602d Mon Sep 17 00:00:00 2001 From: Oluwatobi Awe Date: Mon, 15 Jul 2024 17:32:35 +0100 Subject: [PATCH 9/9] LH Model update --- AdminUI/LearningHub.Nhs.AdminUI/LearningHub.Nhs.AdminUI.csproj | 2 +- LearningHub.Nhs.WebUI/LearningHub.Nhs.WebUI.csproj | 2 +- WebAPI/LearningHub.Nhs.API/LearningHub.Nhs.Api.csproj | 2 +- .../LearningHub.Nhs.Api.Shared.csproj | 2 +- .../LearningHub.Nhs.Api.UnitTests.csproj | 2 +- .../LearningHub.Nhs.Repository.Interface.csproj | 2 +- .../LearningHub.Nhs.Repository.csproj | 2 +- .../LearningHub.Nhs.Services.Interface.csproj | 2 +- .../LearningHub.Nhs.Services.UnitTests.csproj | 2 +- .../LearningHub.Nhs.Migration.ConsoleApp.csproj | 2 +- .../LearningHub.Nhs.Migration.Interface.csproj | 2 +- .../LearningHub.Nhs.Migration.Models.csproj | 2 +- .../LearningHub.Nhs.Migration.Staging.Repository.csproj | 2 +- .../LearningHub.Nhs.Migration.UnitTests.csproj | 2 +- .../LearningHub.Nhs.Migration/LearningHub.Nhs.Migration.csproj | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/AdminUI/LearningHub.Nhs.AdminUI/LearningHub.Nhs.AdminUI.csproj b/AdminUI/LearningHub.Nhs.AdminUI/LearningHub.Nhs.AdminUI.csproj index 7bef84029..87d033c41 100644 --- a/AdminUI/LearningHub.Nhs.AdminUI/LearningHub.Nhs.AdminUI.csproj +++ b/AdminUI/LearningHub.Nhs.AdminUI/LearningHub.Nhs.AdminUI.csproj @@ -89,7 +89,7 @@ - + diff --git a/LearningHub.Nhs.WebUI/LearningHub.Nhs.WebUI.csproj b/LearningHub.Nhs.WebUI/LearningHub.Nhs.WebUI.csproj index acea5791b..d94046f5e 100644 --- a/LearningHub.Nhs.WebUI/LearningHub.Nhs.WebUI.csproj +++ b/LearningHub.Nhs.WebUI/LearningHub.Nhs.WebUI.csproj @@ -108,7 +108,7 @@ - + diff --git a/WebAPI/LearningHub.Nhs.API/LearningHub.Nhs.Api.csproj b/WebAPI/LearningHub.Nhs.API/LearningHub.Nhs.Api.csproj index 120f41ef6..306a1d96b 100644 --- a/WebAPI/LearningHub.Nhs.API/LearningHub.Nhs.Api.csproj +++ b/WebAPI/LearningHub.Nhs.API/LearningHub.Nhs.Api.csproj @@ -27,7 +27,7 @@ - + diff --git a/WebAPI/LearningHub.Nhs.Api.Shared/LearningHub.Nhs.Api.Shared.csproj b/WebAPI/LearningHub.Nhs.Api.Shared/LearningHub.Nhs.Api.Shared.csproj index 7f4998158..cb4ee1d13 100644 --- a/WebAPI/LearningHub.Nhs.Api.Shared/LearningHub.Nhs.Api.Shared.csproj +++ b/WebAPI/LearningHub.Nhs.Api.Shared/LearningHub.Nhs.Api.Shared.csproj @@ -9,7 +9,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/WebAPI/LearningHub.Nhs.Api.UnitTests/LearningHub.Nhs.Api.UnitTests.csproj b/WebAPI/LearningHub.Nhs.Api.UnitTests/LearningHub.Nhs.Api.UnitTests.csproj index 9cbb1fe4e..fcb18f40b 100644 --- a/WebAPI/LearningHub.Nhs.Api.UnitTests/LearningHub.Nhs.Api.UnitTests.csproj +++ b/WebAPI/LearningHub.Nhs.Api.UnitTests/LearningHub.Nhs.Api.UnitTests.csproj @@ -11,7 +11,7 @@ - + diff --git a/WebAPI/LearningHub.Nhs.Repository.Interface/LearningHub.Nhs.Repository.Interface.csproj b/WebAPI/LearningHub.Nhs.Repository.Interface/LearningHub.Nhs.Repository.Interface.csproj index 3793e6980..265a6732b 100644 --- a/WebAPI/LearningHub.Nhs.Repository.Interface/LearningHub.Nhs.Repository.Interface.csproj +++ b/WebAPI/LearningHub.Nhs.Repository.Interface/LearningHub.Nhs.Repository.Interface.csproj @@ -9,7 +9,7 @@ - + diff --git a/WebAPI/LearningHub.Nhs.Repository/LearningHub.Nhs.Repository.csproj b/WebAPI/LearningHub.Nhs.Repository/LearningHub.Nhs.Repository.csproj index 073c1995f..dcae43e50 100644 --- a/WebAPI/LearningHub.Nhs.Repository/LearningHub.Nhs.Repository.csproj +++ b/WebAPI/LearningHub.Nhs.Repository/LearningHub.Nhs.Repository.csproj @@ -9,7 +9,7 @@ - + diff --git a/WebAPI/LearningHub.Nhs.Services.Interface/LearningHub.Nhs.Services.Interface.csproj b/WebAPI/LearningHub.Nhs.Services.Interface/LearningHub.Nhs.Services.Interface.csproj index e40618911..805eb0bf0 100644 --- a/WebAPI/LearningHub.Nhs.Services.Interface/LearningHub.Nhs.Services.Interface.csproj +++ b/WebAPI/LearningHub.Nhs.Services.Interface/LearningHub.Nhs.Services.Interface.csproj @@ -16,7 +16,7 @@ - + all diff --git a/WebAPI/LearningHub.Nhs.Services.UnitTests/LearningHub.Nhs.Services.UnitTests.csproj b/WebAPI/LearningHub.Nhs.Services.UnitTests/LearningHub.Nhs.Services.UnitTests.csproj index 58581b46c..bd60bf209 100644 --- a/WebAPI/LearningHub.Nhs.Services.UnitTests/LearningHub.Nhs.Services.UnitTests.csproj +++ b/WebAPI/LearningHub.Nhs.Services.UnitTests/LearningHub.Nhs.Services.UnitTests.csproj @@ -13,7 +13,7 @@ - + diff --git a/WebAPI/MigrationTool/LearningHub.Nhs.Migration.ConsoleApp/LearningHub.Nhs.Migration.ConsoleApp.csproj b/WebAPI/MigrationTool/LearningHub.Nhs.Migration.ConsoleApp/LearningHub.Nhs.Migration.ConsoleApp.csproj index 588f60cd9..114fef270 100644 --- a/WebAPI/MigrationTool/LearningHub.Nhs.Migration.ConsoleApp/LearningHub.Nhs.Migration.ConsoleApp.csproj +++ b/WebAPI/MigrationTool/LearningHub.Nhs.Migration.ConsoleApp/LearningHub.Nhs.Migration.ConsoleApp.csproj @@ -24,7 +24,7 @@ - + all diff --git a/WebAPI/MigrationTool/LearningHub.Nhs.Migration.Interface/LearningHub.Nhs.Migration.Interface.csproj b/WebAPI/MigrationTool/LearningHub.Nhs.Migration.Interface/LearningHub.Nhs.Migration.Interface.csproj index df3a5bef3..e864135b8 100644 --- a/WebAPI/MigrationTool/LearningHub.Nhs.Migration.Interface/LearningHub.Nhs.Migration.Interface.csproj +++ b/WebAPI/MigrationTool/LearningHub.Nhs.Migration.Interface/LearningHub.Nhs.Migration.Interface.csproj @@ -9,7 +9,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/WebAPI/MigrationTool/LearningHub.Nhs.Migration.Models/LearningHub.Nhs.Migration.Models.csproj b/WebAPI/MigrationTool/LearningHub.Nhs.Migration.Models/LearningHub.Nhs.Migration.Models.csproj index 27645a969..a19a496c8 100644 --- a/WebAPI/MigrationTool/LearningHub.Nhs.Migration.Models/LearningHub.Nhs.Migration.Models.csproj +++ b/WebAPI/MigrationTool/LearningHub.Nhs.Migration.Models/LearningHub.Nhs.Migration.Models.csproj @@ -10,7 +10,7 @@ - + all diff --git a/WebAPI/MigrationTool/LearningHub.Nhs.Migration.Staging.Repository/LearningHub.Nhs.Migration.Staging.Repository.csproj b/WebAPI/MigrationTool/LearningHub.Nhs.Migration.Staging.Repository/LearningHub.Nhs.Migration.Staging.Repository.csproj index 3cb7eb534..e969bef6b 100644 --- a/WebAPI/MigrationTool/LearningHub.Nhs.Migration.Staging.Repository/LearningHub.Nhs.Migration.Staging.Repository.csproj +++ b/WebAPI/MigrationTool/LearningHub.Nhs.Migration.Staging.Repository/LearningHub.Nhs.Migration.Staging.Repository.csproj @@ -9,7 +9,7 @@ - + diff --git a/WebAPI/MigrationTool/LearningHub.Nhs.Migration.UnitTests/LearningHub.Nhs.Migration.UnitTests.csproj b/WebAPI/MigrationTool/LearningHub.Nhs.Migration.UnitTests/LearningHub.Nhs.Migration.UnitTests.csproj index 1d70a4338..a700f45a8 100644 --- a/WebAPI/MigrationTool/LearningHub.Nhs.Migration.UnitTests/LearningHub.Nhs.Migration.UnitTests.csproj +++ b/WebAPI/MigrationTool/LearningHub.Nhs.Migration.UnitTests/LearningHub.Nhs.Migration.UnitTests.csproj @@ -10,7 +10,7 @@ - + diff --git a/WebAPI/MigrationTool/LearningHub.Nhs.Migration/LearningHub.Nhs.Migration.csproj b/WebAPI/MigrationTool/LearningHub.Nhs.Migration/LearningHub.Nhs.Migration.csproj index c9abd00e0..3a3ab4459 100644 --- a/WebAPI/MigrationTool/LearningHub.Nhs.Migration/LearningHub.Nhs.Migration.csproj +++ b/WebAPI/MigrationTool/LearningHub.Nhs.Migration/LearningHub.Nhs.Migration.csproj @@ -12,7 +12,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive