First try
This commit is contained in:
@@ -4,25 +4,33 @@
|
||||
"newProjectRoot": "projects",
|
||||
"projects": {
|
||||
"skydivelogs-app": {
|
||||
"projectType": "application",
|
||||
"schematics": {
|
||||
"@schematics/angular:component": {
|
||||
"style": "scss"
|
||||
}
|
||||
},
|
||||
"root": "",
|
||||
"sourceRoot": "src",
|
||||
"projectType": "application",
|
||||
"prefix": "app",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:application",
|
||||
"options": {
|
||||
"outputPath": {
|
||||
"base": "dist"
|
||||
},
|
||||
"outputPath": "dist",
|
||||
"index": "src/index.html",
|
||||
"tsConfig": "src/tsconfig.app.json",
|
||||
"polyfills": [
|
||||
"src/polyfills.ts"
|
||||
],
|
||||
"browser": "src/main.ts",
|
||||
"polyfills": ["zone.js"],
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"inlineStyleLanguage": "scss",
|
||||
"assets": [
|
||||
"src/assets",
|
||||
"src/config",
|
||||
"src/favicon.ico"
|
||||
"src/favicon.ico",
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "public"
|
||||
}
|
||||
],
|
||||
"styles": [
|
||||
"src/assets/css/styles-app-loading.scss",
|
||||
@@ -30,26 +38,28 @@
|
||||
"src/assets/css/new-theme.scss",
|
||||
"@angular/material/prebuilt-themes/pink-bluegrey.css"
|
||||
],
|
||||
"scripts": [],
|
||||
"extractLicenses": false,
|
||||
"sourceMap": true,
|
||||
"optimization": false,
|
||||
"namedChunks": true,
|
||||
"browser": "src/main.ts"
|
||||
"scripts": []
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
"maximumWarning": "500kB",
|
||||
"maximumError": "1MB"
|
||||
},
|
||||
{
|
||||
"type": "anyComponentStyle",
|
||||
"maximumWarning": "6kb"
|
||||
"maximumWarning": "4kB",
|
||||
"maximumError": "8kB"
|
||||
}
|
||||
],
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"namedChunks": false,
|
||||
"extractLicenses": true,
|
||||
"outputHashing": "all"
|
||||
},
|
||||
"development": {
|
||||
"optimization": false,
|
||||
"extractLicenses": false,
|
||||
"sourceMap": true,
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
@@ -57,91 +67,41 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "production"
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
"options": {
|
||||
"buildTarget": "skydivelogs-app:build"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"buildTarget": "skydivelogs-app:build:production"
|
||||
},
|
||||
"development": {
|
||||
"buildTarget": "skydivelogs-app:build:development"
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development"
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
"options": {
|
||||
"buildTarget": "skydivelogs-app:build"
|
||||
}
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n"
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "src/test.ts",
|
||||
"karmaConfig": "./karma.conf.js",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "src/tsconfig.spec.json",
|
||||
"scripts": [],
|
||||
"styles": [
|
||||
"src/styles.css"
|
||||
],
|
||||
"polyfills": ["zone.js", "zone.js/testing"],
|
||||
"tsConfig": "tsconfig.spec.json",
|
||||
"inlineStyleLanguage": "scss",
|
||||
"assets": [
|
||||
"src/assets",
|
||||
"src/favicon.ico"
|
||||
]
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"src/tsconfig.app.json",
|
||||
"src/tsconfig.spec.json"
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "public"
|
||||
}
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"skydivelogs-app-e2e": {
|
||||
"root": "e2e",
|
||||
"sourceRoot": "e2e",
|
||||
"projectType": "application",
|
||||
"architect": {
|
||||
"e2e": {
|
||||
"builder": "@angular-devkit/build-angular:protractor",
|
||||
"options": {
|
||||
"protractorConfig": "./protractor.conf.js",
|
||||
"devServerTarget": "skydivelogs-app:serve"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"e2e/tsconfig.e2e.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
"styles": ["src/styles.scss"],
|
||||
"scripts": []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"schematics": {
|
||||
"@schematics/angular:component": {
|
||||
"prefix": "app"
|
||||
},
|
||||
"@schematics/angular:directive": {
|
||||
"prefix": "app"
|
||||
}
|
||||
},
|
||||
"cli": {
|
||||
"analytics": false
|
||||
}
|
||||
}
|
||||
|
||||
16
Front/skydivelogs-app/package-lock.json
generated
16
Front/skydivelogs-app/package-lock.json
generated
@@ -22,7 +22,7 @@
|
||||
"@ngx-translate/core": "^15.0.0",
|
||||
"@ngx-translate/http-loader": "^8.0.0",
|
||||
"chart.js": "^4.3.0",
|
||||
"ng2-charts": "^5.0.2",
|
||||
"ng2-charts": "^8.0.0",
|
||||
"rxjs": "~7.8.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.15.0"
|
||||
@@ -10714,19 +10714,19 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ng2-charts": {
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/ng2-charts/-/ng2-charts-5.0.4.tgz",
|
||||
"integrity": "sha512-AnOZ2KSRw7QjiMMNtXz9tdnO+XrIKP/2MX1TfqEEo2fwFU5c8LFJIYqmkMPkIzAEm/U9y/1psA5TDNmxxjEdgA==",
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ng2-charts/-/ng2-charts-8.0.0.tgz",
|
||||
"integrity": "sha512-nofsNHI2Zt+EAwT+BJBVg0kgOhNo9ukO4CxULlaIi7VwZSr7I1km38kWSoU41Oq6os6qqIh5srnL+CcV+RFPFA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"lodash-es": "^4.17.15",
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/cdk": ">=16.0.0",
|
||||
"@angular/common": ">=16.0.0",
|
||||
"@angular/core": ">=16.0.0",
|
||||
"@angular/platform-browser": ">=16.0.0",
|
||||
"@angular/cdk": ">=19.0.0",
|
||||
"@angular/common": ">=19.0.0",
|
||||
"@angular/core": ">=19.0.0",
|
||||
"@angular/platform-browser": ">=19.0.0",
|
||||
"chart.js": "^3.4.0 || ^4.0.0",
|
||||
"rxjs": "^6.5.3 || ^7.4.0"
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
"@ngx-translate/core": "^15.0.0",
|
||||
"@ngx-translate/http-loader": "^8.0.0",
|
||||
"chart.js": "^4.3.0",
|
||||
"ng2-charts": "^5.0.2",
|
||||
"ng2-charts": "^8.0.0",
|
||||
"rxjs": "~7.8.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.15.0"
|
||||
|
||||
@@ -72,7 +72,7 @@ import { MatRadioModule } from "@angular/material/radio";
|
||||
import { MatSidenavModule } from "@angular/material/sidenav";
|
||||
import { MatListModule } from "@angular/material/list";
|
||||
import { MatToolbarModule } from "@angular/material/toolbar";
|
||||
import { NgChartsModule } from "ng2-charts";
|
||||
import { provideCharts, withDefaultRegisterables } from "ng2-charts";
|
||||
|
||||
import { JwtAuthInterceptor } from "../interceptor/jwt-auth.interceptor";
|
||||
import { ErrorInterceptor } from "../interceptor/error.interceptor";
|
||||
@@ -209,7 +209,6 @@ export function initConfig(configService: ConfigurationHelper) {
|
||||
MatSidenavModule,
|
||||
MatListModule,
|
||||
MatToolbarModule,
|
||||
NgChartsModule,
|
||||
],
|
||||
exports: [HttpClientModule],
|
||||
providers: [
|
||||
@@ -229,11 +228,12 @@ export function initConfig(configService: ConfigurationHelper) {
|
||||
DatePipe,
|
||||
ServiceCacheApi,
|
||||
provideAppInitializer(() => {
|
||||
const initializerFn = (initConfig)(inject(ConfigurationHelper));
|
||||
return initializerFn();
|
||||
}),
|
||||
const initializerFn = initConfig(inject(ConfigurationHelper));
|
||||
return initializerFn();
|
||||
}),
|
||||
{ provide: HTTP_INTERCEPTORS, useClass: JwtAuthInterceptor, multi: true },
|
||||
{ provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true },
|
||||
provideCharts(withDefaultRegisterables()),
|
||||
],
|
||||
bootstrap: [AppComponent],
|
||||
})
|
||||
|
||||
@@ -1,72 +1,102 @@
|
||||
<form [formGroup]="createForm" (ngSubmit)="onCreateSubmit()" autocomplete="off" style="padding: 10px;">
|
||||
<form
|
||||
[formGroup]="createForm"
|
||||
(ngSubmit)="onCreateSubmit()"
|
||||
autocomplete="off"
|
||||
style="padding: 10px"
|
||||
>
|
||||
<p>
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'LoginCreateUser_Firstname' | translate }}</mat-label>
|
||||
<input matInput type="text" formControlName="firstname"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls.firstname.errors }" tabindex="0" />
|
||||
<mat-error *ngIf="formCtrls.firstname.hasError('required')">
|
||||
{{ 'LoginCreateUser_FirstnameRequired' | translate }}
|
||||
<mat-label>{{ "LoginCreateUser_Firstname" | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
type="text"
|
||||
formControlName="firstname"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls['firstname'].errors }"
|
||||
tabindex="0"
|
||||
/>
|
||||
<mat-error *ngIf="formCtrls['firstname'].hasError('required')">
|
||||
{{ "LoginCreateUser_FirstnameRequired" | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="formCtrls.firstname.hasError('minlength')">
|
||||
{{ 'LoginCreateUser_FirstnamePattern' | translate }}
|
||||
<mat-error *ngIf="formCtrls['firstname'].hasError('minlength')">
|
||||
{{ "LoginCreateUser_FirstnamePattern" | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</p>
|
||||
<p>
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'LoginCreateUser_Lastname' | translate }}</mat-label>
|
||||
<input matInput type="text" formControlName="lastname"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls.lastname.errors }" tabindex="1" />
|
||||
<mat-error *ngIf="formCtrls.lastname.hasError('required')">
|
||||
{{ 'LoginCreateUser_LastnameRequired' | translate }}
|
||||
<mat-label>{{ "LoginCreateUser_Lastname" | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
type="text"
|
||||
formControlName="lastname"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls['lastname'].errors }"
|
||||
tabindex="1"
|
||||
/>
|
||||
<mat-error *ngIf="formCtrls['lastname'].hasError('required')">
|
||||
{{ "LoginCreateUser_LastnameRequired" | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="formCtrls.lastname.hasError('minlength')">
|
||||
{{ 'LoginCreateUser_LastnamePattern' | translate }}
|
||||
<mat-error *ngIf="formCtrls['lastname'].hasError('minlength')">
|
||||
{{ "LoginCreateUser_LastnamePattern" | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</p>
|
||||
<p>
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'LoginCreateUser_Email' | translate }}</mat-label>
|
||||
<input matInput type="email" formControlName="email"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls.email.errors }" tabindex="3" />
|
||||
<mat-error *ngIf="formCtrls.email.hasError('required')">
|
||||
{{ 'LoginCreateUser_EmailRequired' | translate }}
|
||||
<mat-label>{{ "LoginCreateUser_Email" | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
type="email"
|
||||
formControlName="email"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls['email'].errors }"
|
||||
tabindex="3"
|
||||
/>
|
||||
<mat-error *ngIf="formCtrls['email'].hasError('required')">
|
||||
{{ "LoginCreateUser_EmailRequired" | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="formCtrls.email.hasError('email')">
|
||||
{{ 'LoginCreateUser_EmailPattern' | translate }}
|
||||
<mat-error *ngIf="formCtrls['email'].hasError('email')">
|
||||
{{ "LoginCreateUser_EmailPattern" | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</p>
|
||||
<p>
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'LoginCreateUser_Username' | translate }}</mat-label>
|
||||
<input matInput type="text" formControlName="username"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls.username.errors }" tabindex="4" />
|
||||
<mat-error *ngIf="formCtrls.username.hasError('required')">
|
||||
{{ 'LoginCreateUser_UsernameRequired' | translate }}
|
||||
<mat-label>{{ "LoginCreateUser_Username" | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
type="text"
|
||||
formControlName="username"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls['username'].errors }"
|
||||
tabindex="4"
|
||||
/>
|
||||
<mat-error *ngIf="formCtrls['username'].hasError('required')">
|
||||
{{ "LoginCreateUser_UsernameRequired" | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="formCtrls.username.hasError('minlength')">
|
||||
{{ 'LoginCreateUser_UsernamePattern' | translate }}
|
||||
<mat-error *ngIf="formCtrls['username'].hasError('minlength')">
|
||||
{{ "LoginCreateUser_UsernamePattern" | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</p>
|
||||
<p>
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'LoginCreateUser_Password' | translate }}</mat-label>
|
||||
<input matInput type="password" formControlName="password"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls.password.errors }" tabindex="5" />
|
||||
<mat-error *ngIf="formCtrls.password.hasError('required')">
|
||||
{{ 'LoginCreateUser_PasswordRequired' | translate }}
|
||||
<mat-label>{{ "LoginCreateUser_Password" | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
type="password"
|
||||
formControlName="password"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls['password'].errors }"
|
||||
tabindex="5"
|
||||
/>
|
||||
<mat-error *ngIf="formCtrls['password'].hasError('required')">
|
||||
{{ "LoginCreateUser_PasswordRequired" | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="formCtrls.password.hasError('pattern')">
|
||||
{{ 'LoginCreateUser_PasswordPattern' | translate }}
|
||||
<mat-error *ngIf="formCtrls['password'].hasError('pattern')">
|
||||
{{ "LoginCreateUser_PasswordPattern" | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</p>
|
||||
|
||||
<button [disabled]="!createForm.valid" mat-raised-button color="accent">
|
||||
{{ 'LoginCreateUser_BtnLogin' | translate }}
|
||||
{{ "LoginCreateUser_BtnLogin" | translate }}
|
||||
</button>
|
||||
<div *ngIf="error" class="alert alert-danger mt-3 mb-0">{{error}}</div>
|
||||
<div *ngIf="error" class="alert alert-danger mt-3 mb-0">{{ error }}</div>
|
||||
</form>
|
||||
|
||||
@@ -9,10 +9,10 @@ import { AuthenticationService } from "../../services/authentication.service";
|
||||
import { User } from "../../models/user";
|
||||
|
||||
@Component({
|
||||
selector: "app-create-user",
|
||||
templateUrl: "./create-user.component.html",
|
||||
styleUrls: ["./create-user.component.css"],
|
||||
standalone: false
|
||||
selector: "app-create-user",
|
||||
templateUrl: "./create-user.component.html",
|
||||
styleUrls: ["./create-user.component.css"],
|
||||
standalone: false,
|
||||
})
|
||||
export class CreateUserComponent implements OnInit {
|
||||
createForm: FormGroup;
|
||||
@@ -21,11 +21,13 @@ export class CreateUserComponent implements OnInit {
|
||||
returnUrl: string;
|
||||
error = "";
|
||||
|
||||
constructor(private formBuilder: FormBuilder,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private authenticationService: AuthenticationService,
|
||||
private translateService: TranslateService) {
|
||||
constructor(
|
||||
private formBuilder: FormBuilder,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private authenticationService: AuthenticationService,
|
||||
private translateService: TranslateService
|
||||
) {
|
||||
// redirect to home if already logged in
|
||||
if (this.authenticationService.currentUserValue) {
|
||||
this.router.navigate(["/"]);
|
||||
@@ -38,11 +40,16 @@ export class CreateUserComponent implements OnInit {
|
||||
username: ["", [Validators.required, Validators.minLength(3)]],
|
||||
password: [
|
||||
"",
|
||||
[Validators.required, Validators.pattern("^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[@$!%*#?&\-_|]).{8,}$")]
|
||||
[
|
||||
Validators.required,
|
||||
Validators.pattern(
|
||||
"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[@$!%*#?&-_|]).{8,}$"
|
||||
),
|
||||
],
|
||||
],
|
||||
firstname: ["", [Validators.required, Validators.minLength(3)]],
|
||||
lastname: ["", [Validators.required, Validators.minLength(3)]],
|
||||
email: ["", [Validators.required, Validators.email]]
|
||||
email: ["", [Validators.required, Validators.email]],
|
||||
},
|
||||
{ updateOn: "blur" }
|
||||
);
|
||||
@@ -65,23 +72,24 @@ export class CreateUserComponent implements OnInit {
|
||||
}
|
||||
|
||||
let createUser = new User();
|
||||
createUser.login = this.formCtrls.username.value;
|
||||
createUser.password = this.formCtrls.password.value;
|
||||
createUser.firstName = this.formCtrls.firstname.value;
|
||||
createUser.lastName = this.formCtrls.lastname.value;
|
||||
createUser.email = this.formCtrls.email.value;
|
||||
createUser.login = this.formCtrls["username"].value;
|
||||
createUser.password = this.formCtrls["password"].value;
|
||||
createUser.firstName = this.formCtrls["firstname"].value;
|
||||
createUser.lastName = this.formCtrls["lastname"].value;
|
||||
createUser.email = this.formCtrls["email"].value;
|
||||
createUser.language = this.translateService.currentLang;
|
||||
|
||||
this.authenticationService.create(createUser)
|
||||
.pipe(first())
|
||||
.subscribe(
|
||||
data => {
|
||||
this.router.navigate([this.returnUrl]);
|
||||
},
|
||||
error => {
|
||||
this.error = error;
|
||||
this.invalidForm = false;
|
||||
}
|
||||
);
|
||||
this.authenticationService
|
||||
.create(createUser)
|
||||
.pipe(first())
|
||||
.subscribe(
|
||||
(data) => {
|
||||
this.router.navigate([this.returnUrl]);
|
||||
},
|
||||
(error) => {
|
||||
this.error = error;
|
||||
this.invalidForm = false;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
baseChart
|
||||
[data]="barChartData"
|
||||
[options]="barChartOptions"
|
||||
[plugins]="barChartPlugins"
|
||||
[legend]="barChartLegend"
|
||||
[type]="barChartType"
|
||||
>
|
||||
|
||||
@@ -1,233 +1,253 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { formatDate } from '@angular/common';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { ChartConfiguration, ChartData, ChartType } from 'chart.js';
|
||||
import { from, of, groupBy, mergeMap, reduce, map, Observable } from 'rxjs';
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { formatDate } from "@angular/common";
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
import { MatTableDataSource } from "@angular/material/table";
|
||||
import { ChartConfiguration, ChartData, ChartType } from "chart.js";
|
||||
import { from, of, groupBy, mergeMap, reduce, map, Observable } from "rxjs";
|
||||
|
||||
import { ServiceComm } from '../../services/service-comm.service';
|
||||
import { ServiceComm } from "../../services/service-comm.service";
|
||||
import { TunnelFlightService } from "../../services/tunnel-flight.service";
|
||||
import { DateService } from '../../services/date.service';
|
||||
import { TunnelFlight, TunnelFlightByMonth } from '../../models/tunnel-flight';
|
||||
import { DateService } from "../../services/date.service";
|
||||
import { TunnelFlight, TunnelFlightByMonth } from "../../models/tunnel-flight";
|
||||
|
||||
@Component({
|
||||
selector: 'app-list-of-tunnel-flights',
|
||||
templateUrl: './list-of-tunnel-flights.component.html',
|
||||
styleUrls: ['./list-of-tunnel-flights.component.css'],
|
||||
standalone: false
|
||||
selector: "app-list-of-tunnel-flights",
|
||||
templateUrl: "./list-of-tunnel-flights.component.html",
|
||||
styleUrls: ["./list-of-tunnel-flights.component.css"],
|
||||
standalone: false,
|
||||
})
|
||||
export class ListOfTunnelFlightsComponent implements OnInit {
|
||||
public barChartLegend = true;
|
||||
public barChartPlugins = [];
|
||||
public barChartData: ChartData<'bar'>;
|
||||
public barChartOptions: ChartConfiguration['options'];
|
||||
public barChartType: ChartType;
|
||||
public isLoading: boolean = false;
|
||||
public selectedPeriod: string;
|
||||
public dataSourceTable: MatTableDataSource<TunnelFlight> = new MatTableDataSource();
|
||||
public displayedColumns: Array<string> = [
|
||||
"id",
|
||||
"tunnel",
|
||||
"jumpType",
|
||||
"nbMinutes",
|
||||
"notes",
|
||||
"flightDate",
|
||||
"actions"
|
||||
];
|
||||
public stats: Array<{id: String|Number, values: String|Number}> = [];
|
||||
public barChartLegend = true;
|
||||
public barChartData: ChartData<"bar">;
|
||||
public barChartOptions: ChartConfiguration["options"];
|
||||
public barChartType: ChartType;
|
||||
public isLoading: boolean = false;
|
||||
public selectedPeriod: string;
|
||||
public dataSourceTable: MatTableDataSource<TunnelFlight> =
|
||||
new MatTableDataSource();
|
||||
public displayedColumns: Array<string> = [
|
||||
"id",
|
||||
"tunnel",
|
||||
"jumpType",
|
||||
"nbMinutes",
|
||||
"notes",
|
||||
"flightDate",
|
||||
"actions",
|
||||
];
|
||||
public stats: Array<{ id: String | Number; values: String | Number }> = [];
|
||||
|
||||
constructor(private serviceComm: ServiceComm,
|
||||
private serviceTunnelFlight: TunnelFlightService,
|
||||
private translateService: TranslateService,
|
||||
private dateService: DateService) { }
|
||||
constructor(
|
||||
private serviceComm: ServiceComm,
|
||||
private serviceTunnelFlight: TunnelFlightService,
|
||||
private translateService: TranslateService,
|
||||
private dateService: DateService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
||||
if (data === true) {
|
||||
this.updateTitle();
|
||||
}
|
||||
});
|
||||
ngOnInit() {
|
||||
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
||||
if (data === true) {
|
||||
this.updateTitle();
|
||||
}
|
||||
});
|
||||
this.updateTitle();
|
||||
|
||||
this.chartConfig();
|
||||
this.selectedPeriod = "currentYear"
|
||||
this.getDataForGraph();
|
||||
}
|
||||
|
||||
public onPeriodChange() {
|
||||
this.getDataForGraph();
|
||||
if (this.dataSourceTable?.data.length > 0){
|
||||
this.getDataForTable();
|
||||
}
|
||||
this.chartConfig();
|
||||
this.selectedPeriod = "currentYear";
|
||||
this.getDataForGraph();
|
||||
}
|
||||
|
||||
public onPeriodChange() {
|
||||
this.getDataForGraph();
|
||||
if (this.dataSourceTable?.data.length > 0) {
|
||||
this.getDataForTable();
|
||||
}
|
||||
}
|
||||
|
||||
public onLoadTable() {
|
||||
this.getDataForTable();
|
||||
}
|
||||
public onLoadTable() {
|
||||
this.getDataForTable();
|
||||
}
|
||||
|
||||
private chartConfig() {
|
||||
this.barChartType = "bar";
|
||||
this.barChartOptions = {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
plugins: {
|
||||
legend: {
|
||||
display: true
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
footer: this.footer,
|
||||
}
|
||||
}
|
||||
},
|
||||
interaction: {
|
||||
intersect: false,
|
||||
mode: 'nearest',
|
||||
axis: 'x'
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
stacked: true
|
||||
},
|
||||
y: {
|
||||
stacked: true
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private updateTitle() {
|
||||
this.translateService.get("ListTunnelFlight_Title").subscribe(
|
||||
data => { this.serviceComm.updatedComponentTitle(data); }
|
||||
);
|
||||
}
|
||||
|
||||
private getDataForTable(): void {
|
||||
this.isLoading = true;
|
||||
|
||||
// Get data to show in a table
|
||||
let endDate = new Date();
|
||||
endDate.setHours(0, 0, 0, 0);
|
||||
let beginDate = this.computeBeginDateByPeriod(this.selectedPeriod, endDate);
|
||||
|
||||
this.serviceTunnelFlight.getTunnelFlights(beginDate, endDate)
|
||||
.subscribe((data) => {
|
||||
this.dataSourceTable.data = data;
|
||||
this.isLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
private getDataForGraph(): void {
|
||||
this.isLoading = true;
|
||||
|
||||
// Get data to show in a table
|
||||
let endDate = new Date();
|
||||
endDate.setHours(0, 0, 0, 0);
|
||||
let beginDate = this.computeBeginDateByPeriod(this.selectedPeriod, endDate);
|
||||
|
||||
this.serviceTunnelFlight.getTunnelFlightsByMonth(beginDate, endDate)
|
||||
.subscribe((data) => {
|
||||
const allMonths = this.getMontsBetweenDates(beginDate, endDate)
|
||||
const cumulatedTime = this.getCumulatedTimeByTypeByMonth(data, allMonths);
|
||||
this.computeTimeByType(data);
|
||||
this.barChartData = {
|
||||
labels: allMonths,
|
||||
datasets: cumulatedTime
|
||||
};
|
||||
|
||||
this.isLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
private computeTimeByType(stats: TunnelFlightByMonth[]) {
|
||||
this.stats = [];
|
||||
from(stats).pipe(
|
||||
groupBy((type) => type.type, { element: (p) => p.nb }),
|
||||
mergeMap((group$) =>
|
||||
group$.pipe(reduce((acc, cur) => [...acc, cur], [`${group$.key}`]))
|
||||
),
|
||||
map((arr) => ({ id: arr[0], values: arr.slice(1).reduce((a, b) => Number(a) + Number(b), 0) }))
|
||||
)
|
||||
.subscribe((p) => {
|
||||
console.log(p);
|
||||
this.stats.push(p);
|
||||
});
|
||||
}
|
||||
|
||||
private getMontsBetweenDates(beginDate: Date, endDate: Date): Array<string> {
|
||||
let results: Array<string> = [];
|
||||
let tmpBeginDate = new Date(beginDate.getTime());
|
||||
const tmpEndDate = new Date(endDate.getTime());
|
||||
|
||||
while (tmpBeginDate < tmpEndDate) {
|
||||
results.push(formatDate(tmpBeginDate, "yy-MM", "en"));
|
||||
tmpBeginDate.setMonth(tmpBeginDate.getMonth() + 1);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private getCumulatedTimeByTypeByMonth(stats: TunnelFlightByMonth[], allMonths: string[]): Array<any> {
|
||||
let tmpResults = new Map<string, number[]>();
|
||||
|
||||
const disctintType = Array.from(new Set(stats.map((item) => item.type)));
|
||||
disctintType.forEach(type => {
|
||||
tmpResults.set(type, Array.from({length: allMonths.length}, (v, k) => 0));
|
||||
});
|
||||
|
||||
for (let i = 0; i < allMonths.length; i++) {
|
||||
const month = allMonths[i];
|
||||
let filteredStats = stats.filter((d) => d.month == month);
|
||||
|
||||
if (filteredStats.length > 0){
|
||||
filteredStats.forEach(fs => {
|
||||
tmpResults.get(fs.type)[i] += fs.nb;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const results = Array.from(tmpResults, function (item) {
|
||||
return { label: item[0], data: item[1] }
|
||||
});
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private footer = (tooltipItems) => {
|
||||
let sum = 0;
|
||||
|
||||
tooltipItems.forEach(function (tooltipItem) {
|
||||
sum += tooltipItem.parsed.y;
|
||||
});
|
||||
|
||||
return 'Sum: ' + sum;
|
||||
private chartConfig() {
|
||||
this.barChartType = "bar";
|
||||
this.barChartOptions = {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
plugins: {
|
||||
legend: {
|
||||
display: true,
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
footer: this.footer,
|
||||
},
|
||||
},
|
||||
},
|
||||
interaction: {
|
||||
intersect: false,
|
||||
mode: "nearest",
|
||||
axis: "x",
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
stacked: true,
|
||||
},
|
||||
y: {
|
||||
stacked: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
private computeBeginDateByPeriod(selectedPeriod: String, endDate: Date): Date {
|
||||
let beginDate = new Date();
|
||||
|
||||
switch (selectedPeriod) {
|
||||
case "currentYear":
|
||||
beginDate = new Date(endDate.getFullYear(), 0, 1);
|
||||
break;
|
||||
case "12Months":
|
||||
beginDate = this.dateService.addMonths(endDate, -12);
|
||||
beginDate.setDate(1);
|
||||
break;
|
||||
case "all":
|
||||
beginDate = this.dateService.addMonths(endDate, -120);
|
||||
beginDate.setDate(1);
|
||||
break;
|
||||
}
|
||||
private updateTitle() {
|
||||
this.translateService.get("ListTunnelFlight_Title").subscribe((data) => {
|
||||
this.serviceComm.updatedComponentTitle(data);
|
||||
});
|
||||
}
|
||||
|
||||
return beginDate;
|
||||
}
|
||||
private getDataForTable(): void {
|
||||
this.isLoading = true;
|
||||
|
||||
public delete(item: TunnelFlight) {
|
||||
let data: Array<TunnelFlight> = this.dataSourceTable.data;
|
||||
data = data.filter((d) => d.id !== item.id);
|
||||
// Get data to show in a table
|
||||
let endDate = new Date();
|
||||
endDate.setHours(0, 0, 0, 0);
|
||||
let beginDate = this.computeBeginDateByPeriod(this.selectedPeriod, endDate);
|
||||
|
||||
this.serviceTunnelFlight
|
||||
.getTunnelFlights(beginDate, endDate)
|
||||
.subscribe((data) => {
|
||||
this.dataSourceTable.data = data;
|
||||
this.serviceTunnelFlight.deleteTunnelFlight(item);
|
||||
this.isLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
private getDataForGraph(): void {
|
||||
this.isLoading = true;
|
||||
|
||||
// Get data to show in a table
|
||||
let endDate = new Date();
|
||||
endDate.setHours(0, 0, 0, 0);
|
||||
let beginDate = this.computeBeginDateByPeriod(this.selectedPeriod, endDate);
|
||||
|
||||
this.serviceTunnelFlight
|
||||
.getTunnelFlightsByMonth(beginDate, endDate)
|
||||
.subscribe((data) => {
|
||||
const allMonths = this.getMontsBetweenDates(beginDate, endDate);
|
||||
const cumulatedTime = this.getCumulatedTimeByTypeByMonth(
|
||||
data,
|
||||
allMonths
|
||||
);
|
||||
this.computeTimeByType(data);
|
||||
this.barChartData = {
|
||||
labels: allMonths,
|
||||
datasets: cumulatedTime,
|
||||
};
|
||||
|
||||
this.isLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
private computeTimeByType(stats: TunnelFlightByMonth[]) {
|
||||
this.stats = [];
|
||||
from(stats)
|
||||
.pipe(
|
||||
groupBy((type) => type.type, { element: (p) => p.nb }),
|
||||
mergeMap((group$) =>
|
||||
group$.pipe(reduce((acc, cur) => [...acc, cur], [`${group$.key}`]))
|
||||
),
|
||||
map((arr) => ({
|
||||
id: arr[0],
|
||||
values: arr.slice(1).reduce((a, b) => Number(a) + Number(b), 0),
|
||||
}))
|
||||
)
|
||||
.subscribe((p) => {
|
||||
console.log(p);
|
||||
this.stats.push(p);
|
||||
});
|
||||
}
|
||||
|
||||
private getMontsBetweenDates(beginDate: Date, endDate: Date): Array<string> {
|
||||
let results: Array<string> = [];
|
||||
let tmpBeginDate = new Date(beginDate.getTime());
|
||||
const tmpEndDate = new Date(endDate.getTime());
|
||||
|
||||
while (tmpBeginDate < tmpEndDate) {
|
||||
results.push(formatDate(tmpBeginDate, "yy-MM", "en"));
|
||||
tmpBeginDate.setMonth(tmpBeginDate.getMonth() + 1);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private getCumulatedTimeByTypeByMonth(
|
||||
stats: TunnelFlightByMonth[],
|
||||
allMonths: string[]
|
||||
): Array<any> {
|
||||
let tmpResults = new Map<string, number[]>();
|
||||
|
||||
const disctintType = Array.from(new Set(stats.map((item) => item.type)));
|
||||
disctintType.forEach((type) => {
|
||||
tmpResults.set(
|
||||
type,
|
||||
Array.from({ length: allMonths.length }, (v, k) => 0)
|
||||
);
|
||||
});
|
||||
|
||||
for (let i = 0; i < allMonths.length; i++) {
|
||||
const month = allMonths[i];
|
||||
let filteredStats = stats.filter((d) => d.month == month);
|
||||
|
||||
if (filteredStats.length > 0) {
|
||||
filteredStats.forEach((fs) => {
|
||||
tmpResults.get(fs.type)[i] += fs.nb;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const results = Array.from(tmpResults, function (item) {
|
||||
return { label: item[0], data: item[1] };
|
||||
});
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private footer = (tooltipItems: any) => {
|
||||
let sum = 0;
|
||||
|
||||
tooltipItems.forEach(function (tooltipItem: any) {
|
||||
sum += tooltipItem.parsed.y;
|
||||
});
|
||||
|
||||
return "Sum: " + sum;
|
||||
};
|
||||
|
||||
private computeBeginDateByPeriod(
|
||||
selectedPeriod: String,
|
||||
endDate: Date
|
||||
): Date {
|
||||
let beginDate = new Date();
|
||||
|
||||
switch (selectedPeriod) {
|
||||
case "currentYear":
|
||||
beginDate = new Date(endDate.getFullYear(), 0, 1);
|
||||
break;
|
||||
case "12Months":
|
||||
beginDate = this.dateService.addMonths(endDate, -12);
|
||||
beginDate.setDate(1);
|
||||
break;
|
||||
case "all":
|
||||
beginDate = this.dateService.addMonths(endDate, -120);
|
||||
beginDate.setDate(1);
|
||||
break;
|
||||
}
|
||||
|
||||
return beginDate;
|
||||
}
|
||||
|
||||
public delete(item: TunnelFlight) {
|
||||
let data: Array<TunnelFlight> = this.dataSourceTable.data;
|
||||
data = data.filter((d) => d.id !== item.id);
|
||||
|
||||
this.dataSourceTable.data = data;
|
||||
this.serviceTunnelFlight.deleteTunnelFlight(item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +1,50 @@
|
||||
<form focusInvalidInput autocomplete="off" style="padding: 10px;"
|
||||
[formGroup]="loginForm" (ngSubmit)="onLoginSubmit()">
|
||||
<form
|
||||
focusInvalidInput
|
||||
autocomplete="off"
|
||||
style="padding: 10px"
|
||||
[formGroup]="loginForm"
|
||||
(ngSubmit)="onLoginSubmit()"
|
||||
>
|
||||
<p>
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'LoginUser_Username' | translate }}</mat-label>
|
||||
<input type="text" matInput #username="matInput" formControlName="username"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls.username.errors }">
|
||||
<mat-error *ngIf="formCtrls.username.hasError('required')">
|
||||
{{ 'LoginUser_UsernameRequired' | translate }}
|
||||
<mat-label>{{ "LoginUser_Username" | translate }}</mat-label>
|
||||
<input
|
||||
type="text"
|
||||
matInput
|
||||
#username="matInput"
|
||||
formControlName="username"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls['username'].errors }"
|
||||
/>
|
||||
<mat-error *ngIf="formCtrls['username'].hasError('required')">
|
||||
{{ "LoginUser_UsernameRequired" | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="formCtrls.username.hasError('minlength')">
|
||||
<mat-error *ngIf="formCtrls['username'].hasError('minlength')">
|
||||
{{ 'LoginUser_UsernamePattern | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</p>
|
||||
<p>
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'LoginUser_Password' | translate }}</mat-label>
|
||||
<input type="password" matInput formControlName="password"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls.password.errors }">
|
||||
<mat-error *ngIf="formCtrls.password.hasError('required')">
|
||||
{{ 'LoginUser_PasswordRequired' | translate }}
|
||||
<mat-label>{{ "LoginUser_Password" | translate }}</mat-label>
|
||||
<input
|
||||
type="password"
|
||||
matInput
|
||||
formControlName="password"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls['password'].errors }"
|
||||
/>
|
||||
<mat-error *ngIf="formCtrls['password'].hasError('required')">
|
||||
{{ "LoginUser_PasswordRequired" | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="formCtrls.password.hasError('pattern')">
|
||||
{{ 'LoginUser_PasswordPattern' | translate }}
|
||||
<mat-error *ngIf="formCtrls['password'].hasError('pattern')">
|
||||
{{ "LoginUser_PasswordPattern" | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</p>
|
||||
|
||||
<button [disabled]="loading" mat-raised-button color="accent">
|
||||
<span *ngIf="loading" class="spinner-border spinner-border-sm mr-1"></span>
|
||||
{{ 'LoginUser_BtnLogin' | translate }}
|
||||
{{ "LoginUser_BtnLogin" | translate }}
|
||||
</button>
|
||||
|
||||
<div *ngIf="error" class="alert alert-danger mt-3 mb-0">{{error}}</div>
|
||||
<div *ngIf="error" class="alert alert-danger mt-3 mb-0">{{ error }}</div>
|
||||
</form>
|
||||
|
||||
@@ -1,32 +1,34 @@
|
||||
import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { MatInput } from '@angular/material/input';
|
||||
import { Component, OnInit, ViewChild, AfterViewInit } from "@angular/core";
|
||||
import { Router, ActivatedRoute } from "@angular/router";
|
||||
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
|
||||
import { MatInput } from "@angular/material/input";
|
||||
|
||||
import { first } from 'rxjs/operators';
|
||||
import { first } from "rxjs/operators";
|
||||
|
||||
import { AuthenticationService } from '../../services/authentication.service';
|
||||
import { AuthenticationService } from "../../services/authentication.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-login-user',
|
||||
templateUrl: './login-user.component.html',
|
||||
styleUrls: ['./login-user.component.css'],
|
||||
standalone: false
|
||||
selector: "app-login-user",
|
||||
templateUrl: "./login-user.component.html",
|
||||
styleUrls: ["./login-user.component.css"],
|
||||
standalone: false,
|
||||
})
|
||||
export class LoginUserComponent implements OnInit, AfterViewInit {
|
||||
loginForm: FormGroup;
|
||||
loading = false;
|
||||
submitted = false;
|
||||
returnUrl: string;
|
||||
error = '';
|
||||
@ViewChild('username') userNameInput: MatInput;
|
||||
error = "";
|
||||
@ViewChild("username") userNameInput: MatInput;
|
||||
|
||||
constructor(private formBuilder: FormBuilder,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private authenticationService: AuthenticationService) {
|
||||
constructor(
|
||||
private formBuilder: FormBuilder,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private authenticationService: AuthenticationService
|
||||
) {
|
||||
if (this.authenticationService.currentUserValue) {
|
||||
this.router.navigate(['/']);
|
||||
this.router.navigate(["/"]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,15 +39,14 @@ export class LoginUserComponent implements OnInit, AfterViewInit {
|
||||
ngOnInit() {
|
||||
this.loginForm = this.formBuilder.group(
|
||||
{
|
||||
username: ['', [Validators.required, Validators.minLength(3)]],
|
||||
password: ['', [Validators.required]]
|
||||
username: ["", [Validators.required, Validators.minLength(3)]],
|
||||
password: ["", [Validators.required]],
|
||||
},
|
||||
{ updateOn: 'submit' }
|
||||
{ updateOn: "submit" }
|
||||
);
|
||||
|
||||
// get return url from route parameters or default to '/'
|
||||
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
|
||||
|
||||
this.returnUrl = this.route.snapshot.queryParams["returnUrl"] || "/";
|
||||
}
|
||||
|
||||
get formCtrls() {
|
||||
@@ -57,17 +58,21 @@ export class LoginUserComponent implements OnInit, AfterViewInit {
|
||||
|
||||
if (this.loginForm.valid) {
|
||||
this.loading = true;
|
||||
this.authenticationService.login(this.formCtrls.username.value, this.formCtrls.password.value)
|
||||
.pipe(first())
|
||||
.subscribe(
|
||||
data => {
|
||||
this.router.navigate([this.returnUrl]);
|
||||
},
|
||||
error => {
|
||||
this.error = error;
|
||||
this.loading = false;
|
||||
}
|
||||
);
|
||||
this.authenticationService
|
||||
.login(
|
||||
this.formCtrls["username"].value,
|
||||
this.formCtrls["password"].value
|
||||
)
|
||||
.pipe(first())
|
||||
.subscribe(
|
||||
(data) => {
|
||||
this.router.navigate([this.returnUrl]);
|
||||
},
|
||||
(error) => {
|
||||
this.error = error;
|
||||
this.loading = false;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpRequest, HttpResponse } from '@angular/common/http';
|
||||
import { Injectable } from "@angular/core";
|
||||
import { HttpRequest, HttpResponse } from "@angular/common/http";
|
||||
|
||||
@Injectable()
|
||||
export class RequestCache {
|
||||
@@ -10,8 +10,8 @@ export class RequestCache {
|
||||
}
|
||||
|
||||
get(req: HttpRequest<any>): HttpResponse<any> | undefined {
|
||||
const splittedUrl = req.urlWithParams.split('/');
|
||||
const url = splittedUrl[splittedUrl.length - 1] + '_' + req.method;
|
||||
const splittedUrl = req.urlWithParams.split("/");
|
||||
const url = splittedUrl[splittedUrl.length - 1] + "_" + req.method;
|
||||
this.clearExpiredEntries();
|
||||
const cached = this.cache.get(url);
|
||||
|
||||
@@ -24,8 +24,8 @@ export class RequestCache {
|
||||
}
|
||||
|
||||
put(req: HttpRequest<any>, response: HttpResponse<any>): void {
|
||||
const splittedUrl = req.urlWithParams.split('/');
|
||||
const url = splittedUrl[splittedUrl.length - 1] + '_' + req.method;
|
||||
const splittedUrl = req.urlWithParams.split("/");
|
||||
const url = splittedUrl[splittedUrl.length - 1] + "_" + req.method;
|
||||
|
||||
const entry = { url, response, lastRead: Date.now() };
|
||||
this.cache.set(url, entry);
|
||||
@@ -36,7 +36,7 @@ export class RequestCache {
|
||||
const maxAge = 30000;
|
||||
const expired = Date.now() - maxAge;
|
||||
|
||||
this.cache.forEach(expiredEntry => {
|
||||
this.cache.forEach((expiredEntry) => {
|
||||
if (expiredEntry.lastRead < expired) {
|
||||
this.cache.delete(expiredEntry.url);
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/app",
|
||||
"baseUrl": "./",
|
||||
"types": []
|
||||
},
|
||||
"files": [
|
||||
"main.ts",
|
||||
"polyfills.ts"
|
||||
]
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/spec",
|
||||
"baseUrl": "./",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"test.ts",
|
||||
"polyfills.ts"
|
||||
],
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
||||
15
Front/skydivelogs-app/tsconfig.app.json
Normal file
15
Front/skydivelogs-app/tsconfig.app.json
Normal file
@@ -0,0 +1,15 @@
|
||||
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
||||
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./out-tsc/app",
|
||||
"types": []
|
||||
},
|
||||
"files": [
|
||||
"src/main.ts"
|
||||
],
|
||||
"include": [
|
||||
"src/**/*.d.ts"
|
||||
]
|
||||
}
|
||||
@@ -1,25 +1,29 @@
|
||||
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
||||
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
||||
{
|
||||
"compileOnSave": false,
|
||||
"angularCompilerOptions": {
|
||||
"strictTemplates": true,
|
||||
},
|
||||
"compilerOptions": {
|
||||
"importHelpers": true,
|
||||
"outDir": "./dist/out-tsc",
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"skipLibCheck": true,
|
||||
"isolatedModules": true,
|
||||
"esModuleInterop": true,
|
||||
"sourceMap": true,
|
||||
"declaration": false,
|
||||
"moduleResolution": "node",
|
||||
"experimentalDecorators": true,
|
||||
"target": "es2015",
|
||||
"typeRoots": [
|
||||
"node_modules/@types"
|
||||
],
|
||||
"lib": [
|
||||
"es2017",
|
||||
"dom"
|
||||
],
|
||||
"module": "esnext",
|
||||
"baseUrl": "./"
|
||||
"moduleResolution": "bundler",
|
||||
"importHelpers": true,
|
||||
"target": "ES2022",
|
||||
"module": "ES2022",
|
||||
"strictPropertyInitialization": false,
|
||||
"strictNullChecks": false
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"enableI18nLegacyMessageIdFormat": false,
|
||||
"strictInjectionParameters": true,
|
||||
"strictInputAccessModifiers": true,
|
||||
"strictTemplates": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
15
Front/skydivelogs-app/tsconfig.spec.json
Normal file
15
Front/skydivelogs-app/tsconfig.spec.json
Normal file
@@ -0,0 +1,15 @@
|
||||
/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */
|
||||
/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./out-tsc/spec",
|
||||
"types": [
|
||||
"jasmine"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.spec.ts",
|
||||
"src/**/*.d.ts"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user