Mise à jour de composants

This commit is contained in:
Julien Gautier
2023-10-03 13:48:26 +02:00
parent 6d3e79aac5
commit 3a5e837842
8 changed files with 190 additions and 300 deletions
+3 -3
View File
@@ -44,7 +44,7 @@ export class AuthComponent implements OnInit, OnDestroy {
) { ) {
this._resetErrors(); this._resetErrors();
// use FormBuilder to create a form group // use FormBuilder to create a form group
this.authForm = this.fb.group({ let controlsConfig = {
email: ['', [Validators.required, Validators.email]], email: ['', [Validators.required, Validators.email]],
username: '', username: '',
firstname: '', firstname: '',
@@ -54,7 +54,8 @@ export class AuthComponent implements OnInit, OnDestroy {
poids: '', poids: '',
password: ['', Validators.required], password: ['', Validators.required],
confirmPassword: '' confirmPassword: ''
}, { validators: this.checkPasswords }); };
this.authForm = this.fb.group(controlsConfig, { validators: this.checkPasswords });
} }
ngOnInit() { ngOnInit() {
@@ -100,7 +101,6 @@ export class AuthComponent implements OnInit, OnDestroy {
this._user = user$.subscribe({ this._user = user$.subscribe({
next: () => this.router.navigateByUrl('/'), next: () => this.router.navigateByUrl('/'),
error: (err) => { error: (err) => {
console.log(err);
this.errors = err; this.errors = err;
this.isSubmitting = false; this.isSubmitting = false;
} }
@@ -7,7 +7,7 @@
<form #searchFormData="ngForm" class="inputs-form"> <form #searchFormData="ngForm" class="inputs-form">
<mat-form-field class="bg-crystal me-3" subscriptSizing="dynamic"> <mat-form-field class="bg-crystal me-3" subscriptSizing="dynamic">
<mat-label>Nombre de sauts</mat-label> <mat-label>Nombre de sauts</mat-label>
<input matInput [(ngModel)]="inputs.jumps" (change)="refresh()" type="number" min="0" name="jumps"> <input matInput [(ngModel)]="inputs.jumps" (change)="refresh()" type="number" min="0" max="2000" step="1" name="jumps">
</mat-form-field> </mat-form-field>
<mat-form-field class="bg-crystal me-3" subscriptSizing="dynamic"> <mat-form-field class="bg-crystal me-3" subscriptSizing="dynamic">
<mat-label>Poids nu</mat-label> <mat-label>Poids nu</mat-label>
@@ -106,11 +106,11 @@
<tbody> <tbody>
<tr class="warn"> <tr class="warn">
<th class="first">Taille de voile en ft<sup>2</sup></th> <th class="first">Taille de voile en ft<sup>2</sup></th>
<td *ngFor="let value of sizesValues; let index = index;" class="pl-3 text-nowrap {{ tableHeader[(index+1)].active }}">{{ value }}</td> <td *ngFor="let value of sizesValuesFeet; let index = index;" class="pl-3 text-nowrap {{ tableHeader[(index+1)].active }}">{{ value }}</td>
</tr> </tr>
<tr class="warn"> <tr class="warn">
<th class="first">Abbattement 11%</th> <th class="first">Abbattement 11%</th>
<td *ngFor="let value of sizesMinValues; let index = index;" class="pl-3 text-nowrap {{ tableHeader[(index+1)].active }}">{{ value }}</td> <td *ngFor="let value of sizesMinValuesFeet; let index = index;" class="pl-3 text-nowrap {{ tableHeader[(index+1)].active }}">{{ value }}</td>
</tr> </tr>
<tr class="warn"> <tr class="warn">
<th class="first">Charge alaire</th> <th class="first">Charge alaire</th>
@@ -118,7 +118,7 @@
</tr> </tr>
<tr class="warn"> <tr class="warn">
<th class="first">Taille de voile en m<sup>2</sup></th> <th class="first">Taille de voile en m<sup>2</sup></th>
<td *ngFor="let value of sizesValuesM; let index = index;" class="pl-3 text-nowrap {{ tableHeader[(index+1)].active }}">{{ value | number : '1.2-2' }}</td> <td *ngFor="let value of sizesValuesMeter; let index = index;" class="pl-3 text-nowrap {{ tableHeader[(index+1)].active }}">{{ value | number : '1.2-2' }}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@@ -177,7 +177,7 @@
<th class="pl-3" mat-header-cell *matHeaderCellDef class="{{tableHeader[9].active}}"> {{tableHeader[9].name}} </th> <th class="pl-3" mat-header-cell *matHeaderCellDef class="{{tableHeader[9].active}}"> {{tableHeader[9].name}} </th>
<td mat-cell *matCellDef="let element;" class="pl-3 text-nowrap fs-6 {{element.ranges[8].active}}">{{element.ranges[8].value}}</td> <td mat-cell *matCellDef="let element;" class="pl-3 text-nowrap fs-6 {{element.ranges[8].active}}">{{element.ranges[8].value}}</td>
</ng-container> </ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true" class="warn"></tr> <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: false" class="warn"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;" class="text-middle font-monospace warn {{row.active}}" id="weight_{{row.weight}}"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;" class="text-middle font-monospace warn {{row.active}}" id="weight_{{row.weight}}"></tr>
</table> </table>
<div class="clearfix"> <div class="clearfix">
@@ -25,19 +25,6 @@
justify-content: center; justify-content: center;
width: 120px; width: 120px;
} }
/* Chrome, Safari, Edge, Opera */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
appearance: none;
-webkit-appearance: none;
margin: 0;
}
/* Firefox */
input[type=number] {
appearance: textfield;
-moz-appearance: textfield;
}
th { th {
&.first { &.first {
width: 180px; width: 180px;
@@ -16,8 +16,8 @@ import { NgChartsModule } from 'ng2-charts';
import { Observable, Subscription } from 'rxjs'; import { Observable, Subscription } from 'rxjs';
import { MenuItems } from 'src/app/components/shared'; import { MenuItems } from 'src/app/components/shared';
import { CalculatorInfo, CalculatorResult, InputParams, Jump, LineConfig, Range, TableHeader, User, WeightSize, weightSizes } from 'src/app/core/models'; import { CalculatorInfo, CalculatorResult, CalculatorState, InputParams, Jump, LineConfig, Range, TableHeader, User, WeightSize, weightSizes } from 'src/app/core/models';
import { JumpsService, UserService, UtilitiesService } from 'src/app/core/services'; import { CalculatorService, JumpsService, UserService, UtilitiesService } from 'src/app/core/services';
@Component({ @Component({
standalone: true, standalone: true,
@@ -33,46 +33,33 @@ import { JumpsService, UserService, UtilitiesService } from 'src/app/core/servic
templateUrl: './calculator.component.html' templateUrl: './calculator.component.html'
}) })
export class CalculatorComponent implements OnInit, OnDestroy { export class CalculatorComponent implements OnInit, OnDestroy {
private _lastjump: Subscription = new Subscription(); //private _lastjump!: Subscription; // = new Subscription();
private _currentUser: Subscription = new Subscription(); //private _currentUser!: Subscription; // = new Subscription();
private _subscriptions: Array<Subscription> = [];
public title = 'Calcul de taille de voile'; public title = 'Calcul de taille de voile';
public subtitle = 'DT48 - 13 mars 2020'; public subtitle = 'DT48 - 13 mars 2020';
public lastjump: Jump = {} as Jump; public lastjump: Jump = {} as Jump;
public currentUser: User = {} as User; public currentUser: User = {} as User;
public displayedColumns: string[] = ['weight']; public displayedColumns: Array<string> = ['weight'];
public tableHeader: TableHeader[] = [{name: 'Poids nu en kg', active: ''}]; public tableHeader: Array<TableHeader> = [<TableHeader>{name: 'Poids nu en kg', active: ''}];
public sizesHeader: TableHeader[] = []; public sizesHeader: Array<TableHeader> = [];
public sizesValues: number[] = []; public sizesValuesFeet: Array<number> = [];
public sizesMinValues: number[] = []; public sizesMinValuesFeet: Array<number> = [];
public sizesCharges: number[] = []; public sizesCharges: Array<number> = [];
public sizesValuesM: number[] = []; public sizesValuesMeter: Array<number> = [];
public displayCharts = false; public displayCharts = false;
public chartConfig: LineConfig = this._utilitiesService.getLineChartConfig(); public chartConfig: LineConfig = this._utilitiesService.getLineChartConfig();
public info: CalculatorInfo = {
charges: {
current: 0,
min: 0,
min11: 0
},
sizesFeet: {
current: 0,
min: 0,
min11: 0
},
sizesMeter: {
current: 0,
min: 0,
min11: 0
},
state: {
color: 'danger'
}
}
public coeffKgLbs: number = this._utilitiesService.getCoeffKgLbs(); public coeffKgLbs: number = this._utilitiesService.getCoeffKgLbs();
public coeffFtM: number = this._utilitiesService.getCoeffFtM(); public coeffFtM: number = this._utilitiesService.getCoeffFtM();
public info: CalculatorInfo = {
charges: <CalculatorResult>{ current: 0, min: 0, min11: 0 },
sizesFeet: <CalculatorResult>{ current: 0, min: 0, min11: 0 },
sizesMeter: <CalculatorResult>{ current: 0, min: 0, min11: 0 },
state: <CalculatorState>{ color: 'danger' }
}
@Input() canopy_size_table!: MatTableDataSource<WeightSize>; @Input() canopy_size_table!: MatTableDataSource<WeightSize>;
@Input() inputs: InputParams = { @Input() inputs: InputParams = <InputParams>{
jumps: 0, jumps: 0,
weight: 60, weight: 60,
gear: 10, gear: 10,
@@ -83,159 +70,67 @@ export class CalculatorComponent implements OnInit, OnDestroy {
@ViewChild(MatPaginator) paginator!: MatPaginator; @ViewChild(MatPaginator) paginator!: MatPaginator;
constructor( constructor(
private jumpsService: JumpsService, private _calculatorService: CalculatorService,
private userService: UserService, private _jumpsService: JumpsService,
private _userService: UserService,
private _utilitiesService: UtilitiesService, private _utilitiesService: UtilitiesService,
public menuItems: MenuItems public menuItems: MenuItems
) { } ) { }
ngOnInit() { ngOnInit() {
const currentUser$: Observable<User> = this.userService.currentUser; const currentUser$: Observable<User> = this._userService.currentUser;
const lastjump$: Observable<Jump> = this.jumpsService.getLastJump(); const lastjump$: Observable<Jump> = this._jumpsService.getLastJump();
this._currentUser = currentUser$.subscribe((userData: User) => {
this.currentUser = userData;
weightSizes[0].ranges.forEach((range: Range) => { weightSizes[0].ranges.forEach((range: Range) => {
let header: TableHeader = {name: range.label, active: range.active}; let header: TableHeader = {name: range.label, active: range.active};
this.tableHeader.push(header) this.tableHeader.push(header)
this.sizesHeader.push(header); this.sizesHeader.push(header);
this.displayedColumns.push(range.name); this.displayedColumns.push(range.name);
}); });
this._lastjump = lastjump$.subscribe((jump) => { this.chartConfig.lineChartData.labels = [...this.sizesHeader.map(
(data: TableHeader): string => data.name
)];
this.chartConfig.lineChartData.datasets = [
{
label: 'Tailles min -11%',
data: this.sizesMinValuesFeet,
fill: true,
stepped: true,
pointStyle: false,
borderColor: 'rgba(241, 80, 80, 1)',
backgroundColor: 'rgba(241, 80, 80, 0.3)'
},
{
label: 'Tailles min',
data: this.sizesValuesFeet,
fill: true,
stepped: true,
pointStyle: false,
borderColor: 'rgba(32, 182, 252, 1)',
backgroundColor: 'rgba(32, 182, 252, 0.3)'
}
];
this._subscriptions.push(
currentUser$.subscribe((userData: User) => {
this.currentUser = userData;
this._subscriptions.push(
lastjump$.subscribe((jump) => {
this.lastjump = jump; this.lastjump = jump;
this.inputs.jumps = jump.numero; this.inputs.jumps = jump.numero;
this.inputs.weight = this.currentUser.poids!; this.inputs.weight = this.currentUser.poids!;
this.inputs.current = jump.taille!; this.inputs.current = jump.taille!;
this.canopy_size_table = new MatTableDataSource<WeightSize>(weightSizes); this.canopy_size_table = new MatTableDataSource<WeightSize>(weightSizes);
this.refresh(); this.refresh();
}); })
}); );
})
);
} }
ngOnDestroy() { ngOnDestroy() {
this._currentUser.unsubscribe(); this._subscriptions.forEach((sub: Subscription) => {
this._lastjump.unsubscribe(); sub.unsubscribe();
}
private _canopySizeCalc(weight: number, jumps: number): CalculatorResult {
let result: CalculatorResult = {
min: 0,
min11: 0
};
if (jumps > 2000) {
this.info.error = '2000Jumps';
return result;
}
let index: number = (this._getTableLine(weight) - this._getTableLine(0));
result.min = weightSizes[index].ranges[this._getTableColumn(jumps)].value;
result.min11 = this._reduceLimit(result.min, 11);
return result;
}
private _getCanopyMinSize(weight: number, jumps: number, reduce: number = 0): number {
var result: CalculatorResult = this._canopySizeCalc(weight, jumps);
let size: number = 0;
switch (reduce) {
case 11:
size = result.min11;
break;
case 0:
default:
size = result.min;
break;
}
return size;
}
private _getCanopySizes(weight: number, eleven = false): number[] {
var data: number[] = [];
if (weight < 60) {
weight = 60;
}
if (weight > 110) {
weight = 110;
}
if (weight >= 60 && weight <= 110) {
const line = (weight - this._getTableLine(0));
let data = weightSizes[line];
if (eleven) {
return data.ranges.map((range: Range) => {
return Math.ceil(range.value * (100 - 11) / 100);
}); });
} else {
return data.ranges.map((range: Range) => {
return range.value;
});
}
}
return data;
}
private _getCharge(canopySize: number, nakedWeight: number, equipementWeight: number): number {
return (((nakedWeight + equipementWeight) * this.coeffKgLbs) / canopySize);
}
private _getRangeNum(): number {
let data: Range[] = weightSizes[0].ranges;
let num: number = 1;
data.some((range: Range) => {
if (range.start <= this.inputs.jumps && range.end >= this.inputs.jumps) {
num = range.num;
return true;
}
return false;
});
return num;
}
private _getTableColumn(jumps: number): number {
let column = 0;
if (jumps < 100) {
column = 0;
} else if (jumps < 250) {
column = 1;
} else if (jumps < 400) {
column = 2;
} else if (jumps < 600) {
column = 3;
} else if (jumps < 800) {
column = 4;
} else if (jumps < 1000) {
column = 5;
} else if (jumps < 1400) {
column = 6;
} else if (jumps < 1800) {
column = 7;
} else {
column = 8;
}
return column;
}
private _getTableLine(weight: number): number {
let line;
let min = 60;
let max = 110;
if (weight < min) {
line = min;
} else if (weight > max) {
line = max;
} else {
line = weight;
}
return line;
}
private _convertFeet2Meters(size: number): number {
return (size * this._utilitiesService.getCoeffFtM());
}
private _isInRange(nb: number, range: Range): boolean {
return (nb >= range.start && nb < range.end);
}
private _reduceLimit(surface: number, percentOff: number) {
return Math.ceil(surface * (100 - percentOff) / 100);
} }
public refresh():void { public refresh():void {
@@ -257,7 +152,7 @@ export class CalculatorComponent implements OnInit, OnDestroy {
weightSizes[(this.inputs.weight - 60)].active = 'active'; weightSizes[(this.inputs.weight - 60)].active = 'active';
} }
if (this.inputs.jumps >= 0) { if (this.inputs.jumps >= 0) {
var num = this._getRangeNum(); var num = this._calculatorService.getRangeNum(this.inputs.jumps);
this.tableHeader[num].active = 'active'; this.tableHeader[num].active = 'active';
weightSizes.forEach(element => { weightSizes.forEach(element => {
element.ranges[(num-1)].active = 'active'; element.ranges[(num-1)].active = 'active';
@@ -265,66 +160,32 @@ export class CalculatorComponent implements OnInit, OnDestroy {
} }
} }
private _getStateColor(current: number, min: number, min11: number): string {
let color: string = 'danger';
if (current >= min11 && current < min) {
color = 'warning';
}
if (current >= min) {
color = 'success';
}
return color;
}
private _refreshSizes(): void { private _refreshSizes(): void {
this.sizesValues = this._getCanopySizes(this.inputs.weight, false); if (this.inputs.jumps > 2000) {
this.sizesMinValues = this._getCanopySizes(this.inputs.weight, true); this.info.state.error = '2K+ Jumps';
this.sizesValues.forEach((value: number, index: number) => { }
this.sizesCharges[index] = this._getCharge(value, this.inputs.weight, this.inputs.gear); this.sizesValuesFeet = this._calculatorService.getCanopySizes(this.inputs.weight);
this.sizesValuesM[index] = this._convertFeet2Meters(value); this.sizesMinValuesFeet = this._calculatorService.getCanopySizes(this.inputs.weight, true);
this.sizesValuesMeter = this.sizesValuesFeet.map((value: number, index: number) => {
this.sizesCharges[index] = this._calculatorService.getCharge(value, this.inputs.weight, this.inputs.gear);
return this._calculatorService.convertFeet2Meters(value);
}); });
this.info.sizesFeet = this._canopySizeCalc(this.inputs.weight, this.inputs.jumps); this.info.sizesFeet = this._calculatorService.canopySizeCalc(this.inputs.weight, this.inputs.jumps);
this.info.sizesFeet.current = this.inputs.current; this.info.sizesFeet.current = this.inputs.current;
this.info.sizesMeter = { this.info.sizesMeter = {
current: this._convertFeet2Meters(this.inputs.current), current: this._calculatorService.convertFeet2Meters(this.inputs.current),
min: this._convertFeet2Meters(this.info.sizesFeet.min), min: this._calculatorService.convertFeet2Meters(this.info.sizesFeet.min),
min11: this._convertFeet2Meters(this.info.sizesFeet.min11) min11: this._calculatorService.convertFeet2Meters(this.info.sizesFeet.min11)
} }
this.info.charges = { this.info.charges = {
current: this._getCharge(this.inputs.current, this.inputs.weight, this.inputs.gear), current: this._calculatorService.getCharge(this.inputs.current, this.inputs.weight, this.inputs.gear),
min: this._getCharge(this.info.sizesFeet.min, this.inputs.weight, this.inputs.gear), min: this._calculatorService.getCharge(this.info.sizesFeet.min, this.inputs.weight, this.inputs.gear),
min11: this._getCharge(this.info.sizesFeet.min11, this.inputs.weight, this.inputs.gear) min11: this._calculatorService.getCharge(this.info.sizesFeet.min11, this.inputs.weight, this.inputs.gear)
} }
this.info.state.color = this._getStateColor(this.info.sizesFeet.current, this.info.sizesFeet.min, this.info.sizesFeet.min11); this.info.state.color = this._calculatorService.getStateColor(this.info.sizesFeet);
this.chartConfig.lineChartData.labels = [...this.sizesHeader.map(( this.chartConfig.lineChartData.datasets[0].data = this.sizesMinValuesFeet;
data: { this.chartConfig.lineChartData.datasets[1].data = this.sizesValuesFeet;
name: string;
active: string;
}
): string => {
return data.name;
})];
this.chartConfig.lineChartData.datasets = [
{
label: 'Tailles min -11%',
data: this.sizesMinValues,
fill: true,
stepped: true,
pointStyle: false,
borderColor: 'rgba(241, 80, 80, 1)',
backgroundColor: 'rgba(241, 80, 80, 0.3)'
},
{
label: 'Tailles min',
data: this.sizesValues,
fill: true,
stepped: true,
pointStyle: false,
borderColor: 'rgba(32, 182, 252, 1)',
backgroundColor: 'rgba(32, 182, 252, 0.3)'
}
];
this.displayCharts = true; this.displayCharts = true;
} }
+6 -1
View File
@@ -8,7 +8,12 @@ import { take } from 'rxjs/operators';
import { User, Errors, Aeronef, AeronefByImat, Canopy, CanopyModelBySize, DropZone, DropZoneByYear } from 'src/app/core/models'; import { User, Errors, Aeronef, AeronefByImat, Canopy, CanopyModelBySize, DropZone, DropZoneByYear } from 'src/app/core/models';
import { AeronefsService, CanopiesService, DropZonesService, UserService } from 'src/app/core/services'; import { AeronefsService, CanopiesService, DropZonesService, UserService } from 'src/app/core/services';
import { ShowAuthedDirective } from 'src/app/components/shared/show-authed.directive'; import { ShowAuthedDirective } from 'src/app/components/shared/show-authed.directive';
import { AeronefsComponent, AeronefsBarComponent, CanopyModelsComponent, CanopySizesComponent, DropZonesComponent, DropZonesBarComponent, JumpsByMonthComponent } from './dashboard-components'; import {
AeronefsComponent, AeronefsBarComponent,
CanopyModelsComponent, CanopySizesComponent,
DropZonesComponent, DropZonesBarComponent,
JumpsByMonthComponent
} from 'src/app/components/shared/dashboard-components';
@Component({ @Component({
standalone: true, standalone: true,
@@ -2,11 +2,11 @@
<mat-card> <mat-card>
<mat-card-header class="bg-accent rounded-top py-3 px-4"> <mat-card-header class="bg-accent rounded-top py-3 px-4">
<mat-card-title> <mat-card-title>
{{ title }} <span class="fs-5" [hidden]="!lastjump.numero">({{ lastjump.numero }})</span> {{ title }} <span class="fs-5" [hidden]="!lastJump.numero">({{ lastJump.numero }})</span>
</mat-card-title> </mat-card-title>
<mat-card-subtitle> <mat-card-subtitle>
<span [hidden]="!lastjump.numero" class="me-2 fst-italic"> <span [hidden]="!lastJump.numero" class="me-2 fst-italic">
Dernier saut enregistré : # {{ lastjump.numero }} le {{ lastjump.date | date: 'dd/MM/yyyy' }} à {{ lastjump.lieu }} Dernier saut enregistré : # {{ lastJump.numero }} le {{ lastJump.date | date: 'dd/MM/yyyy' }} à {{ lastJump.lieu }}
</span> </span>
</mat-card-subtitle> </mat-card-subtitle>
<span class="flex-spacer"></span> <span class="flex-spacer"></span>
@@ -30,7 +30,7 @@
</mat-menu> </mat-menu>
</mat-card-header> </mat-card-header>
<mat-card-content class="my-4"> <mat-card-content class="my-4">
<huapp-jump-table #jumpTable [refresh]="refreshInterval" [config]="listConfig" [isUser]="isUser" [showAdd]="canModify" [title]="title"> <huapp-jump-table #jumpTable [refresh]="refresh" [config]="listConfig" [isUser]="isUser" [showAdd]="canModify" [title]="title">
</huapp-jump-table> </huapp-jump-table>
</mat-card-content> </mat-card-content>
</mat-card> </mat-card>
+65 -29
View File
@@ -1,4 +1,4 @@
import { Component, OnInit, OnDestroy } from '@angular/core'; import { Component, AfterContentChecked, OnInit, OnDestroy } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { ActivatedRoute, Router, RouterLink, RouterModule } from '@angular/router'; import { ActivatedRoute, Router, RouterLink, RouterModule } from '@angular/router';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
@@ -6,16 +6,17 @@ import { MatCardModule } from '@angular/material/card';
import { MatDialog, MatDialogModule } from '@angular/material/dialog'; import { MatDialog, MatDialogModule } from '@angular/material/dialog';
import { MatIconModule } from '@angular/material/icon'; import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu'; import { MatMenuModule } from '@angular/material/menu';
import { MatSnackBar, MatSnackBarHorizontalPosition, MatSnackBarModule, MatSnackBarVerticalPosition } from '@angular/material/snack-bar'; import { MatSnackBar, MatSnackBarConfig, MatSnackBarHorizontalPosition, MatSnackBarModule, MatSnackBarVerticalPosition } from '@angular/material/snack-bar';
import { Observable, Subscription } from 'rxjs'; import { Observable, Subscription } from 'rxjs';
import { take } from 'rxjs/operators'; import { take } from 'rxjs/operators';
import { MenuItems, JumpAddDialogComponent, JumpTableComponent } from 'src/app/components/shared'; import { MenuItems, JumpAddDialogComponent, JumpTableComponent } from 'src/app/components/shared';
//import { JumpTableComponent } from 'src/app/components/shared/helpers-jump'; //import { JumpTableComponent } from 'src/app/components/shared/helpers-jump';
import { Errors, Jump, JumpListConfig, User } from 'src/app/core/models'; import { Errors, Jump, JumpAddParams, JumpListConfig, User } from 'src/app/core/models';
import { JumpsService, UserService } from 'src/app/core/services'; import { JumpsService, JumpTableService, UserService } from 'src/app/core/services';
import { environment } from 'src/environments/environment'; import { environment } from 'src/environments/environment';
import data from 'src/jumps.json'; import data from 'src/jumps.json';
//import data from 'src/jumps_02.json';
@Component({ @Component({
standalone: true, standalone: true,
@@ -29,29 +30,33 @@ import data from 'src/jumps.json';
templateUrl: './logbook.component.html', templateUrl: './logbook.component.html',
styleUrls: ['./logbook.component.scss'] styleUrls: ['./logbook.component.scss']
}) })
export class LogbookComponent implements OnInit, OnDestroy { export class LogbookComponent implements OnInit, OnDestroy, AfterContentChecked {
private _currentUser: Subscription = new Subscription(); private _currentUser: Subscription = new Subscription();
private _data: Subscription = new Subscription(); private _data: Subscription = new Subscription();
private _lastjump: Subscription = new Subscription(); private _lastjump: Subscription = new Subscription();
private _lastjump$: Observable<Jump> = new Observable();
public errors!: Errors; public errors!: Errors;
public title = 'Carnet de sauts'; public title = 'Carnet de sauts';
public jump: Jump = {} as Jump; public jump: Jump = {} as Jump;
public lastjump: Jump = {} as Jump; public lastJump: Jump = {} as Jump;
public currentUser: User = {} as User; public currentUser: User = {} as User;
public listConfig: JumpListConfig = { type: 'all', filters: {} }; public listConfig: JumpListConfig = { type: 'all', filters: {} };
public refreshInterval: number = environment.refresh_interval; public refresh: boolean = false;
public isAuthenticated = false; public isAuthenticated = false;
public isUser = true; public isUser = true;
public canModify = false; public canModify = false;
public isSubmitting = false; public isSubmitting = false;
public tableRefresh = false;
public jumpRefresh = false;
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
private router: Router, private router: Router,
private dialog: MatDialog, private dialog: MatDialog,
private snackBar: MatSnackBar, private snackBar: MatSnackBar,
private jumpsService: JumpsService, private _jumpsService: JumpsService,
private userService: UserService, private _jumpTableService: JumpTableService,
private _userService: UserService,
public menuItems: MenuItems public menuItems: MenuItems
) { } ) { }
@@ -64,15 +69,15 @@ export class LogbookComponent implements OnInit, OnDestroy {
this.router.navigateByUrl('/login'); this.router.navigateByUrl('/login');
return; return;
} }
const currentUser$: Observable<User> = this.userService.currentUser; const currentUser$: Observable<User> = this._userService.currentUser;
this._currentUser = currentUser$.subscribe((userData: User) => { this._currentUser = currentUser$.subscribe((userData: User) => {
this.currentUser = userData; this.currentUser = userData;
this.canModify = this.currentUser.role === 'Admin'; this.canModify = this.currentUser.role === 'Admin';
}); });
const lastjump$: Observable<Jump> = this.jumpsService.getLastJump(); this._lastjump$ = this._jumpsService.getLastJump();
this._lastjump = lastjump$.subscribe((jump) => { this._lastjump = this._lastjump$.subscribe((jump) => {
this.lastjump = jump; this.lastJump = jump;
}); });
}); });
} }
@@ -83,12 +88,23 @@ export class LogbookComponent implements OnInit, OnDestroy {
this._lastjump.unsubscribe(); this._lastjump.unsubscribe();
} }
ngAfterContentChecked() {
if (this.tableRefresh != this._jumpTableService.tableRefresh) {
this.tableRefresh = this._jumpTableService.tableRefresh;
this._lastjump$ = this._jumpsService.getLastJump();
this._lastjump = this._lastjump$.subscribe((jump) => {
this.lastJump = jump;
});
console.log('lastjump has been updated in logbook component');
}
}
importJumps() { importJumps() {
try { try {
data.forEach((entry) => { data.forEach((entry) => {
Object.assign(this.jump, entry); Object.assign(this.jump, entry);
//console.log(this.jump); //console.log(this.jump);
this.jumpsService.save(this.jump) this._jumpsService.save(this.jump)
.pipe(take(1)) .pipe(take(1))
.subscribe({ .subscribe({
next: (jump) => { next: (jump) => {
@@ -106,9 +122,13 @@ export class LogbookComponent implements OnInit, OnDestroy {
} }
openAddDialog(): void { openAddDialog(): void {
this.jump = <Jump>{};
this.jump.numero = (this.lastJump.numero + 1);
this.jump.sautants = [];
this.jump.participants = 1;
const dialogRef = this.dialog.open(JumpAddDialogComponent, { const dialogRef = this.dialog.open(JumpAddDialogComponent, {
width: '60vw', width: '70vw',
data: this.jump data: {jump: this.jump, lastJump: this.lastJump}
}); });
dialogRef.afterClosed().pipe(take(1)) dialogRef.afterClosed().pipe(take(1))
.subscribe(result => { .subscribe(result => {
@@ -118,35 +138,51 @@ export class LogbookComponent implements OnInit, OnDestroy {
}); });
} }
private _onEntry(jumps: Array<Jump>): void {
const max: number = jumps.length;
let refresh: boolean = false;
jumps.forEach((jump: Jump, index: number) => {
console.log('Ajout du saut', jump.numero);
Object.assign(this.jump, jump);
if (max == index+1) {
refresh = true;
}
this._saveJump(jump, refresh);
});
}
private _onEntry(entry: NonNullable<unknown>): void { private _saveJump(jump: Jump, refresh: boolean) {
try { //console.log(jump);
this.isSubmitting = true; this._jumpsService.save(jump)
Object.assign(this.jump, entry);
this.jumpsService.save(this.jump)
.pipe(take(1)) .pipe(take(1))
.subscribe({ .subscribe({
next: (jump) => { next: (jump) => {
this._openSnackBar(`Le saut n°${jump.numero} a été ajouté !`, 'OK'); this._openSnackBar(`Le saut n°${jump.numero} a été ajouté !`, 'Annuler');
this._resetErrors(); this._resetErrors();
//this.runQuery(); if (refresh) {
this.jumpRefresh = !this.jumpRefresh;
this._jumpTableService.updateJumpRefresh(this.jumpRefresh);
//this.refresh = !this.refresh;
this._lastjump$ = this._jumpsService.getLastJump();
this._lastjump = this._lastjump$.subscribe((jump) => {
this.lastJump = jump;
});
}
}, },
error: (err) => { error: (err) => {
this.errors = err; this.errors = err;
this.isSubmitting = false; this.isSubmitting = false;
} }
}); });
} catch (error) {
console.error(error);
}
} }
private _openSnackBar(content: string, title: string) { private _openSnackBar(content: string, title: string) {
this.snackBar.open(content, title, { const config: MatSnackBarConfig = {
horizontalPosition: <MatSnackBarHorizontalPosition>'end', horizontalPosition: <MatSnackBarHorizontalPosition>'end',
verticalPosition: <MatSnackBarVerticalPosition>'bottom', verticalPosition: <MatSnackBarVerticalPosition>'bottom',
duration: 4000, duration: 4000
}); };
this.snackBar.open(content, title, config);
} }
private _resetErrors(): void { private _resetErrors(): void {
@@ -1,5 +1,5 @@
import { Component, OnInit, OnDestroy } from '@angular/core'; import { Component, OnInit, OnDestroy } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup, AbstractControl, Validators, ValidatorFn, ValidationErrors, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { AbstractControl, FormsModule, ReactiveFormsModule, UntypedFormBuilder, UntypedFormGroup, Validators, ValidatorFn, ValidationErrors } from '@angular/forms';
import { Router, RouterLink } from '@angular/router'; import { Router, RouterLink } from '@angular/router';
import { Title } from '@angular/platform-browser'; import { Title } from '@angular/platform-browser';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
@@ -57,7 +57,8 @@ export class SettingsComponent implements OnInit, OnDestroy {
image: '', image: '',
bg_image: '' bg_image: ''
}, { validators: this.checkPasswords }); }, { validators: this.checkPasswords });
// Optional: subscribe to changes on the form : this.settingsForm.valueChanges.pipe(this._scavenger.collect()).subscribe(values => this.updateUser(values)); // Optional: subscribe to changes on the form :
// this.settingsForm.valueChanges.pipe(this._scavenger.collect()).subscribe(values => this.updateUser(values));
} }
get f() { get f() {