Mise à jour de composants
This commit is contained in:
@@ -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() {
|
||||||
@@ -98,13 +99,12 @@ export class AuthComponent implements OnInit, OnDestroy {
|
|||||||
const credentials = this.authForm.value;
|
const credentials = this.authForm.value;
|
||||||
const user$ = this.userService.attemptAuth(this.authType, credentials).pipe(take(1));
|
const user$ = this.userService.attemptAuth(this.authType, credentials).pipe(take(1));
|
||||||
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.lastjump = jump;
|
|
||||||
this.inputs.jumps = jump.numero;
|
|
||||||
this.inputs.weight = this.currentUser.poids!;
|
|
||||||
this.inputs.current = jump.taille!;
|
|
||||||
this.canopy_size_table = new MatTableDataSource<WeightSize>(weightSizes);
|
|
||||||
this.refresh();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
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.inputs.jumps = jump.numero;
|
||||||
|
this.inputs.weight = this.currentUser.poids!;
|
||||||
|
this.inputs.current = jump.taille!;
|
||||||
|
this.canopy_size_table = new MatTableDataSource<WeightSize>(weightSizes);
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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);
|
.pipe(take(1))
|
||||||
this.jumpsService.save(this.jump)
|
.subscribe({
|
||||||
.pipe(take(1))
|
next: (jump) => {
|
||||||
.subscribe({
|
this._openSnackBar(`Le saut n°${jump.numero} a été ajouté !`, 'Annuler');
|
||||||
next: (jump) => {
|
this._resetErrors();
|
||||||
this._openSnackBar(`Le saut n°${jump.numero} a été ajouté !`, 'OK');
|
if (refresh) {
|
||||||
this._resetErrors();
|
this.jumpRefresh = !this.jumpRefresh;
|
||||||
//this.runQuery();
|
this._jumpTableService.updateJumpRefresh(this.jumpRefresh);
|
||||||
},
|
//this.refresh = !this.refresh;
|
||||||
error: (err) => {
|
this._lastjump$ = this._jumpsService.getLastJump();
|
||||||
this.errors = err;
|
this._lastjump = this._lastjump$.subscribe((jump) => {
|
||||||
this.isSubmitting = false;
|
this.lastJump = jump;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
} catch (error) {
|
error: (err) => {
|
||||||
console.error(error);
|
this.errors = err;
|
||||||
}
|
this.isSubmitting = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
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() {
|
||||||
|
|||||||
Reference in New Issue
Block a user