Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • web-et-numerique/factory/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_client
1 result
Show changes
Commits on Source (2)
Showing
with 107 additions and 83 deletions
......@@ -9,7 +9,7 @@ import { SearchQuery, SearchResults } from './models/searchQuery.model';
templateUrl: './annuaire.component.html',
styleUrls: ['./annuaire.component.scss'],
})
export class AnnuaireComponent implements OnInit {
export class AnnuaireComponent {
constructor(private searchService: SearchService, private authService: AuthService) {}
public userList: UserAnnuary[] = [];
public searchedValue: string;
......@@ -18,18 +18,16 @@ export class AnnuaireComponent implements OnInit {
public nextPage: number = 1;
public filterActive: boolean = false;
ngOnInit(): void {
this.getUsers({ queryParam: '', page: 1, jobFilters: [], employerFilter: [] });
}
public getUsers(params: SearchQuery): void {
if (this.userIsLoggedIn()) {
if (params.employerFilter?.length || params.jobFilters.length) {
this.searchService.annuaireSearchQuery = params;
if (params.employerFilters?.length || params.jobFilters?.length) {
this.filterActive = true;
} else {
this.filterActive = false;
}
this.searchService
.searchUserRegistry(params.queryParam, params.page, params.jobFilters, params.employerFilter)
.searchUserRegistry(params.queryParam, params.page, params.jobFilters, params.employerFilters)
.subscribe((res: SearchResults) => {
this.userList = res.docs;
this.totalUserResult = res.count;
......
......@@ -7,17 +7,10 @@
@import '../../../assets/scss/z-index';
.modalemployers {
left: 212px;
@media #{$large-desktop} {
left: 273px;
}
left: 515px;
}
.modaljobs {
left: 331px;
@media #{$large-desktop} {
left: 417px;
}
left: 412px;
}
.maxModal .blockLigne {
......
......@@ -4,7 +4,7 @@ export interface SearchQuery {
queryParam: string;
page: number;
jobFilters?: string[];
employerFilter?: string[];
employerFilters?: string[];
}
export interface SearchResults {
count: number;
......
<div class="results notEmpty" *ngIf="isLogged && userList.length" [ngClass]="{ filterActive: filterActive }">
<div class="userNumber">
{{ userList.length }} <span *ngIf="showPagination"> sur {{ totalUserResult }} </span> utilisateurs trouvés
{{ userList.length }} utilisateur(s)<span *ngIf="showPagination"> sur {{ totalUserResult }} </span>
</div>
<div class="singleUser" *ngFor="let user of userList; let index = index" (click)="goToUser(user._id)">
<div
class="singleUser"
[ngClass]="{ singleResult: userList.length == 1 }"
*ngFor="let user of userList; let index = index"
(click)="goToUser(user._id)"
>
<div class="avatar-container">
<app-svg-icon class="avatar" [type]="'avatar'" [icon]="'defaultAvatar'" [iconClass]="'icon-40'"></app-svg-icon>
</div>
......@@ -13,7 +18,9 @@
<div class="employer" *ngIf="user.employer">{{ user.employer.name }}</div>
</div>
<div class="pagination" *ngIf="showPagination">
<div class="text">{{ userList.length }} utilisateurs affichés sur {{ totalUserResult }} utilisateurs trouvés.</div>
<div class="text">
{{ userList.length }} utilisateur(s) affiché(s) sur {{ totalUserResult }} utilisateur(s) trouvé(s).
</div>
<app-button
[style]="buttonTypeEnum.modalSecondary"
[type]="'form'"
......
......@@ -128,4 +128,7 @@
color: $grey-3;
}
}
.singleResult {
border-bottom: none;
}
}
......@@ -29,13 +29,13 @@
type="button"
fxLayout="row"
[ngClass]="{
selected: modalTypeOpened === TypeModal.employers,
containCheckedFilters: numberEmployersChecked
selected: modalTypeOpened === TypeModal.jobs,
containCheckedFilters: numberJobChecked
}"
fxLayoutAlign="space-between center"
(click)="openModal(TypeModal.employers)"
(click)="openModal(TypeModal.jobs)"
>
<span>Employeur</span>
<span>Fonction</span>
<div class="arrow"></div>
</button>
<button
......@@ -43,20 +43,20 @@
type="button"
fxLayout="row"
[ngClass]="{
selected: modalTypeOpened === TypeModal.jobs,
containCheckedFilters: numberJobChecked
selected: modalTypeOpened === TypeModal.employers,
containCheckedFilters: numberEmployersChecked
}"
fxLayoutAlign="space-between center"
(click)="openModal(TypeModal.jobs)"
(click)="openModal(TypeModal.employers)"
>
<span>Fonction</span>
<span>Employeur</span>
<div class="arrow"></div>
</button>
<div *ngIf="modalTypeOpened">
<app-filter-modal
[modalType]="modalTypeOpened"
[checkedFilters]="checkedFilterList"
[checkedFilters]="searchService.checkedFilterList"
[filtersTypes]="getModalCategory()"
(searchEvent)="fetchResults($event)"
(closeEvent)="closeModal()"
......@@ -66,10 +66,15 @@
</div>
</div>
<div *ngIf="checkedFilterList.length" fxLayout="row wrap" fxLayoutGap="4px" class="filterTags isntPhoneContent">
<div
*ngIf="searchService.checkedFilterList.length"
fxLayout="row wrap"
fxLayoutGap="4px"
class="filterTags isntPhoneContent"
>
<div class="title">Filtres :</div>
<app-button
*ngFor="let filter of checkedFilterList"
*ngFor="let filter of searchService.checkedFilterList"
[style]="buttonTypeEnum.TagCloudButton"
[text]="filter"
(action)="removeFilter(filter)"
......
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { forkJoin } from 'rxjs';
import { ButtonType } from '../../shared/components/button/buttonType.enum';
import { Filter } from '../../structure-list/models/filter.model';
import { SearchService } from '../../structure-list/services/search.service';
import { TypeModal } from '../enums/TypeModal.enum';
......@@ -21,12 +21,10 @@ export class SearchBarComponent implements OnInit, OnChanges {
public buttonTypeEnum = ButtonType;
public searchForm: FormGroup;
public modalTypeOpened: TypeModal;
public checkedFilterList: string[] = [];
public numberEmployersChecked = 0;
public numberJobChecked = 0;
public jobTypes: string[] = [];
public employerTypes: string[] = [];
public queryString: string;
public jobFilterChecked: string[] = [];
public employerFilterChecked: string[] = [];
......@@ -36,42 +34,45 @@ export class SearchBarComponent implements OnInit, OnChanges {
private activatedRoute: ActivatedRoute,
private route: ActivatedRoute,
private router: Router,
private searchService: SearchService
) {
this.searchForm = this.fb.group({
searchTerm: this.activatedRoute.snapshot.queryParamMap.get('search')
? this.activatedRoute.snapshot.queryParamMap.get('search')
: '',
});
}
public searchService: SearchService
) {}
ngOnInit(): void {
// Will store the different categories
this.getData();
this.queryString = this.activatedRoute.snapshot.queryParamMap.get('search');
if (this.queryString) {
const filters: Filter[] = [];
filters.push(new Filter('query', this.queryString));
this.searchEvent.emit(filters);
let queryString = this.activatedRoute.snapshot.queryParamMap.get('search');
// Use existing query if back to the page or init the query
if (!this.searchService.annuaireSearchQuery) {
this.searchService.annuaireSearchQuery = { queryParam: '', page: 1, jobFilters: [], employerFilters: [] };
}
if (queryString) {
this.searchService.annuaireSearchQuery.queryParam = queryString;
}
this.searchForm = this.fb.group({
searchTerm: this.searchService.annuaireSearchQuery.queryParam,
});
this.searchEvent.emit(this.searchService.annuaireSearchQuery);
}
ngOnChanges(changes: SimpleChanges): void {
if (changes.shouldResetFilters && changes.shouldResetFilters.currentValue !== 0) this.resetFilters();
if (changes.shouldShowMore && !changes.shouldShowMore.firstChange) {
const term = this.searchForm.get('searchTerm').value || '';
this.searchEvent.emit({
queryParam: this.searchForm.get('searchTerm').value,
queryParam: term,
page: changes.shouldShowMore.currentValue,
jobFilters: this.jobFilterChecked,
employerFilter: this.employerFilterChecked,
employerFilters: this.employerFilterChecked,
});
}
}
// Get the categories for each modal type
private getData(): void {
this.searchService.getJobs().subscribe((res) => {
this.jobTypes = res;
});
this.searchService.getEmployers().subscribe((res) => {
this.employerTypes = res;
forkJoin({
job: this.searchService.getJobs(),
employer: this.searchService.getEmployers(),
}).subscribe((data) => {
this.jobTypes = data.job;
this.employerTypes = data.employer;
this.countCheckedFilters();
});
}
......@@ -107,16 +108,16 @@ export class SearchBarComponent implements OnInit, OnChanges {
relativeTo: this.route,
});
}
this.splitFilters(this.checkedFilterList);
this.splitFilters(this.searchService.checkedFilterList);
this.searchEvent.emit({
queryParam: term || '',
jobFilters: this.jobFilterChecked,
employerFilter: this.employerFilterChecked,
employerFilters: this.employerFilterChecked,
});
}
public fetchResults(checkedFilters: string[]): void {
this.checkedFilterList = checkedFilters;
this.searchService.checkedFilterList = checkedFilters;
const inputTerm = this.searchForm.get('searchTerm').value;
this.closeModal();
this.applyFilter(inputTerm);
......@@ -124,8 +125,12 @@ export class SearchBarComponent implements OnInit, OnChanges {
// Check if some modules is checked on filter and store number of modules checked
public countCheckedFilters(): void {
this.numberJobChecked = this.checkedFilterList.filter((filter) => this.jobTypes.includes(filter)).length;
this.numberEmployersChecked = this.checkedFilterList.filter((filter) => this.employerTypes.includes(filter)).length;
this.numberJobChecked = this.searchService.checkedFilterList.filter((filter) =>
this.jobTypes.includes(filter)
).length;
this.numberEmployersChecked = this.searchService.checkedFilterList.filter((filter) =>
this.employerTypes.includes(filter)
).length;
}
public getModalCategory(): string[] | Error {
......@@ -155,25 +160,25 @@ export class SearchBarComponent implements OnInit, OnChanges {
}
public resetFilters(): void {
this.checkedFilterList = [];
this.searchService.checkedFilterList = [];
this.numberEmployersChecked = 0;
this.numberJobChecked = 0;
this.employerFilterChecked = [];
this.jobFilterChecked = [];
this.searchEvent.emit({ queryParam: '', jobFilters: [], employerFilter: [] });
this.searchEvent.emit({ queryParam: '', jobFilters: [], employerFilters: [] });
this.router.navigate(['/annuaire']);
this.searchForm.reset();
}
public removeFilter(filter: string): void {
const index = this.checkedFilterList.findIndex((checkedFilter: string) => checkedFilter === filter);
this.checkedFilterList.splice(index, 1);
const index = this.searchService.checkedFilterList.findIndex((checkedFilter: string) => checkedFilter === filter);
this.searchService.checkedFilterList.splice(index, 1);
const inputTerm = this.searchForm.get('searchTerm').value;
this.splitFilters(this.checkedFilterList);
this.splitFilters(this.searchService.checkedFilterList);
this.countCheckedFilters();
this.searchEvent.emit({
queryParam: inputTerm || '',
jobFilters: this.checkedFilterList.length ? this.jobFilterChecked : [],
employerFilter: this.checkedFilterList.length ? this.employerFilterChecked : [],
jobFilters: this.jobFilterChecked,
employerFilters: this.employerFilterChecked,
});
}
}
......@@ -193,7 +193,7 @@
maxlength="500"
[(ngModel)]="userProfile.description"
></textarea>
<p class="descriptionLength">{{ userProfile.description?.length }}&nbsp;/&nbsp;500</p>
<p class="descriptionLength">{{ userProfile.description?.length || 0 }}&nbsp;/&nbsp;500</p>
</div>
</div>
......
import { ChangeDetectorRef, Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core';
import { Router } from '@angular/router';
import { HttpErrorResponse } from '@angular/common/http';
import { forkJoin, of } from 'rxjs';
import { catchError, first, map } from 'rxjs/operators';
......@@ -62,7 +63,8 @@ export class EditComponent implements OnInit {
private profileService: ProfileService,
private notificationService: NotificationService,
private cdr: ChangeDetectorRef,
private authService: AuthService
private authService: AuthService,
private router: Router
) {}
ngOnInit(): void {
......@@ -100,7 +102,7 @@ export class EditComponent implements OnInit {
return this.userProfile.surname !== '';
}
public descriptionValid(): boolean {
return this.userProfile.description.length <= 500;
return this.userProfile.description?.length <= 500;
}
public emailValid(email: string): boolean {
return !!email.match(CustomRegExp.EMAIL);
......@@ -196,7 +198,7 @@ export class EditComponent implements OnInit {
phone: this.userProfile.phone,
})
.subscribe((user: User) => {
this.notificationService.showSuccess('Vos coordonnées ont bien été mises à jour');
this.notificationService.showSuccess('Vos informations ont bien été enregistrées');
//Update localstorage
const updatedUser = {
...this.authService.userSubject.value,
......@@ -207,6 +209,7 @@ export class EditComponent implements OnInit {
localStorage.setItem('user', JSON.stringify(updatedUser));
this.authService.userSubject.next(updatedUser);
this.updateInitialProfile();
this.router.navigate(['/profile']);
});
}
......@@ -221,19 +224,24 @@ export class EditComponent implements OnInit {
map((res) => res),
catchError(() => of(this.selectJob))
),
profile: this.profileService.updateProfile(this.selectedEmployer.name, this.selectedJob.name).pipe(
map((res) => res),
catchError(() => of())
),
}).subscribe(() => {
this.notificationService.showSuccess('Vos informations ont bien été enregistrées');
this.profileService.updateProfile(this.selectedEmployer.name, this.selectedJob.name).subscribe(
() => {
this.router.navigate(['/profile']);
this.notificationService.showSuccess('Vos informations ont bien été enregistrées');
},
() => {
this.notificationService.showError("Vos informations n'ont pas été enregistrées", 'Une erreur est survenue');
}
);
});
}
public confirmDescription(): void {
this.profileService.updateDescription(this.userProfile.description).subscribe(() => {
this.notificationService.showSuccess('Vos description a bien été enregistrée');
this.notificationService.showSuccess('Vos informations ont bien été enregistrées');
this.updateInitialProfile();
this.router.navigate(['/profile']);
});
}
......
......@@ -33,7 +33,6 @@
<p class="section-title">informations</p>
<div fxLayout="row" fxLayoutAlign="space-between center" fxLayoutGap="12px">
<app-button
*ngIf="!isPublic"
class="hide-on-mobile"
[type]="'button'"
[iconBtn]="'eyePassword'"
......@@ -45,7 +44,6 @@
[routerLinkActive]="'active'"
></app-button>
<app-button
*ngIf="!isPublic"
class="hide-on-desktop"
[type]="'button'"
[iconBtn]="'eyePassword'"
......
......@@ -163,7 +163,7 @@
<app-no-information *ngIf="!hasWebsite() && !hasSocialNetworks()"></app-no-information>
<ng-container *ngIf="hasWebsite() || hasSocialNetworks()">
<div *ngIf="structure.website">
<a href="structure.website">{{ structure.website }}</a>
<a href="{{ structure.website }}">{{ structure.website }}</a>
</div>
<!-- Social networks-->
......
......@@ -4,7 +4,9 @@
<div fxLayout="row" fxLayoutAlign="space-between center" fxFill>
<div fxLayout="row" fxLayoutAlign="start center" class="headerBack">
<app-svg-icon [iconClass]="'backArrow'" [type]="'ico'" [icon]="'arrowBack'" (click)="goBack()"></app-svg-icon>
<h1>Gérer les membres<br />de {{ structure.structureName }}</h1>
<h1>
Gérer les membres de <span>{{ structure.structureName }}</span>
</h1>
</div>
<app-button
[style]="buttonTypeEnum.Secondary"
......
......@@ -14,6 +14,9 @@
}
.headerBack {
cursor: pointer;
span {
color: $red;
}
}
h1 {
@include lato-regular-24;
......
......@@ -20,7 +20,6 @@ import { PublicCategorie } from '../../enum/public.enum';
import { Category } from '../../models/category.model';
import { Module } from '../../models/module.model';
import { SearchService } from '../../services/search.service';
@Component({
selector: 'app-structure-details',
templateUrl: './structure-details.component.html',
......@@ -85,8 +84,8 @@ export class StructureDetailsComponent implements OnInit {
private tclService: TclService,
private profileService: ProfileService,
private authService: AuthService,
private route: ActivatedRoute,
private parametersService: ParametersService,
private route: ActivatedRoute,
private location: Location,
private router: Router
) {
......
......@@ -2,7 +2,7 @@ import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { SearchResults } from '../../annuaire/models/searchQuery.model';
import { SearchQuery, SearchResults } from '../../annuaire/models/searchQuery.model';
import { Category } from '../models/category.model';
import { Module } from '../models/module.model';
......@@ -10,6 +10,9 @@ import { Module } from '../models/module.model';
providedIn: 'root',
})
export class SearchService {
public annuaireSearchQuery: SearchQuery;
public checkedFilterList: string[] = [];
constructor(private http: HttpClient) {}
public getCategoriesTraining(): Observable<Category[]> {
......
......@@ -17,7 +17,7 @@ export class CustomRegExp {
/**
* Validate an email
*/
public static readonly EMAIL: RegExp = /^[a-z0-9.\-_]+@[a-z0-9.-]+[.][a-z]{2,3}/; //NOSONAR
public static readonly EMAIL: RegExp = /^[a-z0-9.\-_]+@[a-z0-9.-]+[.][a-z]{2,3}$/; //NOSONAR
public static readonly TEXT_WITHOUT_NUMBER: RegExp = /^[A-Za-zÀ-ÖØ-öø-ÿ- ]{1,}$/; //NOSONAR
/**
* Validate a phone number (4 or 10 digits, allowing spaces, dashes and dots as spacers)
......