-
+
+
+ {{ subtitle }}
+
+
+ @if (displayCharts) {
+
+
\ No newline at end of file
diff --git a/src/app/components/auth/auth.component.html b/src/app/components/auth/auth.component.html
index 3877036..c914655 100644
--- a/src/app/components/auth/auth.component.html
+++ b/src/app/components/auth/auth.component.html
@@ -1,4 +1,4 @@
-
-
-
- {{title}}
- - Dernier saut enregistré : {{ lastJump.numero }}ème à {{ lastJump.lieu }} le {{ lastJump.date | date: 'dd/MM/yyyy' }} - -
-
-
- @for (menuitem of menuItems.getMenuPanel(); track menuitem) {
-
- }
-
-
+
+
-
-
- {{ subtitle }}
-
-
- @if (displayCharts) {
-
+
+
- {{title}}
+ + Dernier saut enregistré : {{ lastJump.numero }}ème à {{ lastJump.lieu }} le {{ lastJump.date | date: 'dd/MM/yyyy' }} +
-
+
+
-
-
-
-
-
-
-
+
+
+ @for (menuitem of menuItems.getMenuPanel(); track menuitem) {
+
}
-
+
-
-
-
+
-
-
-
-
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ title }}
diff --git a/src/app/components/calculator/calculator.component.html b/src/app/components/calculator/calculator.component.html index e76176c..3214fdb 100644 --- a/src/app/components/calculator/calculator.component.html +++ b/src/app/components/calculator/calculator.component.html @@ -1,259 +1,257 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/app/components/canopy/canopy.component.html b/src/app/components/canopy/canopy.component.html
index 50acdec..7bdd887 100644
--- a/src/app/components/canopy/canopy.component.html
+++ b/src/app/components/canopy/canopy.component.html
@@ -1,58 +1,56 @@
-
+
-
-
- {{title}}
- DT48 - 08 février 2024 -
-
-
- @for (menuitem of menuItems.getMenuCalculator(); track menuitem) {
- @if (menuitem.type === 'link') {
-
- }
- }
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+ {{title}}
+ DT48 - 08 février 2024 +
+
+
+ @for (menuitem of menuItems.getMenuCalculator(); track menuitem) {
+ @if (menuitem.type === 'link') {
+
+ }
+ }
+
-
-
-
-
-
-
-
- | - | Taille actuelle | -Taille min | -Taille min -11% | -
|---|---|---|---|
| Taille de voile en ft2 | -● - {{ info.sizesFeet.current }} | -● {{ info.sizesFeet.min }} | -● {{ info.sizesFeet.min11 }} | -
| Charge alaire | -{{ info.charges.current | number : '1.2-3' }} | -{{ info.charges.min | number : '1.2-3' }} | -{{ info.charges.min11 | number : '1.2-3' }} | -
| Taille de voile en m2 | -{{ info.sizesMeter.current | number : '1.2-3' }} | -{{ info.sizesMeter.min | number : '1.2-3' }} | -{{ info.sizesMeter.min11 | number : '1.2-3' }} | -
| Coefficient kilo/livres | -{{ coeffKgLbs }} | -||
| Coefficient pied/mètre | -{{ coeffFtM }} | -||
| Formule charge alaire | -
- ( ( {{ inputs.weight }} + {{ inputs.gear }} ) * {{ coeffKgLbs }} ) /
- {{ inputs.current }} = {{ info.charges.current | number : '1.5' }} - ( ( poids nu en kg + poids equipement en kg ) * coefficient kg/lbs ) / taille de - voile en ft2 - |
- ||
- @if (displayCharts) {
-
-
-
-
- }
- Tailles de voile pour {{ inputs.weight }} kg
-
- Prochain changement de valeurs dans {{ ((this.currentRange.end + 1) - inputs.jumps) }}
- {{ ((this.currentRange.end + 1) - inputs.jumps) > 1 ? 'sauts' : 'saut'}}
-
- -
- {{ ((((inputs.jumps - this.currentRange.start) + 1) / ((this.currentRange.end - this.currentRange.start) + 1)) * 100) | number : '1.2-2' }}%
- de la tranche actuelle ({{this.currentRange.start}} à {{this.currentRange.end}})
-
- | - @for (header of sizesHeader; track header; let index = $index) { - | {{ header.name }} | - } -
|---|---|
| Taille de voile en ft2 | - @for (value of sizesValuesFeet; track value; let index = $index) { -{{ value }} | - } -
| Abbattement 11% | - @for (value of sizesMinValuesFeet; track value; let index = $index) { -{{ value }} | - } -
| Charge alaire | - @for (charge of sizesCharges; track charge; let index = $index) { -- {{ charge | number : '1.2-3' }} | - } -
| Taille de voile en m2 | - @for (value of sizesValuesMeter; track value; let index = $index) { -- {{ value | number : '1.2-2' }} | - } -
Tableau des tailles de voile par poids
-
- {{ ((inputs.jumps / 1600) * 100) | number : '1.2-2' }}% de la plage complète (0 à 1600)
-
- | - {{tableHeader[0].name}} | -- {{element.weight}} - | -- {{tableHeader[1].name}} | -{{element.ranges[0].value}} | -- {{tableHeader[2].name}} | -{{element.ranges[1].value}} | -- {{tableHeader[3].name}} | -{{element.ranges[2].value}} | -- {{tableHeader[4].name}} | -{{element.ranges[3].value}} | -- {{tableHeader[5].name}} | -{{element.ranges[4].value}} | -- {{tableHeader[6].name}} | -{{element.ranges[5].value}} | -- {{tableHeader[7].name}} | -{{element.ranges[6].value}} | -- {{tableHeader[8].name}} | -{{element.ranges[7].value}} | -- {{tableHeader[9].name}} | -{{element.ranges[8].value}} | -
|---|
-
-
-
+
+
+
+
+
+
+ | + | Taille actuelle | +Taille min | +Taille min -11% | +
|---|---|---|---|
| Taille de voile en ft2 | +● + {{ info.sizesFeet.current }} | +● {{ info.sizesFeet.min }} | +● {{ info.sizesFeet.min11 }} | +
| Charge alaire | +{{ info.charges.current | number : '1.2-3' }} | +{{ info.charges.min | number : '1.2-3' }} | +{{ info.charges.min11 | number : '1.2-3' }} | +
| Taille de voile en m2 | +{{ info.sizesMeter.current | number : '1.2-3' }} | +{{ info.sizesMeter.min | number : '1.2-3' }} | +{{ info.sizesMeter.min11 | number : '1.2-3' }} | +
| Coefficient kilo/livres | +{{ coeffKgLbs }} | +||
| Coefficient pied/mètre | +{{ coeffFtM }} | +||
| Formule charge alaire | +
+ ( ( {{ inputs.weight }} + {{ inputs.gear }} ) * {{ coeffKgLbs }} ) /
+ {{ inputs.current }} = {{ info.charges.current | number : '1.5' }} + ( ( poids nu en kg + poids equipement en kg ) * coefficient kg/lbs ) / taille de + voile en ft2 + |
+ ||
+ @if (displayCharts) {
+
+
+
+
+ }
+ Tailles de voile pour {{ inputs.weight }} kg
+
+ Prochain changement de valeurs dans {{ ((this.currentRange.end + 1) - inputs.jumps) }}
+ {{ ((this.currentRange.end + 1) - inputs.jumps) > 1 ? 'sauts' : 'saut'}}
+
+ +
+ {{ ((((inputs.jumps - this.currentRange.start) + 1) / ((this.currentRange.end - this.currentRange.start) + 1)) * 100) | number : '1.2-2' }}%
+ de la tranche actuelle ({{this.currentRange.start}} à {{this.currentRange.end}})
+
+ | + @for (header of sizesHeader; track header; let index = $index) { + | {{ header.name }} | + } +
|---|---|
| Taille de voile en ft2 | + @for (value of sizesValuesFeet; track value; let index = $index) { +{{ value }} | + } +
| Abbattement 11% | + @for (value of sizesMinValuesFeet; track value; let index = $index) { +{{ value }} | + } +
| Charge alaire | + @for (charge of sizesCharges; track charge; let index = $index) { ++ {{ charge | number : '1.2-3' }} | + } +
| Taille de voile en m2 | + @for (value of sizesValuesMeter; track value; let index = $index) { ++ {{ value | number : '1.2-2' }} | + } +
Tableau des tailles de voile par poids
+
+ {{ ((inputs.jumps / 1600) * 100) | number : '1.2-2' }}% de la plage complète (0 à 1600)
+
+ | + {{tableHeader[0].name}} | ++ {{element.weight}} + | ++ {{tableHeader[1].name}} | +{{element.ranges[0].value}} | ++ {{tableHeader[2].name}} | +{{element.ranges[1].value}} | ++ {{tableHeader[3].name}} | +{{element.ranges[2].value}} | ++ {{tableHeader[4].name}} | +{{element.ranges[3].value}} | ++ {{tableHeader[5].name}} | +{{element.ranges[4].value}} | ++ {{tableHeader[6].name}} | +{{element.ranges[5].value}} | ++ {{tableHeader[7].name}} | +{{element.ranges[6].value}} | ++ {{tableHeader[8].name}} | +{{element.ranges[7].value}} | ++ {{tableHeader[9].name}} | +{{element.ranges[8].value}} | +
|---|
+
+
+
-
-
-
+
+
+ {{ subtitle }}
+
+
+ @if (displayCharts) {
+
+
\ No newline at end of file
diff --git a/src/app/components/dashboard/dashboard.component.html b/src/app/components/dashboard/dashboard.component.html
index 71148cd..e05f6dc 100644
--- a/src/app/components/dashboard/dashboard.component.html
+++ b/src/app/components/dashboard/dashboard.component.html
@@ -1,38 +1,36 @@
-
-
-
- {{title}}
- - Dernier saut enregistré : {{ lastJump.numero }}ème à {{ lastJump.lieu }} le {{ lastJump.date | date: 'dd/MM/yyyy' }} - -
-
-
- @for (menuitem of menuItems.getMenuPanel(); track menuitem) {
-
- }
-
-
+
+
-
-
- {{ subtitle }}
-
-
- @if (displayCharts) {
-
+
+
- {{title}}
+ + Dernier saut enregistré : {{ lastJump.numero }}ème à {{ lastJump.lieu }} le {{ lastJump.date | date: 'dd/MM/yyyy' }} +
-
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+ @for (menuitem of menuItems.getMenuPanel(); track menuitem) {
+
}
-
+
-
-
-
+
-
-
-
-
-
-
-
-
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
{{title}}
- - Dernier saut enregistré : {{ lastJump.numero }}ème à {{ lastJump.lieu }} le {{ lastJump.date | date: 'dd/MM/yyyy' }} - -
-
+
+
-
-
+{{title}}
+ + Dernier saut enregistré : {{ lastJump.numero }}ème à {{ lastJump.lieu }} le {{ lastJump.date | date: 'dd/MM/yyyy' }} + +
+
+
-
-
+
-
-
-
-
-
+
+
+
-
-
+
-
-
-
-
-
+
+
-
-
+
-
-
-
-
-
+
+
\ No newline at end of file
+
+
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/src/app/components/dropzone/dropzone.component.html b/src/app/components/dropzone/dropzone.component.html
index af44860..c9bbc23 100644
--- a/src/app/components/dropzone/dropzone.component.html
+++ b/src/app/components/dropzone/dropzone.component.html
@@ -1,57 +1,55 @@
+
+
+
+
+
+
-
-
- Saut n°{{jump.numero}}
-
-
+
+
+ {{ subtitle }}
+
+
+ @if (displayCharts) {
+
+
\ No newline at end of file
diff --git a/src/app/components/home/home.component.html b/src/app/components/home/home.component.html
index 91d2e48..36ce21e 100644
--- a/src/app/components/home/home.component.html
+++ b/src/app/components/home/home.component.html
@@ -1,26 +1,137 @@
-
-
- {{title}}
- - Dernier saut enregistré : {{ lastJump.numero }}ème à {{ lastJump.lieu }} le {{ lastJump.date | date: 'dd/MM/yyyy' }} - -
-
-
- @for (menuitem of menuItems.getMenuPanel(); track menuitem) {
-
- }
-
-
+
+
-
-
- {{ subtitle }}
-
-
- @if (displayCharts) {
-
+
+
- {{title}}
+ + Dernier saut enregistré : {{ lastJump.numero }}ème à {{ lastJump.lieu }} le {{ lastJump.date | date: 'dd/MM/yyyy' }} +
-
+
+
-
-
-
-
-
-
-
+
+
+ @for (menuitem of menuItems.getMenuPanel(); track menuitem) {
+
}
-
+
-
-
-
+
-
-
-
-
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
diff --git a/src/app/components/logbook/dialogs/jump-view.dialog.html b/src/app/components/logbook/dialogs/jump-view.dialog.html
index 9059afe..308ea26 100644
--- a/src/app/components/logbook/dialogs/jump-view.dialog.html
+++ b/src/app/components/logbook/dialogs/jump-view.dialog.html
@@ -1,69 +1,214 @@
-
-
- ju_solide
+ {{ jump.author.username }}
-
+
+
\ No newline at end of file
diff --git a/src/app/components/home/home.component.scss b/src/app/components/home/home.component.scss
index e69de29..5fe7004 100644
--- a/src/app/components/home/home.component.scss
+++ b/src/app/components/home/home.component.scss
@@ -0,0 +1,17 @@
+/* Home */
+//@use 'variable' as var;
+
+
+/*
+#FF41F8
+#F0060B
+#F0070C
+#CC26D5
+#7702FF
+
+#35A2EB
+#B7DDD0
+#B0D9CB
+#D9CAAE
+#9788C7
+*/
diff --git a/src/app/components/home/home.component.ts b/src/app/components/home/home.component.ts
index 5e0ab37..28ad6ac 100644
--- a/src/app/components/home/home.component.ts
+++ b/src/app/components/home/home.component.ts
@@ -41,6 +41,8 @@ export class HomeComponent implements OnInit {
public errors: Errors = { errors: {} };
public lastJump: Jump = {} as Jump;
public destroyRef = inject(DestroyRef);
+ public now = new Date();
+ public isJumpDay = false;
constructor(
private _jumpsService: JumpsService
@@ -50,6 +52,12 @@ export class HomeComponent implements OnInit {
this._lastjump$ = this._jumpsService.getLastJump().pipe(takeUntilDestroyed(this.destroyRef));
this._lastjump = this._lastjump$.subscribe((jump) => {
this.lastJump = jump;
+ this.isJumpDay = this._isToday(new Date(this.lastJump.date));
});
}
+ private _isToday(someDate: Date) {
+ return someDate.getDate() == this.now.getDate() &&
+ someDate.getMonth() == this.now.getMonth() &&
+ someDate.getFullYear() == this.now.getFullYear()
+ }
}
diff --git a/src/app/components/index.ts b/src/app/components/index.ts
index 8e6ecbb..9f98f67 100644
--- a/src/app/components/index.ts
+++ b/src/app/components/index.ts
@@ -6,6 +6,7 @@ export * from './dashboard/dashboard.component';
export * from './dropzone/dropzone.component';
export * from './home/home.component';
export * from './jump/jump.component';
+export * from './jumps/jumps.component';
export * from './logbook/logbook.component';
export * from './profile/profile.component';
export * from './qcm/qcm.component';
diff --git a/src/app/components/jump/jump.component.html b/src/app/components/jump/jump.component.html
index fd296b1..9726868 100644
--- a/src/app/components/jump/jump.component.html
+++ b/src/app/components/jump/jump.component.html
@@ -1,132 +1,283 @@
-
-
-
- {{title}}
- - Dernier saut enregistré : {{ lastJump.numero }}ème à {{ lastJump.lieu }} le {{ lastJump.date | date: 'dd/MM/yyyy' }} - -
-
+ Home works!
-
+
-
-
-
- Card title
-
-
-
-
+
+
+
+ {{title}}
+ + Dernier saut enregistré : {{ lastJump.numero }}ème à {{ lastJump.lieu }} le {{ lastJump.date | date: 'dd/MM/yyyy' }} + +
+ {{ now | date: 'dd/MM/yyyy' }}
+ @if (!isJumpDay) {
+
Aucun saut aujourd'hui + }
- Aucun saut aujourd'hui + }
Home works!
-
+
+
+
+
+
-
diff --git a/src/app/components/logbook/dialogs/jump-edit.dialog.html b/src/app/components/logbook/dialogs/jump-edit.dialog.html
index 077c239..8a72925 100644
--- a/src/app/components/logbook/dialogs/jump-edit.dialog.html
+++ b/src/app/components/logbook/dialogs/jump-edit.dialog.html
@@ -180,7 +180,7 @@
}
-
+
+
+
+
+@if (jump.x2data) {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
+@else {
+
+
+
+
+
+
+ Aucune donnée GPS
+
+
+}
\ No newline at end of file
diff --git a/src/app/components/jump/jump.component.spec.ts b/src/app/components/jump/jump.component.spec.ts
index 8915da0..474dc8c 100644
--- a/src/app/components/jump/jump.component.spec.ts
+++ b/src/app/components/jump/jump.component.spec.ts
@@ -6,10 +6,12 @@ describe('JumpComponent', () => {
let component: JumpComponent;
let fixture: ComponentFixture;
- beforeEach(() => {
- TestBed.configureTestingModule({
- imports: [JumpComponent]
-});
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [JumpComponent]
+ })
+ .compileComponents();
+
fixture = TestBed.createComponent(JumpComponent);
component = fixture.componentInstance;
fixture.detectChanges();
diff --git a/src/app/components/jump/jump.component.ts b/src/app/components/jump/jump.component.ts
index 241335f..5ef29bf 100644
--- a/src/app/components/jump/jump.component.ts
+++ b/src/app/components/jump/jump.component.ts
@@ -1,248 +1,71 @@
-import { trigger, state, style, animate, transition } from '@angular/animations';
import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core';
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
-import { ActivatedRoute } from '@angular/router';
-import { CommonModule } from '@angular/common';
+import { DatePipe, DecimalPipe } from '@angular/common';
+import { ActivatedRoute, RouterLink } from '@angular/router';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatDividerModule } from '@angular/material/divider';
-import { MatExpansionModule } from '@angular/material/expansion';
import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu';
-
import { Observable, Subscription } from 'rxjs';
-import { MenuItems } from 'src/app/components/shared';
-import { BarsChartComponent, CircleChartComponent, LineChartComponent, LineAreaChartComponent } from 'src/app/components/shared/helpers-chart';
-import { UtilitiesService } from 'src/app/core/services';
-import { Jump, JumpByCategorie, JumpByDate, JumpByDateByModule, JumpByModule, JumpsPageData, JumpYears } from 'src/app/core/models';
+import { ListErrorsComponent, MenuItems } from 'src/app/components/shared';
+import { Errors, Jump, JumpPageData } from 'src/app/core/models';
@Component({
selector: 'app-jump',
standalone: true,
imports: [
- CommonModule,
- MatButtonModule, MatCardModule, MatDividerModule,
- MatExpansionModule, MatIconModule, MatMenuModule,
- BarsChartComponent, CircleChartComponent, LineChartComponent, LineAreaChartComponent
+ DatePipe, DecimalPipe, RouterLink,
+ MatButtonModule, MatCardModule,
+ MatDividerModule, MatIconModule, MatMenuModule,
+ ListErrorsComponent
],
templateUrl: './jump.component.html',
- styleUrl: './jump.component.scss',
- animations: [
- trigger('flyInOut', [
- state('in', style({ transform: 'translateX(0)' })),
- transition('void => *', [
- style({ transform: 'translateX(-100%)' }),
- animate(200)
- ]),
- transition('* => void', [
- style({ transform: 'translateX(100%)' }),
- animate(200)
- ])
- ])
- ]
+ styleUrl: './jump.component.scss'
})
export class JumpComponent implements OnInit, OnDestroy {
private _data: Subscription = new Subscription();
- private _jumpsByCategorie: Array = [];
- private _jumpsByModule: Array = [];
- private _jumpsByDate: Array = [];
- public lastJump: Jump = {} as Jump;
- public title: string = 'Sauts';
- public subtitle: string = 'Nombre total de sauts par mois';
- public displayCharts = false;
+ public title: string = '';
+ public errors: Errors = { errors: {} };
public destroyRef = inject(DestroyRef);
- public min = 0;
- public max = 0;
- public grandAvg = 0;
- public grandAvgLastYears = 0;
- public grandTotal = 0;
- public seriesHeader: string[] = [];
- public seriesName: string[] = [];
- public seriesRow: Array> = [];
- public seriesColor: {
- backgroundColor: string[],
- borderColor: string[]
- } = {
- backgroundColor: this._utilitiesService.getSeriesColors(0.8, 'all'),
- borderColor: this._utilitiesService.getSeriesColors(1, 'all')
- };
- public seriesTypesHeader: string[] = [];
- public seriesTypesName: string[] = [];
- public seriesTypesRow: Array> = [];
- public seriesTypesRowCumulated: Array> = [];
- public seriesTypesColor: {
- backgroundColor: string[],
- borderColor: string[]
- } = {
- backgroundColor: this._utilitiesService.getSeriesColors(0.8, 'pastels'),
- borderColor: this._utilitiesService.getSeriesColors(1, 'pastels')
- };
- public seriesColorClass: string[] = this._utilitiesService.getChartColors();
- public seriesRowTotal: number[] = [];
- public seriesRowAvg: number[] = [];
- public seriesRowAvgLastYears: number[] = [];
- public seriesColTotal: number[] = [];
- public seriesColTotalClosed: number[] = [];
- public seriesColTotalLastYears: number[] = [];
+ public jump: Jump = {} as Jump;
+ public prevSlug: string = '';
+ public nextSlug: string = '';
constructor(
private route: ActivatedRoute,
- private _utilitiesService: UtilitiesService,
public menuItems: MenuItems
) { }
ngOnInit() {
- const data$: Observable<{ jumpsPageData: JumpsPageData }> = this.route.data as Observable<{ jumpsPageData: JumpsPageData }>;
- this._data = data$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { jumpsPageData: JumpsPageData }) => {
- const pageData: JumpsPageData = data.jumpsPageData;
- this.lastJump = pageData.lastjump;
- const currentYear: number = new Date().getFullYear();
- const types: Array = ['FF', 'Solo', 'VR', 'Wingsuit'];
- const verticals: Array = ['Chutas', 'Head Up', 'Head Down'];
- const others: Array = ['Track', 'Trace'];
- const modules: Array = [...verticals, ...others];
- this.min = pageData.jumpsByYears[0].year;
- this.max = pageData.jumpsByYears[(pageData.jumpsByYears.length-1)].year;
-
- this.seriesHeader = this._utilitiesService.getMonthsList();
- const values: Array = this.seriesHeader.map(() => 0);
- this.seriesColTotal = [...values];
- this.seriesColTotalClosed = [...values];
- this.seriesColTotalLastYears = [...values];
- this.seriesName = pageData.jumpsByYears.map((row: JumpYears) => {
- this.seriesRow.push([...values]);
- return row.year.toString();
- });
-
- this._jumpsByDate = pageData.jumpsByDate.map((row: JumpByDate) => {
- this.seriesRow[(row.year-this.min)][(row.month-1)] = row.count;
- this.seriesColTotal[(row.month-1)] += row.count;
- if (row.year < currentYear) {
- this.seriesColTotalClosed[(row.month-1)] += row.count;
- }
- if (row.year >= (currentYear-3) && row.year < currentYear) {
- this.seriesColTotalLastYears[(row.month-1)] += row.count;
- }
- return row;
- });
- this.seriesRow.forEach((row: number[]) => {
- const total = row.reduce((partialSum, a) => partialSum + a, 0);
- this.seriesRowTotal.push(total);
- });
- this.seriesColTotalClosed.forEach((row: number) => {
- const value: number = (row/(this.seriesName.length-2)); // -2 pour ne pas compter la première année
- this.seriesRowAvg.push(parseInt(value.toFixed(0)));
- });
- this.seriesColTotalLastYears.forEach((row: number) => {
- const value: number = (row/3); // Les 3 dernières années
- this.seriesRowAvgLastYears.push(parseInt(value.toFixed(0)));
- });
- this.grandAvg = this.seriesRowAvg.reduce((partialSum, accumulated) => partialSum + accumulated, 0);
- this.grandAvgLastYears = this.seriesRowAvgLastYears.reduce((partialSum, accumulated) => partialSum + accumulated, 0);
- this.grandTotal = this.seriesColTotal.reduce((partialSum, accumulated) => partialSum + accumulated, 0);
-
- pageData.jumpsByCategory.forEach((row: JumpByCategorie) => {
- if (types.indexOf(row.categorie) !== -1) {
- this._jumpsByCategorie.push(row);
- }
- });
-
- //const focus: Array = ['FF', 'Solo']; // ['FF']
- let verticalCount:number = 0;
- let otherCount:number = 0;
- pageData.jumpsByModule.forEach((row: JumpByModule) => {
- //if (focus.indexOf(row.categorie) !== -1 && modules.indexOf(row.module) !== -1) {
- if (modules.indexOf(row.module) !== -1) {
- if (verticals.indexOf(row.module) !== -1) {
- verticalCount += row.count;
- } else {
- otherCount += row.count;
- }
- }
- });
- if (verticalCount > 0) {
- const row:JumpByModule = {
- categorie: 'FF',
- module: 'Vertical',
- count: verticalCount
- }
- this._jumpsByModule.push(row);
- }
- if (otherCount > 0) {
- const row:JumpByModule = {
- categorie: 'FF',
- module: 'Track/Trace',
- count: otherCount
- }
- this._jumpsByModule.push(row);
- }
-
- for (let year = 0; year < pageData.jumpsByYears.length; year++) {
- for (let index = 0; index < 12; index++) {
- const month: string = ((index+1) < 10) ? `0${(index+1)}` : `${(index+1)}`;
- this.seriesTypesHeader.push(`${month}-${pageData.jumpsByYears[year].year}`);
- }
- }
- const emptyValues: Array = this.seriesTypesHeader.map(() => 0);
- this.seriesTypesName = types;
- this.seriesTypesName.forEach(() => {
- this.seriesTypesRow.push([...emptyValues]);
- });
- pageData.jumpsByDateByModule.forEach((row: JumpByDateByModule) => {
- const indexOf: number = this.seriesTypesName.indexOf(row.categorie);
- if (indexOf !== -1) {
- this.seriesTypesRow[indexOf][(((row.year-this.min)*12)+row.month-1)] += row.count;
- }
- });
- this.seriesTypesRowCumulated = this.seriesTypesRow.map((row: Array) => {
- let accumulated: number = 0;
- return row.map((value: number) => {
- accumulated += value;
- return accumulated;
- });
- });
- this.seriesTypesHeader = this.seriesTypesHeader.slice((pageData.jumpsByDateByModule[0].month+1), -(pageData.jumpsByDateByModule[(pageData.jumpsByDateByModule.length-1)].month));
- this.seriesTypesRow = this.seriesTypesRow.map((row: Array) => {
- return row.slice((pageData.jumpsByDateByModule[0].month+1), -(pageData.jumpsByDateByModule[(pageData.jumpsByDateByModule.length-1)].month));
- });
- this.seriesTypesRowCumulated = this.seriesTypesRowCumulated.map((row: Array) => {
- return row.slice((pageData.jumpsByDateByModule[0].month+1), -(pageData.jumpsByDateByModule[(pageData.jumpsByDateByModule.length-1)].month));
- });
- /*
- console.log('this.min', this.min);
- console.log('this.max', this.max);
- console.log('this.lastJump', this.lastJump);
- console.log('this.seriesHeader', this.seriesHeader);
- console.log('this.seriesName', this.seriesName);
- console.log('this.seriesRow', this.seriesRow);
- console.log('this.seriesRowTotal', this.seriesRowTotal);
- console.log('this.seriesRowAvg', this.seriesRowAvg);
- console.log('this.seriesRowAvgLastYears', this.seriesRowAvgLastYears);
- console.log('this._jumpsByCategorie', this._jumpsByCategorie);
- console.log('this._jumpsByModule', this._jumpsByModule);
- console.log('this.seriesTypesHeader', this.seriesTypesHeader);
- console.log('this.seriesTypesName', this.seriesTypesName);
- console.log('this.seriesTypesRow', this.seriesTypesRow);
- console.log('this.seriesTypesRowCumulated', this.seriesTypesRowCumulated);
- */
- this.displayCharts = true;
+ const data$: Observable<{ pageData: JumpPageData }> = this.route.data as Observable<{ pageData: JumpPageData }>;
+ this._data = data$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { pageData: JumpPageData }) => {
+ this.jump = data.pageData.jump;
+ this.prevSlug = data.pageData.prevJump?.slug;
+ this.nextSlug = data.pageData.nextJump?.slug;
+ this.title = `Saut n° ${this.jump.numero} `;
});
+ /*
+ const data$: Observable = this.route.data as Observable;
+ this._data = data$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: Jump) => {
+ this.jump = data;
+ console.log('jump : ', this.jump);
+ });
+ */
}
ngOnDestroy() {
this._data.unsubscribe();
}
- public getCategories(): Array {
- return this._jumpsByCategorie;
+ formatDuration(duration: number): string {
+ const start = new Date(0);
+ start.setSeconds(duration);
+ return start.toISOString().substring(14, 19);
}
- public getModules(): Array {
- return this._jumpsByModule;
- }
-
- public getModuleColor(index: number): number {
- return (this._jumpsByCategorie.length + index);
+ private _resetErrors(): void {
+ this.errors = { errors: {} };
}
}
diff --git a/src/app/components/jumps/jumps.component.html b/src/app/components/jumps/jumps.component.html
new file mode 100644
index 0000000..e7a89b7
--- /dev/null
+++ b/src/app/components/jumps/jumps.component.html
@@ -0,0 +1,130 @@
+;
+
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ imports: [JumpsComponent]
+});
+ fixture = TestBed.createComponent(JumpsComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/components/jumps/jumps.component.ts b/src/app/components/jumps/jumps.component.ts
new file mode 100644
index 0000000..0cfe22c
--- /dev/null
+++ b/src/app/components/jumps/jumps.component.ts
@@ -0,0 +1,249 @@
+import { trigger, state, style, animate, transition } from '@angular/animations';
+import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core';
+import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
+import { ActivatedRoute } from '@angular/router';
+import { CommonModule } from '@angular/common';
+import { MatButtonModule } from '@angular/material/button';
+import { MatCardModule } from '@angular/material/card';
+import { MatDividerModule } from '@angular/material/divider';
+import { MatExpansionModule } from '@angular/material/expansion';
+import { MatIconModule } from '@angular/material/icon';
+import { MatMenuModule } from '@angular/material/menu';
+
+import { Observable, Subscription } from 'rxjs';
+
+import { MenuItems } from 'src/app/components/shared';
+import { BarsChartComponent, CircleChartComponent, LineChartComponent, LineAreaChartComponent } from 'src/app/components/shared/helpers-chart';
+import { UtilitiesService } from 'src/app/core/services';
+import { Jump, JumpByCategorie, JumpByDate, JumpByDateByModule, JumpByModule, JumpsPageData, JumpYears } from 'src/app/core/models';
+
+@Component({
+ selector: 'app-jumps',
+ standalone: true,
+ imports: [
+ CommonModule,
+ MatButtonModule, MatCardModule, MatDividerModule,
+ MatExpansionModule, MatIconModule, MatMenuModule,
+ BarsChartComponent, CircleChartComponent, LineChartComponent, LineAreaChartComponent
+ ],
+ templateUrl: './jumps.component.html',
+ styleUrl: './jumps.component.scss',
+ animations: [
+ trigger('flyInOut', [
+ state('in', style({ transform: 'translateX(0)' })),
+ transition('void => *', [
+ style({ transform: 'translateX(-100%)' }),
+ animate(200)
+ ]),
+ transition('* => void', [
+ style({ transform: 'translateX(100%)' }),
+ animate(200)
+ ])
+ ])
+ ]
+})
+export class JumpsComponent implements OnInit, OnDestroy {
+ private _data: Subscription = new Subscription();
+ private _jumpsByCategorie: Array = [];
+ private _jumpsByModule: Array = [];
+ private _jumpsByDate: Array = [];
+ public lastJump: Jump = {} as Jump;
+ public title: string = 'Sauts';
+ public subtitle: string = 'Nombre total de sauts par mois';
+ public displayCharts = false;
+ public destroyRef = inject(DestroyRef);
+ public min = 0;
+ public max = 0;
+ public grandAvg = 0;
+ public grandAvgLastYears = 0;
+ public grandTotal = 0;
+ public seriesHeader: string[] = [];
+ public seriesName: string[] = [];
+ public seriesRow: Array> = [];
+ public seriesColor: {
+ backgroundColor: string[],
+ borderColor: string[]
+ } = {
+ backgroundColor: this._utilitiesService.getSeriesColors(0.8, 'all'),
+ borderColor: this._utilitiesService.getSeriesColors(1, 'all')
+ };
+ public seriesTypesHeader: string[] = [];
+ public seriesTypesName: string[] = [];
+ public seriesTypesRow: Array> = [];
+ public seriesTypesRowCumulated: Array> = [];
+ public seriesTypesColor: {
+ backgroundColor: string[],
+ borderColor: string[]
+ } = {
+ backgroundColor: this._utilitiesService.getSeriesColors(0.8, 'pastels'),
+ borderColor: this._utilitiesService.getSeriesColors(1, 'pastels')
+ };
+ public seriesColorClass: string[] = this._utilitiesService.getChartColors();
+ public seriesRowTotal: number[] = [];
+ public seriesRowAvg: number[] = [];
+ public seriesRowAvgLastYears: number[] = [];
+ public seriesColTotal: number[] = [];
+ public seriesColTotalClosed: number[] = [];
+ public seriesColTotalLastYears: number[] = [];
+
+ constructor(
+ private route: ActivatedRoute,
+ private _utilitiesService: UtilitiesService,
+ public menuItems: MenuItems
+ ) { }
+
+ ngOnInit() {
+ const data$: Observable<{ pageData: JumpsPageData }> = this.route.data as Observable<{ pageData: JumpsPageData }>;
+ this._data = data$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { pageData: JumpsPageData }) => {
+ const pageData: JumpsPageData = data.pageData;
+ this.lastJump = pageData.lastjump;
+ const currentYear: number = new Date().getFullYear();
+ const types: Array = ['FF', 'Solo', 'VR', 'Wingsuit'];
+ const verticals: Array = ['Chutas', 'Head Up', 'Head Down'];
+ const others: Array = ['Track', 'Trace'];
+ const modules: Array = [...verticals, ...others];
+ const minoration = 2; // -2 pour ne pas compter la première année
+ this.min = pageData.jumpsByYears[0].year;
+ this.max = pageData.jumpsByYears[(pageData.jumpsByYears.length-1)].year;
+
+ this.seriesHeader = this._utilitiesService.getMonthsList();
+ const values: Array = this.seriesHeader.map(() => 0);
+ this.seriesColTotal = [...values];
+ this.seriesColTotalClosed = [...values];
+ this.seriesColTotalLastYears = [...values];
+ this.seriesName = pageData.jumpsByYears.map((row: JumpYears) => {
+ this.seriesRow.push([...values]);
+ return row.year.toString();
+ });
+
+ this._jumpsByDate = pageData.jumpsByDate.map((row: JumpByDate) => {
+ this.seriesRow[(row.year-this.min)][(row.month-1)] = row.count;
+ this.seriesColTotal[(row.month-1)] += row.count;
+ if (row.year < currentYear) {
+ this.seriesColTotalClosed[(row.month-1)] += row.count;
+ }
+ if (row.year >= (currentYear-3) && row.year < currentYear) {
+ this.seriesColTotalLastYears[(row.month-1)] += row.count;
+ }
+ return row;
+ });
+ this.seriesRow.forEach((row: number[]) => {
+ const total = row.reduce((partialSum, a) => partialSum + a, 0);
+ this.seriesRowTotal.push(total);
+ });
+ this.seriesColTotalClosed.forEach((row: number) => {
+ const value: number = (row/(this.seriesName.length-minoration));
+ this.seriesRowAvg.push(parseInt(value.toFixed(0)));
+ });
+ this.seriesColTotalLastYears.forEach((row: number) => {
+ const value: number = (row/3); // Les 3 dernières années
+ this.seriesRowAvgLastYears.push(parseInt(value.toFixed(0)));
+ });
+ this.grandAvg = this.seriesRowAvg.reduce((partialSum, accumulated) => partialSum + accumulated, 0);
+ this.grandAvgLastYears = this.seriesRowAvgLastYears.reduce((partialSum, accumulated) => partialSum + accumulated, 0);
+ this.grandTotal = this.seriesColTotal.reduce((partialSum, accumulated) => partialSum + accumulated, 0);
+
+ pageData.jumpsByCategory.forEach((row: JumpByCategorie) => {
+ if (types.indexOf(row.categorie) !== -1) {
+ this._jumpsByCategorie.push(row);
+ }
+ });
+
+ //const focus: Array = ['FF', 'Solo']; // ['FF']
+ let verticalCount:number = 0;
+ let otherCount:number = 0;
+ pageData.jumpsByModule.forEach((row: JumpByModule) => {
+ //if (focus.indexOf(row.categorie) !== -1 && modules.indexOf(row.module) !== -1) {
+ if (modules.indexOf(row.module) !== -1) {
+ if (verticals.indexOf(row.module) !== -1) {
+ verticalCount += row.count;
+ } else {
+ otherCount += row.count;
+ }
+ }
+ });
+ if (verticalCount > 0) {
+ const row:JumpByModule = {
+ categorie: 'FF',
+ module: 'Vertical',
+ count: verticalCount
+ }
+ this._jumpsByModule.push(row);
+ }
+ if (otherCount > 0) {
+ const row:JumpByModule = {
+ categorie: 'FF',
+ module: 'Track/Trace',
+ count: otherCount
+ }
+ this._jumpsByModule.push(row);
+ }
+
+ for (let year = 0; year < pageData.jumpsByYears.length; year++) {
+ for (let index = 0; index < 12; index++) {
+ const month: string = ((index+1) < 10) ? `0${(index+1)}` : `${(index+1)}`;
+ this.seriesTypesHeader.push(`${month}-${pageData.jumpsByYears[year].year}`);
+ }
+ }
+ const emptyValues: Array = this.seriesTypesHeader.map(() => 0);
+ this.seriesTypesName = types;
+ this.seriesTypesName.forEach(() => {
+ this.seriesTypesRow.push([...emptyValues]);
+ });
+ pageData.jumpsByDateByModule.forEach((row: JumpByDateByModule) => {
+ const indexOf: number = this.seriesTypesName.indexOf(row.categorie);
+ if (indexOf !== -1) {
+ this.seriesTypesRow[indexOf][(((row.year-this.min)*12)+row.month-1)] += row.count;
+ }
+ });
+ this.seriesTypesRowCumulated = this.seriesTypesRow.map((row: Array) => {
+ let accumulated: number = 0;
+ return row.map((value: number) => {
+ accumulated += value;
+ return accumulated;
+ });
+ });
+ this.seriesTypesHeader = this.seriesTypesHeader.slice((pageData.jumpsByDateByModule[0].month+1), -(pageData.jumpsByDateByModule[(pageData.jumpsByDateByModule.length-1)].month));
+ this.seriesTypesRow = this.seriesTypesRow.map((row: Array) => {
+ return row.slice((pageData.jumpsByDateByModule[0].month+1), -(pageData.jumpsByDateByModule[(pageData.jumpsByDateByModule.length-1)].month));
+ });
+ this.seriesTypesRowCumulated = this.seriesTypesRowCumulated.map((row: Array) => {
+ return row.slice((pageData.jumpsByDateByModule[0].month+1), -(pageData.jumpsByDateByModule[(pageData.jumpsByDateByModule.length-1)].month));
+ });
+ /*
+ console.log('this.min', this.min);
+ console.log('this.max', this.max);
+ console.log('this.lastJump', this.lastJump);
+ console.log('this.seriesHeader', this.seriesHeader);
+ console.log('this.seriesName', this.seriesName);
+ console.log('this.seriesRow', this.seriesRow);
+ console.log('this.seriesRowTotal', this.seriesRowTotal);
+ console.log('this.seriesRowAvg', this.seriesRowAvg);
+ console.log('this.seriesRowAvgLastYears', this.seriesRowAvgLastYears);
+ console.log('this._jumpsByCategorie', this._jumpsByCategorie);
+ console.log('this._jumpsByModule', this._jumpsByModule);
+ console.log('this.seriesTypesHeader', this.seriesTypesHeader);
+ console.log('this.seriesTypesName', this.seriesTypesName);
+ console.log('this.seriesTypesRow', this.seriesTypesRow);
+ console.log('this.seriesTypesRowCumulated', this.seriesTypesRowCumulated);
+ */
+ this.displayCharts = true;
+ });
+ }
+
+ ngOnDestroy() {
+ this._data.unsubscribe();
+ }
+
+ public getCategories(): Array {
+ return this._jumpsByCategorie;
+ }
+
+ public getModules(): Array {
+ return this._jumpsByModule;
+ }
+
+ public getModuleColor(index: number): number {
+ return (this._jumpsByCategorie.length + index);
+ }
+}
diff --git a/src/app/components/logbook/dialogs/jump-add.dialog.html b/src/app/components/logbook/dialogs/jump-add.dialog.html
index 8a7a9b4..4612117 100644
--- a/src/app/components/logbook/dialogs/jump-add.dialog.html
+++ b/src/app/components/logbook/dialogs/jump-add.dialog.html
@@ -245,7 +245,7 @@
}
- ju_solide
+ {{ lastJump.author.username }}
-
+
-
-
- {{title}}
- - Dernier saut enregistré : {{ lastJump.numero }}ème à {{ lastJump.lieu }} le {{ lastJump.date | date: 'dd/MM/yyyy' }} - -
-
+
+
+
+ -
+
- Aeronef: +
- {{ jump.aeronef }} {{ jump.imat }} +
- Voile: +
- {{ jump.voile }} {{ jump.taille }} ft2 + @if (jump.programme) { +
- Programme: +
- {{ jump.programme }} + } +
+
+ -
+ @if (!jump.x2data) {
+
- Hauteur: +
- {{ jump.hauteur }} m +
- Déploiement: +
- {{ jump.deploiement }} m + } + @for (file of jump.files; track file) { +
- Fichier {{ file.type }} +
- {{ file.name }} + } +
+
+
+
+ }
+ {{ jump.x2data.altitude.exit }} m
+
+ Hauteur
+ @if (jump.x2data.altitude.exit > 4200) { +
+
+ {{ formatDuration(jump.x2data.duration.freeFall) }}
+
+ Durée de la chute
+ {{ formatDuration(jump.x2data.duration.freeFall) }}
+
+
+ {{ jump.x2data.altitude.deployment }} m
+ }
+ @else if (jump.x2data.altitude.deployment < 750) {
+
+ {{ jump.x2data.altitude.deployment }} m
+ }
+ @else if (jump.x2data.altitude.deployment > 1000) {
+
+ {{ jump.x2data.altitude.deployment }} m
+ }
+
+ Déploiement
+ @if (jump.x2data.altitude.deployment < 650) { +
+
+
+
+ @for (sautant of jump.sautants; track sautant) {
+
+
+ {{ sautant }}
+
+ }
+
+
+ {{ jump.author.username }}
+
+
+ @if (jump.accessoires) {
+ Participants ({{ jump.sautants.length + 1 }})
+ @for (sautant of jump.sautants; track sautant) {
+
+
+
+
+
+ {{ jump.accessoires }}
+
+
+ }
+ Accessoires
+
+
+
+
+
+
+
+
+ Vitesse en chute
+
+
+ Vitesse maximale
+ {{ (jump.x2data.speed.freeFall.vertical.max / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+ Vitesse moyenne
+ {{ (jump.x2data.speed.freeFall.vertical.avg / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+ Vitesse maximale
+ {{ (jump.x2data.speed.freeFall.horizontal.max / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+ Vitesse moyenne
+ {{ (jump.x2data.speed.freeFall.horizontal.avg / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+
+
+
+
+
+ Vitesse sous voile
+
+
+ Vitesse maximale
+ {{ (jump.x2data.speed.underCanopy.vertical.max / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+ Vitesse moyenne
+ {{ (jump.x2data.speed.underCanopy.vertical.avg / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+ Vitesse maximale
+ {{ (jump.x2data.speed.underCanopy.horizontal.max / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+ Vitesse moyenne
+ {{ (jump.x2data.speed.underCanopy.horizontal.avg / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+
+
+
+
+
+ Finesse
+
+
+ Finesse Max
+ {{ jump.x2data.glideRatio.freeFall.max | number : '1.2-2' }} +
+
+ Finesse Moyenne
+ {{ jump.x2data.glideRatio.freeFall.avg | number : '1.2-2' }} +
+
+ Finesse Max
+ {{ jump.x2data.glideRatio.underCanopy.max | number : '1.2-2' }} +
+
+ Finesse Moyenne
+ {{ jump.x2data.glideRatio.underCanopy.avg | number : '1.2-2' }} +
+
+
+
+
+ Distance
+
+
+ Distance au largage
+ {{ jump.x2data.distance.exitFromLandingZone| number : '1.0-0' }} m +
+
+ Durée sous voile
+ {{ formatDuration(jump.x2data.duration.underCanopy) }} +
+
+ Distance totale
+ {{ jump.x2data.distance.totalFlying | number : '1.0-0' }} m +
+
+ Distance horizontale
+ {{ jump.x2data.distance.totalHorizontal | number : '1.0-0' }} m +
+
+
+
+ @for (sautant of jump.sautants; track sautant) {
+
+
+ {{ sautant }}
+
+ }
+
+
+ {{ jump.author.username }}
+
+
+ Participants ({{ jump.sautants.length + 1 }})
+ @for (sautant of jump.sautants; track sautant) {
+
+
+
+
+
+ {{ subtitle }}
+
+
+ @if(displayCharts) {
+
+
+
+
+ Types de sauts
+
+
+ @if(displayCharts) {
+
+
+
+ }
+
+
+
\ No newline at end of file
diff --git a/src/app/components/jumps/jumps.component.scss b/src/app/components/jumps/jumps.component.scss
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/components/jumps/jumps.component.spec.ts b/src/app/components/jumps/jumps.component.spec.ts
new file mode 100644
index 0000000..48c78e8
--- /dev/null
+++ b/src/app/components/jumps/jumps.component.spec.ts
@@ -0,0 +1,21 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { JumpsComponent } from './jumps.component';
+
+describe('JumpsComponent', () => {
+ let component: JumpsComponent;
+ let fixture: ComponentFixture
+
+
+
+
+ {{title}}
+ + Dernier saut enregistré : {{ lastJump.numero }}ème à {{ lastJump.lieu }} le {{ lastJump.date | date: 'dd/MM/yyyy' }} + +
+
+
+
+
+ @for (menuitem of menuItems.getMenuPanel(); track menuitem) {
+
+
+ {{ menuitem.name }}
+
+ }
+
+
+
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ | + | {{ name }} | +Total | +
|---|---|---|
| ● {{ seriesName[i] }} | +
+ {{ value }}
+ |
+ {{ seriesRowTotal[i] }} | +
| Total | +
+ {{ value }}
+ |
+ {{ grandTotal }} | +
| Moyenne | +
+ {{ value | number : '1.0-1' }}
+ |
+ {{ grandAvg | number : '1.0-1' }} | +
| Moyenne 3 dernières années | +
+ {{ value | number : '1.0-1' }}
+ |
+ {{ grandAvgLastYears | number : '1.0-1' }} | +
+
+
+
+
+
+ @for (item of getCategories(); track $index) {
+
+
+
+
+ }
+ @for (item of getModules(); track $index) {
+
+
+
+ }
+
- Saut n°{{jump.numero}}
-
+
+ Saut n° {{jump.numero}}
+
-
- Le {{ jump.date | date: 'dd/MM/yyyy' }} à {{ jump.lieu }} :
-
-
-
- - Lieu:
- - {{jump.lieu}}
- - Oaci:
- - {{jump.oaci}}
- - Aeronef:
- - {{jump.aeronef}}
- - Imat:
- - {{jump.imat}}
- - Voile:
- - {{jump.voile}}
- - Taille:
- - {{jump.taille}} ft2
- - Participants:
- - {{jump.participants}}
- - Sautants:
- -
- @for (sautant of jump.sautants; track sautant) {
-
-
- {{ sautant }}
-
- }
-
-
- ju_solide
-
-
-
-
-
-
- - Hauteur:
- - {{jump.hauteur}} m
- - Deploiement:
- - {{jump.deploiement}} m
- - Categorie:
- - {{jump.categorie}}
- - Module:
- - {{jump.module}}
- - Accessoires:
- - {{jump.accessoires}}
- - Zone:
- - {{jump.zone}}
- - Dossier media:
- - {{jump.dossier}}
- - Video:
- - {{jump.video}}
- - Programme:
- - {{jump.programme}}
-
-
+
+
+
+ Le {{ jump.date | date: 'dd/MM/yyyy' }} à {{ jump.lieu }} {{ jump.zone ? jump.zone : jump.oaci }} :
+
+
+
+ {{ jump.categorie }}
+ @if (jump.module) {
+ /
+ {{ jump.module }}
+ }
+
+
+
+
+
+ - Aeronef:
+ - {{ jump.aeronef }} {{ jump.imat }}
+ - Voile:
+ - {{ jump.voile }} {{ jump.taille }} ft2
+ @if (jump.programme) {
+ - Programme:
+ - {{ jump.programme }}
+ }
+
+
+
+
+ @if (!jump.x2data) {
+ - Hauteur:
+ - {{ jump.hauteur }} m
+ - Déploiement:
+ - {{ jump.deploiement }} m
+ }
+ @for (file of jump.files; track file) {
+ - Fichier {{ file.type }}
+ - {{ file.name }}
+ }
+
+
+
+
+ @if (jump.x2data) {
+
+
+ Hauteur
+ {{ jump.x2data.altitude.exit }} m
+
+
+ Durée de la chute
+ {{formatDuration(jump.x2data.duration.freeFall)}}
+
+
+ Déploiement
+ {{ jump.x2data.altitude.deployment }} m
+
+
+
+
+ Participants ({{ jump.sautants.length + 1 }})
+ @for (sautant of jump.sautants; track sautant) {
+
+
+ {{ sautant }}
+
+ }
+
+
+ {{ jump.author.username }}
+
+
+ @if (jump.accessoires) {
+
+ Accessoires
+
+
+ {{ jump.accessoires }}
+
+
+ }
+
+
+
+
+ Vitesse en chute
+
+
+ Max Verticale
+ {{ (jump.x2data.speed.freeFall.vertical.max / 1000 * 60 * 60) | number : '1.0-0' }} km/h
+
+
+ Max Horizontale
+ {{ (jump.x2data.speed.freeFall.horizontal.max / 1000 * 60 * 60) | number : '1.0-0' }} km/h
+
+
+ Moyenne Verticale
+ {{ (jump.x2data.speed.freeFall.vertical.avg / 1000 * 60 * 60) | number : '1.0-0' }} km/h
+
+
+ Moyenne Horizontale
+ {{ (jump.x2data.speed.freeFall.horizontal.avg / 1000 * 60 * 60) | number : '1.0-0' }} km/h
+
+
+
+
+
+
+ Vitesse sous voile
+
+
+ Max Verticale
+ {{ (jump.x2data.speed.underCanopy.vertical.max / 1000 * 60 * 60) | number : '1.0-0' }} km/h
+
+
+ Max Horizontale
+ {{ (jump.x2data.speed.underCanopy.horizontal.max / 1000 * 60 * 60) | number : '1.0-0' }} km/h
+
+
+ Moyenne Verticale
+ {{ (jump.x2data.speed.underCanopy.vertical.avg / 1000 * 60 * 60) | number : '1.0-0' }} km/h
+
+
+ Moyenne Horizontale
+ {{ (jump.x2data.speed.underCanopy.horizontal.avg / 1000 * 60 * 60) | number : '1.0-0' }} km/h
+
+
+
+
+
+
+ Finesse
+
+
+ Finesse en chute
+
+
+ Finesse sous voile
+
+
+
+
+ Finesse Max
+ {{ jump.x2data.glideRatio.freeFall.max | number : '1.2-2' }}
+
+
+ Finesse Moyenne
+ {{ jump.x2data.glideRatio.freeFall.avg | number : '1.2-2' }}
+
+
+ Finesse Max
+ {{ jump.x2data.glideRatio.underCanopy.max | number : '1.2-2' }}
+
+
+ Finesse Moyenne
+ {{ jump.x2data.glideRatio.underCanopy.avg | number : '1.2-2' }}
+
+
+
+
+
+
+ Distance
+
+
+ Distance au largage
+ {{ jump.x2data.distance.exitFromLandingZone| number : '1.0-0' }} m
+
+
+ Durée sous voile
+ {{formatDuration(jump.x2data.duration.underCanopy)}}
+
+
+ Distance totale
+ {{ jump.x2data.distance.totalFlying | number : '1.0-0' }} m
+
+
+ Distance horizontale
+ {{ jump.x2data.distance.totalHorizontal | number : '1.0-0' }} m
+
+
+
+ }
+ @else {
+
+
+ Participants ({{ jump.sautants.length + 1 }})
+ @for (sautant of jump.sautants; track sautant) {
+
+
+ {{ sautant }}
+
+ }
+
+
+ {{ jump.author.username }}
+
+
+
+
+ Aucune donnée GPS
+
+ }
-
-
-
- Fermer
+
+ Fermer
diff --git a/src/app/components/logbook/dialogs/jump-view.dialog.ts b/src/app/components/logbook/dialogs/jump-view.dialog.ts
index 1e41a9d..cc59ab8 100644
--- a/src/app/components/logbook/dialogs/jump-view.dialog.ts
+++ b/src/app/components/logbook/dialogs/jump-view.dialog.ts
@@ -1,5 +1,5 @@
import { Component, Inject } from '@angular/core';
-import { DatePipe } from '@angular/common';
+import { DatePipe, DecimalPipe } from '@angular/common';
import { MatButtonModule } from '@angular/material/button';
import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
import { MatDividerModule } from '@angular/material/divider';
@@ -12,11 +12,9 @@ import { Jump } from 'src/app/core/models';
templateUrl: 'jump-view.dialog.html',
standalone: true,
imports: [
- DatePipe,
- MatButtonModule,
- MatDialogModule,
- MatDividerModule,
- MatIconModule
+ DatePipe, DecimalPipe,
+ MatButtonModule, MatDialogModule,
+ MatDividerModule, MatIconModule
]
})
export class JumpViewDialogComponent {
@@ -30,4 +28,10 @@ export class JumpViewDialogComponent {
// close the dialog without result
this.dialogRef.close();
}
+
+ formatDuration(duration: number): string {
+ const start = new Date(0);
+ start.setSeconds(duration);
+ return start.toISOString().substring(14, 19);
+ }
}
diff --git a/src/app/components/logbook/logbook.component.html b/src/app/components/logbook/logbook.component.html
index a2e2e41..801b42c 100644
--- a/src/app/components/logbook/logbook.component.html
+++ b/src/app/components/logbook/logbook.component.html
@@ -1,107 +1,105 @@
-
-
-
- {{title}}
-
- Dernier saut enregistré : {{ lastJump.numero }}ème à {{ lastJump.lieu }} le {{ lastJump.date | date: 'dd/MM/yyyy' }}
-
-
-
-
-
+
+
+ {{title}}
+
+ Dernier saut enregistré : {{ lastJump.numero }}ème à {{ lastJump.lieu }} le {{ lastJump.date | date: 'dd/MM/yyyy' }}
+
+
+
+
+
+
+
+
+
+
+
+
+ Ajouter un saut
-
-
-
-
-
-
- Ajouter un saut
+ @for (menuitem of menuItems.getMenuLogbook(); track menuitem) {
+ @if (menuitem.type === 'link') {
+
+
+ {{ menuitem.name }}
- @for (menuitem of menuItems.getMenuLogbook(); track menuitem) {
- @if (menuitem.type === 'link') {
-
-
- {{ menuitem.name }}
-
- }
}
-
-
+ }
+
-
- @if (jumpsToHundred() <= 20) {
-
-
-
-
- {{ lastJump.numero + jumpsToHundred() }}ème à venir dans {{ jumpsToHundred() }}
- {{ jumpsToHundred() > 1 ? 'sauts' : 'saut' }}
-
-
- }
-
-
-
-
- Filtrer les sauts
- @if (jumpsCount < lastJump.numero) {
-
- {{ jumpsCount }} {{ jumpsCount > 1 ? 'sauts' : 'saut' }} sur {{ lastJump.numero }} correspondent à la recherche
-
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ @if (jumpsToHundred() <= 20) {
+
+
+
+
+ {{ lastJump.numero + jumpsToHundred() }}ème à venir dans {{ jumpsToHundred() }}
+ {{ jumpsToHundred() > 1 ? 'sauts' : 'saut' }}
+
+
+ }
+
+
+
+
+ Filtrer les sauts
+ @if (jumpsCount < lastJump.numero) {
+
+ {{ jumpsCount }} {{ jumpsCount > 1 ? 'sauts' : 'saut' }} sur {{ lastJump.numero }} correspondent à la recherche
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/app/components/profile/profile.component.html b/src/app/components/profile/profile.component.html
index a580871..c10f68f 100644
--- a/src/app/components/profile/profile.component.html
+++ b/src/app/components/profile/profile.component.html
@@ -12,14 +12,20 @@
-
- {{title}}
-
+
+
+
+ {{title}}
+
+
+
+
+
-
+
Vector 3 - V306 Micron
diff --git a/src/app/components/profile/profile.component.scss b/src/app/components/profile/profile.component.scss
index b3806e8..cea222b 100644
--- a/src/app/components/profile/profile.component.scss
+++ b/src/app/components/profile/profile.component.scss
@@ -4,6 +4,7 @@
.banner {
background-color: var.$sidebar-footer;
padding: 1.6rem 0 1.3rem 0;
+ margin: -1.5rem -1.5rem 1.5rem -1.5rem;
.user-img {
width: var.$user-img-size;
height: var.$user-img-size;
diff --git a/src/app/components/qcm/qcm.component.html b/src/app/components/qcm/qcm.component.html
index 8c8b2fd..7b9904a 100644
--- a/src/app/components/qcm/qcm.component.html
+++ b/src/app/components/qcm/qcm.component.html
@@ -1,32 +1,43 @@
-
-
-
-
- {{ title }}
- {{ questionsCount }} {{ questionsCount > 1 ? 'questions' : 'question' }}
-
- {{ subtitle }}
-
-
-
-
-
-
-
- @for (menuitem of menuItems.getMenuPanel(); track menuitem) {
-
-
- {{ menuitem.name }}
-
- }
-
-
+
+
+
+ {{ title }}
+ {{ questionsCount }} {{ questionsCount > 1 ? 'questions' : 'question' }}
+
+ {{ subtitle }}
-
-
-
-
-
+
+
+@if (questions.controls.length) {
+
+
+
+
+
+ @for (category of qcm.categories; track category.num) {
+ @for (question of category.questions; track question.num) {
+ - {{ question.num }}
+ }
+ }
+
+
+
+
+
-
+}
diff --git a/src/app/components/qcm/qcm.component.scss b/src/app/components/qcm/qcm.component.scss
index e69de29..9b29b2e 100644
--- a/src/app/components/qcm/qcm.component.scss
+++ b/src/app/components/qcm/qcm.component.scss
@@ -0,0 +1,37 @@
+/* QCM */
+@use 'variable' as var;
+
+ol.squareItem {
+ padding: 0;
+ margin: 1rem 0;
+ li {
+ color: var.$primary;
+ background-color: var.$sidenav-content; //var.$dark;
+ background-image: none;
+ border: 1px solid var.$dark; //var.$extra-muted;
+ cursor: pointer;
+ float: left;
+ list-style-type: none;
+ margin: 0.17em;
+ padding: 0.34em 0;
+ text-align: center;
+ width: 33px;
+ height: 33px;
+ &.active {
+ border-color: var.$info;
+ }
+ &.valid {
+ color: var.$sidenav-content;
+ border-color: var.$success;
+ background-color: var.$primary;
+ }
+ &.defer {
+ border-color: var.$info-dark;
+ background-color: var.$navy-light;
+ }
+ &.error {
+ border-color: var.$purple-light;
+ background-color: var.$secondary;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/app/components/qcm/qcm.component.ts b/src/app/components/qcm/qcm.component.ts
index dfc6de2..b110f81 100644
--- a/src/app/components/qcm/qcm.component.ts
+++ b/src/app/components/qcm/qcm.component.ts
@@ -8,12 +8,15 @@ import { MatDividerModule } from '@angular/material/divider';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu';
+import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatRadioModule } from '@angular/material/radio';
-import { Observable, Subscription } from 'rxjs';
+import { MatSelectModule } from '@angular/material/select';
+import { interval, Observable, Subscription } from 'rxjs';
+import { take } from 'rxjs/operators';
import { MenuItems } from 'src/app/components/shared';
-import { ListErrorsComponent, } from 'src/app/components/shared';
-import { Errors, Qcm, User } from 'src/app/core/models';
+import { ListErrorsComponent } from 'src/app/components/shared';
+import { Errors, Qcm, QcmCategory, QcmQuestion, User } from 'src/app/core/models';
import { QcmService, UserService } from 'src/app/core/services';
import data from 'src/qcm-bpa.json';
@@ -23,7 +26,8 @@ import data from 'src/qcm-bpa.json';
imports: [
FormsModule, ReactiveFormsModule,
MatButtonModule, MatCardModule, MatDividerModule, MatExpansionModule,
- MatIconModule, MatMenuModule, MatRadioModule,
+ MatIconModule, MatMenuModule, MatProgressBarModule, MatRadioModule,
+ MatSelectModule,
ListErrorsComponent
],
templateUrl: './qcm.component.html',
@@ -32,6 +36,8 @@ import data from 'src/qcm-bpa.json';
export class QcmComponent implements OnInit, OnDestroy {
private _currentUser: Subscription = new Subscription();
private _data: Subscription = new Subscription();
+ private _timer: Subscription = new Subscription();
+ private _refresh = 1000;
public qcm: Qcm = {} as Qcm;
public currentUser: User = {} as User;
public canModify = false;
@@ -42,6 +48,11 @@ export class QcmComponent implements OnInit, OnDestroy {
public expandedIndex = 0;
public questionsCount = 0;
public qcmForm!: FormGroup;
+ public loading = true;
+ public totalAnswer = 0;
+ public timeProgress = 0;
+ public timeProgressColor = 'primary';
+ public timeMax = (60*45);
constructor(
private route: ActivatedRoute,
@@ -56,15 +67,16 @@ export class QcmComponent implements OnInit, OnDestroy {
}
get questions(): FormArray {
- return this.qcmForm.controls['questions'];
+ return this.qcmForm.controls['questions'] as FormArray;
}
ngOnInit() {
- //this.importQuestions();
- //this.importChoices();
+ //this._importQuestions();
+ //this._importChoices();
// Retreive the prefetched QCM
const data$: Observable<{ qcm: Qcm }> = this.route.data as Observable<{ qcm: Qcm }>;
this._data = data$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { qcm: Qcm }) => {
+ this.questionsCount = 0;
this.qcm = data.qcm;
if (this.qcm.name === 'bpa') {
this.title = 'QCM du BPA';
@@ -77,13 +89,7 @@ export class QcmComponent implements OnInit, OnDestroy {
this.qcm.categories.forEach(category => {
this.questionsCount += category.questions.length;
category.questions.forEach(question => {
- this.questions.push(
- this.fb.group({
- id: new FormControl({ value: question.num, disabled: false }),
- choice: ['']
- //choice: new FormControl({ value: '', disabled: false })
- })
- );
+ this.addQuestion(question);
});
});
});
@@ -93,6 +99,7 @@ export class QcmComponent implements OnInit, OnDestroy {
this.currentUser = userData;
this.canModify = userData.role === 'Admin';
});
+ this.loading = false;
}
ngOnDestroy() {
@@ -100,15 +107,61 @@ export class QcmComponent implements OnInit, OnDestroy {
this._currentUser.unsubscribe();
}
+ private _starTimer(): void {
+ this._timer = interval(1000)
+ .pipe(take(this.timeMax))
+ .subscribe(() => {
+ this.timeProgress++;
+ if (this.timeProgress > (this.timeMax/100*70) && this.timeProgress <= (this.timeMax/100*90)) {
+ this.timeProgressColor = 'warning';
+ } else if (this.timeProgress > (this.timeMax/100*90) && this.timeProgress <= (this.timeMax/100*98)) {
+ this.timeProgressColor = 'danger';
+ } else if (this.timeProgress > (this.timeMax/100*98)) {
+ this.timeProgressColor = 'purple';
+ }
+ if (this.timeProgress >= this.timeMax) {
+ this.timeProgressColor = 'accent';
+ this._timer.unsubscribe();
+ }
+ });
+ }
+
+ addQuestion(question: QcmQuestion) {
+ const item = this.fb.group({
+ id: [question.num],
+ choice: ['']
+ });
+ this.questions.push(item);
+ }
+
setExpandedIndex(index: number) {
this.expandedIndex = index;
}
- onChange() {
- //this.isDisabled = true;
+ onChange(category: QcmCategory, question: QcmQuestion, value: unknown) {
+ //console.log('onChange', category.num, question.num, value);
+ if (this.timeProgress === 0) {
+ this._starTimer();
+ }
+ this.qcm.categories[(category.num-1)].questions[(question.num-1)].choices.forEach(choice => {
+ if (choice.index === value) {
+ if (choice.correct) {
+ console.log(`Réponse à la question ${question.num} de la catégorie ${category.num} : correcte`);
+ } else {
+ console.log(`Réponse à la question ${question.num} de la catégorie ${category.num} : incorrecte`);
+ }
+ }
+ });
+ this.totalAnswer++;
+ this.questions.controls[(question.num-1)].disable();
+ //console.log(this.questions.controls[(question.num-1)].disabled);
}
- importChoices() {
+ onSubmit() {
+ console.log('onSubmit');
+ }
+
+ private _importChoices() {
try {
data.categories.forEach((category) => {
category.questions.forEach(question => {
@@ -132,7 +185,7 @@ export class QcmComponent implements OnInit, OnDestroy {
}
}
- importQuestions() {
+ private _importQuestions() {
try {
data.categories.forEach((category) => {
//Object.assign(this.jump, category);
@@ -154,4 +207,8 @@ export class QcmComponent implements OnInit, OnDestroy {
console.error(error);
}
}
+
+ private _resetErrors(): void {
+ this.errors = { errors: {} };
+ }
}
diff --git a/src/app/components/settings/credentials/credentials.component.html b/src/app/components/settings/credentials/credentials.component.html
index 85130a5..5b01ab0 100644
--- a/src/app/components/settings/credentials/credentials.component.html
+++ b/src/app/components/settings/credentials/credentials.component.html
@@ -12,7 +12,7 @@
-
+
{{title}}
diff --git a/src/app/components/settings/credentials/credentials.component.scss b/src/app/components/settings/credentials/credentials.component.scss
index a78305d..68affb2 100644
--- a/src/app/components/settings/credentials/credentials.component.scss
+++ b/src/app/components/settings/credentials/credentials.component.scss
@@ -4,6 +4,7 @@
.banner {
background-color: var.$sidebar-footer;
padding: 1.6rem 0 1.3rem 0;
+ margin: -1.5rem -1.5rem 1.5rem -1.5rem;
.user-img {
width: var.$user-img-size;
height: var.$user-img-size;
diff --git a/src/app/components/settings/settings.component.html b/src/app/components/settings/settings.component.html
index 0f193c5..015953a 100644
--- a/src/app/components/settings/settings.component.html
+++ b/src/app/components/settings/settings.component.html
@@ -12,7 +12,7 @@
-
+
{{title}}
diff --git a/src/app/components/settings/settings.component.scss b/src/app/components/settings/settings.component.scss
index 05665a2..d4b557d 100644
--- a/src/app/components/settings/settings.component.scss
+++ b/src/app/components/settings/settings.component.scss
@@ -4,6 +4,7 @@
.banner {
background-color: var.$sidebar-footer;
padding: 1.6rem 0 1.3rem 0;
+ margin: -1.5rem -1.5rem 1.5rem -1.5rem;
/*
background-color: mat.get-color-from-palette(var.$md-custom-warn, 700);
margin-bottom: 1rem;
diff --git a/src/app/components/shared/dashboard-components/jumps-by-month/jumps-by-month.component.ts b/src/app/components/shared/dashboard-components/jumps-by-month/jumps-by-month.component.ts
index 18da665..1210d7e 100755
--- a/src/app/components/shared/dashboard-components/jumps-by-month/jumps-by-month.component.ts
+++ b/src/app/components/shared/dashboard-components/jumps-by-month/jumps-by-month.component.ts
@@ -74,6 +74,7 @@ export class JumpsByMonthComponent implements OnInit, OnDestroy {
}
private _loadJumpByDate() {
+ const minoration = 2; // -2 pour ne pas compter la première année
this.seriesHeader = this._utilitiesService.getMonthsList();
const values: Array = this.seriesHeader.map(() => 0);
this.seriesColTotal = [...values];
@@ -111,7 +112,7 @@ export class JumpsByMonthComponent implements OnInit, OnDestroy {
this.seriesRowTotal.push(total);
});
this.seriesColTotalClosed.forEach((row: number) => {
- const value: number = (row/(this.seriesName.length-2)); // -2 pour ne pas compter la première année
+ const value: number = (row/(this.seriesName.length-minoration));
this.seriesRowAvg.push(parseInt(value.toFixed(0)));
});
this.seriesColTotalLastYears.forEach((row: number) => {
diff --git a/src/app/components/shared/helpers-jump/jump-table.component.html b/src/app/components/shared/helpers-jump/jump-table.component.html
index 4caf00d..3f6444c 100644
--- a/src/app/components/shared/helpers-jump/jump-table.component.html
+++ b/src/app/components/shared/helpers-jump/jump-table.component.html
@@ -12,7 +12,7 @@
Aucun saut à afficher pour le moment.
- Actualisation des sauts en cours
+ Chargement des sauts en cours
@@ -224,7 +224,7 @@
-->
-
+
+
+
+ Fichiers
+
+ @if (element.files) {
+ @for (file of element.files; track $index) {
+ @switch (file.type) {
+ @case ('video') {
+
+ {{ file.type }}
+
+ }
+ @case ('image') {
+
+ {{ file.type }}
+
+ }
+ @case ('kml') {
+
+ {{ file.type }}
+
+ }
+ @default {
+
+ {{ file.type }}
+
+ }
+ }
+ }
+ }
+ @if (!element.numero) {
+
+ }
+
@@ -247,13 +282,17 @@
more_vert
+
+
+ Détails
+
Modifier
-
- Supprimer
+
+ Supprimer
}
diff --git a/src/app/components/shared/helpers-jump/jump-table.component.ts b/src/app/components/shared/helpers-jump/jump-table.component.ts
index 9ef69c9..da4a1fa 100644
--- a/src/app/components/shared/helpers-jump/jump-table.component.ts
+++ b/src/app/components/shared/helpers-jump/jump-table.component.ts
@@ -21,7 +21,7 @@ import { take } from 'rxjs/operators';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { FrenchPaginator } from 'src/app/components/shared/french-paginator.component';
-import { ColumnDefinition, Errors, Jump, JumpList, JumpListConfig, jumpColumns } from 'src/app/core/models';
+import { ColumnDefinition, Errors, Jump, JumpByDay, JumpFile, JumpFileType, JumpList, JumpListConfig, jumpColumns } from 'src/app/core/models';
import { JumpsService, JumpTableService } from 'src/app/core/services';
import { JumpAddDialogComponent, JumpDeleteDialogComponent, JumpEditDialogComponent, JumpViewDialogComponent } from 'src/app/components/logbook/dialogs'
@@ -41,6 +41,7 @@ import { JumpAddDialogComponent, JumpDeleteDialogComponent, JumpEditDialogCompon
})
export class JumpTableComponent implements OnChanges, OnDestroy, AfterContentChecked {
private _jumps: Subscription = new Subscription();
+ private _subscriptions: Array = [];
//private _jump: Subscription = new Subscription();
private _query: JumpListConfig = { type: 'all', filters: {} };
//private _lastjump: Jump = {} as Jump;
@@ -53,13 +54,13 @@ export class JumpTableComponent implements OnChanges, OnDestroy, AfterContentChe
'numero', 'date', 'lieu', 'oaci', 'aeronef',
'imat', 'hauteur', 'voile', 'taille', 'categorie',
'module', 'participants', 'programme', 'accessoires',
- 'zone', 'video', 'actions'
+ 'zone', 'files', 'actions'
];*/
public displayedColumns: string[] = [
'numero', 'date', 'lieu', 'aeronef',
'hauteur', 'voile', 'categorie',
'participants', 'zone', 'accessoires',
- 'video', 'actions'
+ 'files', 'actions'
];
//public displayedColumns: string[] = jumpColumns.map((col) => col.key)
public columnsSchema: Array = jumpColumns;
@@ -115,7 +116,9 @@ export class JumpTableComponent implements OnChanges, OnDestroy, AfterContentChe
ngOnDestroy() {
this._jumps.unsubscribe();
- //this._jump.unsubscribe();
+ this._subscriptions.forEach(subscription => {
+ subscription.unsubscribe();
+ });
}
ngAfterContentChecked() {
@@ -155,6 +158,9 @@ export class JumpTableComponent implements OnChanges, OnDestroy, AfterContentChe
const jumps$: Observable = this._jumpsService.query(this._query);
this._jumps = jumps$.subscribe({
next: (data: JumpList) => {
+ //this.updateJumps(data.jumps);
+ //this.linkSkydiverIdJumps();
+ //this.getKmlJumpFiles(data.jumps);
this.loading = false;
this.jumps = new MatTableDataSource(data.jumps);
this.jumpsCount = data.jumpsCount;
@@ -170,12 +176,150 @@ export class JumpTableComponent implements OnChanges, OnDestroy, AfterContentChe
});
}
+ linkSkydiverIdJumps() {
+ const config: JumpListConfig = { type: 'all', filters: {} } as JumpListConfig;
+ config.filters.limit = 200;
+ config.filters.offset = 0;
+ config.filters.dateRangeStart = '2024-01-01 00:00:00';
+ //const year = new Date().getFullYear();
+ //config.filters.dateRangeEnd = `${year}-12-31 23:59:59`;
+ config.filters.dateRangeEnd = '2024-12-31 23:59:59';
+ //console.log(config.filters);
+ const subscription: Subscription = this._jumpsService.getAllByDay(config)
+ .pipe(take(1))
+ .subscribe({
+ next: (days) => {
+ this._resetErrors();
+ //console.log('getAllByDay : ', days);
+ days.forEach(day => {
+ this.loadSkydiverIdJumps(day, config);
+ });
+ },
+ error: (err) => {
+ this.errors = err;
+ }
+ });
+ this._subscriptions.push(subscription);
+ }
+
+ loadSkydiverIdJumps(day: JumpByDay, config: JumpListConfig) {
+ config.filters.dateRangeStart = `${day.jumps[0].date!.substring(0, 10)} 00:00:00`;
+ config.filters.dateRangeEnd = `${day.jumps[0].date!.substring(0, 10)} 23:59:59`;
+ const subscription: Subscription = this._jumpsService.getAllFromSkydiverIdApi(config)
+ .pipe(take(1))
+ .subscribe({
+ next: (data) => {
+ if (data.items.length) {
+ const diff = day.count - data.items.length;
+ if (diff < 0) {
+ console.error(`${diff} ${diff > 1 ? 'données' : 'donnée'} altimètre de trop le ${day.jumps[0].date!.substring(0, 10)}`);
+ } else {
+ if (diff > 0) {
+ console.error(`${diff}/${day.count} ${diff > 1 ? 'données altimètre manquantes' : 'donnée altimètre manquante'} le ${day.jumps[0].date!.substring(0, 10)}`, day.jumps, data.items);
+ }
+ console.log(`${day.count} ${day.count > 1 ? 'sauts' : 'saut'} le ${data.items[0].date!.substring(0, 10)}`, day.jumps.sort((a, b) => b.numero! - a.numero!), data.items);
+ data.items.map((jump, index) => {
+ const file: JumpFile = {
+ name: jump.name,
+ path: `/Volumes/Storage/Skydive/X2_Logs/${day.jumps[index].date!.substring(0, 4)}/`,
+ type: JumpFileType.CSV
+ } as JumpFile;
+ this._subscriptions.push(
+ this._jumpsService.saveX2Data(day.jumps[index].slug!, file, jump)
+ .pipe(take(1))
+ .subscribe({
+ next: (jump) => {
+ this._resetErrors();
+ console.log(`Le fichier ${file.name} a été ajouté au saut n°${jump.numero} !`, 'OK');
+ },
+ error: (err) => {
+ this.errors = err;
+ }
+ })
+ );
+ return jump;
+ });
+ }
+ //console.log(`${day.count} ${day.count > 1 ? 'sauts' : 'saut'} le ${day.jumps[0].date!.substring(0, 10)}`);
+ //console.log(`${data.items.length} ${data.items.length > 1 ? 'sauts' : 'saut'} le ${data.items[0].date!.substring(0, 10)}`, data);
+ } else {
+ console.info('Aucune données altimètre pour le ', day.jumps[0].date!.substring(0, 10));
+ }
+ },
+ error: (err) => {
+ console.error('getAllFromSkydiverIdApi error');
+ this.errors = err;
+ }
+ });
+ this._subscriptions.push(subscription);
+ }
+
+ updateJumps(jumps: Array) {
+ jumps.map(jump => {
+ jump.files = [];
+ if (jump.dossier !== "" && jump.video !== "") {
+ const file: JumpFile = {
+ name: jump.video!,
+ path: jump.dossier!,
+ type: JumpFileType.VIDEO
+ } as JumpFile;
+ this._subscriptions.push(
+ this._jumpsService.saveFile(jump.slug, file)
+ .pipe(take(1))
+ .subscribe({
+ next: (file) => {
+ this._resetErrors();
+ jump.files.push(file);
+ console.log(`Le fichier ${file.name} a été ajouté au saut n°${jump.numero} !`, 'OK');
+ },
+ error: (err) => {
+ this.errors = err;
+ }
+ })
+ );
+ }
+ return jump;
+ });
+ }
+
+ getKmlJumpFiles(jumps: Array) {
+ jumps.map(jump => {
+ if (jump.x2data !== null) {
+ //console.log(`Le fichier ${jump.x2data.name} existe pour le saut n°${jump.numero} !`, `https://skydiver.id/api/jump/${jump.x2data.id}/kml`);
+ const file: JumpFile = {
+ name: jump.x2data.name.substring(0, -4) + '.kml',
+ path: `/X2_Kmls/${jump.date.substring(0, 4)}/`,
+ type: JumpFileType.KML
+ } as JumpFile;
+ this._subscriptions.push(
+ this._jumpsService.saveKml(jump.slug, file)
+ .pipe(take(1))
+ .subscribe({
+ next: (file) => {
+ this._resetErrors();
+ console.log(`Le fichier ${file.path}${file.name} a été ajouté au saut n°${jump.numero} !`, 'OK');
+ },
+ error: (err) => {
+ this.errors = err;
+ }
+ })
+ );
+ /*
+ */
+ }
+ return jump;
+ });
+ }
+
deleteJump(slug: string) {
this.isDeleting = true;
- this._jumpsService.destroy(slug).pipe(take(1))
+ this._subscriptions.push(
+ this._jumpsService.destroy(slug)
+ .pipe(take(1))
.subscribe(() => {
this.router.navigateByUrl('/');
- });
+ })
+ );
}
openDeleteDialog(jump: Jump): void {
@@ -183,12 +327,15 @@ export class JumpTableComponent implements OnChanges, OnDestroy, AfterContentChe
width: '60vw',
data: jump
});
- dialogRef.afterClosed().pipe(take(1))
+ this._subscriptions.push(
+ dialogRef.afterClosed()
+ .pipe(take(1))
.subscribe(result => {
if (result != undefined) {
this._onDelete(result.slug);
}
- });
+ })
+ );
}
openEditDialog(jump: Jump): void {
@@ -196,12 +343,15 @@ export class JumpTableComponent implements OnChanges, OnDestroy, AfterContentChe
width: '70vw',
data: jump
});
- dialogRef.afterClosed().pipe(take(1))
- .subscribe(result => {
- if (result != undefined) {
- this._onEdit(result);
- }
- });
+ this._subscriptions.push(
+ dialogRef.afterClosed()
+ .pipe(take(1))
+ .subscribe(result => {
+ if (result != undefined) {
+ this._onEdit(result);
+ }
+ })
+ );
}
openViewDialog(jump: Jump): void {
@@ -230,20 +380,22 @@ export class JumpTableComponent implements OnChanges, OnDestroy, AfterContentChe
private _onDelete(slug: string): void {
try {
this.isDeleting = true;
- this._jumpsService.destroy(slug)
- .pipe(take(1))
- .subscribe({
- next: () => {
- this._resetErrors();
- this._openSnackBar(`Le saut a été supprimé !`, 'OK');
- this.runQuery();
- this.tableRefresh = !this.tableRefresh;
- this._jumpTableService.updateTableRefresh(this.tableRefresh);
- },
- error: (err) => {
- this.errors = err;
- }
- });
+ this._subscriptions.push(
+ this._jumpsService.destroy(slug)
+ .pipe(take(1))
+ .subscribe({
+ next: () => {
+ this._resetErrors();
+ this._openSnackBar(`Le saut a été supprimé !`, 'OK');
+ this.runQuery();
+ this.tableRefresh = !this.tableRefresh;
+ this._jumpTableService.updateTableRefresh(this.tableRefresh);
+ },
+ error: (err) => {
+ this.errors = err;
+ }
+ })
+ );
} catch (error) {
console.error(error);
}
@@ -252,21 +404,23 @@ export class JumpTableComponent implements OnChanges, OnDestroy, AfterContentChe
private _onEdit(jump: Jump): void {
try {
this.isSubmitting = true;
- this._jumpsService.update(jump)
- .pipe(take(1))
- .subscribe({
- next: (jump) => {
- this._resetErrors();
- this._openSnackBar(`Le saut n°${jump.numero} a été mis à jour !`, 'OK');
- this.runQuery();
- this.tableRefresh = !this.tableRefresh;
- this._jumpTableService.updateTableRefresh(this.tableRefresh);
- },
- error: (err) => {
- this.errors = err;
- this.isSubmitting = false;
- }
- });
+ this._subscriptions.push(
+ this._jumpsService.update(jump)
+ .pipe(take(1))
+ .subscribe({
+ next: (jump) => {
+ this._resetErrors();
+ this._openSnackBar(`Le saut n°${jump.numero} a été mis à jour !`, 'OK');
+ this.runQuery();
+ this.tableRefresh = !this.tableRefresh;
+ this._jumpTableService.updateTableRefresh(this.tableRefresh);
+ },
+ error: (err) => {
+ this.errors = err;
+ this.isSubmitting = false;
+ }
+ })
+ );
} catch (error) {
console.error(error);
}
diff --git a/src/app/components/shared/layout/full.component.html b/src/app/components/shared/layout/full.component.html
index c435754..4901035 100755
--- a/src/app/components/shared/layout/full.component.html
+++ b/src/app/components/shared/layout/full.component.html
@@ -1,6 +1,6 @@
-
-
- Fermer
+
+ Fermer
diff --git a/src/app/components/logbook/dialogs/jump-view.dialog.ts b/src/app/components/logbook/dialogs/jump-view.dialog.ts
index 1e41a9d..cc59ab8 100644
--- a/src/app/components/logbook/dialogs/jump-view.dialog.ts
+++ b/src/app/components/logbook/dialogs/jump-view.dialog.ts
@@ -1,5 +1,5 @@
import { Component, Inject } from '@angular/core';
-import { DatePipe } from '@angular/common';
+import { DatePipe, DecimalPipe } from '@angular/common';
import { MatButtonModule } from '@angular/material/button';
import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
import { MatDividerModule } from '@angular/material/divider';
@@ -12,11 +12,9 @@ import { Jump } from 'src/app/core/models';
templateUrl: 'jump-view.dialog.html',
standalone: true,
imports: [
- DatePipe,
- MatButtonModule,
- MatDialogModule,
- MatDividerModule,
- MatIconModule
+ DatePipe, DecimalPipe,
+ MatButtonModule, MatDialogModule,
+ MatDividerModule, MatIconModule
]
})
export class JumpViewDialogComponent {
@@ -30,4 +28,10 @@ export class JumpViewDialogComponent {
// close the dialog without result
this.dialogRef.close();
}
+
+ formatDuration(duration: number): string {
+ const start = new Date(0);
+ start.setSeconds(duration);
+ return start.toISOString().substring(14, 19);
+ }
}
diff --git a/src/app/components/logbook/logbook.component.html b/src/app/components/logbook/logbook.component.html
index a2e2e41..801b42c 100644
--- a/src/app/components/logbook/logbook.component.html
+++ b/src/app/components/logbook/logbook.component.html
@@ -1,107 +1,105 @@
-Le {{ jump.date | date: 'dd/MM/yyyy' }} à {{ jump.lieu }} :
-
-
-
-
- -
-
- Lieu: -
- {{jump.lieu}} -
- Oaci: -
- {{jump.oaci}} -
- Aeronef: -
- {{jump.aeronef}} -
- Imat: -
- {{jump.imat}} -
- Voile: -
- {{jump.voile}} -
- Taille: -
- {{jump.taille}} ft2 -
- Participants: -
- {{jump.participants}} -
- Sautants: -
-
- @for (sautant of jump.sautants; track sautant) {
-
-
- {{ sautant }} - - } - - - ju_solide - -
-
-
+ -
-
- Hauteur: -
- {{jump.hauteur}} m -
- Deploiement: -
- {{jump.deploiement}} m -
- Categorie: -
- {{jump.categorie}} -
- Module: -
- {{jump.module}} -
- Accessoires: -
- {{jump.accessoires}} -
- Zone: -
- {{jump.zone}} -
- Dossier media: -
- {{jump.dossier}} -
- Video: -
- {{jump.video}} -
- Programme: -
- {{jump.programme}} -
+
+ @if (jump.x2data) {
+
+
+
+
+
+
+
+ }
+ @else {
+
+ Aucune donnée GPS
+
+ }
-
+
+
+
+
+ Le {{ jump.date | date: 'dd/MM/yyyy' }} à {{ jump.lieu }} {{ jump.zone ? jump.zone : jump.oaci }} :
+
+ {{ jump.categorie }}
+ @if (jump.module) {
+ /
+ {{ jump.module }}
+ }
+
+
+
+
+
+ -
+
- Aeronef: +
- {{ jump.aeronef }} {{ jump.imat }} +
- Voile: +
- {{ jump.voile }} {{ jump.taille }} ft2 + @if (jump.programme) { +
- Programme: +
- {{ jump.programme }} + } +
+
+ -
+ @if (!jump.x2data) {
+
- Hauteur: +
- {{ jump.hauteur }} m +
- Déploiement: +
- {{ jump.deploiement }} m + } + @for (file of jump.files; track file) { +
- Fichier {{ file.type }} +
- {{ file.name }} + } +
+
+
+
+ Hauteur
+ {{ jump.x2data.altitude.exit }} m +
+
+ {{formatDuration(jump.x2data.duration.freeFall)}}
+
+ Durée de la chute
+ {{formatDuration(jump.x2data.duration.freeFall)}}
+
+
+ Déploiement
+ {{ jump.x2data.altitude.deployment }} m +
+
+
+
+
+ @for (sautant of jump.sautants; track sautant) {
+
+
+ {{ sautant }}
+
+ }
+
+
+ {{ jump.author.username }}
+
+
+ @if (jump.accessoires) {
+ Participants ({{ jump.sautants.length + 1 }})
+ @for (sautant of jump.sautants; track sautant) {
+
+
+
+
+
+ {{ jump.accessoires }}
+
+
+ }
+ Accessoires
+
+
+
+
+
+
+ Vitesse en chute
+
+
+ Max Verticale
+ {{ (jump.x2data.speed.freeFall.vertical.max / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+ Max Horizontale
+ {{ (jump.x2data.speed.freeFall.horizontal.max / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+ Moyenne Verticale
+ {{ (jump.x2data.speed.freeFall.vertical.avg / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+ Moyenne Horizontale
+ {{ (jump.x2data.speed.freeFall.horizontal.avg / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+
+
+
+ Vitesse sous voile
+
+
+ Max Verticale
+ {{ (jump.x2data.speed.underCanopy.vertical.max / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+ Max Horizontale
+ {{ (jump.x2data.speed.underCanopy.horizontal.max / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+ Moyenne Verticale
+ {{ (jump.x2data.speed.underCanopy.vertical.avg / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+ Moyenne Horizontale
+ {{ (jump.x2data.speed.underCanopy.horizontal.avg / 1000 * 60 * 60) | number : '1.0-0' }} km/h +
+
+
+
+
+ Finesse
+
+
+ Finesse en chute
+
+
+ Finesse sous voile
+
+
+
+
+ Finesse Max
+ {{ jump.x2data.glideRatio.freeFall.max | number : '1.2-2' }} +
+
+ Finesse Moyenne
+ {{ jump.x2data.glideRatio.freeFall.avg | number : '1.2-2' }} +
+
+ Finesse Max
+ {{ jump.x2data.glideRatio.underCanopy.max | number : '1.2-2' }} +
+
+ Finesse Moyenne
+ {{ jump.x2data.glideRatio.underCanopy.avg | number : '1.2-2' }} +
+
+
+
+
+ Distance
+
+
+ Distance au largage
+ {{ jump.x2data.distance.exitFromLandingZone| number : '1.0-0' }} m +
+
+ {{formatDuration(jump.x2data.duration.underCanopy)}}
+
+ Durée sous voile
+ {{formatDuration(jump.x2data.duration.underCanopy)}}
+
+
+ Distance totale
+ {{ jump.x2data.distance.totalFlying | number : '1.0-0' }} m +
+
+ Distance horizontale
+ {{ jump.x2data.distance.totalHorizontal | number : '1.0-0' }} m +
+
+
+
+ @for (sautant of jump.sautants; track sautant) {
+
+
+ {{ sautant }}
+
+ }
+
+
+ {{ jump.author.username }}
+
+
+ Participants ({{ jump.sautants.length + 1 }})
+ @for (sautant of jump.sautants; track sautant) {
+
+
-
-
-
+ @if (jumpsToHundred() <= 20) {
+
+
+
+
+ Filtrer les sauts
+ @if (jumpsCount < lastJump.numero) {
+
+ {{ jumpsCount }} {{ jumpsCount > 1 ? 'sauts' : 'saut' }} sur {{ lastJump.numero }} correspondent à la recherche
+
+ }
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/app/components/profile/profile.component.html b/src/app/components/profile/profile.component.html
index a580871..c10f68f 100644
--- a/src/app/components/profile/profile.component.html
+++ b/src/app/components/profile/profile.component.html
@@ -12,14 +12,20 @@
-
-
- {{title}}
- - Dernier saut enregistré : {{ lastJump.numero }}ème à {{ lastJump.lieu }} le {{ lastJump.date | date: 'dd/MM/yyyy' }} - -
-
+
- @if (jumpsToHundred() <= 20) {
-
-
-
-
- Filtrer les sauts
- @if (jumpsCount < lastJump.numero) {
-
- {{ jumpsCount }} {{ jumpsCount > 1 ? 'sauts' : 'saut' }} sur {{ lastJump.numero }} correspondent à la recherche
-
- }
-
-
-
-
-
-
-
-
+
+
-
+
+
+ {{title}}
+ + Dernier saut enregistré : {{ lastJump.numero }}ème à {{ lastJump.lieu }} le {{ lastJump.date | date: 'dd/MM/yyyy' }} + +
+
+
+
+
+
+
+
+
+ Ajouter un saut
-
-
-
-
-
-
- Ajouter un saut
+ @for (menuitem of menuItems.getMenuLogbook(); track menuitem) {
+ @if (menuitem.type === 'link') {
+
+
+ {{ menuitem.name }}
- @for (menuitem of menuItems.getMenuLogbook(); track menuitem) {
- @if (menuitem.type === 'link') {
-
-
- {{ menuitem.name }}
-
- }
}
-
-
+ }
+
-
-
-
- }
-
- {{ lastJump.numero + jumpsToHundred() }}ème à venir dans {{ jumpsToHundred() }}
- {{ jumpsToHundred() > 1 ? 'sauts' : 'saut' }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+ }
+
+ {{ lastJump.numero + jumpsToHundred() }}ème à venir dans {{ jumpsToHundred() }}
+ {{ jumpsToHundred() > 1 ? 'sauts' : 'saut' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-{{title}}
-
+
-
+
+
+
+
+
+ {{title}}
+
-
+
diff --git a/src/app/components/profile/profile.component.scss b/src/app/components/profile/profile.component.scss
index b3806e8..cea222b 100644
--- a/src/app/components/profile/profile.component.scss
+++ b/src/app/components/profile/profile.component.scss
@@ -4,6 +4,7 @@
.banner {
background-color: var.$sidebar-footer;
padding: 1.6rem 0 1.3rem 0;
+ margin: -1.5rem -1.5rem 1.5rem -1.5rem;
.user-img {
width: var.$user-img-size;
height: var.$user-img-size;
diff --git a/src/app/components/qcm/qcm.component.html b/src/app/components/qcm/qcm.component.html
index 8c8b2fd..7b9904a 100644
--- a/src/app/components/qcm/qcm.component.html
+++ b/src/app/components/qcm/qcm.component.html
@@ -1,32 +1,43 @@
-
+
Vector 3 - V306 Micron
- this.qcmForm.controls['questions'];
+ return this.qcmForm.controls['questions'] as FormArray;
}
ngOnInit() {
- //this.importQuestions();
- //this.importChoices();
+ //this._importQuestions();
+ //this._importChoices();
// Retreive the prefetched QCM
const data$: Observable<{ qcm: Qcm }> = this.route.data as Observable<{ qcm: Qcm }>;
this._data = data$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { qcm: Qcm }) => {
+ this.questionsCount = 0;
this.qcm = data.qcm;
if (this.qcm.name === 'bpa') {
this.title = 'QCM du BPA';
@@ -77,13 +89,7 @@ export class QcmComponent implements OnInit, OnDestroy {
this.qcm.categories.forEach(category => {
this.questionsCount += category.questions.length;
category.questions.forEach(question => {
- this.questions.push(
- this.fb.group({
- id: new FormControl({ value: question.num, disabled: false }),
- choice: ['']
- //choice: new FormControl({ value: '', disabled: false })
- })
- );
+ this.addQuestion(question);
});
});
});
@@ -93,6 +99,7 @@ export class QcmComponent implements OnInit, OnDestroy {
this.currentUser = userData;
this.canModify = userData.role === 'Admin';
});
+ this.loading = false;
}
ngOnDestroy() {
@@ -100,15 +107,61 @@ export class QcmComponent implements OnInit, OnDestroy {
this._currentUser.unsubscribe();
}
+ private _starTimer(): void {
+ this._timer = interval(1000)
+ .pipe(take(this.timeMax))
+ .subscribe(() => {
+ this.timeProgress++;
+ if (this.timeProgress > (this.timeMax/100*70) && this.timeProgress <= (this.timeMax/100*90)) {
+ this.timeProgressColor = 'warning';
+ } else if (this.timeProgress > (this.timeMax/100*90) && this.timeProgress <= (this.timeMax/100*98)) {
+ this.timeProgressColor = 'danger';
+ } else if (this.timeProgress > (this.timeMax/100*98)) {
+ this.timeProgressColor = 'purple';
+ }
+ if (this.timeProgress >= this.timeMax) {
+ this.timeProgressColor = 'accent';
+ this._timer.unsubscribe();
+ }
+ });
+ }
+
+ addQuestion(question: QcmQuestion) {
+ const item = this.fb.group({
+ id: [question.num],
+ choice: ['']
+ });
+ this.questions.push(item);
+ }
+
setExpandedIndex(index: number) {
this.expandedIndex = index;
}
- onChange() {
- //this.isDisabled = true;
+ onChange(category: QcmCategory, question: QcmQuestion, value: unknown) {
+ //console.log('onChange', category.num, question.num, value);
+ if (this.timeProgress === 0) {
+ this._starTimer();
+ }
+ this.qcm.categories[(category.num-1)].questions[(question.num-1)].choices.forEach(choice => {
+ if (choice.index === value) {
+ if (choice.correct) {
+ console.log(`Réponse à la question ${question.num} de la catégorie ${category.num} : correcte`);
+ } else {
+ console.log(`Réponse à la question ${question.num} de la catégorie ${category.num} : incorrecte`);
+ }
+ }
+ });
+ this.totalAnswer++;
+ this.questions.controls[(question.num-1)].disable();
+ //console.log(this.questions.controls[(question.num-1)].disabled);
}
- importChoices() {
+ onSubmit() {
+ console.log('onSubmit');
+ }
+
+ private _importChoices() {
try {
data.categories.forEach((category) => {
category.questions.forEach(question => {
@@ -132,7 +185,7 @@ export class QcmComponent implements OnInit, OnDestroy {
}
}
- importQuestions() {
+ private _importQuestions() {
try {
data.categories.forEach((category) => {
//Object.assign(this.jump, category);
@@ -154,4 +207,8 @@ export class QcmComponent implements OnInit, OnDestroy {
console.error(error);
}
}
+
+ private _resetErrors(): void {
+ this.errors = { errors: {} };
+ }
}
diff --git a/src/app/components/settings/credentials/credentials.component.html b/src/app/components/settings/credentials/credentials.component.html
index 85130a5..5b01ab0 100644
--- a/src/app/components/settings/credentials/credentials.component.html
+++ b/src/app/components/settings/credentials/credentials.component.html
@@ -12,7 +12,7 @@
-
+
+@if (questions.controls.length) {
+
+
+
+
-
+}
diff --git a/src/app/components/qcm/qcm.component.scss b/src/app/components/qcm/qcm.component.scss
index e69de29..9b29b2e 100644
--- a/src/app/components/qcm/qcm.component.scss
+++ b/src/app/components/qcm/qcm.component.scss
@@ -0,0 +1,37 @@
+/* QCM */
+@use 'variable' as var;
+
+ol.squareItem {
+ padding: 0;
+ margin: 1rem 0;
+ li {
+ color: var.$primary;
+ background-color: var.$sidenav-content; //var.$dark;
+ background-image: none;
+ border: 1px solid var.$dark; //var.$extra-muted;
+ cursor: pointer;
+ float: left;
+ list-style-type: none;
+ margin: 0.17em;
+ padding: 0.34em 0;
+ text-align: center;
+ width: 33px;
+ height: 33px;
+ &.active {
+ border-color: var.$info;
+ }
+ &.valid {
+ color: var.$sidenav-content;
+ border-color: var.$success;
+ background-color: var.$primary;
+ }
+ &.defer {
+ border-color: var.$info-dark;
+ background-color: var.$navy-light;
+ }
+ &.error {
+ border-color: var.$purple-light;
+ background-color: var.$secondary;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/app/components/qcm/qcm.component.ts b/src/app/components/qcm/qcm.component.ts
index dfc6de2..b110f81 100644
--- a/src/app/components/qcm/qcm.component.ts
+++ b/src/app/components/qcm/qcm.component.ts
@@ -8,12 +8,15 @@ import { MatDividerModule } from '@angular/material/divider';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu';
+import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatRadioModule } from '@angular/material/radio';
-import { Observable, Subscription } from 'rxjs';
+import { MatSelectModule } from '@angular/material/select';
+import { interval, Observable, Subscription } from 'rxjs';
+import { take } from 'rxjs/operators';
import { MenuItems } from 'src/app/components/shared';
-import { ListErrorsComponent, } from 'src/app/components/shared';
-import { Errors, Qcm, User } from 'src/app/core/models';
+import { ListErrorsComponent } from 'src/app/components/shared';
+import { Errors, Qcm, QcmCategory, QcmQuestion, User } from 'src/app/core/models';
import { QcmService, UserService } from 'src/app/core/services';
import data from 'src/qcm-bpa.json';
@@ -23,7 +26,8 @@ import data from 'src/qcm-bpa.json';
imports: [
FormsModule, ReactiveFormsModule,
MatButtonModule, MatCardModule, MatDividerModule, MatExpansionModule,
- MatIconModule, MatMenuModule, MatRadioModule,
+ MatIconModule, MatMenuModule, MatProgressBarModule, MatRadioModule,
+ MatSelectModule,
ListErrorsComponent
],
templateUrl: './qcm.component.html',
@@ -32,6 +36,8 @@ import data from 'src/qcm-bpa.json';
export class QcmComponent implements OnInit, OnDestroy {
private _currentUser: Subscription = new Subscription();
private _data: Subscription = new Subscription();
+ private _timer: Subscription = new Subscription();
+ private _refresh = 1000;
public qcm: Qcm = {} as Qcm;
public currentUser: User = {} as User;
public canModify = false;
@@ -42,6 +48,11 @@ export class QcmComponent implements OnInit, OnDestroy {
public expandedIndex = 0;
public questionsCount = 0;
public qcmForm!: FormGroup;
+ public loading = true;
+ public totalAnswer = 0;
+ public timeProgress = 0;
+ public timeProgressColor = 'primary';
+ public timeMax = (60*45);
constructor(
private route: ActivatedRoute,
@@ -56,15 +67,16 @@ export class QcmComponent implements OnInit, OnDestroy {
}
get questions(): FormArray {
- return
-
-
- - {{ title }} - {{ questionsCount }} {{ questionsCount > 1 ? 'questions' : 'question' }} -
- {{ subtitle }} -
-
-
-
-
- @for (menuitem of menuItems.getMenuPanel(); track menuitem) {
-
-
- {{ menuitem.name }}
-
- }
-
-
+
+
-
-
-
-
+
+
- + {{ title }} + {{ questionsCount }} {{ questionsCount > 1 ? 'questions' : 'question' }} +
+ {{ subtitle }}
+
+
+
+ -
+ @for (category of qcm.categories; track category.num) {
+ @for (question of category.questions; track question.num) {
+
- {{ question.num }} + } + } +
+
diff --git a/src/app/components/settings/credentials/credentials.component.scss b/src/app/components/settings/credentials/credentials.component.scss
index a78305d..68affb2 100644
--- a/src/app/components/settings/credentials/credentials.component.scss
+++ b/src/app/components/settings/credentials/credentials.component.scss
@@ -4,6 +4,7 @@
.banner {
background-color: var.$sidebar-footer;
padding: 1.6rem 0 1.3rem 0;
+ margin: -1.5rem -1.5rem 1.5rem -1.5rem;
.user-img {
width: var.$user-img-size;
height: var.$user-img-size;
diff --git a/src/app/components/settings/settings.component.html b/src/app/components/settings/settings.component.html
index 0f193c5..015953a 100644
--- a/src/app/components/settings/settings.component.html
+++ b/src/app/components/settings/settings.component.html
@@ -12,7 +12,7 @@
{{title}}
+
diff --git a/src/app/components/settings/settings.component.scss b/src/app/components/settings/settings.component.scss
index 05665a2..d4b557d 100644
--- a/src/app/components/settings/settings.component.scss
+++ b/src/app/components/settings/settings.component.scss
@@ -4,6 +4,7 @@
.banner {
background-color: var.$sidebar-footer;
padding: 1.6rem 0 1.3rem 0;
+ margin: -1.5rem -1.5rem 1.5rem -1.5rem;
/*
background-color: mat.get-color-from-palette(var.$md-custom-warn, 700);
margin-bottom: 1rem;
diff --git a/src/app/components/shared/dashboard-components/jumps-by-month/jumps-by-month.component.ts b/src/app/components/shared/dashboard-components/jumps-by-month/jumps-by-month.component.ts
index 18da665..1210d7e 100755
--- a/src/app/components/shared/dashboard-components/jumps-by-month/jumps-by-month.component.ts
+++ b/src/app/components/shared/dashboard-components/jumps-by-month/jumps-by-month.component.ts
@@ -74,6 +74,7 @@ export class JumpsByMonthComponent implements OnInit, OnDestroy {
}
private _loadJumpByDate() {
+ const minoration = 2; // -2 pour ne pas compter la première année
this.seriesHeader = this._utilitiesService.getMonthsList();
const values: Array = this.seriesHeader.map(() => 0);
this.seriesColTotal = [...values];
@@ -111,7 +112,7 @@ export class JumpsByMonthComponent implements OnInit, OnDestroy {
this.seriesRowTotal.push(total);
});
this.seriesColTotalClosed.forEach((row: number) => {
- const value: number = (row/(this.seriesName.length-2)); // -2 pour ne pas compter la première année
+ const value: number = (row/(this.seriesName.length-minoration));
this.seriesRowAvg.push(parseInt(value.toFixed(0)));
});
this.seriesColTotalLastYears.forEach((row: number) => {
diff --git a/src/app/components/shared/helpers-jump/jump-table.component.html b/src/app/components/shared/helpers-jump/jump-table.component.html
index 4caf00d..3f6444c 100644
--- a/src/app/components/shared/helpers-jump/jump-table.component.html
+++ b/src/app/components/shared/helpers-jump/jump-table.component.html
@@ -12,7 +12,7 @@
Aucun saut à afficher pour le moment.
- Actualisation des sauts en cours
+ Chargement des sauts en cours
{{title}}
@@ -224,7 +224,7 @@
-->
-
+
+
+
+ Fichiers
+
+ @if (element.files) {
+ @for (file of element.files; track $index) {
+ @switch (file.type) {
+ @case ('video') {
+
+ {{ file.type }}
+
+ }
+ @case ('image') {
+
+ {{ file.type }}
+
+ }
+ @case ('kml') {
+
+ {{ file.type }}
+
+ }
+ @default {
+
+ {{ file.type }}
+
+ }
+ }
+ }
+ }
+ @if (!element.numero) {
+
+ }
+
@@ -247,13 +282,17 @@
more_vert
+
+
+ Détails
+
Modifier
-
- Supprimer
+
+ Supprimer
}
diff --git a/src/app/components/shared/helpers-jump/jump-table.component.ts b/src/app/components/shared/helpers-jump/jump-table.component.ts
index 9ef69c9..da4a1fa 100644
--- a/src/app/components/shared/helpers-jump/jump-table.component.ts
+++ b/src/app/components/shared/helpers-jump/jump-table.component.ts
@@ -21,7 +21,7 @@ import { take } from 'rxjs/operators';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { FrenchPaginator } from 'src/app/components/shared/french-paginator.component';
-import { ColumnDefinition, Errors, Jump, JumpList, JumpListConfig, jumpColumns } from 'src/app/core/models';
+import { ColumnDefinition, Errors, Jump, JumpByDay, JumpFile, JumpFileType, JumpList, JumpListConfig, jumpColumns } from 'src/app/core/models';
import { JumpsService, JumpTableService } from 'src/app/core/services';
import { JumpAddDialogComponent, JumpDeleteDialogComponent, JumpEditDialogComponent, JumpViewDialogComponent } from 'src/app/components/logbook/dialogs'
@@ -41,6 +41,7 @@ import { JumpAddDialogComponent, JumpDeleteDialogComponent, JumpEditDialogCompon
})
export class JumpTableComponent implements OnChanges, OnDestroy, AfterContentChecked {
private _jumps: Subscription = new Subscription();
+ private _subscriptions: Array = [];
//private _jump: Subscription = new Subscription();
private _query: JumpListConfig = { type: 'all', filters: {} };
//private _lastjump: Jump = {} as Jump;
@@ -53,13 +54,13 @@ export class JumpTableComponent implements OnChanges, OnDestroy, AfterContentChe
'numero', 'date', 'lieu', 'oaci', 'aeronef',
'imat', 'hauteur', 'voile', 'taille', 'categorie',
'module', 'participants', 'programme', 'accessoires',
- 'zone', 'video', 'actions'
+ 'zone', 'files', 'actions'
];*/
public displayedColumns: string[] = [
'numero', 'date', 'lieu', 'aeronef',
'hauteur', 'voile', 'categorie',
'participants', 'zone', 'accessoires',
- 'video', 'actions'
+ 'files', 'actions'
];
//public displayedColumns: string[] = jumpColumns.map((col) => col.key)
public columnsSchema: Array = jumpColumns;
@@ -115,7 +116,9 @@ export class JumpTableComponent implements OnChanges, OnDestroy, AfterContentChe
ngOnDestroy() {
this._jumps.unsubscribe();
- //this._jump.unsubscribe();
+ this._subscriptions.forEach(subscription => {
+ subscription.unsubscribe();
+ });
}
ngAfterContentChecked() {
@@ -155,6 +158,9 @@ export class JumpTableComponent implements OnChanges, OnDestroy, AfterContentChe
const jumps$: Observable = this._jumpsService.query(this._query);
this._jumps = jumps$.subscribe({
next: (data: JumpList) => {
+ //this.updateJumps(data.jumps);
+ //this.linkSkydiverIdJumps();
+ //this.getKmlJumpFiles(data.jumps);
this.loading = false;
this.jumps = new MatTableDataSource(data.jumps);
this.jumpsCount = data.jumpsCount;
@@ -170,12 +176,150 @@ export class JumpTableComponent implements OnChanges, OnDestroy, AfterContentChe
});
}
+ linkSkydiverIdJumps() {
+ const config: JumpListConfig = { type: 'all', filters: {} } as JumpListConfig;
+ config.filters.limit = 200;
+ config.filters.offset = 0;
+ config.filters.dateRangeStart = '2024-01-01 00:00:00';
+ //const year = new Date().getFullYear();
+ //config.filters.dateRangeEnd = `${year}-12-31 23:59:59`;
+ config.filters.dateRangeEnd = '2024-12-31 23:59:59';
+ //console.log(config.filters);
+ const subscription: Subscription = this._jumpsService.getAllByDay(config)
+ .pipe(take(1))
+ .subscribe({
+ next: (days) => {
+ this._resetErrors();
+ //console.log('getAllByDay : ', days);
+ days.forEach(day => {
+ this.loadSkydiverIdJumps(day, config);
+ });
+ },
+ error: (err) => {
+ this.errors = err;
+ }
+ });
+ this._subscriptions.push(subscription);
+ }
+
+ loadSkydiverIdJumps(day: JumpByDay, config: JumpListConfig) {
+ config.filters.dateRangeStart = `${day.jumps[0].date!.substring(0, 10)} 00:00:00`;
+ config.filters.dateRangeEnd = `${day.jumps[0].date!.substring(0, 10)} 23:59:59`;
+ const subscription: Subscription = this._jumpsService.getAllFromSkydiverIdApi(config)
+ .pipe(take(1))
+ .subscribe({
+ next: (data) => {
+ if (data.items.length) {
+ const diff = day.count - data.items.length;
+ if (diff < 0) {
+ console.error(`${diff} ${diff > 1 ? 'données' : 'donnée'} altimètre de trop le ${day.jumps[0].date!.substring(0, 10)}`);
+ } else {
+ if (diff > 0) {
+ console.error(`${diff}/${day.count} ${diff > 1 ? 'données altimètre manquantes' : 'donnée altimètre manquante'} le ${day.jumps[0].date!.substring(0, 10)}`, day.jumps, data.items);
+ }
+ console.log(`${day.count} ${day.count > 1 ? 'sauts' : 'saut'} le ${data.items[0].date!.substring(0, 10)}`, day.jumps.sort((a, b) => b.numero! - a.numero!), data.items);
+ data.items.map((jump, index) => {
+ const file: JumpFile = {
+ name: jump.name,
+ path: `/Volumes/Storage/Skydive/X2_Logs/${day.jumps[index].date!.substring(0, 4)}/`,
+ type: JumpFileType.CSV
+ } as JumpFile;
+ this._subscriptions.push(
+ this._jumpsService.saveX2Data(day.jumps[index].slug!, file, jump)
+ .pipe(take(1))
+ .subscribe({
+ next: (jump) => {
+ this._resetErrors();
+ console.log(`Le fichier ${file.name} a été ajouté au saut n°${jump.numero} !`, 'OK');
+ },
+ error: (err) => {
+ this.errors = err;
+ }
+ })
+ );
+ return jump;
+ });
+ }
+ //console.log(`${day.count} ${day.count > 1 ? 'sauts' : 'saut'} le ${day.jumps[0].date!.substring(0, 10)}`);
+ //console.log(`${data.items.length} ${data.items.length > 1 ? 'sauts' : 'saut'} le ${data.items[0].date!.substring(0, 10)}`, data);
+ } else {
+ console.info('Aucune données altimètre pour le ', day.jumps[0].date!.substring(0, 10));
+ }
+ },
+ error: (err) => {
+ console.error('getAllFromSkydiverIdApi error');
+ this.errors = err;
+ }
+ });
+ this._subscriptions.push(subscription);
+ }
+
+ updateJumps(jumps: Array) {
+ jumps.map(jump => {
+ jump.files = [];
+ if (jump.dossier !== "" && jump.video !== "") {
+ const file: JumpFile = {
+ name: jump.video!,
+ path: jump.dossier!,
+ type: JumpFileType.VIDEO
+ } as JumpFile;
+ this._subscriptions.push(
+ this._jumpsService.saveFile(jump.slug, file)
+ .pipe(take(1))
+ .subscribe({
+ next: (file) => {
+ this._resetErrors();
+ jump.files.push(file);
+ console.log(`Le fichier ${file.name} a été ajouté au saut n°${jump.numero} !`, 'OK');
+ },
+ error: (err) => {
+ this.errors = err;
+ }
+ })
+ );
+ }
+ return jump;
+ });
+ }
+
+ getKmlJumpFiles(jumps: Array) {
+ jumps.map(jump => {
+ if (jump.x2data !== null) {
+ //console.log(`Le fichier ${jump.x2data.name} existe pour le saut n°${jump.numero} !`, `https://skydiver.id/api/jump/${jump.x2data.id}/kml`);
+ const file: JumpFile = {
+ name: jump.x2data.name.substring(0, -4) + '.kml',
+ path: `/X2_Kmls/${jump.date.substring(0, 4)}/`,
+ type: JumpFileType.KML
+ } as JumpFile;
+ this._subscriptions.push(
+ this._jumpsService.saveKml(jump.slug, file)
+ .pipe(take(1))
+ .subscribe({
+ next: (file) => {
+ this._resetErrors();
+ console.log(`Le fichier ${file.path}${file.name} a été ajouté au saut n°${jump.numero} !`, 'OK');
+ },
+ error: (err) => {
+ this.errors = err;
+ }
+ })
+ );
+ /*
+ */
+ }
+ return jump;
+ });
+ }
+
deleteJump(slug: string) {
this.isDeleting = true;
- this._jumpsService.destroy(slug).pipe(take(1))
+ this._subscriptions.push(
+ this._jumpsService.destroy(slug)
+ .pipe(take(1))
.subscribe(() => {
this.router.navigateByUrl('/');
- });
+ })
+ );
}
openDeleteDialog(jump: Jump): void {
@@ -183,12 +327,15 @@ export class JumpTableComponent implements OnChanges, OnDestroy, AfterContentChe
width: '60vw',
data: jump
});
- dialogRef.afterClosed().pipe(take(1))
+ this._subscriptions.push(
+ dialogRef.afterClosed()
+ .pipe(take(1))
.subscribe(result => {
if (result != undefined) {
this._onDelete(result.slug);
}
- });
+ })
+ );
}
openEditDialog(jump: Jump): void {
@@ -196,12 +343,15 @@ export class JumpTableComponent implements OnChanges, OnDestroy, AfterContentChe
width: '70vw',
data: jump
});
- dialogRef.afterClosed().pipe(take(1))
- .subscribe(result => {
- if (result != undefined) {
- this._onEdit(result);
- }
- });
+ this._subscriptions.push(
+ dialogRef.afterClosed()
+ .pipe(take(1))
+ .subscribe(result => {
+ if (result != undefined) {
+ this._onEdit(result);
+ }
+ })
+ );
}
openViewDialog(jump: Jump): void {
@@ -230,20 +380,22 @@ export class JumpTableComponent implements OnChanges, OnDestroy, AfterContentChe
private _onDelete(slug: string): void {
try {
this.isDeleting = true;
- this._jumpsService.destroy(slug)
- .pipe(take(1))
- .subscribe({
- next: () => {
- this._resetErrors();
- this._openSnackBar(`Le saut a été supprimé !`, 'OK');
- this.runQuery();
- this.tableRefresh = !this.tableRefresh;
- this._jumpTableService.updateTableRefresh(this.tableRefresh);
- },
- error: (err) => {
- this.errors = err;
- }
- });
+ this._subscriptions.push(
+ this._jumpsService.destroy(slug)
+ .pipe(take(1))
+ .subscribe({
+ next: () => {
+ this._resetErrors();
+ this._openSnackBar(`Le saut a été supprimé !`, 'OK');
+ this.runQuery();
+ this.tableRefresh = !this.tableRefresh;
+ this._jumpTableService.updateTableRefresh(this.tableRefresh);
+ },
+ error: (err) => {
+ this.errors = err;
+ }
+ })
+ );
} catch (error) {
console.error(error);
}
@@ -252,21 +404,23 @@ export class JumpTableComponent implements OnChanges, OnDestroy, AfterContentChe
private _onEdit(jump: Jump): void {
try {
this.isSubmitting = true;
- this._jumpsService.update(jump)
- .pipe(take(1))
- .subscribe({
- next: (jump) => {
- this._resetErrors();
- this._openSnackBar(`Le saut n°${jump.numero} a été mis à jour !`, 'OK');
- this.runQuery();
- this.tableRefresh = !this.tableRefresh;
- this._jumpTableService.updateTableRefresh(this.tableRefresh);
- },
- error: (err) => {
- this.errors = err;
- this.isSubmitting = false;
- }
- });
+ this._subscriptions.push(
+ this._jumpsService.update(jump)
+ .pipe(take(1))
+ .subscribe({
+ next: (jump) => {
+ this._resetErrors();
+ this._openSnackBar(`Le saut n°${jump.numero} a été mis à jour !`, 'OK');
+ this.runQuery();
+ this.tableRefresh = !this.tableRefresh;
+ this._jumpTableService.updateTableRefresh(this.tableRefresh);
+ },
+ error: (err) => {
+ this.errors = err;
+ this.isSubmitting = false;
+ }
+ })
+ );
} catch (error) {
console.error(error);
}
diff --git a/src/app/components/shared/layout/full.component.html b/src/app/components/shared/layout/full.component.html
index c435754..4901035 100755
--- a/src/app/components/shared/layout/full.component.html
+++ b/src/app/components/shared/layout/full.component.html
@@ -1,6 +1,6 @@