From 67036b126176c85bf308eb6c36d06754d1a58168 Mon Sep 17 00:00:00 2001 From: matthieuaudemard Date: Fri, 5 May 2023 13:30:42 +0200 Subject: [PATCH] feat: [community/profiles] ajoute un badge sur la side bar (#308) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ajoute un badge sur le lien vers les profils ayant effectué une demande de relation --- .../profile/controller/ProfileController.java | 9 ++- .../repository/ProfileRepositoryCustom.java | 1 + .../impl/ProfileRepositoryCustomImpl.java | 56 +++++++++++-------- .../dto/enums/RelationCriteriaEnum.java | 4 +- .../profile/service/ProfileService.java | 4 ++ .../controller/ProfileControllerTest.java | 4 ++ .../profile/service/ProfileServiceTest.java | 8 +-- .../src/app/app-routing.module.ts | 2 +- .../app/community/community-routing.module.ts | 12 ---- .../models/enums/profile-menu-enum.ts | 19 +++++++ .../community/models/enums/relation-action.ts | 10 +--- .../models/enums/relation-criteria-enum.ts | 3 - .../profile-list-page.component.ts | 47 ++++++++-------- .../services/profile/profile.service.ts | 8 ++- .../core/services/api-endpoints.service.ts | 8 ++- .../sidemenu/sidemenu.component.html | 2 + .../sidemenu/sidemenu.component.scss | 6 ++ .../enums/enum-code-label-abstract.enum.ts | 4 +- .../src/app/shared/models/uris.ts | 1 + 19 files changed, 128 insertions(+), 80 deletions(-) create mode 100644 frontend-implicaction/src/app/community/models/enums/profile-menu-enum.ts delete mode 100644 frontend-implicaction/src/app/community/models/enums/relation-criteria-enum.ts diff --git a/backend-implicaction/src/main/java/com/dynonuggets/refonteimplicaction/community/profile/controller/ProfileController.java b/backend-implicaction/src/main/java/com/dynonuggets/refonteimplicaction/community/profile/controller/ProfileController.java index 8420f736f..0fe3133b9 100644 --- a/backend-implicaction/src/main/java/com/dynonuggets/refonteimplicaction/community/profile/controller/ProfileController.java +++ b/backend-implicaction/src/main/java/com/dynonuggets/refonteimplicaction/community/profile/controller/ProfileController.java @@ -1,5 +1,6 @@ package com.dynonuggets.refonteimplicaction.community.profile.controller; +import com.dynonuggets.refonteimplicaction.auth.service.AuthService; import com.dynonuggets.refonteimplicaction.community.profile.dto.ProfileDto; import com.dynonuggets.refonteimplicaction.community.profile.dto.ProfileUpdateRequest; import com.dynonuggets.refonteimplicaction.community.profile.dto.enums.RelationCriteriaEnum; @@ -25,6 +26,7 @@ public class ProfileController { private final ProfileService profileService; + private final AuthService authService; @GetMapping @ResponseBody @@ -33,7 +35,7 @@ public ResponseEntity> getAllProfiles( @RequestParam(defaultValue = "10") final int rows, @RequestParam(value = "sortBy", defaultValue = "id") final String[] sortBy, @RequestParam(value = "sortOrder", defaultValue = "ASC") final String sortOrder, - @RequestParam(value = "relationCriteria", defaultValue = "ANY") final RelationCriteriaEnum relationCriteria + @RequestParam(value = "relationCriteria", defaultValue = "ALL") final RelationCriteriaEnum relationCriteria ) { final Pageable pageable = PageRequest.of(page, rows, Sort.by(Sort.Direction.valueOf(sortOrder), sortBy)); return ResponseEntity.ok(profileService.getAllProfiles(relationCriteria, pageable)); @@ -53,4 +55,9 @@ public ResponseEntity getProfileByUsername(@PathVariable final Strin public ResponseEntity postProfileAvatar(@RequestParam final MultipartFile file, @PathVariable final String username) { return ResponseEntity.ok(profileService.uploadAvatar(file, username)); } + + @GetMapping("/friend-requests/count") + public Long getCountFriendRequestsByUsername() { + return profileService.countFriendRequestsByUsername(authService.getCurrentUser().getUsername()); + } } diff --git a/backend-implicaction/src/main/java/com/dynonuggets/refonteimplicaction/community/profile/domain/repository/ProfileRepositoryCustom.java b/backend-implicaction/src/main/java/com/dynonuggets/refonteimplicaction/community/profile/domain/repository/ProfileRepositoryCustom.java index b361d718d..78032686a 100644 --- a/backend-implicaction/src/main/java/com/dynonuggets/refonteimplicaction/community/profile/domain/repository/ProfileRepositoryCustom.java +++ b/backend-implicaction/src/main/java/com/dynonuggets/refonteimplicaction/community/profile/domain/repository/ProfileRepositoryCustom.java @@ -9,4 +9,5 @@ public interface ProfileRepositoryCustom { Page findAllProfilesWithRelationTypeCriteria(final String username, final RelationCriteriaEnum relationCriteria, final Pageable pageable); + Long countFriendRequestsByUsername(String username); } diff --git a/backend-implicaction/src/main/java/com/dynonuggets/refonteimplicaction/community/profile/domain/repository/impl/ProfileRepositoryCustomImpl.java b/backend-implicaction/src/main/java/com/dynonuggets/refonteimplicaction/community/profile/domain/repository/impl/ProfileRepositoryCustomImpl.java index f17e04243..031b2402b 100644 --- a/backend-implicaction/src/main/java/com/dynonuggets/refonteimplicaction/community/profile/domain/repository/impl/ProfileRepositoryCustomImpl.java +++ b/backend-implicaction/src/main/java/com/dynonuggets/refonteimplicaction/community/profile/domain/repository/impl/ProfileRepositoryCustomImpl.java @@ -4,11 +4,11 @@ import com.dynonuggets.refonteimplicaction.community.profile.domain.repository.ProfileRepositoryCustom; import com.dynonuggets.refonteimplicaction.community.profile.dto.enums.RelationCriteriaEnum; import com.dynonuggets.refonteimplicaction.community.relation.domain.model.RelationModel; -import com.dynonuggets.refonteimplicaction.job.company.domain.model.CompanyModel; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.support.PageableExecutionUtils; +import org.springframework.transaction.annotation.Transactional; import javax.persistence.EntityManager; import javax.persistence.criteria.*; @@ -23,38 +23,58 @@ public class ProfileRepositoryCustomImpl implements ProfileRepositoryCustom { private final EntityManager entityManager; /** - * @param username nom de l'utilisateur courant + * @param username nom de l’utilisateur courant * @param relationCriteria type de relation. * @param pageable options de pagination * @return
    - *
  • {@link ANY} retourne tous profils qu'ils soient en relation ou non avec l'utilisateur courant à l'exception de l'utilisateur courant
  • - *
  • {@link ALL_FRIENDS} retourne toutes les relations confirmées de l'utilisateur (en tant que sender ou receiver) à l'exception de l'utilisateur courant
  • - *
  • {@link ONLY_FRIEND_REQUESTS} retourne seulement les profiles qui ont effectué une demande de relation avec l'utilisateur courant à l'exception de l'utilisateur courant
  • + *
  • {@link RelationCriteriaEnum#ALL} retourne tous profils qu'ils soient en relation ou non avec l'utilisateur courant à l'exception de l'utilisateur courant
  • + *
  • {@link RelationCriteriaEnum#ALL_FRIENDS} retourne toutes les relations confirmées de l'utilisateur (en tant que sender ou receiver) à l'exception de l'utilisateur courant
  • + *
  • {@link RelationCriteriaEnum#ONLY_FRIEND_REQUESTS} retourne seulement les profiles qui ont effectué une demande de relation avec l'utilisateur courant à l'exception de l'utilisateur courant
  • */ @Override public Page findAllProfilesWithRelationTypeCriteria(final String username, final RelationCriteriaEnum relationCriteria, final Pageable pageable) { final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); final CriteriaQuery query = builder.createQuery(ProfileModel.class); - final Root p = query.from(ProfileModel.class); - final List queryPredicates = new ArrayList<>(); + final Predicate[] queryPredicates = generateFilterPredicates(username, relationCriteria, query); + + query.where(queryPredicates); + + final CriteriaQuery countQuery = builder.createQuery(Long.class).where(queryPredicates); + countQuery.select(builder.count(countQuery.from(ProfileModel.class))); + final List profileModels = entityManager.createQuery(query) + .setFirstResult(pageable.getPageNumber() * pageable.getPageSize()) + .getResultList(); + + return PageableExecutionUtils.getPage(profileModels, pageable, () -> entityManager.createQuery(countQuery).getSingleResult()); + } + + @Override + @Transactional(readOnly = true) + public Long countFriendRequestsByUsername(final String username) { + return findAllProfilesWithRelationTypeCriteria(username, ONLY_FRIEND_REQUESTS, Pageable.ofSize(Integer.MAX_VALUE)).getTotalElements(); + } - queryPredicates.add(builder.isTrue(p.get("user").get("enabled"))); - queryPredicates.add(builder.notEqual(p.get("user").get("username"), username)); + private Predicate[] generateFilterPredicates(final String username, final RelationCriteriaEnum relationCriteria, final CriteriaQuery query) { + final Root p = query.from(ProfileModel.class); + final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + final List queryPredicates = new ArrayList<>() {{ + add(builder.isTrue(p.get("user").get("enabled"))); + add(builder.notEqual(p.get("user").get("username"), username)); + }}; if (List.of(ALL_FRIENDS, ONLY_FRIEND_REQUESTS).contains(relationCriteria)) { final Subquery subQuery = query.subquery(Integer.class); final Root r = subQuery.from(RelationModel.class); - // l'utilisateur doit être à la cible d'une invitation (receiver) + // l'utilisateur doit être à la cible d’une invitation (receiver) Predicate relationPredicate = builder.and(builder.equal(r.get("receiver").get("user").get("username"), username), builder.equal(r.get("sender"), p)); - // si l'on veut remonter toutes les relatons de l'utilisateur, il faut aussi récupérer les profils pour lesquels il est à l'origine d'une relation + // si l’on veut remonter toutes les relatons de l’utilisateur, il faut aussi récupérer les profils pour lesquels il est à l’origine d’une relation if (relationCriteria == ALL_FRIENDS) { final Predicate isSender = builder.and(builder.equal(r.get("sender").get("user").get("username"), username), builder.equal(r.get("receiver"), p)); relationPredicate = builder.or(relationPredicate, isSender); } - // si 2 utilisateurs sont amis, alors la relation a été confirmée, sinon non final Predicate confirmedPredicate = relationCriteria == ALL_FRIENDS ? builder.isNotNull(r.get("confirmedAt")) : builder.isNull(r.get("confirmedAt")); @@ -65,15 +85,7 @@ public Page findAllProfilesWithRelationTypeCriteria(final String u queryPredicates.add(builder.exists(subQuery)); } - - query.where(queryPredicates.toArray(Predicate[]::new)); - - final CriteriaQuery countQuery = builder.createQuery(Long.class).where(queryPredicates.toArray(Predicate[]::new)); - countQuery.select(builder.count(countQuery.from(CompanyModel.class))); - final List profileModels = entityManager.createQuery(query) - .setFirstResult(pageable.getPageNumber() * pageable.getPageSize()) - .getResultList(); - - return PageableExecutionUtils.getPage(profileModels, pageable, () -> entityManager.createQuery(countQuery).getSingleResult()); + return queryPredicates.toArray(Predicate[]::new); } + } diff --git a/backend-implicaction/src/main/java/com/dynonuggets/refonteimplicaction/community/profile/dto/enums/RelationCriteriaEnum.java b/backend-implicaction/src/main/java/com/dynonuggets/refonteimplicaction/community/profile/dto/enums/RelationCriteriaEnum.java index b48849cbb..19b45a46b 100644 --- a/backend-implicaction/src/main/java/com/dynonuggets/refonteimplicaction/community/profile/dto/enums/RelationCriteriaEnum.java +++ b/backend-implicaction/src/main/java/com/dynonuggets/refonteimplicaction/community/profile/dto/enums/RelationCriteriaEnum.java @@ -1,5 +1,7 @@ package com.dynonuggets.refonteimplicaction.community.profile.dto.enums; public enum RelationCriteriaEnum { - ANY, ALL_FRIENDS, ONLY_FRIEND_REQUESTS + ALL, + ALL_FRIENDS, + ONLY_FRIEND_REQUESTS } diff --git a/backend-implicaction/src/main/java/com/dynonuggets/refonteimplicaction/community/profile/service/ProfileService.java b/backend-implicaction/src/main/java/com/dynonuggets/refonteimplicaction/community/profile/service/ProfileService.java index 20270aac1..d74f9fb9c 100644 --- a/backend-implicaction/src/main/java/com/dynonuggets/refonteimplicaction/community/profile/service/ProfileService.java +++ b/backend-implicaction/src/main/java/com/dynonuggets/refonteimplicaction/community/profile/service/ProfileService.java @@ -104,6 +104,10 @@ public Page getAllProfiles(final RelationCriteriaEnum relationCriter }); } + public Long countFriendRequestsByUsername(final String username) { + return profileRepository.countFriendRequestsByUsername(username); + } + /** * Renvoie le profil s’il existe, sinon, si l’utilisateur existe, le profil est créé * diff --git a/backend-implicaction/src/test/java/com/dynonuggets/refonteimplicaction/community/profile/controller/ProfileControllerTest.java b/backend-implicaction/src/test/java/com/dynonuggets/refonteimplicaction/community/profile/controller/ProfileControllerTest.java index 66f3a7eea..ddfd0f124 100644 --- a/backend-implicaction/src/test/java/com/dynonuggets/refonteimplicaction/community/profile/controller/ProfileControllerTest.java +++ b/backend-implicaction/src/test/java/com/dynonuggets/refonteimplicaction/community/profile/controller/ProfileControllerTest.java @@ -1,5 +1,6 @@ package com.dynonuggets.refonteimplicaction.community.profile.controller; +import com.dynonuggets.refonteimplicaction.auth.service.AuthService; import com.dynonuggets.refonteimplicaction.community.profile.dto.ProfileDto; import com.dynonuggets.refonteimplicaction.community.profile.dto.ProfileUpdateRequest; import com.dynonuggets.refonteimplicaction.community.profile.dto.enums.RelationCriteriaEnum; @@ -51,6 +52,9 @@ class ProfileControllerTest extends ControllerIntegrationTestBase { @Getter protected String baseUri = PROFILES_BASE_URI; + @MockBean + AuthService authService; + @MockBean ProfileService profileService; diff --git a/backend-implicaction/src/test/java/com/dynonuggets/refonteimplicaction/community/profile/service/ProfileServiceTest.java b/backend-implicaction/src/test/java/com/dynonuggets/refonteimplicaction/community/profile/service/ProfileServiceTest.java index 9e7ec0845..11c35712f 100644 --- a/backend-implicaction/src/test/java/com/dynonuggets/refonteimplicaction/community/profile/service/ProfileServiceTest.java +++ b/backend-implicaction/src/test/java/com/dynonuggets/refonteimplicaction/community/profile/service/ProfileServiceTest.java @@ -263,19 +263,19 @@ void should_get_all_profiles_when_getAllProfiles() { final UserModel currentUser = generateRandomUserModel(); final Pageable pageable = Pageable.ofSize(10); final List usernames = profileModels.stream().map(p -> p.getUser().getUsername()).collect(Collectors.toList()); - + given(authService.getCurrentUser()).willReturn(currentUser); - given(profileRepository.findAllProfilesWithRelationTypeCriteria(currentUser.getUsername(), RelationCriteriaEnum.ANY, pageable)).willReturn(profiles); + given(profileRepository.findAllProfilesWithRelationTypeCriteria(currentUser.getUsername(), RelationCriteriaEnum.ALL, pageable)).willReturn(profiles); given(relationRepository.findAllRelationByUsernameWhereUserListAreSenderOrReceiver(currentUser.getUsername(), usernames)).willReturn(of()); profiles.forEach(p -> given(profileMapper.toDtoLight(p)).willReturn(ProfileDto.builder().username(p.getUser().getUsername()).build())); // when - final Page result = profileService.getAllProfiles(RelationCriteriaEnum.ANY, pageable); + final Page result = profileService.getAllProfiles(RelationCriteriaEnum.ALL, pageable); // then final int size = profiles.getSize(); assertThat(result).hasSize(size); - verify(profileRepository, times(1)).findAllProfilesWithRelationTypeCriteria(currentUser.getUsername(), RelationCriteriaEnum.ANY, pageable); + verify(profileRepository, times(1)).findAllProfilesWithRelationTypeCriteria(currentUser.getUsername(), RelationCriteriaEnum.ALL, pageable); verify(profileMapper, times(size)).toDtoLight(any()); } diff --git a/frontend-implicaction/src/app/app-routing.module.ts b/frontend-implicaction/src/app/app-routing.module.ts index ab91de6f6..df2b16d9e 100644 --- a/frontend-implicaction/src/app/app-routing.module.ts +++ b/frontend-implicaction/src/app/app-routing.module.ts @@ -8,7 +8,7 @@ import {UnauthorizedPageComponent} from './auth/pages/unauthorized-page/unauthor const routes: Routes = [ { - path: 'auth', + path: Univers.AUTH.url, loadChildren: () => import('./auth/auth.module').then(m => m.AuthModule) }, { diff --git a/frontend-implicaction/src/app/community/community-routing.module.ts b/frontend-implicaction/src/app/community/community-routing.module.ts index fa420e869..4be5cbe16 100644 --- a/frontend-implicaction/src/app/community/community-routing.module.ts +++ b/frontend-implicaction/src/app/community/community-routing.module.ts @@ -4,18 +4,6 @@ import {ProfileListPageComponent} from "./pages/profile-list-page/profile-list-p import {ProfileDetailsPageComponent} from "./pages/profile-details-page/profile-details-page.component"; const routes: Routes = [ - { - path: 'relations/received', - component: ProfileListPageComponent, - }, - { - path: 'relations/sent', - component: ProfileListPageComponent, - }, - { - path: 'relations', - component: ProfileListPageComponent, - }, { path: 'profiles/:username', component: ProfileDetailsPageComponent diff --git a/frontend-implicaction/src/app/community/models/enums/profile-menu-enum.ts b/frontend-implicaction/src/app/community/models/enums/profile-menu-enum.ts new file mode 100644 index 000000000..dadb4a46f --- /dev/null +++ b/frontend-implicaction/src/app/community/models/enums/profile-menu-enum.ts @@ -0,0 +1,19 @@ +import {EnumCodeLabelAbstract} from "../../../shared/enums/enum-code-label-abstract.enum"; +import {Univers} from "../../../shared/enums/univers"; + +export enum ProfileMenuCode { + ALL = 'ALL', + ALL_FRIENDS = 'ALL_FRIENDS', + ONLY_FRIEND_REQUESTS = 'ONLY_FRIEND_REQUESTS' +} + +export class ProfileMenuEnum extends EnumCodeLabelAbstract { + + static readonly ALL = new ProfileMenuEnum(ProfileMenuCode.ALL, 'Tous les utilisateurs', null, `/${Univers.COMMUNITY.url}/profiles`); + static readonly ALL_FRIENDS = new ProfileMenuEnum(ProfileMenuCode.ALL_FRIENDS, 'Mes amis', null, `/${Univers.COMMUNITY.url}/profiles`); + static readonly ONLY_FRIEND_REQUESTS = new ProfileMenuEnum(ProfileMenuCode.ONLY_FRIEND_REQUESTS, 'Invitations', null, `/${Univers.COMMUNITY.url}/profiles`); + + constructor(readonly code: ProfileMenuCode, readonly label: string, readonly icon: string, readonly url: string) { + super(code, label); + } +} diff --git a/frontend-implicaction/src/app/community/models/enums/relation-action.ts b/frontend-implicaction/src/app/community/models/enums/relation-action.ts index a02557026..ba7021f6a 100644 --- a/frontend-implicaction/src/app/community/models/enums/relation-action.ts +++ b/frontend-implicaction/src/app/community/models/enums/relation-action.ts @@ -1,13 +1,9 @@ -import {Relation} from '../relation'; import {EnumCodeLabelAbstract} from '../../../shared/enums/enum-code-label-abstract.enum'; export enum RelationActionEnumCode { - CREATE = 'CREATE', DELETE = 'DELETE', CONFIRM = 'CONFIRM' -} - -export interface RelationAction { - relation: Relation; - action: RelationActionEnumCode; + CREATE = 'CREATE', + DELETE = 'DELETE', + CONFIRM = 'CONFIRM' } export class RelationActionEnum extends EnumCodeLabelAbstract { diff --git a/frontend-implicaction/src/app/community/models/enums/relation-criteria-enum.ts b/frontend-implicaction/src/app/community/models/enums/relation-criteria-enum.ts deleted file mode 100644 index 1804f4361..000000000 --- a/frontend-implicaction/src/app/community/models/enums/relation-criteria-enum.ts +++ /dev/null @@ -1,3 +0,0 @@ -export enum RelationCriteriaEnum { - ANY = 'ANY', ALL_FRIENDS = 'ALL_FRIENDS', ONLY_FRIEND_REQUESTS = 'ONLY_FRIEND_REQUESTS' -} diff --git a/frontend-implicaction/src/app/community/pages/profile-list-page/profile-list-page.component.ts b/frontend-implicaction/src/app/community/pages/profile-list-page/profile-list-page.component.ts index d19bc3705..ea177bcf2 100644 --- a/frontend-implicaction/src/app/community/pages/profile-list-page/profile-list-page.component.ts +++ b/frontend-implicaction/src/app/community/pages/profile-list-page/profile-list-page.component.ts @@ -14,8 +14,8 @@ import {Constants} from '../../../config/constants'; import {RelationActionEnumCode} from '../../models/enums/relation-action'; import {Relation} from '../../models/relation'; import {Subject} from 'rxjs'; -import {RelationCriteriaEnum} from '../../models/enums/relation-criteria-enum'; import {RelationButton} from '../../models/relation-button'; +import {ProfileMenuCode, ProfileMenuEnum} from "../../models/enums/profile-menu-enum"; @Component({ templateUrl: './profile-list-page.component.html', @@ -30,28 +30,18 @@ export class ProfileListPageComponent implements OnInit, OnDestroy { currentUser: User; action: string; loading = true; - relationTypeCriteria: RelationCriteriaEnum; - menuItems: MenuItem[] = [ - { - label: 'Tous les utilisateurs', - routerLink: `/${Univers.COMMUNITY.url}/profiles`, - routerLinkActiveOptions: {exact: true} - }, - { - label: 'Mes amis', - routerLink: `/${Univers.COMMUNITY.url}/profiles`, - queryParams: {filter: RelationCriteriaEnum.ALL_FRIENDS}, - routerLinkActiveOptions: {exact: true} - }, - { - label: 'Invitations', - routerLink: `/${Univers.COMMUNITY.url}/profiles`, - queryParams: {filter: RelationCriteriaEnum.ONLY_FRIEND_REQUESTS}, - routerLinkActiveOptions: {exact: true} - } - ]; + selectedItemMenuCode: ProfileMenuCode; + menuItems: MenuItem[] = ProfileMenuEnum.values() + .map((item: ProfileMenuEnum) => ({ + id: item.code, + label: item.label, + routerLink: item.url, + queryParams: {filter: item.code}, + routerLinkActiveOptions: {queryParams: 'subset'} + } as MenuItem)); private onDestroySubject = new Subject(); + private onlyFriendRequestMenuItem: MenuItem; constructor( private authService: AuthService, @@ -65,13 +55,20 @@ export class ProfileListPageComponent implements OnInit, OnDestroy { ngOnInit(): void { this.currentUser = this.authService.getPrincipal(); + this.onlyFriendRequestMenuItem = this.menuItems.find(item => item.id === ProfileMenuCode.ONLY_FRIEND_REQUESTS); this.route.queryParams .pipe(takeUntil(this.onDestroySubject)) .subscribe(params => { this.pageable.number = (params.page ?? 1) - 1; - this.relationTypeCriteria = params.filter ?? RelationCriteriaEnum.ANY; + this.selectedItemMenuCode = params.filter ?? ProfileMenuCode.ALL; this.fetchProfiles(); }); + + this.profileService.getProfileRequestAsFriendCount().subscribe(relationCount => { + if (this.onlyFriendRequestMenuItem) { + this.onlyFriendRequestMenuItem.badge = relationCount ? `${relationCount}` : null; + } + }); } trackByUsername = (index: number, item: Profile) => item.username; @@ -130,11 +127,15 @@ export class ProfileListPageComponent implements OnInit, OnDestroy { const index = this.pageable.content.findIndex(p => p.username === profile.username); this.pageable.content.splice(index, 1, {...profile, relationWithCurrentUser}); this.profiles = [...this.pageable.content]; + if (relationWithCurrentUser.confirmedAt) { + const relationCount = +this.onlyFriendRequestMenuItem.badge - 1; + this.onlyFriendRequestMenuItem.badge = relationCount ? `${relationCount}` : null; + } } private fetchProfiles(): void { this.loading = true; - this.profileService.getAllProfiles(this.relationTypeCriteria ?? RelationCriteriaEnum.ANY, this.pageable) + this.profileService.getAllProfiles(this.selectedItemMenuCode ?? ProfileMenuCode.ALL, this.pageable) .pipe( finalize(() => this.loading = false), take(1), diff --git a/frontend-implicaction/src/app/community/services/profile/profile.service.ts b/frontend-implicaction/src/app/community/services/profile/profile.service.ts index f962c8ee0..bf2d15970 100644 --- a/frontend-implicaction/src/app/community/services/profile/profile.service.ts +++ b/frontend-implicaction/src/app/community/services/profile/profile.service.ts @@ -5,7 +5,7 @@ import {HttpClient, HttpEvent, HttpRequest} from '@angular/common/http'; import {ApiEndpointsService} from '../../../core/services/api-endpoints.service'; import {Profile} from '../../models/profile'; import {Pageable} from '../../../shared/models/pageable'; -import {RelationCriteriaEnum} from '../../models/enums/relation-criteria-enum'; +import {ProfileMenuCode} from "../../models/enums/profile-menu-enum"; @Injectable({ providedIn: 'root' @@ -37,7 +37,11 @@ export class ProfileService { return this.http.request(req); } - getAllProfiles(relationCriteria: RelationCriteriaEnum, pageable: Pageable): Observable> { + getAllProfiles(relationCriteria: ProfileMenuCode, pageable: Pageable): Observable> { return this.http.get>(this.apiEndpointsService.getAllProfilesEndpoint(relationCriteria, pageable)); } + + getProfileRequestAsFriendCount(): Observable { + return this.http.get(this.apiEndpointsService.getProfileRequestAsFriendCountEndpoint(), {}); + } } diff --git a/frontend-implicaction/src/app/core/services/api-endpoints.service.ts b/frontend-implicaction/src/app/core/services/api-endpoints.service.ts index 46e3d5889..9de72cc78 100644 --- a/frontend-implicaction/src/app/core/services/api-endpoints.service.ts +++ b/frontend-implicaction/src/app/core/services/api-endpoints.service.ts @@ -10,7 +10,7 @@ import {Response} from '../../forum/model/response'; import {GetCategoriesOptions} from '../../forum/services/category.service'; import {Profile} from '../../community/models/profile'; import {Relation} from '../../community/models/relation'; -import {RelationCriteriaEnum} from '../../community/models/enums/relation-criteria-enum'; +import {ProfileMenuCode} from "../../community/models/enums/profile-menu-enum"; export type QueryStringHandler = (queryStringParameters: QueryStringParameters) => void; export type CreateUrlOptions = { isMockApi?: boolean, queryStringHandler?: QueryStringHandler, pathVariables?: any[] }; @@ -161,7 +161,7 @@ export class ApiEndpointsService { return ApiEndpointsService.createUrl(Uris.PROFILES.BASE_URI); } - getAllProfilesEndpoint(relationCriteria: RelationCriteriaEnum, pageable: Pageable): string { + getAllProfilesEndpoint(relationCriteria: ProfileMenuCode, pageable: Pageable): string { const objectParam = ApiEndpointsService.concatCriteria({relationCriteria}, pageable); return ApiEndpointsService.createUrlWithQueryParameters( Uris.PROFILES.BASE_URI, @@ -170,6 +170,10 @@ export class ApiEndpointsService { ); } + getProfileRequestAsFriendCountEndpoint() { + return ApiEndpointsService.createUrl(Uris.PROFILES.REQUEST_AS_FRIEND_COUNT); + } + getActivateUserEndpoint(username: string): string { return ApiEndpointsService.createUrl(Uris.USERS.ACTIVATE_USER.replace('{username}', username)); } diff --git a/frontend-implicaction/src/app/shared/components/sidemenu/sidemenu.component.html b/frontend-implicaction/src/app/shared/components/sidemenu/sidemenu.component.html index 891095b31..63f24e5aa 100644 --- a/frontend-implicaction/src/app/shared/components/sidemenu/sidemenu.component.html +++ b/frontend-implicaction/src/app/shared/components/sidemenu/sidemenu.component.html @@ -10,6 +10,8 @@ {{menuItem.label}} + + {{menuItem.badge}} diff --git a/frontend-implicaction/src/app/shared/components/sidemenu/sidemenu.component.scss b/frontend-implicaction/src/app/shared/components/sidemenu/sidemenu.component.scss index 8cd980716..3646a3b30 100644 --- a/frontend-implicaction/src/app/shared/components/sidemenu/sidemenu.component.scss +++ b/frontend-implicaction/src/app/shared/components/sidemenu/sidemenu.component.scss @@ -18,8 +18,14 @@ } &:after { + position: absolute; + right: 10px; font-family: FontAwesome; content: "\f054"; } + + .badge { + font-size: 0.9rem; + } } } diff --git a/frontend-implicaction/src/app/shared/enums/enum-code-label-abstract.enum.ts b/frontend-implicaction/src/app/shared/enums/enum-code-label-abstract.enum.ts index 44357ea12..463da1694 100644 --- a/frontend-implicaction/src/app/shared/enums/enum-code-label-abstract.enum.ts +++ b/frontend-implicaction/src/app/shared/enums/enum-code-label-abstract.enum.ts @@ -9,14 +9,14 @@ export class EnumCodeLabelAbstract { /** * @return toutes les valeurs de l'enum */ - protected static values(): U[] { + public static values(): U[] { return Object.values(this).filter(enumVal => typeof enumVal === 'object'); } /** * @return l'enum correspondant au code fourni */ - protected static fromCode, R = {}>(code: R): U { + public static fromCode, R = {}>(code: R): U { return this.values().find(enumVal => enumVal.code === code); } } diff --git a/frontend-implicaction/src/app/shared/models/uris.ts b/frontend-implicaction/src/app/shared/models/uris.ts index 29e0573f9..734f65ffc 100644 --- a/frontend-implicaction/src/app/shared/models/uris.ts +++ b/frontend-implicaction/src/app/shared/models/uris.ts @@ -34,6 +34,7 @@ export class Uris { static readonly BASE_URI = 'profiles'; static readonly BY_USERNAME = 'profiles'; static readonly POST_AVATAR = 'profiles/{username}/avatar'; + static readonly REQUEST_AS_FRIEND_COUNT = 'profiles/friend-requests/count'; }; /**