From e528f1b430ffc2049449d6cc6be06c47eb80132a Mon Sep 17 00:00:00 2001 From: Pierre Ecarlat <pecarlat@grandlyon.com> Date: Wed, 21 Aug 2024 09:04:40 +0200 Subject: [PATCH 01/11] wip: updated admin navbar to match news --- .../claim-structure.component.html | 2 +- .../deleted-structures.component.html | 2 +- .../espace-coop-cnfs.component.html | 2 +- .../manage-employers.component.html | 2 +- .../manage-jobs/manage-jobs.component.html | 2 +- .../manage-users/manage-users.component.html | 2 +- .../components/nav-bar/nav-bar.component.html | 40 ++++++----- .../components/nav-bar/nav-bar.component.scss | 67 +++++++++++++++---- .../components/nav-bar/nav-bar.component.ts | 7 +- .../admin-structures-list.component.html | 2 +- 10 files changed, 90 insertions(+), 38 deletions(-) diff --git a/src/app/admin/components/claim-structure/claim-structure.component.html b/src/app/admin/components/claim-structure/claim-structure.component.html index 0e63cd7fe..4475e31a7 100644 --- a/src/app/admin/components/claim-structure/claim-structure.component.html +++ b/src/app/admin/components/claim-structure/claim-structure.component.html @@ -1,4 +1,4 @@ -<app-admin-nav-bar /> +<app-nav-bar /> <div class="adminLayout"> <h2>Revendication structure</h2> <ag-grid-angular diff --git a/src/app/admin/components/deleted-structures/deleted-structures.component.html b/src/app/admin/components/deleted-structures/deleted-structures.component.html index 875fd4dba..d87a7c7dc 100644 --- a/src/app/admin/components/deleted-structures/deleted-structures.component.html +++ b/src/app/admin/components/deleted-structures/deleted-structures.component.html @@ -1,4 +1,4 @@ -<app-admin-nav-bar /> +<app-nav-bar /> <div *ngIf="isLoading" class="loader" aria-busy="true"> <img class="loader-gif" src="/assets/gif/loader_circle.gif" alt /> </div> diff --git a/src/app/admin/components/espace-coop-cnfs/espace-coop-cnfs.component.html b/src/app/admin/components/espace-coop-cnfs/espace-coop-cnfs.component.html index 7d6870a69..54b24e4c8 100644 --- a/src/app/admin/components/espace-coop-cnfs/espace-coop-cnfs.component.html +++ b/src/app/admin/components/espace-coop-cnfs/espace-coop-cnfs.component.html @@ -1,4 +1,4 @@ -<app-admin-nav-bar /> +<app-nav-bar /> <div class="adminLayout"> <h2>CNFS présents dans Espace Coop sans compte Rés'in ({{ unregisteredCNFS.length }})</h2> <ag-grid-angular diff --git a/src/app/admin/components/manage-employers/manage-employers.component.html b/src/app/admin/components/manage-employers/manage-employers.component.html index f098ac42f..4180d1718 100644 --- a/src/app/admin/components/manage-employers/manage-employers.component.html +++ b/src/app/admin/components/manage-employers/manage-employers.component.html @@ -1,4 +1,4 @@ -<app-admin-nav-bar /> +<app-nav-bar /> <div class="adminLayout"> <h2> Gestion des employeurs diff --git a/src/app/admin/components/manage-jobs/manage-jobs.component.html b/src/app/admin/components/manage-jobs/manage-jobs.component.html index 57256cc84..c9f0e0e55 100644 --- a/src/app/admin/components/manage-jobs/manage-jobs.component.html +++ b/src/app/admin/components/manage-jobs/manage-jobs.component.html @@ -1,4 +1,4 @@ -<app-admin-nav-bar /> +<app-nav-bar /> <div class="adminLayout"> <h2> Gestion des fonctions diff --git a/src/app/admin/components/manage-users/manage-users.component.html b/src/app/admin/components/manage-users/manage-users.component.html index 2dd43a692..77f2f6739 100644 --- a/src/app/admin/components/manage-users/manage-users.component.html +++ b/src/app/admin/components/manage-users/manage-users.component.html @@ -1,4 +1,4 @@ -<app-admin-nav-bar /> +<app-nav-bar /> <div class="adminLayout"> <h2> Gestion des utilisateurs diff --git a/src/app/admin/components/nav-bar/nav-bar.component.html b/src/app/admin/components/nav-bar/nav-bar.component.html index 569fc8cbe..0fb987213 100644 --- a/src/app/admin/components/nav-bar/nav-bar.component.html +++ b/src/app/admin/components/nav-bar/nav-bar.component.html @@ -1,23 +1,33 @@ <div class="header"> <div class="title-and-ghost"> <h1>Administration</h1> - <app-button - [variant]="'secondary'" - [label]="'Ghost'" - [type]="'button'" - (action)="openGhost()" - /> + <app-button [variant]="'secondary'" [label]="'Ghost'" [type]="'button'" (action)="openGhost()" /> </div> <nav> - <ng-container *ngFor="let button of buttons"> - <div [class]="isActive(button.route)"> - <app-button - [variant]="'tertiary'" - [label]="button.label" - [type]="'button'" - (action)="navigateTo(button.route)" - /> + <div role="tablist" class="navigation" aria-label="Filtrer les actualités"> + <div + *ngFor="let button of buttons" + class="tag" + role="tab" + tabindex="0" + aria-controls="posts" + [attr.aria-selected]="button.label === activeTab ? true : false" + [ngClass]="{ active: button.label === activeTab }" + (click)="navigateTo(button.route)" + (keydown.enter)="navigateTo(button.route)" + > + <span> + {{ button.label }} + </span> + <!-- <div [class]="isActive(button.route)"> + <app-button + [variant]="'tertiary'" + [label]="button.label" + [type]="'button'" + (action)="navigateTo(button.route)" + /> + </div> --> </div> - </ng-container> + </div> </nav> </div> diff --git a/src/app/admin/components/nav-bar/nav-bar.component.scss b/src/app/admin/components/nav-bar/nav-bar.component.scss index 57d5fe7d5..afdbd19f7 100644 --- a/src/app/admin/components/nav-bar/nav-bar.component.scss +++ b/src/app/admin/components/nav-bar/nav-bar.component.scss @@ -1,3 +1,6 @@ +@import 'color'; +@import 'typography'; + .header { display: flex; flex-direction: column; @@ -19,22 +22,60 @@ } nav { - margin-top: 0.5rem; display: flex; justify-content: space-between; - border-bottom: 1px solid #ccc; - margin-bottom: 1.5rem; - width: 80%; - overflow-x: auto; - } + align-items: center; - app-button { - height: 3.75rem; - position: relative; - } + border-bottom: 1px solid $grey-4; - .active { - border-bottom: 3px solid black; - padding-bottom: 0.5rem; + .navigation { + display: flex; + overflow-x: auto; + white-space: nowrap; + + .tag { + cursor: pointer; + user-select: none; + @include font-regular-16; + box-sizing: border-box; + padding: 0 16px; + height: 60px; + display: flex; + align-items: center; + border-bottom: 3px solid transparent; + transition: all 0.3s ease-in-out; + outline-offset: -2px; // Fixes the focus display issue in Firefox where it was not visible due to "overflow-x" on .navigation + &.active { + @include font-bold-16; + border-color: $grey-1; + } + &:hover { + border-color: $grey-4; + } + &:focus { + outline-color: $red; + } + } + } } + + // nav { + // margin-top: 0.5rem; + // display: flex; + // justify-content: space-between; + // border-bottom: 1px solid #ccc; + // margin-bottom: 1.5rem; + // width: 80%; + // overflow-x: auto; + // } + + // app-button { + // height: 3.75rem; + // position: relative; + // } + + // .active { + // border-bottom: 3px solid black; + // padding-bottom: 0.5rem; + // } } diff --git a/src/app/admin/components/nav-bar/nav-bar.component.ts b/src/app/admin/components/nav-bar/nav-bar.component.ts index 42e33463f..3fd2d66e1 100644 --- a/src/app/admin/components/nav-bar/nav-bar.component.ts +++ b/src/app/admin/components/nav-bar/nav-bar.component.ts @@ -1,11 +1,11 @@ import { Component, OnInit } from '@angular/core'; -import { Router, NavigationEnd } from '@angular/router'; +import { NavigationEnd, Router } from '@angular/router'; +import { filter } from 'rxjs/operators'; import { ConfigService } from '../../../services/config.service'; import { AdminRoutes } from '../../admin-routing.module'; -import { filter } from 'rxjs/operators'; @Component({ - selector: 'app-admin-nav-bar', + selector: 'app-nav-bar', templateUrl: './nav-bar.component.html', styleUrls: ['./nav-bar.component.scss'], }) @@ -13,6 +13,7 @@ export class NavBarComponent implements OnInit { public routes = AdminRoutes; private ghostLink: string; public currentRoute: string; + public activeTab = 'Revendication structure'; public buttons = [ { label: 'Revendication structure', route: this.routes.pendingStructures.link }, diff --git a/src/app/admin/components/structures-list/admin-structures-list.component.html b/src/app/admin/components/structures-list/admin-structures-list.component.html index 73d9a9e43..bc789c993 100644 --- a/src/app/admin/components/structures-list/admin-structures-list.component.html +++ b/src/app/admin/components/structures-list/admin-structures-list.component.html @@ -1,4 +1,4 @@ -<app-admin-nav-bar /> +<app-nav-bar /> <div class="filters-containers"> <div *ngFor="let filterOption of filterOptions"> -- GitLab From 141b9f90db2f7102192c34705a2a5789e988e3ec Mon Sep 17 00:00:00 2001 From: Pierre Ecarlat <pecarlat@grandlyon.com> Date: Wed, 21 Aug 2024 16:34:05 +0200 Subject: [PATCH 02/11] First version of nav-bar, set for one case of admin --- src/app/admin/admin.module.ts | 4 +- src/app/admin/admin.scss | 11 ++- .../admin-header/admin-header.component.html | 7 ++ .../admin-header/admin-header.component.scss | 22 +++++ .../admin-header/admin-header.component.ts | 52 ++++++++++ .../claim-structure.component.html | 3 +- .../deleted-structures.component.html | 2 +- .../espace-coop-cnfs.component.html | 2 +- .../manage-employers.component.html | 2 +- .../manage-jobs/manage-jobs.component.html | 2 +- .../manage-users/manage-users.component.html | 2 +- .../components/nav-bar/nav-bar.component.html | 53 ++++------ .../components/nav-bar/nav-bar.component.scss | 99 ++++++------------- .../components/nav-bar/nav-bar.component.ts | 59 +++-------- .../admin-structures-list.component.html | 2 +- .../post-header/post-header.component.html | 16 +-- .../post-header/post-header.component.scss | 8 +- src/app/profile/edit/edit.component.html | 38 +++++-- src/app/profile/edit/edit.component.scss | 44 +++++++++ src/app/profile/edit/edit.component.ts | 27 +++-- .../personal-offer-edition.component.html | 46 +++++---- .../personal-offer-edition.component.scss | 60 ++++++----- .../personal-offer-edition.component.ts | 13 ++- 23 files changed, 340 insertions(+), 234 deletions(-) create mode 100644 src/app/admin/components/admin-header/admin-header.component.html create mode 100644 src/app/admin/components/admin-header/admin-header.component.scss create mode 100644 src/app/admin/components/admin-header/admin-header.component.ts diff --git a/src/app/admin/admin.module.ts b/src/app/admin/admin.module.ts index 81a4a46a9..27e0dc8d6 100644 --- a/src/app/admin/admin.module.ts +++ b/src/app/admin/admin.module.ts @@ -3,6 +3,8 @@ import { NgModule } from '@angular/core'; import { AgGridModule } from 'ag-grid-angular'; import { SharedModule } from '../shared/shared.module'; import { AdminRoutingModule } from './admin-routing.module'; +import { AdminHeaderComponent } from './components/admin-header/admin-header.component'; +import { ButtonCellRendererComponent } from './components/button-cell-renderer/button-cell-renderer.component'; import { ClaimStructureComponent } from './components/claim-structure/claim-structure.component'; import { DeletedStructuresComponent } from './components/deleted-structures/deleted-structures.component'; import { EspaceCoopCNFSComponent } from './components/espace-coop-cnfs/espace-coop-cnfs.component'; @@ -23,7 +25,6 @@ import { JobRendererComponent } from './components/manage-users/job-renderer/job import { ManageUsersComponent } from './components/manage-users/manage-users.component'; import { NavBarComponent } from './components/nav-bar/nav-bar.component'; import { AdminStructuresListComponent } from './components/structures-list/admin-structures-list.component'; -import { ButtonCellRendererComponent } from './components/button-cell-renderer/button-cell-renderer.component'; @NgModule({ declarations: [ @@ -46,6 +47,7 @@ import { ButtonCellRendererComponent } from './components/button-cell-renderer/b ManageEmployersComponent, DeletedStructuresComponent, NavBarComponent, + AdminHeaderComponent, EspaceCoopCNFSComponent, ButtonCellRendererComponent, ], diff --git a/src/app/admin/admin.scss b/src/app/admin/admin.scss index 7e52d1c76..58b03d54b 100644 --- a/src/app/admin/admin.scss +++ b/src/app/admin/admin.scss @@ -1,12 +1,13 @@ @import 'color'; .adminLayout { - display: flex; - flex-direction: column; - align-items: start; - gap: 1rem; + // display: flex; + // flex-direction: column; + // align-items: start; + // gap: 1rem; + display: block; margin: auto; - padding-bottom: 1rem; + padding: 2rem 0; width: 80%; } diff --git a/src/app/admin/components/admin-header/admin-header.component.html b/src/app/admin/components/admin-header/admin-header.component.html new file mode 100644 index 000000000..16baadd89 --- /dev/null +++ b/src/app/admin/components/admin-header/admin-header.component.html @@ -0,0 +1,7 @@ +<div class="header"> + <div class="title-and-ghost"> + <h1>Administration</h1> + <app-button [variant]="'secondary'" [label]="'Ghost'" [size]="'small'" (action)="openGhost()" /> + </div> + <app-nav-bar [tabs]="getTabsNames()" [currentTab]="currentTab" (clickedTab)="navigateTo($event)" /> +</div> diff --git a/src/app/admin/components/admin-header/admin-header.component.scss b/src/app/admin/components/admin-header/admin-header.component.scss new file mode 100644 index 000000000..802b74bab --- /dev/null +++ b/src/app/admin/components/admin-header/admin-header.component.scss @@ -0,0 +1,22 @@ +@import 'typography'; + +.header { + display: flex; + flex-direction: column; + width: 100%; + + .title-and-ghost { + display: flex; + justify-content: space-between; + width: 100%; + + h1 { + justify-content: start; + @include font-regular-24; + } + } + + app-nav-bar { + margin: 1.5rem 0; + } +} diff --git a/src/app/admin/components/admin-header/admin-header.component.ts b/src/app/admin/components/admin-header/admin-header.component.ts new file mode 100644 index 000000000..8bdaca400 --- /dev/null +++ b/src/app/admin/components/admin-header/admin-header.component.ts @@ -0,0 +1,52 @@ +import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +import { ConfigService } from '../../../services/config.service'; +import { AdminRoutes } from '../../admin-routing.module'; + +@Component({ + selector: 'app-admin-header', + templateUrl: './admin-header.component.html', + styleUrls: ['./admin-header.component.scss'], +}) +export class AdminHeaderComponent implements OnInit { + private ghostLink: string; + public currentTab = 0; + public routes = AdminRoutes; + + public tabs = [ + { label: 'Revendication structure', route: this.routes.pendingStructures.link }, + { label: 'Liste structures', route: this.routes.structuresList.link }, + { label: 'Structures supprimées', route: this.routes.deletedStructures.link }, + { label: 'Gestion des utilisateurs', route: this.routes.manageUsers.link }, + { label: 'Fonctions', route: this.routes.jobsList.link }, + { label: 'Employeurs', route: this.routes.employersList.link }, + { label: 'CNFS Espace Coop', route: this.routes.espaceCoopCNFS.link }, + ]; + + constructor( + public router: Router, + private configService: ConfigService, + ) {} + + ngOnInit(): void { + // Fetch configuration and set ghost link + this.configService.getConfig().then((config) => { + this.ghostLink = config.ghostAdminUrl; + }); + + // We navigateTo distinct routes, so we need to recover the currentTab after rerouting + this.currentTab = this.tabs.findIndex((tab) => tab.route === this.router.url.substring(1)); + } + + public getTabsNames(): string[] { + return this.tabs.map((tab) => tab.label); + } + + public navigateTo(tabIndex: number): void { + this.router.navigateByUrl(this.tabs[tabIndex].route); + } + + public openGhost(): void { + window.open(this.ghostLink); + } +} diff --git a/src/app/admin/components/claim-structure/claim-structure.component.html b/src/app/admin/components/claim-structure/claim-structure.component.html index 4475e31a7..ca40b8adc 100644 --- a/src/app/admin/components/claim-structure/claim-structure.component.html +++ b/src/app/admin/components/claim-structure/claim-structure.component.html @@ -1,5 +1,6 @@ -<app-nav-bar /> <div class="adminLayout"> + <app-admin-header /> + <h2>Revendication structure</h2> <ag-grid-angular *ngIf="demandsAttachment?.length" diff --git a/src/app/admin/components/deleted-structures/deleted-structures.component.html b/src/app/admin/components/deleted-structures/deleted-structures.component.html index d87a7c7dc..c746ded7d 100644 --- a/src/app/admin/components/deleted-structures/deleted-structures.component.html +++ b/src/app/admin/components/deleted-structures/deleted-structures.component.html @@ -1,8 +1,8 @@ -<app-nav-bar /> <div *ngIf="isLoading" class="loader" aria-busy="true"> <img class="loader-gif" src="/assets/gif/loader_circle.gif" alt /> </div> <div *ngIf="!isLoading" class="adminLayout"> + <app-admin-header /> <h2>Liste des structures supprimées</h2> <ag-grid-angular *ngIf="deletedStructures" diff --git a/src/app/admin/components/espace-coop-cnfs/espace-coop-cnfs.component.html b/src/app/admin/components/espace-coop-cnfs/espace-coop-cnfs.component.html index 54b24e4c8..0a41926ad 100644 --- a/src/app/admin/components/espace-coop-cnfs/espace-coop-cnfs.component.html +++ b/src/app/admin/components/espace-coop-cnfs/espace-coop-cnfs.component.html @@ -1,5 +1,5 @@ -<app-nav-bar /> <div class="adminLayout"> + <app-admin-header /> <h2>CNFS présents dans Espace Coop sans compte Rés'in ({{ unregisteredCNFS.length }})</h2> <ag-grid-angular *ngIf="unregisteredCNFS.length" diff --git a/src/app/admin/components/manage-employers/manage-employers.component.html b/src/app/admin/components/manage-employers/manage-employers.component.html index 4180d1718..be5309345 100644 --- a/src/app/admin/components/manage-employers/manage-employers.component.html +++ b/src/app/admin/components/manage-employers/manage-employers.component.html @@ -1,4 +1,4 @@ -<app-nav-bar /> +<app-admin-header /> <div class="adminLayout"> <h2> Gestion des employeurs diff --git a/src/app/admin/components/manage-jobs/manage-jobs.component.html b/src/app/admin/components/manage-jobs/manage-jobs.component.html index c9f0e0e55..7575dab47 100644 --- a/src/app/admin/components/manage-jobs/manage-jobs.component.html +++ b/src/app/admin/components/manage-jobs/manage-jobs.component.html @@ -1,4 +1,4 @@ -<app-nav-bar /> +<app-admin-header /> <div class="adminLayout"> <h2> Gestion des fonctions diff --git a/src/app/admin/components/manage-users/manage-users.component.html b/src/app/admin/components/manage-users/manage-users.component.html index 77f2f6739..7db18952d 100644 --- a/src/app/admin/components/manage-users/manage-users.component.html +++ b/src/app/admin/components/manage-users/manage-users.component.html @@ -1,4 +1,4 @@ -<app-nav-bar /> +<app-admin-header /> <div class="adminLayout"> <h2> Gestion des utilisateurs diff --git a/src/app/admin/components/nav-bar/nav-bar.component.html b/src/app/admin/components/nav-bar/nav-bar.component.html index 0fb987213..5aa452b8e 100644 --- a/src/app/admin/components/nav-bar/nav-bar.component.html +++ b/src/app/admin/components/nav-bar/nav-bar.component.html @@ -1,33 +1,22 @@ -<div class="header"> - <div class="title-and-ghost"> - <h1>Administration</h1> - <app-button [variant]="'secondary'" [label]="'Ghost'" [type]="'button'" (action)="openGhost()" /> - </div> - <nav> - <div role="tablist" class="navigation" aria-label="Filtrer les actualités"> - <div - *ngFor="let button of buttons" - class="tag" - role="tab" - tabindex="0" - aria-controls="posts" - [attr.aria-selected]="button.label === activeTab ? true : false" - [ngClass]="{ active: button.label === activeTab }" - (click)="navigateTo(button.route)" - (keydown.enter)="navigateTo(button.route)" - > - <span> - {{ button.label }} - </span> - <!-- <div [class]="isActive(button.route)"> - <app-button - [variant]="'tertiary'" - [label]="button.label" - [type]="'button'" - (action)="navigateTo(button.route)" - /> - </div> --> - </div> +<nav> + <div + role="tablist" + class="navigation" + aria-label="Sélectionner le panneau admin" + [ngClass]="{ expand: shouldExpand }" + > + <div + *ngFor="let tab of tabs; let i = index" + class="tab" + role="tab" + tabindex="0" + aria-controls="posts" + [attr.aria-selected]="isActive(i)" + [ngClass]="{ active: isActive(i) }" + (click)="onClickTab(i)" + (keydown.enter)="onClickTab(i)" + > + {{ tab }} </div> - </nav> -</div> + </div> +</nav> diff --git a/src/app/admin/components/nav-bar/nav-bar.component.scss b/src/app/admin/components/nav-bar/nav-bar.component.scss index afdbd19f7..1893a0b09 100644 --- a/src/app/admin/components/nav-bar/nav-bar.component.scss +++ b/src/app/admin/components/nav-bar/nav-bar.component.scss @@ -1,81 +1,42 @@ @import 'color'; @import 'typography'; -.header { +nav { display: flex; - flex-direction: column; - align-items: center; + border-bottom: 1px solid $grey-4; - .title-and-ghost { - margin-top: 2rem; + .navigation { display: flex; - flex-direction: row; - justify-content: space-between; - width: 80%; - height: 2rem; - margin-bottom: 1.5rem; - } - - h1 { - justify-content: start; - font-weight: 400; - } - - nav { - display: flex; - justify-content: space-between; - align-items: center; - - border-bottom: 1px solid $grey-4; + overflow-x: auto; + white-space: nowrap; + &.expand { + width: 100%; + } - .navigation { + .tab { + cursor: pointer; + user-select: none; + @include font-regular-16; + box-sizing: border-box; + padding: 0 16px; + height: 60px; display: flex; - overflow-x: auto; - white-space: nowrap; - - .tag { - cursor: pointer; - user-select: none; - @include font-regular-16; - box-sizing: border-box; - padding: 0 16px; - height: 60px; - display: flex; - align-items: center; - border-bottom: 3px solid transparent; - transition: all 0.3s ease-in-out; - outline-offset: -2px; // Fixes the focus display issue in Firefox where it was not visible due to "overflow-x" on .navigation - &.active { - @include font-bold-16; - border-color: $grey-1; - } - &:hover { - border-color: $grey-4; - } - &:focus { - outline-color: $red; - } + align-items: center; + justify-content: center; + flex: 1; + border-bottom: 3px solid transparent; + transition: all 0.3s ease-in-out; + outline-offset: -2px; // Fixes the focus display issue in Firefox where it was not visible due to "overflow-x" on .navigation + &.active { + @include font-bold-16; + border-color: $grey-1; + } + &:hover { + border-color: $grey-4; + } + &:focus { + outline-color: $red; } } } - - // nav { - // margin-top: 0.5rem; - // display: flex; - // justify-content: space-between; - // border-bottom: 1px solid #ccc; - // margin-bottom: 1.5rem; - // width: 80%; - // overflow-x: auto; - // } - - // app-button { - // height: 3.75rem; - // position: relative; - // } - - // .active { - // border-bottom: 3px solid black; - // padding-bottom: 0.5rem; - // } } diff --git a/src/app/admin/components/nav-bar/nav-bar.component.ts b/src/app/admin/components/nav-bar/nav-bar.component.ts index 3fd2d66e1..87cc771b0 100644 --- a/src/app/admin/components/nav-bar/nav-bar.component.ts +++ b/src/app/admin/components/nav-bar/nav-bar.component.ts @@ -1,57 +1,22 @@ -import { Component, OnInit } from '@angular/core'; -import { NavigationEnd, Router } from '@angular/router'; -import { filter } from 'rxjs/operators'; -import { ConfigService } from '../../../services/config.service'; -import { AdminRoutes } from '../../admin-routing.module'; +import { Component, EventEmitter, Input, Output } from '@angular/core'; @Component({ selector: 'app-nav-bar', templateUrl: './nav-bar.component.html', styleUrls: ['./nav-bar.component.scss'], }) -export class NavBarComponent implements OnInit { - public routes = AdminRoutes; - private ghostLink: string; - public currentRoute: string; - public activeTab = 'Revendication structure'; - - public buttons = [ - { label: 'Revendication structure', route: this.routes.pendingStructures.link }, - { label: 'Liste structures', route: this.routes.structuresList.link }, - { label: 'Structures supprimées', route: this.routes.deletedStructures.link }, - { label: 'Gestion des utilisateurs', route: this.routes.manageUsers.link }, - { label: 'Fonctions', route: this.routes.jobsList.link }, - { label: 'Employeurs', route: this.routes.employersList.link }, - { label: 'CNFS Espace Coop', route: this.routes.espaceCoopCNFS.link }, - ]; - - constructor( - public router: Router, - private configService: ConfigService, - ) {} - - ngOnInit(): void { - // Fetch configuration and set ghost link - this.configService.getConfig().then((config) => { - this.ghostLink = config.ghostAdminUrl; - }); - - this.router.events.pipe(filter((event) => event instanceof NavigationEnd)).subscribe((event: NavigationEnd) => { - this.currentRoute = event.urlAfterRedirects || event.url; - }); - - this.currentRoute = this.router.url.substring(1); - } - - public openGhost(): void { - window.open(this.ghostLink); - } - - public navigateTo(route: string): void { - this.router.navigateByUrl(route); +export class NavBarComponent { + @Input({ required: true }) tabs: string[]; + @Input() currentTab = 0; + @Input() shouldExpand = false; + @Output() clickedTab = new EventEmitter<number>(); + + public onClickTab(tabIndex: number): void { + this.currentTab = tabIndex; + this.clickedTab.emit(tabIndex); } - public isActive(route: string): string { - return this.currentRoute === route ? 'active' : ''; + public isActive(idx: number): boolean { + return this.currentTab === idx; } } diff --git a/src/app/admin/components/structures-list/admin-structures-list.component.html b/src/app/admin/components/structures-list/admin-structures-list.component.html index bc789c993..ea54f12c5 100644 --- a/src/app/admin/components/structures-list/admin-structures-list.component.html +++ b/src/app/admin/components/structures-list/admin-structures-list.component.html @@ -1,4 +1,4 @@ -<app-nav-bar /> +<app-admin-header /> <div class="filters-containers"> <div *ngFor="let filterOption of filterOptions"> diff --git a/src/app/post/components/post-header/post-header.component.html b/src/app/post/components/post-header/post-header.component.html index a24a9232a..03ff2a6e8 100644 --- a/src/app/post/components/post-header/post-header.component.html +++ b/src/app/post/components/post-header/post-header.component.html @@ -9,20 +9,20 @@ </div> <nav> - <div role="tablist" class="navigation" aria-label="Filtrer les actualités"> + <div role="tablist" class="navigation" aria-label="Filtrer les actualités" [ngClass]="{ expand: false }"> <div - *ngFor="let tag of tags.others" - class="tag" + *ngFor="let tab of tags.others" + class="tab" role="tab" tabindex="0" aria-controls="posts" - [attr.aria-selected]="tag.slug === mainActiveTag.slug ? true : false" - [ngClass]="{ active: tag.slug === mainActiveTag.slug || tag.name === mainActiveTag.slug }" - (click)="activateTag(tag)" - (keydown.enter)="activateTag(tag)" + [attr.aria-selected]="tab.slug === mainActiveTag.slug ? true : false" + [ngClass]="{ active: tab.slug === mainActiveTag.slug || tab.name === mainActiveTag.slug }" + (click)="activateTag(tab)" + (keydown.enter)="activateTag(tab)" > <span> - {{ tag.name }} + {{ tab.name }} </span> </div> </div> diff --git a/src/app/post/components/post-header/post-header.component.scss b/src/app/post/components/post-header/post-header.component.scss index c934ed5f4..438ca2b20 100644 --- a/src/app/post/components/post-header/post-header.component.scss +++ b/src/app/post/components/post-header/post-header.component.scss @@ -18,6 +18,7 @@ nav { display: flex; justify-content: space-between; align-items: center; + width: 100%; border-bottom: 1px solid $grey-4; @@ -25,8 +26,11 @@ nav { display: flex; overflow-x: auto; white-space: nowrap; + &.expand { + width: 100%; + } - .tag { + .tab { cursor: pointer; user-select: none; @include font-regular-16; @@ -35,6 +39,8 @@ nav { height: 60px; display: flex; align-items: center; + justify-content: center; + flex: 1; border-bottom: 3px solid transparent; transition: all 0.3s ease-in-out; outline-offset: -2px; // Fixes the focus display issue in Firefox where it was not visible due to "overflow-x" on .navigation diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index 79195f232..f3e744a7c 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -24,7 +24,31 @@ /> </div> <!-- Navigation --> - <div class="navigation" role="menu"> + <nav> + <div + role="tablist" + class="navigation" + aria-label="Sélectionner le panneau mon compte" + [ngClass]="{ expand: true }" + > + <div + *ngFor="let tab of tabs" + class="tab" + role="tab" + tabindex="0" + aria-controls="posts" + [attr.aria-selected]="tab.route === activeTab ? true : false" + [ngClass]="{ active: tab.route === activeTab }" + (click)="navigateTo(tab.route)" + (keydown.enter)="navigateTo(tab.route)" + > + <span> + {{ tab.label }} + </span> + </div> + </div> + </nav> + <!-- <div class="navigation" role="menu"> <div class="tab" tabindex="0" @@ -65,10 +89,10 @@ > Description </div> - </div> + </div> --> <!-- Content of tabs --> <div class="content"> - <div *ngIf="currentTab === tabsEnum.details" class="detailsTab"> + <div *ngIf="activeTab === tabsEnum.details" class="detailsTab"> <app-input [id]="'name'" [label]="'Prénom'" @@ -92,7 +116,7 @@ /> </div> - <div *ngIf="currentTab === tabsEnum.credentials" class="credentialsTab"> + <div *ngIf="activeTab === tabsEnum.credentials" class="credentialsTab"> <div class="credentials"> <div class="inline"> <app-svg-icon [folder]="'tags'" [icon]="'mail'" [iconClass]="'icon-20'" /> @@ -123,7 +147,7 @@ </div> </div> - <div *ngIf="currentTab === tabsEnum.employer" class="employerJob"> + <div *ngIf="activeTab === tabsEnum.employer" class="employerJob"> <app-select-or-create [autocompleteFunction]="profileService.getEmployers.bind(profileService)" [name]="'Employeur'" @@ -149,7 +173,7 @@ /> </div> - <div *ngIf="currentTab === tabsEnum.description" class="descriptionTab"> + <div *ngIf="activeTab === tabsEnum.description" class="descriptionTab"> <app-textarea [id]="'description'" [label]="'Description'" @@ -160,7 +184,7 @@ </div> <!-- Footer --> - <div *ngIf="currentTab !== tabsEnum.credentials" class="footer"> + <div *ngIf="activeTab !== tabsEnum.credentials" class="footer"> <app-button [variant]="'secondary'" [label]="'Annuler'" (action)="goBack()" /> <app-button [variant]="'primary'" [label]="'Valider'" [disabled]="!isPageValid()" (action)="confirm()" /> </div> diff --git a/src/app/profile/edit/edit.component.scss b/src/app/profile/edit/edit.component.scss index 32672d9d1..423c2adbb 100644 --- a/src/app/profile/edit/edit.component.scss +++ b/src/app/profile/edit/edit.component.scss @@ -53,6 +53,50 @@ } } + nav { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + + border-bottom: 1px solid $grey-4; + + .navigation { + display: flex; + overflow-x: auto; + white-space: nowrap; + &.expand { + width: 100%; + } + + .tab { + cursor: pointer; + user-select: none; + @include font-regular-16; + box-sizing: border-box; + padding: 0 16px; + height: 60px; + display: flex; + align-items: center; + justify-content: center; + flex: 1; + border-bottom: 3px solid transparent; + transition: all 0.3s ease-in-out; + outline-offset: -2px; // Fixes the focus display issue in Firefox where it was not visible due to "overflow-x" on .navigation + &.active { + @include font-bold-16; + border-color: $grey-1; + } + &:hover { + border-color: $grey-4; + } + &:focus { + outline-color: $red; + } + } + } + } + .navigation { justify-content: flex-start; overflow-x: auto; diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index 2fe8d98a2..a60fa8fe9 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -34,7 +34,7 @@ type passwordStatuses = 'error' | 'info' | 'success'; }) export class EditComponent implements OnInit { public tabsEnum = tabsEnum; - public currentTab: tabsEnum = tabsEnum.details; + public activeTab: tabsEnum = tabsEnum.details; @Input() userProfile: User; public initialUserProfile: User; @@ -70,6 +70,13 @@ export class EditComponent implements OnInit { private canDeactivate = false; public appointmentModal = false; + public tabs = [ + { label: 'Coordonnées', route: this.tabsEnum.details }, + { label: 'Email et mot de passe', route: this.tabsEnum.credentials }, + { label: 'Employeur et fonction', route: this.tabsEnum.employer }, + { label: 'Description', route: this.tabsEnum.description }, + ]; + constructor( public profileService: ProfileService, private notificationService: NotificationService, @@ -80,7 +87,7 @@ export class EditComponent implements OnInit { ngOnInit(): void { if (history.state.data === 'description') { - this.currentTab = tabsEnum.description; + this.activeTab = tabsEnum.description; } this.profileService.getProfile().then((profile) => { if (profile.hasOwnProperty('withAppointment')) this.selectedRdvChoice = profile.withAppointment; @@ -181,7 +188,7 @@ export class EditComponent implements OnInit { } public navigateTo(tab: tabsEnum): void { - this.currentTab = tab; + this.activeTab = tab; } public cancel(): void { @@ -214,15 +221,15 @@ export class EditComponent implements OnInit { } public isPageValid(): boolean { - if (this.currentTab === tabsEnum.details) { + if (this.activeTab === tabsEnum.details) { return this.coordsHaveChanged() && this.phoneValid() && this.nameValid() && this.surnameValid(); - } else if (this.currentTab === tabsEnum.credentials) { + } else if (this.activeTab === tabsEnum.credentials) { if (this.emailModal) { return this.emailValid(this.newEmail) && this.newEmail === this.newEmailConfirm; } else if (this.passwordModal) { return this.passwordValid(this.newPassword) && this.newPassword === this.newPasswordConfirm; } - } else if (this.currentTab === tabsEnum.employer) { + } else if (this.activeTab === tabsEnum.employer) { return this.employerAndJobValid() && this.employerOrJobHasChanged(); } else if (this.descriptionHasChanged()) { return this.descriptionValid(); @@ -231,17 +238,17 @@ export class EditComponent implements OnInit { public confirm(): void { this.canDeactivate = true; - if (this.currentTab === tabsEnum.details) { + if (this.activeTab === tabsEnum.details) { this.confirmDetails(); - } else if (this.currentTab === tabsEnum.credentials) { + } else if (this.activeTab === tabsEnum.credentials) { if (this.emailModal) { this.confirmNewEmail(); } else if (this.passwordModal) { this.confirmNewPassword(); } - } else if (this.currentTab === tabsEnum.employer) { + } else if (this.activeTab === tabsEnum.employer) { this.confirmEmployer(); - } else if (this.currentTab === tabsEnum.description) { + } else if (this.activeTab === tabsEnum.description) { this.confirmDescription(); } } diff --git a/src/app/profile/personal-offer-edition/personal-offer-edition.component.html b/src/app/profile/personal-offer-edition/personal-offer-edition.component.html index 895ea56f9..e1a4a7f1b 100644 --- a/src/app/profile/personal-offer-edition/personal-offer-edition.component.html +++ b/src/app/profile/personal-offer-edition/personal-offer-edition.component.html @@ -26,29 +26,33 @@ /> </div> <!-- Navigation --> - <div class="navigation"> - <span - tabindex="0" - role="button" - [ngClass]="{ tab: true, selected: currentTab === tabsEnum.onlineProcedures }" - (click)="navigateTo(tabsEnum.onlineProcedures)" - (keyup.enter)="navigateTo(tabsEnum.onlineProcedures)" + <nav> + <div + role="tablist" + class="navigation" + aria-label="Sélectionner quelle offre changer" + [ngClass]="{ expand: true }" > - Démarches en ligne - </span> - <span - tabindex="0" - role="button" - [ngClass]="{ tab: true, selected: currentTab === tabsEnum.digitalSkills }" - (click)="navigateTo(tabsEnum.digitalSkills)" - (keyup.enter)="navigateTo(tabsEnum.digitalSkills)" - > - Compétences numériques - </span> - </div> + <div + *ngFor="let tab of tabs" + class="tab" + role="tab" + tabindex="0" + aria-controls="posts" + [attr.aria-selected]="tab.route === activeTab ? true : false" + [ngClass]="{ active: tab.route === activeTab }" + (click)="navigateTo(tab.route)" + (keydown.enter)="navigateTo(tab.route)" + > + <span> + {{ tab.label }} + </span> + </div> + </div> + </nav> <!-- Content of tabs --> <div class="content"> - <div *ngIf="currentTab === tabsEnum.onlineProcedures"> + <div *ngIf="activeTab === tabsEnum.onlineProcedures"> <app-accompaniment-picker *ngIf="personalOfferForm" [personalOfferForm]="personalOfferForm" @@ -56,7 +60,7 @@ /> </div> - <div *ngIf="currentTab === tabsEnum.digitalSkills"> + <div *ngIf="activeTab === tabsEnum.digitalSkills"> <app-training-type-picker *ngIf="personalOfferForm" [baseSkills]="personalOfferForm.get('categories').get('baseSkills').value" diff --git a/src/app/profile/personal-offer-edition/personal-offer-edition.component.scss b/src/app/profile/personal-offer-edition/personal-offer-edition.component.scss index 581ea7142..f9003259a 100644 --- a/src/app/profile/personal-offer-edition/personal-offer-edition.component.scss +++ b/src/app/profile/personal-offer-edition/personal-offer-edition.component.scss @@ -11,7 +11,6 @@ .edit-personal-offer { display: flex; flex-direction: column; - flex: 1; max-width: 980px; width: 100%; margin: 0 auto; @@ -59,31 +58,46 @@ } } - .navigation { - justify-content: flex-start; - overflow-x: auto; - white-space: nowrap; - border-bottom: 1px solid $grey-5; + nav { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; - .tab { - cursor: pointer; - user-select: none; - @include font-regular-14; - box-sizing: border-box; - padding: 0 16px; - height: 60px; + border-bottom: 1px solid $grey-4; + + .navigation { display: flex; - justify-content: center; - align-items: center; - flex: 1; - border-bottom: 3px solid transparent; - transition: all 0.3s ease-in-out; - &:hover { - border-color: $grey-4; + overflow-x: auto; + white-space: nowrap; + &.expand { + width: 100%; } - &.selected { - font-weight: bold; - border-color: $grey-1; + + .tab { + cursor: pointer; + user-select: none; + @include font-regular-16; + box-sizing: border-box; + padding: 0 16px; + height: 60px; + display: flex; + align-items: center; + justify-content: center; + flex: 1; + border-bottom: 3px solid transparent; + transition: all 0.3s ease-in-out; + outline-offset: -2px; // Fixes the focus display issue in Firefox where it was not visible due to "overflow-x" on .navigation + &.active { + @include font-bold-16; + border-color: $grey-1; + } + &:hover { + border-color: $grey-4; + } + &:focus { + outline-color: $red; + } } } } diff --git a/src/app/profile/personal-offer-edition/personal-offer-edition.component.ts b/src/app/profile/personal-offer-edition/personal-offer-edition.component.ts index 28461141e..f5b3ce244 100644 --- a/src/app/profile/personal-offer-edition/personal-offer-edition.component.ts +++ b/src/app/profile/personal-offer-edition/personal-offer-edition.component.ts @@ -21,7 +21,7 @@ enum tabsEnum { }) export class PersonalOfferEditionComponent implements OnInit { public tabsEnum = tabsEnum; - public currentTab: tabsEnum = tabsEnum.onlineProcedures; + public activeTab: tabsEnum = tabsEnum.onlineProcedures; public personalOffer: PersonalOffer; public personalOfferForm: UntypedFormGroup = null; @@ -31,6 +31,11 @@ export class PersonalOfferEditionComponent implements OnInit { public deleteOfferModal: boolean; public structureName: string; + public tabs = [ + { label: 'Démarches en ligne', route: this.tabsEnum.onlineProcedures }, + { label: 'Compétences numériques', route: this.tabsEnum.digitalSkills }, + ]; + constructor( private route: ActivatedRoute, private router: Router, @@ -69,7 +74,9 @@ export class PersonalOfferEditionComponent implements OnInit { // We sort modules alphabetically, except for the 'autres' module which is always at the end this.onlineProcedures = categ; const othersModule = this.onlineProcedures.modules.find((module) => module.id === 'autres'); - const sortedModules = this.onlineProcedures.modules.filter((module) => module.id !== 'autres').sort((a, b) => a.name.localeCompare(b.name)); + const sortedModules = this.onlineProcedures.modules + .filter((module) => module.id !== 'autres') + .sort((a, b) => a.name.localeCompare(b.name)); if (othersModule) sortedModules.push(othersModule); this.onlineProcedures.modules = sortedModules; break; @@ -86,7 +93,7 @@ export class PersonalOfferEditionComponent implements OnInit { } public navigateTo(tab: tabsEnum): void { - this.currentTab = tab; + this.activeTab = tab; } public cancel(): void { -- GitLab From 6626e299d77562cc07142ec748b6951fabb27460 Mon Sep 17 00:00:00 2001 From: Pierre Ecarlat <pecarlat@grandlyon.com> Date: Wed, 21 Aug 2024 16:48:11 +0200 Subject: [PATCH 03/11] Updated other admin tabs --- src/app/admin/admin.scss | 4 -- .../manage-employers.component.html | 4 +- .../manage-jobs/manage-jobs.component.html | 4 +- .../manage-users/manage-users.component.html | 4 +- .../admin-structures-list.component.html | 64 ++++++++++--------- .../admin-structures-list.component.scss | 6 +- 6 files changed, 37 insertions(+), 49 deletions(-) diff --git a/src/app/admin/admin.scss b/src/app/admin/admin.scss index 58b03d54b..232783dd8 100644 --- a/src/app/admin/admin.scss +++ b/src/app/admin/admin.scss @@ -1,10 +1,6 @@ @import 'color'; .adminLayout { - // display: flex; - // flex-direction: column; - // align-items: start; - // gap: 1rem; display: block; margin: auto; padding: 2rem 0; diff --git a/src/app/admin/components/manage-employers/manage-employers.component.html b/src/app/admin/components/manage-employers/manage-employers.component.html index be5309345..7bb145742 100644 --- a/src/app/admin/components/manage-employers/manage-employers.component.html +++ b/src/app/admin/components/manage-employers/manage-employers.component.html @@ -1,14 +1,12 @@ -<app-admin-header /> <div class="adminLayout"> + <app-admin-header /> <h2> Gestion des employeurs <span *ngIf="unvalidatedEmployers && validatedEmployers"> ({{ unvalidatedEmployers.length + validatedEmployers.length }}) </span> </h2> -</div> -<div class="adminLayout"> <h3 *ngIf="unvalidatedEmployers" class="title">Employeurs non validés ({{ unvalidatedEmployers.length }})</h3> <ag-grid-angular *ngIf="unvalidatedEmployers" diff --git a/src/app/admin/components/manage-jobs/manage-jobs.component.html b/src/app/admin/components/manage-jobs/manage-jobs.component.html index 7575dab47..0e4702bf3 100644 --- a/src/app/admin/components/manage-jobs/manage-jobs.component.html +++ b/src/app/admin/components/manage-jobs/manage-jobs.component.html @@ -1,12 +1,10 @@ -<app-admin-header /> <div class="adminLayout"> + <app-admin-header /> <h2> Gestion des fonctions <span *ngIf="unvalidatedJobs && validatedJobs"> ({{ unvalidatedJobs.length + validatedJobs.length }}) </span> </h2> -</div> -<div class="adminLayout"> <h3 *ngIf="unvalidatedJobs" class="title">Fonctions non validées ({{ unvalidatedJobs.length }})</h3> <ag-grid-angular *ngIf="unvalidatedJobs" diff --git a/src/app/admin/components/manage-users/manage-users.component.html b/src/app/admin/components/manage-users/manage-users.component.html index 7db18952d..297bd295e 100644 --- a/src/app/admin/components/manage-users/manage-users.component.html +++ b/src/app/admin/components/manage-users/manage-users.component.html @@ -1,14 +1,12 @@ -<app-admin-header /> <div class="adminLayout"> + <app-admin-header /> <h2> Gestion des utilisateurs <span *ngIf="unVerifiedUsers && unAttachedUsers && attachedUsers"> ({{ unVerifiedUsers.length + unAttachedUsers.length + attachedUsers.length }}) </span> </h2> -</div> -<div class="adminLayout"> <h3 *ngIf="unVerifiedUsers" class="title">Utilisateurs non vérifiés ({{ unVerifiedUsers.length }})</h3> <ag-grid-angular *ngIf="validatedJobs && validatedEmployers" diff --git a/src/app/admin/components/structures-list/admin-structures-list.component.html b/src/app/admin/components/structures-list/admin-structures-list.component.html index ea54f12c5..218b7051c 100644 --- a/src/app/admin/components/structures-list/admin-structures-list.component.html +++ b/src/app/admin/components/structures-list/admin-structures-list.component.html @@ -1,37 +1,39 @@ -<app-admin-header /> +<div class="adminLayout"> + <app-admin-header /> -<div class="filters-containers"> - <div *ngFor="let filterOption of filterOptions"> - <div class="filter"> - <app-radio-option - class="filter-option" - [id]="filterOption.value" - [label]="filterOption.label" - [value]="filterOption.value" - [selected]="filter === filterOption.value" - (click)="setFilter(filterOption.value)" - /> + <div class="filters-containers"> + <div *ngFor="let filterOption of filterOptions"> + <div class="filter"> + <app-radio-option + class="filter-option" + [id]="filterOption.value" + [label]="filterOption.label" + [value]="filterOption.value" + [selected]="filter === filterOption.value" + (click)="setFilter(filterOption.value)" + /> + </div> </div> </div> -</div> -<div *ngIf="isLoading" class="loader" aria-busy="true"> - <img class="loader-gif" src="/assets/gif/loader_circle.gif" alt="" /> -</div> -<div *ngIf="!isLoading" class="adminLayout"> - <div *ngFor="let section of filteredSections" class="section"> - <h3>{{ section.title }} ({{ section.data?.length || 0 }})</h3> - <ag-grid-angular - *ngIf="section.data?.length" - class="ag-theme-alpine" - domLayout="autoHeight" - style="width: 100%" - [gridOptions]="getGridContext(section.filter)" - [rowData]="section.data" - [columnDefs]="columnDefs" - [rowHeight]="rowHeight" - [ngClass]="section.cssClass" - /> - <div *ngIf="!section.data?.length" class="no-structures">Aucun renseignement</div> + <div *ngIf="isLoading" class="loader" aria-busy="true"> + <img class="loader-gif" src="/assets/gif/loader_circle.gif" alt="" /> + </div> + <div *ngIf="!isLoading"> + <div *ngFor="let section of filteredSections" class="section"> + <h3>{{ section.title }} ({{ section.data?.length || 0 }})</h3> + <ag-grid-angular + *ngIf="section.data?.length" + class="ag-theme-alpine" + domLayout="autoHeight" + style="width: 100%" + [gridOptions]="getGridContext(section.filter)" + [rowData]="section.data" + [columnDefs]="columnDefs" + [rowHeight]="rowHeight" + [ngClass]="section.cssClass" + /> + <div *ngIf="!section.data?.length" class="no-structures">Aucun renseignement</div> + </div> </div> </div> diff --git a/src/app/admin/components/structures-list/admin-structures-list.component.scss b/src/app/admin/components/structures-list/admin-structures-list.component.scss index a2fb1edba..f442b750f 100644 --- a/src/app/admin/components/structures-list/admin-structures-list.component.scss +++ b/src/app/admin/components/structures-list/admin-structures-list.component.scss @@ -19,12 +19,8 @@ } .filters-containers { - width: 80%; display: flex; - margin-left: 10%; - flex-direction: row; - align-items: center; - margin-bottom: 1rem; + margin-bottom: 2rem; gap: 0.5rem; } -- GitLab From 427f86457ea464f9fe243a677354eaceedb8fbcf Mon Sep 17 00:00:00 2001 From: Pierre Ecarlat <pecarlat@grandlyon.com> Date: Wed, 21 Aug 2024 16:53:19 +0200 Subject: [PATCH 04/11] Better design for BO --- src/app/admin/admin.scss | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/app/admin/admin.scss b/src/app/admin/admin.scss index 232783dd8..ff4af5a87 100644 --- a/src/app/admin/admin.scss +++ b/src/app/admin/admin.scss @@ -7,11 +7,14 @@ width: 80%; } +h3 { + margin: 1rem 0; +} + h3.inline { display: flex; flex-direction: row; align-items: center; - gap: 1rem; } .incomplete { -- GitLab From b70fe4e18c323a16facf85fbb86863f7f2c06422 Mon Sep 17 00:00:00 2001 From: Pierre Ecarlat <pecarlat@grandlyon.com> Date: Wed, 21 Aug 2024 17:31:16 +0200 Subject: [PATCH 05/11] updated post-header --- src/app/admin/admin.module.ts | 2 -- .../post-header/post-header.component.html | 20 +--------------- .../post-header/post-header.component.ts | 24 +++++++++---------- src/app/shared/components/index.ts | 3 +++ .../components/nav-bar/nav-bar.component.html | 0 .../components/nav-bar/nav-bar.component.scss | 0 .../components/nav-bar/nav-bar.component.ts | 0 7 files changed, 16 insertions(+), 33 deletions(-) rename src/app/{admin => shared}/components/nav-bar/nav-bar.component.html (100%) rename src/app/{admin => shared}/components/nav-bar/nav-bar.component.scss (100%) rename src/app/{admin => shared}/components/nav-bar/nav-bar.component.ts (100%) diff --git a/src/app/admin/admin.module.ts b/src/app/admin/admin.module.ts index 27e0dc8d6..b7b28df10 100644 --- a/src/app/admin/admin.module.ts +++ b/src/app/admin/admin.module.ts @@ -23,7 +23,6 @@ import { DeleteUserComponent } from './components/manage-users/delete-user/delet import { EmployerRendererComponent } from './components/manage-users/employer-renderer/employer-renderer.component'; import { JobRendererComponent } from './components/manage-users/job-renderer/job-renderer.component'; import { ManageUsersComponent } from './components/manage-users/manage-users.component'; -import { NavBarComponent } from './components/nav-bar/nav-bar.component'; import { AdminStructuresListComponent } from './components/structures-list/admin-structures-list.component'; @NgModule({ @@ -46,7 +45,6 @@ import { AdminStructuresListComponent } from './components/structures-list/admin ManageJobsComponent, ManageEmployersComponent, DeletedStructuresComponent, - NavBarComponent, AdminHeaderComponent, EspaceCoopCNFSComponent, ButtonCellRendererComponent, diff --git a/src/app/post/components/post-header/post-header.component.html b/src/app/post/components/post-header/post-header.component.html index 03ff2a6e8..85cee5cb1 100644 --- a/src/app/post/components/post-header/post-header.component.html +++ b/src/app/post/components/post-header/post-header.component.html @@ -8,23 +8,5 @@ </div> </div> - <nav> - <div role="tablist" class="navigation" aria-label="Filtrer les actualités" [ngClass]="{ expand: false }"> - <div - *ngFor="let tab of tags.others" - class="tab" - role="tab" - tabindex="0" - aria-controls="posts" - [attr.aria-selected]="tab.slug === mainActiveTag.slug ? true : false" - [ngClass]="{ active: tab.slug === mainActiveTag.slug || tab.name === mainActiveTag.slug }" - (click)="activateTag(tab)" - (keydown.enter)="activateTag(tab)" - > - <span> - {{ tab.name }} - </span> - </div> - </div> - </nav> + <app-nav-bar [tabs]="getTabsNames()" [currentTab]="currentTab" (clickedTab)="activateTag($event)" /> </div> diff --git a/src/app/post/components/post-header/post-header.component.ts b/src/app/post/components/post-header/post-header.component.ts index fd5c0a482..1e4e68ada 100644 --- a/src/app/post/components/post-header/post-header.component.ts +++ b/src/app/post/components/post-header/post-header.component.ts @@ -11,8 +11,8 @@ import { parseSlugToTag } from '../utils/NewsUtils'; }) export class PostHeaderComponent implements OnInit { public tags: TagWithMeta; - public mainActiveTag: Tag = new Tag({ slug: TagEnum.aLaUne }); public tagEnum = TagEnum; + public currentTab = 0; public checkedPublicTags: Tag[] = []; public checkedLocationTags: Tag[] = []; @@ -33,8 +33,9 @@ export class PostHeaderComponent implements OnInit { }); this.route.queryParams.subscribe((queryParams) => { + // We navigateTo distinct routes, so we need to recover the currentTab after rerouting if (queryParams.mainTag) { - this.mainActiveTag = new Tag({ slug: queryParams.mainTag }); + this.currentTab = this.tags.others.findIndex((tag) => tag.slug === queryParams.mainTag); } if (queryParams.publicTags) { this.checkedPublicTags = parseSlugToTag(queryParams.publicTags); @@ -45,6 +46,10 @@ export class PostHeaderComponent implements OnInit { }); } + public getTabsNames(): string[] { + return this.tags.others.map((tab) => tab.name); + } + private removeTagBySlug(slugToRemove: string): void { this.tags.others = this.tags.others.filter((tag) => tag.slug !== slugToRemove); } @@ -67,16 +72,11 @@ export class PostHeaderComponent implements OnInit { return nameTagA.localeCompare(nameTagB); } - public activateTag(tag: Tag): void { - this.mainActiveTag = tag; - this.setQueryParam(); - } - - private setQueryParam(): void { + public activateTag(tabIndex: number): void { this.router.navigate(['/actualites'], { relativeTo: this.route, queryParams: { - mainTag: this.getMainTag(), + mainTag: this.getMainTag(this.tags.others[tabIndex]), publicTags: this.checkedPublicTags.map((tag) => tag.slug), locationTags: this.checkedLocationTags.map((tag) => tag.slug), }, @@ -84,10 +84,10 @@ export class PostHeaderComponent implements OnInit { }); } - public getMainTag(): string { - if (this.mainActiveTag.slug === TagEnum.aLaUne) { + public getMainTag(tag: Tag): string { + if (tag.slug === TagEnum.aLaUne) { return ''; } - return this.mainActiveTag.slug === this.tagEnum.etudes ? this.mainActiveTag.name : this.mainActiveTag.slug; + return tag.slug === this.tagEnum.etudes ? tag.name : tag.slug; } } diff --git a/src/app/shared/components/index.ts b/src/app/shared/components/index.ts index c30311533..ce2234a5b 100644 --- a/src/app/shared/components/index.ts +++ b/src/app/shared/components/index.ts @@ -20,6 +20,7 @@ import { InputComponent } from './input/input.component'; import { LogoCardComponent } from './logo-card/logo-card.component'; import { MemberCardComponent } from './member-card/member-card.component'; import { ModalComponent } from './modal/modal.component'; +import { NavBarComponent } from './nav-bar/nav-bar.component'; import { PrintHeaderComponent } from './print-header/print-header.component'; import { PrintStructuresGridComponent } from './print-structures-grid/print-structures-grid.component'; import { RadioOptionComponent } from './radio-option/radio-option.component'; @@ -51,6 +52,7 @@ export { LogoCardComponent, MemberCardComponent, ModalComponent, + NavBarComponent, PrintHeaderComponent, PrintStructuresGridComponent, ProgressBarComponent, @@ -87,6 +89,7 @@ export const SharedComponents = [ MemberCardComponent, LogoCardComponent, ModalComponent, + NavBarComponent, ProgressBarComponent, PrintHeaderComponent, PrintStructuresGridComponent, diff --git a/src/app/admin/components/nav-bar/nav-bar.component.html b/src/app/shared/components/nav-bar/nav-bar.component.html similarity index 100% rename from src/app/admin/components/nav-bar/nav-bar.component.html rename to src/app/shared/components/nav-bar/nav-bar.component.html diff --git a/src/app/admin/components/nav-bar/nav-bar.component.scss b/src/app/shared/components/nav-bar/nav-bar.component.scss similarity index 100% rename from src/app/admin/components/nav-bar/nav-bar.component.scss rename to src/app/shared/components/nav-bar/nav-bar.component.scss diff --git a/src/app/admin/components/nav-bar/nav-bar.component.ts b/src/app/shared/components/nav-bar/nav-bar.component.ts similarity index 100% rename from src/app/admin/components/nav-bar/nav-bar.component.ts rename to src/app/shared/components/nav-bar/nav-bar.component.ts -- GitLab From c68bce682e9f156ffa4ce3cfc9386e67b073cd3c Mon Sep 17 00:00:00 2001 From: Pierre Ecarlat <pecarlat@grandlyon.com> Date: Thu, 22 Aug 2024 09:23:36 +0200 Subject: [PATCH 06/11] Updated moncompte --- src/app/profile/edit/edit.component.html | 73 +++--------------------- src/app/profile/edit/edit.component.ts | 22 +++---- 2 files changed, 16 insertions(+), 79 deletions(-) diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index f3e744a7c..5b4fe696f 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -24,72 +24,13 @@ /> </div> <!-- Navigation --> - <nav> - <div - role="tablist" - class="navigation" - aria-label="Sélectionner le panneau mon compte" - [ngClass]="{ expand: true }" - > - <div - *ngFor="let tab of tabs" - class="tab" - role="tab" - tabindex="0" - aria-controls="posts" - [attr.aria-selected]="tab.route === activeTab ? true : false" - [ngClass]="{ active: tab.route === activeTab }" - (click)="navigateTo(tab.route)" - (keydown.enter)="navigateTo(tab.route)" - > - <span> - {{ tab.label }} - </span> - </div> - </div> - </nav> - <!-- <div class="navigation" role="menu"> - <div - class="tab" - tabindex="0" - role="menuitem" - [ngClass]="{ selected: currentTab === tabsEnum.details }" - (click)="navigateTo(tabsEnum.details)" - (keyup.enter)="navigateTo(tabsEnum.details)" - > - Coordonnées - </div> - <div - class="tab" - tabindex="0" - role="menuitem" - [ngClass]="{ selected: currentTab === tabsEnum.credentials }" - (click)="navigateTo(tabsEnum.credentials)" - (keyup.enter)="navigateTo(tabsEnum.credentials)" - > - Email et mot de passe - </div> - <div - class="tab" - tabindex="0" - role="menuitem" - [ngClass]="{ selected: currentTab === tabsEnum.employer }" - (click)="navigateTo(tabsEnum.employer)" - (keyup.enter)="navigateTo(tabsEnum.employer)" - > - Employeur et fonction - </div> - <div - class="tab" - tabindex="0" - role="menuitem" - [ngClass]="{ selected: currentTab === tabsEnum.description }" - (click)="navigateTo(tabsEnum.description)" - (keyup.enter)="navigateTo(tabsEnum.description)" - > - Description - </div> - </div> --> + <app-nav-bar + [tabs]="getTabsNames()" + [currentTab]="activeTab" + [shouldExpand]="true" + (clickedTab)="changeTab($event)" + /> + <!-- Content of tabs --> <div class="content"> <div *ngIf="activeTab === tabsEnum.details" class="detailsTab"> diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index a60fa8fe9..8c2c87961 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -16,7 +16,6 @@ enum tabsEnum { credentials, employer, description, - avatar, } enum showPasswordEnum { @@ -34,7 +33,7 @@ type passwordStatuses = 'error' | 'info' | 'success'; }) export class EditComponent implements OnInit { public tabsEnum = tabsEnum; - public activeTab: tabsEnum = tabsEnum.details; + public activeTab = tabsEnum.details; @Input() userProfile: User; public initialUserProfile: User; @@ -70,13 +69,6 @@ export class EditComponent implements OnInit { private canDeactivate = false; public appointmentModal = false; - public tabs = [ - { label: 'Coordonnées', route: this.tabsEnum.details }, - { label: 'Email et mot de passe', route: this.tabsEnum.credentials }, - { label: 'Employeur et fonction', route: this.tabsEnum.employer }, - { label: 'Description', route: this.tabsEnum.description }, - ]; - constructor( public profileService: ProfileService, private notificationService: NotificationService, @@ -106,6 +98,14 @@ export class EditComponent implements OnInit { history.back(); } + public getTabsNames(): string[] { + return ['Coordonnées', 'Email et mot de passe', 'Employeur et fonction', 'Description']; + } + + public changeTab(tab: number): void { + this.activeTab = tab; + } + public phoneValid(): boolean { return Boolean(this.userProfile.phone.match(CustomRegExp.PHONE)); } @@ -187,10 +187,6 @@ export class EditComponent implements OnInit { return success ? 'success' : 'error'; } - public navigateTo(tab: tabsEnum): void { - this.activeTab = tab; - } - public cancel(): void { this.userProfile = { ...this.initialUserProfile }; } -- GitLab From 715861e93ca0d6820d70cea5d59807bcce0fdc8e Mon Sep 17 00:00:00 2001 From: Pierre Ecarlat <pecarlat@grandlyon.com> Date: Thu, 22 Aug 2024 09:52:26 +0200 Subject: [PATCH 07/11] Updated personnal offer edition --- .../post-header/post-header.component.scss | 44 ----------- src/app/profile/edit/edit.component.scss | 75 ------------------- .../personal-offer-edition.component.html | 30 ++------ .../personal-offer-edition.component.scss | 44 ----------- .../personal-offer-edition.component.ts | 17 ++--- 5 files changed, 14 insertions(+), 196 deletions(-) diff --git a/src/app/post/components/post-header/post-header.component.scss b/src/app/post/components/post-header/post-header.component.scss index 438ca2b20..a516d2d25 100644 --- a/src/app/post/components/post-header/post-header.component.scss +++ b/src/app/post/components/post-header/post-header.component.scss @@ -13,47 +13,3 @@ color: $grey-3; } } - -nav { - display: flex; - justify-content: space-between; - align-items: center; - width: 100%; - - border-bottom: 1px solid $grey-4; - - .navigation { - display: flex; - overflow-x: auto; - white-space: nowrap; - &.expand { - width: 100%; - } - - .tab { - cursor: pointer; - user-select: none; - @include font-regular-16; - box-sizing: border-box; - padding: 0 16px; - height: 60px; - display: flex; - align-items: center; - justify-content: center; - flex: 1; - border-bottom: 3px solid transparent; - transition: all 0.3s ease-in-out; - outline-offset: -2px; // Fixes the focus display issue in Firefox where it was not visible due to "overflow-x" on .navigation - &.active { - @include font-bold-16; - border-color: $grey-1; - } - &:hover { - border-color: $grey-4; - } - &:focus { - outline-color: $red; - } - } - } -} diff --git a/src/app/profile/edit/edit.component.scss b/src/app/profile/edit/edit.component.scss index 423c2adbb..62c4eac23 100644 --- a/src/app/profile/edit/edit.component.scss +++ b/src/app/profile/edit/edit.component.scss @@ -53,81 +53,6 @@ } } - nav { - display: flex; - justify-content: space-between; - align-items: center; - width: 100%; - - border-bottom: 1px solid $grey-4; - - .navigation { - display: flex; - overflow-x: auto; - white-space: nowrap; - &.expand { - width: 100%; - } - - .tab { - cursor: pointer; - user-select: none; - @include font-regular-16; - box-sizing: border-box; - padding: 0 16px; - height: 60px; - display: flex; - align-items: center; - justify-content: center; - flex: 1; - border-bottom: 3px solid transparent; - transition: all 0.3s ease-in-out; - outline-offset: -2px; // Fixes the focus display issue in Firefox where it was not visible due to "overflow-x" on .navigation - &.active { - @include font-bold-16; - border-color: $grey-1; - } - &:hover { - border-color: $grey-4; - } - &:focus { - outline-color: $red; - } - } - } - } - - .navigation { - justify-content: flex-start; - overflow-x: auto; - white-space: nowrap; - border-bottom: 1px solid $grey-5; - - .tab { - cursor: pointer; - user-select: none; - @include font-regular-16; - box-sizing: border-box; - padding: 0 16px; - height: 60px; - display: flex; - justify-content: center; - align-items: center; - flex: 1; - border-bottom: 3px solid transparent; - transition: all 0.3s ease-in-out; - - &:hover { - border-color: $grey-4; - } - - &.selected { - font-weight: bold; - border-color: $grey-1; - } - } - } - .content { flex: 1; max-width: 600px; diff --git a/src/app/profile/personal-offer-edition/personal-offer-edition.component.html b/src/app/profile/personal-offer-edition/personal-offer-edition.component.html index e1a4a7f1b..b05d37e8c 100644 --- a/src/app/profile/personal-offer-edition/personal-offer-edition.component.html +++ b/src/app/profile/personal-offer-edition/personal-offer-edition.component.html @@ -26,30 +26,12 @@ /> </div> <!-- Navigation --> - <nav> - <div - role="tablist" - class="navigation" - aria-label="Sélectionner quelle offre changer" - [ngClass]="{ expand: true }" - > - <div - *ngFor="let tab of tabs" - class="tab" - role="tab" - tabindex="0" - aria-controls="posts" - [attr.aria-selected]="tab.route === activeTab ? true : false" - [ngClass]="{ active: tab.route === activeTab }" - (click)="navigateTo(tab.route)" - (keydown.enter)="navigateTo(tab.route)" - > - <span> - {{ tab.label }} - </span> - </div> - </div> - </nav> + <app-nav-bar + [tabs]="getTabsNames()" + [currentTab]="activeTab" + [shouldExpand]="true" + (clickedTab)="changeTab($event)" + /> <!-- Content of tabs --> <div class="content"> <div *ngIf="activeTab === tabsEnum.onlineProcedures"> diff --git a/src/app/profile/personal-offer-edition/personal-offer-edition.component.scss b/src/app/profile/personal-offer-edition/personal-offer-edition.component.scss index f9003259a..cde2cb5a3 100644 --- a/src/app/profile/personal-offer-edition/personal-offer-edition.component.scss +++ b/src/app/profile/personal-offer-edition/personal-offer-edition.component.scss @@ -58,50 +58,6 @@ } } - nav { - display: flex; - justify-content: space-between; - align-items: center; - width: 100%; - - border-bottom: 1px solid $grey-4; - - .navigation { - display: flex; - overflow-x: auto; - white-space: nowrap; - &.expand { - width: 100%; - } - - .tab { - cursor: pointer; - user-select: none; - @include font-regular-16; - box-sizing: border-box; - padding: 0 16px; - height: 60px; - display: flex; - align-items: center; - justify-content: center; - flex: 1; - border-bottom: 3px solid transparent; - transition: all 0.3s ease-in-out; - outline-offset: -2px; // Fixes the focus display issue in Firefox where it was not visible due to "overflow-x" on .navigation - &.active { - @include font-bold-16; - border-color: $grey-1; - } - &:hover { - border-color: $grey-4; - } - &:focus { - outline-color: $red; - } - } - } - } - .content { flex: 1; max-width: 600px; diff --git a/src/app/profile/personal-offer-edition/personal-offer-edition.component.ts b/src/app/profile/personal-offer-edition/personal-offer-edition.component.ts index f5b3ce244..2966c1c7a 100644 --- a/src/app/profile/personal-offer-edition/personal-offer-edition.component.ts +++ b/src/app/profile/personal-offer-edition/personal-offer-edition.component.ts @@ -31,11 +31,6 @@ export class PersonalOfferEditionComponent implements OnInit { public deleteOfferModal: boolean; public structureName: string; - public tabs = [ - { label: 'Démarches en ligne', route: this.tabsEnum.onlineProcedures }, - { label: 'Compétences numériques', route: this.tabsEnum.digitalSkills }, - ]; - constructor( private route: ActivatedRoute, private router: Router, @@ -56,6 +51,14 @@ export class PersonalOfferEditionComponent implements OnInit { this.structureName = history.state.structureName; } + public getTabsNames(): string[] { + return ['Démarches en ligne', 'Compétences numériques']; + } + + public changeTab(tab: number): void { + this.activeTab = tab; + } + private createPersonalOfferForm(personalOfferState): UntypedFormGroup { return new UntypedFormGroup({ categories: new UntypedFormGroup({ @@ -92,10 +95,6 @@ export class PersonalOfferEditionComponent implements OnInit { }); } - public navigateTo(tab: tabsEnum): void { - this.activeTab = tab; - } - public cancel(): void { this.personalOfferForm = this.createPersonalOfferForm(this.initialPersonalOffer); } -- GitLab From f3da6a73e70b7d36dd9f602e3b4c8da2ad308869 Mon Sep 17 00:00:00 2001 From: Pierre Ecarlat <pecarlat@grandlyon.com> Date: Thu, 22 Aug 2024 09:57:30 +0200 Subject: [PATCH 08/11] renamed to currentTab --- src/app/profile/edit/edit.component.html | 12 +++++------ src/app/profile/edit/edit.component.ts | 20 +++++++++---------- .../personal-offer-edition.component.html | 6 +++--- .../personal-offer-edition.component.ts | 4 ++-- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index 5b4fe696f..fdc12f5c6 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -26,14 +26,14 @@ <!-- Navigation --> <app-nav-bar [tabs]="getTabsNames()" - [currentTab]="activeTab" + [currentTab]="currentTab" [shouldExpand]="true" (clickedTab)="changeTab($event)" /> <!-- Content of tabs --> <div class="content"> - <div *ngIf="activeTab === tabsEnum.details" class="detailsTab"> + <div *ngIf="currentTab === tabsEnum.details" class="detailsTab"> <app-input [id]="'name'" [label]="'Prénom'" @@ -57,7 +57,7 @@ /> </div> - <div *ngIf="activeTab === tabsEnum.credentials" class="credentialsTab"> + <div *ngIf="currentTab === tabsEnum.credentials" class="credentialsTab"> <div class="credentials"> <div class="inline"> <app-svg-icon [folder]="'tags'" [icon]="'mail'" [iconClass]="'icon-20'" /> @@ -88,7 +88,7 @@ </div> </div> - <div *ngIf="activeTab === tabsEnum.employer" class="employerJob"> + <div *ngIf="currentTab === tabsEnum.employer" class="employerJob"> <app-select-or-create [autocompleteFunction]="profileService.getEmployers.bind(profileService)" [name]="'Employeur'" @@ -114,7 +114,7 @@ /> </div> - <div *ngIf="activeTab === tabsEnum.description" class="descriptionTab"> + <div *ngIf="currentTab === tabsEnum.description" class="descriptionTab"> <app-textarea [id]="'description'" [label]="'Description'" @@ -125,7 +125,7 @@ </div> <!-- Footer --> - <div *ngIf="activeTab !== tabsEnum.credentials" class="footer"> + <div *ngIf="currentTab !== tabsEnum.credentials" class="footer"> <app-button [variant]="'secondary'" [label]="'Annuler'" (action)="goBack()" /> <app-button [variant]="'primary'" [label]="'Valider'" [disabled]="!isPageValid()" (action)="confirm()" /> </div> diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index 8c2c87961..8646bac23 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -33,7 +33,7 @@ type passwordStatuses = 'error' | 'info' | 'success'; }) export class EditComponent implements OnInit { public tabsEnum = tabsEnum; - public activeTab = tabsEnum.details; + public currentTab = tabsEnum.details; @Input() userProfile: User; public initialUserProfile: User; @@ -79,7 +79,7 @@ export class EditComponent implements OnInit { ngOnInit(): void { if (history.state.data === 'description') { - this.activeTab = tabsEnum.description; + this.currentTab = tabsEnum.description; } this.profileService.getProfile().then((profile) => { if (profile.hasOwnProperty('withAppointment')) this.selectedRdvChoice = profile.withAppointment; @@ -103,7 +103,7 @@ export class EditComponent implements OnInit { } public changeTab(tab: number): void { - this.activeTab = tab; + this.currentTab = tab; } public phoneValid(): boolean { @@ -217,15 +217,15 @@ export class EditComponent implements OnInit { } public isPageValid(): boolean { - if (this.activeTab === tabsEnum.details) { + if (this.currentTab === tabsEnum.details) { return this.coordsHaveChanged() && this.phoneValid() && this.nameValid() && this.surnameValid(); - } else if (this.activeTab === tabsEnum.credentials) { + } else if (this.currentTab === tabsEnum.credentials) { if (this.emailModal) { return this.emailValid(this.newEmail) && this.newEmail === this.newEmailConfirm; } else if (this.passwordModal) { return this.passwordValid(this.newPassword) && this.newPassword === this.newPasswordConfirm; } - } else if (this.activeTab === tabsEnum.employer) { + } else if (this.currentTab === tabsEnum.employer) { return this.employerAndJobValid() && this.employerOrJobHasChanged(); } else if (this.descriptionHasChanged()) { return this.descriptionValid(); @@ -234,17 +234,17 @@ export class EditComponent implements OnInit { public confirm(): void { this.canDeactivate = true; - if (this.activeTab === tabsEnum.details) { + if (this.currentTab === tabsEnum.details) { this.confirmDetails(); - } else if (this.activeTab === tabsEnum.credentials) { + } else if (this.currentTab === tabsEnum.credentials) { if (this.emailModal) { this.confirmNewEmail(); } else if (this.passwordModal) { this.confirmNewPassword(); } - } else if (this.activeTab === tabsEnum.employer) { + } else if (this.currentTab === tabsEnum.employer) { this.confirmEmployer(); - } else if (this.activeTab === tabsEnum.description) { + } else if (this.currentTab === tabsEnum.description) { this.confirmDescription(); } } diff --git a/src/app/profile/personal-offer-edition/personal-offer-edition.component.html b/src/app/profile/personal-offer-edition/personal-offer-edition.component.html index b05d37e8c..81153edba 100644 --- a/src/app/profile/personal-offer-edition/personal-offer-edition.component.html +++ b/src/app/profile/personal-offer-edition/personal-offer-edition.component.html @@ -28,13 +28,13 @@ <!-- Navigation --> <app-nav-bar [tabs]="getTabsNames()" - [currentTab]="activeTab" + [currentTab]="currentTab" [shouldExpand]="true" (clickedTab)="changeTab($event)" /> <!-- Content of tabs --> <div class="content"> - <div *ngIf="activeTab === tabsEnum.onlineProcedures"> + <div *ngIf="currentTab === tabsEnum.onlineProcedures"> <app-accompaniment-picker *ngIf="personalOfferForm" [personalOfferForm]="personalOfferForm" @@ -42,7 +42,7 @@ /> </div> - <div *ngIf="activeTab === tabsEnum.digitalSkills"> + <div *ngIf="currentTab === tabsEnum.digitalSkills"> <app-training-type-picker *ngIf="personalOfferForm" [baseSkills]="personalOfferForm.get('categories').get('baseSkills').value" diff --git a/src/app/profile/personal-offer-edition/personal-offer-edition.component.ts b/src/app/profile/personal-offer-edition/personal-offer-edition.component.ts index 2966c1c7a..5b349639d 100644 --- a/src/app/profile/personal-offer-edition/personal-offer-edition.component.ts +++ b/src/app/profile/personal-offer-edition/personal-offer-edition.component.ts @@ -21,7 +21,7 @@ enum tabsEnum { }) export class PersonalOfferEditionComponent implements OnInit { public tabsEnum = tabsEnum; - public activeTab: tabsEnum = tabsEnum.onlineProcedures; + public currentTab: tabsEnum = tabsEnum.onlineProcedures; public personalOffer: PersonalOffer; public personalOfferForm: UntypedFormGroup = null; @@ -56,7 +56,7 @@ export class PersonalOfferEditionComponent implements OnInit { } public changeTab(tab: number): void { - this.activeTab = tab; + this.currentTab = tab; } private createPersonalOfferForm(personalOfferState): UntypedFormGroup { -- GitLab From 3367c6f0745e5e7fca4f11ed2419e0648daae491 Mon Sep 17 00:00:00 2001 From: Pierre Ecarlat <pecarlat@grandlyon.com> Date: Thu, 22 Aug 2024 14:46:54 +0200 Subject: [PATCH 09/11] Added storybook --- .../components/nav-bar/nav-bar.component.ts | 2 +- .../components/nav-bar/nav-bar.stories.ts | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 src/app/shared/components/nav-bar/nav-bar.stories.ts diff --git a/src/app/shared/components/nav-bar/nav-bar.component.ts b/src/app/shared/components/nav-bar/nav-bar.component.ts index 87cc771b0..b46cb5ad2 100644 --- a/src/app/shared/components/nav-bar/nav-bar.component.ts +++ b/src/app/shared/components/nav-bar/nav-bar.component.ts @@ -7,8 +7,8 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; }) export class NavBarComponent { @Input({ required: true }) tabs: string[]; - @Input() currentTab = 0; @Input() shouldExpand = false; + @Input() currentTab = 0; @Output() clickedTab = new EventEmitter<number>(); public onClickTab(tabIndex: number): void { diff --git a/src/app/shared/components/nav-bar/nav-bar.stories.ts b/src/app/shared/components/nav-bar/nav-bar.stories.ts new file mode 100644 index 000000000..c3ac5ce69 --- /dev/null +++ b/src/app/shared/components/nav-bar/nav-bar.stories.ts @@ -0,0 +1,36 @@ +import { CommonModule } from '@angular/common'; +import type { Meta, StoryObj } from '@storybook/angular'; +import { moduleMetadata } from '@storybook/angular'; +import { SvgIconComponent } from '../svg-icon/svg-icon.component'; +import { TagItemComponent } from '../tag-item/tag-item.component'; +import { NavBarComponent } from './nav-bar.component'; + +// More on how to set up stories at: https://storybook.js.org/docs/angular/writing-stories/introduction +const meta: Meta<NavBarComponent> = { + title: 'Components/NavBar', + component: NavBarComponent, + tags: ['autodocs'], + decorators: [ + moduleMetadata({ + declarations: [TagItemComponent, SvgIconComponent], + imports: [CommonModule], + }), + ], + argTypes: {}, +}; + +export default meta; +type Story = StoryObj<NavBarComponent>; + +export const NavBar: Story = { + args: { + tabs: ['tab 1', 'tab 2'], + }, +}; + +export const ExpandedNavBar: Story = { + args: { + tabs: ['tab 1', 'tab 2'], + shouldExpand: true, + }, +}; -- GitLab From 821702413524c6579b4800423a28fe8e905b1dd5 Mon Sep 17 00:00:00 2001 From: Pierre Ecarlat <pecarlat@grandlyon.com> Date: Wed, 28 Aug 2024 11:21:08 +0200 Subject: [PATCH 10/11] Added aria-labels + controls --- src/app/admin/admin.scss | 3 ++- .../admin-header/admin-header.component.html | 7 ++++++- .../components/post-header/post-header.component.html | 7 ++++++- src/app/profile/edit/edit.component.html | 10 ++++++---- src/app/profile/edit/edit.component.ts | 4 ++++ .../personal-offer-edition.component.html | 6 ++++-- .../personal-offer-edition.component.ts | 4 ++++ .../shared/components/nav-bar/nav-bar.component.html | 9 ++------- src/app/shared/components/nav-bar/nav-bar.component.ts | 6 ++++++ src/app/shared/components/nav-bar/nav-bar.stories.ts | 4 +--- 10 files changed, 41 insertions(+), 19 deletions(-) diff --git a/src/app/admin/admin.scss b/src/app/admin/admin.scss index ff4af5a87..017d2f5dd 100644 --- a/src/app/admin/admin.scss +++ b/src/app/admin/admin.scss @@ -7,7 +7,8 @@ width: 80%; } -h3 { +h3, +h2 { margin: 1rem 0; } diff --git a/src/app/admin/components/admin-header/admin-header.component.html b/src/app/admin/components/admin-header/admin-header.component.html index 16baadd89..462fa25f6 100644 --- a/src/app/admin/components/admin-header/admin-header.component.html +++ b/src/app/admin/components/admin-header/admin-header.component.html @@ -3,5 +3,10 @@ <h1>Administration</h1> <app-button [variant]="'secondary'" [label]="'Ghost'" [size]="'small'" (action)="openGhost()" /> </div> - <app-nav-bar [tabs]="getTabsNames()" [currentTab]="currentTab" (clickedTab)="navigateTo($event)" /> + <app-nav-bar + [tabs]="getTabsNames()" + [currentTab]="currentTab" + [ariaLabel]="'Sélectionner le panneau admin'" + (clickedTab)="navigateTo($event)" + /> </div> diff --git a/src/app/post/components/post-header/post-header.component.html b/src/app/post/components/post-header/post-header.component.html index 85cee5cb1..e7ee9f473 100644 --- a/src/app/post/components/post-header/post-header.component.html +++ b/src/app/post/components/post-header/post-header.component.html @@ -8,5 +8,10 @@ </div> </div> - <app-nav-bar [tabs]="getTabsNames()" [currentTab]="currentTab" (clickedTab)="activateTag($event)" /> + <app-nav-bar + [tabs]="getTabsNames()" + [currentTab]="currentTab" + [ariaLabel]="'Sélectionner une catégorie d\'actualités'" + (clickedTab)="activateTag($event)" + /> </div> diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index fdc12f5c6..bfffb8af5 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -28,12 +28,14 @@ [tabs]="getTabsNames()" [currentTab]="currentTab" [shouldExpand]="true" + [ariaLabel]="'Sélectionner quelle section de votre profil éditer'" + [ariaControls]="getTabsIds()" (clickedTab)="changeTab($event)" /> <!-- Content of tabs --> <div class="content"> - <div *ngIf="currentTab === tabsEnum.details" class="detailsTab"> + <div *ngIf="currentTab === tabsEnum.details" id="detailsTab" class="detailsTab"> <app-input [id]="'name'" [label]="'Prénom'" @@ -57,7 +59,7 @@ /> </div> - <div *ngIf="currentTab === tabsEnum.credentials" class="credentialsTab"> + <div *ngIf="currentTab === tabsEnum.credentials" id="credentialsTab" class="credentialsTab"> <div class="credentials"> <div class="inline"> <app-svg-icon [folder]="'tags'" [icon]="'mail'" [iconClass]="'icon-20'" /> @@ -88,7 +90,7 @@ </div> </div> - <div *ngIf="currentTab === tabsEnum.employer" class="employerJob"> + <div *ngIf="currentTab === tabsEnum.employer" id="employerJob" class="employerJob"> <app-select-or-create [autocompleteFunction]="profileService.getEmployers.bind(profileService)" [name]="'Employeur'" @@ -114,7 +116,7 @@ /> </div> - <div *ngIf="currentTab === tabsEnum.description" class="descriptionTab"> + <div *ngIf="currentTab === tabsEnum.description" id="descriptionTab" class="descriptionTab"> <app-textarea [id]="'description'" [label]="'Description'" diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index 8646bac23..1c28692ec 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -102,6 +102,10 @@ export class EditComponent implements OnInit { return ['Coordonnées', 'Email et mot de passe', 'Employeur et fonction', 'Description']; } + public getTabsIds(): string[] { + return ['detailsTab', 'credentials', 'employerJob', 'descriptionTab']; + } + public changeTab(tab: number): void { this.currentTab = tab; } diff --git a/src/app/profile/personal-offer-edition/personal-offer-edition.component.html b/src/app/profile/personal-offer-edition/personal-offer-edition.component.html index 81153edba..0324e56a4 100644 --- a/src/app/profile/personal-offer-edition/personal-offer-edition.component.html +++ b/src/app/profile/personal-offer-edition/personal-offer-edition.component.html @@ -30,11 +30,13 @@ [tabs]="getTabsNames()" [currentTab]="currentTab" [shouldExpand]="true" + [ariaLabel]="'Sélectionner le type d\'offre personnelle'" + [ariaControls]="getTabsIds()" (clickedTab)="changeTab($event)" /> <!-- Content of tabs --> <div class="content"> - <div *ngIf="currentTab === tabsEnum.onlineProcedures"> + <div *ngIf="currentTab === tabsEnum.onlineProcedures" id="onlineProcedures"> <app-accompaniment-picker *ngIf="personalOfferForm" [personalOfferForm]="personalOfferForm" @@ -42,7 +44,7 @@ /> </div> - <div *ngIf="currentTab === tabsEnum.digitalSkills"> + <div *ngIf="currentTab === tabsEnum.digitalSkills" id="digitalSkills"> <app-training-type-picker *ngIf="personalOfferForm" [baseSkills]="personalOfferForm.get('categories').get('baseSkills').value" diff --git a/src/app/profile/personal-offer-edition/personal-offer-edition.component.ts b/src/app/profile/personal-offer-edition/personal-offer-edition.component.ts index 5b349639d..815eafa41 100644 --- a/src/app/profile/personal-offer-edition/personal-offer-edition.component.ts +++ b/src/app/profile/personal-offer-edition/personal-offer-edition.component.ts @@ -55,6 +55,10 @@ export class PersonalOfferEditionComponent implements OnInit { return ['Démarches en ligne', 'Compétences numériques']; } + public getTabsIds(): string[] { + return ['onlineProcedures', 'digitalSkills']; + } + public changeTab(tab: number): void { this.currentTab = tab; } diff --git a/src/app/shared/components/nav-bar/nav-bar.component.html b/src/app/shared/components/nav-bar/nav-bar.component.html index 5aa452b8e..0e708821d 100644 --- a/src/app/shared/components/nav-bar/nav-bar.component.html +++ b/src/app/shared/components/nav-bar/nav-bar.component.html @@ -1,16 +1,11 @@ <nav> - <div - role="tablist" - class="navigation" - aria-label="Sélectionner le panneau admin" - [ngClass]="{ expand: shouldExpand }" - > + <div role="tablist" class="navigation" [attr.aria-label]="ariaLabel" [ngClass]="{ expand: shouldExpand }"> <div *ngFor="let tab of tabs; let i = index" class="tab" role="tab" tabindex="0" - aria-controls="posts" + [attr.aria-controls]="getControl(i)" [attr.aria-selected]="isActive(i)" [ngClass]="{ active: isActive(i) }" (click)="onClickTab(i)" diff --git a/src/app/shared/components/nav-bar/nav-bar.component.ts b/src/app/shared/components/nav-bar/nav-bar.component.ts index b46cb5ad2..33f943ee5 100644 --- a/src/app/shared/components/nav-bar/nav-bar.component.ts +++ b/src/app/shared/components/nav-bar/nav-bar.component.ts @@ -7,8 +7,10 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; }) export class NavBarComponent { @Input({ required: true }) tabs: string[]; + @Input({ required: true }) ariaLabel: string; @Input() shouldExpand = false; @Input() currentTab = 0; + @Input() ariaControls = []; @Output() clickedTab = new EventEmitter<number>(); public onClickTab(tabIndex: number): void { @@ -19,4 +21,8 @@ export class NavBarComponent { public isActive(idx: number): boolean { return this.currentTab === idx; } + + public getControl(index: number): string | null { + return this.ariaControls[index] ?? null; + } } diff --git a/src/app/shared/components/nav-bar/nav-bar.stories.ts b/src/app/shared/components/nav-bar/nav-bar.stories.ts index c3ac5ce69..42768e544 100644 --- a/src/app/shared/components/nav-bar/nav-bar.stories.ts +++ b/src/app/shared/components/nav-bar/nav-bar.stories.ts @@ -1,8 +1,6 @@ import { CommonModule } from '@angular/common'; import type { Meta, StoryObj } from '@storybook/angular'; import { moduleMetadata } from '@storybook/angular'; -import { SvgIconComponent } from '../svg-icon/svg-icon.component'; -import { TagItemComponent } from '../tag-item/tag-item.component'; import { NavBarComponent } from './nav-bar.component'; // More on how to set up stories at: https://storybook.js.org/docs/angular/writing-stories/introduction @@ -12,7 +10,7 @@ const meta: Meta<NavBarComponent> = { tags: ['autodocs'], decorators: [ moduleMetadata({ - declarations: [TagItemComponent, SvgIconComponent], + declarations: [], imports: [CommonModule], }), ], -- GitLab From a2cd5985efc0421ef5f7af9ec02222fd89259689 Mon Sep 17 00:00:00 2001 From: Pierre Ecarlat <pecarlat@grandlyon.com> Date: Thu, 29 Aug 2024 13:12:52 +0200 Subject: [PATCH 11/11] Removed escaping character --- src/app/post/components/post-header/post-header.component.html | 2 +- .../personal-offer-edition.component.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/post/components/post-header/post-header.component.html b/src/app/post/components/post-header/post-header.component.html index e7ee9f473..d489ed9cc 100644 --- a/src/app/post/components/post-header/post-header.component.html +++ b/src/app/post/components/post-header/post-header.component.html @@ -9,9 +9,9 @@ </div> <app-nav-bar + ariaLabel="Sélectionner une catégorie d'actualités" [tabs]="getTabsNames()" [currentTab]="currentTab" - [ariaLabel]="'Sélectionner une catégorie d\'actualités'" (clickedTab)="activateTag($event)" /> </div> diff --git a/src/app/profile/personal-offer-edition/personal-offer-edition.component.html b/src/app/profile/personal-offer-edition/personal-offer-edition.component.html index 0324e56a4..0b65f9a8c 100644 --- a/src/app/profile/personal-offer-edition/personal-offer-edition.component.html +++ b/src/app/profile/personal-offer-edition/personal-offer-edition.component.html @@ -27,10 +27,10 @@ </div> <!-- Navigation --> <app-nav-bar + ariaLabel="Sélectionner le type d'offre personnelle" [tabs]="getTabsNames()" [currentTab]="currentTab" [shouldExpand]="true" - [ariaLabel]="'Sélectionner le type d\'offre personnelle'" [ariaControls]="getTabsIds()" (clickedTab)="changeTab($event)" /> -- GitLab