Mise à jours du dashboard

This commit is contained in:
Julien Gautier
2023-09-14 18:28:02 +02:00
parent 0e6b3ef1c7
commit 92b204c769
41 changed files with 981 additions and 852 deletions
+1
View File
@@ -34,6 +34,7 @@
"src/manifest.webmanifest" "src/manifest.webmanifest"
], ],
"styles": [ "styles": [
"node_modules/chartist/dist/index.scss",
"src/styles/styles.scss" "src/styles/styles.scss"
], ],
"scripts": [], "scripts": [],
+3
View File
@@ -3,6 +3,9 @@
<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * --> <!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
<huapp-full-layout></huapp-full-layout> <huapp-full-layout></huapp-full-layout>
<!-- <!--
<div class="p-5">
<router-outlet><huapp-spinner></huapp-spinner></router-outlet>
</div>
<huapp-layout-header></huapp-layout-header> <huapp-layout-header></huapp-layout-header>
<router-outlet><huapp-spinner></huapp-spinner></router-outlet> <router-outlet><huapp-spinner></huapp-spinner></router-outlet>
<huapp-layout-footer></huapp-layout-footer> <huapp-layout-footer></huapp-layout-footer>
+1 -1
View File
@@ -1,4 +1,4 @@
<div class="container page auth-page"> <div class="container content auth-page">
<div class="row"> <div class="row">
<div class="col-md-6 offset-md-3 col-xs-12"> <div class="col-md-6 offset-md-3 col-xs-12">
<h1 class="text-xs-center">{{ title }}</h1> <h1 class="text-xs-center">{{ title }}</h1>
@@ -50,6 +50,7 @@ export class AuthComponent implements OnInit, OnDestroy {
firstname: '', firstname: '',
lastname: '', lastname: '',
phone: '', phone: '',
licence: '',
password: ['', Validators.required], password: ['', Validators.required],
confirmPassword: '' confirmPassword: ''
}, { validators: this.checkPasswords }); }, { validators: this.checkPasswords });
@@ -98,6 +99,7 @@ export class AuthComponent implements OnInit, OnDestroy {
this._user = user$.subscribe({ this._user = user$.subscribe({
next: () => this.router.navigateByUrl('/'), next: () => this.router.navigateByUrl('/'),
error: (err) => { error: (err) => {
console.log(err);
this.errors = err; this.errors = err;
this.isSubmitting = false; this.isSubmitting = false;
} }
@@ -49,7 +49,7 @@
<!-- Numero Column --> <!-- Numero Column -->
<ng-container matColumnDef="weight"> <ng-container matColumnDef="weight">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="{{tableHeader[0].active}}"> {{tableHeader[0].name}} </th> <th mat-header-cell *matHeaderCellDef mat-sort-header class="{{tableHeader[0].active}}"> {{tableHeader[0].name}} </th>
<th mat-cell *matCellDef="let element;" class="text-right pl-3 pr-3">{{element.weight}}</th> <th mat-cell *matCellDef="let element;" class="text-end pl-3 pr-3">{{element.weight}}</th>
</ng-container> </ng-container>
<!-- range_ Column --> <!-- range_ Column -->
<ng-container matColumnDef="range_1"> <ng-container matColumnDef="range_1">
@@ -3,8 +3,7 @@
<mat-card-title>Aéronefs</mat-card-title> <mat-card-title>Aéronefs</mat-card-title>
<mat-card-subtitle>Nombre total de sauts par avions</mat-card-subtitle> <mat-card-subtitle>Nombre total de sauts par avions</mat-card-subtitle>
<div class="barchrt"> <div class="barchrt">
<x-chartist class="" [data]="barChartAeronef.data" [type]="barChartAeronef.type" [options]="barChartAeronef.options" [responsiveOptions]="barChartAeronef.responsiveOptions" <x-chartist [configuration]="barChartAeronef"></x-chartist>
[events]="barChartAeronef.events"> </x-chartist>
</div> </div>
</mat-card-content> </mat-card-content>
<hr> <hr>
@@ -13,18 +12,18 @@
<thead> <thead>
<tr> <tr>
<th></th> <th></th>
<th *ngFor='let name of seriesHeader; let i=index' class="text-right"> {{name}} </th> <th *ngFor='let name of seriesHeader; let i=index' class="text-end"> {{name}} </th>
<th class="text-right">Total</th> <th class="text-end">Total</th>
</tr> </tr>
</thead> </thead>
<tbody class="text-mono"> <tbody class="font-monospace">
<tr *ngFor='let values of seriesRow; let i=index'> <tr *ngFor='let values of seriesRow; let i=index'>
<th class="{{seriesColor[i]}} text-right"><i class="mdi mdi-checkbox-blank-circle font-10 m-r-10 "></i> {{seriesName[i]}} </th> <th class="{{seriesColor[i]}} text-end"> {{seriesName[i]}} </th>
<td *ngFor='let value of values; let i=index' class="text-right"> <td *ngFor='let value of values; let i=index' class="text-end">
<span *ngIf="value; else elseBlock" class="pr-1">{{value}}</span> <span *ngIf="value; else elseBlock" class="pr-1">{{value}}</span>
<ng-template #elseBlock><span class="text-empty pr-1">{{value}}</span></ng-template> <ng-template #elseBlock><span class="text-empty pr-1">{{value}}</span></ng-template>
</td> </td>
<th class="{{seriesColor[i]}} text-right"> <th class="{{seriesColor[i]}} text-end">
<span *ngIf="seriesValue[i]; else elseBlock" class="pr-1">{{seriesValue[i]}}</span> <span *ngIf="seriesValue[i]; else elseBlock" class="pr-1">{{seriesValue[i]}}</span>
<ng-template #elseBlock><span class="text-empty pr-1">{{seriesValue[i]}}</span></ng-template> <ng-template #elseBlock><span class="text-empty pr-1">{{seriesValue[i]}}</span></ng-template>
</th> </th>
@@ -1,10 +1,11 @@
import { Component, OnInit} from '@angular/core'; import { Component, OnInit, OnDestroy } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { MatCardModule } from '@angular/material/card'; import { MatCardModule } from '@angular/material/card';
import { ChartistModule, Configuration } from 'ng-chartist'; import { ChartistModule, Configuration } from 'ng-chartist';
import { Observable, Subscription } from 'rxjs';
import { BackendService } from 'src/app/core/services'; import { BackendService, AeronefsService } from 'src/app/core/services';
import { ReduceRow } from 'src/app/core/models'; import { chartBar, AeronefByImat, AeronefByYear } from 'src/app/core/models';
@Component({ @Component({
standalone: true, standalone: true,
@@ -12,50 +13,42 @@ import { ReduceRow } from 'src/app/core/models';
selector: 'huapp-aeronefs-bar', selector: 'huapp-aeronefs-bar',
templateUrl: './aeronefs-bar.component.html' templateUrl: './aeronefs-bar.component.html'
}) })
export class AeronefsBarComponent implements OnInit { export class AeronefsBarComponent implements OnInit, OnDestroy {
rows: Object[] = [] as Array<Object>; private _aeronefByImat: Subscription = new Subscription();
private _aeronefByYear: Subscription = new Subscription();
aeronefByImat!: Array<AeronefByImat>;
aeronefByYear!: Array<AeronefByYear>;
aeronefByImatCount = 0;
aeronefByYearCount = 0;
seriesName: string[] = []; seriesName: string[] = [];
seriesValue: any[] = []; seriesValue: any[] = [];
seriesColor: string[] = this._dataService.getChartColors(); seriesColor: string[] = this._dataService.getChartColors();
seriesHeader: string[] = []; seriesHeader: string[] = [];
seriesRow: any[] = []; seriesRow: any[] = [];
barChartAeronef: Configuration = { barChartAeronef: Configuration = chartBar;
type: 'Bar',
data: {
"labels": [],
"series": []
},
options: {},
responsiveOptions: []
};
constructor(private _dataService: BackendService) { } constructor(
private aeronefsService: AeronefsService,
loadDataByDate() { private _dataService: BackendService
return this._dataService ) { }
.getAeronefsByDate(2)
.subscribe((res) => {
this.seriesName.forEach((name: string) => {
this.seriesRow.push([0, 0, 0, 0, 0, 0]);
});
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
res["rows"].forEach((row: ReduceRow) => {
let year = row.key[1].toString();
let avion = row.key[0];
this.seriesRow[this.seriesName.indexOf(avion)][this.seriesHeader.indexOf(year)] = row.value;
});
return true;
});
}
ngOnInit() { ngOnInit() {
return this._dataService this._loadAeronefByImat();
.getAeronefs() }
.subscribe((res) => {
this.rows = res["rows"] ngOnDestroy() {
this.rows.forEach((row: ReduceRow) => { this._aeronefByImat.unsubscribe();
this.seriesName.push(row.key[0] + ' ' + row.key[1]); this._aeronefByYear.unsubscribe();
this.seriesValue.push([row.value]); }
private _loadAeronefByImat(): void {
const aeronefs$: Observable<Array<AeronefByImat>> = this.aeronefsService.getAllByImat();
this._aeronefByImat = aeronefs$.subscribe((aggregate: Array<AeronefByImat>) => {
this.aeronefByImat = aggregate;
this.aeronefByImatCount = aggregate.length;
this.aeronefByImat.forEach((row) => {
this.seriesName.push(`${row._id.aeronef} ${row._id.imat}`);
this.seriesValue.push(row.count);
}); });
this.barChartAeronef = { this.barChartAeronef = {
type: 'Bar', type: 'Bar',
@@ -73,9 +66,10 @@ export class AeronefsBarComponent implements OnInit {
seriesBarDistance: 15, seriesBarDistance: 15,
horizontalBars: true, horizontalBars: true,
axisX: { axisX: {
onlyInteger: true,
position: 'end', position: 'end',
labelOffset: { labelOffset: {
x: -5, x: 0,
y: 0 y: 0
}, },
showGrid: true, showGrid: true,
@@ -122,7 +116,29 @@ export class AeronefsBarComponent implements OnInit {
}] }]
] ]
}; };
return this.loadDataByDate(); this._loadAeronefByYear();
});
}
private _loadAeronefByYear(): void {
let values: Array<number> = [];
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
this.seriesHeader.forEach(() => {
values.push(0);
});
this.seriesName.forEach(() => {
this.seriesRow.push([...values]);
});
const dropzones$: Observable<Array<AeronefByYear>> = this.aeronefsService.getAllByDate();
this._aeronefByYear = dropzones$.subscribe((aggregate: Array<AeronefByYear>) => {
this.aeronefByYear = aggregate;
this.aeronefByYearCount = aggregate.length;
this.aeronefByYear.forEach((row: AeronefByYear) => {
let aeronef: string = row._id.aeronef;
let imat: string = row._id.imat;
let year: string = row._id.year.toString();
this.seriesRow[this.seriesName.indexOf(`${aeronef} ${imat}`)][this.seriesHeader.indexOf(year)] = row.count;
});
}); });
} }
} }
@@ -3,7 +3,7 @@
<mat-card-title>Aéronefs</mat-card-title> <mat-card-title>Aéronefs</mat-card-title>
<mat-card-subtitle>Nombre total de sauts par avions</mat-card-subtitle> <mat-card-subtitle>Nombre total de sauts par avions</mat-card-subtitle>
<div class="piechart"> <div class="piechart">
<x-chartist [configuration]="donuteChartModel"> </x-chartist> <x-chartist [configuration]="donuteAeronefs"></x-chartist>
</div> </div>
</mat-card-content> </mat-card-content>
<hr> <hr>
@@ -12,18 +12,18 @@
<thead> <thead>
<tr> <tr>
<th></th> <th></th>
<th *ngFor='let name of seriesHeader; let i=index' class="text-right"> {{name}} </th> <th *ngFor='let name of seriesHeader; let i=index' class="text-end"> {{name}} </th>
<th class="text-right">Total</th> <th class="text-end">Total</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr *ngFor='let values of seriesRow; let i=index'> <tr *ngFor='let values of seriesRow; let i=index'>
<th class="{{seriesColor[i]}} text-right"><i class="mdi mdi-checkbox-blank-circle font-10 m-r-10 "></i> {{seriesName[i]}} </th> <th class="{{seriesColor[i]}} text-end"> {{seriesName[i]}} </th>
<td *ngFor='let value of values; let i=index' class="text-mono text-right"> <td *ngFor='let value of values; let i=index' class="font-monospace text-end">
<span *ngIf="value; else elseBlock" class="pr-1">{{value}}</span> <span *ngIf="value; else elseBlock" class="pr-1">{{value}}</span>
<ng-template #elseBlock><span class="text-empty pr-1">{{value}}</span></ng-template> <ng-template #elseBlock><span class="text-empty pr-1">{{value}}</span></ng-template>
</td> </td>
<th class="{{seriesColor[i]}} text-right"> <th class="{{seriesColor[i]}} text-end">
<span *ngIf="seriesValue[i]; else elseBlock" class="pr-1">{{seriesValue[i]}}</span> <span *ngIf="seriesValue[i]; else elseBlock" class="pr-1">{{seriesValue[i]}}</span>
<ng-template #elseBlock><span class="text-empty pr-1">{{seriesValue[i]}}</span></ng-template> <ng-template #elseBlock><span class="text-empty pr-1">{{seriesValue[i]}}</span></ng-template>
</th> </th>
@@ -1,11 +1,11 @@
import { Component, OnInit} from '@angular/core'; import { Component, OnInit, OnDestroy } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { MatCardModule } from '@angular/material/card'; import { MatCardModule } from '@angular/material/card';
import { ChartistModule, Configuration } from 'ng-chartist'; import { ChartistModule, Configuration } from 'ng-chartist';
import { Observable, Subscription } from 'rxjs'; import { Observable, Subscription } from 'rxjs';
import { BackendService, AeronefsService, UserService } from 'src/app/core/services'; import { BackendService, AeronefsService, UserService } from 'src/app/core/services';
import { Aeronef, AeronefByImat } from 'src/app/core/models'; import { Aeronef, AeronefByImat, AeronefByYear, chartPieDonute } from 'src/app/core/models';
@Component({ @Component({
standalone: true, standalone: true,
@@ -13,110 +13,49 @@ import { Aeronef, AeronefByImat } from 'src/app/core/models';
selector: 'huapp-aeronefs', selector: 'huapp-aeronefs',
templateUrl: './aeronefs.component.html' templateUrl: './aeronefs.component.html'
}) })
export class AeronefsComponent implements OnInit { export class AeronefsComponent implements OnInit, OnDestroy {
private _aeronefs: Subscription = new Subscription(); private _aeronefByImat: Subscription = new Subscription();
aggregate!: Array<AeronefByImat> private _aeronefByYear: Subscription = new Subscription();
aeronefs!: Array<Aeronef>; aeronefByImat!: Array<AeronefByImat>;
aeronefsCount = 0; aeronefByYear!: Array<AeronefByYear>;
aeronefByImatCount = 0;
aeronefByYearCount = 0;
rows: Object[] = [] as Array<Object>; rows: Object[] = [] as Array<Object>;
seriesName: string[] = [];//= ["Arcachon", "Béni-Mellal", "La Réole", "Royan", "Pamiers", "Soulac", "Sables d'Olonne", "Rochefort"]; seriesName: string[] = [];//= ["Arcachon", "Béni-Mellal", "La Réole", "Royan", "Pamiers", "Soulac", "Sables d'Olonne", "Rochefort"];
seriesValue: number[] = []; seriesValue: number[] = [];
seriesColor: string[] = this._dataService.getChartColors(); //["blue", "red", "turquoise", "orange", "cyan", "purple-dark", "megna", "raspberry"]; seriesColor: string[] = this._dataService.getChartColors(); //["blue", "red", "turquoise", "orange", "cyan", "purple-dark", "megna", "raspberry"];
seriesHeader: string[] = []; seriesHeader: string[] = [];
seriesRow: any[] = []; seriesRow: any[] = [];
donuteChartModel: Configuration = { donuteAeronefs: Configuration = chartPieDonute;
type: 'Pie',
data: {
"labels": [],
"series": []
},
options: {
donut: true,
height: 260,
donutWidth: 40,
startAngle: 270,
showLabel: true
}
};
constructor( constructor(
private aeronefsService: AeronefsService, private aeronefsService: AeronefsService,
private _dataService: BackendService private _dataService: BackendService
) { } ) { }
/*loadDataByDate() {
return this._dataService
.getAeronefsByDate(2)
.subscribe((res) => {
this.seriesName.forEach((name: string) => {
this.seriesRow.push([0, 0, 0, 0, 0, 0]);
});
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
res["rows"].forEach((row: ReduceRow) => {
let year = row.key[1].toString();
let avion = row.key[0];
this.seriesRow[this.seriesName.indexOf(avion)][this.seriesHeader.indexOf(year)] = row.value;
});
return true;
});
}*/
ngOnInit() { ngOnInit() {
this.loadAeronefs(); this._loadAeronefByImat();
return this._dataService
.getAeronefs()
.subscribe((res) => {
console.log(res);
/* this.rows = res["rows"]
var labels: string[] = [];
var series: number[] = [];
this.rows.forEach((row: ReduceRow) => {
this.seriesName.push(row.key[0] + ' ' + row.key[1]);
this.seriesValue.push(row.value);
//console.log(row.key, row.value);
labels.push(row.value.toString());
series.push(row.value);
});
this.donuteChartModel = {
type: 'Pie',
data: {
"labels": labels,
"series": series
},
options: {
donut: true,
height: 260,
donutWidth: 40,
startAngle: 270,
showLabel: true
}
//,
// events: <ChartEvent>{
// draw: (data) => {
// //this.donuteChartModel.data = data;
// console.log(data);
// }
// }
};
return this.loadDataByDate(); */
});
} }
loadAeronefs() { ngOnDestroy() {
this._aeronefByImat.unsubscribe();
this._aeronefByYear.unsubscribe();
}
private _loadAeronefByImat(): void {
const aeronefs$: Observable<Array<AeronefByImat>> = this.aeronefsService.getAllByImat(); const aeronefs$: Observable<Array<AeronefByImat>> = this.aeronefsService.getAllByImat();
this._aeronefs = aeronefs$.subscribe((aggregate: Array<AeronefByImat>) => { this._aeronefByImat = aeronefs$.subscribe((aggregate: Array<AeronefByImat>) => {
this.aggregate = aggregate; this.aeronefByImat = aggregate;
this.aeronefsCount = aggregate.length; this.aeronefByImatCount = aggregate.length;
var labels: string[] = []; var labels: string[] = [];
var series: number[] = []; var series: number[] = [];
this.aggregate.forEach((row) => { this.aeronefByImat.forEach((row) => {
this.seriesName.push(row._id.aeronef + ' ' + row._id.imat); this.seriesName.push(`${row._id.aeronef} ${row._id.imat}`);
this.seriesValue.push(row.count); this.seriesValue.push(row.count);
labels.push(row.count.toString()); labels.push(row.count.toString());
//labels.push(row._id.aeronef + ' ' + row._id.imat);
series.push(row.count); series.push(row.count);
}); });
this.donuteChartModel = { this.donuteAeronefs = {
type: 'Pie', type: 'Pie',
data: { data: {
"labels": labels, "labels": labels,
@@ -130,6 +69,29 @@ export class AeronefsComponent implements OnInit {
showLabel: true showLabel: true
} }
}; };
this._loadAeronefByYear();
});
}
private _loadAeronefByYear(): void {
let values: Array<number> = [];
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
this.seriesHeader.forEach(() => {
values.push(0);
});
this.seriesName.forEach(() => {
this.seriesRow.push([...values]);
});
const dropzones$: Observable<Array<AeronefByYear>> = this.aeronefsService.getAllByDate();
this._aeronefByYear = dropzones$.subscribe((aggregate: Array<AeronefByYear>) => {
this.aeronefByYear = aggregate;
this.aeronefByYearCount = aggregate.length;
this.aeronefByYear.forEach((row: AeronefByYear) => {
let aeronef: string = row._id.aeronef;
let imat: string = row._id.imat;
let year: string = row._id.year.toString();
this.seriesRow[this.seriesName.indexOf(`${aeronef} ${imat}`)][this.seriesHeader.indexOf(year)] = row.count;
});
}); });
} }
} }
@@ -3,7 +3,7 @@
<mat-card-title>Modèles de voile</mat-card-title> <mat-card-title>Modèles de voile</mat-card-title>
<mat-card-subtitle>Nombre total de sauts par modèle</mat-card-subtitle> <mat-card-subtitle>Nombre total de sauts par modèle</mat-card-subtitle>
<div class="piechart"> <div class="piechart">
<x-chartist [configuration]="donuteCanopyModel"> </x-chartist> <x-chartist [configuration]="donuteCanopies"></x-chartist>
</div> </div>
</mat-card-content> </mat-card-content>
<hr> <hr>
@@ -12,18 +12,18 @@
<thead> <thead>
<tr> <tr>
<th></th> <th></th>
<th *ngFor='let name of seriesHeader; let i=index' class="text-right"> {{name}} </th> <th *ngFor='let name of seriesHeader; let i=index' class="text-end"> {{name}} </th>
<th class="text-right">Total</th> <th class="text-end">Total</th>
</tr> </tr>
</thead> </thead>
<tbody class="text-mono"> <tbody class="font-monospace">
<tr *ngFor='let values of seriesRow; let i=index'> <tr *ngFor='let values of seriesRow; let i=index'>
<th class="{{seriesColor[i]}} text-right"><i class="mdi mdi-checkbox-blank-circle font-10 m-r-10 "></i> {{seriesName[i]}} </th> <th class="{{seriesColor[i]}} text-end"> {{seriesName[i]}} </th>
<td *ngFor='let value of values; let i=index' class="text-right"> <td *ngFor='let value of values; let i=index' class="text-end">
<span *ngIf="value; else elseBlock" class="pr-1">{{value}}</span> <span *ngIf="value; else elseBlock" class="pr-1">{{value}}</span>
<ng-template #elseBlock><span class="text-empty pr-1">{{value}}</span></ng-template> <ng-template #elseBlock><span class="text-empty pr-1">{{value}}</span></ng-template>
</td> </td>
<th class="{{seriesColor[i]}} text-right"> <th class="{{seriesColor[i]}} text-end">
<span *ngIf="seriesValue[i]; else elseBlock" class="pr-1">{{seriesValue[i]}}</span> <span *ngIf="seriesValue[i]; else elseBlock" class="pr-1">{{seriesValue[i]}}</span>
<ng-template #elseBlock><span class="text-empty pr-1">{{seriesValue[i]}}</span></ng-template> <ng-template #elseBlock><span class="text-empty pr-1">{{seriesValue[i]}}</span></ng-template>
</th> </th>
@@ -1,13 +1,12 @@
import { Component, OnInit} from '@angular/core'; import { Component, OnInit, OnDestroy} from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { MatCardModule } from '@angular/material/card'; import { MatCardModule } from '@angular/material/card';
import { ChartistModule, Configuration } from 'ng-chartist'; import { ChartistModule, Configuration } from 'ng-chartist';
import { Observable, Observer, Subscription } from 'rxjs'; import { Observable, Subscription } from 'rxjs';
import { take } from 'rxjs/operators';
import { BackendService, CanopiesService } from 'src/app/core/services'; import { BackendService, CanopiesService } from 'src/app/core/services';
import { Canopy, CanopyBySize, ReduceRow } from 'src/app/core/models'; import { Canopy, CanopyModelBySize, CanopyModelByYear, chartPieDonute } from 'src/app/core/models';
@Component({ @Component({
standalone: true, standalone: true,
@@ -15,106 +14,49 @@ import { Canopy, CanopyBySize, ReduceRow } from 'src/app/core/models';
selector: 'huapp-canopy-models', selector: 'huapp-canopy-models',
templateUrl: './canopy-models.component.html' templateUrl: './canopy-models.component.html'
}) })
export class CanopyModelsComponent implements OnInit { export class CanopyModelsComponent implements OnInit, OnDestroy {
private _canopies: Subscription = new Subscription(); private _canopyBySize: Subscription = new Subscription();
aggregate!: Array<CanopyBySize> private _canopyByYear: Subscription = new Subscription();
canopies!: Array<Canopy>; canopyBySize!: Array<CanopyModelBySize>;
canopiesCount = 0; canopyByYear!: Array<CanopyModelByYear>;
canopyBySizeCount = 0;
canopyByYearCount = 0;
rows: Object[] = [] as Array<Object>; rows: Object[] = [] as Array<Object>;
seriesName: string[] = []; seriesName: string[] = [];
seriesValue: number[] = []; seriesValue: number[] = [];
seriesColor: string[] = this._dataService.getChartColors(); seriesColor: string[] = this._dataService.getChartColors();
seriesHeader: string[] = []; seriesHeader: string[] = [];
seriesRow: any[] = []; seriesRow: any[] = [];
donuteCanopyModel: Configuration = { donuteCanopies: Configuration = chartPieDonute;
type: 'Pie',
data: {
"labels": [],
"series": []
},
options: {
donut: true,
height: 260,
donutWidth: 40,
startAngle: 270,
showLabel: true
}
};
constructor( constructor(
private canopiesService: CanopiesService, private canopiesService: CanopiesService,
private _dataService: BackendService private _dataService: BackendService
) { } ) { }
/*
loadDataByDate() {
return this._dataService
.getCanopyModelsByDate(2)
.subscribe((res) => {
this.seriesName.forEach((name: string) => {
this.seriesRow.push([0, 0, 0, 0, 0, 0]);
});
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
res["rows"].forEach((row: ReduceRow) => {
let year = row.key[1].toString();
let voile = row.key[0];
this.seriesRow[this.seriesName.indexOf(voile)][this.seriesHeader.indexOf(year)] = row.value;
});
return true;
});
}
*/
ngOnInit() { ngOnInit() {
this.loadCanopies(); this._loadCanopyModelBySize();
/*
return this._dataService
.getCanopyModels()
.subscribe((res) => {
this.rows = res["rows"]
var labels: string[] = [];
var series: number[] = [];
this.rows.forEach((row: ReduceRow) => {
this.seriesName.push(row.key);
this.seriesValue.push(row.value);
labels.push(row.value.toString());
series.push(row.value);
});
this.donuteCanopyModel = {
type: 'Pie',
data: {
"labels": labels,
"series": series
},
options: {
donut: true,
height: 260,
donutWidth: 40,
donutSolid: true,
startAngle: 270,
showLabel: true
}
};
return this.loadDataByDate();
});
*/
} }
loadCanopies() { ngOnDestroy() {
const canopies$: Observable<Array<CanopyBySize>> = this.canopiesService.getAllBySize(); this._canopyBySize.unsubscribe();
this._canopies = canopies$.subscribe((aggregate: Array<CanopyBySize>) => { this._canopyByYear.unsubscribe();
this.aggregate = aggregate; }
//this.canopies = canopies;
this.canopiesCount = aggregate.length; private _loadCanopyModelBySize(): void {
const canopies$: Observable<Array<CanopyModelBySize>> = this.canopiesService.getAllModelBySize();
this._canopyBySize = canopies$.subscribe((aggregate: Array<CanopyModelBySize>) => {
this.canopyBySize = aggregate;
this.canopyBySizeCount = aggregate.length;
var labels: string[] = []; var labels: string[] = [];
var series: number[] = []; var series: number[] = [];
this.aggregate.forEach((row) => { this.canopyBySize.forEach((row) => {
this.seriesName.push(row._id.canopy + ' ' + row._id.taille); this.seriesName.push(`${row._id.taille.toString()} - ${row._id.voile}`);
this.seriesValue.push(row.count); this.seriesValue.push(row.count);
labels.push(row.count.toString()); labels.push(row.count.toString());
series.push(row.count); series.push(row.count);
}); });
this.donuteCanopyModel = { this.donuteCanopies = {
type: 'Pie', type: 'Pie',
data: { data: {
"labels": labels, "labels": labels,
@@ -128,6 +70,29 @@ export class CanopyModelsComponent implements OnInit {
showLabel: true showLabel: true
} }
}; };
this._loadCanopyModelByYear();
});
}
private _loadCanopyModelByYear(): void {
let values: Array<number> = [];
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
this.seriesHeader.forEach(() => {
values.push(0);
});
this.seriesName.forEach(() => {
this.seriesRow.push([...values]);
});
const dropzones$: Observable<Array<CanopyModelByYear>> = this.canopiesService.getAllModelByYear();
this._canopyByYear = dropzones$.subscribe((aggregate: Array<CanopyModelByYear>) => {
this.canopyByYear = aggregate;
this.canopyByYearCount = aggregate.length;
this.canopyByYear.forEach((row: CanopyModelByYear) => {
let voile: string = row._id.voile;
let taille: string = row._id.taille.toString();
let year: string = row._id.year.toString();
this.seriesRow[this.seriesName.indexOf(`${taille} - ${voile}`)][this.seriesHeader.indexOf(year)] = row.count;
});
}); });
} }
} }
@@ -3,9 +3,7 @@
<mat-card-title>Taille de voile</mat-card-title> <mat-card-title>Taille de voile</mat-card-title>
<mat-card-subtitle>Nombre total de sauts par taille</mat-card-subtitle> <mat-card-subtitle>Nombre total de sauts par taille</mat-card-subtitle>
<div class="piechart"> <div class="piechart">
<x-chartist class="" [data]="donuteChartSize.data" [type]="donuteChartSize.type" <x-chartist [configuration]="donuteCanopiesSize"></x-chartist>
[options]="donuteChartSize.options" [responsiveOptions]="donuteChartSize.responsiveOptions"
[events]="donuteChartSize.events"> </x-chartist>
</div> </div>
</mat-card-content> </mat-card-content>
<hr> <hr>
@@ -14,18 +12,18 @@
<thead> <thead>
<tr> <tr>
<th></th> <th></th>
<th *ngFor='let name of seriesHeader; let i=index' class="text-right"> {{name}} </th> <th *ngFor='let name of seriesHeader; let i=index' class="text-end"> {{name}} </th>
<th class="text-right">Total</th> <th class="text-end">Total</th>
</tr> </tr>
</thead> </thead>
<tbody class="text-mono"> <tbody class="font-monospace">
<tr *ngFor='let values of seriesRow; let i=index'> <tr *ngFor='let values of seriesRow; let i=index'>
<th class="{{seriesColor[i]}} text-right"><i class="mdi mdi-checkbox-blank-circle font-10 m-r-10 "></i> {{seriesName[i]}} </th> <th class="{{seriesColor[i]}} text-end"> {{seriesName[i]}} </th>
<td *ngFor='let value of values; let i=index' class="text-right"> <td *ngFor='let value of values; let i=index' class="text-end">
<span *ngIf="value; else elseBlock" class="pr-1">{{value}}</span> <span *ngIf="value; else elseBlock" class="pr-1">{{value}}</span>
<ng-template #elseBlock><span class="text-empty pr-1">{{value}}</span></ng-template> <ng-template #elseBlock><span class="text-empty pr-1">{{value}}</span></ng-template>
</td> </td>
<th class="{{seriesColor[i]}} text-right"> <th class="{{seriesColor[i]}} text-end">
<span *ngIf="seriesValue[i]; else elseBlock" class="pr-1">{{seriesValue[i]}}</span> <span *ngIf="seriesValue[i]; else elseBlock" class="pr-1">{{seriesValue[i]}}</span>
<ng-template #elseBlock><span class="text-empty pr-1">{{seriesValue[i]}}</span></ng-template> <ng-template #elseBlock><span class="text-empty pr-1">{{seriesValue[i]}}</span></ng-template>
</th> </th>
@@ -1,10 +1,12 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit, OnDestroy } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { MatCardModule } from '@angular/material/card'; import { MatCardModule } from '@angular/material/card';
import { ChartistModule, Configuration } from 'ng-chartist'; import { ChartistModule, Configuration } from 'ng-chartist';
import { BackendService } from 'src/app/core/services'; import { Observable, Subscription } from 'rxjs';
import { ReduceRow } from 'src/app/core/models';
import { BackendService, CanopiesService } from 'src/app/core/services';
import { chartPieDonute, CanopyBySize, CanopyByYear, ReduceRow } from 'src/app/core/models';
@Component({ @Component({
standalone: true, standalone: true,
@@ -12,61 +14,49 @@ import { ReduceRow } from 'src/app/core/models';
selector: 'huapp-canopy-sizes', selector: 'huapp-canopy-sizes',
templateUrl: './canopy-sizes.component.html' templateUrl: './canopy-sizes.component.html'
}) })
export class CanopySizesComponent implements OnInit { export class CanopySizesComponent implements OnInit, OnDestroy {
private _canopyBySize: Subscription = new Subscription();
private _canopyByYear: Subscription = new Subscription();
canopyBySize!: Array<CanopyBySize>;
canopyByYear!: Array<CanopyByYear>;
canopyBySizeCount = 0;
canopyByYearCount = 0;
rows: Object[] = [] as Array<Object>; rows: Object[] = [] as Array<Object>;
seriesName: string[] = []; seriesName: string[] = [];
seriesValue: number[] = []; seriesValue: number[] = [];
seriesColor: string[] = this._dataService.getChartColors(); seriesColor: string[] = this._dataService.getChartColors();
seriesHeader: string[] = []; seriesHeader: string[] = [];
seriesRow: any[] = []; seriesRow: any[] = [];
donuteChartSize: Configuration = { donuteCanopiesSize: Configuration = chartPieDonute;
type: 'Pie',
data: {
"labels": [],
"series": []
},
options: {
donut: true,
height: 260,
donutWidth: 40,
startAngle: 0,
showLabel: true
}
};
constructor(private _dataService: BackendService) { } constructor(
private canopiesService: CanopiesService,
loadDataByDate() { private _dataService: BackendService
return this._dataService ) { }
.getCanopySizesByDate(2)
.subscribe((res) => {
this.seriesName.forEach((name: string) => {
this.seriesRow.push([0, 0, 0, 0, 0, 0]);
});
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
res["rows"].forEach((row: ReduceRow) => {
let year = row.key[1].toString();
let size = row.key[0];
this.seriesRow[this.seriesName.indexOf(size)][this.seriesHeader.indexOf(year)] = row.value;
});
return true;
});
}
ngOnInit() { ngOnInit() {
return this._dataService this._loadCanopyBySize();
.getCanopySizes() }
.subscribe((res) => {
this.rows = res["rows"] ngOnDestroy() {
this._canopyBySize.unsubscribe();
this._canopyByYear.unsubscribe();
}
private _loadCanopyBySize(): void {
const canopies$: Observable<Array<CanopyBySize>> = this.canopiesService.getAllBySize();
this._canopyBySize = canopies$.subscribe((aggregate: Array<CanopyBySize>) => {
this.canopyBySize = aggregate;
this.canopyBySizeCount = aggregate.length;
var labels: string[] = []; var labels: string[] = [];
var series: number[] = []; var series: number[] = [];
this.rows.forEach((row: ReduceRow) => { this.canopyBySize.forEach((row) => {
this.seriesName.push(row.key); this.seriesName.push(row._id.taille.toString());
this.seriesValue.push(row.value); this.seriesValue.push(row.count);
labels.push(row.value.toString()); labels.push(row.count.toString());
series.push(row.value); series.push(row.count);
}); });
this.donuteChartSize = { this.donuteCanopiesSize = {
type: 'Pie', type: 'Pie',
data: { data: {
"labels": labels, "labels": labels,
@@ -76,12 +66,32 @@ export class CanopySizesComponent implements OnInit {
donut: true, donut: true,
height: 260, height: 260,
donutWidth: 40, donutWidth: 40,
donutSolid: true,
startAngle: 330, startAngle: 330,
showLabel: true showLabel: true
} }
}; };
return this.loadDataByDate(); this._loadCanopyByYear();
});
}
private _loadCanopyByYear(): void {
let values: Array<number> = [];
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
this.seriesHeader.forEach(() => {
values.push(0);
});
this.seriesName.forEach(() => {
this.seriesRow.push([...values]);
});
const dropzones$: Observable<Array<CanopyByYear>> = this.canopiesService.getAllByYear();
this._canopyByYear = dropzones$.subscribe((aggregate: Array<CanopyByYear>) => {
this.canopyByYear = aggregate;
this.canopyByYearCount = aggregate.length;
this.canopyByYear.forEach((row: CanopyByYear) => {
let taille: string = row._id.taille.toString();
let year: string = row._id.year.toString();
this.seriesRow[this.seriesName.indexOf(taille)][this.seriesHeader.indexOf(year)] = row.count;
});
}); });
} }
} }
@@ -1,10 +1,12 @@
import { Component, OnInit, Input, Output } from '@angular/core'; import { Component, OnInit, OnDestroy, Input, Output } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { MatCardModule } from '@angular/material/card'; import { MatCardModule } from '@angular/material/card';
import { ChartistModule, Configuration } from 'ng-chartist'; import { ChartistModule, Configuration } from 'ng-chartist';
import { BackendService } from 'src/app/core/services'; import { Observable, Subscription } from 'rxjs';
import { DropZone, ReduceRow} from 'src/app/core/models';
import { BackendService, DropZonesService } from 'src/app/core/services';
import { chartBar, chartPieDonute, DropZone, DropZoneByOaci, DropZoneByYear } from 'src/app/core/models';
@Component({ @Component({
standalone: true, standalone: true,
@@ -12,63 +14,86 @@ import { DropZone, ReduceRow} from 'src/app/core/models';
selector: 'huapp-drop-zones-bar', selector: 'huapp-drop-zones-bar',
templateUrl: './drop-zones-bar.component.html' templateUrl: './drop-zones-bar.component.html'
}) })
export class DropZonesBarComponent implements OnInit { export class DropZonesBarComponent implements OnInit, OnDestroy {
private _dropzoneByOaci: Subscription = new Subscription();
private _dropzoneByYear: Subscription = new Subscription();
dropzoneByOaci!: Array<DropZoneByOaci>;
dropzoneByYear!: Array<DropZoneByYear>;
dropzoneByOaciCount = 0;
dropzoneByYearCount = 0;
dropzones: Object[] = [] as Array<Object>; dropzones: Object[] = [] as Array<Object>;
seriesName: string[] = [];//= ["Arcachon", "Béni-Mellal", "La Réole", "Royan", "Pamiers", "Soulac", "Sables d'Olonne", "Rochefort"]; seriesName: string[] = [];
seriesValue: number[] = []; seriesValue: number[] = [];
seriesColor: string[] = this._dataService.getChartColors(); seriesColor: string[] = this._dataService.getChartColors();
seriesHeader: string[] = []; seriesHeader: string[] = [];
seriesRow: any[] = []; seriesRow: any[] = [];
donuteDropZones: Configuration = { donuteDropZones: Configuration = chartPieDonute;
barChartDropZones: Configuration = chartBar;
constructor(
private dropzonesService: DropZonesService,
private _dataService: BackendService
) { }
ngOnInit() {
this._loadDropZoneByOaci();
}
ngOnDestroy() {
this._dropzoneByOaci.unsubscribe();
this._dropzoneByYear.unsubscribe();
}
private _loadDropZoneByOaci(): void {
const dropzones$: Observable<Array<DropZoneByOaci>> = this.dropzonesService.getAllByOaci();
this._dropzoneByOaci = dropzones$.subscribe((aggregate: Array<DropZoneByOaci>) => {
this.dropzoneByOaci = aggregate;
this.dropzoneByOaciCount = aggregate.length;
var labels: string[] = [];
var series: number[] = [];
this.dropzoneByOaci.forEach((row) => {
this.seriesName.push(`${row._id.oaci} - ${row._id.lieu}`);
this.seriesValue.push(row.count);
labels.push(row.count.toString());
series.push(row.count);
});
this.donuteDropZones = {
type: 'Pie', type: 'Pie',
/*
data: { data: {
"labels": ["261", "45", "178", "16", "13", "11", "4", "2"], "labels": labels,
"series": [261, 45, 178, 16, 13, 11, 4, 2] "series": series
},
*/
data: {
"labels": [],
"series": []
}, },
options: { options: {
donut: true, donut: true,
height: 260, height: 260,
donutWidth: 40, donutWidth: 50,
startAngle: 270, startAngle: 270,
showLabel: true showLabel: true
} }
}; };
barChartDropZones: Configuration = { this._loadDropZoneByYear();
type: 'Bar',
data: {
"labels": [],
"series": []
},
options: {},
responsiveOptions: []
};
constructor(private _dataService: BackendService) { }
loadDataByDate() {
return this._dataService
.getDropZonesByDate(2)
.subscribe((res) => {
console.log(res["rows"]);
this.seriesName.forEach((name: string) => {
this.seriesRow.push([0, 0, 0, 0, 0, 0]);
}); });
}
private _loadDropZoneByYear(): void {
let values: Array<number> = [];
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"]; this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
res["rows"].forEach((row: ReduceRow) => { this.seriesHeader.forEach(() => {
let year = row.key[1].toString(); values.push(0);
let lieu = row.key[0]; });
this.seriesRow[this.seriesName.indexOf(lieu)][this.seriesHeader.indexOf(year)] = row.value; this.seriesName.forEach(() => {
//console.log(row.key, row.value); this.seriesRow.push([...values]);
});
const dropzones$: Observable<Array<DropZoneByYear>> = this.dropzonesService.getAllByDate();
this._dropzoneByYear = dropzones$.subscribe((aggregate: Array<DropZoneByYear>) => {
this.dropzoneByYear = aggregate;
this.dropzoneByYearCount = aggregate.length;
this.dropzoneByYear.forEach((row: DropZoneByYear) => {
let lieu: string = row._id.lieu;
let oaci: string = row._id.oaci;
let year: string = row._id.year.toString();
this.seriesRow[this.seriesName.indexOf(`${oaci} - ${lieu}`)][this.seriesHeader.indexOf(year)] = row.count;
}); });
//console.log(this.seriesName);
//console.log(this.seriesHeader);
//console.log(this.seriesRow);
this.barChartDropZones = { this.barChartDropZones = {
type: 'Bar', type: 'Bar',
data: { data: {
@@ -121,50 +146,6 @@ export class DropZonesBarComponent implements OnInit {
}] }]
] ]
}; };
return true;
});
}
ngOnInit() {
return this._dataService
.getDropZones()
.subscribe((res) => {
//console.log('ngOnInit');
//console.log(res["rows"]);
this.dropzones = res["rows"]
var labels: string[] = [];
var series: number[] = [];
this.dropzones.forEach((dropzone: DropZone) => {
this.seriesName.push(dropzone.key);
this.seriesValue.push(dropzone.value);
//console.log(dropzone.key, dropzone.value);
labels.push(dropzone.value.toString());
series.push(dropzone.value);
});
this.donuteDropZones = {
type: 'Pie',
data: {
"labels": labels,
"series": series
},
options: {
donut: true,
height: 260,
donutWidth: 40,
donutSolid: true,
startAngle: 270,
showLabel: true
}
/*,
events: <ChartEvent>{
draw: (data) => {
//this.donuteDropZones.data = data;
console.log(data);
}
}
*/
};
return this.loadDataByDate();
}); });
} }
} }
@@ -12,18 +12,18 @@
<thead> <thead>
<tr> <tr>
<th></th> <th></th>
<th *ngFor='let name of seriesHeader; let i=index' class="text-right"> {{name}} </th> <th *ngFor='let name of seriesHeader; let i=index' class="text-end"> {{name}} </th>
<th class="text-right">Total</th> <th class="text-end">Total</th>
</tr> </tr>
</thead> </thead>
<tbody class="text-mono"> <tbody class="font-monospace">
<tr *ngFor='let values of seriesRow; let i=index'> <tr *ngFor='let values of seriesRow; let i=index'>
<th class="{{seriesColor[i]}} text-right"><i class="mdi mdi-checkbox-blank-circle font-10 m-r-10 "></i> {{seriesName[i]}} </th> <th class="{{seriesColor[i]}} text-end"> {{seriesName[i]}} </th>
<td *ngFor='let value of values; let i=index' class="text-right"> <td *ngFor='let value of values; let i=index' class="text-end">
<span *ngIf="value; else elseBlock" class="pr-1">{{value}}</span> <span *ngIf="value; else elseBlock" class="pr-1">{{value}}</span>
<ng-template #elseBlock><span class="text-empty pr-1">{{value}}</span></ng-template> <ng-template #elseBlock><span class="text-empty pr-1">{{value}}</span></ng-template>
</td> </td>
<th class="{{seriesColor[i]}} text-right"> <th class="{{seriesColor[i]}} text-end">
<span *ngIf="seriesValue[i]; else elseBlock" class="pr-1">{{seriesValue[i]}}</span> <span *ngIf="seriesValue[i]; else elseBlock" class="pr-1">{{seriesValue[i]}}</span>
<ng-template #elseBlock><span class="text-empty pr-1">{{seriesValue[i]}}</span></ng-template> <ng-template #elseBlock><span class="text-empty pr-1">{{seriesValue[i]}}</span></ng-template>
</th> </th>
@@ -1,12 +1,12 @@
import { Component, OnInit, Input, Output } from '@angular/core'; import { Component, OnInit, OnDestroy, Input, Output } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { MatCardModule } from '@angular/material/card'; import { MatCardModule } from '@angular/material/card';
import { ChartistModule, Configuration } from 'ng-chartist'; import { ChartistModule, Configuration } from 'ng-chartist';
import { Observable, Observer, Subscription } from 'rxjs'; import { Observable, Subscription } from 'rxjs';
import { BackendService, DropZonesService } from 'src/app/core/services'; import { BackendService, DropZonesService } from 'src/app/core/services';
import { DropZone, DropZoneByOaci, ReduceRow} from 'src/app/core/models'; import { DropZoneByOaci, DropZoneByYear, chartPieDonute} from 'src/app/core/models';
@Component({ @Component({
standalone: true, standalone: true,
@@ -14,156 +14,43 @@ import { DropZone, DropZoneByOaci, ReduceRow} from 'src/app/core/models';
selector: 'huapp-drop-zones', selector: 'huapp-drop-zones',
templateUrl: './drop-zones.component.html' templateUrl: './drop-zones.component.html'
}) })
export class DropZonesComponent implements OnInit { export class DropZonesComponent implements OnInit, OnDestroy {
private _dropzones: Subscription = new Subscription(); private _dropzoneByOaci: Subscription = new Subscription();
aggregate!: Array<DropZoneByOaci> private _dropzoneByYear: Subscription = new Subscription();
dropzones!: Array<DropZone>; dropzoneByOaci!: Array<DropZoneByOaci>;
dropzonesCount = 0; dropzoneByYear!: Array<DropZoneByYear>;
seriesName: string[] = [];//= ["Arcachon", "Béni-Mellal", "La Réole", "Royan", "Pamiers", "Soulac", "Sables d'Olonne", "Rochefort"]; dropzoneByOaciCount = 0;
dropzoneByYearCount = 0;
seriesName: string[] = [];
seriesValue: number[] = []; seriesValue: number[] = [];
seriesColor: string[] = this._dataService.getChartColors(); seriesColor: string[] = this._dataService.getChartColors();
seriesHeader: string[] = []; seriesHeader: string[] = [];
seriesRow: any[] = []; seriesRow: any[] = [];
donuteDropZones: Configuration = { donuteDropZones: Configuration = chartPieDonute;
type: 'Pie',
/*
data: {
"labels": ["261", "45", "178", "16", "13", "11", "4", "2"],
"series": [261, 45, 178, 16, 13, 11, 4, 2]
},
*/
data: {
"labels": [],
"series": []
},
options: {
donut: true,
height: 260,
donutWidth: 40,
startAngle: 270,
showLabel: true
}
};
barChartDropZones: Configuration = {
type: 'Bar',
data: {
"labels": [],
"series": []
},
options: {
seriesBarDistance: 5,
high: 170,
axisX: {
showGrid: false,
offset: 20
},
axisY: {
showGrid: true,
offset: 40
},
height: 207
},
responsiveOptions: [
['screen and (min-width: 1024px)', {
axisX: {
labelInterpolationFnc: function(value: number, index: number): string {
return index % 1 === 0 ? `${value}` : '';
}
}
}],
['screen and (min-width: 641px) and (max-width: 1024px)', {
seriesBarDistance: 10,
axisY: {
offset: 30
},
axisX: {
labelInterpolationFnc: function(value: any, index: number): string {
return index % 1 === 0 ? `${value[2]}${value[3]}` : '';
}
}
}],
['screen and (max-width: 640px)', {
seriesBarDistance: 5,
axisY: {
offset: 20
},
axisX: {
labelInterpolationFnc: function(value: any, index: number): string {
return index % 1 === 0 ? `${value[2]}${value[3]}` : '';
}
}
}]
]
};
constructor( constructor(
private dropzonesService: DropZonesService, private dropzonesService: DropZonesService,
private _dataService: BackendService private _dataService: BackendService
) { } ) { }
ngOnInit() { ngOnInit() {
this.loadDropZones(); this._loadDropZoneByOaci();
/*
return this._dataService
.getDropZones()
.subscribe((res) => {
this.dropzones = res["rows"]
var labels: string[] = [];
var series: number[] = [];
this.dropzones.forEach((dropzone: DropZone) => {
this.seriesName.push(dropzone.key);
this.seriesValue.push(dropzone.value);
labels.push(dropzone.value.toString());
series.push(dropzone.value);
});
this.donuteDropZones = {
type: 'Pie',
data: {
"labels": labels,
"series": series
},
options: {
donut: true,
height: 260,
donutWidth: 40,
donutSolid: true,
startAngle: 270,
showLabel: true
}
,
// events: <ChartEvent>{
// draw: (data) => {
// //this.donuteDropZones.data = data;
// console.log(data);
// }
// }
};
return this._dataService
.getDropZonesByDate(2)
.subscribe((res) => {
this.seriesName.forEach((name: string) => {
this.seriesRow.push([0, 0, 0, 0, 0, 0]);
});
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
res["rows"].forEach((row: ReduceRow) => {
let year = row.key[1].toString();
let lieu = row.key[0];
this.seriesRow[this.seriesName.indexOf(lieu)][this.seriesHeader.indexOf(year)] = row.value;
});
return true;
});
});
*/
} }
loadDropZones() { ngOnDestroy() {
this._dropzoneByOaci.unsubscribe();
this._dropzoneByYear.unsubscribe();
}
private _loadDropZoneByOaci(): void {
const dropzones$: Observable<Array<DropZoneByOaci>> = this.dropzonesService.getAllByOaci(); const dropzones$: Observable<Array<DropZoneByOaci>> = this.dropzonesService.getAllByOaci();
this._dropzones = dropzones$.subscribe((aggregate: Array<DropZoneByOaci>) => { this._dropzoneByOaci = dropzones$.subscribe((aggregate: Array<DropZoneByOaci>) => {
this.aggregate = aggregate; this.dropzoneByOaci = aggregate;
//this.dropzones = dropzones; this.dropzoneByOaciCount = aggregate.length;
this.dropzonesCount = aggregate.length;
var labels: string[] = []; var labels: string[] = [];
var series: number[] = []; var series: number[] = [];
this.aggregate.forEach((row) => { this.dropzoneByOaci.forEach((row) => {
this.seriesName.push(row._id.lieu + ' ' + row._id.oaci); this.seriesName.push(`${row._id.oaci} - ${row._id.lieu}`);
this.seriesValue.push(row.count); this.seriesValue.push(row.count);
labels.push(row.count.toString()); labels.push(row.count.toString());
series.push(row.count); series.push(row.count);
@@ -182,6 +69,29 @@ export class DropZonesComponent implements OnInit {
showLabel: true showLabel: true
} }
}; };
this._loadDropZoneByYear();
});
}
private _loadDropZoneByYear(): void {
let values: Array<number> = [];
this.seriesHeader = ["2018", "2019", "2020", "2021", "2022", "2023"];
this.seriesHeader.forEach(() => {
values.push(0);
});
this.seriesName.forEach(() => {
this.seriesRow.push([...values]);
});
const dropzones$: Observable<Array<DropZoneByYear>> = this.dropzonesService.getAllByDate();
this._dropzoneByYear = dropzones$.subscribe((aggregate: Array<DropZoneByYear>) => {
this.dropzoneByYear = aggregate;
this.dropzoneByYearCount = aggregate.length;
this.dropzoneByYear.forEach((row: DropZoneByYear) => {
let lieu: string = row._id.lieu;
let oaci: string = row._id.oaci;
let year: string = row._id.year.toString();
this.seriesRow[this.seriesName.indexOf(`${oaci} - ${lieu}`)][this.seriesHeader.indexOf(year)] = row.count;
});
}); });
} }
} }
@@ -1,7 +1,7 @@
export * from './aeronefs/aeronefs.component'; export * from './aeronefs/aeronefs.component';
//export * from './aeronefs-bar/aeronefs-bar.component'; export * from './aeronefs-bar/aeronefs-bar.component';
export * from './canopy-models/canopy-models.component'; export * from './canopy-models/canopy-models.component';
//export * from './canopy-sizes/canopy-sizes.component'; export * from './canopy-sizes/canopy-sizes.component';
export * from './drop-zones/drop-zones.component'; export * from './drop-zones/drop-zones.component';
//export * from './drop-zones-bar/drop-zones-bar.component'; export * from './drop-zones-bar/drop-zones-bar.component';
//export * from './jumps-by-month/jumps-by-month.component'; export * from './jumps-by-month/jumps-by-month.component';
@@ -7,15 +7,18 @@
</div> </div>
</div> </div>
<div class="barchrt"> <div class="barchrt">
<x-chartist [configuration]="barChartJumps"></x-chartist>
<!--
<x-chartist class="" [data]="barChartJumps.data" [type]="barChartJumps.type" [options]="barChartJumps.options" [responsiveOptions]="barChartJumps.responsiveOptions" <x-chartist class="" [data]="barChartJumps.data" [type]="barChartJumps.type" [options]="barChartJumps.options" [responsiveOptions]="barChartJumps.responsiveOptions"
[events]="barChartJumps.events"> </x-chartist> [events]="barChartJumps.events"> </x-chartist>
-->
</div> </div>
<div class="text-center mt-3 mb-2"> <div class="text-center my-3">
<ul class="list-inline my-0"> <ul class="list-inline my-0">
<li *ngFor='let name of seriesName; let i=index'> <li *ngFor='let name of seriesName; let i=index' class="list-inline-item me-lg-3 me-sm-2">
<h4 class="{{seriesColor[i]}} m-0"> <span class="{{seriesColor[i]}} fs-6 m-0">
<i class="mdi mdi-checkbox-blank-circle font-10 m-r-10 "></i>{{name}} {{name}}
</h4> </span>
</li> </li>
</ul> </ul>
</div> </div>
@@ -25,28 +28,28 @@
<thead> <thead>
<tr> <tr>
<th></th> <th></th>
<th *ngFor='let name of seriesHeader; let i=index' class="text-right"> {{name}} </th> <th *ngFor='let name of seriesHeader; let i=index' class="text-end"> {{name}} </th>
<th class="text-right">Total</th> <th class="text-end">Total</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr *ngFor='let values of seriesRow; let i=index'> <tr *ngFor='let values of seriesRow; let i=index'>
<th class="{{seriesColor[i]}} text-right"><i class="mdi mdi-checkbox-blank-circle font-10 m-r-10 "></i> {{seriesName[i]}} </th> <th class="{{seriesColor[i]}} text-end"> {{seriesName[i]}} </th>
<td *ngFor='let value of values; let i=index' class="text-mono text-right"> <td *ngFor='let value of values; let i=index' class="font-monospace text-end">
<span *ngIf="value; else elseBlock" class="pr-1">{{value}}</span> <span *ngIf="value; else elseBlock" class="pr-1">{{value}}</span>
<ng-template #elseBlock><span class="text-empty pr-1">{{value}}</span></ng-template> <ng-template #elseBlock><span class="text-empty pr-1">{{value}}</span></ng-template>
</td> </td>
<th class="text-mono text-right">{{seriesRowTotal[i]}}</th> <th class="font-monospace text-end">{{seriesRowTotal[i]}}</th>
</tr> </tr>
</tbody> </tbody>
<tfoot> <tfoot>
<tr> <tr>
<th class="text-right">Total</th> <th class="text-end">Total</th>
<th *ngFor='let value of seriesColTotal; let i=index' class="text-mono text-right"> <th *ngFor='let value of seriesColTotal; let i=index' class="font-monospace text-end">
<span *ngIf="value; else elseBlock" class="pr-1">{{value}}</span> <span *ngIf="value; else elseBlock" class="pr-1">{{value}}</span>
<ng-template #elseBlock><span class="text-empty pr-1">{{value}}</span></ng-template> <ng-template #elseBlock><span class="text-empty pr-1">{{value}}</span></ng-template>
</th> </th>
<th class="text-mono text-right">{{grandTotal}}</th> <th class="font-monospace text-end">{{grandTotal}}</th>
</tr> </tr>
</tfoot> </tfoot>
</table> </table>
@@ -1,20 +1,26 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit, OnDestroy } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatCardModule } from '@angular/material/card'; import { MatCardModule } from '@angular/material/card';
import { ChartistModule, Configuration } from 'ng-chartist'; import { ChartistModule, Configuration } from 'ng-chartist';
import { BackendService } from 'src/app/core/services'; import { Observable, Subscription } from 'rxjs';
import { ReduceRow } from 'src/app/core/models';
import { BackendService, JumpsService } from 'src/app/core/services';
import { chartBar, JumpByDate, ReduceRow } from 'src/app/core/models';
declare var require: any; declare var require: any;
const data= require('./data.json'); const data= require('./data.json');
@Component({ @Component({
standalone: true, standalone: true,
imports: [MatCardModule, ChartistModule], imports: [CommonModule, MatCardModule, ChartistModule],
selector: 'huapp-jumps-by-month', selector: 'huapp-jumps-by-month',
templateUrl: './jumps-by-month.component.html' templateUrl: './jumps-by-month.component.html'
}) })
export class JumpsByMonthComponent implements OnInit { export class JumpsByMonthComponent implements OnInit, OnDestroy {
private _jumpByDate: Subscription = new Subscription();
jumpByDate!: Array<JumpByDate>;
jumpByDateCount = 0;
rows: Object[] = [] as Array<Object>; rows: Object[] = [] as Array<Object>;
min: number = 0; min: number = 0;
max: number = 0; max: number = 0;
@@ -25,88 +31,53 @@ export class JumpsByMonthComponent implements OnInit {
seriesColTotal: number[] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; seriesColTotal: number[] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
seriesName: String[] = []; // ["2018", "2019", "2020", "2021", "2022", "2023"]; seriesName: String[] = []; // ["2018", "2019", "2020", "2021", "2022", "2023"];
seriesColor: String[] = this._dataService.getChartColors(); seriesColor: String[] = this._dataService.getChartColors();
barChartJumps: Configuration = { barChartJumps: Configuration = chartBar;
type: 'Bar',
data: { constructor(
"labels": [], private jumpsService: JumpsService,
"series": [] private _dataService: BackendService
}, ) { }
options: {
seriesBarDistance: 5,
high: 70,
axisX: {
showGrid: false,
offset: 20
},
axisY: {
showGrid: true,
offset: 40
},
height: 300
},
responsiveOptions: [
['screen and (min-width: 1024px)', {
axisX: {
labelInterpolationFnc: function(value: number, index: number): string {
return index % 1 === 0 ? `${value}` : '';
}
}
}],
['screen and (min-width: 641px) and (max-width: 1024px)', {
seriesBarDistance: 10,
axisY: {
offset: 30
},
axisX: {
labelInterpolationFnc: function(value: any, index: number): string {
return index % 1 === 0 ? `${value[0]}` : '';
}
}
}],
['screen and (max-width: 640px)', {
seriesBarDistance: 5,
axisY: {
offset: 20
},
axisX: {
labelInterpolationFnc: function(value: any, index: number): string {
return index % 1 === 0 ? `${value[0]}` : '';
}
}
}]
]
};
constructor(private _dataService: BackendService) { }
ngOnInit() { ngOnInit() {
return this._dataService this._loadJumpByDate();
.getJumpsByDate(2) }
.subscribe((res) => {
//console.log(res["rows"]); ngOnDestroy() {
this.rows = res["rows"] this._jumpByDate.unsubscribe();
this.rows.forEach((row: ReduceRow) => { }
let year = row.key[0].toString();
let month = row.key[1]; private _loadJumpByDate() {
let values: Array<number> = [];
this.seriesHeader.forEach(() => {
values.push(0);
});
const jumps$: Observable<Array<JumpByDate>> = this.jumpsService.getAllByDate();
this._jumpByDate = jumps$.subscribe((aggregate: Array<JumpByDate>) => {
this.jumpByDate = aggregate;
this.jumpByDateCount = aggregate.length;
console.log(this.jumpByDate);
console.log(this.jumpByDateCount);
this.jumpByDate.forEach((row) => {
let year = row._id.year.toString();
let month = row._id.month;
if (this.seriesName.indexOf(year) < 0) { if (this.seriesName.indexOf(year) < 0) {
this.seriesName.push(year); this.seriesName.push(year);
if (row.key[0] < this.min || this.min == 0) { if (row._id.year < this.min || this.min == 0) {
this.min = row.key[0]; this.min = row._id.year;
} }
if (row.key[0] > this.max) { if (row._id.year > this.max) {
this.max = row.key[0]; this.max = row._id.year;
} }
this.seriesRow.push([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); this.seriesRow.push([...values]);
} }
this.seriesRow[(this.seriesRow.length-1)][(month-1)] = row.value; this.seriesRow[(this.seriesRow.length-1)][(month-1)] = row.count;
this.seriesColTotal[(month-1)] += row.value; this.seriesColTotal[(month-1)] += row.count;
//console.log(row.key, row.value);
}); });
this.seriesRow.forEach((row: number[]) => { this.seriesRow.forEach((row: number[]) => {
const total = row.reduce((partialSum, a) => partialSum + a, 0); const total = row.reduce((partialSum, a) => partialSum + a, 0);
this.seriesRowTotal.push(total); this.seriesRowTotal.push(total);
}); });
console.log(this.seriesColTotal);
this.grandTotal = this.seriesColTotal.reduce((partialSum, a) => partialSum + a, 0); this.grandTotal = this.seriesColTotal.reduce((partialSum, a) => partialSum + a, 0);
//console.log(this.seriesRow, this.seriesName);
this.barChartJumps = { this.barChartJumps = {
type: 'Bar', type: 'Bar',
data: { data: {
@@ -158,7 +129,6 @@ export class JumpsByMonthComponent implements OnInit {
}] }]
] ]
}; };
return true;
}); });
} }
} }
+17 -4
View File
@@ -6,15 +6,28 @@
<div *appShowAuthed="false"> <div *appShowAuthed="false">
Not connected Not connected
</div> </div>
<div> <div class="row">
<huapp-aeronefs></huapp-aeronefs> <div class="col-md-8 col-sm-12">
<huapp-jumps-by-month></huapp-jumps-by-month>
</div> </div>
<div> <div class="col-md-4 col-sm-12">
<huapp-drop-zones></huapp-drop-zones> <huapp-drop-zones></huapp-drop-zones>
</div> </div>
<div> </div>
<div class="row mt-sm-2 mt-lg-3">
<div class="col-lg-3 col-md-4 col-sm-6 col-xs-12">
<huapp-canopy-sizes></huapp-canopy-sizes>
</div>
<div class="col-lg-3 col-md-4 col-sm-6 col-xs-12">
<huapp-canopy-models></huapp-canopy-models> <huapp-canopy-models></huapp-canopy-models>
</div> </div>
<div class="col-lg-6 col-md-4 col-sm-6 col-xs-12">
<huapp-aeronefs-bar></huapp-aeronefs-bar>
<!--
<huapp-aeronefs></huapp-aeronefs>
-->
</div>
</div>
<!-- <!--
<div fxLayout="row wrap"> <div fxLayout="row wrap">
<div fxFlex.gt-lg="66" fxFlex.gt-md="66" fxFlex.gt-sm="100" fxFlex.gt-xs="100" fxFlex="100"> <div fxFlex.gt-lg="66" fxFlex.gt-md="66" fxFlex.gt-sm="100" fxFlex.gt-xs="100" fxFlex="100">
+51 -38
View File
@@ -5,18 +5,19 @@ import { ActivatedRoute, Data, Router } from '@angular/router';
import { Observable, Observer, Subscription } from 'rxjs'; import { Observable, Observer, Subscription } from 'rxjs';
import { take } from 'rxjs/operators'; import { take } from 'rxjs/operators';
import { User, Errors, Aeronef, AeronefByImat, AeronefList, Canopy, CanopyBySize, DropZone, DropZoneByOaci } from 'src/app/core/models'; import { User, Errors, Aeronef, AeronefByImat, Canopy, CanopyModelBySize, DropZone, DropZoneByYear } from 'src/app/core/models';
import { AeronefsService, CanopiesService, DropZonesService, UserService } from 'src/app/core/services'; import { AeronefsService, CanopiesService, DropZonesService, UserService } from 'src/app/core/services';
import { ShowAuthedDirective } from 'src/app/components/shared/show-authed.directive'; import { ShowAuthedDirective } from 'src/app/components/shared/show-authed.directive';
import { AeronefsComponent, DropZonesComponent, CanopyModelsComponent } from './dashboard-components'; import { AeronefsBarComponent, DropZonesComponent, CanopyModelsComponent, CanopySizesComponent, JumpsByMonthComponent } from './dashboard-components';
//import { JumpsByMonthComponent, AeronefsComponent, AeronefsBarComponent, DropZonesComponent, DropZonesBarComponent, CanopySizesComponent, CanopyModelsComponent} from './dashboard-components'; //import { JumpsByMonthComponent, AeronefsComponent, AeronefsBarComponent, DropZonesComponent, DropZonesBarComponent, CanopySizesComponent, CanopyModelsComponent} from './dashboard-components';
@Component({ @Component({
standalone: true, standalone: true,
imports: [ imports: [
ShowAuthedDirective,
AeronefsBarComponent, DropZonesComponent, CanopyModelsComponent, CanopySizesComponent, JumpsByMonthComponent
//AeronefsComponent, AeronefsBarComponent, DropZonesComponent, DropZonesBarComponent, //AeronefsComponent, AeronefsBarComponent, DropZonesComponent, DropZonesBarComponent,
//CanopySizesComponent, CanopyModelsComponent, JumpsByMonthComponent, //CanopySizesComponent, CanopyModelsComponent, JumpsByMonthComponent,
AeronefsComponent, DropZonesComponent, CanopyModelsComponent, ShowAuthedDirective
], ],
selector: 'huapp-home', selector: 'huapp-home',
templateUrl: './home.component.html', templateUrl: './home.component.html',
@@ -32,13 +33,15 @@ export class HomeComponent implements OnInit, OnDestroy {
errors!: Errors; errors!: Errors;
isAuthenticated = false; isAuthenticated = false;
canModify = false; canModify = false;
aeronefAggregate!: Array<AeronefByImat> aeronefAggregate!: Array<AeronefByImat>
aeronefs!: Array<Aeronef>; aeronefs!: Array<Aeronef>;
aeronefsCount = 0; aeronefsCount = 0;
canopyAggregate!: Array<CanopyBySize> canopyAggregate!: Array<CanopyModelBySize>
canopies!: Array<Canopy>; canopies!: Array<Canopy>;
canopiesCount = 0; canopiesCount = 0;
dropzoneAggregate!: Array<DropZoneByOaci> //dropzoneAggregate!: Array<DropZoneByOaci>
dropzoneAggregate!: Array<DropZoneByYear>
dropzones!: Array<DropZone>; dropzones!: Array<DropZone>;
dropzonesCount = 0; dropzonesCount = 0;
@@ -46,10 +49,10 @@ export class HomeComponent implements OnInit, OnDestroy {
private route: ActivatedRoute, private route: ActivatedRoute,
private router: Router, private router: Router,
private titleService: Title, private titleService: Title,
private userService: UserService,
private aeronefsService: AeronefsService, private aeronefsService: AeronefsService,
private canopiesService: CanopiesService, private canopiesService: CanopiesService,
private dropzonesService: DropZonesService, private dropzonesService: DropZonesService
private userService: UserService
) { ) {
this._resetErrors(); this._resetErrors();
} }
@@ -64,51 +67,61 @@ export class HomeComponent implements OnInit, OnDestroy {
this.router.navigateByUrl('/login'); this.router.navigateByUrl('/login');
return; return;
} }
const currentUser$: Observable<User> = this.userService.currentUser.pipe(take(1)); const currentUser$: Observable<User> = this.userService.currentUser;
this._currentUser = currentUser$.subscribe((userData: User) => { this._currentUser = currentUser$.subscribe((userData: User) => {
this.canModify = userData.role === 'Admin'; this.canModify = userData.role === 'Admin';
}); });
}); });
this.loadAeronefs(); /*
this.loadCanopies(); this._loadAeronefs();
this.loadDropzones(); this._loadCanopies();
} this._loadDropzones();
*/
loadAeronefs() {
const aeronefs$: Observable<Array<AeronefByImat>> = this.aeronefsService.getAllByImat();
this._aeronefs = aeronefs$.subscribe((aggregate: Array<AeronefByImat>) => {
this.aeronefAggregate = aggregate;
this.aeronefsCount = aggregate.length;
console.log(this.aeronefs);
console.log(this.aeronefsCount);
});
}
loadCanopies() {
const canopies$: Observable<Array<CanopyBySize>> = this.canopiesService.getAllBySize();
this._canopies = canopies$.subscribe((aggregate: Array<CanopyBySize>) => {
this.canopyAggregate = aggregate;
this.canopiesCount = aggregate.length;
// console.log(this.canopies);
// console.log(this.canopiesCount);
});
}
loadDropzones() {
const dropzones$: Observable<Array<DropZoneByOaci>> = this.dropzonesService.getAllByOaci();
this._dropzones = dropzones$.subscribe((aggregate: Array<DropZoneByOaci>) => {
this.dropzoneAggregate = aggregate;
this.dropzonesCount = aggregate.length;
// console.log(this.dropzones);
// console.log(this.dropzonesCount);
});
} }
ngOnDestroy() { ngOnDestroy() {
this._currentUser.unsubscribe();
/*
this._aeronefs.unsubscribe(); this._aeronefs.unsubscribe();
this._canopies.unsubscribe(); this._canopies.unsubscribe();
this._dropzones.unsubscribe(); this._dropzones.unsubscribe();
*/
} }
private _resetErrors(): void { private _resetErrors(): void {
this.errors = { errors: {} }; this.errors = { errors: {} };
} }
private _loadAeronefs(): void {
const aeronefs$: Observable<Array<AeronefByImat>> = this.aeronefsService.getAllByImat();
this._aeronefs = aeronefs$.subscribe((aggregate: Array<AeronefByImat>) => {
this.aeronefAggregate = aggregate;
this.aeronefsCount = aggregate.length;
console.log(this.aeronefAggregate);
console.log(this.aeronefsCount);
});
}
private _loadCanopies(): void {
const canopies$: Observable<Array<CanopyModelBySize>> = this.canopiesService.getAllModelBySize();
this._canopies = canopies$.subscribe((aggregate: Array<CanopyModelBySize>) => {
this.canopyAggregate = aggregate;
this.canopiesCount = aggregate.length;
console.log(this.canopyAggregate);
console.log(this.canopiesCount);
});
}
private _loadDropzones(): void {
//const dropzones$: Observable<Array<DropZoneByOaci>> = this.dropzonesService.getAllByOaci();
//this._dropzones = dropzones$.subscribe((aggregate: Array<DropZoneByOaci>) => {
const dropzones$: Observable<Array<DropZoneByYear>> = this.dropzonesService.getAllByDate();
this._dropzones = dropzones$.subscribe((aggregate: Array<DropZoneByYear>) => {
this.dropzoneAggregate = aggregate;
this.dropzonesCount = aggregate.length;
console.log(this.dropzoneAggregate);
console.log(this.dropzonesCount);
});
}
} }
@@ -30,7 +30,7 @@
<!-- Numero Column --> <!-- Numero Column -->
<ng-container matColumnDef="numero"> <ng-container matColumnDef="numero">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Numero </th> <th mat-header-cell *matHeaderCellDef mat-sort-header> Numero </th>
<td class="text-right pl-3 pr-3" mat-cell *matCellDef="let element"> <td class="text-end pl-3 pr-3" mat-cell *matCellDef="let element">
<ng-container *ngIf="element.numero"><a [routerLink]="['/jump', element.slug]">{{element.numero}}</a></ng-container> <ng-container *ngIf="element.numero"><a [routerLink]="['/jump', element.slug]">{{element.numero}}</a></ng-container>
<ng-container *ngIf="!element.numero"><ngx-skeleton-loader [theme]="{width: '30px', height: '13px', marginBottom: '0px'}"></ngx-skeleton-loader></ng-container> <ng-container *ngIf="!element.numero"><ngx-skeleton-loader [theme]="{width: '30px', height: '13px', marginBottom: '0px'}"></ngx-skeleton-loader></ng-container>
</td> </td>
@@ -94,7 +94,7 @@
<!-- Taille Column --> <!-- Taille Column -->
<ng-container matColumnDef="taille"> <ng-container matColumnDef="taille">
<th class="pl-3" mat-header-cell *matHeaderCellDef> Taille </th> <th class="pl-3" mat-header-cell *matHeaderCellDef> Taille </th>
<td class="text-nowrap text-right pl-3 pr-3" mat-cell *matCellDef="let element"> <td class="text-nowrap text-end pl-3 pr-3" mat-cell *matCellDef="let element">
<ng-container *ngIf="element.taille">{{element.taille}}</ng-container> <ng-container *ngIf="element.taille">{{element.taille}}</ng-container>
<ng-container *ngIf="!element.numero"><ngx-skeleton-loader [theme]="{width: '30px', height: '13px', marginBottom: '0px'}"></ngx-skeleton-loader></ng-container> <ng-container *ngIf="!element.numero"><ngx-skeleton-loader [theme]="{width: '30px', height: '13px', marginBottom: '0px'}"></ngx-skeleton-loader></ng-container>
</td> </td>
@@ -118,7 +118,7 @@
<!-- Participants Column --> <!-- Participants Column -->
<ng-container matColumnDef="participants"> <ng-container matColumnDef="participants">
<th class="pl-3" mat-header-cell *matHeaderCellDef> Participants </th> <th class="pl-3" mat-header-cell *matHeaderCellDef> Participants </th>
<td class="text-right pl-3 pr-3" mat-cell *matCellDef="let element"> <td class="text-end pl-3 pr-3" mat-cell *matCellDef="let element">
<ng-container *ngIf="element.participants">{{element.participants}}</ng-container> <ng-container *ngIf="element.participants">{{element.participants}}</ng-container>
<ng-container *ngIf="!element.numero"><ngx-skeleton-loader [theme]="{width: '30px', height: '13px', marginBottom: '0px'}"></ngx-skeleton-loader></ng-container> <ng-container *ngIf="!element.numero"><ngx-skeleton-loader [theme]="{width: '30px', height: '13px', marginBottom: '0px'}"></ngx-skeleton-loader></ng-container>
</td> </td>
@@ -1,7 +1,54 @@
<huapp-layout-header></huapp-layout-header> <mat-toolbar color="primary" class="topbar">
<div class="navbar-header">
<a class="navbar-brand" href="index.html">
<span>
<img src="assets/images/logo-light-icon.svg" alt="homepage" class="light-logo">
</span>
<span>
<img src="assets/images/logo-light-text.svg" alt="homepage" class="light-logo">
</span>
</a>
</div>
<button mat-icon-button (click)="snav.toggle()" value="sidebarclosed">
<mat-icon fontIcon="menu"></mat-icon>
</button>
<span class="flex-spacer"></span>
<ng-container *appShowAuthed="true">
<span class="fw-light me-1">@{{ currentUser.username }}</span>
<div class="position-relative">
<button [matMenuTriggerFor]="profile" mat-icon-button>
<img [src]="currentUser.image" alt="user" class="profile-pic">
</button>
<mat-menu #profile="matMenu">
<button mat-menu-item [routerLink]="['/profile', currentUser.username]" routerLinkActive="active">
<mat-icon fontIcon="account_circle" color="primary"></mat-icon> Mon compte
</button>
<button mat-menu-item routerLink="/settings" routerLinkActive="active">
<mat-icon fontIcon="settings" color="primary"></mat-icon> Paramètres
</button>
<button mat-menu-item (click)="goToGitHub()">
<mat-icon fontIcon="code" color="primary"></mat-icon> GitHub
</button>
<button mat-menu-item>
<mat-icon fontIcon="notifications_off" color="primary"></mat-icon> Désactiver les notifications
</button>
<hr class="my-0" />
<button mat-menu-item (click)="logout()">
<mat-icon fontIcon="logout" color="warn"></mat-icon> Se déconnecter
</button>
</mat-menu>
</div>
</ng-container>
<ng-container *appShowAuthed="false">
<span>
<button mat-button routerLink="/login" routerLinkActive="active">Se connecter</button>
<button mat-button routerLink="/register" routerLinkActive="active">Créer un compte</button>
</span>
</ng-container>
</mat-toolbar>
<mat-sidenav-container class="app-sidenav-container" [style.marginTop.px]="mobileQuery.matches ? 0 : 0"> <mat-sidenav-container class="app-sidenav-container" [style.marginTop.px]="mobileQuery.matches ? 0 : 0">
<mat-sidenav #snav id="snav" class="dark-sidebar pl-xs" [mode]="mobileQuery.matches ? 'side' : 'over'" fixedTopGap="0" [opened]="mobileQuery.matches" [disableClose]="mobileQuery.matches"> <mat-sidenav #snav id="snav" class="dark-sidebar pl-xs" [mode]="mobileQuery.matches ? 'side' : 'over'" fixedTopGap="0" [opened]="mobileQuery.matches" [disableClose]="mobileQuery.matches">
<div *appShowAuthed="true"> <ng-container *appShowAuthed="true">
<div class="user-profile" style="background-image: url('{{ currentUser.bg_image }}');"> <div class="user-profile" style="background-image: url('{{ currentUser.bg_image }}');">
<div class="profile-img"> <img [src]="currentUser.image" alt="user"> </div> <div class="profile-img"> <img [src]="currentUser.image" alt="user"> </div>
<div class="profile-text"> <div class="profile-text">
@@ -48,8 +95,8 @@
</mat-list-item> </mat-list-item>
</div> </div>
</mat-nav-list> </mat-nav-list>
</div> </ng-container>
<div *appShowAuthed="false"> <ng-container *appShowAuthed="false">
<div class="user-profile"> <div class="user-profile">
<!-- <div class="profile-img"> <img src="/assets/images/users/user.jpg" alt="user"> </div> --> <!-- <div class="profile-img"> <img src="/assets/images/users/user.jpg" alt="user"> </div> -->
</div> </div>
@@ -78,7 +125,7 @@
</mat-list-item> </mat-list-item>
</div> </div>
</mat-nav-list> </mat-nav-list>
</div> </ng-container>
<huapp-layout-footer></huapp-layout-footer> <huapp-layout-footer></huapp-layout-footer>
</mat-sidenav> </mat-sidenav>
<mat-sidenav-content class="page-wrapper"> <mat-sidenav-content class="page-wrapper">
@@ -20,10 +20,12 @@ import { UserService } from 'src/app/core/services';
] ]
}) })
export class HeaderComponent implements OnInit, OnDestroy { export class HeaderComponent implements OnInit, OnDestroy {
private _currentUser: Subscription = new Subscription(); private _currentUser: Subscription = new Subscription();
private _isAuthenticated: Subscription = new Subscription(); private _isAuthenticated: Subscription = new Subscription();
private isAuthenticated = false; private isAuthenticated = false;
currentUser: User = {} as User; currentUser: User = {} as User;
constructor( constructor(
private router: Router, private router: Router,
private userService: UserService private userService: UserService
+1
View File
@@ -19,6 +19,7 @@ export interface AeronefByImat {
export interface AeronefByYear { export interface AeronefByYear {
_id: { _id: {
aeronef: string, aeronef: string,
imat: string,
year: number year: number
}, },
count: number count: number
+21 -21
View File
@@ -1,11 +1,16 @@
export interface WeightSize { export interface CalcResult {
weight: number; weight: number;
active?: string; jumps: number;
ranges: Range[]; minSize: number;
minSize11: number;
minSize21: number;
error?: string;
} }
export interface InputParams {
export interface WeightSizes { jumps: number;
data: WeightSize[]; weight: number;
gear: number;
current: number;
} }
export interface Range { export interface Range {
@@ -18,6 +23,16 @@ export interface Range {
value: number; value: number;
} }
export interface WeightSize {
weight: number;
active?: string;
ranges: Range[];
}
export interface WeightSizes {
data: WeightSize[];
}
export const weightSizes: WeightSize[] = [ export const weightSizes: WeightSize[] = [
{active: '', weight: 60, ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 175}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 161}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 147}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 133}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 124}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 115}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 107}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 97}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 89}] }, {active: '', weight: 60, ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 175}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 161}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 147}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 133}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 124}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 115}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 107}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 97}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 89}] },
{active: '', weight: 61, ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 178}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 163}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 149}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 135}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 126}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 116}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 108}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 98}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 90}] }, {active: '', weight: 61, ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 178}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 163}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 149}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 135}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 126}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 116}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 108}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 98}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 90}] },
@@ -71,18 +86,3 @@ export const weightSizes: WeightSize[] = [
{active: '', weight: 109, ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 298}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 274}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 247}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 219}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 199}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 179}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 161}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 138}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 120}] }, {active: '', weight: 109, ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 298}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 274}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 247}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 219}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 199}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 179}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 161}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 138}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 120}] },
{active: '', weight: 110, ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 300}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 276}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 249}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 220}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 201}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 180}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 162}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 138}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 120}] } {active: '', weight: 110, ranges: [{num: 1, active: '', name: 'range_1', label: '0 à 99', start: 0, end: 99, value: 300}, {num: 2, active: '', name: 'range_2', label: '100 à 249', start: 100, end: 249, value: 276}, {num: 3, active: '', name: 'range_3', label: '250 à 399', start: 250, end: 399, value: 249}, {num: 4, active: '', name: 'range_4', label: '400 à 599', start: 400, end: 599, value: 220}, {num: 5, active: '', name: 'range_5', label: '600 à 799', start: 600, end: 799, value: 201}, {num: 6, active: '', name: 'range_6', label: '800 à 999', start: 800, end: 999, value: 180}, {num: 7, active: '', name: 'range_7', label: '1000 à 1399', start: 1000, end: 1399, value: 162}, {num: 8, active: '', name: 'range_8', label: '1400 à 1799', start: 1400, end: 1799, value: 138}, {num: 9, active: '', name: 'range_9', label: '1800 à 2000', start: 1800, end: 2000, value: 120}] }
] ]
export interface CalcResult {
weight: number;
jumps: number;
minSize: number;
minSize11: number;
minSize21: number;
error?: string;
}
export interface InputParams {
jumps: number;
weight: number;
gear: number;
current: number;
}
+19 -3
View File
@@ -1,16 +1,32 @@
import { Profile } from './profile.model'; import { Profile } from './profile.model';
export interface Canopy { export interface Canopy {
canopy: string; voile: string;
taille: number; taille: number;
author: Profile; author: Profile;
createdAt: string; createdAt: string;
updatedAt: string; updatedAt: string;
} }
export interface CanopyModelBySize {
_id: {
voile: string,
taille: number
},
count: number
}
export interface CanopyModelByYear {
_id: {
voile: string,
taille: number,
year: number
},
count: number
}
export interface CanopyBySize { export interface CanopyBySize {
_id: { _id: {
canopy: string,
taille: number taille: number
}, },
count: number count: number
@@ -18,7 +34,7 @@ export interface CanopyBySize {
export interface CanopyByYear { export interface CanopyByYear {
_id: { _id: {
canopy: string, taille: number,
year: number year: number
}, },
count: number count: number
+80
View File
@@ -0,0 +1,80 @@
import { Configuration } from 'ng-chartist';
export const chartPieDonute: Configuration = {
type: 'Pie',
data: {
"labels": [],
"series": []
},
options: {
donut: true,
height: 260,
donutWidth: 46,
startAngle: 270,
showLabel: true
}
};
export const chartBar: Configuration = {
type: 'Bar',
data: {
"labels": [],
"series": []
},
options: {},
responsiveOptions: []
};
/*
export const chartBar: Configuration = {
type: 'Bar',
data: {
"labels": [],
"series": []
},
options: {
seriesBarDistance: 5,
high: 170,
axisX: {
showGrid: false,
offset: 20
},
axisY: {
showGrid: true,
offset: 40
},
height: 207
},
responsiveOptions: [
['screen and (min-width: 1024px)', {
axisX: {
labelInterpolationFnc: function(value: number, index: number): string {
return index % 1 === 0 ? `${value}` : '';
}
}
}],
['screen and (min-width: 641px) and (max-width: 1024px)', {
seriesBarDistance: 10,
axisY: {
offset: 30
},
axisX: {
labelInterpolationFnc: function(value: any, index: number): string {
return index % 1 === 0 ? `${value[2]}${value[3]}` : '';
}
}
}],
['screen and (max-width: 640px)', {
seriesBarDistance: 5,
axisY: {
offset: 20
},
axisX: {
labelInterpolationFnc: function(value: any, index: number): string {
return index % 1 === 0 ? `${value[2]}${value[3]}` : '';
}
}
}]
]
};
*/
+1
View File
@@ -19,6 +19,7 @@ export interface DropZoneByOaci {
export interface DropZoneByYear { export interface DropZoneByYear {
_id: { _id: {
lieu: string, lieu: string,
oaci: string,
year: number year: number
}, },
count: number count: number
+1
View File
@@ -5,6 +5,7 @@ export * from './application-list-config.model';
export * from './calculator.model'; export * from './calculator.model';
export * from './canopy.model'; export * from './canopy.model';
export * from './canopysize.model'; export * from './canopysize.model';
export * from './chart.model';
export * from './reducerow.model'; export * from './reducerow.model';
export * from './dropzone.model'; export * from './dropzone.model';
export * from './errors.model'; export * from './errors.model';
+8
View File
@@ -25,6 +25,14 @@ export interface Jump {
updatedAt: string; updatedAt: string;
} }
export interface JumpByDate {
_id: {
month: number,
year: number
},
count: number
}
export interface JumpDoc { export interface JumpDoc {
_id?: string; _id?: string;
_rev?: string; _rev?: string;
+6 -2
View File
@@ -1,10 +1,9 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { ApiService } from './api.service'; import { ApiService } from './api.service';
import { Aeronef, AeronefByImat, AeronefList, JumpList, JumpListConfig, JumpListFilters } from 'src/app/core/models'; import { Aeronef, AeronefByImat, AeronefByYear } from 'src/app/core/models';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AeronefsService { export class AeronefsService {
@@ -27,4 +26,9 @@ export class AeronefsService {
*/ */
} }
getAllByDate(): Observable<Array<AeronefByYear>> {
return this.apiService.get('/aeronefs/allByDate')
.pipe(map(data => data.aeronefs));
}
} }
+17 -3
View File
@@ -1,10 +1,9 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { ApiService } from './api.service'; import { ApiService } from './api.service';
import { Canopy, CanopyBySize ,JumpList, JumpListConfig, JumpListFilters } from 'src/app/core/models'; import { Canopy, CanopyBySize, CanopyByYear, CanopyModelBySize, CanopyModelByYear } from 'src/app/core/models';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class CanopiesService { export class CanopiesService {
@@ -13,7 +12,22 @@ export class CanopiesService {
) { } ) { }
getAllBySize(): Observable<Array<CanopyBySize>> { getAllBySize(): Observable<Array<CanopyBySize>> {
return this.apiService.get('/canopies') return this.apiService.get('/canopies/allBySize')
.pipe(map(data => data.canopies));
}
getAllByYear(): Observable<Array<CanopyByYear>> {
return this.apiService.get('/canopies/allByYear')
.pipe(map(data => data.canopies));
}
getAllModelBySize(): Observable<Array<CanopyModelBySize>> {
return this.apiService.get('/canopies/allModelBySize')
.pipe(map(data => data.canopies));
}
getAllModelByYear(): Observable<Array<CanopyModelByYear>> {
return this.apiService.get('/canopies/allModelByYear')
.pipe(map(data => data.canopies)); .pipe(map(data => data.canopies));
} }
+6 -1
View File
@@ -4,7 +4,7 @@ import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { ApiService } from './api.service'; import { ApiService } from './api.service';
import { DropZone, DropZoneByOaci, JumpList, JumpListConfig, JumpListFilters } from 'src/app/core/models'; import { DropZone, DropZoneByOaci, DropZoneByYear, JumpListConfig, JumpListFilters } from 'src/app/core/models';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class DropZonesService { export class DropZonesService {
@@ -17,4 +17,9 @@ export class DropZonesService {
.pipe(map(data => data.dropzones)); .pipe(map(data => data.dropzones));
} }
getAllByDate(): Observable<Array<DropZoneByYear>> {
return this.apiService.get('/dropzones/allByDate')
.pipe(map(data => data.dropzones));
}
} }
+6 -1
View File
@@ -4,7 +4,7 @@ import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { ApiService } from './api.service'; import { ApiService } from './api.service';
import { Jump, JumpList, JumpListConfig, JumpListFilters } from 'src/app/core/models'; import { Jump, JumpByDate, JumpList, JumpListConfig, JumpListFilters } from 'src/app/core/models';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class JumpsService { export class JumpsService {
@@ -50,6 +50,11 @@ export class JumpsService {
.pipe(map(data => data.jumps)); .pipe(map(data => data.jumps));
} }
getAllByDate(): Observable<Array<JumpByDate>> {
return this.apiService.get('/jumps/allByDate')
.pipe(map(data => data.jumps));
}
create(jump: Jump): Observable<Jump> { create(jump: Jump): Observable<Jump> {
return this.apiService.post('/jumps/', { jump: jump }) return this.apiService.post('/jumps/', { jump: jump })
.pipe(map(data => data.jump)); .pipe(map(data => data.jump));
+2 -2
View File
@@ -8,12 +8,12 @@
<link rel="icon" type="image/x-icon" href="favicon.ico"> <link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="preconnect" href="https://fonts.gstatic.com"> <link rel="preconnect" href="https://fonts.gstatic.com">
<!-- <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inconsolata&family=Poppins:wght@300;400;500;600;700&family=Merriweather:wght@400;700&display=swap"> --> <!-- <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inconsolata&family=Poppins:wght@300;400;500;600;700&family=Merriweather:wght@400;700&display=swap"> -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inconsolata&family=Barlow:wght@300;400;500;600;700&family=Merriweather:wght@400;700&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inconsolata:wght@200;300;500&family=Barlow:wght@300;400;500;600;700&family=Merriweather:wght@400;700&display=swap">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="manifest" href="manifest.webmanifest" /> <link rel="manifest" href="manifest.webmanifest" />
<meta name="theme-color" content="#a7d4c4" /> <meta name="theme-color" content="#a7d4c4" />
</head> </head>
<body class="mat-typography"> <body class="mat-app-background mat-typography">
<huapp-root></huapp-root> <huapp-root></huapp-root>
</body> </body>
</html> </html>
+99 -7
View File
@@ -84,16 +84,13 @@ a.link {
max-width: 100%; max-width: 100%;
height: auto; height: auto;
} }
.img-rounded {
border-radius: $radius;
}
.rounded {
border-radius: $radius;
}
.shadow-none { .shadow-none {
box-shadow: none !important; box-shadow: none !important;
} }
.font-monospace.fw-lighter,
.font-monospace .fw-lighter {
font-weight: 200 !important;
}
huapp-full-layout .mat-mdc-form-field, huapp-full-layout .mat-mdc-form-field,
huapp-full-layout .mdc-text-field--filled .mdc-floating-label { huapp-full-layout .mdc-text-field--filled .mdc-floating-label {
font-size: initial; font-size: initial;
@@ -109,6 +106,98 @@ huapp-full-layout .mdc-text-field--filled .mdc-floating-label {
} }
} }
/****************
* Text Colors *
****************/
.text-primary {
color: $primary !important;
}
.text-secondary,
.text-warn {
color: $secondary !important;
}
.text-accent {
color: $accent !important;
}
.text-success {
color: $success !important;
}
.text-info {
color: $info !important;
}
.text-warning {
color: $warning !important;
}
.text-danger {
color: $danger !important;
}
.text-error {
color: $error !important;
}
.text-white {
color: $white !important;
}
.text-red {
color: $red !important;
}
.text-red-dark {
color: $red-dark !important;
}
.text-orange {
color: $orange !important;
}
.text-yellow {
color: $yellow !important;
}
.text-megna {
color: $megna !important;
}
.text-green {
color: $green !important;
}
.text-teal {
color: $teal !important;
}
.text-turquoise {
color: $turquoise !important;
}
.text-cyan {
color: $cyan !important;
}
.text-blue {
color: $blue !important;
}
.text-navy {
color: $navy !important;
}
.text-pink {
color: $pink !important;
}
.text-magenta {
color: $magenta !important;
}
.text-purple {
color: $purple !important;
}
.text-purple-dark {
color: $purple-dark !important;
}
.text-raspberry {
color: $raspberry !important;
}
.text-grey {
color: $grey !important;
}
.text-muted {
color: $muted !important;
}
.text-extra-muted {
color: $extra-muted !important;
}
.text-empty {
color: $empty !important;
}
/********************** /**********************
* Background Colors * * Background Colors *
**********************/ **********************/
@@ -197,6 +286,9 @@ huapp-full-layout .mdc-text-field--filled .mdc-floating-label {
.bg-extra-muted { .bg-extra-muted {
background-color: $extra-muted !important; background-color: $extra-muted !important;
} }
.bg-empty {
background-color: $empty !important;
}
.bg-crystal, .bg-crystal,
.bg-crystal .mdc-text-field--filled:not(.mdc-text-field--disabled) { .bg-crystal .mdc-text-field--filled:not(.mdc-text-field--disabled) {
background-color: transparent !important; background-color: transparent !important;
+1 -1
View File
@@ -160,7 +160,7 @@ $chart-color-r: #ffffff;
stroke:$chart-color-q; stroke:$chart-color-q;
} }
.ct-series-r .ct-bar { .ct-series-r .ct-bar {
stroke:$chart-color-r stroke:$chart-color-r;
} }
} }
+3
View File
@@ -30,6 +30,7 @@ File: scss
@import "bootstrap/scss/helpers"; @import "bootstrap/scss/helpers";
@import "bootstrap/scss/utilities/api"; @import "bootstrap/scss/utilities/api";
//@import "bootstrap/scss/tables"; //@import "bootstrap/scss/tables";
@import "bootstrap/scss/type";
@import "bootstrap/scss/pagination"; @import "bootstrap/scss/pagination";
@import "bootstrap/scss/alert"; @import "bootstrap/scss/alert";
@@ -119,6 +120,8 @@ $background: map.get($headup_app-theme, background);
@include mat.all-component-themes($headup_app-theme); @include mat.all-component-themes($headup_app-theme);
@include components.theme($headup_app-theme, $custom-typography, $headup_app-variants); @include components.theme($headup_app-theme, $custom-typography, $headup_app-variants);
@import "chartist/dist/index";
@import 'spinner'; @import 'spinner';
@import 'header'; @import 'header';
@import 'sidebar'; @import 'sidebar';
+4
View File
@@ -9,6 +9,8 @@ File: scss
$bodyfont: 'Barlow', "Helvetica Neue", sans-serif; $bodyfont: 'Barlow', "Helvetica Neue", sans-serif;
$headingfont: 'Barlow', "Helvetica Neue", sans-serif; $headingfont: 'Barlow', "Helvetica Neue", sans-serif;
$font-family-monospace: 'Inconsolata', SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !default;
$font-size-base: 0.875rem;
/* Custom Theme Palettes */ /* Custom Theme Palettes */
$md-custom-primary: ( $md-custom-primary: (
@@ -130,6 +132,8 @@ $success: #16d57c;
$warning: #ffb035; $warning: #ffb035;
$info: #0dcaf0; $info: #0dcaf0;
$inverse: #292154; $inverse: #292154;
$empty: #717171;
$muted: #aaaaaa; $muted: #aaaaaa;
$extra-muted: #c4c4c4; $extra-muted: #c4c4c4;
$dark: #263238; $dark: #263238;