From 87125043769bd9140901670370cc22ef859209e0 Mon Sep 17 00:00:00 2001 From: VictorHugoDuranS Date: Fri, 10 Jan 2025 15:35:41 -0600 Subject: [PATCH] Fix for User profile (/profile): only 20 group memberships shown instead of all (#3105) * Add - groups paginated on profile page * Add - groups paginated on profile page * Add - groups paginated on profile page * Add - groups paginated on profile page * Fix UPDATE - Add pagination message error and loader * Update BRANCH * Fix - LINT ERRORS * Fix: Error declaring variable for group pagination * Fix: Remove unnecessary translations for paging groups * Fix: Lint erros * Fix: Remove unnecessary translations --------- Co-authored-by: VictorDuranEscire --- .../profile-page/profile-page.component.html | 30 ++++++++++++---- .../profile-page.component.spec.ts | 8 +++++ .../profile-page/profile-page.component.ts | 34 ++++++++++++++++++- src/assets/i18n/en.json5 | 2 ++ .../profile-page/profile-page.component.ts | 6 ++++ 5 files changed, 72 insertions(+), 8 deletions(-) diff --git a/src/app/profile-page/profile-page.component.html b/src/app/profile-page/profile-page.component.html index 3dc7c9d4891..d56c4b10f3c 100644 --- a/src/app/profile-page/profile-page.component.html +++ b/src/app/profile-page/profile-page.component.html @@ -33,13 +33,29 @@

{{'profile.title' | translate}}

- -
-

{{'profile.groups.head' | translate}}

-
    -
  • {{ dsoNameService.getName(group) }}
  • -
-
+ + + + + +
+

{{ 'profile.groups.head' | translate }}

+
    +
  • {{ dsoNameService.getName(group) }}
  • +
+
+
+
+
+ + + +
diff --git a/src/app/profile-page/profile-page.component.spec.ts b/src/app/profile-page/profile-page.component.spec.ts index 82a0a9d67b9..ebd3939432c 100644 --- a/src/app/profile-page/profile-page.component.spec.ts +++ b/src/app/profile-page/profile-page.component.spec.ts @@ -1,3 +1,4 @@ +import { NgTemplateOutlet } from '@angular/common'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, @@ -29,7 +30,10 @@ import { EPersonDataService } from '../core/eperson/eperson-data.service'; import { EPerson } from '../core/eperson/models/eperson.model'; import { ConfigurationProperty } from '../core/shared/configuration-property.model'; import { SuggestionsNotificationComponent } from '../notifications/suggestions-notification/suggestions-notification.component'; +import { ErrorComponent } from '../shared/error/error.component'; +import { ThemedLoadingComponent } from '../shared/loading/themed-loading.component'; import { NotificationsService } from '../shared/notifications/notifications.service'; +import { PaginationComponent } from '../shared/pagination/pagination.component'; import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$, @@ -134,6 +138,10 @@ describe('ProfilePageComponent', () => { ProfilePageSecurityFormComponent, ProfilePageResearcherFormComponent, SuggestionsNotificationComponent, + NgTemplateOutlet, + PaginationComponent, + ThemedLoadingComponent, + ErrorComponent, ], }, }) diff --git a/src/app/profile-page/profile-page.component.ts b/src/app/profile-page/profile-page.component.ts index 75760105e0d..a8ac070e702 100644 --- a/src/app/profile-page/profile-page.component.ts +++ b/src/app/profile-page/profile-page.component.ts @@ -2,6 +2,7 @@ import { AsyncPipe, NgForOf, NgIf, + NgTemplateOutlet, } from '@angular/common'; import { Component, @@ -33,8 +34,10 @@ import { RemoteData } from '../core/data/remote-data'; import { EPersonDataService } from '../core/eperson/eperson-data.service'; import { EPerson } from '../core/eperson/models/eperson.model'; import { Group } from '../core/eperson/models/group.model'; +import { PaginationService } from '../core/pagination/pagination.service'; import { ConfigurationProperty } from '../core/shared/configuration-property.model'; import { + getAllCompletedRemoteData, getAllSucceededRemoteData, getFirstCompletedRemoteData, getRemoteDataPayload, @@ -44,7 +47,11 @@ import { hasValue, isNotEmpty, } from '../shared/empty.util'; +import { ErrorComponent } from '../shared/error/error.component'; +import { ThemedLoadingComponent } from '../shared/loading/themed-loading.component'; import { NotificationsService } from '../shared/notifications/notifications.service'; +import { PaginationComponent } from '../shared/pagination/pagination.component'; +import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model'; import { followLink } from '../shared/utils/follow-link-config.model'; import { VarDirective } from '../shared/utils/var.directive'; import { ThemedProfilePageMetadataFormComponent } from './profile-page-metadata-form/themed-profile-page-metadata-form.component'; @@ -65,6 +72,10 @@ import { ProfilePageSecurityFormComponent } from './profile-page-security-form/p NgIf, NgForOf, SuggestionsNotificationComponent, + NgTemplateOutlet, + PaginationComponent, + ThemedLoadingComponent, + ErrorComponent, ], standalone: true, }) @@ -122,6 +133,15 @@ export class ProfilePageComponent implements OnInit { private currentUser: EPerson; canChangePassword$: Observable; + /** + * Default configuration for group pagination + **/ + optionsGroupsPagination = Object.assign(new PaginationComponentOptions(),{ + id: 'page_groups', + currentPage: 1, + pageSize: 20, + }); + isResearcherProfileEnabled$: BehaviorSubject = new BehaviorSubject(false); constructor(private authService: AuthService, @@ -131,6 +151,7 @@ export class ProfilePageComponent implements OnInit { private authorizationService: AuthorizationDataService, private configurationService: ConfigurationDataService, public dsoNameService: DSONameService, + private paginationService: PaginationService, ) { } @@ -142,7 +163,18 @@ export class ProfilePageComponent implements OnInit { getRemoteDataPayload(), tap((user: EPerson) => this.currentUser = user), ); - this.groupsRD$ = this.user$.pipe(switchMap((user: EPerson) => user.groups)); + this.groupsRD$ = this.paginationService.getCurrentPagination(this.optionsGroupsPagination.id, this.optionsGroupsPagination).pipe( + switchMap((pageOptions: PaginationComponentOptions) => { + return this.epersonService.findById(this.currentUser.id, true, true, followLink('groups',{ + findListOptions: { + elementsPerPage: pageOptions.pageSize, + currentPage: pageOptions.currentPage, + } })); + }), + getAllCompletedRemoteData(), + getRemoteDataPayload(), + switchMap((user: EPerson) => user?.groups), + ); this.canChangePassword$ = this.user$.pipe(switchMap((user: EPerson) => this.authorizationService.isAuthorized(FeatureID.CanChangePassword, user._links.self.href))); this.specialGroupsRD$ = this.authService.getSpecialGroupsFromAuthStatus(); diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index ee9844070ee..7d07f070ec3 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1852,6 +1852,8 @@ "error.recent-submissions": "Error fetching recent submissions", + "error.profile-groups": "Error retrieving profile groups", + "error.search-results": "Error fetching search results", "error.invalid-search-query": "Search query is not valid. Please check Solr query syntax best practices for further information about this error.", diff --git a/src/themes/custom/app/profile-page/profile-page.component.ts b/src/themes/custom/app/profile-page/profile-page.component.ts index 74a88fdba63..e810ca09daf 100644 --- a/src/themes/custom/app/profile-page/profile-page.component.ts +++ b/src/themes/custom/app/profile-page/profile-page.component.ts @@ -11,6 +11,9 @@ import { ProfilePageComponent as BaseComponent } from '../../../../app/profile-p import { ThemedProfilePageMetadataFormComponent } from '../../../../app/profile-page/profile-page-metadata-form/themed-profile-page-metadata-form.component'; import { ProfilePageResearcherFormComponent } from '../../../../app/profile-page/profile-page-researcher-form/profile-page-researcher-form.component'; import { ProfilePageSecurityFormComponent } from '../../../../app/profile-page/profile-page-security-form/profile-page-security-form.component'; +import { ErrorComponent } from '../../../../app/shared/error/error.component'; +import { ThemedLoadingComponent } from '../../../../app/shared/loading/themed-loading.component'; +import { PaginationComponent } from '../../../../app/shared/pagination/pagination.component'; import { VarDirective } from '../../../../app/shared/utils/var.directive'; @Component({ @@ -30,6 +33,9 @@ import { VarDirective } from '../../../../app/shared/utils/var.directive'; NgIf, NgForOf, SuggestionsNotificationComponent, + PaginationComponent, + ThemedLoadingComponent, + ErrorComponent, ], }) /**