Skip to content
Snippets Groups Projects
Commit b73ba205 authored by Rémi PAILHAREY's avatar Rémi PAILHAREY :fork_knife_plate:
Browse files

Merge branch 'feat/US191-section-mon-offre-de-service' into 'V2.0'

Feat/us191 section mon offre de service

See merge request web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_client!359
parents 720b0fd4 a2159c52
No related branches found
No related tags found
4 merge requests!418V2.1.0,!400V2.0,!359Feat/us191 section mon offre de service,!230V2.0
Showing with 258 additions and 27 deletions
export class PersonalOffer { export class PersonalOffer {
public _id: string = null;
public categories: { [key: string]: string[] }; public categories: { [key: string]: string[] };
public categoriesDisplay?: { [key: string]: string[] };
constructor(obj?: any) { constructor(obj?: any) {
Object.assign(this, obj, { Object.assign(this, obj, {
......
<div *ngIf="this.personalOffer.categoriesDisplay" class="container">
<div class="header">
<p>mon offre de service</p>
<app-button
*ngIf="!isPublic"
class="hide-on-mobile"
[type]="'button'"
[iconBtn]="'edit'"
[text]="'Modifier mon offre'"
[style]="buttonTypeEnum.SecondaryWide"
[disabled]="true"
></app-button>
<app-button
*ngIf="!isPublic"
class="hide-on-desktop"
[type]="'button'"
[iconBtn]="'edit'"
[style]="buttonTypeEnum.SecondaryOnlyIcon"
[disabled]="true"
></app-button>
</div>
<div class="content">
<div class="dropDown" *ngIf="this.personalOffer.categoriesDisplay.onlineProcedures.length">
<div class="collapseHeader" (click)="toggleOnlineProcedures()">
<p>Démarches en ligne</p>
<app-svg-icon
*ngIf="!showOnlineProcedures"
[type]="'ico'"
[icon]="'unfold'"
[iconClass]="'icon-26'"
></app-svg-icon>
<app-svg-icon
*ngIf="showOnlineProcedures"
[type]="'ico'"
[icon]="'fold'"
[iconClass]="'icon-26'"
></app-svg-icon>
</div>
<div class="collapseContent" [@collapse]="showOnlineProcedures">
<ul>
<li *ngFor="let onlineProcedure of this.personalOffer.categoriesDisplay.onlineProcedures">
{{ onlineProcedure }}
</li>
</ul>
</div>
</div>
<div class="dropDown" *ngIf="this.personalOffer.categoriesDisplay.baseSkills.length">
<div class="collapseHeader" (click)="toggleBaseSkills()">
<p>Compétences numériques de base</p>
<app-svg-icon *ngIf="!showBaseSkills" [type]="'ico'" [icon]="'unfold'" [iconClass]="'icon-26'"></app-svg-icon>
<app-svg-icon *ngIf="showBaseSkills" [type]="'ico'" [icon]="'fold'" [iconClass]="'icon-26'"></app-svg-icon>
</div>
<div class="collapseContent" [@collapse]="showBaseSkills">
<ul>
<li *ngFor="let baseSkill of this.personalOffer.categoriesDisplay.baseSkills">{{ baseSkill }}</li>
</ul>
</div>
</div>
<div class="dropDown" *ngIf="this.personalOffer.categoriesDisplay.advancedSkills.length">
<div class="collapseHeader" (click)="toggleAdvancedSkills()">
<p>Compétences numériques avancées</p>
<app-svg-icon
*ngIf="!showAdvancedSkills"
[type]="'ico'"
[icon]="'unfold'"
[iconClass]="'icon-26'"
></app-svg-icon>
<app-svg-icon *ngIf="showAdvancedSkills" [type]="'ico'" [icon]="'fold'" [iconClass]="'icon-26'"></app-svg-icon>
</div>
<div class="collapseContent" [@collapse]="showAdvancedSkills">
<ul>
<li *ngFor="let advancedSkill of this.personalOffer.categoriesDisplay.advancedSkills">{{ advancedSkill }}</li>
</ul>
</div>
</div>
</div>
</div>
@import '../../../../assets/scss/color';
@import '../../../../assets/scss/typography';
.container {
display: flex;
flex-direction: column;
gap: 8px;
p {
margin: 0;
}
.header {
display: flex;
align-items: center;
justify-content: space-between;
p {
text-transform: uppercase;
@include lato-bold-14;
color: $grey-3;
}
}
.content {
.dropDown {
overflow: hidden;
.collapseHeader {
display: flex;
align-items: center;
justify-content: space-between;
height: 2.5rem;
cursor: pointer;
color: $grey-2;
}
.collapseContent {
background-color: $grey-7;
border-radius: 4px;
ul {
margin: 0;
padding: 0.5rem 1.5rem;
list-style-position: inside;
li {
line-height: 2rem;
@include lato-regular-15;
}
}
}
&:not(:last-child) {
border-bottom: 1px solid $grey-8;
}
}
}
}
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PersonalOfferComponent } from './personal-offer.component';
describe('PersonalOfferComponent', () => {
let component: PersonalOfferComponent;
let fixture: ComponentFixture<PersonalOfferComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PersonalOfferComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(PersonalOfferComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { animate, AUTO_STYLE, state, style, transition, trigger } from '@angular/animations';
import { Component, Input, OnInit } from '@angular/core';
import { ButtonType } from '../../../shared/components/button/buttonType.enum';
import { PersonalOffer } from './../../../models/personalOffer.model';
@Component({
selector: 'app-personal-offer',
templateUrl: './personal-offer.component.html',
styleUrls: ['./personal-offer.component.scss'],
animations: [
trigger('collapse', [
state('true', style({ height: AUTO_STYLE, visibility: AUTO_STYLE, margin: '8px 0' })),
state('false', style({ height: '0px', visibility: 'hidden', margin: '0' })),
transition('true => false', animate('300ms ease-out')),
transition('false => true', animate('300ms ease-out')),
]),
],
})
export class PersonalOfferComponent {
@Input() public personalOffer: PersonalOffer;
@Input() public isPublic: boolean;
public buttonTypeEnum = ButtonType;
public showOnlineProcedures: boolean = false;
public showBaseSkills: boolean = false;
public showAdvancedSkills: boolean = false;
public toggleOnlineProcedures(): void {
this.showOnlineProcedures = !this.showOnlineProcedures;
}
public toggleBaseSkills(): void {
this.showBaseSkills = !this.showBaseSkills;
}
public toggleAdvancedSkills(): void {
this.showAdvancedSkills = !this.showAdvancedSkills;
}
}
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
</div> </div>
</div> </div>
<div [@collapse]="showDetails"> <div [@collapse]="showDetails">
<div class="collapseContent" fxLayout="column" fxLayoutAlign="center" fxLayoutGap="10px"> <div class="collapseContent" fxLayout="column" fxLayoutAlign="center" fxLayoutGap="16px">
<div fxLayout="column"> <div fxLayout="column">
<div fxLayout="row" fxLayoutAlign="space-between center" fxLayoutGap="20px"> <div fxLayout="row" fxLayoutAlign="space-between center" fxLayoutGap="20px">
<p class="section-title">informations</p> <p class="section-title">informations</p>
...@@ -90,6 +90,8 @@ ...@@ -90,6 +90,8 @@
</div> </div>
</div> </div>
</div> </div>
<app-personal-offer *ngIf="this.personalOffer" [personalOffer]="personalOffer" [isPublic]="isPublic">
</app-personal-offer>
<div *ngIf="members.length > 0" fxLayout="column" fxLayoutGap="9px"> <div *ngIf="members.length > 0" fxLayout="column" fxLayoutGap="9px">
<div fxLayout="row" fxLayoutAlign="space-between center"> <div fxLayout="row" fxLayoutAlign="space-between center">
<p class="section-title">membres</p> <p class="section-title">membres</p>
...@@ -127,6 +129,16 @@ ...@@ -127,6 +129,16 @@
(click)="addMemberModalOpenned = true" (click)="addMemberModalOpenned = true"
></app-button> ></app-button>
</div> </div>
<div class="call-to-action" *ngIf="!isPublic && !this.personalOffer" fxLayout="row" fxLayoutAlign="center">
<app-button
[type]="'button'"
[iconBtn]="'add'"
[text]="'Ajouter une offre'"
[style]="buttonTypeEnum.SecondaryUltraWide"
[routerLinkActive]="'active'"
[disabled]="true"
></app-button>
</div>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -7,7 +7,10 @@ import { Structure } from '../../models/structure.model'; ...@@ -7,7 +7,10 @@ import { Structure } from '../../models/structure.model';
import { StructureWithOwners } from '../../models/structureWithOwners.model'; import { StructureWithOwners } from '../../models/structureWithOwners.model';
import { NotificationService } from '../../services/notification.service'; import { NotificationService } from '../../services/notification.service';
import { ButtonType } from '../../shared/components/button/buttonType.enum'; import { ButtonType } from '../../shared/components/button/buttonType.enum';
import { SearchService } from '../../structure-list/services/search.service';
import { formUtils } from '../../utils/formUtils'; import { formUtils } from '../../utils/formUtils';
import { Utils } from '../../utils/utils';
import { PersonalOffer } from './../../models/personalOffer.model';
import { User } from './../../models/user.model'; import { User } from './../../models/user.model';
import { UserService } from './../../services/user.service'; import { UserService } from './../../services/user.service';
...@@ -34,14 +37,17 @@ export class ProfileStructureComponent implements OnInit { ...@@ -34,14 +37,17 @@ export class ProfileStructureComponent implements OnInit {
public showDetails: boolean = false; public showDetails: boolean = false;
public addMemberModalOpenned: boolean = false; public addMemberModalOpenned: boolean = false;
public structure: Structure; public structure: Structure;
public personalOffer: PersonalOffer;
constructor( constructor(
private router: Router, private router: Router,
private userService: UserService, private userService: UserService,
private notificationService: NotificationService private notificationService: NotificationService,
private searchService: SearchService,
public utils: Utils
) {} ) {}
ngOnInit(): void { async ngOnInit(): Promise<void> {
this.structureForm = new formUtils().createStructureForm(this.structureWithOwners.structure, true); this.structureForm = new formUtils().createStructureForm(this.structureWithOwners.structure, true);
this.structureWithOwners.owners this.structureWithOwners.owners
.filter((owner) => { .filter((owner) => {
...@@ -53,6 +59,23 @@ export class ProfileStructureComponent implements OnInit { ...@@ -53,6 +59,23 @@ export class ProfileStructureComponent implements OnInit {
}); });
}); });
this.structure = new Structure(this.structureWithOwners.structure); this.structure = new Structure(this.structureWithOwners.structure);
this.personalOffer = await this.getSharedPersonalOffer();
}
public async getSharedPersonalOffer(): Promise<PersonalOffer> {
// Check if user has personal offers
if (!this.userProfile.job.hasPersonalOffer || this.userProfile.personalOffers.length === 0) return null;
// Check if structure has personal offers
if (this.structure.personalOffers.length === 0) return null;
// Return personnal offer if the user has one in this structure
const personalOffer = this.structure.personalOffers.filter((structureOffer) =>
this.userProfile.personalOffers.includes(structureOffer._id)
)[0];
// Get categories labels
if (personalOffer) {
const categories = await this.searchService.getCategories().toPromise();
return this.utils.setServiceCategories(categories, personalOffer);
}
} }
public goBack(): void { public goBack(): void {
......
...@@ -12,6 +12,7 @@ import { StructureAddMemberModalComponent } from './structure-add-member-modal/s ...@@ -12,6 +12,7 @@ import { StructureAddMemberModalComponent } from './structure-add-member-modal/s
import { StructuresManagementComponent } from './structures-management/structures-management.component'; import { StructuresManagementComponent } from './structures-management/structures-management.component';
import { MissingInformationComponent } from './structure-edition-summary/missing-information/missing-information.component'; import { MissingInformationComponent } from './structure-edition-summary/missing-information/missing-information.component';
import { NoInformationComponent } from './structure-edition-summary/no-information/no-information.component'; import { NoInformationComponent } from './structure-edition-summary/no-information/no-information.component';
import { PersonalOfferComponent } from './profile-structure/personal-offer/personal-offer.component';
@NgModule({ @NgModule({
declarations: [ declarations: [
...@@ -25,6 +26,7 @@ import { NoInformationComponent } from './structure-edition-summary/no-informati ...@@ -25,6 +26,7 @@ import { NoInformationComponent } from './structure-edition-summary/no-informati
StructureEditionSummaryComponent, StructureEditionSummaryComponent,
StructureMembersManagementComponent, StructureMembersManagementComponent,
StructuresManagementComponent, StructuresManagementComponent,
PersonalOfferComponent,
], ],
imports: [CommonModule, ProfileRoutingModule, SharedModule], imports: [CommonModule, ProfileRoutingModule, SharedModule],
}) })
......
...@@ -4,9 +4,9 @@ import { forkJoin, Observable, Subject } from 'rxjs'; ...@@ -4,9 +4,9 @@ import { forkJoin, Observable, Subject } from 'rxjs';
import { catchError, map } from 'rxjs/operators'; import { catchError, map } from 'rxjs/operators';
import { Structure } from '../models/structure.model'; import { Structure } from '../models/structure.model';
import { StructureService } from '../services/structure.service'; import { StructureService } from '../services/structure.service';
import { Category } from '../structure-list/models/category.model';
import { Module } from '../structure-list/models/module.model';
import { SearchService } from '../structure-list/services/search.service'; import { SearchService } from '../structure-list/services/search.service';
import { Utils } from '../utils/utils';
@Injectable() @Injectable()
export class StructureResolver implements Resolve<Structure> { export class StructureResolver implements Resolve<Structure> {
...@@ -15,7 +15,8 @@ export class StructureResolver implements Resolve<Structure> { ...@@ -15,7 +15,8 @@ export class StructureResolver implements Resolve<Structure> {
constructor( constructor(
private structureService: StructureService, private structureService: StructureService,
private searchService: SearchService, private searchService: SearchService,
private router: Router private router: Router,
public utils: Utils
) {} ) {}
resolve(route: ActivatedRouteSnapshot): Observable<Structure> { resolve(route: ActivatedRouteSnapshot): Observable<Structure> {
...@@ -32,7 +33,7 @@ export class StructureResolver implements Resolve<Structure> { ...@@ -32,7 +33,7 @@ export class StructureResolver implements Resolve<Structure> {
), ),
categories: this.searchService.getCategories(), categories: this.searchService.getCategories(),
}).subscribe((res) => { }).subscribe((res) => {
const structure = this.setServiceCategories(res.categories, res.structure); const structure = this.utils.setServiceCategories(res.categories, res.structure) as Structure;
// return res; // return res;
this.setSubject(structure); this.setSubject(structure);
}); });
...@@ -48,24 +49,4 @@ export class StructureResolver implements Resolve<Structure> { ...@@ -48,24 +49,4 @@ export class StructureResolver implements Resolve<Structure> {
getSubject(): Observable<Structure> { getSubject(): Observable<Structure> {
return this.subject.asObservable(); return this.subject.asObservable();
} }
public setServiceCategories(categories: Category[], structure: Structure): Structure {
categories.forEach((category) => {
const structureModuleIds = structure.categories[category.id];
if (structureModuleIds) {
const moduleNames = category.modules
.map((module: Module) => {
if (structureModuleIds.includes(module.id)) {
return module.name;
}
})
.filter((value) => value !== undefined);
structure.categoriesDisplay = {
...structure.categoriesDisplay,
[category.id]: moduleNames,
};
}
});
return structure;
}
} }
import { PersonalOffer } from './../models/personalOffer.model';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { UntypedFormGroup } from '@angular/forms'; import { UntypedFormGroup } from '@angular/forms';
import { Structure } from '../models/structure.model'; import { Structure } from '../models/structure.model';
...@@ -7,6 +8,8 @@ import { FreeWorkshop } from '../shared/enum/freeWorkshop.enum'; ...@@ -7,6 +8,8 @@ import { FreeWorkshop } from '../shared/enum/freeWorkshop.enum';
import { OtherServices } from '../shared/enum/otherServices.enum'; import { OtherServices } from '../shared/enum/otherServices.enum';
import { AccessModality } from '../structure-list/enum/access-modality.enum'; import { AccessModality } from '../structure-list/enum/access-modality.enum';
import { Equipment } from '../structure-list/enum/equipment.enum'; import { Equipment } from '../structure-list/enum/equipment.enum';
import { Category } from '../structure-list/models/category.model';
import { Module } from '../structure-list/models/module.model';
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
...@@ -133,4 +136,24 @@ export class Utils { ...@@ -133,4 +136,24 @@ export class Utils {
public getOtherServicesLabel(otherService: OtherServices) { public getOtherServicesLabel(otherService: OtherServices) {
return OtherServices[otherService]; return OtherServices[otherService];
} }
public setServiceCategories(categories: Category[], structure: Structure | PersonalOffer): Structure | PersonalOffer {
categories.forEach((category) => {
const structureModuleIds = structure.categories[category.id];
if (structureModuleIds) {
const moduleNames = category.modules
.map((module: Module) => {
if (structureModuleIds.includes(module.id)) {
return module.name;
}
})
.filter((value) => value !== undefined);
structure.categoriesDisplay = {
...structure.categoriesDisplay,
[category.id]: moduleNames,
};
}
});
return structure;
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment