Commit 032e65c1 authored by Hugo SUBTIL's avatar Hugo SUBTIL
Browse files

Merge branch 'dev' into 'master'

Dev

See merge request !154
parents be4ea483 ee4e4a89
Pipeline #14319 passed with stage
in 4 minutes and 17 seconds
......@@ -49,3 +49,6 @@ Thumbs.db
.env
# apiMock
api/db.json
# Documentation generated with compodoc
documentation
......@@ -2,6 +2,42 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
## [1.9.0](https://forge.grandlyon.com///compare/v1.8.0...v1.9.0) (2021-05-31)
### Features
* **admin:** add visualisation of unclaimed structure ([20fa1b0](https://forge.grandlyon.com///commit/20fa1b024f8536270282dc1bdcf88312ddfee91b))
* **structure-form:** add remote accompaniment step ([509129b](https://forge.grandlyon.com///commit/509129bc9931a2cbcbdf069bfecf844f64051f95))
* add admin and profile as lazy loaded modules ([a4b3181](https://forge.grandlyon.com///commit/a4b31817444dd340521cd6aabd5bac37793d4767))
* **doc:** add compodoc ([407aeed](https://forge.grandlyon.com///commit/407aeed22daef3b78a5399b90c78e66efd555e1a))
* add pix label ([ff5a522](https://forge.grandlyon.com///commit/ff5a522989d5ca2208650d3652ce4ff76c91e7b0))
* add women public ([d9a5d4f](https://forge.grandlyon.com///commit/d9a5d4faa42aeae32d1a2dc40c4f9a23da4d51e0))
* update cgu ([0f1d634](https://forge.grandlyon.com///commit/0f1d634e6967f095232db42a89e78b80302ef293))
### Bug Fixes
* **news:** 'a-la-une' tag was creating bug in other news display. Multiple 'a-la-une' tag is now possible. ([a44912e](https://forge.grandlyon.com///commit/a44912e0737ac96c72a131c11aa9acf9f368bb02))
* add titles for tooltip of structure details ([56358bd](https://forge.grandlyon.com///commit/56358bd58c90601499f827d9aa0420b077d285fb))
* align of validation icon ([0abdd3e](https://forge.grandlyon.com///commit/0abdd3e14581ce7f7844220bbfda32cc07039e80))
* angular lib warning + update readme ([a77f6da](https://forge.grandlyon.com///commit/a77f6dacc28ead8ce0da7c6f74338c7966b18d99))
* change filter modal padding ([1f148f4](https://forge.grandlyon.com///commit/1f148f4c8cdbb05a460ba61cf0a1529381c0608c))
* change regex for email (special character) ([2250272](https://forge.grandlyon.com///commit/225027237ba0b2e1e9e22ca1c37a94e8410ba07a))
* check for opening hours of structure on component init ([2117c68](https://forge.grandlyon.com///commit/2117c68d3daea77dd6ffdb8f3cb70c77d324ae7e))
* display updated_at instead of published_at ([36a68a4](https://forge.grandlyon.com///commit/36a68a4582ee2ebdd1ed4c5e5fa1f1be6370215a))
* fill the query input with url param and reset url param on query changes ([b123f00](https://forge.grandlyon.com///commit/b123f00c8a48c5cdb69cc3dc5da2ab3517251e4c))
* height of label card ([b4489cd](https://forge.grandlyon.com///commit/b4489cdf136e80cdb001908236472d1ab7f02f75))
* issue on hour-picker focus + clean code ([1fdc33f](https://forge.grandlyon.com///commit/1fdc33f2f7242894e0c542d2851fcdefd8a818a7))
* opengraph logo ([c54587c](https://forge.grandlyon.com///commit/c54587c3ff6851f0201d63a97cd88e4ab0c9226d))
* plural handling ([43d2440](https://forge.grandlyon.com///commit/43d2440d66db2571b17ab56dd20532743929a34c))
* posts image size ([b085c5d](https://forge.grandlyon.com///commit/b085c5d085fa432f2ce8ae21b01c7c0bafce1338))
* remove console.log + clean code ([bd4bba8](https://forge.grandlyon.com///commit/bd4bba845fa8ee1bd36038093886b640e4cbd5c8))
* remove deletion of accompaniement on strucutre edit ([76f4332](https://forge.grandlyon.com///commit/76f4332bb3cf3dbd33448a38cef9177afbdd3b4a))
* revendication on login ([f9de450](https://forge.grandlyon.com///commit/f9de450a28a84b7a5870dc436dedb7e27f3d92df))
* update linkedin regex to allow compagny pages ([a4a032b](https://forge.grandlyon.com///commit/a4a032bba9122dc66af45a88bd82bbd4bf4f1fcd))
* update regex of password and email to handle hyphen ([31193b7](https://forge.grandlyon.com///commit/31193b7ab8c8179a21bab435a309c46926a61453))
## [1.8.0](https://forge.grandlyon.com///compare/v1.7.0...v1.8.0) (2021-05-06)
......
......@@ -35,6 +35,12 @@ Run `npm run e2e` to execute the end-to-end tests via [Protractor](http://www.pr
Use conventional commit format. For more info please read this article on [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/)
## Documentation
A documentation is generated with compodoc in addition of the existing documentation on the wiki.
```sh
npm run doc:serve
```
You can now visualize it at : `localhost:8080`
## Further help
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
......@@ -36,6 +36,7 @@
"tsConfig": "tsconfig.app.json",
"localize": true,
"aot": true,
"allowedCommonJsDependencies": ["lodash", "leaflet.locatecontrol"],
"assets": [
"src/favicon.ico",
"src/assets",
......
This diff is collapsed.
{
"name": "pamn",
"version": "1.8.0",
"version": "1.9.0",
"scripts": {
"ng": "ng",
"start": "ng serve --configuration=fr --proxy-config proxy.conf.json",
"build:prod": "ng build --prod --configuration=production,fr --output-path=dist --subresource-integrity",
"build:dev": "ng build --prod --configuration=fr --output-path=dist --subresource-integrity",
"doc": "npx @compodoc/compodoc -p tsconfig.doc.json",
"doc:serve": "npm run doc && npx compodoc -s",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
......@@ -42,6 +44,7 @@
"@angular/cli": "^11.2.11",
"@angular/compiler-cli": "~11.2.12",
"@angular/localize": "^11.2.12",
"@compodoc/compodoc": "^1.1.11",
"@types/jasmine": "~3.5.0",
"@types/jasminewd2": "~2.0.3",
"@types/leaflet": "^1.5.17",
......
.selector {
margin-bottom: 20px;
.option {
margin-right: 30px;
}
}
.results-tab {
margin-bottom: 20px;
}
.results-column {
width: 30%;
}
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { PanelComponent } from './components/panel/panel.component';
const routes: Routes = [
{
path: '',
component: PanelComponent,
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class AdminRoutingModule {}
......@@ -4,11 +4,12 @@ import { PanelComponent } from './components/panel/panel.component';
import { ClaimStructureComponent } from './components/claim-structure/claim-structure.component';
import { DeleteUserComponent } from './components/delete-user/delete-user.component';
import { SharedModule } from '../shared/shared.module';
import { NewsComponent } from '../post/news.component';
import { NewsletterUsersComponent } from './components/newsletter-users/newsletter-users.component';
import { AdminStructuresListComponent } from './components/structures-list/admin-structures-list.component';
import { AdminRoutingModule } from './admin-routing.module';
@NgModule({
declarations: [PanelComponent, ClaimStructureComponent, DeleteUserComponent, NewsletterUsersComponent],
imports: [CommonModule, SharedModule],
declarations: [PanelComponent, ClaimStructureComponent, DeleteUserComponent, NewsletterUsersComponent, AdminStructuresListComponent],
imports: [CommonModule, AdminRoutingModule, SharedModule],
})
export class AdminModule {}
<div fxLayout="row" fxLayoutAlign="center center">
<table *ngIf="demandsAttachment" aria-describedby="demands attachment results">
<div fxLayout="column" fxLayoutAlign="center center">
<table *ngIf="isClaimedStructure" aria-describedby="demands attachment results" class="results-tab">
<thead>
<th scope="col">Utilisateur</th>
<th scope="col">Structure</th>
<th scope="col">Options</th>
</thead>
<tbody>
<tr *ngFor="let demand of demandsAttachment">
<td>{{ demand.userEmail }}</td>
<td>{{ demand.structureName }}</td>
<tr *ngFor="let structure of demandsAttachment">
<td>{{ structure.userEmail }}</td>
<td>{{ structure.structureName }}</td>
<td>
<button (click)="acceptDemand(demand)">Valider</button><button (click)="refuseDemand(demand)">Refuser</button>
<button (click)="acceptDemand(structure)">Valider</button
><button (click)="refuseDemand(structure)">Refuser</button>
</td>
</tr>
<tr *ngIf="!demandsAttachment.length">
<tr *ngIf="!demandsAttachment?.length">
<td colspan="3">Aucune demande en attente</td>
</tr>
</tbody>
......
import { Component, OnInit } from '@angular/core';
import { DemandAttachment } from '../../models/demandAttachment.model';
import { StructureAdminInfo } from '../../models/demandAttachment.model';
import { AdminService } from '../../services/admin.service';
@Component({
selector: 'app-admin-claim-structure',
templateUrl: './claim-structure.component.html',
styleUrls: ['../../admin-pannel.scss'],
})
export class ClaimStructureComponent implements OnInit {
public demandsAttachment: DemandAttachment[];
public demandsAttachment: StructureAdminInfo[];
public structuresUnclaimed: StructureAdminInfo[];
public isClaimedStructure: boolean = true;
public isUnclaimedStructure: boolean = false;
constructor(private adminService: AdminService) {}
ngOnInit(): void {
......@@ -16,7 +20,7 @@ export class ClaimStructureComponent implements OnInit {
});
}
public acceptDemand(demand: DemandAttachment): void {
public acceptDemand(demand: StructureAdminInfo): void {
this.adminService
.acceptStructureClaim(demand.userEmail, demand.structureId, demand.structureName)
.subscribe((data) => {
......@@ -24,11 +28,15 @@ export class ClaimStructureComponent implements OnInit {
});
}
public refuseDemand(demand: DemandAttachment): void {
public refuseDemand(demand: StructureAdminInfo): void {
this.adminService
.refuseStructureClaim(demand.userEmail, demand.structureId, demand.structureName)
.subscribe((data) => {
this.demandsAttachment = data;
});
}
public claimedStructure(event: boolean): void {
this.isClaimedStructure = !this.isClaimedStructure;
}
}
<div fxLayout="column" fxLayoutGap="20px" class="content-container full-screen">
<div fxLayout="row" fxLayoutAlign="center center"><h1>Administration</h1></div>
<div fxLayout="row" fxLayoutGap="20px" fxLayoutAlign="center center">
<button (click)="changeActiveFeature(features.pendingStructures)">Gestion structure</button>
<button (click)="changeActiveFeature(features.pendingStructures)">Revendication structure</button>
<button (click)="changeActiveFeature(features.structuresList)">Liste structures</button>
<button (click)="changeActiveFeature(features.deleteUsers)">Suppression d'utilisateurs</button>
<button (click)="changeActiveFeature(features.newsletterUsers)">Newsletter</button>
<a target="_blank" class="custom-link" rel="noopener noreferrer" [href]="ghostLink">Ghost</a>
</div>
<div *ngIf="selectedFeature === features.structuresList">
<app-admin-structures-list></app-admin-structures-list>
</div>
<div *ngIf="selectedFeature === features.deleteUsers">
<app-admin-delete-user></app-admin-delete-user>
</div>
......
<div fxLayout="column" fxLayoutAlign="center center">
<div fxLayout="row" class="selector">
<div fxLayout="row" class="checkbox no-width">
<div class="checkboxItem">
<label>
<input type="checkbox" [checked]="isInClaimStructure" (change)="inClaimStructure($event)" />
<span class="customCheck"></span>
<div class="label pass option">En revendication</div>
</label>
</div>
<div class="checkboxItem">
<label>
<input type="checkbox" [checked]="isClaimedStructure" (change)="claimedStructure($event)" />
<span class="customCheck"></span>
<div class="label pass option">Revendiquées</div>
</label>
</div>
<div class="checkboxItem">
<label>
<input type="checkbox" [checked]="isToClaimStructure" (change)="toClaimStructure($event)" />
<span class="customCheck"></span>
<div class="label pass option">Non revendiquées</div>
</label>
</div>
<div class="checkboxItem">
<label>
<input type="checkbox" [checked]="isAll" (change)="allStructure($event)" />
<span class="customCheck"></span>
<div class="label pass option">Toutes</div>
</label>
</div>
</div>
</div>
<div *ngIf="!isInClaimStructure && !isToClaimStructure && !isClaimedStructure">
Choisir un filtre pour afficher la liste des structures
</div>
<table *ngIf="isInClaimStructure" aria-describedby="demands attachment results" class="results-tab results-column">
<thead>
<th scope="col">Structures en cours de revendication ({{ structuresInClaim.length }})</th>
</thead>
<tbody>
<tr *ngFor="let structure of structuresInClaim">
<td>
<a href="/acteurs?id={{ structure.structureId }}" target="_blank"> {{ structure.structureName }}</a>
</td>
</tr>
<tr *ngIf="!structuresInClaim?.length">
<td colspan="3">Aucune structure</td>
</tr>
</tbody>
</table>
<table *ngIf="isToClaimStructure" aria-describedby="demands attachment results" class="results-tab results-column">
<thead>
<th scope="col">Structures à revendiquer ({{ structuresToClaim.length }})</th>
</thead>
<tbody>
<tr *ngFor="let structure of structuresToClaim">
<td>
<a href="/acteurs?id={{ structure.structureId }}" target="_blank"> {{ structure.structureName }}</a>
</td>
</tr>
<tr *ngIf="!structuresToClaim?.length">
<td colspan="3">Aucune structure</td>
</tr>
</tbody>
</table>
<table *ngIf="isClaimedStructure" aria-describedby="demands attachment results" class="results-tab results-column">
<thead>
<th scope="col">Structures revendiquées ({{ structuresClaimed.length }})</th>
</thead>
<tbody>
<tr *ngFor="let structure of structuresClaimed">
<td>
<a href="/acteurs?id={{ structure.structureId }}" target="_blank"> {{ structure.structureName }}</a>
</td>
</tr>
<tr *ngIf="!structuresInClaim?.length">
<td colspan="3">Aucune structure</td>
</tr>
</tbody>
</table>
</div>
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AdminStructuresListComponent } from './admin-structures-list.component';
describe('AdminStructuresListComponent', () => {
let component: AdminStructuresListComponent;
let fixture: ComponentFixture<AdminStructuresListComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [AdminStructuresListComponent],
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(AdminStructuresListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit } from '@angular/core';
import { StructureAdminInfo } from '../../models/demandAttachment.model';
import { AdminService } from '../../services/admin.service';
@Component({
selector: 'app-admin-structures-list',
templateUrl: './admin-structures-list.component.html',
styleUrls: ['../../admin-pannel.scss'],
})
export class AdminStructuresListComponent implements OnInit {
public structuresInClaim: StructureAdminInfo[];
public structuresToClaim: StructureAdminInfo[];
public structuresClaimed: StructureAdminInfo[];
public isClaimedStructure: boolean = false;
public isToClaimStructure: boolean = false;
public isInClaimStructure: boolean = true;
public isAll: boolean = false;
constructor(private adminService: AdminService) {}
ngOnInit(): void {
this.adminService.getAllStructureAdmin().subscribe((structures) => {
this.structuresClaimed = structures.claimed;
this.structuresInClaim = structures.inClaim;
this.structuresToClaim = structures.toClaim;
});
}
public claimedStructure(event: boolean): void {
this.isClaimedStructure = !this.isClaimedStructure;
}
public toClaimStructure(event: boolean): void {
this.isToClaimStructure = !this.isToClaimStructure;
}
public inClaimStructure(event: boolean): void {
this.isInClaimStructure = !this.isInClaimStructure;
}
public allStructure(event: boolean): void {
if (!this.isAll) {
this.isAll = !this.isAll;
this.isInClaimStructure = true;
this.isToClaimStructure = true;
this.isClaimedStructure = true;
} else {
this.isAll = !this.isAll;
this.isInClaimStructure = false;
this.isToClaimStructure = false;
this.isClaimedStructure = false;
}
}
}
export class DemandAttachment {
export class StructureAdminInfo {
userEmail: string;
structureId: number;
structureName: string;
......
......@@ -3,7 +3,7 @@ import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { NewsletterSubscription } from '../../models/subscription-model';
import { User } from '../../models/user.model';
import { DemandAttachment } from '../models/demandAttachment.model';
import { StructureAdminInfo } from '../models/demandAttachment.model';
@Injectable({
providedIn: 'root',
......@@ -13,8 +13,16 @@ export class AdminService {
constructor(private http: HttpClient) {}
// Return pendingAttachments of all profiles.
public getPendingStructure(): Observable<DemandAttachment[]> {
return this.http.get<DemandAttachment[]>(`${this.baseUrl}/pendingStructures`);
public getPendingStructure(): Observable<StructureAdminInfo[]> {
return this.http.get<StructureAdminInfo[]>(`${this.baseUrl}/pendingStructures`);
}
public getToClaimStructure(): Observable<StructureAdminInfo[]> {
return this.http.get<StructureAdminInfo[]>(`${this.baseUrl}/unclaimedStructures`);
}
public getAllStructureAdmin(): Observable<any> {
return this.http.get<StructureAdminInfo[]>(`${this.baseUrl}/adminStructuresList`);
}
public getUsers(): Observable<User[]> {
......@@ -45,8 +53,8 @@ export class AdminService {
userEmail: string,
structureId: number,
structureName: string
): Observable<DemandAttachment[]> {
return this.http.post<DemandAttachment[]>(`${this.baseUrl}/validatePendingStructure`, {
): Observable<StructureAdminInfo[]> {
return this.http.post<StructureAdminInfo[]>(`${this.baseUrl}/validatePendingStructure`, {
userEmail,
structureId,
structureName,
......@@ -57,8 +65,8 @@ export class AdminService {
userEmail: string,
structureId: number,
structureName: string
): Observable<DemandAttachment[]> {
return this.http.post<DemandAttachment[]>(`${this.baseUrl}/rejectPendingStructure`, {
): Observable<StructureAdminInfo[]> {
return this.http.post<StructureAdminInfo[]>(`${this.baseUrl}/rejectPendingStructure`, {
userEmail,
structureId,
structureName,
......
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AboutComponent } from './about/about.component';
import { PanelComponent } from './admin/components/panel/panel.component';
import { FormComponent } from './form/form.component';
import { AdminGuard } from './guards/admin.guard';
import { AuthGuard } from './guards/auth.guard';
import { DeactivateGuard } from './guards/deactivate.guard';
import { CartoComponent } from './carto/carto.component';
import { LegalNoticeComponent } from './legal-notice/legal-notice.component';
import { ProfileComponent } from './profile/profile.component';
import { ResetEmailComponent } from './reset-email/reset-email.component';
import { ResetPasswordComponent } from './reset-password/reset-password.component';
import { TempUserResolver } from './resolvers/temp-user.resolver';
......@@ -59,7 +57,7 @@ const routes: Routes = [
{
path: 'profile',
canActivate: [AuthGuard],
component: ProfileComponent,
loadChildren: () => import('./profile/profile.module').then((m) => m.ProfileModule),
},
{
path: 'join',
......@@ -70,11 +68,6 @@ const routes: Routes = [
path: 'reset-password',
component: ResetPasswordComponent,
},
{
path: 'admin',
canActivate: [AdminGuard],
component: PanelComponent,
},
{
path: 'create-structure',
component: FormComponent,
......@@ -94,6 +87,11 @@ const routes: Routes = [
path: 'news',
loadChildren: () => import('./post/post.module').then((m) => m.PostModule),
},
{
path: 'admin',
canActivate: [AdminGuard],
loadChildren: () => import('./admin/admin.module').then((m) => m.AdminModule),
},
{
path: 'home',
redirectTo: 'news',
......
......@@ -57,7 +57,7 @@ import { NewsletterSubscriptionComponent } from './newsletter-subscription/newsl
StructureJoinComponent,
NewsletterSubscriptionComponent,
],
imports: [BrowserModule, HttpClientModule, AppRoutingModule, SharedModule, MapModule, ProfileModule, AdminModule],
imports: [BrowserModule, HttpClientModule, AppRoutingModule, SharedModule, MapModule],
providers: [
{ provide: LOCALE_ID, useValue: 'fr' },
{ provide: HTTP_INTERCEPTORS, useClass: CustomHttpInterceptor, multi: true },
......
......@@ -121,7 +121,7 @@
<h3>Qui êtes-vous ?</h3>
<p>Ces informations ne seront pas visibles sur la plateforme</p>
</div>
<div class="title">
<div *ngIf="!isClaimMode" class="title">
<h4>Vous possédez déja un compte ? Connectez-vous:</h4>
<button class="btn-primary small next" *ngIf="!isLoggedIn" (click)="isPopUpOpen = !isPopUpOpen">
Se connecter
......@@ -770,6 +770,16 @@
</p>
</div>
</div>
<div *ngIf="currentPage == pageTypeEnum.structureRemoteAccompaniment" class="page">
<div class="title">
<h3>Proposez vous un accompagnement à distance ?</h3>
</div>
<app-radio-form
[selectedOption]="getStructureControl('remoteAccompaniment').value"
(selectedEvent)="onRadioBtnChange('remoteAccompaniment', $event)"
>
</app-radio-form>
</div>
<div *ngIf="currentPage == pageTypeEnum.structureWorkshop" class="page">
<div class="title">
<h3>Quel(s) atelier(s) au numérique proposez-vous ?</h3>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment