Mise à jours et ajout de fonctionnalités

This commit is contained in:
Julien Gautier
2023-09-13 20:48:18 +02:00
parent 747948a422
commit 1147d5f5bb
24 changed files with 478 additions and 155 deletions
+8
View File
@@ -37,6 +37,14 @@ yarn-error.log
testem.log testem.log
/typings /typings
# e2e
/e2e/*.js
/e2e/*.map
# System files # System files
.DS_Store .DS_Store
Thumbs.db Thumbs.db
**/*.copy.ts
**/*.copy.scss
**/*.copy.html
+28 -10
View File
@@ -23,10 +23,10 @@
"outputPath": "dist/headup_app", "outputPath": "dist/headup_app",
"index": "src/index.html", "index": "src/index.html",
"main": "src/main.ts", "main": "src/main.ts",
"tsConfig": "tsconfig.app.json",
"polyfills": [ "polyfills": [
"zone.js" "zone.js"
], ],
"tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss", "inlineStyleLanguage": "scss",
"assets": [ "assets": [
"src/favicon.ico", "src/favicon.ico",
@@ -36,10 +36,23 @@
"styles": [ "styles": [
"src/styles/styles.scss" "src/styles/styles.scss"
], ],
"scripts": [] "scripts": [],
"vendorChunk": true,
"extractLicenses": false,
"buildOptimizer": false,
"sourceMap": true,
"optimization": false,
"namedChunks": true
}, },
"configurations": { "configurations": {
"production": { "production": {
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [ "budgets": [
{ {
"type": "initial", "type": "initial",
@@ -51,21 +64,26 @@
"maximumWarning": "2kb", "maximumWarning": "2kb",
"maximumError": "4kb" "maximumError": "4kb"
} }
], ]
"outputHashing": "all"
}, },
"development": { "development": {
"buildOptimizer": false, "optimization": true,
"optimization": false, "sourceMap": false,
"vendorChunk": true, "namedChunks": false,
"extractLicenses": false, "extractLicenses": true,
"sourceMap": true, "vendorChunk": false,
"namedChunks": true, "buildOptimizer": true,
"fileReplacements": [ "fileReplacements": [
{ {
"replace": "src/environments/environment.ts", "replace": "src/environments/environment.ts",
"with": "src/environments/environment.development.ts" "with": "src/environments/environment.development.ts"
} }
],
"budgets": [
{
"type": "anyComponentStyle",
"maximumWarning": "6kb"
}
] ]
} }
}, },
+10 -5
View File
@@ -3,14 +3,16 @@ import { BrowserModule, Title } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { registerLocaleData } from '@angular/common'; import { registerLocaleData } from '@angular/common';
import localeFr from '@angular/common/locales/fr'; import localeFr from '@angular/common/locales/fr';
import { ChartistModule } from "ng-chartist";
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { CoreModule } from './core/core.module'; import { CoreModule } from './core/core.module';
import { AuthModule } from './components/auth/auth.module'; import { AuthModule } from './components/auth/auth.module';
import { HomeModule } from './components/home/home.module'; import { HomeModule } from './components/home/home.module';
import { SpinnerComponent, FullComponent } from './components/shared'; import { SpinnerComponent } from './components/shared';
import { FullComponent } from 'src/app/components/shared/layout';
//import { FullComponent } from 'src/app/components/shared/layout/full.component';
//import { HeaderComponent, FooterComponent, FullComponent } from 'src/app/components/shared/layout';
registerLocaleData(localeFr); registerLocaleData(localeFr);
@@ -18,11 +20,14 @@ registerLocaleData(localeFr);
declarations: [ AppComponent ], declarations: [ AppComponent ],
imports: [ imports: [
BrowserModule, BrowserModule,
CoreModule,
AuthModule,
AppRoutingModule, AppRoutingModule,
ChartistModule,
BrowserAnimationsModule, BrowserAnimationsModule,
AuthModule, CoreModule, HomeModule, SpinnerComponent,
SpinnerComponent, FullComponent FullComponent,
//HeaderComponent, FooterComponent, FullComponent,
HomeModule
], ],
providers: [ Title, { provide: LOCALE_ID, useValue: 'fr-FR' } ], providers: [ Title, { provide: LOCALE_ID, useValue: 'fr-FR' } ],
bootstrap: [ AppComponent ] bootstrap: [ AppComponent ]
@@ -1,3 +1,110 @@
<div class="calculator-page content">
<mat-card class="calculator">
<mat-card-header class="bg-warn rounded-top py-3 px-4">
<mat-card-title>Calcul de taille de voile</mat-card-title>
<mat-card-subtitle>DT48 - 13 mars 2020</mat-card-subtitle>
<span class="flex-spacer"></span>
<button mat-icon-button [matMenuTriggerFor]="menuCalculator" aria-label="Menu Calculator">
<mat-icon>more_vert</mat-icon>
</button>
<mat-menu #menuCalculator="matMenu">
<button mat-menu-item>
<mat-icon>search</mat-icon>
<span>Recherche avancée</span>
</button>
<button mat-menu-item>
<mat-icon>person_search</mat-icon>
<span>Recherche par participant</span>
</button>
<button mat-menu-item>
<mat-icon>display_settings</mat-icon>
<span>Paramètre d'affichage</span>
</button>
<button mat-menu-item disabled>
<mat-icon>upload_file</mat-icon>
<span>Import CSV</span>
</button>
</mat-menu>
</mat-card-header>
<mat-card-content class="my-4 mx-2">
<form #searchFormData="ngForm" class="inputs-form">
<mat-form-field class="bg-crystal me-3">
<mat-label>Nombre de sauts</mat-label>
<input matInput [(ngModel)]="inputs.jumps" (change)="refreshActive()" type="number" min="0" name="jumps">
</mat-form-field>
<mat-form-field class="bg-crystal me-3">
<mat-label>Poids nu</mat-label>
<input matInput [(ngModel)]="inputs.weight" (change)="refreshActive()" type="number" min="60" max="110" name="weight">
</mat-form-field>
<mat-form-field class="bg-crystal me-3">
<mat-label>Poids équipement</mat-label>
<input matInput [(ngModel)]="inputs.gear" type="number" min="0" name="gear">
</mat-form-field>
<mat-form-field class="bg-crystal me-3">
<mat-label>Taille actuelle</mat-label>
<input matInput [(ngModel)]="inputs.current" type="number" min="0" name="current" id="current" placeholder="Taille actuelle" >
</mat-form-field>
</form>
<table mat-table [dataSource]="canopy_size_table" matSort class="table table-striped table-dark table-hover mat-elevation-z2">
<!-- Numero Column -->
<ng-container matColumnDef="weight">
<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>
</ng-container>
<!-- range_ Column -->
<ng-container matColumnDef="range_1">
<th class="pl-3" mat-header-cell *matHeaderCellDef class="{{tableHeader[1].active}}"> {{tableHeader[1].name}} </th>
<td mat-cell *matCellDef="let element;" class="pl-3 text-nowrap {{element.ranges[0].active}}">{{element.ranges[0].value}}</td>
</ng-container>
<!-- range_ Column -->
<ng-container matColumnDef="range_2">
<th class="pl-3" mat-header-cell *matHeaderCellDef class="{{tableHeader[2].active}}"> {{tableHeader[2].name}} </th>
<td mat-cell *matCellDef="let element;" class="pl-3 text-nowrap {{element.ranges[1].active}}">{{element.ranges[1].value}}</td>
</ng-container>
<!-- range_ Column -->
<ng-container matColumnDef="range_3">
<th class="pl-3" mat-header-cell *matHeaderCellDef class="{{tableHeader[3].active}}"> {{tableHeader[3].name}} </th>
<td mat-cell *matCellDef="let element;" class="pl-3 text-nowrap {{element.ranges[2].active}}">{{element.ranges[2].value}}</td>
</ng-container>
<!-- range_ Column -->
<ng-container matColumnDef="range_4">
<th class="pl-3" mat-header-cell *matHeaderCellDef class="{{tableHeader[4].active}}"> {{tableHeader[4].name}} </th>
<td mat-cell *matCellDef="let element;" class="pl-3 text-nowrap {{element.ranges[3].active}}">{{element.ranges[3].value}}</td>
</ng-container>
<!-- range_ Column -->
<ng-container matColumnDef="range_5">
<th class="pl-3" mat-header-cell *matHeaderCellDef class="{{tableHeader[5].active}}"> {{tableHeader[5].name}} </th>
<td mat-cell *matCellDef="let element;" class="pl-3 text-nowrap {{element.ranges[4].active}}">{{element.ranges[4].value}}</td>
</ng-container>
<!-- range_ Column -->
<ng-container matColumnDef="range_6">
<th class="pl-3" mat-header-cell *matHeaderCellDef class="{{tableHeader[6].active}}"> {{tableHeader[6].name}} </th>
<td mat-cell *matCellDef="let element;" class="pl-3 text-nowrap {{element.ranges[5].active}}">{{element.ranges[5].value}}</td>
</ng-container>
<!-- range_ Column -->
<ng-container matColumnDef="range_7">
<th class="pl-3" mat-header-cell *matHeaderCellDef class="{{tableHeader[7].active}}"> {{tableHeader[7].name}} </th>
<td mat-cell *matCellDef="let element;" class="pl-3 text-nowrap {{element.ranges[6].active}}">{{element.ranges[6].value}}</td>
</ng-container>
<!-- range_ Column -->
<ng-container matColumnDef="range_8">
<th class="pl-3" mat-header-cell *matHeaderCellDef class="{{tableHeader[8].active}}"> {{tableHeader[8].name}} </th>
<td mat-cell *matCellDef="let element;" class="pl-3 text-nowrap {{element.ranges[7].active}}">{{element.ranges[7].value}}</td>
</ng-container>
<!-- range_ Column -->
<ng-container matColumnDef="range_9">
<th class="pl-3" mat-header-cell *matHeaderCellDef class="{{tableHeader[9].active}}"> {{tableHeader[9].name}} </th>
<td mat-cell *matCellDef="let element;" class="pl-3 text-nowrap {{element.ranges[8].active}}">{{element.ranges[8].value}}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true" class="warn"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;" class="text-middle warn {{row.active}}" id="weight_{{row.weight}}"></tr>
</table>
<div class="clearfix">
<mat-paginator [pageSize]="50" [pageSizeOptions]="[5, 10, 15, 25, 50]" showFirstLastButtons class="pull-right mb-1 mt-2"></mat-paginator>
</div>
</mat-card-content>
</mat-card>
</div>
<div class="content"> <div class="content">
<h1>{{title}}</h1> <h1>{{title}}</h1>
<div class="col-xs-12"> <div class="col-xs-12">
@@ -1,3 +1,4 @@
.calculator-page {
section { section {
display: table; display: table;
} }
@@ -24,3 +25,17 @@ section {
justify-content: center; justify-content: center;
width: 120px; width: 120px;
} }
/* Chrome, Safari, Edge, Opera */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
appearance: none;
-webkit-appearance: none;
margin: 0;
}
/* Firefox */
input[type=number] {
appearance: textfield;
-moz-appearance: textfield;
}
}
@@ -1,28 +1,111 @@
import { Component, OnInit, OnDestroy } from '@angular/core'; import { Component, Input, OnInit, OnDestroy, ViewChild } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatDividerModule } from '@angular/material/divider'; import { MatDividerModule } from '@angular/material/divider';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon'; import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatMenuModule } from '@angular/material/menu';
import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator';
import { MatSort, MatSortModule } from '@angular/material/sort';
import { MatTableDataSource, MatTableModule } from '@angular/material/table';
import { CalcResult, InputParams, Range, WeightSize, weightSizes } from 'src/app/core/models';
@Component({ @Component({
standalone: true, standalone: true,
imports: [ imports: [
MatButtonModule, MatDividerModule, MatIconModule FormsModule,
MatButtonModule, MatCardModule, MatDividerModule,
MatFormFieldModule, MatInputModule, MatIconModule, MatMenuModule,
MatPaginatorModule, MatSortModule, MatTableModule
], ],
selector: 'huapp-calculator', selector: 'huapp-calculator',
templateUrl: './calculator.component.html', styleUrls: ['./calculator.component.scss'],
styleUrls: ['./calculator.component.scss'] templateUrl: './calculator.component.html'
}) })
export class CalculatorComponent implements OnInit, OnDestroy { export class CalculatorComponent implements OnInit, OnDestroy {
title = 'Taille de voile - DT48'; title = 'Calcul de taille de voile';
subtitle = 'DT48 - 13 mars 2020';
displayedColumns: string[] = [
"weight",
"range_1", "range_2", "range_3",
"range_4", "range_5", "range_6",
"range_7", "range_8", "range_9"
];
tableHeader: {name: string, active: string}[] = [
{name: "Poids nu", active: ''},
{name: "0 à 99", active: ''},
{name: "100 à 249", active: ''},
{name: "250 à 399", active: ''},
{name: "400 à 599", active: ''},
{name: "600 à 799", active: ''},
{name: "800 à 999", active: ''},
{name: "1000 à 1399", active: ''},
{name: "1400 à 1799", active: ''},
{name: "1800 à 2000", active: ''},
];;
@Input() canopy_size_table!: MatTableDataSource<WeightSize>;
@Input() inputs: InputParams = {
jumps: 0,
weight: 60,
gear: 10,
current: 175
} as InputParams;
@ViewChild(MatSort) sort!: MatSort;
@ViewChild(MatPaginator) paginator!: MatPaginator;
constructor() { } constructor() { }
ngOnInit() { ngOnInit() {
// return this.loadData();
} }
ngOnDestroy() { ngOnDestroy() {
//this._scavenger.unsubscribe(); //this._scavenger.unsubscribe();
} }
loadData():void {
this.refreshActive();
this.canopy_size_table = new MatTableDataSource<WeightSize>(weightSizes);
}
refreshActive():void {
weightSizes.forEach(element => {
element.active = '';
element.ranges.forEach(range => {
range.active = '';
});
});
this.tableHeader.forEach(element => {
element.active = '';
});
if (this.inputs.weight >= 60 && this.inputs.weight <= 110) {
weightSizes[(this.inputs.weight - 60)].active = 'active';
}
if (this.inputs.jumps >= 0) {
var num = this.getRangeNum();
this.tableHeader[num].active = 'active';
weightSizes.forEach(element => {
element.ranges[(num-1)].active = 'active';
});
}
}
private getRangeNum(): number {
var data: Range[] = weightSizes[0].ranges;
var num: number = 1;
data.some((range: Range) => {
if (range.start <= this.inputs.jumps && range.end >= this.inputs.jumps) {
num = range.num;
return true;
}
return false;
});
return num;
}
} }
@@ -5,7 +5,7 @@ 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, AeronefAggregate } from 'src/app/core/models'; import { Aeronef, AeronefByImat } from 'src/app/core/models';
@Component({ @Component({
standalone: true, standalone: true,
@@ -15,7 +15,7 @@ import { Aeronef, AeronefAggregate } from 'src/app/core/models';
}) })
export class AeronefsComponent implements OnInit { export class AeronefsComponent implements OnInit {
private _aeronefs: Subscription = new Subscription(); private _aeronefs: Subscription = new Subscription();
aggregate!: Array<AeronefAggregate> aggregate!: Array<AeronefByImat>
aeronefs!: Array<Aeronef>; aeronefs!: Array<Aeronef>;
aeronefsCount = 0; aeronefsCount = 0;
rows: Object[] = [] as Array<Object>; rows: Object[] = [] as Array<Object>;
@@ -103,8 +103,8 @@ export class AeronefsComponent implements OnInit {
} }
loadAeronefs() { loadAeronefs() {
const aeronefs$: Observable<Array<AeronefAggregate>> = this.aeronefsService.getAll(); const aeronefs$: Observable<Array<AeronefByImat>> = this.aeronefsService.getAllByImat();
this._aeronefs = aeronefs$.subscribe((aggregate: Array<AeronefAggregate>) => { this._aeronefs = aeronefs$.subscribe((aggregate: Array<AeronefByImat>) => {
this.aggregate = aggregate; this.aggregate = aggregate;
this.aeronefsCount = aggregate.length; this.aeronefsCount = aggregate.length;
var labels: string[] = []; var labels: string[] = [];
@@ -7,7 +7,7 @@ import { Observable, Observer, Subscription } from 'rxjs';
import { take } from 'rxjs/operators'; import { take } from 'rxjs/operators';
import { BackendService, CanopiesService } from 'src/app/core/services'; import { BackendService, CanopiesService } from 'src/app/core/services';
import { Canopy, CanopyAggregate, ReduceRow } from 'src/app/core/models'; import { Canopy, CanopyBySize, ReduceRow } from 'src/app/core/models';
@Component({ @Component({
standalone: true, standalone: true,
@@ -17,7 +17,7 @@ import { Canopy, CanopyAggregate, ReduceRow } from 'src/app/core/models';
}) })
export class CanopyModelsComponent implements OnInit { export class CanopyModelsComponent implements OnInit {
private _canopies: Subscription = new Subscription(); private _canopies: Subscription = new Subscription();
aggregate!: Array<CanopyAggregate> aggregate!: Array<CanopyBySize>
canopies!: Array<Canopy>; canopies!: Array<Canopy>;
canopiesCount = 0; canopiesCount = 0;
rows: Object[] = [] as Array<Object>; rows: Object[] = [] as Array<Object>;
@@ -101,8 +101,8 @@ export class CanopyModelsComponent implements OnInit {
} }
loadCanopies() { loadCanopies() {
const canopies$: Observable<Array<CanopyAggregate>> = this.canopiesService.getAll(); const canopies$: Observable<Array<CanopyBySize>> = this.canopiesService.getAllBySize();
this._canopies = canopies$.subscribe((aggregate: Array<CanopyAggregate>) => { this._canopies = canopies$.subscribe((aggregate: Array<CanopyBySize>) => {
this.aggregate = aggregate; this.aggregate = aggregate;
//this.canopies = canopies; //this.canopies = canopies;
this.canopiesCount = aggregate.length; this.canopiesCount = aggregate.length;
@@ -6,7 +6,7 @@ import { ChartistModule, Configuration } from 'ng-chartist';
import { Observable, Observer, Subscription } from 'rxjs'; import { Observable, Observer, Subscription } from 'rxjs';
import { BackendService, DropZonesService } from 'src/app/core/services'; import { BackendService, DropZonesService } from 'src/app/core/services';
import { DropZone, DropZoneAggregate, ReduceRow} from 'src/app/core/models'; import { DropZone, DropZoneByOaci, ReduceRow} from 'src/app/core/models';
@Component({ @Component({
standalone: true, standalone: true,
@@ -16,7 +16,7 @@ import { DropZone, DropZoneAggregate, ReduceRow} from 'src/app/core/models';
}) })
export class DropZonesComponent implements OnInit { export class DropZonesComponent implements OnInit {
private _dropzones: Subscription = new Subscription(); private _dropzones: Subscription = new Subscription();
aggregate!: Array<DropZoneAggregate> aggregate!: Array<DropZoneByOaci>
dropzones!: Array<DropZone>; dropzones!: Array<DropZone>;
dropzonesCount = 0; dropzonesCount = 0;
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"];
@@ -155,8 +155,8 @@ export class DropZonesComponent implements OnInit {
} }
loadDropZones() { loadDropZones() {
const dropzones$: Observable<Array<DropZoneAggregate>> = this.dropzonesService.getAll(); const dropzones$: Observable<Array<DropZoneByOaci>> = this.dropzonesService.getAllByOaci();
this._dropzones = dropzones$.subscribe((aggregate: Array<DropZoneAggregate>) => { this._dropzones = dropzones$.subscribe((aggregate: Array<DropZoneByOaci>) => {
this.aggregate = aggregate; this.aggregate = aggregate;
//this.dropzones = dropzones; //this.dropzones = dropzones;
this.dropzonesCount = aggregate.length; this.dropzonesCount = aggregate.length;
@@ -1,7 +1,7 @@
//export * from './jumps-by-month/jumps-by-month.component';
export * from './drop-zones/drop-zones.component';
//export * from './drop-zones-bar/drop-zones-bar.component';
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-sizes/canopy-sizes.component';
export * from './canopy-models/canopy-models.component'; export * from './canopy-models/canopy-models.component';
//export * from './canopy-sizes/canopy-sizes.component';
export * from './drop-zones/drop-zones.component';
//export * from './drop-zones-bar/drop-zones-bar.component';
//export * from './jumps-by-month/jumps-by-month.component';
+10 -10
View File
@@ -5,7 +5,7 @@ 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, AeronefAggregate, AeronefList, Canopy, CanopyAggregate, DropZone, DropZoneAggregate } from 'src/app/core/models'; import { User, Errors, Aeronef, AeronefByImat, AeronefList, Canopy, CanopyBySize, DropZone, DropZoneByOaci } 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 { AeronefsComponent, DropZonesComponent, CanopyModelsComponent } from './dashboard-components';
@@ -32,13 +32,13 @@ export class HomeComponent implements OnInit, OnDestroy {
errors!: Errors; errors!: Errors;
isAuthenticated = false; isAuthenticated = false;
canModify = false; canModify = false;
aeronefAggregate!: Array<AeronefAggregate> aeronefAggregate!: Array<AeronefByImat>
aeronefs!: Array<Aeronef>; aeronefs!: Array<Aeronef>;
aeronefsCount = 0; aeronefsCount = 0;
canopyAggregate!: Array<CanopyAggregate> canopyAggregate!: Array<CanopyBySize>
canopies!: Array<Canopy>; canopies!: Array<Canopy>;
canopiesCount = 0; canopiesCount = 0;
dropzoneAggregate!: Array<DropZoneAggregate> dropzoneAggregate!: Array<DropZoneByOaci>
dropzones!: Array<DropZone>; dropzones!: Array<DropZone>;
dropzonesCount = 0; dropzonesCount = 0;
@@ -75,8 +75,8 @@ export class HomeComponent implements OnInit, OnDestroy {
} }
loadAeronefs() { loadAeronefs() {
const aeronefs$: Observable<Array<AeronefAggregate>> = this.aeronefsService.getAll(); const aeronefs$: Observable<Array<AeronefByImat>> = this.aeronefsService.getAllByImat();
this._aeronefs = aeronefs$.subscribe((aggregate: Array<AeronefAggregate>) => { this._aeronefs = aeronefs$.subscribe((aggregate: Array<AeronefByImat>) => {
this.aeronefAggregate = aggregate; this.aeronefAggregate = aggregate;
this.aeronefsCount = aggregate.length; this.aeronefsCount = aggregate.length;
console.log(this.aeronefs); console.log(this.aeronefs);
@@ -84,8 +84,8 @@ export class HomeComponent implements OnInit, OnDestroy {
}); });
} }
loadCanopies() { loadCanopies() {
const canopies$: Observable<Array<CanopyAggregate>> = this.canopiesService.getAll(); const canopies$: Observable<Array<CanopyBySize>> = this.canopiesService.getAllBySize();
this._canopies = canopies$.subscribe((aggregate: Array<CanopyAggregate>) => { this._canopies = canopies$.subscribe((aggregate: Array<CanopyBySize>) => {
this.canopyAggregate = aggregate; this.canopyAggregate = aggregate;
this.canopiesCount = aggregate.length; this.canopiesCount = aggregate.length;
// console.log(this.canopies); // console.log(this.canopies);
@@ -93,8 +93,8 @@ export class HomeComponent implements OnInit, OnDestroy {
}); });
} }
loadDropzones() { loadDropzones() {
const dropzones$: Observable<Array<DropZoneAggregate>> = this.dropzonesService.getAll(); const dropzones$: Observable<Array<DropZoneByOaci>> = this.dropzonesService.getAllByOaci();
this._dropzones = dropzones$.subscribe((aggregate: Array<DropZoneAggregate>) => { this._dropzones = dropzones$.subscribe((aggregate: Array<DropZoneByOaci>) => {
this.dropzoneAggregate = aggregate; this.dropzoneAggregate = aggregate;
this.dropzonesCount = aggregate.length; this.dropzonesCount = aggregate.length;
// console.log(this.dropzones); // console.log(this.dropzones);
+2
View File
@@ -2,6 +2,8 @@ export * from './accordion';
export * from './confirmed.validator'; export * from './confirmed.validator';
export * from './dialogs'; export * from './dialogs';
export * from './helpers-jump'; export * from './helpers-jump';
export * from './layout/header.component';
export * from './layout/footer.component';
export * from './layout/full.component'; export * from './layout/full.component';
export * from './list-errors/list-errors.component'; export * from './list-errors/list-errors.component';
export * from './menu-items'; export * from './menu-items';
@@ -1,48 +1,4 @@
<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>
<span *appShowAuthed="true" class="fw-light me-1">@{{ currentUser.username }}</span>
<div *appShowAuthed="true" 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>
<span *appShowAuthed="false">
<button mat-button routerLink="/login" routerLinkActive="active">Se connecter</button>
<button mat-button routerLink="/register" routerLinkActive="active">Créer un compte</button>
</span>
</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"> <div *appShowAuthed="true">
@@ -123,14 +79,7 @@
</div> </div>
</mat-nav-list> </mat-nav-list>
</div> </div>
<footer class="footer"> <huapp-layout-footer></huapp-layout-footer>
<div class="container-fluid text-end">
<a class="me-1" [href]="siteLink" target="_blank">{{ author }}</a>
<span class="copyright">
&copy; {{ today | date: 'yyyy' }}
</span>
</div>
</footer>
</mat-sidenav> </mat-sidenav>
<mat-sidenav-content class="page-wrapper"> <mat-sidenav-content class="page-wrapper">
<div class="page-content"> <div class="page-content">
@@ -15,6 +15,7 @@ import { Observable, Subscription } from 'rxjs';
import { User } from 'src/app/core/models'; import { User } from 'src/app/core/models';
import { UserService } from 'src/app/core/services'; import { UserService } from 'src/app/core/services';
import { MenuItems, ShowAuthedDirective, SpinnerComponent, AccordionAnchorDirective, AccordionLinkDirective, AccordionDirective } from 'src/app/components/shared'; import { MenuItems, ShowAuthedDirective, SpinnerComponent, AccordionAnchorDirective, AccordionLinkDirective, AccordionDirective } from 'src/app/components/shared';
import { HeaderComponent, FooterComponent } from 'src/app/components/shared/layout';
/** @title Responsive sidenav */ /** @title Responsive sidenav */
@@ -24,7 +25,7 @@ import { MenuItems, ShowAuthedDirective, SpinnerComponent, AccordionAnchorDirect
imports: [ imports: [
CommonModule, RouterModule, RouterOutlet, CommonModule, RouterModule, RouterOutlet,
MatBadgeModule, MatButtonModule, MatIconModule, MatListModule, MatMenuModule, MatSidenavModule, MatToolbarModule, MatBadgeModule, MatButtonModule, MatIconModule, MatListModule, MatMenuModule, MatSidenavModule, MatToolbarModule,
ShowAuthedDirective, SpinnerComponent, ShowAuthedDirective, SpinnerComponent, HeaderComponent, FooterComponent,
AccordionAnchorDirective, AccordionLinkDirective, AccordionDirective AccordionAnchorDirective, AccordionLinkDirective, AccordionDirective
], ],
providers: [ MenuItems ], providers: [ MenuItems ],
+9 -1
View File
@@ -8,10 +8,18 @@ export interface Aeronef {
updatedAt: string; updatedAt: string;
} }
export interface AeronefAggregate { export interface AeronefByImat {
_id: { _id: {
aeronef: string, aeronef: string,
imat: string imat: string
}, },
count: number count: number
} }
export interface AeronefByYear {
_id: {
aeronef: string,
year: number
},
count: number
}
+9 -1
View File
@@ -8,10 +8,18 @@ export interface Canopy {
updatedAt: string; updatedAt: string;
} }
export interface CanopyAggregate { export interface CanopyBySize {
_id: { _id: {
canopy: string, canopy: string,
taille: number taille: number
}, },
count: number count: number
} }
export interface CanopyByYear {
_id: {
canopy: string,
year: number
},
count: number
}
+9 -1
View File
@@ -8,10 +8,18 @@ export interface DropZone {
updatedAt: string; updatedAt: string;
} }
export interface DropZoneAggregate { export interface DropZoneByOaci {
_id: { _id: {
lieu: string, lieu: string,
oaci: string oaci: string
}, },
count: number count: number
} }
export interface DropZoneByYear {
_id: {
lieu: string,
year: number
},
count: number
}
+1
View File
@@ -2,6 +2,7 @@ export * from './aeronef.model';
export * from './aeronef-list.model'; export * from './aeronef-list.model';
export * from './application.model'; export * from './application.model';
export * from './application-list-config.model'; export * from './application-list-config.model';
export * from './calculator.model';
export * from './canopy.model'; export * from './canopy.model';
export * from './canopysize.model'; export * from './canopysize.model';
export * from './reducerow.model'; export * from './reducerow.model';
+2 -2
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 { Aeronef, AeronefAggregate, AeronefList, JumpList, JumpListConfig, JumpListFilters } from 'src/app/core/models'; import { Aeronef, AeronefByImat, AeronefList, JumpList, JumpListConfig, JumpListFilters } from 'src/app/core/models';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AeronefsService { export class AeronefsService {
@@ -12,7 +12,7 @@ export class AeronefsService {
private apiService: ApiService private apiService: ApiService
) { } ) { }
getAll(): Observable<Array<AeronefAggregate>> { getAllByImat(): Observable<Array<AeronefByImat>> {
return this.apiService.get('/aeronefs') return this.apiService.get('/aeronefs')
.pipe(map(data => data.aeronefs)); .pipe(map(data => data.aeronefs));
/* /*
+2 -2
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 { Canopy, CanopyAggregate ,JumpList, JumpListConfig, JumpListFilters } from 'src/app/core/models'; import { Canopy, CanopyBySize ,JumpList, JumpListConfig, JumpListFilters } from 'src/app/core/models';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class CanopiesService { export class CanopiesService {
@@ -12,7 +12,7 @@ export class CanopiesService {
private apiService: ApiService private apiService: ApiService
) { } ) { }
getAll(): Observable<Array<CanopyAggregate>> { getAllBySize(): Observable<Array<CanopyBySize>> {
return this.apiService.get('/canopies') return this.apiService.get('/canopies')
.pipe(map(data => data.canopies)); .pipe(map(data => data.canopies));
} }
+2 -2
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, DropZoneAggregate, JumpList, JumpListConfig, JumpListFilters } from 'src/app/core/models'; import { DropZone, DropZoneByOaci, JumpList, JumpListConfig, JumpListFilters } from 'src/app/core/models';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class DropZonesService { export class DropZonesService {
@@ -12,7 +12,7 @@ export class DropZonesService {
private apiService: ApiService private apiService: ApiService
) { } ) { }
getAll(): Observable<Array<DropZoneAggregate>> { getAllByOaci(): Observable<Array<DropZoneByOaci>> {
return this.apiService.get('/dropzones') return this.apiService.get('/dropzones')
.pipe(map(data => data.dropzones)); .pipe(map(data => data.dropzones));
} }
+93
View File
@@ -108,3 +108,96 @@ huapp-full-layout .mdc-text-field--filled .mdc-floating-label {
padding-bottom: 8px; padding-bottom: 8px;
} }
} }
/**********************
* Background Colors *
**********************/
.bg-primary {
background-color: $primary !important;
}
.bg-secondary,
.bg-warn {
background-color: $secondary !important;
}
.bg-accent {
background-color: $accent !important;
}
.bg-success {
background-color: $success !important;
}
.bg-info {
background-color: $info !important;
}
.bg-warning {
background-color: $warning !important;
}
.bg-danger {
background-color: $danger !important;
}
.bg-error {
background-color: $error !important;
}
.bg-white {
background-color: $white !important;
}
.bg-red {
background-color: $red !important;
}
.bg-red-dark {
background-color: $red-dark !important;
}
.bg-orange {
background-color: $orange !important;
}
.bg-yellow {
background-color: $yellow !important;
}
.bg-megna {
background-color: $megna !important;
}
.bg-green {
background-color: $green !important;
}
.bg-teal {
background-color: $teal !important;
}
.bg-turquoise {
background-color: $turquoise !important;
}
.bg-cyan {
background-color: $cyan !important;
}
.bg-blue {
background-color: $blue !important;
}
.bg-navy {
background-color: $navy !important;
}
.bg-pink {
background-color: $pink !important;
}
.bg-magenta {
background-color: $magenta !important;
}
.bg-purple {
background-color: $purple !important;
}
.bg-purple-dark {
background-color: $purple-dark !important;
}
.bg-raspberry {
background-color: $raspberry !important;
}
.bg-grey {
background-color: $grey !important;
}
.bg-muted {
background-color: $muted !important;
}
.bg-extra-muted {
background-color: $extra-muted !important;
}
.bg-crystal,
.bg-crystal .mdc-text-field--filled:not(.mdc-text-field--disabled) {
background-color: transparent !important;
}
+2 -2
View File
@@ -29,7 +29,7 @@ File: scss
@import "bootstrap/scss/grid"; @import "bootstrap/scss/grid";
@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/pagination"; @import "bootstrap/scss/pagination";
@import "bootstrap/scss/alert"; @import "bootstrap/scss/alert";
@@ -122,7 +122,7 @@ $background: map.get($headup_app-theme, background);
@import 'spinner'; @import 'spinner';
@import 'header'; @import 'header';
@import 'sidebar'; @import 'sidebar';
//@import 'tables'; @import 'tables';
@import 'charts'; @import 'charts';
@import 'responsive'; @import 'responsive';
@import 'app'; @import 'app';
+35 -18
View File
@@ -9,7 +9,7 @@ File: scss
Table Table
*******************/ *******************/
.table-rasponsive { .table-responsive {
overflow: auto; overflow: auto;
.mat-table { .mat-table {
min-width: 280px; min-width: 280px;
@@ -77,31 +77,41 @@ caption {
} }
.table.table-dark>thead>tr>th { .table.table-dark>thead>tr>th {
border-bottom:2px solid rgb(221, 221, 221, 0.3); border-bottom:2px solid rgb(221, 221, 221, 0.3);
padding-top: 1rem;
} }
.table.table-dark>tfoot>tr>th { .table.table-dark>tfoot>tr>th {
border-top:2px solid rgb(221, 221, 221, 0.3); border-top:2px solid rgb(221, 221, 221, 0.3);
padding-top: 1rem;
} }
.table.table-dark>tbody>tr.active>td,
.table.table-dark>tbody>tr.active>th, tr.mat-mdc-header-row.primary {
.table.table-dark>tbody>tr>td.active, background-color: rgba(167, 212, 196, 0.1);
.table.table-dark>tbody>tr>th.active, }
.table.table-dark>tfoot>tr.active>td, .table.table-dark>tbody>tr.primary.active>td,
.table.table-dark>tfoot>tr.active>th, .table.table-dark>tbody>tr.primary.active>th,
.table.table-dark>tfoot>tr>td.active, .table.table-dark>tbody>tr.primary>td.active,
.table.table-dark>tfoot>tr>th.active, .table.table-dark>tbody>tr.primary>th.active,
.table.table-dark>thead>tr.active>td, .table.table-dark>tfoot>tr.primary.active>td,
.table.table-dark>thead>tr.active>th, .table.table-dark>tfoot>tr.primary.active>th,
.table.table-dark>thead>tr>td.active, .table.table-dark>tfoot>tr.primary>td.active,
.table.table-dark>thead>tr>th.active { .table.table-dark>tfoot>tr.primary>th.active,
.table.table-dark>thead>tr.primary.active>td,
.table.table-dark>thead>tr.primary.active>th,
.table.table-dark>thead>tr.primary>td.active,
.table.table-dark>thead>tr.primary>th.active {
background-color: rgba(165, 212, 146, 0.2); //#a5d492; background-color: rgba(165, 212, 146, 0.2); //#a5d492;
} }
.table-dark.table-hover>tbody>tr.active:hover>td, .table-dark.table-hover>tbody>tr.primary.active:hover>td,
.table-dark.table-hover>tbody>tr.active:hover>th, .table-dark.table-hover>tbody>tr.primary.active:hover>th,
.table-dark.table-hover>tbody>tr:hover>.active, .table-dark.table-hover>tbody>tr.primary:hover>.active,
.table-dark.table-hover>tbody>tr>td.active:hover, .table-dark.table-hover>tbody>tr.primary>td.active:hover,
.table-dark.table-hover>tbody>tr>th.active:hover { .table-dark.table-hover>tbody>tr.primary>th.active:hover {
background-color: rgba(165, 212, 146, 0.3); //#93c081; background-color: rgba(165, 212, 146, 0.3); //#93c081;
} }
tr.mat-mdc-header-row.warn {
background-color: rgba(151, 136, 199, 0.1);
}
.table.table-dark>tbody>tr.warn.active>td, .table.table-dark>tbody>tr.warn.active>td,
.table.table-dark>tbody>tr.warn.active>th, .table.table-dark>tbody>tr.warn.active>th,
.table.table-dark>tbody>tr.warn>td.active, .table.table-dark>tbody>tr.warn>td.active,
@@ -297,6 +307,13 @@ table th[class*=col-] {
min-height:.01%; min-height:.01%;
overflow-x:auto overflow-x:auto
} }
.table .mat-mdc-row {
height: auto;
color: inherit;
}
.table .mat-mdc-header-row {
height: auto;
}
@media screen and (max-width:767px) { @media screen and (max-width:767px) {
.table-responsive { .table-responsive {
width:100%; width:100%;