update Angular to v20
Reviewed-on: #4 Co-authored-by: sandre <perso@sebastienandre.com> Co-committed-by: sandre <perso@sebastienandre.com>
This commit was merged in pull request #4.
This commit is contained in:
@@ -345,6 +345,7 @@ namespace skydiveLogs_api.DomainBusiness
|
|||||||
myStats.ForLastMonthByJumpType = resetStats.ForLastMonthByJumpType;
|
myStats.ForLastMonthByJumpType = resetStats.ForLastMonthByJumpType;
|
||||||
myStats.ForLastYearByDz = resetStats.ForLastYearByDz;
|
myStats.ForLastYearByDz = resetStats.ForLastYearByDz;
|
||||||
myStats.ForLastYearByJumpType = resetStats.ForLastYearByJumpType;
|
myStats.ForLastYearByJumpType = resetStats.ForLastYearByJumpType;
|
||||||
|
myStats.ByYearByJumpType = resetStats.ByYearByJumpType;
|
||||||
|
|
||||||
_userStatsRepository.Update(myStats);
|
_userStatsRepository.Update(myStats);
|
||||||
}
|
}
|
||||||
@@ -358,8 +359,10 @@ namespace skydiveLogs_api.DomainBusiness
|
|||||||
var allStats = _userStatsRepository.GetAll(_identityService.ConnectedUser);
|
var allStats = _userStatsRepository.GetAll(_identityService.ConnectedUser);
|
||||||
if (allStats == null)
|
if (allStats == null)
|
||||||
{
|
{
|
||||||
allStats = new UserStats();
|
allStats = new UserStats
|
||||||
allStats.User = _identityService.ConnectedUser;
|
{
|
||||||
|
User = _identityService.ConnectedUser
|
||||||
|
};
|
||||||
_userStatsRepository.Add(allStats);
|
_userStatsRepository.Add(allStats);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
19
Dockerfile
19
Dockerfile
@@ -2,15 +2,17 @@
|
|||||||
|
|
||||||
# Use the official Microsoft ASP.NET Core image to build the backend
|
# Use the official Microsoft ASP.NET Core image to build the backend
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build-backend
|
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build-backend
|
||||||
WORKDIR "/src/backend"
|
WORKDIR /src/backend
|
||||||
COPY Back/ .
|
COPY Back .
|
||||||
RUN dotnet restore "skydiveLogs-api/skydiveLogs-api.csproj"
|
RUN dotnet restore skydiveLogs-api/skydiveLogs-api.csproj
|
||||||
RUN dotnet publish "skydiveLogs-api/skydiveLogs-api.csproj" -c Release -o /app/publish
|
RUN dotnet publish skydiveLogs-api/skydiveLogs-api.csproj -c Release -o /app/publish
|
||||||
|
|
||||||
# Use the official node image to build the Angular app
|
# Use the official node image to build the Angular app
|
||||||
FROM node:20-alpine AS build-frontend
|
FROM node:22-alpine AS build-frontend
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY ["Front/skydivelogs-app/package.json", "Front/skydivelogs-app/package-lock.json*", "./"]
|
# COPY ["../Front/skydivelogs-app/package.json", "../Front/skydivelogs-app/package-lock.json*", "./"]
|
||||||
|
COPY Front/skydivelogs-app/package.json .
|
||||||
|
COPY Front/skydivelogs-app/package-lock.json .
|
||||||
RUN npm install
|
RUN npm install
|
||||||
COPY --exclude=Front/skydivelogs-app/node_modules/* Front/skydivelogs-app/ .
|
COPY --exclude=Front/skydivelogs-app/node_modules/* Front/skydivelogs-app/ .
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
@@ -21,13 +23,12 @@ WORKDIR /app
|
|||||||
|
|
||||||
# Install nginx
|
# Install nginx
|
||||||
RUN apt-get update && apt-get install -y nginx curl && rm -rf /var/lib/apt/lists/*
|
RUN apt-get update && apt-get install -y nginx curl && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Copy custom nginx configuration
|
# Copy custom nginx configuration
|
||||||
COPY nginx.conf /etc/nginx/sites-available/default
|
COPY nginx.conf /etc/nginx/sites-available/default
|
||||||
RUN rm -rf /usr/share/nginx/html/*
|
RUN rm -rf /usr/share/nginx/html/*
|
||||||
|
|
||||||
# Copy frontend dist folder to nginx html directory
|
# Copy frontend dist folder to nginx html directory
|
||||||
COPY --from=build-frontend /app/dist/browser /usr/share/nginx/html
|
COPY --from=build-frontend --exclude=/app/dist/browser/config/* /app/dist/browser /usr/share/nginx/html
|
||||||
|
RUN mkdir -p /usr/share/nginx/html/config
|
||||||
|
|
||||||
# Copy backend from the correct build stage
|
# Copy backend from the correct build stage
|
||||||
COPY --from=build-backend /app/publish /app
|
COPY --from=build-backend /app/publish /app
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ root = true
|
|||||||
[*]
|
[*]
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 2
|
indent_size = 4
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
|||||||
@@ -1,123 +1,145 @@
|
|||||||
{
|
{
|
||||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"newProjectRoot": "projects",
|
"newProjectRoot": "projects",
|
||||||
"projects": {
|
"projects": {
|
||||||
"skydivelogs-app": {
|
"skydivelogs-app": {
|
||||||
"projectType": "application",
|
"projectType": "application",
|
||||||
"schematics": {
|
"schematics": {
|
||||||
|
"@schematics/angular:component": {
|
||||||
|
"style": "scss"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "",
|
||||||
|
"sourceRoot": "src",
|
||||||
|
"prefix": "app",
|
||||||
|
"architect": {
|
||||||
|
"build": {
|
||||||
|
"builder": "@angular/build:application",
|
||||||
|
"options": {
|
||||||
|
"outputPath": "dist",
|
||||||
|
"index": "src/index.html",
|
||||||
|
"browser": "src/main.ts",
|
||||||
|
"polyfills": ["zone.js"],
|
||||||
|
"tsConfig": "tsconfig.app.json",
|
||||||
|
"inlineStyleLanguage": "scss",
|
||||||
|
"assets": [
|
||||||
|
"src/assets",
|
||||||
|
"src/config",
|
||||||
|
"src/favicon.ico"
|
||||||
|
],
|
||||||
|
"styles": [
|
||||||
|
"src/assets/css/styles-app-loading.scss",
|
||||||
|
"src/assets/css/styles.css",
|
||||||
|
"src/assets/css/new-theme.scss",
|
||||||
|
"@angular/material/prebuilt-themes/pink-bluegrey.css"
|
||||||
|
],
|
||||||
|
"scripts": []
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"budgets": [
|
||||||
|
{
|
||||||
|
"type": "initial",
|
||||||
|
"maximumWarning": "2mb",
|
||||||
|
"maximumError": "5mb"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "bundle",
|
||||||
|
"name": "main",
|
||||||
|
"baseline": "1mb",
|
||||||
|
"maximumWarning": "1.5mb",
|
||||||
|
"maximumError": "2mb"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "anyComponentStyle",
|
||||||
|
"maximumWarning": "2kb",
|
||||||
|
"maximumError": "4kb"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputHashing": "all",
|
||||||
|
"optimization": true,
|
||||||
|
"extractLicenses": true,
|
||||||
|
"sourceMap": false,
|
||||||
|
"fileReplacements": [
|
||||||
|
{
|
||||||
|
"replace": "src/environments/environment.ts",
|
||||||
|
"with": "src/environments/environment.prod.ts"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"development": {
|
||||||
|
"optimization": false,
|
||||||
|
"extractLicenses": false,
|
||||||
|
"sourceMap": true,
|
||||||
|
"fileReplacements": [
|
||||||
|
{
|
||||||
|
"replace": "src/environments/environment.ts",
|
||||||
|
"with": "src/environments/environment.dev.ts"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"defaultConfiguration": "production"
|
||||||
|
},
|
||||||
|
"serve": {
|
||||||
|
"builder": "@angular/build:dev-server",
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"buildTarget": "skydivelogs-app:build:production"
|
||||||
|
},
|
||||||
|
"development": {
|
||||||
|
"buildTarget": "skydivelogs-app:build:development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"defaultConfiguration": "development"
|
||||||
|
},
|
||||||
|
"extract-i18n": {
|
||||||
|
"builder": "@angular/build:extract-i18n"
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"builder": "@angular/build:karma",
|
||||||
|
"options": {
|
||||||
|
"polyfills": ["zone.js", "zone.js/testing"],
|
||||||
|
"tsConfig": "tsconfig.spec.json",
|
||||||
|
"inlineStyleLanguage": "scss",
|
||||||
|
"assets": [
|
||||||
|
{
|
||||||
|
"glob": "**/*",
|
||||||
|
"input": "public"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"styles": ["src/styles.scss"],
|
||||||
|
"scripts": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"schematics": {
|
||||||
"@schematics/angular:component": {
|
"@schematics/angular:component": {
|
||||||
"style": "scss"
|
"type": "component"
|
||||||
|
},
|
||||||
|
"@schematics/angular:directive": {
|
||||||
|
"type": "directive"
|
||||||
|
},
|
||||||
|
"@schematics/angular:service": {
|
||||||
|
"type": "service"
|
||||||
|
},
|
||||||
|
"@schematics/angular:guard": {
|
||||||
|
"typeSeparator": "."
|
||||||
|
},
|
||||||
|
"@schematics/angular:interceptor": {
|
||||||
|
"typeSeparator": "."
|
||||||
|
},
|
||||||
|
"@schematics/angular:module": {
|
||||||
|
"typeSeparator": "."
|
||||||
|
},
|
||||||
|
"@schematics/angular:pipe": {
|
||||||
|
"typeSeparator": "."
|
||||||
|
},
|
||||||
|
"@schematics/angular:resolver": {
|
||||||
|
"typeSeparator": "."
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"root": "",
|
|
||||||
"sourceRoot": "src",
|
|
||||||
"prefix": "app",
|
|
||||||
"architect": {
|
|
||||||
"build": {
|
|
||||||
"builder": "@angular-devkit/build-angular:application",
|
|
||||||
"options": {
|
|
||||||
"outputPath": "dist",
|
|
||||||
"index": "src/index.html",
|
|
||||||
"browser": "src/main.ts",
|
|
||||||
"polyfills": ["zone.js"],
|
|
||||||
"tsConfig": "tsconfig.app.json",
|
|
||||||
"inlineStyleLanguage": "scss",
|
|
||||||
"assets": [
|
|
||||||
"src/assets",
|
|
||||||
"src/config",
|
|
||||||
"src/favicon.ico",
|
|
||||||
{
|
|
||||||
"glob": "**/*",
|
|
||||||
"input": "public"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"styles": [
|
|
||||||
"src/assets/css/styles-app-loading.scss",
|
|
||||||
"src/assets/css/styles.css",
|
|
||||||
"src/assets/css/new-theme.scss",
|
|
||||||
"@angular/material/prebuilt-themes/pink-bluegrey.css"
|
|
||||||
],
|
|
||||||
"scripts": []
|
|
||||||
},
|
|
||||||
"configurations": {
|
|
||||||
"production": {
|
|
||||||
"budgets": [
|
|
||||||
{
|
|
||||||
"type": "initial",
|
|
||||||
"maximumWarning": "2mb",
|
|
||||||
"maximumError": "5mb"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "bundle",
|
|
||||||
"name": "main",
|
|
||||||
"baseline": "1mb",
|
|
||||||
"maximumWarning": "1.5mb",
|
|
||||||
"maximumError": "2mb"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "anyComponentStyle",
|
|
||||||
"maximumWarning": "2kb",
|
|
||||||
"maximumError": "4kb"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"outputHashing": "all",
|
|
||||||
"optimization": true,
|
|
||||||
"extractLicenses": true,
|
|
||||||
"sourceMap": false,
|
|
||||||
"fileReplacements": [
|
|
||||||
{
|
|
||||||
"replace": "src/environments/environment.ts",
|
|
||||||
"with": "src/environments/environment.prod.ts"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"development": {
|
|
||||||
"optimization": false,
|
|
||||||
"extractLicenses": false,
|
|
||||||
"sourceMap": true,
|
|
||||||
"fileReplacements": [
|
|
||||||
{
|
|
||||||
"replace": "src/environments/environment.ts",
|
|
||||||
"with": "src/environments/environment.dev.ts"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"defaultConfiguration": "production"
|
|
||||||
},
|
|
||||||
"serve": {
|
|
||||||
"builder": "@angular-devkit/build-angular:dev-server",
|
|
||||||
"configurations": {
|
|
||||||
"production": {
|
|
||||||
"buildTarget": "skydivelogs-app:build:production"
|
|
||||||
},
|
|
||||||
"development": {
|
|
||||||
"buildTarget": "skydivelogs-app:build:development"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"defaultConfiguration": "development"
|
|
||||||
},
|
|
||||||
"extract-i18n": {
|
|
||||||
"builder": "@angular-devkit/build-angular:extract-i18n"
|
|
||||||
},
|
|
||||||
"test": {
|
|
||||||
"builder": "@angular-devkit/build-angular:karma",
|
|
||||||
"options": {
|
|
||||||
"polyfills": ["zone.js", "zone.js/testing"],
|
|
||||||
"tsConfig": "tsconfig.spec.json",
|
|
||||||
"inlineStyleLanguage": "scss",
|
|
||||||
"assets": [
|
|
||||||
{
|
|
||||||
"glob": "**/*",
|
|
||||||
"input": "public"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"styles": ["src/styles.scss"],
|
|
||||||
"scripts": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
8036
Front/skydivelogs-app/package-lock.json
generated
8036
Front/skydivelogs-app/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,46 +1,46 @@
|
|||||||
{
|
{
|
||||||
"name": "skydivelogs-app",
|
"name": "skydivelogs-app",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"ng": "ng",
|
"ng": "ng",
|
||||||
"start": "ng serve",
|
"start": "ng serve",
|
||||||
"build": "ng build",
|
"build": "ng build --configuration production",
|
||||||
"test": "ng test",
|
"test": "ng test",
|
||||||
"lint": "ng lint",
|
"lint": "ng lint",
|
||||||
"e2e": "ng e2e"
|
"e2e": "ng e2e"
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "^19.2.6",
|
"@angular/animations": "^20.3.16",
|
||||||
"@angular/cdk": "^19.2.9",
|
"@angular/cdk": "^20.2.14",
|
||||||
"@angular/common": "^19.2.6",
|
"@angular/common": "^20.3.16",
|
||||||
"@angular/compiler": "^19.2.6",
|
"@angular/compiler": "^20.3.16",
|
||||||
"@angular/core": "^19.2.6",
|
"@angular/core": "^20.3.16",
|
||||||
"@angular/forms": "^19.2.6",
|
"@angular/forms": "^20.3.16",
|
||||||
"@angular/material": "^19.2.9",
|
"@angular/material": "^20.2.14",
|
||||||
"@angular/platform-browser": "^19.2.6",
|
"@angular/platform-browser": "^20.3.16",
|
||||||
"@angular/platform-browser-dynamic": "^19.2.6",
|
"@angular/platform-browser-dynamic": "^20.3.16",
|
||||||
"@angular/router": "^19.2.6",
|
"@angular/router": "^20.3.16",
|
||||||
"@ngx-translate/core": "^17.0.0",
|
"@ngx-translate/core": "^17.0.0",
|
||||||
"@ngx-translate/http-loader": "^17.0.0",
|
"@ngx-translate/http-loader": "^17.0.0",
|
||||||
"chart.js": "^4.3.0",
|
"chart.js": "^4.3.0",
|
||||||
"ng2-charts": "^8.0.0",
|
"ng2-charts": "^8.0.0",
|
||||||
"rxjs": "~7.8.0",
|
"rxjs": "~7.8.0",
|
||||||
"tslib": "^2.3.0",
|
"tslib": "^2.3.0",
|
||||||
"zone.js": "~0.15.0"
|
"zone.js": "~0.15.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-devkit/build-angular": "^19.2.7",
|
"@angular/build": "^20.3.14",
|
||||||
"@angular/cli": "~19.2.7",
|
"@angular/cli": "~20.3.14",
|
||||||
"@angular/compiler-cli": "^19.2.6",
|
"@angular/compiler-cli": "^20.3.16",
|
||||||
"@types/jasmine": "~4.3.0",
|
"@types/jasmine": "~4.3.0",
|
||||||
"jasmine-core": "~5.1.0",
|
"jasmine-core": "~5.1.0",
|
||||||
"karma": "~6.4.0",
|
"karma": "~6.4.0",
|
||||||
"karma-chrome-launcher": "~3.2.0",
|
"karma-chrome-launcher": "~3.2.0",
|
||||||
"karma-coverage": "~2.2.0",
|
"karma-coverage": "~2.2.0",
|
||||||
"karma-jasmine": "~5.1.0",
|
"karma-jasmine": "~5.1.0",
|
||||||
"karma-jasmine-html-reporter": "~2.1.0",
|
"karma-jasmine-html-reporter": "~2.1.0",
|
||||||
"typescript": "~5.5.4"
|
"typescript": "~5.9.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
import { inject, OnInit } from "@angular/core";
|
|
||||||
import { IconResolver, MatIconRegistry } from "@angular/material/icon";
|
|
||||||
import { DomSanitizer } from "@angular/platform-browser";
|
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
|
||||||
import { ServiceComm } from "../services/service-comm.service";
|
|
||||||
|
|
||||||
@decorator
|
|
||||||
export class BaseComponent implements OnInit {
|
|
||||||
private titleId: string = "???";
|
|
||||||
protected serviceComm: ServiceComm;
|
|
||||||
protected translateService: TranslateService;
|
|
||||||
|
|
||||||
constructor(titleId: string) {
|
|
||||||
let iconRegistry = inject(MatIconRegistry);
|
|
||||||
let sanitizer = inject(DomSanitizer);
|
|
||||||
const resolver: IconResolver = (name) =>
|
|
||||||
sanitizer.bypassSecurityTrustResourceUrl(`/assets/icon/${name}.svg`);
|
|
||||||
iconRegistry.addSvgIconResolver(resolver);
|
|
||||||
|
|
||||||
this.serviceComm = inject(ServiceComm);
|
|
||||||
this.translateService = inject(TranslateService);
|
|
||||||
this.titleId = titleId;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.translateService.get(this.titleId).subscribe((data) => {
|
|
||||||
this.serviceComm.updatedComponentTitle(data);
|
|
||||||
// this.serviceComm.componentTitle.subscribe((title) => (this.title = data));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function decorator(target: typeof BaseComponent): void | typeof BaseComponent {}
|
|
||||||
@@ -1,56 +1,44 @@
|
|||||||
/* .hamburger__icon {
|
|
||||||
position: relative;
|
|
||||||
height: 1rem;
|
|
||||||
margin-right: 1rem;
|
|
||||||
cursor: pointer;
|
|
||||||
fill: #ffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hamburger__icon__fill {
|
|
||||||
fill: #424242
|
|
||||||
} */
|
|
||||||
|
|
||||||
.navigation.side-menu-active {
|
.navigation.side-menu-active {
|
||||||
left: 0px;
|
left: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navigation {
|
.navigation {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 200px;
|
width: 200px;
|
||||||
z-index: 101;
|
z-index: 101;
|
||||||
background-color: grey;
|
background-color: grey;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
left: -220px;
|
left: -220px;
|
||||||
transition: 0.5s linear left;
|
transition: 0.5s linear left;
|
||||||
-webkit-transition: 0.5s linear left;
|
-webkit-transition: 0.5s linear left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navigation ul {
|
.navigation ul {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navigation ul li {
|
.navigation ul li {
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navigation ul li a {
|
.navigation ul li a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: #424242;
|
color: #424242;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navigation .mat-icon {
|
.navigation .mat-icon {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navigation .splitter {
|
.navigation .splitter {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mat-icon {
|
.mat-icon {
|
||||||
margin-right: 15px;
|
margin-right: 15px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,190 +1,200 @@
|
|||||||
<mat-toolbar *ngIf="this.show()">
|
@if (this.show()) {
|
||||||
<mat-icon svgIcon="menu" (click)="snav.toggle()"></mat-icon>
|
<mat-toolbar>
|
||||||
<h2>{{ translatedTitle }}</h2>
|
<h2 (click)="snav.toggle()">
|
||||||
|
<mat-icon svgIcon="menu"></mat-icon>
|
||||||
<mat-select
|
{{ translatedTitle }}
|
||||||
[(value)]="selectedLanguageFlag"
|
</h2>
|
||||||
(selectionChange)="switchLang($event)"
|
<mat-select
|
||||||
style="margin-left: 50px; width: 100px"
|
[(value)]="selectedLanguageFlag"
|
||||||
>
|
(selectionChange)="switchLang($event)"
|
||||||
<mat-select-trigger>
|
style="margin-left: 50px; width: 100px"
|
||||||
<img
|
>
|
||||||
src="{{ 'assets/img/' + selectedLanguageFlag + '.svg' }}"
|
<mat-select-trigger>
|
||||||
style="width: 30px"
|
<img
|
||||||
/>
|
src="{{ 'assets/img/' + selectedLanguageFlag + '.svg' }}"
|
||||||
</mat-select-trigger>
|
style="width: 30px"
|
||||||
<mat-option value="fr">
|
/>
|
||||||
<img src="assets/img/fr.svg" style="width: 30px" />
|
</mat-select-trigger>
|
||||||
</mat-option>
|
<mat-option value="fr">
|
||||||
<mat-option value="en">
|
<img src="assets/img/fr.svg" style="width: 30px" />
|
||||||
<img src="assets/img/en.svg" style="width: 30px" />
|
</mat-option>
|
||||||
</mat-option>
|
<mat-option value="en">
|
||||||
</mat-select>
|
<img src="assets/img/en.svg" style="width: 30px" />
|
||||||
</mat-toolbar>
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-toolbar>
|
||||||
|
}
|
||||||
|
|
||||||
<mat-sidenav-container>
|
<mat-sidenav-container>
|
||||||
<mat-sidenav #snav mode="over" style="padding: 0 20px 0 10px">
|
<mat-sidenav #snav mode="over" style="padding: 0 20px 0 10px">
|
||||||
<mat-nav-list>
|
<mat-nav-list>
|
||||||
<mat-icon
|
<mat-icon
|
||||||
aria-hidden="false"
|
aria-hidden="false"
|
||||||
aria-label="Summary"
|
aria-label="Summary"
|
||||||
svgIcon="summary"
|
svgIcon="summary"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
<a
|
<a
|
||||||
routerLink="/summary"
|
routerLink="/summary"
|
||||||
routerLinkActive="active"
|
routerLinkActive="active"
|
||||||
(click)="snav.toggle()"
|
(click)="snav.toggle()"
|
||||||
skipLocationChange
|
skipLocationChange
|
||||||
>{{ "App_Nav_Summary" | translate }}</a
|
>{{ "App_Nav_Summary" | translate }}</a
|
||||||
>
|
>
|
||||||
<hr class="splitter" />
|
<hr class="splitter" />
|
||||||
</mat-nav-list>
|
</mat-nav-list>
|
||||||
<mat-nav-list>
|
<mat-nav-list>
|
||||||
<mat-icon
|
<mat-icon
|
||||||
aria-hidden="false"
|
aria-hidden="false"
|
||||||
aria-label="List of jumps"
|
aria-label="List of jumps"
|
||||||
svgIcon="list"
|
svgIcon="list"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
<a
|
<a
|
||||||
routerLink="/jumps"
|
routerLink="/jumps"
|
||||||
routerLinkActive="active"
|
routerLinkActive="active"
|
||||||
(click)="snav.toggle()"
|
(click)="snav.toggle()"
|
||||||
skipLocationChange
|
skipLocationChange
|
||||||
>{{ "App_Nav_Jumps" | translate }}</a
|
>{{ "App_Nav_Jumps" | translate }}</a
|
||||||
>
|
>
|
||||||
</mat-nav-list>
|
</mat-nav-list>
|
||||||
<mat-nav-list>
|
<mat-nav-list>
|
||||||
<mat-icon
|
<mat-icon
|
||||||
aria-hidden="false"
|
aria-hidden="false"
|
||||||
aria-label="Add jumps"
|
aria-label="Add jumps"
|
||||||
svgIcon="add"
|
svgIcon="add"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
<a
|
<a
|
||||||
routerLink="/newjump"
|
routerLink="/newjump"
|
||||||
routerLinkActive="active"
|
routerLinkActive="active"
|
||||||
(click)="snav.toggle()"
|
(click)="snav.toggle()"
|
||||||
skipLocationChange
|
skipLocationChange
|
||||||
>{{ "App_Nav_NewJump" | translate }}</a
|
>{{ "App_Nav_NewJump" | translate }}</a
|
||||||
>
|
>
|
||||||
<hr class="splitter" />
|
<hr class="splitter" />
|
||||||
</mat-nav-list>
|
</mat-nav-list>
|
||||||
<mat-nav-list>
|
<mat-nav-list>
|
||||||
<mat-icon
|
<mat-icon
|
||||||
aria-hidden="false"
|
aria-hidden="false"
|
||||||
aria-label="List of tunnel flights"
|
aria-label="List of tunnel flights"
|
||||||
svgIcon="list"
|
svgIcon="list"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
<a
|
<a
|
||||||
routerLink="/tunnelFlights"
|
routerLink="/tunnelFlights"
|
||||||
routerLinkActive="active"
|
routerLinkActive="active"
|
||||||
(click)="snav.toggle()"
|
(click)="snav.toggle()"
|
||||||
skipLocationChange
|
skipLocationChange
|
||||||
>{{ "App_Nav_TunnelFlights" | translate }}</a
|
>{{ "App_Nav_TunnelFlights" | translate }}</a
|
||||||
>
|
>
|
||||||
</mat-nav-list>
|
</mat-nav-list>
|
||||||
<mat-nav-list>
|
<mat-nav-list>
|
||||||
<mat-icon
|
<mat-icon
|
||||||
aria-hidden="false"
|
aria-hidden="false"
|
||||||
aria-label="Add flights in tunnel"
|
aria-label="Add flights in tunnel"
|
||||||
svgIcon="add"
|
svgIcon="add"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
<a
|
<a
|
||||||
routerLink="/newTunnelFlight"
|
routerLink="/newTunnelFlight"
|
||||||
routerLinkActive="active"
|
routerLinkActive="active"
|
||||||
(click)="snav.toggle()"
|
(click)="snav.toggle()"
|
||||||
skipLocationChange
|
skipLocationChange
|
||||||
>{{ "App_Nav_NewTunnelFlight" | translate }}</a
|
>{{ "App_Nav_NewTunnelFlight" | translate }}</a
|
||||||
>
|
>
|
||||||
<hr class="splitter" />
|
<hr class="splitter" />
|
||||||
</mat-nav-list>
|
</mat-nav-list>
|
||||||
<mat-nav-list>
|
<mat-nav-list>
|
||||||
<mat-icon
|
<mat-icon
|
||||||
aria-hidden="false"
|
aria-hidden="false"
|
||||||
aria-label="Dropzones"
|
aria-label="Dropzones"
|
||||||
svgIcon="dz"
|
svgIcon="dz"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
<a
|
<a
|
||||||
routerLink="/dzs"
|
routerLink="/dzs"
|
||||||
routerLinkActive="active"
|
routerLinkActive="active"
|
||||||
(click)="snav.toggle()"
|
(click)="snav.toggle()"
|
||||||
skipLocationChange
|
skipLocationChange
|
||||||
>{{ "App_Nav_Dzs" | translate }}</a
|
>{{ "App_Nav_Dzs" | translate }}</a
|
||||||
>
|
>
|
||||||
</mat-nav-list>
|
</mat-nav-list>
|
||||||
<mat-nav-list>
|
<mat-nav-list>
|
||||||
<mat-icon
|
<mat-icon
|
||||||
aria-hidden="false"
|
aria-hidden="false"
|
||||||
aria-label="Aircrafts"
|
aria-label="Aircrafts"
|
||||||
svgIcon="aircraft"
|
svgIcon="aircraft"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
<a
|
<a
|
||||||
routerLink="/aircrafts"
|
routerLink="/aircrafts"
|
||||||
routerLinkActive="active"
|
routerLinkActive="active"
|
||||||
(click)="snav.toggle()"
|
(click)="snav.toggle()"
|
||||||
skipLocationChange
|
skipLocationChange
|
||||||
>{{ "App_Nav_Aircrafts" | translate }}</a
|
>{{ "App_Nav_Aircrafts" | translate }}</a
|
||||||
>
|
>
|
||||||
</mat-nav-list>
|
</mat-nav-list>
|
||||||
<mat-nav-list>
|
<mat-nav-list>
|
||||||
<mat-icon
|
<mat-icon
|
||||||
aria-hidden="false"
|
aria-hidden="false"
|
||||||
aria-label="List of jump types"
|
aria-label="List of jump types"
|
||||||
svgIcon="flight_land"
|
svgIcon="flight_land"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
<a
|
<a
|
||||||
routerLink="/jumpTypes"
|
routerLink="/jumpTypes"
|
||||||
routerLinkActive="active"
|
routerLinkActive="active"
|
||||||
(click)="snav.toggle()"
|
(click)="snav.toggle()"
|
||||||
skipLocationChange
|
skipLocationChange
|
||||||
>{{ "App_Nav_JumpTypes" | translate }}</a
|
>{{ "App_Nav_JumpTypes" | translate }}</a
|
||||||
>
|
>
|
||||||
</mat-nav-list>
|
</mat-nav-list>
|
||||||
<mat-nav-list>
|
<mat-nav-list>
|
||||||
<mat-icon
|
<mat-icon
|
||||||
aria-hidden="false"
|
aria-hidden="false"
|
||||||
aria-label="List of gears"
|
aria-label="List of gears"
|
||||||
svgIcon="gear"
|
svgIcon="gear"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
<a
|
<a
|
||||||
routerLink="/gears"
|
routerLink="/gears"
|
||||||
routerLinkActive="active"
|
routerLinkActive="active"
|
||||||
(click)="snav.toggle()"
|
(click)="snav.toggle()"
|
||||||
skipLocationChange
|
skipLocationChange
|
||||||
>{{ "App_Nav_Gears" | translate }}</a
|
>{{ "App_Nav_Gears" | translate }}</a
|
||||||
>
|
>
|
||||||
</mat-nav-list>
|
</mat-nav-list>
|
||||||
<mat-nav-list *ngIf="currentUser">
|
@if (currentUser) {
|
||||||
<hr class="splitter" />
|
<mat-nav-list>
|
||||||
<mat-icon
|
<hr class="splitter" />
|
||||||
aria-hidden="false"
|
<mat-icon
|
||||||
aria-label="User account"
|
aria-hidden="false"
|
||||||
svgIcon="account"
|
aria-label="User account"
|
||||||
></mat-icon>
|
svgIcon="account"
|
||||||
<a
|
></mat-icon>
|
||||||
routerLink="/user"
|
<a
|
||||||
routerLinkActive="active"
|
routerLink="/user"
|
||||||
(click)="snav.toggle()"
|
routerLinkActive="active"
|
||||||
skipLocationChange
|
(click)="snav.toggle()"
|
||||||
>
|
skipLocationChange
|
||||||
{{ this.currentUser.firstName }} {{ this.currentUser.lastName }}
|
>
|
||||||
</a>
|
{{ this.currentUser.firstName }}
|
||||||
</mat-nav-list>
|
{{ this.currentUser.lastName }}
|
||||||
<mat-nav-list *ngIf="currentUser">
|
</a>
|
||||||
<mat-icon
|
</mat-nav-list>
|
||||||
aria-hidden="false"
|
}
|
||||||
aria-label="To logout"
|
@if (currentUser) {
|
||||||
svgIcon="logout"
|
<mat-nav-list>
|
||||||
></mat-icon>
|
<mat-icon
|
||||||
<span (click)="snav.toggle(); logout()" style="cursor: pointer">{{
|
aria-hidden="false"
|
||||||
"App_Nav_Logout" | translate
|
aria-label="To logout"
|
||||||
}}</span>
|
svgIcon="logout"
|
||||||
</mat-nav-list>
|
></mat-icon>
|
||||||
</mat-sidenav>
|
<span
|
||||||
|
(click)="snav.toggle(); logout()"
|
||||||
|
style="cursor: pointer"
|
||||||
|
>{{ "App_Nav_Logout" | translate }}</span
|
||||||
|
>
|
||||||
|
</mat-nav-list>
|
||||||
|
}
|
||||||
|
</mat-sidenav>
|
||||||
|
|
||||||
<mat-sidenav-content>
|
<mat-sidenav-content>
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
<footer style="text-align: right">
|
<footer style="text-align: right">
|
||||||
{{ "App_Footer" | translate }}{{ version }} - @Séb
|
{{ "App_Footer" | translate }}{{ version }} - @Séb
|
||||||
</footer>
|
</footer>
|
||||||
</mat-sidenav-content>
|
</mat-sidenav-content>
|
||||||
</mat-sidenav-container>
|
</mat-sidenav-container>
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
import { Component, inject, OnInit } from "@angular/core";
|
import { Component, inject, OnInit } from "@angular/core";
|
||||||
import { Router, RouterLink, RouterOutlet } from "@angular/router";
|
import { Router, RouterLink, RouterOutlet } from "@angular/router";
|
||||||
import { CommonModule } from "@angular/common";
|
|
||||||
import { DomSanitizer } from "@angular/platform-browser";
|
import { DomSanitizer } from "@angular/platform-browser";
|
||||||
import { MatToolbarModule } from "@angular/material/toolbar";
|
import { MatToolbarModule } from "@angular/material/toolbar";
|
||||||
import {
|
import {
|
||||||
IconResolver,
|
IconResolver,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
MatIconRegistry,
|
MatIconRegistry,
|
||||||
} from "@angular/material/icon";
|
} from "@angular/material/icon";
|
||||||
import { MatSelectModule } from "@angular/material/select";
|
import { MatSelectModule } from "@angular/material/select";
|
||||||
import { MatOptionModule } from "@angular/material/core";
|
import { MatOptionModule } from "@angular/material/core";
|
||||||
import { MatSidenavModule } from "@angular/material/sidenav";
|
import { MatSidenavModule } from "@angular/material/sidenav";
|
||||||
import { MatListModule } from "@angular/material/list";
|
import { MatListModule } from "@angular/material/list";
|
||||||
import {
|
import {
|
||||||
TranslateService,
|
TranslateService,
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
TranslatePipe,
|
TranslatePipe,
|
||||||
} from "@ngx-translate/core";
|
} from "@ngx-translate/core";
|
||||||
|
|
||||||
import { User } from "../models/user";
|
import { User } from "../models/user";
|
||||||
@@ -27,80 +27,82 @@ import { ConfigurationHelper } from "../services/configuration-helper";
|
|||||||
import { ServiceCacheApi } from "../services/service-cache-api.service";
|
import { ServiceCacheApi } from "../services/service-cache-api.service";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-root",
|
selector: "app-root",
|
||||||
templateUrl: "./app.component.html",
|
templateUrl: "./app.component.html",
|
||||||
styleUrls: ["./app.component.css"],
|
styleUrls: ["./app.component.css"],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
MatToolbarModule,
|
||||||
MatToolbarModule,
|
MatIconModule,
|
||||||
MatIconModule,
|
MatSelectModule,
|
||||||
MatSelectModule,
|
MatOptionModule,
|
||||||
MatOptionModule,
|
MatSidenavModule,
|
||||||
MatSidenavModule,
|
MatListModule,
|
||||||
MatListModule,
|
RouterOutlet,
|
||||||
RouterOutlet,
|
RouterLink,
|
||||||
RouterLink,
|
TranslateModule,
|
||||||
TranslateModule,
|
TranslatePipe,
|
||||||
TranslatePipe,
|
],
|
||||||
],
|
|
||||||
})
|
})
|
||||||
export class AppComponent implements OnInit {
|
export class AppComponent implements OnInit {
|
||||||
public translatedTitle = "???";
|
public translatedTitle = "???";
|
||||||
public currentUser: User;
|
public currentUser: User;
|
||||||
public version: string;
|
public version: string;
|
||||||
public selectedLanguageFlag: string;
|
public selectedLanguageFlag: string;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private authenticationService: AuthenticationService,
|
private authenticationService: AuthenticationService,
|
||||||
private serviceComm: ServiceComm,
|
private serviceComm: ServiceComm,
|
||||||
private serviceCacheApi: ServiceCacheApi,
|
private serviceCacheApi: ServiceCacheApi,
|
||||||
private translateService: TranslateService,
|
private translateService: TranslateService,
|
||||||
) {
|
) {
|
||||||
const sanitizer = inject(DomSanitizer);
|
const sanitizer = inject(DomSanitizer);
|
||||||
const resolver: IconResolver = (name) =>
|
const resolver: IconResolver = (name) =>
|
||||||
sanitizer.bypassSecurityTrustResourceUrl(`/assets/icon/${name}.svg`);
|
sanitizer.bypassSecurityTrustResourceUrl(
|
||||||
const iconRegistry = inject(MatIconRegistry);
|
`/assets/icon/${name}.svg`,
|
||||||
iconRegistry.addSvgIconResolver(resolver);
|
);
|
||||||
|
const iconRegistry = inject(MatIconRegistry);
|
||||||
|
iconRegistry.addSvgIconResolver(resolver);
|
||||||
|
|
||||||
this.authenticationService.currentUser.subscribe((user) => {
|
this.authenticationService.currentUser.subscribe((user) => {
|
||||||
if (user) {
|
if (user) {
|
||||||
this.currentUser = user;
|
this.currentUser = user;
|
||||||
this.translateService.addLangs(["en", "fr"]);
|
this.translateService.addLangs(["en", "fr"]);
|
||||||
this.translateService.use(user.language);
|
this.translateService.use(user.language);
|
||||||
this.selectedLanguageFlag = user.language;
|
this.selectedLanguageFlag = user.language;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ConfigurationHelper.settings.subscribe((settings) => {
|
ConfigurationHelper.settings.subscribe((settings) => {
|
||||||
if (settings != null) {
|
if (settings != null) {
|
||||||
this.version = settings.version;
|
this.version = settings.version;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {}
|
||||||
this.serviceComm.componentTitle.subscribe(
|
ngAfterViewInit() {
|
||||||
(title) => (this.translatedTitle = title),
|
this.serviceComm.componentTitle.subscribe(
|
||||||
);
|
(title) => (this.translatedTitle = title),
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public show() {
|
public show() {
|
||||||
return this.authenticationService.currentUserValue != undefined;
|
return this.authenticationService.currentUserValue != undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
public logout() {
|
public logout() {
|
||||||
this.serviceCacheApi.delete(CacheApiKey.Dropzone);
|
this.serviceCacheApi.delete(CacheApiKey.Dropzone);
|
||||||
this.authenticationService.logout();
|
this.authenticationService.logout();
|
||||||
this.router.navigate(["/login"], { skipLocationChange: true });
|
this.router.navigate(["/login"], { skipLocationChange: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
public switchLang(event: any) {
|
public switchLang(event: any) {
|
||||||
this.translateService.use(event.value);
|
this.translateService.use(event.value);
|
||||||
this.currentUser.language = event.value;
|
this.currentUser.language = event.value;
|
||||||
this.authenticationService.currentUserValue = this.currentUser;
|
this.authenticationService.currentUserValue = this.currentUser;
|
||||||
this.selectedLanguageFlag = event.value;
|
this.selectedLanguageFlag = event.value;
|
||||||
|
|
||||||
this.serviceComm.forceTranslate();
|
this.serviceComm.forceTranslate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,42 +32,44 @@ import { provideTranslateHttpLoader } from "@ngx-translate/http-loader";
|
|||||||
|
|
||||||
// Déclaration de la fonction d'initialisation de la configuration
|
// Déclaration de la fonction d'initialisation de la configuration
|
||||||
export function initConfig(configService: ConfigurationHelper) {
|
export function initConfig(configService: ConfigurationHelper) {
|
||||||
return () => configService.load(environment.env);
|
return () => configService.load(environment.env);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const appConfig: ApplicationConfig = {
|
export const appConfig: ApplicationConfig = {
|
||||||
providers: [
|
providers: [
|
||||||
TunnelService,
|
TunnelService,
|
||||||
TunnelFlightService,
|
TunnelFlightService,
|
||||||
ImageService,
|
ImageService,
|
||||||
AircraftService,
|
AircraftService,
|
||||||
DropzoneService,
|
DropzoneService,
|
||||||
GearService,
|
GearService,
|
||||||
JumpService,
|
JumpService,
|
||||||
JumpTypeService,
|
JumpTypeService,
|
||||||
StatsService,
|
StatsService,
|
||||||
ServiceComm,
|
ServiceComm,
|
||||||
DateService,
|
DateService,
|
||||||
RequestCache,
|
RequestCache,
|
||||||
ConfigurationHelper,
|
ConfigurationHelper,
|
||||||
DatePipe,
|
DatePipe,
|
||||||
ServiceCacheApi,
|
ServiceCacheApi,
|
||||||
provideAppInitializer(() => {
|
provideAppInitializer(() => {
|
||||||
const initializerFn = initConfig(inject(ConfigurationHelper));
|
const initializerFn = initConfig(inject(ConfigurationHelper));
|
||||||
return initializerFn();
|
return initializerFn();
|
||||||
}),
|
}),
|
||||||
provideHttpClient(withInterceptors([JwtAuthInterceptor, ErrorInterceptor])),
|
provideHttpClient(
|
||||||
provideCharts(withDefaultRegisterables()),
|
withInterceptors([JwtAuthInterceptor, ErrorInterceptor]),
|
||||||
provideZoneChangeDetection({ eventCoalescing: true }),
|
),
|
||||||
provideRouter(routes),
|
provideCharts(withDefaultRegisterables()),
|
||||||
provideHttpClient(),
|
provideZoneChangeDetection({ eventCoalescing: true }),
|
||||||
provideTranslateService({
|
provideRouter(routes),
|
||||||
loader: provideTranslateHttpLoader({
|
provideHttpClient(),
|
||||||
prefix: "/assets/i18n/",
|
provideTranslateService({
|
||||||
suffix: ".json",
|
loader: provideTranslateHttpLoader({
|
||||||
}),
|
prefix: "/assets/i18n/",
|
||||||
fallbackLang: "en",
|
suffix: ".json",
|
||||||
lang: "en",
|
}),
|
||||||
}),
|
fallbackLang: "en",
|
||||||
],
|
lang: "en",
|
||||||
|
}),
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,91 +3,97 @@ import { Routes } from "@angular/router";
|
|||||||
import { AuthGuardService } from "../services/auth-guard.service";
|
import { AuthGuardService } from "../services/auth-guard.service";
|
||||||
|
|
||||||
export const routes: Routes = [
|
export const routes: Routes = [
|
||||||
{
|
{
|
||||||
path: "",
|
path: "",
|
||||||
loadComponent: () =>
|
loadComponent: () =>
|
||||||
import("./default/default.component").then((m) => m.DefaultComponent),
|
import("./default/default.component").then(
|
||||||
canActivate: [AuthGuardService],
|
(m) => m.DefaultComponent,
|
||||||
},
|
),
|
||||||
{
|
canActivate: [AuthGuardService],
|
||||||
path: "summary",
|
},
|
||||||
loadComponent: () =>
|
{
|
||||||
import("./summary/summary.component").then((m) => m.SummaryComponent),
|
path: "summary",
|
||||||
canActivate: [AuthGuardService],
|
loadComponent: () =>
|
||||||
},
|
import("./summary/summary.component").then(
|
||||||
{
|
(m) => m.SummaryComponent,
|
||||||
path: "jumps",
|
),
|
||||||
loadComponent: () =>
|
canActivate: [AuthGuardService],
|
||||||
import("./list-of-jumps/list-of-jumps.component").then(
|
},
|
||||||
(m) => m.ListOfJumpsComponent,
|
{
|
||||||
),
|
path: "jumps",
|
||||||
canActivate: [AuthGuardService],
|
loadComponent: () =>
|
||||||
},
|
import("./list-of-jumps/list-of-jumps.component").then(
|
||||||
{
|
(m) => m.ListOfJumpsComponent,
|
||||||
path: "dzs",
|
),
|
||||||
loadComponent: () =>
|
canActivate: [AuthGuardService],
|
||||||
import("./list-of-dzs/list-of-dzs.component").then(
|
},
|
||||||
(m) => m.ListOfDzsComponent,
|
{
|
||||||
),
|
path: "dzs",
|
||||||
canActivate: [AuthGuardService],
|
loadComponent: () =>
|
||||||
},
|
import("./list-of-dzs/list-of-dzs.component").then(
|
||||||
{
|
(m) => m.ListOfDzsComponent,
|
||||||
path: "newjump",
|
),
|
||||||
loadComponent: () =>
|
canActivate: [AuthGuardService],
|
||||||
import("./new-jump/new-jump.component").then((m) => m.NewJumpComponent),
|
},
|
||||||
canActivate: [AuthGuardService],
|
{
|
||||||
},
|
path: "newjump",
|
||||||
{
|
loadComponent: () =>
|
||||||
path: "aircrafts",
|
import("./new-jump/new-jump.component").then(
|
||||||
loadComponent: () =>
|
(m) => m.NewJumpComponent,
|
||||||
import("./list-of-aircrafts/list-of-aircrafts.component").then(
|
),
|
||||||
(m) => m.ListOfAircraftsComponent,
|
canActivate: [AuthGuardService],
|
||||||
),
|
},
|
||||||
canActivate: [AuthGuardService],
|
{
|
||||||
},
|
path: "aircrafts",
|
||||||
{
|
loadComponent: () =>
|
||||||
path: "jumpTypes",
|
import("./list-of-aircrafts/list-of-aircrafts.component").then(
|
||||||
loadComponent: () =>
|
(m) => m.ListOfAircraftsComponent,
|
||||||
import("./list-of-jump-types/list-of-jump-types.component").then(
|
),
|
||||||
(m) => m.ListOfJumpTypesComponent,
|
canActivate: [AuthGuardService],
|
||||||
),
|
},
|
||||||
canActivate: [AuthGuardService],
|
{
|
||||||
},
|
path: "jumpTypes",
|
||||||
{
|
loadComponent: () =>
|
||||||
path: "gears",
|
import("./list-of-jump-types/list-of-jump-types.component").then(
|
||||||
loadComponent: () =>
|
(m) => m.ListOfJumpTypesComponent,
|
||||||
import("./list-of-gears/list-of-gears.component").then(
|
),
|
||||||
(m) => m.ListOfGearsComponent,
|
canActivate: [AuthGuardService],
|
||||||
),
|
},
|
||||||
canActivate: [AuthGuardService],
|
{
|
||||||
},
|
path: "gears",
|
||||||
{
|
loadComponent: () =>
|
||||||
path: "user",
|
import("./list-of-gears/list-of-gears.component").then(
|
||||||
loadComponent: () =>
|
(m) => m.ListOfGearsComponent,
|
||||||
import("./user-profile/user-profile.component").then(
|
),
|
||||||
(m) => m.UserProfileComponent,
|
canActivate: [AuthGuardService],
|
||||||
),
|
},
|
||||||
canActivate: [AuthGuardService],
|
{
|
||||||
},
|
path: "user",
|
||||||
{
|
loadComponent: () =>
|
||||||
path: "newTunnelFlight",
|
import("./user-profile/user-profile.component").then(
|
||||||
loadComponent: () =>
|
(m) => m.UserProfileComponent,
|
||||||
import("./new-tunnel-flight/new-tunnel-flight.component").then(
|
),
|
||||||
(m) => m.NewTunnelFlightComponent,
|
canActivate: [AuthGuardService],
|
||||||
),
|
},
|
||||||
canActivate: [AuthGuardService],
|
{
|
||||||
},
|
path: "newTunnelFlight",
|
||||||
{
|
loadComponent: () =>
|
||||||
path: "tunnelFlights",
|
import("./new-tunnel-flight/new-tunnel-flight.component").then(
|
||||||
loadComponent: () =>
|
(m) => m.NewTunnelFlightComponent,
|
||||||
import("./list-of-tunnel-flights/list-of-tunnel-flights.component").then(
|
),
|
||||||
(m) => m.ListOfTunnelFlightsComponent,
|
canActivate: [AuthGuardService],
|
||||||
),
|
},
|
||||||
canActivate: [AuthGuardService],
|
{
|
||||||
},
|
path: "tunnelFlights",
|
||||||
{
|
loadComponent: () =>
|
||||||
path: "login",
|
import("./list-of-tunnel-flights/list-of-tunnel-flights.component").then(
|
||||||
loadComponent: () =>
|
(m) => m.ListOfTunnelFlightsComponent,
|
||||||
import("./login/login.component").then((m) => m.LoginComponent),
|
),
|
||||||
},
|
canActivate: [AuthGuardService],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "login",
|
||||||
|
loadComponent: () =>
|
||||||
|
import("./login/login.component").then((m) => m.LoginComponent),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,104 +1,136 @@
|
|||||||
<form
|
<form
|
||||||
focusInvalidInput
|
focusInvalidInput
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
style="padding: 10px"
|
style="padding: 10px"
|
||||||
(ngSubmit)="onCreateSubmit()"
|
(ngSubmit)="onCreateSubmit()"
|
||||||
[formGroup]="createForm"
|
[formGroup]="createForm"
|
||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ "LoginCreateUser_Firstname" | translate }}</mat-label>
|
<mat-label>{{ "CreateUser_Firstname" | translate }}</mat-label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
matInput
|
matInput
|
||||||
#firstname="matInput"
|
#firstname="matInput"
|
||||||
formControlName="firstname"
|
formControlName="firstname"
|
||||||
[ngClass]="{ 'is-invalid': submitted && formCtrls['firstname'].errors }"
|
[ngClass]="{
|
||||||
tabindex="0"
|
'is-invalid': submitted && formCtrls['firstname'].errors,
|
||||||
/>
|
}"
|
||||||
<mat-error *ngIf="formCtrls['firstname'].hasError('required')">
|
tabindex="0"
|
||||||
{{ "LoginCreateUser_FirstnameRequired" | translate }}
|
/>
|
||||||
</mat-error>
|
@if (formCtrls["firstname"].hasError("required")) {
|
||||||
<mat-error *ngIf="formCtrls['firstname'].hasError('minlength')">
|
<mat-error>
|
||||||
{{ "LoginCreateUser_FirstnamePattern" | translate }}
|
{{ "CreateUser_FirstnameRequired" | translate }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
}
|
||||||
</p>
|
@if (formCtrls["firstname"].hasError("minlength")) {
|
||||||
<p>
|
<mat-error>
|
||||||
<mat-form-field>
|
{{ "CreateUser_FirstnamePattern" | translate }}
|
||||||
<mat-label>{{ "LoginCreateUser_Lastname" | translate }}</mat-label>
|
</mat-error>
|
||||||
<input
|
}
|
||||||
matInput
|
</mat-form-field>
|
||||||
type="text"
|
</p>
|
||||||
formControlName="lastname"
|
<p>
|
||||||
[ngClass]="{ 'is-invalid': submitted && formCtrls['lastname'].errors }"
|
<mat-form-field>
|
||||||
tabindex="1"
|
<mat-label>{{ "CreateUser_Lastname" | translate }}</mat-label>
|
||||||
/>
|
<input
|
||||||
<mat-error *ngIf="formCtrls['lastname'].hasError('required')">
|
matInput
|
||||||
{{ "LoginCreateUser_LastnameRequired" | translate }}
|
type="text"
|
||||||
</mat-error>
|
formControlName="lastname"
|
||||||
<mat-error *ngIf="formCtrls['lastname'].hasError('minlength')">
|
[ngClass]="{
|
||||||
{{ "LoginCreateUser_LastnamePattern" | translate }}
|
'is-invalid': submitted && formCtrls['lastname'].errors,
|
||||||
</mat-error>
|
}"
|
||||||
</mat-form-field>
|
tabindex="1"
|
||||||
</p>
|
/>
|
||||||
<p>
|
@if (formCtrls["lastname"].hasError("required")) {
|
||||||
<mat-form-field>
|
<mat-error>
|
||||||
<mat-label>{{ "LoginCreateUser_Email" | translate }}</mat-label>
|
{{ "CreateUser_LastnameRequired" | translate }}
|
||||||
<input
|
</mat-error>
|
||||||
matInput
|
}
|
||||||
type="email"
|
@if (formCtrls["lastname"].hasError("minlength")) {
|
||||||
formControlName="email"
|
<mat-error>
|
||||||
[ngClass]="{ 'is-invalid': submitted && formCtrls['email'].errors }"
|
{{ "CreateUser_LastnamePattern" | translate }}
|
||||||
tabindex="3"
|
</mat-error>
|
||||||
/>
|
}
|
||||||
<mat-error *ngIf="formCtrls['email'].hasError('required')">
|
</mat-form-field>
|
||||||
{{ "LoginCreateUser_EmailRequired" | translate }}
|
</p>
|
||||||
</mat-error>
|
<p>
|
||||||
<mat-error *ngIf="formCtrls['email'].hasError('email')">
|
<mat-form-field>
|
||||||
{{ "LoginCreateUser_EmailPattern" | translate }}
|
<mat-label>{{ "CreateUser_Email" | translate }}</mat-label>
|
||||||
</mat-error>
|
<input
|
||||||
</mat-form-field>
|
matInput
|
||||||
</p>
|
type="email"
|
||||||
<p>
|
formControlName="email"
|
||||||
<mat-form-field>
|
[ngClass]="{
|
||||||
<mat-label>{{ "LoginCreateUser_Username" | translate }}</mat-label>
|
'is-invalid': submitted && formCtrls['email'].errors,
|
||||||
<input
|
}"
|
||||||
matInput
|
tabindex="3"
|
||||||
type="text"
|
/>
|
||||||
formControlName="username"
|
@if (formCtrls["email"].hasError("required")) {
|
||||||
[ngClass]="{ 'is-invalid': submitted && formCtrls['username'].errors }"
|
<mat-error>
|
||||||
tabindex="4"
|
{{ "CreateUser_EmailRequired" | translate }}
|
||||||
/>
|
</mat-error>
|
||||||
<mat-error *ngIf="formCtrls['username'].hasError('required')">
|
}
|
||||||
{{ "LoginCreateUser_UsernameRequired" | translate }}
|
@if (formCtrls["email"].hasError("email")) {
|
||||||
</mat-error>
|
<mat-error>
|
||||||
<mat-error *ngIf="formCtrls['username'].hasError('minlength')">
|
{{ "CreateUser_EmailPattern" | translate }}
|
||||||
{{ "LoginCreateUser_UsernamePattern" | translate }}
|
</mat-error>
|
||||||
</mat-error>
|
}
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ "LoginCreateUser_Password" | translate }}</mat-label>
|
<mat-label>{{ "CreateUser_Username" | translate }}</mat-label>
|
||||||
<input
|
<input
|
||||||
matInput
|
matInput
|
||||||
type="password"
|
type="text"
|
||||||
formControlName="password"
|
formControlName="username"
|
||||||
[ngClass]="{ 'is-invalid': submitted && formCtrls['password'].errors }"
|
[ngClass]="{
|
||||||
tabindex="5"
|
'is-invalid': submitted && formCtrls['username'].errors,
|
||||||
/>
|
}"
|
||||||
<mat-error *ngIf="formCtrls['password'].hasError('required')">
|
tabindex="4"
|
||||||
{{ "LoginCreateUser_PasswordRequired" | translate }}
|
/>
|
||||||
</mat-error>
|
@if (formCtrls["username"].hasError("required")) {
|
||||||
<mat-error *ngIf="formCtrls['password'].hasError('pattern')">
|
<mat-error>
|
||||||
{{ "LoginCreateUser_PasswordPattern" | translate }}
|
{{ "CreateUser_UsernameRequired" | translate }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
}
|
||||||
</p>
|
@if (formCtrls["username"].hasError("minlength")) {
|
||||||
|
<mat-error>
|
||||||
|
{{ "CreateUser_UsernamePattern" | translate }}
|
||||||
|
</mat-error>
|
||||||
|
}
|
||||||
|
</mat-form-field>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>{{ "CreateUser_Password" | translate }}</mat-label>
|
||||||
|
<input
|
||||||
|
matInput
|
||||||
|
type="password"
|
||||||
|
formControlName="password"
|
||||||
|
[ngClass]="{
|
||||||
|
'is-invalid': submitted && formCtrls['password'].errors,
|
||||||
|
}"
|
||||||
|
tabindex="5"
|
||||||
|
/>
|
||||||
|
@if (formCtrls["password"].hasError("required")) {
|
||||||
|
<mat-error>
|
||||||
|
{{ "CreateUser_PasswordRequired" | translate }}
|
||||||
|
</mat-error>
|
||||||
|
}
|
||||||
|
@if (formCtrls["password"].hasError("pattern")) {
|
||||||
|
<mat-error>
|
||||||
|
{{ "CreateUser_PasswordPattern" | translate }}
|
||||||
|
</mat-error>
|
||||||
|
}
|
||||||
|
</mat-form-field>
|
||||||
|
</p>
|
||||||
|
|
||||||
<button [disabled]="!createForm.valid" mat-raised-button color="accent">
|
<button [disabled]="!createForm.valid" mat-raised-button color="accent">
|
||||||
{{ "LoginCreateUser_BtnLogin" | translate }}
|
{{ "CreateUser_BtnLogin" | translate }}
|
||||||
</button>
|
</button>
|
||||||
<div *ngIf="error" class="alert alert-danger mt-3 mb-0">{{ error }}</div>
|
@if (error) {
|
||||||
|
<div class="alert alert-danger mt-3 mb-0">{{ error }}</div>
|
||||||
|
}
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import { Component, OnInit, ViewChild } from "@angular/core";
|
import { Component, OnInit, ViewChild } from "@angular/core";
|
||||||
import { Router, ActivatedRoute } from "@angular/router";
|
import { Router, ActivatedRoute } from "@angular/router";
|
||||||
import {
|
import {
|
||||||
FormBuilder,
|
FormBuilder,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
Validators,
|
Validators,
|
||||||
} from "@angular/forms";
|
} from "@angular/forms";
|
||||||
import {
|
import {
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
TranslatePipe,
|
TranslatePipe,
|
||||||
TranslateService,
|
TranslateService,
|
||||||
} from "@ngx-translate/core";
|
} from "@ngx-translate/core";
|
||||||
import { CommonModule } from "@angular/common";
|
import { CommonModule } from "@angular/common";
|
||||||
import { MatFormFieldModule } from "@angular/material/form-field";
|
import { MatFormFieldModule } from "@angular/material/form-field";
|
||||||
@@ -22,90 +22,90 @@ import { AuthenticationService } from "../../services/authentication.service";
|
|||||||
import { User } from "../../models/user";
|
import { User } from "../../models/user";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-create-user",
|
selector: "app-create-user",
|
||||||
templateUrl: "./create-user.component.html",
|
templateUrl: "./create-user.component.html",
|
||||||
styleUrls: ["./create-user.component.css"],
|
styleUrls: ["./create-user.component.css"],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
MatFormFieldModule,
|
MatFormFieldModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
MatInputModule,
|
MatInputModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
TranslatePipe,
|
TranslatePipe,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class CreateUserComponent implements OnInit {
|
export class CreateUserComponent implements OnInit {
|
||||||
public createForm: FormGroup;
|
public createForm: FormGroup;
|
||||||
public invalidForm = true;
|
public invalidForm = true;
|
||||||
public submitted = false;
|
public submitted = false;
|
||||||
public returnUrl: string;
|
public returnUrl: string;
|
||||||
public error: string = "";
|
public error: string = "";
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private authenticationService: AuthenticationService,
|
private authenticationService: AuthenticationService,
|
||||||
private translateService: TranslateService,
|
private translateService: TranslateService,
|
||||||
) {
|
) {
|
||||||
// redirect to home if already logged in
|
// redirect to home if already logged in
|
||||||
if (this.authenticationService.currentUserValue) {
|
if (this.authenticationService.currentUserValue) {
|
||||||
this.router.navigate(["/"]);
|
this.router.navigate(["/"]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.createForm = this.formBuilder.group(
|
this.createForm = this.formBuilder.group(
|
||||||
{
|
{
|
||||||
firstname: ["", [Validators.required, Validators.minLength(3)]],
|
firstname: ["", [Validators.required, Validators.minLength(3)]],
|
||||||
lastname: ["", [Validators.required, Validators.minLength(3)]],
|
lastname: ["", [Validators.required, Validators.minLength(3)]],
|
||||||
email: ["", [Validators.required, Validators.email]],
|
email: ["", [Validators.required, Validators.email]],
|
||||||
username: ["", [Validators.required, Validators.minLength(3)]],
|
username: ["", [Validators.required, Validators.minLength(3)]],
|
||||||
password: [
|
password: [
|
||||||
"",
|
"",
|
||||||
[
|
[
|
||||||
Validators.required,
|
Validators.required,
|
||||||
Validators.pattern(
|
Validators.pattern(
|
||||||
"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[@$!%*#?&-_|]).{8,}$",
|
"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[@$!%*#?&-_|]).{8,}$",
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{ updateOn: "blur" },
|
{ updateOn: "blur" },
|
||||||
);
|
);
|
||||||
|
|
||||||
// get return url from route parameters or default to '/'
|
// 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() {
|
get formCtrls() {
|
||||||
return this.createForm.controls;
|
return this.createForm.controls;
|
||||||
}
|
}
|
||||||
|
|
||||||
onCreateSubmit() {
|
onCreateSubmit() {
|
||||||
this.invalidForm = false;
|
this.invalidForm = false;
|
||||||
this.submitted = true;
|
this.submitted = true;
|
||||||
if (this.createForm.invalid) {
|
if (this.createForm.invalid) {
|
||||||
this.invalidForm = true;
|
this.invalidForm = true;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
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.language = this.translateService.getCurrentLang();
|
||||||
|
this.authenticationService
|
||||||
|
.create(createUser)
|
||||||
|
.pipe(first())
|
||||||
|
.subscribe({
|
||||||
|
complete: () => this.router.navigate([this.returnUrl]),
|
||||||
|
error: (error) => {
|
||||||
|
this.error = error.message;
|
||||||
|
this.invalidForm = false;
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
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.language = this.translateService.getCurrentLang();
|
|
||||||
this.authenticationService
|
|
||||||
.create(createUser)
|
|
||||||
.pipe(first())
|
|
||||||
.subscribe({
|
|
||||||
complete: () => this.router.navigate([this.returnUrl]),
|
|
||||||
error: (error) => {
|
|
||||||
this.error = error.message;
|
|
||||||
this.invalidForm = false;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
.content {
|
.content {
|
||||||
height: 90vh;
|
height: 90vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: left;
|
justify-content: left;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: initial;
|
align-items: initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,62 +1,62 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<p>
|
<p>
|
||||||
<a
|
<a
|
||||||
class="nostyle"
|
class="nostyle"
|
||||||
routerLink="/summary"
|
routerLink="/summary"
|
||||||
routerLinkActive="active"
|
routerLinkActive="active"
|
||||||
skipLocationChange
|
skipLocationChange
|
||||||
>
|
>
|
||||||
<mat-icon
|
<mat-icon
|
||||||
aria-hidden="false"
|
aria-hidden="false"
|
||||||
aria-label="Summary"
|
aria-label="Summary"
|
||||||
style="width: 128px; height: 128px; font-size: 128px"
|
style="width: 128px; height: 128px; font-size: 128px"
|
||||||
svgIcon="summary"
|
svgIcon="summary"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<a
|
<a
|
||||||
class="nostyle"
|
class="nostyle"
|
||||||
routerLink="/newjump"
|
routerLink="/newjump"
|
||||||
routerLinkActive="active"
|
routerLinkActive="active"
|
||||||
skipLocationChange
|
skipLocationChange
|
||||||
>
|
>
|
||||||
<mat-icon
|
<mat-icon
|
||||||
aria-hidden="false"
|
aria-hidden="false"
|
||||||
aria-label="Add jumps"
|
aria-label="Add jumps"
|
||||||
style="width: 128px; height: 128px; font-size: 128px"
|
style="width: 128px; height: 128px; font-size: 128px"
|
||||||
svgIcon="add"
|
svgIcon="add"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<a
|
<a
|
||||||
class="nostyle"
|
class="nostyle"
|
||||||
routerLink="/jumps"
|
routerLink="/jumps"
|
||||||
routerLinkActive="active"
|
routerLinkActive="active"
|
||||||
skipLocationChange
|
skipLocationChange
|
||||||
>
|
>
|
||||||
<mat-icon
|
<mat-icon
|
||||||
aria-hidden="false"
|
aria-hidden="false"
|
||||||
aria-label="List of jumps"
|
aria-label="List of jumps"
|
||||||
style="width: 128px; height: 128px; font-size: 128px"
|
style="width: 128px; height: 128px; font-size: 128px"
|
||||||
svgIcon="list"
|
svgIcon="list"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<a
|
<a
|
||||||
class="nostyle"
|
class="nostyle"
|
||||||
routerLink="/tunnelFlights"
|
routerLink="/tunnelFlights"
|
||||||
routerLinkActive="active"
|
routerLinkActive="active"
|
||||||
skipLocationChange
|
skipLocationChange
|
||||||
>
|
>
|
||||||
<mat-icon
|
<mat-icon
|
||||||
aria-hidden="false"
|
aria-hidden="false"
|
||||||
aria-label="List of tunnel flights"
|
aria-label="List of tunnel flights"
|
||||||
style="width: 128px; height: 128px; font-size: 128px"
|
style="width: 128px; height: 128px; font-size: 128px"
|
||||||
svgIcon="wind"
|
svgIcon="wind"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -12,48 +12,48 @@ import { JumpTypeService } from "../../services/jump-type.service";
|
|||||||
import { ServiceComm } from "../../services/service-comm.service";
|
import { ServiceComm } from "../../services/service-comm.service";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-default",
|
selector: "app-default",
|
||||||
templateUrl: "./default.component.html",
|
templateUrl: "./default.component.html",
|
||||||
styleUrls: ["./default.component.css"],
|
styleUrls: ["./default.component.css"],
|
||||||
imports: [TranslateModule, MatIconModule, RouterLink],
|
imports: [TranslateModule, MatIconModule, RouterLink],
|
||||||
})
|
})
|
||||||
export class DefaultComponent implements OnInit {
|
export class DefaultComponent implements OnInit {
|
||||||
constructor(
|
constructor(
|
||||||
private serviceComm: ServiceComm,
|
private serviceComm: ServiceComm,
|
||||||
private translateService: TranslateService,
|
private translateService: TranslateService,
|
||||||
private authenticationService: AuthenticationService,
|
private authenticationService: AuthenticationService,
|
||||||
private serviceApiAircraft: AircraftService,
|
private serviceApiAircraft: AircraftService,
|
||||||
private serviceApiJumpType: JumpTypeService,
|
private serviceApiJumpType: JumpTypeService,
|
||||||
private serviceApiDropzone: DropzoneService,
|
private serviceApiDropzone: DropzoneService,
|
||||||
private serviceApiGear: GearService,
|
private serviceApiGear: GearService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.authenticationService.alwaysLogin();
|
this.authenticationService.alwaysLogin();
|
||||||
|
|
||||||
this.putToCacheRefDatas().subscribe(() => {
|
this.putToCacheRefDatas().subscribe(() => {
|
||||||
console.log("Push to cache the referentiel datas");
|
console.log("Push to cache the referentiel datas");
|
||||||
});
|
});
|
||||||
this.updateTitle();
|
|
||||||
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
|
||||||
if (data === true) {
|
|
||||||
this.updateTitle();
|
this.updateTitle();
|
||||||
}
|
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
||||||
});
|
if (data === true) {
|
||||||
}
|
this.updateTitle();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private putToCacheRefDatas(): Observable<any[]> {
|
private putToCacheRefDatas(): Observable<any[]> {
|
||||||
var aircraftResp = this.serviceApiAircraft.getListOfAircrafts(false);
|
var aircraftResp = this.serviceApiAircraft.getListOfAircrafts(false);
|
||||||
var jumpTypeResp = this.serviceApiJumpType.getListOfJumpTypes();
|
var jumpTypeResp = this.serviceApiJumpType.getListOfJumpTypes();
|
||||||
var dzResp = this.serviceApiDropzone.getListOfDropZones(false);
|
var dzResp = this.serviceApiDropzone.getListOfDropZones(false);
|
||||||
var gearResp = this.serviceApiGear.getListOfGears();
|
var gearResp = this.serviceApiGear.getListOfGears();
|
||||||
|
|
||||||
return forkJoin([aircraftResp, jumpTypeResp, dzResp, gearResp]);
|
return forkJoin([aircraftResp, jumpTypeResp, dzResp, gearResp]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateTitle() {
|
private updateTitle() {
|
||||||
this.translateService.get("Default_Title").subscribe((data) => {
|
this.translateService.get("Default_Title").subscribe((data) => {
|
||||||
this.serviceComm.updatedComponentTitle(data);
|
this.serviceComm.updatedComponentTitle(data);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +1,36 @@
|
|||||||
<form (ngSubmit)="updateJump()">
|
<form (ngSubmit)="updateJump()">
|
||||||
<p>
|
<p>
|
||||||
<span>Gear : {{ jump.gear.name }} ({{ jump.gear.mainCanopy }})</span>
|
<span>Gear : {{ jump.gear.name }} ({{ jump.gear.mainCanopy }})</span>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<mat-checkbox
|
<mat-checkbox
|
||||||
[(ngModel)]="jump.isSpecial"
|
[(ngModel)]="jump.isSpecial"
|
||||||
name="isSpecial"
|
name="isSpecial"
|
||||||
labelPosition="before"
|
labelPosition="before"
|
||||||
>Special jump</mat-checkbox
|
>Special jump</mat-checkbox
|
||||||
>
|
>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<mat-checkbox
|
<mat-checkbox
|
||||||
[(ngModel)]="jump.withCutaway"
|
[(ngModel)]="jump.withCutaway"
|
||||||
name="withCutaway"
|
name="withCutaway"
|
||||||
labelPosition="before"
|
labelPosition="before"
|
||||||
>Cutaway</mat-checkbox
|
>Cutaway</mat-checkbox
|
||||||
>
|
>
|
||||||
</p>
|
</p>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<textarea
|
<textarea
|
||||||
matInput
|
matInput
|
||||||
placeholder="Comments"
|
placeholder="Comments"
|
||||||
name="comments"
|
name="comments"
|
||||||
[(ngModel)]="jump.notes"
|
[(ngModel)]="jump.notes"
|
||||||
name="comments"
|
name="comments"
|
||||||
type="text"
|
type="text"
|
||||||
></textarea>
|
></textarea>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
<button mat-raised-button color="accent" *ngIf="editMode">Update</button>
|
@if (editMode) {
|
||||||
|
<button mat-raised-button color="accent">Update</button>
|
||||||
|
}
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Component, Inject, OnInit } from "@angular/core";
|
import { Component, Inject, OnInit } from "@angular/core";
|
||||||
import { CommonModule } from "@angular/common";
|
|
||||||
import { MAT_DIALOG_DATA } from "@angular/material/dialog";
|
import { MAT_DIALOG_DATA } from "@angular/material/dialog";
|
||||||
import { TranslateModule } from "@ngx-translate/core";
|
import { TranslateModule } from "@ngx-translate/core";
|
||||||
import { MatCheckboxModule } from "@angular/material/checkbox";
|
import { MatCheckboxModule } from "@angular/material/checkbox";
|
||||||
@@ -15,45 +15,44 @@ import { JumpService } from "../../services/jump.service";
|
|||||||
import { ServiceComm } from "../../services/service-comm.service";
|
import { ServiceComm } from "../../services/service-comm.service";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-jump-infos",
|
selector: "app-jump-infos",
|
||||||
templateUrl: "./jump-infos.component.html",
|
templateUrl: "./jump-infos.component.html",
|
||||||
styleUrls: ["./jump-infos.component.css"],
|
styleUrls: ["./jump-infos.component.css"],
|
||||||
imports: [
|
imports: [
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
CommonModule,
|
FormsModule,
|
||||||
FormsModule,
|
MatCheckboxModule,
|
||||||
MatCheckboxModule,
|
MatFormFieldModule,
|
||||||
MatFormFieldModule,
|
ReactiveFormsModule,
|
||||||
ReactiveFormsModule,
|
MatInputModule,
|
||||||
MatInputModule,
|
MatButtonModule,
|
||||||
MatButtonModule,
|
],
|
||||||
],
|
|
||||||
})
|
})
|
||||||
export class JumpInfosComponent implements OnInit {
|
export class JumpInfosComponent implements OnInit {
|
||||||
public editMode: boolean;
|
public editMode: boolean;
|
||||||
public jump: JumpResp;
|
public jump: JumpResp;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||||
private serviceJump: JumpService,
|
private serviceJump: JumpService,
|
||||||
private serviceComm: ServiceComm
|
private serviceComm: ServiceComm,
|
||||||
) {
|
) {
|
||||||
this.jump = new JumpResp(data.jump);
|
this.jump = new JumpResp(data.jump);
|
||||||
this.editMode = data.editMode;
|
this.editMode = data.editMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {}
|
ngOnInit(): void {}
|
||||||
|
|
||||||
public updateJump() {
|
public updateJump() {
|
||||||
this.serviceJump
|
this.serviceJump
|
||||||
.updateJump(
|
.updateJump(
|
||||||
this.jump.id,
|
this.jump.id,
|
||||||
this.jump.isSpecial,
|
this.jump.isSpecial,
|
||||||
this.jump.withCutaway,
|
this.jump.withCutaway,
|
||||||
this.jump.notes
|
this.jump.notes,
|
||||||
)
|
)
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
this.serviceComm.refreshData(AddAction.Jump);
|
this.serviceComm.refreshData(AddAction.Jump);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
table {
|
table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mat-row td {
|
.mat-row td {
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.spanWithBreakWord {
|
.spanWithBreakWord {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
min-height: 90vh;
|
min-height: 90vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: left;
|
justify-content: left;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: initial;
|
align-items: initial;
|
||||||
padding-top: 25px;
|
padding-top: 25px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,49 +1,54 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<div *ngIf="dataSourceTable != null; else loading">
|
@if (dataSourceTable != null) {
|
||||||
<button
|
<div>
|
||||||
mat-raised-button
|
@if (isUserAdmin == true) {
|
||||||
color="accent"
|
<button
|
||||||
(click)="openDialogToAdd()"
|
mat-raised-button
|
||||||
*ngIf="isUserAdmin == true"
|
color="accent"
|
||||||
>
|
(click)="openDialogToAdd()"
|
||||||
{{ "ListAircrafts_Add" | translate }}
|
>
|
||||||
</button>
|
{{ "ListAircrafts_Add" | translate }}
|
||||||
|
</button>
|
||||||
<table mat-table [dataSource]="dataSourceTable">
|
}
|
||||||
<ng-container matColumnDef="id">
|
<table mat-table [dataSource]="dataSourceTable">
|
||||||
<th mat-header-cell *matHeaderCellDef>
|
<ng-container matColumnDef="id">
|
||||||
{{ "ListAircrafts_Header_Id" | translate }}
|
<th mat-header-cell *matHeaderCellDef>
|
||||||
</th>
|
{{ "ListAircrafts_Header_Id" | translate }}
|
||||||
<td mat-cell *matCellDef="let element">{{ element.id }}</td>
|
</th>
|
||||||
</ng-container>
|
<td mat-cell *matCellDef="let element">{{ element.id }}</td>
|
||||||
|
</ng-container>
|
||||||
<ng-container matColumnDef="name">
|
<ng-container matColumnDef="name">
|
||||||
<th mat-header-cell *matHeaderCellDef>
|
<th mat-header-cell *matHeaderCellDef>
|
||||||
{{ "ListAircrafts_Header_Name" | translate }}
|
{{ "ListAircrafts_Header_Name" | translate }}
|
||||||
</th>
|
</th>
|
||||||
<td mat-cell *matCellDef="let element">{{ element.name }}</td>
|
<td mat-cell *matCellDef="let element">
|
||||||
</ng-container>
|
{{ element.name }}
|
||||||
|
</td>
|
||||||
<ng-container matColumnDef="imageData">
|
</ng-container>
|
||||||
<th mat-header-cell *matHeaderCellDef>
|
<ng-container matColumnDef="imageData">
|
||||||
{{ "ListAircrafts_Header_Image" | translate }}
|
<th mat-header-cell *matHeaderCellDef>
|
||||||
</th>
|
{{ "ListAircrafts_Header_Image" | translate }}
|
||||||
<td mat-cell *matCellDef="let element">
|
</th>
|
||||||
<img
|
<td mat-cell *matCellDef="let element">
|
||||||
src="{{ element.imageData }}"
|
<img
|
||||||
alt="No image"
|
src="{{ element.imageData }}"
|
||||||
style="width: 128px"
|
alt="No image"
|
||||||
/>
|
style="width: 128px"
|
||||||
</td>
|
/>
|
||||||
</ng-container>
|
</td>
|
||||||
|
</ng-container>
|
||||||
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
|
<tr
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
mat-header-row
|
||||||
</table>
|
*matHeaderRowDef="displayedColumns; sticky: true"
|
||||||
</div>
|
></tr>
|
||||||
<mat-paginator [length]="resultsLength" [pageSize]="10"></mat-paginator>
|
<tr
|
||||||
|
mat-row
|
||||||
<ng-template #loading>
|
*matRowDef="let row; columns: displayedColumns"
|
||||||
<mat-progress-spinner [mode]="'indeterminate'"></mat-progress-spinner>
|
></tr>
|
||||||
</ng-template>
|
</table>
|
||||||
|
</div>
|
||||||
|
} @else {
|
||||||
|
<mat-progress-spinner [mode]="'indeterminate'"></mat-progress-spinner>
|
||||||
|
}
|
||||||
|
<mat-paginator [length]="resultsLength" [pageSize]="10"></mat-paginator>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { MatPaginator, MatPaginatorModule } from "@angular/material/paginator";
|
|||||||
import { MatTableDataSource, MatTableModule } from "@angular/material/table";
|
import { MatTableDataSource, MatTableModule } from "@angular/material/table";
|
||||||
import { MatDialog } from "@angular/material/dialog";
|
import { MatDialog } from "@angular/material/dialog";
|
||||||
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
||||||
import { CommonModule } from "@angular/common";
|
|
||||||
import { MatProgressSpinnerModule } from "@angular/material/progress-spinner";
|
import { MatProgressSpinnerModule } from "@angular/material/progress-spinner";
|
||||||
import { MatButtonModule } from "@angular/material/button";
|
import { MatButtonModule } from "@angular/material/button";
|
||||||
|
|
||||||
@@ -15,71 +15,72 @@ import { AddAction } from "../../models/add-action.enum";
|
|||||||
import { AircraftResp } from "../../models/aircraft";
|
import { AircraftResp } from "../../models/aircraft";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-list-of-aircrafts",
|
selector: "app-list-of-aircrafts",
|
||||||
templateUrl: "./list-of-aircrafts.component.html",
|
templateUrl: "./list-of-aircrafts.component.html",
|
||||||
styleUrls: ["./list-of-aircrafts.component.css"],
|
styleUrls: ["./list-of-aircrafts.component.css"],
|
||||||
imports: [
|
imports: [
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
CommonModule,
|
MatPaginatorModule,
|
||||||
MatPaginatorModule,
|
MatProgressSpinnerModule,
|
||||||
MatProgressSpinnerModule,
|
MatTableModule,
|
||||||
MatTableModule,
|
MatButtonModule,
|
||||||
MatButtonModule,
|
],
|
||||||
],
|
|
||||||
})
|
})
|
||||||
export class ListOfAircraftsComponent implements OnInit {
|
export class ListOfAircraftsComponent implements OnInit {
|
||||||
public displayedColumns: Array<string> = ["name", "imageData"];
|
public displayedColumns: Array<string> = ["name", "imageData"];
|
||||||
public dataSourceTable: MatTableDataSource<AircraftResp>;
|
public dataSourceTable: MatTableDataSource<AircraftResp>;
|
||||||
public resultsLength = 0;
|
public resultsLength = 0;
|
||||||
public isUserAdmin: boolean;
|
public isUserAdmin: boolean;
|
||||||
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
|
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private serviceApi: AircraftService,
|
private serviceApi: AircraftService,
|
||||||
private serviceComm: ServiceComm,
|
private serviceComm: ServiceComm,
|
||||||
private authenticationService: AuthenticationService,
|
private authenticationService: AuthenticationService,
|
||||||
public dialog: MatDialog,
|
public dialog: MatDialog,
|
||||||
private translateService: TranslateService
|
private translateService: TranslateService,
|
||||||
) {
|
) {
|
||||||
this.isUserAdmin =
|
this.isUserAdmin =
|
||||||
this.authenticationService.currentUserValue.roles === "admin";
|
this.authenticationService.currentUserValue.roles === "admin";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.serviceComm.refreshRequest.subscribe((action) => {
|
||||||
|
if (action === AddAction.Aircraft) {
|
||||||
|
this.dialog.closeAll();
|
||||||
|
this.getListOfAircrafts();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
||||||
|
if (data === true) {
|
||||||
|
this.updateTitle();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.serviceComm.refreshRequest.subscribe((action) => {
|
|
||||||
if (action === AddAction.Aircraft) {
|
|
||||||
this.dialog.closeAll();
|
|
||||||
this.getListOfAircrafts();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
|
||||||
if (data === true) {
|
|
||||||
this.updateTitle();
|
this.updateTitle();
|
||||||
}
|
this.getListOfAircrafts();
|
||||||
});
|
}
|
||||||
|
|
||||||
this.updateTitle();
|
private getListOfAircrafts() {
|
||||||
this.getListOfAircrafts();
|
this.serviceApi.getListOfAircrafts().subscribe((data) => {
|
||||||
}
|
setTimeout(() => {
|
||||||
|
data.sort((a, b) => a.name.localeCompare(b.name));
|
||||||
|
this.dataSourceTable = new MatTableDataSource<AircraftResp>(
|
||||||
|
data,
|
||||||
|
);
|
||||||
|
this.dataSourceTable.paginator = this.paginator;
|
||||||
|
this.resultsLength = data.length;
|
||||||
|
}, 500);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private getListOfAircrafts() {
|
openDialogToAdd() {
|
||||||
this.serviceApi.getListOfAircrafts().subscribe((data) => {
|
this.dialog.open(NewAircraftComponent);
|
||||||
setTimeout(() => {
|
}
|
||||||
data.sort((a, b) => a.name.localeCompare(b.name));
|
|
||||||
this.dataSourceTable = new MatTableDataSource<AircraftResp>(data);
|
|
||||||
this.dataSourceTable.paginator = this.paginator;
|
|
||||||
this.resultsLength = data.length;
|
|
||||||
}, 500);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
openDialogToAdd() {
|
private updateTitle() {
|
||||||
this.dialog.open(NewAircraftComponent);
|
this.translateService.get("ListAircrafts_Title").subscribe((data) => {
|
||||||
}
|
this.serviceComm.updatedComponentTitle(data);
|
||||||
|
});
|
||||||
private updateTitle() {
|
}
|
||||||
this.translateService.get("ListAircrafts_Title").subscribe((data) => {
|
|
||||||
this.serviceComm.updatedComponentTitle(data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
table {
|
table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mat-row td {
|
.mat-row td {
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.spanWithBreakWord {
|
.spanWithBreakWord {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
min-height: 90vh;
|
min-height: 90vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: left;
|
justify-content: left;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: initial;
|
align-items: initial;
|
||||||
padding-top: 25px;
|
padding-top: 25px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,118 +1,138 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<div *ngIf="dataSourceTable != null; else loading">
|
@if (dataSourceTable != null) {
|
||||||
<button
|
<div>
|
||||||
mat-raised-button
|
@if (isUserAdmin == true) {
|
||||||
color="accent"
|
<button
|
||||||
(click)="openDialogToAdd()"
|
mat-raised-button
|
||||||
*ngIf="isUserAdmin == true"
|
color="accent"
|
||||||
>
|
(click)="openDialogToAdd()"
|
||||||
{{ "ListDz_Add" | translate }}
|
>
|
||||||
</button>
|
{{ "ListDz_Add" | translate }}
|
||||||
|
</button>
|
||||||
<mat-form-field>
|
}
|
||||||
<mat-label>{{ "ListDz_Filter" | translate }}</mat-label>
|
<mat-form-field>
|
||||||
<input
|
<mat-label>{{ "ListDz_Filter" | translate }}</mat-label>
|
||||||
matInput
|
<input
|
||||||
(keyup)="applyFilter($event)"
|
matInput
|
||||||
placeholder="{{ 'ListDz_Filter_PlaceHolder' | translate }}"
|
(keyup)="applyFilter($event)"
|
||||||
#input
|
placeholder="{{ 'ListDz_Filter_PlaceHolder' | translate }}"
|
||||||
/>
|
#input
|
||||||
</mat-form-field>
|
/>
|
||||||
|
</mat-form-field>
|
||||||
<table mat-table [dataSource]="dataSourceTable">
|
<table mat-table [dataSource]="dataSourceTable">
|
||||||
<ng-container matColumnDef="isfavorite">
|
<ng-container matColumnDef="isfavorite">
|
||||||
<th mat-header-cell *matHeaderCellDef style="min-width: 144px"></th>
|
<th
|
||||||
<td mat-cell *matCellDef="let element" style="text-align: left">
|
mat-header-cell
|
||||||
<mat-icon
|
*matHeaderCellDef
|
||||||
aria-hidden="false"
|
style="min-width: 144px"
|
||||||
aria-label="Favorite"
|
></th>
|
||||||
*ngIf="element.isFavorite === true"
|
<td
|
||||||
(click)="removeToFavorite(element)"
|
mat-cell
|
||||||
color="primary"
|
*matCellDef="let element"
|
||||||
style="cursor: pointer"
|
style="text-align: left"
|
||||||
svgIcon="favorite"
|
>
|
||||||
></mat-icon>
|
@if (element.isFavorite === true) {
|
||||||
<mat-icon
|
<mat-icon
|
||||||
aria-hidden="false"
|
aria-hidden="false"
|
||||||
aria-label="Not favorite"
|
aria-label="Favorite"
|
||||||
*ngIf="element.isFavorite === false"
|
(click)="removeToFavorite(element)"
|
||||||
(click)="setToFavorite(element)"
|
color="primary"
|
||||||
style="cursor: pointer"
|
style="cursor: pointer"
|
||||||
svgIcon="not_favorite"
|
svgIcon="favorite"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
<a href="http://{{ element.website }}" target="_blank">
|
}
|
||||||
<mat-icon
|
@if (element.isFavorite === false) {
|
||||||
aria-hidden="false"
|
<mat-icon
|
||||||
aria-label="URL to the DZ website"
|
aria-hidden="false"
|
||||||
style="color: white"
|
aria-label="Not favorite"
|
||||||
svgIcon="link"
|
(click)="setToFavorite(element)"
|
||||||
></mat-icon>
|
style="cursor: pointer"
|
||||||
</a>
|
svgIcon="not_favorite"
|
||||||
<a
|
></mat-icon>
|
||||||
href="https://www.openstreetmap.org/?mlat={{
|
}
|
||||||
element.latitude
|
<a href="http://{{ element.website }}" target="_blank">
|
||||||
}}&mlon={{ element.longitude }}#map=14/{{ element.latitude }}/{{
|
<mat-icon
|
||||||
element.longitude
|
aria-hidden="false"
|
||||||
}}"
|
aria-label="URL to the DZ website"
|
||||||
target="_blank"
|
style="color: white"
|
||||||
>
|
svgIcon="link"
|
||||||
<mat-icon
|
></mat-icon>
|
||||||
aria-hidden="false"
|
</a>
|
||||||
aria-label="Location of the DZ"
|
<a
|
||||||
style="color: white"
|
href="https://www.openstreetmap.org/?mlat={{
|
||||||
svgIcon="map"
|
element.latitude
|
||||||
></mat-icon>
|
}}&mlon={{ element.longitude }}#map=14/{{
|
||||||
</a>
|
element.latitude
|
||||||
<a href="mailto:{{ element.email }}" *ngIf="element.email">
|
}}/{{ element.longitude }}"
|
||||||
<mat-icon
|
target="_blank"
|
||||||
aria-hidden="false"
|
>
|
||||||
aria-label="Contact mail of the DZ"
|
<mat-icon
|
||||||
style="color: white"
|
aria-hidden="false"
|
||||||
svgIcon="mail"
|
aria-label="Location of the DZ"
|
||||||
></mat-icon>
|
style="color: white"
|
||||||
</a>
|
svgIcon="map"
|
||||||
</td>
|
></mat-icon>
|
||||||
</ng-container>
|
</a>
|
||||||
|
@if (element.email) {
|
||||||
<ng-container matColumnDef="id">
|
<a href="mailto:{{ element.email }}">
|
||||||
<th mat-header-cell *matHeaderCellDef>
|
<mat-icon
|
||||||
{{ "ListDz_Header_ID" | translate }}
|
aria-hidden="false"
|
||||||
</th>
|
aria-label="Contact mail of the DZ"
|
||||||
<td mat-cell *matCellDef="let element">{{ element.id }}</td>
|
style="color: white"
|
||||||
</ng-container>
|
svgIcon="mail"
|
||||||
|
></mat-icon>
|
||||||
<ng-container matColumnDef="name">
|
</a>
|
||||||
<th mat-header-cell *matHeaderCellDef>
|
}
|
||||||
{{ "ListDz_Header_Name" | translate }}
|
</td>
|
||||||
</th>
|
</ng-container>
|
||||||
<td mat-cell *matCellDef="let element">
|
<ng-container matColumnDef="id">
|
||||||
<span class="spanWithBreakWord" [innerHTML]="element.name"></span>
|
<th mat-header-cell *matHeaderCellDef>
|
||||||
</td>
|
{{ "ListDz_Header_ID" | translate }}
|
||||||
</ng-container>
|
</th>
|
||||||
|
<td mat-cell *matCellDef="let element">{{ element.id }}</td>
|
||||||
<ng-container matColumnDef="address">
|
</ng-container>
|
||||||
<th mat-header-cell *matHeaderCellDef>
|
<ng-container matColumnDef="name">
|
||||||
{{ "ListDz_Header_Address" | translate }}
|
<th mat-header-cell *matHeaderCellDef>
|
||||||
</th>
|
{{ "ListDz_Header_Name" | translate }}
|
||||||
<td mat-cell *matCellDef="let element">
|
</th>
|
||||||
<span class="spanWithBreakWord" [innerHTML]="element.address"></span>
|
<td mat-cell *matCellDef="let element">
|
||||||
</td>
|
<span
|
||||||
</ng-container>
|
class="spanWithBreakWord"
|
||||||
|
[innerHTML]="element.name"
|
||||||
<ng-container matColumnDef="type">
|
></span>
|
||||||
<th mat-header-cell *matHeaderCellDef>
|
</td>
|
||||||
{{ "ListDz_Header_Type" | translate }}
|
</ng-container>
|
||||||
</th>
|
<ng-container matColumnDef="address">
|
||||||
<td mat-cell *matCellDef="let element">{{ element.type }}</td>
|
<th mat-header-cell *matHeaderCellDef>
|
||||||
</ng-container>
|
{{ "ListDz_Header_Address" | translate }}
|
||||||
|
</th>
|
||||||
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
|
<td mat-cell *matCellDef="let element">
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
<span
|
||||||
</table>
|
class="spanWithBreakWord"
|
||||||
</div>
|
[innerHTML]="element.address"
|
||||||
<mat-paginator [length]="resultsLength" [pageSize]="20"></mat-paginator>
|
></span>
|
||||||
|
</td>
|
||||||
<ng-template #loading>
|
</ng-container>
|
||||||
<mat-progress-spinner [mode]="'indeterminate'"></mat-progress-spinner>
|
<ng-container matColumnDef="type">
|
||||||
</ng-template>
|
<th mat-header-cell *matHeaderCellDef>
|
||||||
|
{{ "ListDz_Header_Type" | translate }}
|
||||||
|
</th>
|
||||||
|
<td mat-cell *matCellDef="let element">
|
||||||
|
{{ element.type }}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
<tr
|
||||||
|
mat-header-row
|
||||||
|
*matHeaderRowDef="displayedColumns; sticky: true"
|
||||||
|
></tr>
|
||||||
|
<tr
|
||||||
|
mat-row
|
||||||
|
*matRowDef="let row; columns: displayedColumns"
|
||||||
|
></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
} @else {
|
||||||
|
<mat-progress-spinner [mode]="'indeterminate'"></mat-progress-spinner>
|
||||||
|
}
|
||||||
|
<mat-paginator [length]="resultsLength" [pageSize]="20"></mat-paginator>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { MatPaginator, MatPaginatorModule } from "@angular/material/paginator";
|
|||||||
import { MatTableDataSource, MatTableModule } from "@angular/material/table";
|
import { MatTableDataSource, MatTableModule } from "@angular/material/table";
|
||||||
import { MatDialog } from "@angular/material/dialog";
|
import { MatDialog } from "@angular/material/dialog";
|
||||||
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
||||||
import { CommonModule } from "@angular/common";
|
|
||||||
import { MatIconModule } from "@angular/material/icon";
|
import { MatIconModule } from "@angular/material/icon";
|
||||||
import { MatProgressSpinnerModule } from "@angular/material/progress-spinner";
|
import { MatProgressSpinnerModule } from "@angular/material/progress-spinner";
|
||||||
import { MatFormFieldModule } from "@angular/material/form-field";
|
import { MatFormFieldModule } from "@angular/material/form-field";
|
||||||
@@ -19,112 +19,113 @@ import { AuthenticationService } from "../../services/authentication.service";
|
|||||||
import { NewDropZoneComponent } from "../new-drop-zone/new-drop-zone.component";
|
import { NewDropZoneComponent } from "../new-drop-zone/new-drop-zone.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-list-of-dzs",
|
selector: "app-list-of-dzs",
|
||||||
templateUrl: "./list-of-dzs.component.html",
|
templateUrl: "./list-of-dzs.component.html",
|
||||||
styleUrls: ["./list-of-dzs.component.css"],
|
styleUrls: ["./list-of-dzs.component.css"],
|
||||||
imports: [
|
imports: [
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
CommonModule,
|
MatIconModule,
|
||||||
MatIconModule,
|
MatPaginatorModule,
|
||||||
MatPaginatorModule,
|
MatProgressSpinnerModule,
|
||||||
MatProgressSpinnerModule,
|
MatTableModule,
|
||||||
MatTableModule,
|
MatFormFieldModule,
|
||||||
MatFormFieldModule,
|
ReactiveFormsModule,
|
||||||
ReactiveFormsModule,
|
MatInputModule,
|
||||||
MatInputModule,
|
MatButtonModule,
|
||||||
MatButtonModule,
|
],
|
||||||
],
|
|
||||||
})
|
})
|
||||||
export class ListOfDzsComponent implements OnInit {
|
export class ListOfDzsComponent implements OnInit {
|
||||||
public displayedColumns: Array<string> = [
|
public displayedColumns: Array<string> = [
|
||||||
"isfavorite",
|
"isfavorite",
|
||||||
"name",
|
"name",
|
||||||
"address",
|
"address",
|
||||||
"type",
|
"type",
|
||||||
];
|
];
|
||||||
public dataSourceTable: MatTableDataSource<DropZoneResp>;
|
public dataSourceTable: MatTableDataSource<DropZoneResp>;
|
||||||
public isUserAdmin: boolean;
|
public isUserAdmin: boolean;
|
||||||
public resultsLength = 0;
|
public resultsLength = 0;
|
||||||
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
|
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private serviceApi: DropzoneService,
|
private serviceApi: DropzoneService,
|
||||||
private serviceComm: ServiceComm,
|
private serviceComm: ServiceComm,
|
||||||
private authenticationService: AuthenticationService,
|
private authenticationService: AuthenticationService,
|
||||||
public dialog: MatDialog,
|
public dialog: MatDialog,
|
||||||
private translateService: TranslateService
|
private translateService: TranslateService,
|
||||||
) {
|
) {
|
||||||
this.isUserAdmin =
|
this.isUserAdmin =
|
||||||
this.authenticationService.currentUserValue.roles === "admin";
|
this.authenticationService.currentUserValue.roles === "admin";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.serviceComm.refreshRequest.subscribe((action) => {
|
||||||
|
if (action === AddAction.Dropzone) {
|
||||||
|
this.dialog.closeAll();
|
||||||
|
this.getListOfDropZones();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
||||||
|
if (data === true) {
|
||||||
|
this.updateTitle();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.serviceComm.refreshRequest.subscribe((action) => {
|
|
||||||
if (action === AddAction.Dropzone) {
|
|
||||||
this.dialog.closeAll();
|
|
||||||
this.getListOfDropZones();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
|
||||||
if (data === true) {
|
|
||||||
this.updateTitle();
|
this.updateTitle();
|
||||||
}
|
this.getListOfDropZones();
|
||||||
});
|
}
|
||||||
|
|
||||||
this.updateTitle();
|
private getListOfDropZones() {
|
||||||
this.getListOfDropZones();
|
this.serviceApi.getListOfDropZones().subscribe((data) => {
|
||||||
}
|
setTimeout(() => {
|
||||||
|
data.sort(
|
||||||
|
(a, b) =>
|
||||||
|
(b.isFavorite ? 1 : 0) - (a.isFavorite ? 1 : 0) ||
|
||||||
|
a.name.localeCompare(b.name),
|
||||||
|
);
|
||||||
|
this.dataSourceTable = new MatTableDataSource<DropZoneResp>(
|
||||||
|
data,
|
||||||
|
);
|
||||||
|
this.dataSourceTable.paginator = this.paginator;
|
||||||
|
this.resultsLength = data.length;
|
||||||
|
}, 500);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private getListOfDropZones() {
|
public setToFavorite(dropzone: DropZoneResp) {
|
||||||
this.serviceApi.getListOfDropZones().subscribe((data) => {
|
dropzone.isFavorite = true;
|
||||||
setTimeout(() => {
|
this.serviceApi.setFavoriteDropZone(dropzone);
|
||||||
data.sort(
|
|
||||||
(a, b) =>
|
const data = this.dataSourceTable.data;
|
||||||
(b.isFavorite ? 1 : 0) - (a.isFavorite ? 1 : 0) ||
|
data.sort((a, b) => (b.isFavorite ? 1 : 0) - (a.isFavorite ? 1 : 0));
|
||||||
a.name.localeCompare(b.name)
|
|
||||||
);
|
|
||||||
this.dataSourceTable = new MatTableDataSource<DropZoneResp>(data);
|
this.dataSourceTable = new MatTableDataSource<DropZoneResp>(data);
|
||||||
this.dataSourceTable.paginator = this.paginator;
|
this.dataSourceTable.paginator = this.paginator;
|
||||||
this.resultsLength = data.length;
|
}
|
||||||
}, 500);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public setToFavorite(dropzone: DropZoneResp) {
|
public removeToFavorite(dropzone: DropZoneResp) {
|
||||||
dropzone.isFavorite = true;
|
dropzone.isFavorite = false;
|
||||||
this.serviceApi.setFavoriteDropZone(dropzone);
|
this.serviceApi.removeFavoriteDropZone(dropzone);
|
||||||
|
|
||||||
const data = this.dataSourceTable.data;
|
const data = this.dataSourceTable.data;
|
||||||
data.sort((a, b) => (b.isFavorite ? 1 : 0) - (a.isFavorite ? 1 : 0));
|
data.sort((a, b) => (b.isFavorite ? 1 : 0) - (a.isFavorite ? 1 : 0));
|
||||||
this.dataSourceTable = new MatTableDataSource<DropZoneResp>(data);
|
this.dataSourceTable = new MatTableDataSource<DropZoneResp>(data);
|
||||||
this.dataSourceTable.paginator = this.paginator;
|
this.dataSourceTable.paginator = this.paginator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public removeToFavorite(dropzone: DropZoneResp) {
|
openDialogToAdd() {
|
||||||
dropzone.isFavorite = false;
|
this.dialog.open(NewDropZoneComponent, {
|
||||||
this.serviceApi.removeFavoriteDropZone(dropzone);
|
height: "400px",
|
||||||
|
width: "600px",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const data = this.dataSourceTable.data;
|
applyFilter(event: Event) {
|
||||||
data.sort((a, b) => (b.isFavorite ? 1 : 0) - (a.isFavorite ? 1 : 0));
|
const filterValue = (event.target as HTMLInputElement).value;
|
||||||
this.dataSourceTable = new MatTableDataSource<DropZoneResp>(data);
|
this.dataSourceTable.filter = filterValue.trim().toLowerCase();
|
||||||
this.dataSourceTable.paginator = this.paginator;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
openDialogToAdd() {
|
private updateTitle() {
|
||||||
this.dialog.open(NewDropZoneComponent, {
|
this.translateService.get("ListDz_Title").subscribe((data) => {
|
||||||
height: "400px",
|
this.serviceComm.updatedComponentTitle(data);
|
||||||
width: "600px",
|
});
|
||||||
});
|
}
|
||||||
}
|
|
||||||
|
|
||||||
applyFilter(event: Event) {
|
|
||||||
const filterValue = (event.target as HTMLInputElement).value;
|
|
||||||
this.dataSourceTable.filter = filterValue.trim().toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
private updateTitle() {
|
|
||||||
this.translateService.get("ListDz_Title").subscribe((data) => {
|
|
||||||
this.serviceComm.updatedComponentTitle(data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,26 @@
|
|||||||
table {
|
table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mat-row td {
|
.mat-row td {
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.spanWithBreakWord {
|
.spanWithBreakWord {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
min-height: 90vh;
|
min-height: 90vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: left;
|
justify-content: left;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: initial;
|
align-items: initial;
|
||||||
padding-top: 25px;
|
padding-top: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
th.mat-header-cell {
|
th.mat-header-cell {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,68 +1,88 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<div *ngIf="dataSourceTable != null; else loading">
|
@if (dataSourceTable != null) {
|
||||||
<button mat-raised-button color="accent" (click)="openDialogToAdd()">
|
<div>
|
||||||
{{ "ListGears_Add" | translate }}
|
<button
|
||||||
</button>
|
mat-raised-button
|
||||||
|
color="accent"
|
||||||
<table mat-table [dataSource]="dataSourceTable">
|
(click)="openDialogToAdd()"
|
||||||
<ng-container matColumnDef="id">
|
>
|
||||||
<th mat-header-cell *matHeaderCellDef>
|
{{ "ListGears_Add" | translate }}
|
||||||
{{ "ListGears_Header_Id" | translate }}
|
</button>
|
||||||
</th>
|
<table mat-table [dataSource]="dataSourceTable">
|
||||||
<td mat-cell *matCellDef="let element">{{ element.id }}</td>
|
<ng-container matColumnDef="id">
|
||||||
</ng-container>
|
<th mat-header-cell *matHeaderCellDef>
|
||||||
|
{{ "ListGears_Header_Id" | translate }}
|
||||||
<ng-container matColumnDef="name">
|
</th>
|
||||||
<th mat-header-cell *matHeaderCellDef style="min-width: 130px">
|
<td mat-cell *matCellDef="let element">{{ element.id }}</td>
|
||||||
{{ "ListGears_Header_Name" | translate }}
|
</ng-container>
|
||||||
</th>
|
<ng-container matColumnDef="name">
|
||||||
<td mat-cell *matCellDef="let element">{{ element.name }}</td>
|
<th
|
||||||
</ng-container>
|
mat-header-cell
|
||||||
|
*matHeaderCellDef
|
||||||
<ng-container matColumnDef="manufacturer">
|
style="min-width: 130px"
|
||||||
<th mat-header-cell *matHeaderCellDef>
|
>
|
||||||
{{ "ListGears_Header_Manufacturer" | translate }}
|
{{ "ListGears_Header_Name" | translate }}
|
||||||
</th>
|
</th>
|
||||||
<td mat-cell *matCellDef="let element">{{ element.manufacturer }}</td>
|
<td mat-cell *matCellDef="let element">
|
||||||
</ng-container>
|
{{ element.name }}
|
||||||
|
</td>
|
||||||
<ng-container matColumnDef="maxSize">
|
</ng-container>
|
||||||
<th mat-header-cell *matHeaderCellDef style="min-width: 90px">
|
<ng-container matColumnDef="manufacturer">
|
||||||
{{ "ListGears_Header_CanopySize" | translate }}
|
<th mat-header-cell *matHeaderCellDef>
|
||||||
</th>
|
{{ "ListGears_Header_Manufacturer" | translate }}
|
||||||
<td mat-cell *matCellDef="let element">
|
</th>
|
||||||
{{ element.minSize }} - {{ element.maxSize }}
|
<td mat-cell *matCellDef="let element">
|
||||||
</td>
|
{{ element.manufacturer }}
|
||||||
</ng-container>
|
</td>
|
||||||
|
</ng-container>
|
||||||
<ng-container matColumnDef="aad">
|
<ng-container matColumnDef="maxSize">
|
||||||
<th mat-header-cell *matHeaderCellDef>
|
<th
|
||||||
{{ "ListGears_Header_Aad" | translate }}
|
mat-header-cell
|
||||||
</th>
|
*matHeaderCellDef
|
||||||
<td mat-cell *matCellDef="let element">{{ element.aad }}</td>
|
style="min-width: 90px"
|
||||||
</ng-container>
|
>
|
||||||
|
{{ "ListGears_Header_CanopySize" | translate }}
|
||||||
<ng-container matColumnDef="mainCanopy">
|
</th>
|
||||||
<th mat-header-cell *matHeaderCellDef>
|
<td mat-cell *matCellDef="let element">
|
||||||
{{ "ListGears_Header_Main" | translate }}
|
{{ element.minSize }} - {{ element.maxSize }}
|
||||||
</th>
|
</td>
|
||||||
<td mat-cell *matCellDef="let element">{{ element.mainCanopy }}</td>
|
</ng-container>
|
||||||
</ng-container>
|
<ng-container matColumnDef="aad">
|
||||||
|
<th mat-header-cell *matHeaderCellDef>
|
||||||
<ng-container matColumnDef="reserveCanopy">
|
{{ "ListGears_Header_Aad" | translate }}
|
||||||
<th mat-header-cell *matHeaderCellDef>
|
</th>
|
||||||
{{ "ListGears_Header_Reserve" | translate }}
|
<td mat-cell *matCellDef="let element">
|
||||||
</th>
|
{{ element.aad }}
|
||||||
<td mat-cell *matCellDef="let element">{{ element.reserveCanopy }}</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
<ng-container matColumnDef="mainCanopy">
|
||||||
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
|
<th mat-header-cell *matHeaderCellDef>
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
{{ "ListGears_Header_Main" | translate }}
|
||||||
</table>
|
</th>
|
||||||
</div>
|
<td mat-cell *matCellDef="let element">
|
||||||
<mat-paginator [length]="resultsLength" [pageSize]="10"></mat-paginator>
|
{{ element.mainCanopy }}
|
||||||
|
</td>
|
||||||
<ng-template #loading>
|
</ng-container>
|
||||||
<mat-progress-spinner [mode]="'indeterminate'"></mat-progress-spinner>
|
<ng-container matColumnDef="reserveCanopy">
|
||||||
</ng-template>
|
<th mat-header-cell *matHeaderCellDef>
|
||||||
|
{{ "ListGears_Header_Reserve" | translate }}
|
||||||
|
</th>
|
||||||
|
<td mat-cell *matCellDef="let element">
|
||||||
|
{{ element.reserveCanopy }}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
<tr
|
||||||
|
mat-header-row
|
||||||
|
*matHeaderRowDef="displayedColumns; sticky: true"
|
||||||
|
></tr>
|
||||||
|
<tr
|
||||||
|
mat-row
|
||||||
|
*matRowDef="let row; columns: displayedColumns"
|
||||||
|
></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
} @else {
|
||||||
|
<mat-progress-spinner [mode]="'indeterminate'"></mat-progress-spinner>
|
||||||
|
}
|
||||||
|
<mat-paginator [length]="resultsLength" [pageSize]="10"></mat-paginator>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { MatPaginator, MatPaginatorModule } from "@angular/material/paginator";
|
|||||||
import { MatTableDataSource, MatTableModule } from "@angular/material/table";
|
import { MatTableDataSource, MatTableModule } from "@angular/material/table";
|
||||||
import { MatDialog } from "@angular/material/dialog";
|
import { MatDialog } from "@angular/material/dialog";
|
||||||
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
||||||
import { CommonModule } from "@angular/common";
|
|
||||||
import { MatProgressSpinnerModule } from "@angular/material/progress-spinner";
|
import { MatProgressSpinnerModule } from "@angular/material/progress-spinner";
|
||||||
import { MatButtonModule } from "@angular/material/button";
|
import { MatButtonModule } from "@angular/material/button";
|
||||||
|
|
||||||
@@ -14,76 +14,75 @@ import { AddAction } from "../../models/add-action.enum";
|
|||||||
import { NewGearComponent } from "../new-gear/new-gear.component";
|
import { NewGearComponent } from "../new-gear/new-gear.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-list-of-gears",
|
selector: "app-list-of-gears",
|
||||||
templateUrl: "./list-of-gears.component.html",
|
templateUrl: "./list-of-gears.component.html",
|
||||||
styleUrls: ["./list-of-gears.component.css"],
|
styleUrls: ["./list-of-gears.component.css"],
|
||||||
imports: [
|
imports: [
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
CommonModule,
|
MatPaginatorModule,
|
||||||
MatPaginatorModule,
|
MatProgressSpinnerModule,
|
||||||
MatProgressSpinnerModule,
|
MatTableModule,
|
||||||
MatTableModule,
|
MatButtonModule,
|
||||||
MatButtonModule,
|
],
|
||||||
],
|
|
||||||
})
|
})
|
||||||
export class ListOfGearsComponent implements OnInit {
|
export class ListOfGearsComponent implements OnInit {
|
||||||
public displayedColumns: Array<string> = [
|
public displayedColumns: Array<string> = [
|
||||||
"name",
|
"name",
|
||||||
"manufacturer",
|
"manufacturer",
|
||||||
"maxSize",
|
"maxSize",
|
||||||
"aad",
|
"aad",
|
||||||
"mainCanopy",
|
"mainCanopy",
|
||||||
"reserveCanopy",
|
"reserveCanopy",
|
||||||
];
|
];
|
||||||
public dataSourceTable: MatTableDataSource<GearResp>;
|
public dataSourceTable: MatTableDataSource<GearResp>;
|
||||||
public resultsLength = 0;
|
public resultsLength = 0;
|
||||||
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
|
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private serviceApi: GearService,
|
private serviceApi: GearService,
|
||||||
private serviceComm: ServiceComm,
|
private serviceComm: ServiceComm,
|
||||||
public dialog: MatDialog,
|
public dialog: MatDialog,
|
||||||
private translateService: TranslateService
|
private translateService: TranslateService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.serviceComm.refreshRequest.subscribe((action) => {
|
||||||
|
if (action === AddAction.Gear) {
|
||||||
|
this.dialog.closeAll();
|
||||||
|
this.getListOfGears();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
||||||
|
if (data === true) {
|
||||||
|
this.updateTitle();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.serviceComm.refreshRequest.subscribe((action) => {
|
|
||||||
if (action === AddAction.Gear) {
|
|
||||||
this.dialog.closeAll();
|
|
||||||
this.getListOfGears();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
|
||||||
if (data === true) {
|
|
||||||
this.updateTitle();
|
this.updateTitle();
|
||||||
}
|
this.getListOfGears();
|
||||||
});
|
}
|
||||||
|
|
||||||
this.updateTitle();
|
getListOfGears() {
|
||||||
this.getListOfGears();
|
this.serviceApi.getListOfGears().subscribe((data) => {
|
||||||
}
|
setTimeout(() => {
|
||||||
|
data.sort((a, b) => b.id - a.id);
|
||||||
|
this.dataSourceTable = new MatTableDataSource<GearResp>(data);
|
||||||
|
this.dataSourceTable.paginator = this.paginator;
|
||||||
|
this.resultsLength = data.length;
|
||||||
|
}, 500);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
getListOfGears() {
|
openDialogToAdd() {
|
||||||
this.serviceApi.getListOfGears().subscribe((data) => {
|
this.dialog.open(NewGearComponent, {
|
||||||
setTimeout(() => {
|
height: "400px",
|
||||||
data.sort((a, b) => b.id - a.id);
|
width: "600px",
|
||||||
this.dataSourceTable = new MatTableDataSource<GearResp>(data);
|
});
|
||||||
this.dataSourceTable.paginator = this.paginator;
|
}
|
||||||
this.resultsLength = data.length;
|
|
||||||
}, 500);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
openDialogToAdd() {
|
private updateTitle() {
|
||||||
this.dialog.open(NewGearComponent, {
|
this.translateService.get("ListGears_Title").subscribe((data) => {
|
||||||
height: "400px",
|
this.serviceComm.updatedComponentTitle(data);
|
||||||
width: "600px",
|
});
|
||||||
});
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private updateTitle() {
|
|
||||||
this.translateService.get("ListGears_Title").subscribe((data) => {
|
|
||||||
this.serviceComm.updatedComponentTitle(data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,45 +1,45 @@
|
|||||||
.imgmodal {
|
.imgmodal {
|
||||||
display: none;
|
display: none;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
background-color: #000000;
|
background-color: #000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.imgbox {
|
.imgbox {
|
||||||
display: grid;
|
display: grid;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.center-fit {
|
.center-fit {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
max-height: 100vh;
|
max-height: 100vh;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.close {
|
.close {
|
||||||
color: white;
|
color: white;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 10px;
|
top: 10px;
|
||||||
right: 25px;
|
right: 25px;
|
||||||
font-size: 35px;
|
font-size: 35px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rotate {
|
.rotate {
|
||||||
color: white;
|
color: white;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 10px;
|
top: 10px;
|
||||||
right: 65px;
|
right: 65px;
|
||||||
font-size: 35px;
|
font-size: 35px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cursor {
|
.cursor {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,87 +1,103 @@
|
|||||||
<div>
|
<div>
|
||||||
<form
|
<form
|
||||||
[formGroup]="imgForm"
|
[formGroup]="imgForm"
|
||||||
(ngSubmit)="onSubmit(imgForm.value)"
|
(ngSubmit)="onSubmit(imgForm.value)"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
style="padding: 10px"
|
style="padding: 10px"
|
||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
<input
|
<input
|
||||||
type="file"
|
type="file"
|
||||||
#fileUpload
|
#fileUpload
|
||||||
id="fileUpload"
|
id="fileUpload"
|
||||||
name="fileUpload"
|
name="fileUpload"
|
||||||
accept="image/*"
|
accept="image/*"
|
||||||
formControlName="image"
|
formControlName="image"
|
||||||
(change)="onFileChanged($event)"
|
(change)="onFileChanged($event)"
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>Comment about the image</mat-label>
|
<mat-label>Comment about the image</mat-label>
|
||||||
<input matInput type="text" formControlName="comment" />
|
<input matInput type="text" formControlName="comment" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<button mat-icon-button color="warn" type="submit">
|
<button mat-icon-button color="warn" type="submit">
|
||||||
<mat-icon svgIcon="file_upload"></mat-icon>
|
<mat-icon svgIcon="file_upload"></mat-icon>
|
||||||
Upload image
|
Upload image
|
||||||
</button>
|
</button>
|
||||||
<label>{{ imageError }}</label>
|
<label>{{ imageError }}</label>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="resultsLength > 0">
|
@if (resultsLength > 0) {
|
||||||
<table mat-table [dataSource]="dataSourceTable">
|
<div>
|
||||||
<ng-container matColumnDef="comment">
|
<table mat-table [dataSource]="dataSourceTable">
|
||||||
<th mat-header-cell *matHeaderCellDef style="text-align: center">
|
<ng-container matColumnDef="comment">
|
||||||
Comments
|
<th
|
||||||
</th>
|
mat-header-cell
|
||||||
<td mat-cell *matCellDef="let element" style="text-align: left">
|
*matHeaderCellDef
|
||||||
<span style="white-space: nowrap">{{ element.comment }}</span>
|
style="text-align: center"
|
||||||
</td>
|
>
|
||||||
</ng-container>
|
Comments
|
||||||
|
</th>
|
||||||
<ng-container matColumnDef="data">
|
<td mat-cell *matCellDef="let element" style="text-align: left">
|
||||||
<th mat-header-cell *matHeaderCellDef style="text-align: center">
|
<span style="white-space: nowrap">{{
|
||||||
Image
|
element.comment
|
||||||
</th>
|
}}</span>
|
||||||
<td mat-cell *matCellDef="let element" style="text-align: center">
|
</td>
|
||||||
<img
|
</ng-container>
|
||||||
src="{{ element.data }}"
|
<ng-container matColumnDef="data">
|
||||||
alt="image"
|
<th
|
||||||
style="width: 50%"
|
mat-header-cell
|
||||||
(click)="openModal(element)"
|
*matHeaderCellDef
|
||||||
class="cursor"
|
style="text-align: center"
|
||||||
/>
|
>
|
||||||
</td>
|
Image
|
||||||
</ng-container>
|
</th>
|
||||||
|
<td
|
||||||
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
|
mat-cell
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
*matCellDef="let element"
|
||||||
</table>
|
style="text-align: center"
|
||||||
|
>
|
||||||
<mat-paginator [length]="resultsLength" [pageSize]="10"></mat-paginator>
|
<img
|
||||||
</div>
|
src="{{ element.data }}"
|
||||||
|
alt="image"
|
||||||
|
style="width: 50%"
|
||||||
|
(click)="openModal(element)"
|
||||||
|
class="cursor"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
<tr
|
||||||
|
mat-header-row
|
||||||
|
*matHeaderRowDef="displayedColumns; sticky: true"
|
||||||
|
></tr>
|
||||||
|
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||||
|
</table>
|
||||||
|
<mat-paginator [length]="resultsLength" [pageSize]="10"></mat-paginator>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="imgmodal"
|
class="imgmodal"
|
||||||
[ngStyle]="{ display: showPopin === true ? 'block' : 'none' }"
|
[ngStyle]="{ display: showPopin === true ? 'block' : 'none' }"
|
||||||
>
|
>
|
||||||
<span class="close cursor" (click)="closeModal()">×</span>
|
<span class="close cursor" (click)="closeModal()">×</span>
|
||||||
<mat-icon
|
<mat-icon
|
||||||
aria-hidden="false"
|
aria-hidden="false"
|
||||||
aria-label="Rotation"
|
aria-label="Rotation"
|
||||||
(click)="rotate()"
|
(click)="rotate()"
|
||||||
class="rotate cursor"
|
class="rotate cursor"
|
||||||
svgIcon="rotate"
|
svgIcon="rotate"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
<div class="imgbox">
|
<div class="imgbox">
|
||||||
<img
|
<img
|
||||||
class="center-fit cursor"
|
class="center-fit cursor"
|
||||||
src="{{ popinImage }}"
|
src="{{ popinImage }}"
|
||||||
(click)="closeModal()"
|
(click)="closeModal()"
|
||||||
[@rotatedState]="stateRotation"
|
[@rotatedState]="stateRotation"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { Component, OnInit, ViewChild } from "@angular/core";
|
import { Component, OnInit, ViewChild } from "@angular/core";
|
||||||
import {
|
import {
|
||||||
FormGroup,
|
FormGroup,
|
||||||
FormControl,
|
FormControl,
|
||||||
Validators,
|
Validators,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
} from "@angular/forms";
|
} from "@angular/forms";
|
||||||
import { MatTableDataSource, MatTableModule } from "@angular/material/table";
|
import { MatTableDataSource, MatTableModule } from "@angular/material/table";
|
||||||
import { MatPaginator, MatPaginatorModule } from "@angular/material/paginator";
|
import { MatPaginator, MatPaginatorModule } from "@angular/material/paginator";
|
||||||
@@ -21,139 +21,144 @@ import { ImageResp } from "../../models/image";
|
|||||||
import { AddAction } from "../../models/add-action.enum";
|
import { AddAction } from "../../models/add-action.enum";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-list-of-images",
|
selector: "app-list-of-images",
|
||||||
templateUrl: "./list-of-images.component.html",
|
templateUrl: "./list-of-images.component.html",
|
||||||
styleUrls: ["./list-of-images.component.css"],
|
styleUrls: ["./list-of-images.component.css"],
|
||||||
animations: [
|
animations: [
|
||||||
trigger("rotatedState", [
|
trigger("rotatedState", [
|
||||||
state("default", style({ transform: "rotate(0)" })),
|
state("default", style({ transform: "rotate(0)" })),
|
||||||
state("rot90", style({ transform: "rotate(-90deg)" })),
|
state("rot90", style({ transform: "rotate(-90deg)" })),
|
||||||
state("rot180", style({ transform: "rotate(-180deg)" })),
|
state("rot180", style({ transform: "rotate(-180deg)" })),
|
||||||
state("rot270", style({ transform: "rotate(-270deg)" })),
|
state("rot270", style({ transform: "rotate(-270deg)" })),
|
||||||
]),
|
]),
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
CommonModule,
|
CommonModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
MatPaginatorModule,
|
MatPaginatorModule,
|
||||||
MatFormFieldModule,
|
MatFormFieldModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
MatTableModule,
|
MatTableModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatInputModule,
|
MatInputModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class ListOfImagesComponent implements OnInit {
|
export class ListOfImagesComponent implements OnInit {
|
||||||
public displayedColumns: Array<string> = ["comment", "data"];
|
public displayedColumns: Array<string> = ["comment", "data"];
|
||||||
public imgForm: FormGroup;
|
public imgForm: FormGroup;
|
||||||
public imageError: string;
|
public imageError: string;
|
||||||
private selectedFile: string;
|
private selectedFile: string;
|
||||||
public popinImage: string;
|
public popinImage: string;
|
||||||
public showPopin: boolean;
|
public showPopin: boolean;
|
||||||
public dataSourceTable: MatTableDataSource<ImageResp>;
|
public dataSourceTable: MatTableDataSource<ImageResp>;
|
||||||
public resultsLength = 0;
|
public resultsLength = 0;
|
||||||
public stateRotation: string = "default";
|
public stateRotation: string = "default";
|
||||||
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
|
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private serviceApi: ImageService,
|
private serviceApi: ImageService,
|
||||||
private serviceComm: ServiceComm,
|
private serviceComm: ServiceComm,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.serviceComm.refreshRequest.subscribe((action) => {
|
this.serviceComm.refreshRequest.subscribe((action) => {
|
||||||
if (action === AddAction.Gear) {
|
if (action === AddAction.Gear) {
|
||||||
|
this.getListOfImages();
|
||||||
|
}
|
||||||
|
});
|
||||||
this.getListOfImages();
|
this.getListOfImages();
|
||||||
}
|
|
||||||
});
|
|
||||||
this.getListOfImages();
|
|
||||||
|
|
||||||
this.imgForm = new FormGroup({
|
this.imgForm = new FormGroup({
|
||||||
comment: new FormControl("", Validators.required),
|
comment: new FormControl("", Validators.required),
|
||||||
image: new FormControl("", Validators.required),
|
image: new FormControl("", Validators.required),
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
private getListOfImages() {
|
|
||||||
this.serviceApi.getListOfImages().subscribe((data) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.dataSourceTable = new MatTableDataSource<ImageResp>(data);
|
|
||||||
this.dataSourceTable.paginator = this.paginator;
|
|
||||||
this.resultsLength = data.length;
|
|
||||||
}, 500);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public onFileChanged(fileInput: any) {
|
|
||||||
const file = fileInput.dataTransfer
|
|
||||||
? fileInput.dataTransfer.files[0]
|
|
||||||
: fileInput.target.files[0];
|
|
||||||
const allowed_types = ["image/png", "image/jpeg"];
|
|
||||||
const max_size = 20971520;
|
|
||||||
|
|
||||||
if (!allowed_types.includes(file.type)) {
|
|
||||||
this.imageError = "Only Images are allowed ( JPG | PNG )";
|
|
||||||
} else if (file.size > max_size) {
|
|
||||||
this.imageError = "Maximum size allowed is " + max_size / 1000 + "Mb";
|
|
||||||
} else {
|
|
||||||
const reader = new FileReader();
|
|
||||||
reader.onload = this.checkAndExtractDataToBase64.bind(this);
|
|
||||||
reader.readAsDataURL(fileInput.target.files[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private checkAndExtractDataToBase64(e: any) {
|
|
||||||
const max_height = 15200;
|
|
||||||
const max_width = 25600;
|
|
||||||
|
|
||||||
const image = new Image();
|
|
||||||
image.src = e.target.result;
|
|
||||||
image.onload = (rs) => {
|
|
||||||
const img_height = rs.currentTarget["height"];
|
|
||||||
const img_width = rs.currentTarget["width"];
|
|
||||||
|
|
||||||
if (img_height > max_height && img_width > max_width) {
|
|
||||||
this.imageError =
|
|
||||||
"Maximum dimentions allowed " + max_height + "*" + max_width + "px";
|
|
||||||
} else {
|
|
||||||
const imgBase64Path = e.target.result;
|
|
||||||
this.selectedFile = imgBase64Path;
|
|
||||||
this.imageError = "OK";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit(formData) {
|
|
||||||
if (formData.invalid) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.serviceApi
|
private getListOfImages() {
|
||||||
.addImage(formData.comment, this.selectedFile)
|
this.serviceApi.getListOfImages().subscribe((data) => {
|
||||||
.subscribe(() => {
|
setTimeout(() => {
|
||||||
this.getListOfImages();
|
this.dataSourceTable = new MatTableDataSource<ImageResp>(data);
|
||||||
});
|
this.dataSourceTable.paginator = this.paginator;
|
||||||
}
|
this.resultsLength = data.length;
|
||||||
|
}, 500);
|
||||||
openModal(image: ImageResp) {
|
});
|
||||||
this.popinImage = image.data;
|
}
|
||||||
this.showPopin = true;
|
|
||||||
}
|
public onFileChanged(fileInput: any) {
|
||||||
|
const file = fileInput.dataTransfer
|
||||||
closeModal() {
|
? fileInput.dataTransfer.files[0]
|
||||||
this.showPopin = false;
|
: fileInput.target.files[0];
|
||||||
}
|
const allowed_types = ["image/png", "image/jpeg"];
|
||||||
|
const max_size = 20971520;
|
||||||
rotate() {
|
|
||||||
if (this.stateRotation === "default") {
|
if (!allowed_types.includes(file.type)) {
|
||||||
this.stateRotation = "rot90";
|
this.imageError = "Only Images are allowed ( JPG | PNG )";
|
||||||
} else if (this.stateRotation === "rot90") {
|
} else if (file.size > max_size) {
|
||||||
this.stateRotation = "rot180";
|
this.imageError =
|
||||||
} else if (this.stateRotation === "rot180") {
|
"Maximum size allowed is " + max_size / 1000 + "Mb";
|
||||||
this.stateRotation = "rot270";
|
} else {
|
||||||
} else {
|
const reader = new FileReader();
|
||||||
this.stateRotation = "default";
|
reader.onload = this.checkAndExtractDataToBase64.bind(this);
|
||||||
|
reader.readAsDataURL(fileInput.target.files[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private checkAndExtractDataToBase64(e: any) {
|
||||||
|
const max_height = 15200;
|
||||||
|
const max_width = 25600;
|
||||||
|
|
||||||
|
const image = new Image();
|
||||||
|
image.src = e.target.result;
|
||||||
|
image.onload = (rs) => {
|
||||||
|
const img_height = rs.currentTarget["height"];
|
||||||
|
const img_width = rs.currentTarget["width"];
|
||||||
|
|
||||||
|
if (img_height > max_height && img_width > max_width) {
|
||||||
|
this.imageError =
|
||||||
|
"Maximum dimentions allowed " +
|
||||||
|
max_height +
|
||||||
|
"*" +
|
||||||
|
max_width +
|
||||||
|
"px";
|
||||||
|
} else {
|
||||||
|
const imgBase64Path = e.target.result;
|
||||||
|
this.selectedFile = imgBase64Path;
|
||||||
|
this.imageError = "OK";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit(formData) {
|
||||||
|
if (formData.invalid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.serviceApi
|
||||||
|
.addImage(formData.comment, this.selectedFile)
|
||||||
|
.subscribe(() => {
|
||||||
|
this.getListOfImages();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openModal(image: ImageResp) {
|
||||||
|
this.popinImage = image.data;
|
||||||
|
this.showPopin = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
closeModal() {
|
||||||
|
this.showPopin = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
rotate() {
|
||||||
|
if (this.stateRotation === "default") {
|
||||||
|
this.stateRotation = "rot90";
|
||||||
|
} else if (this.stateRotation === "rot90") {
|
||||||
|
this.stateRotation = "rot180";
|
||||||
|
} else if (this.stateRotation === "rot180") {
|
||||||
|
this.stateRotation = "rot270";
|
||||||
|
} else {
|
||||||
|
this.stateRotation = "default";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
table {
|
table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mat-row td {
|
.mat-row td {
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.spanWithBreakWord {
|
.spanWithBreakWord {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
min-height: 90vh;
|
min-height: 90vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: left;
|
justify-content: left;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: initial;
|
align-items: initial;
|
||||||
padding-top: 25px;
|
padding-top: 25px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,36 +1,42 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<div *ngIf="dataSourceTable != null; else loading">
|
@if (dataSourceTable != null) {
|
||||||
<button
|
<div>
|
||||||
mat-raised-button
|
@if (isUserAdmin == true) {
|
||||||
color="accent"
|
<button
|
||||||
(click)="openDialogToAdd()"
|
mat-raised-button
|
||||||
*ngIf="isUserAdmin == true"
|
color="accent"
|
||||||
>
|
(click)="openDialogToAdd()"
|
||||||
{{ "ListJumpType_Add" | translate }}
|
>
|
||||||
</button>
|
{{ "ListJumpType_Add" | translate }}
|
||||||
|
</button>
|
||||||
<table mat-table [dataSource]="dataSourceTable">
|
}
|
||||||
<ng-container matColumnDef="id">
|
<table mat-table [dataSource]="dataSourceTable">
|
||||||
<th mat-header-cell *matHeaderCellDef>
|
<ng-container matColumnDef="id">
|
||||||
{{ "ListJumpType_Header_Id" | translate }}
|
<th mat-header-cell *matHeaderCellDef>
|
||||||
</th>
|
{{ "ListJumpType_Header_Id" | translate }}
|
||||||
<td mat-cell *matCellDef="let element">{{ element.id }}</td>
|
</th>
|
||||||
</ng-container>
|
<td mat-cell *matCellDef="let element">{{ element.id }}</td>
|
||||||
|
</ng-container>
|
||||||
<ng-container matColumnDef="name">
|
<ng-container matColumnDef="name">
|
||||||
<th mat-header-cell *matHeaderCellDef>
|
<th mat-header-cell *matHeaderCellDef>
|
||||||
{{ "ListJumpType_Header_Name" | translate }}
|
{{ "ListJumpType_Header_Name" | translate }}
|
||||||
</th>
|
</th>
|
||||||
<td mat-cell *matCellDef="let element">{{ element.name }}</td>
|
<td mat-cell *matCellDef="let element">
|
||||||
</ng-container>
|
{{ element.name }}
|
||||||
|
</td>
|
||||||
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
|
</ng-container>
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
<tr
|
||||||
</table>
|
mat-header-row
|
||||||
</div>
|
*matHeaderRowDef="displayedColumns; sticky: true"
|
||||||
<mat-paginator [length]="resultsLength" [pageSize]="20"></mat-paginator>
|
></tr>
|
||||||
|
<tr
|
||||||
<ng-template #loading>
|
mat-row
|
||||||
<mat-progress-spinner [mode]="'indeterminate'"></mat-progress-spinner>
|
*matRowDef="let row; columns: displayedColumns"
|
||||||
</ng-template>
|
></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
} @else {
|
||||||
|
<mat-progress-spinner [mode]="'indeterminate'"></mat-progress-spinner>
|
||||||
|
}
|
||||||
|
<mat-paginator [length]="resultsLength" [pageSize]="20"></mat-paginator>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { MatPaginator, MatPaginatorModule } from "@angular/material/paginator";
|
|||||||
import { MatTableDataSource, MatTableModule } from "@angular/material/table";
|
import { MatTableDataSource, MatTableModule } from "@angular/material/table";
|
||||||
import { MatDialog } from "@angular/material/dialog";
|
import { MatDialog } from "@angular/material/dialog";
|
||||||
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
||||||
import { CommonModule } from "@angular/common";
|
|
||||||
import { MatProgressSpinnerModule } from "@angular/material/progress-spinner";
|
import { MatProgressSpinnerModule } from "@angular/material/progress-spinner";
|
||||||
import { MatButtonModule } from "@angular/material/button";
|
import { MatButtonModule } from "@angular/material/button";
|
||||||
|
|
||||||
@@ -15,71 +15,72 @@ import { AuthenticationService } from "../../services/authentication.service";
|
|||||||
import { NewJumpTypeComponent } from "../new-jump-type/new-jump-type.component";
|
import { NewJumpTypeComponent } from "../new-jump-type/new-jump-type.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-list-of-jump-types",
|
selector: "app-list-of-jump-types",
|
||||||
templateUrl: "./list-of-jump-types.component.html",
|
templateUrl: "./list-of-jump-types.component.html",
|
||||||
styleUrls: ["./list-of-jump-types.component.css"],
|
styleUrls: ["./list-of-jump-types.component.css"],
|
||||||
imports: [
|
imports: [
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
CommonModule,
|
MatPaginatorModule,
|
||||||
MatPaginatorModule,
|
MatProgressSpinnerModule,
|
||||||
MatProgressSpinnerModule,
|
MatTableModule,
|
||||||
MatTableModule,
|
MatButtonModule,
|
||||||
MatButtonModule,
|
],
|
||||||
],
|
|
||||||
})
|
})
|
||||||
export class ListOfJumpTypesComponent implements OnInit {
|
export class ListOfJumpTypesComponent implements OnInit {
|
||||||
public displayedColumns: Array<string> = ["name"];
|
public displayedColumns: Array<string> = ["name"];
|
||||||
public dataSourceTable: MatTableDataSource<JumpTypeResp>;
|
public dataSourceTable: MatTableDataSource<JumpTypeResp>;
|
||||||
public isUserAdmin: boolean;
|
public isUserAdmin: boolean;
|
||||||
public resultsLength = 0;
|
public resultsLength = 0;
|
||||||
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
|
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private serviceApi: JumpTypeService,
|
private serviceApi: JumpTypeService,
|
||||||
private serviceComm: ServiceComm,
|
private serviceComm: ServiceComm,
|
||||||
private authenticationService: AuthenticationService,
|
private authenticationService: AuthenticationService,
|
||||||
public dialog: MatDialog,
|
public dialog: MatDialog,
|
||||||
private translateService: TranslateService
|
private translateService: TranslateService,
|
||||||
) {
|
) {
|
||||||
this.isUserAdmin =
|
this.isUserAdmin =
|
||||||
this.authenticationService.currentUserValue.roles === "admin";
|
this.authenticationService.currentUserValue.roles === "admin";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.serviceComm.refreshRequest.subscribe((action) => {
|
||||||
|
if (action === AddAction.JumpType) {
|
||||||
|
this.dialog.closeAll();
|
||||||
|
this.getListOfJumpTypes();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
||||||
|
if (data === true) {
|
||||||
|
this.updateTitle();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.serviceComm.refreshRequest.subscribe((action) => {
|
|
||||||
if (action === AddAction.JumpType) {
|
|
||||||
this.dialog.closeAll();
|
|
||||||
this.getListOfJumpTypes();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
|
||||||
if (data === true) {
|
|
||||||
this.updateTitle();
|
this.updateTitle();
|
||||||
}
|
this.getListOfJumpTypes();
|
||||||
});
|
}
|
||||||
|
|
||||||
this.updateTitle();
|
getListOfJumpTypes() {
|
||||||
this.getListOfJumpTypes();
|
this.serviceApi.getListOfJumpTypes().subscribe((data) => {
|
||||||
}
|
setTimeout(() => {
|
||||||
|
data.sort((a, b) => a.name.localeCompare(b.name));
|
||||||
|
this.dataSourceTable = new MatTableDataSource<JumpTypeResp>(
|
||||||
|
data,
|
||||||
|
);
|
||||||
|
this.dataSourceTable.paginator = this.paginator;
|
||||||
|
this.resultsLength = data.length;
|
||||||
|
}, 500);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
getListOfJumpTypes() {
|
openDialogToAdd() {
|
||||||
this.serviceApi.getListOfJumpTypes().subscribe((data) => {
|
this.dialog.open(NewJumpTypeComponent);
|
||||||
setTimeout(() => {
|
}
|
||||||
data.sort((a, b) => a.name.localeCompare(b.name));
|
|
||||||
this.dataSourceTable = new MatTableDataSource<JumpTypeResp>(data);
|
|
||||||
this.dataSourceTable.paginator = this.paginator;
|
|
||||||
this.resultsLength = data.length;
|
|
||||||
}, 500);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
openDialogToAdd() {
|
private updateTitle() {
|
||||||
this.dialog.open(NewJumpTypeComponent);
|
this.translateService.get("ListJumpTypes_Title").subscribe((data) => {
|
||||||
}
|
this.serviceComm.updatedComponentTitle(data);
|
||||||
|
});
|
||||||
private updateTitle() {
|
}
|
||||||
this.translateService.get("ListJumpTypes_Title").subscribe((data) => {
|
|
||||||
this.serviceComm.updatedComponentTitle(data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +1,32 @@
|
|||||||
table {
|
table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mat-row td {
|
.mat-row td {
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.spanWithBreakWord {
|
.spanWithBreakWord {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
.smallSpanWithBreakWord {
|
.smallSpanWithBreakWord {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
min-width: 50px;
|
min-width: 50px;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
min-height: 90vh;
|
min-height: 90vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: left;
|
justify-content: left;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: initial;
|
align-items: initial;
|
||||||
padding-top: 25px;
|
padding-top: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
th.mat-header-cell {
|
th.mat-header-cell {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,165 +1,176 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
mat-raised-button
|
mat-raised-button
|
||||||
color="accent"
|
color="accent"
|
||||||
[routerLink]="['/newjump']"
|
[routerLink]="['/newjump']"
|
||||||
[routerLinkActive]="['active']"
|
[routerLinkActive]="['active']"
|
||||||
skipLocationChange
|
skipLocationChange
|
||||||
>
|
|
||||||
{{ "ListJump_Add" | translate }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<mat-progress-bar
|
|
||||||
[mode]="'indeterminate'"
|
|
||||||
*ngIf="isLoading"
|
|
||||||
></mat-progress-bar>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<table mat-table [dataSource]="dataSourceTable">
|
|
||||||
<ng-container matColumnDef="infos">
|
|
||||||
<th
|
|
||||||
mat-header-cell
|
|
||||||
*matHeaderCellDef
|
|
||||||
style="min-width: 80px; text-wrap: nowrap"
|
|
||||||
></th>
|
|
||||||
<td
|
|
||||||
mat-cell
|
|
||||||
*matCellDef="let element"
|
|
||||||
style="text-align: left; text-wrap: nowrap"
|
|
||||||
>
|
>
|
||||||
<mat-icon
|
{{ "ListJump_Add" | translate }}
|
||||||
aria-hidden="false"
|
</button>
|
||||||
aria-label="Additional informations of the jump"
|
</div>
|
||||||
style="cursor: pointer"
|
|
||||||
(click)="openDialog(element, false)"
|
|
||||||
svgIcon="info"
|
|
||||||
></mat-icon>
|
|
||||||
<mat-icon
|
|
||||||
aria-hidden="false"
|
|
||||||
aria-label="Notes"
|
|
||||||
[style.visibility]="
|
|
||||||
element.notes != undefined ? 'visible' : 'hidden'
|
|
||||||
"
|
|
||||||
svgIcon="note"
|
|
||||||
></mat-icon>
|
|
||||||
<mat-icon
|
|
||||||
aria-hidden="false"
|
|
||||||
aria-label="Special jump"
|
|
||||||
[style.visibility]="element.isSpecial ? 'visible' : 'hidden'"
|
|
||||||
svgIcon="celebration"
|
|
||||||
></mat-icon>
|
|
||||||
</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container matColumnDef="id">
|
@if (isLoading) {
|
||||||
<th mat-header-cell *matHeaderCellDef style="min-width: 70px">
|
<mat-progress-bar [mode]="'indeterminate'"></mat-progress-bar>
|
||||||
{{ "ListJump_Header_Num" | translate }}
|
}
|
||||||
</th>
|
|
||||||
<td mat-cell *matCellDef="let element; let i = index">
|
|
||||||
{{
|
|
||||||
paginator.length - (paginator.pageIndex * paginator.pageSize + i)
|
|
||||||
}}
|
|
||||||
</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container matColumnDef="jumpDate">
|
<div>
|
||||||
<th mat-header-cell *matHeaderCellDef>
|
<table mat-table [dataSource]="dataSourceTable">
|
||||||
{{ "ListJump_Header_Date" | translate }}
|
<ng-container matColumnDef="infos">
|
||||||
</th>
|
<th
|
||||||
<td mat-cell *matCellDef="let element">
|
mat-header-cell
|
||||||
<span
|
*matHeaderCellDef
|
||||||
class="smallSpanWithBreakWord"
|
style="min-width: 80px; text-wrap: nowrap"
|
||||||
[innerHTML]="element.jumpDate | date: 'yyyy-MM-dd'"
|
></th>
|
||||||
></span>
|
<td
|
||||||
</td>
|
mat-cell
|
||||||
</ng-container>
|
*matCellDef="let element"
|
||||||
|
style="text-align: left; text-wrap: nowrap"
|
||||||
|
>
|
||||||
|
<mat-icon
|
||||||
|
aria-hidden="false"
|
||||||
|
aria-label="Additional informations of the jump"
|
||||||
|
style="cursor: pointer"
|
||||||
|
(click)="openDialog(element, false)"
|
||||||
|
svgIcon="info"
|
||||||
|
></mat-icon>
|
||||||
|
<mat-icon
|
||||||
|
aria-hidden="false"
|
||||||
|
aria-label="Notes"
|
||||||
|
[style.visibility]="
|
||||||
|
element.notes != undefined ? 'visible' : 'hidden'
|
||||||
|
"
|
||||||
|
svgIcon="note"
|
||||||
|
></mat-icon>
|
||||||
|
<mat-icon
|
||||||
|
aria-hidden="false"
|
||||||
|
aria-label="Special jump"
|
||||||
|
[style.visibility]="
|
||||||
|
element.isSpecial ? 'visible' : 'hidden'
|
||||||
|
"
|
||||||
|
svgIcon="celebration"
|
||||||
|
></mat-icon>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="jumpType">
|
<ng-container matColumnDef="id">
|
||||||
<th
|
<th mat-header-cell *matHeaderCellDef style="min-width: 70px">
|
||||||
mat-header-cell
|
{{ "ListJump_Header_Num" | translate }}
|
||||||
*matHeaderCellDef
|
</th>
|
||||||
style="min-width: 100px; text-wrap: nowrap"
|
<td mat-cell *matCellDef="let element; let i = index">
|
||||||
>
|
{{
|
||||||
{{ "ListJump_Header_JumpType" | translate }}
|
paginator.length -
|
||||||
</th>
|
(paginator.pageIndex * paginator.pageSize + i)
|
||||||
<td mat-cell *matCellDef="let element" style="text-wrap: nowrap">
|
}}
|
||||||
<span
|
</td>
|
||||||
class="smallSpanWithBreakWord"
|
</ng-container>
|
||||||
[innerHTML]="element.jumpType.name"
|
|
||||||
></span>
|
|
||||||
</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<ng-container matColumnDef="aircraft">
|
<ng-container matColumnDef="jumpDate">
|
||||||
<th mat-header-cell *matHeaderCellDef style="min-width: 110px">
|
<th mat-header-cell *matHeaderCellDef>
|
||||||
{{ "ListJump_Header_Aircraft" | translate }}
|
{{ "ListJump_Header_Date" | translate }}
|
||||||
</th>
|
</th>
|
||||||
<td mat-cell *matCellDef="let element">
|
<td mat-cell *matCellDef="let element">
|
||||||
<span
|
<span
|
||||||
class="smallSpanWithBreakWord"
|
class="smallSpanWithBreakWord"
|
||||||
[innerHTML]="element.aircraft.name"
|
[innerHTML]="element.jumpDate | date: 'yyyy-MM-dd'"
|
||||||
></span>
|
></span>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="dropZone">
|
<ng-container matColumnDef="jumpType">
|
||||||
<th mat-header-cell *matHeaderCellDef>
|
<th
|
||||||
{{ "ListJump_Header_Dz" | translate }}
|
mat-header-cell
|
||||||
</th>
|
*matHeaderCellDef
|
||||||
<td mat-cell *matCellDef="let element">
|
style="min-width: 100px; text-wrap: nowrap"
|
||||||
<span
|
>
|
||||||
class="spanWithBreakWord"
|
{{ "ListJump_Header_JumpType" | translate }}
|
||||||
[innerHTML]="element.dropZone.name"
|
</th>
|
||||||
></span>
|
<td
|
||||||
</td>
|
mat-cell
|
||||||
</ng-container>
|
*matCellDef="let element"
|
||||||
|
style="text-wrap: nowrap"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="smallSpanWithBreakWord"
|
||||||
|
[innerHTML]="element.jumpType.name"
|
||||||
|
></span>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="gear">
|
<ng-container matColumnDef="aircraft">
|
||||||
<th mat-header-cell *matHeaderCellDef>
|
<th mat-header-cell *matHeaderCellDef style="min-width: 110px">
|
||||||
{{ "ListJump_Header_Id" | translate }}
|
{{ "ListJump_Header_Aircraft" | translate }}
|
||||||
</th>
|
</th>
|
||||||
<td mat-cell *matCellDef="let element">{{ element.gear.name }}</td>
|
<td mat-cell *matCellDef="let element">
|
||||||
</ng-container>
|
<span
|
||||||
|
class="smallSpanWithBreakWord"
|
||||||
|
[innerHTML]="element.aircraft.name"
|
||||||
|
></span>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="actions">
|
<ng-container matColumnDef="dropZone">
|
||||||
<th
|
<th mat-header-cell *matHeaderCellDef>
|
||||||
mat-header-cell
|
{{ "ListJump_Header_Dz" | translate }}
|
||||||
*matHeaderCellDef
|
</th>
|
||||||
style="min-width: 80px; text-wrap: nowrap"
|
<td mat-cell *matCellDef="let element">
|
||||||
></th>
|
<span
|
||||||
<td
|
class="spanWithBreakWord"
|
||||||
mat-cell
|
[innerHTML]="element.dropZone.name"
|
||||||
*matCellDef="let element"
|
></span>
|
||||||
style="text-align: left; text-wrap: nowrap"
|
</td>
|
||||||
>
|
</ng-container>
|
||||||
<mat-icon
|
|
||||||
aria-hidden="false"
|
|
||||||
aria-label="Delete this jump"
|
|
||||||
style="cursor: pointer"
|
|
||||||
(click)="delete(element)"
|
|
||||||
svgIcon="delete"
|
|
||||||
></mat-icon>
|
|
||||||
<mat-icon
|
|
||||||
aria-hidden="false"
|
|
||||||
aria-label="Update some informations of the jump"
|
|
||||||
style="cursor: pointer; margin-left: 10px"
|
|
||||||
(click)="openDialog(element, true)"
|
|
||||||
svgIcon="edit"
|
|
||||||
></mat-icon>
|
|
||||||
</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
|
<ng-container matColumnDef="gear">
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
<th mat-header-cell *matHeaderCellDef>
|
||||||
</table>
|
{{ "ListJump_Header_Id" | translate }}
|
||||||
</div>
|
</th>
|
||||||
|
<td mat-cell *matCellDef="let element">
|
||||||
|
{{ element.gear.name }}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<mat-paginator
|
<ng-container matColumnDef="actions">
|
||||||
#paginator
|
<th
|
||||||
[pageSize]="20"
|
mat-header-cell
|
||||||
(page)="pageChanged($event)"
|
*matHeaderCellDef
|
||||||
showFirstLastButtons
|
style="min-width: 80px; text-wrap: nowrap"
|
||||||
></mat-paginator>
|
></th>
|
||||||
|
<td
|
||||||
|
mat-cell
|
||||||
|
*matCellDef="let element"
|
||||||
|
style="text-align: left; text-wrap: nowrap"
|
||||||
|
>
|
||||||
|
<mat-icon
|
||||||
|
aria-hidden="false"
|
||||||
|
aria-label="Delete this jump"
|
||||||
|
style="cursor: pointer"
|
||||||
|
(click)="delete(element)"
|
||||||
|
svgIcon="delete"
|
||||||
|
></mat-icon>
|
||||||
|
<mat-icon
|
||||||
|
aria-hidden="false"
|
||||||
|
aria-label="Update some informations of the jump"
|
||||||
|
style="cursor: pointer; margin-left: 10px"
|
||||||
|
(click)="openDialog(element, true)"
|
||||||
|
svgIcon="edit"
|
||||||
|
></mat-icon>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<tr
|
||||||
|
mat-header-row
|
||||||
|
*matHeaderRowDef="displayedColumns; sticky: true"
|
||||||
|
></tr>
|
||||||
|
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<mat-paginator
|
||||||
|
#paginator
|
||||||
|
[pageSize]="20"
|
||||||
|
(page)="pageChanged($event)"
|
||||||
|
showFirstLastButtons
|
||||||
|
></mat-paginator>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { Component, OnInit, ViewChild } from "@angular/core";
|
import { Component, OnInit, ViewChild } from "@angular/core";
|
||||||
import { RouterLink, RouterModule } from "@angular/router";
|
import { RouterLink, RouterModule } from "@angular/router";
|
||||||
import {
|
import {
|
||||||
MatPaginator,
|
MatPaginator,
|
||||||
MatPaginatorModule,
|
MatPaginatorModule,
|
||||||
PageEvent,
|
PageEvent,
|
||||||
} from "@angular/material/paginator";
|
} from "@angular/material/paginator";
|
||||||
import { MatTableDataSource, MatTableModule } from "@angular/material/table";
|
import { MatTableDataSource, MatTableModule } from "@angular/material/table";
|
||||||
import { MatDialog } from "@angular/material/dialog";
|
import { MatDialog } from "@angular/material/dialog";
|
||||||
@@ -25,108 +25,108 @@ import { JumpInfosComponent } from "../jump-infos/jump-infos.component";
|
|||||||
import { StatsService } from "../../services/stats.service";
|
import { StatsService } from "../../services/stats.service";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-list-of-jumps",
|
selector: "app-list-of-jumps",
|
||||||
templateUrl: "./list-of-jumps.component.html",
|
templateUrl: "./list-of-jumps.component.html",
|
||||||
styleUrls: ["./list-of-jumps.component.css"],
|
styleUrls: ["./list-of-jumps.component.css"],
|
||||||
imports: [
|
imports: [
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
CommonModule,
|
CommonModule,
|
||||||
RouterLink,
|
RouterLink,
|
||||||
RouterModule,
|
RouterModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
MatPaginatorModule,
|
MatPaginatorModule,
|
||||||
MatProgressSpinnerModule,
|
MatProgressSpinnerModule,
|
||||||
MatProgressBarModule,
|
MatProgressBarModule,
|
||||||
MatTableModule,
|
MatTableModule,
|
||||||
MatFormFieldModule,
|
MatFormFieldModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
MatInputModule,
|
MatInputModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class ListOfJumpsComponent implements OnInit {
|
export class ListOfJumpsComponent implements OnInit {
|
||||||
public displayedColumns: Array<string> = [
|
public displayedColumns: Array<string> = [
|
||||||
"infos",
|
"infos",
|
||||||
"id",
|
"id",
|
||||||
"jumpDate",
|
"jumpDate",
|
||||||
"jumpType",
|
"jumpType",
|
||||||
"aircraft",
|
"aircraft",
|
||||||
"dropZone",
|
"dropZone",
|
||||||
"actions",
|
"actions",
|
||||||
];
|
];
|
||||||
public dataSourceTable: MatTableDataSource<Jump> = new MatTableDataSource();
|
public dataSourceTable: MatTableDataSource<Jump> = new MatTableDataSource();
|
||||||
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
|
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
|
||||||
public isLoading: boolean = false;
|
public isLoading: boolean = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private serviceApi: JumpService,
|
private serviceApi: JumpService,
|
||||||
private serviceComm: ServiceComm,
|
private serviceComm: ServiceComm,
|
||||||
public dialog: MatDialog,
|
public dialog: MatDialog,
|
||||||
private translateService: TranslateService,
|
private translateService: TranslateService,
|
||||||
private statsService: StatsService
|
private statsService: StatsService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngAferViewInit(): void {
|
ngAferViewInit(): void {
|
||||||
this.dataSourceTable.paginator = this.paginator;
|
this.dataSourceTable.paginator = this.paginator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.serviceComm.refreshRequest.subscribe((action) => {
|
||||||
|
if (action === AddAction.Jump) {
|
||||||
|
this.dialog.closeAll();
|
||||||
|
this.getListOfJumps();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
||||||
|
if (data === true) {
|
||||||
|
this.updateTitle();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.serviceComm.refreshRequest.subscribe((action) => {
|
|
||||||
if (action === AddAction.Jump) {
|
|
||||||
this.dialog.closeAll();
|
|
||||||
this.getListOfJumps();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
|
||||||
if (data === true) {
|
|
||||||
this.updateTitle();
|
this.updateTitle();
|
||||||
}
|
this.getListOfJumps();
|
||||||
});
|
}
|
||||||
|
|
||||||
this.updateTitle();
|
getListOfJumps(pageSize: number = 20, pageIndex: number = 0) {
|
||||||
this.getListOfJumps();
|
this.isLoading = true;
|
||||||
}
|
|
||||||
|
|
||||||
getListOfJumps(pageSize: number = 20, pageIndex: number = 0) {
|
this.serviceApi
|
||||||
this.isLoading = true;
|
.getJumps(pageIndex * pageSize, pageIndex * pageSize + pageSize)
|
||||||
|
.subscribe((data) => {
|
||||||
|
this.dataSourceTable.data = data.rows;
|
||||||
|
setTimeout(() => {
|
||||||
|
this.paginator.length = data.count;
|
||||||
|
this.paginator.pageIndex = pageIndex;
|
||||||
|
this.isLoading = false;
|
||||||
|
}, 500);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.serviceApi
|
openDialog(item: Jump, editMode: boolean) {
|
||||||
.getJumps(pageIndex * pageSize, pageIndex * pageSize + pageSize)
|
this.dialog.open(JumpInfosComponent, {
|
||||||
.subscribe((data) => {
|
data: { jump: item, editMode: editMode },
|
||||||
this.dataSourceTable.data = data.rows;
|
maxHeight: "400px",
|
||||||
setTimeout(() => {
|
minWidth: "350px",
|
||||||
this.paginator.length = data.count;
|
});
|
||||||
this.paginator.pageIndex = pageIndex;
|
}
|
||||||
this.isLoading = false;
|
|
||||||
}, 500);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
openDialog(item: Jump, editMode: boolean) {
|
delete(item: Jump) {
|
||||||
this.dialog.open(JumpInfosComponent, {
|
let data: Array<Jump> = this.dataSourceTable.data;
|
||||||
data: { jump: item, editMode: editMode },
|
data = data.filter((d) => d.id !== item.id);
|
||||||
maxHeight: "400px",
|
|
||||||
minWidth: "350px",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
delete(item: Jump) {
|
this.dataSourceTable.data = data;
|
||||||
let data: Array<Jump> = this.dataSourceTable.data;
|
|
||||||
data = data.filter((d) => d.id !== item.id);
|
|
||||||
|
|
||||||
this.dataSourceTable.data = data;
|
this.serviceApi.deleteJump(item);
|
||||||
|
this.statsService.resetStats();
|
||||||
|
}
|
||||||
|
|
||||||
this.serviceApi.deleteJump(item);
|
pageChanged(event: PageEvent) {
|
||||||
this.statsService.resetStats();
|
this.getListOfJumps(event.pageSize, event.pageIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
pageChanged(event: PageEvent) {
|
private updateTitle() {
|
||||||
this.getListOfJumps(event.pageSize, event.pageIndex);
|
this.translateService.get("ListJumps_Title").subscribe((data) => {
|
||||||
}
|
this.serviceComm.updatedComponentTitle(data);
|
||||||
|
});
|
||||||
private updateTitle() {
|
}
|
||||||
this.translateService.get("ListJumps_Title").subscribe((data) => {
|
|
||||||
this.serviceComm.updatedComponentTitle(data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
.formListTunnelFlight {
|
.formListTunnelFlight {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
min-width: 150px;
|
min-width: 150px;
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
min-height: 90vh;
|
min-height: 90vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: left;
|
justify-content: left;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: initial;
|
align-items: initial;
|
||||||
padding-top: 25px;
|
padding-top: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chart-container {
|
.chart-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
height: 80vh;
|
height: 80vh;
|
||||||
width: 80vw;
|
width: 80vw;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,136 +1,147 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
mat-raised-button
|
mat-raised-button
|
||||||
color="accent"
|
color="accent"
|
||||||
[routerLink]="['/newTunnelFlight']"
|
[routerLink]="['/newTunnelFlight']"
|
||||||
[routerLinkActive]="['active']"
|
[routerLinkActive]="['active']"
|
||||||
skipLocationChange
|
skipLocationChange
|
||||||
|
>
|
||||||
|
{{ "ListTunnelFlight_Add" | translate }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if (isLoading) {
|
||||||
|
<mat-progress-bar [mode]="'indeterminate'"></mat-progress-bar>
|
||||||
|
}
|
||||||
|
|
||||||
|
<mat-radio-group
|
||||||
|
[(ngModel)]="selectedPeriod"
|
||||||
|
(ngModelChange)="onPeriodChange()"
|
||||||
>
|
>
|
||||||
{{ "ListTunnelFlight_Add" | translate }}
|
<mat-radio-button value="currentYear">{{
|
||||||
</button>
|
"ListTunnelFlight_CurrentYear" | translate
|
||||||
</div>
|
}}</mat-radio-button>
|
||||||
|
<mat-radio-button value="12Months">{{
|
||||||
|
"ListTunnelFlight_12Months" | translate
|
||||||
|
}}</mat-radio-button>
|
||||||
|
<mat-radio-button value="all">{{
|
||||||
|
"ListTunnelFlight_AllFlights" | translate
|
||||||
|
}}</mat-radio-button>
|
||||||
|
</mat-radio-group>
|
||||||
|
|
||||||
<mat-progress-bar
|
<mat-nav-list>
|
||||||
[mode]="'indeterminate'"
|
@for (stat of stats; track stat) {
|
||||||
*ngIf="isLoading"
|
<mat-list-item matListItemLine>
|
||||||
></mat-progress-bar>
|
<label>{{ stat.id }} : {{ stat.values }}</label>
|
||||||
|
</mat-list-item>
|
||||||
|
}
|
||||||
|
</mat-nav-list>
|
||||||
|
|
||||||
<mat-radio-group
|
<div class="chart-container">
|
||||||
[(ngModel)]="selectedPeriod"
|
<!-- https://www.freecodecamp.org/news/how-to-make-bar-and-line-charts-using-chartjs-in-angular/ -->
|
||||||
(ngModelChange)="onPeriodChange()"
|
<canvas
|
||||||
>
|
baseChart
|
||||||
<mat-radio-button value="currentYear">{{
|
[data]="barChartData"
|
||||||
"ListTunnelFlight_CurrentYear" | translate
|
[options]="barChartOptions"
|
||||||
}}</mat-radio-button>
|
[legend]="barChartLegend"
|
||||||
<mat-radio-button value="12Months">{{
|
[type]="barChartType"
|
||||||
"ListTunnelFlight_12Months" | translate
|
>
|
||||||
}}</mat-radio-button>
|
</canvas>
|
||||||
<mat-radio-button value="all">{{
|
</div>
|
||||||
"ListTunnelFlight_AllFlights" | translate
|
|
||||||
}}</mat-radio-button>
|
|
||||||
</mat-radio-group>
|
|
||||||
|
|
||||||
<mat-nav-list>
|
<div>
|
||||||
<mat-list-item matListItemLine *ngFor="let stat of stats">
|
<button mat-raised-button color="accent" (click)="onLoadTable()">
|
||||||
<label>{{ stat.id }} : {{ stat.values }}</label>
|
{{ "ListTunnelFlight_LoadTable" | translate }}
|
||||||
</mat-list-item>
|
</button>
|
||||||
</mat-nav-list>
|
|
||||||
|
|
||||||
<div class="chart-container">
|
@if (dataSourceTable?.data.length) {
|
||||||
<!-- https://www.freecodecamp.org/news/how-to-make-bar-and-line-charts-using-chartjs-in-angular/ -->
|
<table mat-table [dataSource]="dataSourceTable">
|
||||||
<canvas
|
<ng-container matColumnDef="id">
|
||||||
baseChart
|
<th mat-header-cell *matHeaderCellDef>ID</th>
|
||||||
[data]="barChartData"
|
<td mat-cell *matCellDef="let element">
|
||||||
[options]="barChartOptions"
|
<span
|
||||||
[legend]="barChartLegend"
|
class="smallSpanWithBreakWord"
|
||||||
[type]="barChartType"
|
[innerHTML]="element.id"
|
||||||
>
|
></span>
|
||||||
</canvas>
|
</td>
|
||||||
</div>
|
</ng-container>
|
||||||
|
<ng-container matColumnDef="tunnel">
|
||||||
<div>
|
<th mat-header-cell *matHeaderCellDef>Tunnel</th>
|
||||||
<button mat-raised-button color="accent" (click)="onLoadTable()">
|
<td mat-cell *matCellDef="let element">
|
||||||
{{ "ListTunnelFlight_LoadTable" | translate }}
|
<span
|
||||||
</button>
|
class="smallSpanWithBreakWord"
|
||||||
|
[innerHTML]="element.tunnel.name"
|
||||||
<table
|
></span>
|
||||||
mat-table
|
</td>
|
||||||
[dataSource]="dataSourceTable"
|
</ng-container>
|
||||||
*ngIf="dataSourceTable?.data.length"
|
<ng-container matColumnDef="jumpType">
|
||||||
>
|
<th mat-header-cell *matHeaderCellDef>Jump Type</th>
|
||||||
<ng-container matColumnDef="id">
|
<td mat-cell *matCellDef="let element">
|
||||||
<th mat-header-cell *matHeaderCellDef>ID</th>
|
<span
|
||||||
<td mat-cell *matCellDef="let element">
|
class="smallSpanWithBreakWord"
|
||||||
<span class="smallSpanWithBreakWord" [innerHTML]="element.id"></span>
|
[innerHTML]="element.jumpType.name"
|
||||||
</td>
|
></span>
|
||||||
</ng-container>
|
</td>
|
||||||
|
</ng-container>
|
||||||
<ng-container matColumnDef="tunnel">
|
<ng-container matColumnDef="nbMinutes">
|
||||||
<th mat-header-cell *matHeaderCellDef>Tunnel</th>
|
<th mat-header-cell *matHeaderCellDef>Minutes</th>
|
||||||
<td mat-cell *matCellDef="let element">
|
<td mat-cell *matCellDef="let element">
|
||||||
<span
|
<span
|
||||||
class="smallSpanWithBreakWord"
|
class="smallSpanWithBreakWord"
|
||||||
[innerHTML]="element.tunnel.name"
|
[innerHTML]="element.nbMinutes"
|
||||||
></span>
|
></span>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
<ng-container matColumnDef="notes">
|
||||||
<ng-container matColumnDef="jumpType">
|
<th mat-header-cell *matHeaderCellDef>Notes</th>
|
||||||
<th mat-header-cell *matHeaderCellDef>Jump Type</th>
|
<td mat-cell *matCellDef="let element">
|
||||||
<td mat-cell *matCellDef="let element">
|
<span
|
||||||
<span
|
class="smallSpanWithBreakWord"
|
||||||
class="smallSpanWithBreakWord"
|
[innerHTML]="element.notes"
|
||||||
[innerHTML]="element.jumpType.name"
|
></span>
|
||||||
></span>
|
</td>
|
||||||
</td>
|
</ng-container>
|
||||||
</ng-container>
|
<ng-container matColumnDef="flightDate">
|
||||||
|
<th mat-header-cell *matHeaderCellDef>Date</th>
|
||||||
<ng-container matColumnDef="nbMinutes">
|
<td mat-cell *matCellDef="let element">
|
||||||
<th mat-header-cell *matHeaderCellDef>Minutes</th>
|
<span
|
||||||
<td mat-cell *matCellDef="let element">
|
class="smallSpanWithBreakWord"
|
||||||
<span
|
[innerHTML]="
|
||||||
class="smallSpanWithBreakWord"
|
element.flightDate | date: 'yyyy-MM-dd'
|
||||||
[innerHTML]="element.nbMinutes"
|
"
|
||||||
></span>
|
></span>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
<ng-container matColumnDef="actions">
|
||||||
<ng-container matColumnDef="notes">
|
<th
|
||||||
<th mat-header-cell *matHeaderCellDef>Notes</th>
|
mat-header-cell
|
||||||
<td mat-cell *matCellDef="let element">
|
*matHeaderCellDef
|
||||||
<span
|
style="min-width: 80px"
|
||||||
class="smallSpanWithBreakWord"
|
></th>
|
||||||
[innerHTML]="element.notes"
|
<td
|
||||||
></span>
|
mat-cell
|
||||||
</td>
|
*matCellDef="let element"
|
||||||
</ng-container>
|
style="text-align: left"
|
||||||
|
>
|
||||||
<ng-container matColumnDef="flightDate">
|
<mat-icon
|
||||||
<th mat-header-cell *matHeaderCellDef>Date</th>
|
aria-hidden="false"
|
||||||
<td mat-cell *matCellDef="let element">
|
aria-label="Delete this jump"
|
||||||
<span
|
style="cursor: pointer"
|
||||||
class="smallSpanWithBreakWord"
|
(click)="delete(element)"
|
||||||
[innerHTML]="element.flightDate | date: 'yyyy-MM-dd'"
|
svgIcon="delete"
|
||||||
></span>
|
></mat-icon>
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
<tr
|
||||||
<ng-container matColumnDef="actions">
|
mat-header-row
|
||||||
<th mat-header-cell *matHeaderCellDef style="min-width: 80px"></th>
|
*matHeaderRowDef="displayedColumns; sticky: true"
|
||||||
<td mat-cell *matCellDef="let element" style="text-align: left">
|
></tr>
|
||||||
<mat-icon
|
<tr
|
||||||
aria-hidden="false"
|
mat-row
|
||||||
aria-label="Delete this jump"
|
*matRowDef="let row; columns: displayedColumns"
|
||||||
style="cursor: pointer"
|
></tr>
|
||||||
(click)="delete(element)"
|
</table>
|
||||||
svgIcon="delete"
|
}
|
||||||
></mat-icon>
|
</div>
|
||||||
</td>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
|
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -22,257 +22,274 @@ import { DateService } from "../../services/date.service";
|
|||||||
import { TunnelFlight, TunnelFlightByMonth } from "../../models/tunnel-flight";
|
import { TunnelFlight, TunnelFlightByMonth } from "../../models/tunnel-flight";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-list-of-tunnel-flights",
|
selector: "app-list-of-tunnel-flights",
|
||||||
templateUrl: "./list-of-tunnel-flights.component.html",
|
templateUrl: "./list-of-tunnel-flights.component.html",
|
||||||
styleUrls: ["./list-of-tunnel-flights.component.css"],
|
styleUrls: ["./list-of-tunnel-flights.component.css"],
|
||||||
imports: [
|
imports: [
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
BaseChartDirective,
|
BaseChartDirective,
|
||||||
CommonModule,
|
CommonModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
MatListModule,
|
MatListModule,
|
||||||
MatProgressSpinnerModule,
|
MatProgressSpinnerModule,
|
||||||
RouterLink,
|
RouterLink,
|
||||||
MatRadioModule,
|
MatRadioModule,
|
||||||
MatProgressBarModule,
|
MatProgressBarModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
RouterModule,
|
RouterModule,
|
||||||
MatTableModule,
|
MatTableModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class ListOfTunnelFlightsComponent implements OnInit {
|
export class ListOfTunnelFlightsComponent implements OnInit {
|
||||||
public barChartLegend = true;
|
public barChartLegend = true;
|
||||||
public barChartData: ChartData<"bar">;
|
public barChartData: ChartData<"bar">;
|
||||||
public barChartOptions: ChartConfiguration["options"];
|
public barChartOptions: ChartConfiguration["options"];
|
||||||
public barChartType: ChartType;
|
public barChartType: ChartType;
|
||||||
public isLoading: boolean = false;
|
public isLoading: boolean = false;
|
||||||
public selectedPeriod: string;
|
public selectedPeriod: string;
|
||||||
public dataSourceTable: MatTableDataSource<TunnelFlight> =
|
public dataSourceTable: MatTableDataSource<TunnelFlight> =
|
||||||
new MatTableDataSource();
|
new MatTableDataSource();
|
||||||
public displayedColumns: Array<string> = [
|
public displayedColumns: Array<string> = [
|
||||||
"id",
|
"id",
|
||||||
"tunnel",
|
"tunnel",
|
||||||
"jumpType",
|
"jumpType",
|
||||||
"nbMinutes",
|
"nbMinutes",
|
||||||
"notes",
|
"notes",
|
||||||
"flightDate",
|
"flightDate",
|
||||||
"actions",
|
"actions",
|
||||||
];
|
];
|
||||||
public stats: Array<{ id: String | Number; values: String | Number }> = [];
|
public stats: Array<{ id: String | Number; values: String | Number }> = [];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private serviceComm: ServiceComm,
|
private serviceComm: ServiceComm,
|
||||||
private serviceTunnelFlight: TunnelFlightService,
|
private serviceTunnelFlight: TunnelFlightService,
|
||||||
private translateService: TranslateService,
|
private translateService: TranslateService,
|
||||||
private dateService: DateService
|
private dateService: DateService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
||||||
if (data === true) {
|
if (data === true) {
|
||||||
this.updateTitle();
|
this.updateTitle();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
this.updateTitle();
|
|
||||||
|
|
||||||
this.chartConfig();
|
|
||||||
this.selectedPeriod = "currentYear";
|
|
||||||
this.getDataForGraph();
|
|
||||||
}
|
|
||||||
|
|
||||||
public onPeriodChange() {
|
|
||||||
this.getDataForGraph();
|
|
||||||
if (this.dataSourceTable?.data.length > 0) {
|
|
||||||
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;
|
|
||||||
});
|
});
|
||||||
}
|
this.updateTitle();
|
||||||
|
|
||||||
|
this.chartConfig();
|
||||||
|
this.selectedPeriod = "currentYear";
|
||||||
|
this.getDataForGraph();
|
||||||
}
|
}
|
||||||
|
|
||||||
const results = Array.from(tmpResults, function (item) {
|
public onPeriodChange() {
|
||||||
return { label: item[0], data: item[1] };
|
this.getDataForGraph();
|
||||||
});
|
if (this.dataSourceTable?.data.length > 0) {
|
||||||
|
this.getDataForTable();
|
||||||
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 onLoadTable() {
|
||||||
}
|
this.getDataForTable();
|
||||||
|
}
|
||||||
|
|
||||||
public delete(item: TunnelFlight) {
|
private chartConfig() {
|
||||||
let data: Array<TunnelFlight> = this.dataSourceTable.data;
|
this.barChartType = "bar";
|
||||||
data = data.filter((d) => d.id !== item.id);
|
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,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
this.dataSourceTable.data = data;
|
private updateTitle() {
|
||||||
this.serviceTunnelFlight.deleteTunnelFlight(item);
|
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: 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,50 +1,66 @@
|
|||||||
<form
|
<form
|
||||||
focusInvalidInput
|
focusInvalidInput
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
style="padding: 10px"
|
style="padding: 10px"
|
||||||
[formGroup]="loginForm"
|
[formGroup]="loginForm"
|
||||||
(ngSubmit)="onLoginSubmit()"
|
(ngSubmit)="onLoginSubmit()"
|
||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ "LoginUser_Username" | translate }}</mat-label>
|
<mat-label>{{ "LoginUser_Username" | translate }}</mat-label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
matInput
|
matInput
|
||||||
#username="matInput"
|
#username="matInput"
|
||||||
formControlName="username"
|
formControlName="username"
|
||||||
[ngClass]="{ 'is-invalid': submitted && formCtrls['username'].errors }"
|
[ngClass]="{
|
||||||
/>
|
'is-invalid': submitted && formCtrls['username'].errors,
|
||||||
<mat-error *ngIf="formCtrls['username'].hasError('required')">
|
}"
|
||||||
{{ "LoginUser_UsernameRequired" | translate }}
|
/>
|
||||||
</mat-error>
|
@if (formCtrls["username"].hasError("required")) {
|
||||||
<mat-error *ngIf="formCtrls['username'].hasError('minlength')">
|
<mat-error>
|
||||||
{{ 'LoginUser_UsernamePattern | translate }}
|
{{ "LoginUser_UsernameRequired" | translate }}
|
||||||
</mat-error>
|
</mat-error>
|
||||||
</mat-form-field>
|
}
|
||||||
</p>
|
@if (formCtrls["username"].hasError("minlength")) {
|
||||||
<p>
|
<mat-error>
|
||||||
<mat-form-field>
|
{{ 'LoginUser_UsernamePattern | translate }}
|
||||||
<mat-label>{{ "LoginUser_Password" | translate }}</mat-label>
|
</mat-error>
|
||||||
<input
|
}
|
||||||
type="password"
|
</mat-form-field>
|
||||||
matInput
|
</p>
|
||||||
formControlName="password"
|
<p>
|
||||||
[ngClass]="{ 'is-invalid': submitted && formCtrls['password'].errors }"
|
<mat-form-field>
|
||||||
/>
|
<mat-label>{{ "LoginUser_Password" | translate }}</mat-label>
|
||||||
<mat-error *ngIf="formCtrls['password'].hasError('required')">
|
<input
|
||||||
{{ "LoginUser_PasswordRequired" | translate }}
|
type="password"
|
||||||
</mat-error>
|
matInput
|
||||||
<mat-error *ngIf="formCtrls['password'].hasError('pattern')">
|
formControlName="password"
|
||||||
{{ "LoginUser_PasswordPattern" | translate }}
|
[ngClass]="{
|
||||||
</mat-error>
|
'is-invalid': submitted && formCtrls['password'].errors,
|
||||||
</mat-form-field>
|
}"
|
||||||
</p>
|
/>
|
||||||
|
@if (formCtrls["password"].hasError("required")) {
|
||||||
|
<mat-error>
|
||||||
|
{{ "LoginUser_PasswordRequired" | translate }}
|
||||||
|
</mat-error>
|
||||||
|
}
|
||||||
|
@if (formCtrls["password"].hasError("pattern")) {
|
||||||
|
<mat-error>
|
||||||
|
{{ "LoginUser_PasswordPattern" | translate }}
|
||||||
|
</mat-error>
|
||||||
|
}
|
||||||
|
</mat-form-field>
|
||||||
|
</p>
|
||||||
|
|
||||||
<button [disabled]="loading" mat-raised-button color="accent">
|
<button [disabled]="loading" mat-raised-button color="accent">
|
||||||
<span *ngIf="loading" class="spinner-border spinner-border-sm mr-1"></span>
|
@if (loading) {
|
||||||
{{ "LoginUser_BtnLogin" | translate }}
|
<span class="spinner-border spinner-border-sm mr-1"></span>
|
||||||
</button>
|
}
|
||||||
|
{{ "LoginUser_BtnLogin" | translate }}
|
||||||
|
</button>
|
||||||
|
|
||||||
<div *ngIf="error" class="alert alert-danger mt-3 mb-0">{{ error }}</div>
|
@if (error) {
|
||||||
|
<div class="alert alert-danger mt-3 mb-0">{{ error }}</div>
|
||||||
|
}
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ import { Component, OnInit, ViewChild, AfterViewInit } from "@angular/core";
|
|||||||
import { Router, ActivatedRoute } from "@angular/router";
|
import { Router, ActivatedRoute } from "@angular/router";
|
||||||
import { CommonModule } from "@angular/common";
|
import { CommonModule } from "@angular/common";
|
||||||
import {
|
import {
|
||||||
FormBuilder,
|
FormBuilder,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
Validators,
|
Validators,
|
||||||
} from "@angular/forms";
|
} from "@angular/forms";
|
||||||
import { TranslateModule, TranslatePipe } from "@ngx-translate/core";
|
import { TranslateModule, TranslatePipe } from "@ngx-translate/core";
|
||||||
import { MatInput, MatInputModule } from "@angular/material/input";
|
import { MatInput, MatInputModule } from "@angular/material/input";
|
||||||
@@ -17,72 +17,72 @@ import { first } from "rxjs/operators";
|
|||||||
import { AuthenticationService } from "../../services/authentication.service";
|
import { AuthenticationService } from "../../services/authentication.service";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-login-user",
|
selector: "app-login-user",
|
||||||
templateUrl: "./login-user.component.html",
|
templateUrl: "./login-user.component.html",
|
||||||
styleUrls: ["./login-user.component.css"],
|
styleUrls: ["./login-user.component.css"],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
MatFormFieldModule,
|
MatFormFieldModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
MatInputModule,
|
MatInputModule,
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
TranslatePipe,
|
TranslatePipe,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class LoginUserComponent implements OnInit {
|
export class LoginUserComponent implements OnInit {
|
||||||
public loginForm: FormGroup;
|
public loginForm: FormGroup;
|
||||||
public loading = false;
|
public loading = false;
|
||||||
public submitted = false;
|
public submitted = false;
|
||||||
public returnUrl: string;
|
public returnUrl: string;
|
||||||
public error: string = "";
|
public error: string = "";
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private authenticationService: AuthenticationService
|
private authenticationService: AuthenticationService,
|
||||||
) {
|
) {
|
||||||
if (this.authenticationService.currentUserValue) {
|
if (this.authenticationService.currentUserValue) {
|
||||||
this.router.navigate(["/"]);
|
this.router.navigate(["/"]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.loginForm = this.formBuilder.group(
|
this.loginForm = this.formBuilder.group(
|
||||||
{
|
{
|
||||||
username: ["", [Validators.required, Validators.minLength(3)]],
|
username: ["", [Validators.required, Validators.minLength(3)]],
|
||||||
password: ["", [Validators.required]],
|
password: ["", [Validators.required]],
|
||||||
},
|
},
|
||||||
{ updateOn: "submit" }
|
{ updateOn: "submit" },
|
||||||
);
|
);
|
||||||
|
|
||||||
// get return url from route parameters or default to '/'
|
// 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() {
|
get formCtrls() {
|
||||||
return this.loginForm.controls;
|
return this.loginForm.controls;
|
||||||
}
|
}
|
||||||
|
|
||||||
public onLoginSubmit() {
|
public onLoginSubmit() {
|
||||||
this.submitted = true;
|
this.submitted = true;
|
||||||
|
|
||||||
if (this.loginForm.valid) {
|
if (this.loginForm.valid) {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
this.authenticationService
|
this.authenticationService
|
||||||
.login(
|
.login(
|
||||||
this.formCtrls["username"].value,
|
this.formCtrls["username"].value,
|
||||||
this.formCtrls["password"].value
|
this.formCtrls["password"].value,
|
||||||
)
|
)
|
||||||
.pipe(first())
|
.pipe(first())
|
||||||
.subscribe({
|
.subscribe({
|
||||||
complete: () => this.router.navigate([this.returnUrl]),
|
complete: () => this.router.navigate([this.returnUrl]),
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
this.error = error.message;
|
this.error = error.message;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
.content {
|
.content {
|
||||||
height: 90vh;
|
height: 90vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mat-card-title {
|
.mat-card-title {
|
||||||
margin: 0 !important;
|
margin: 0 !important;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,43 +1,51 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<mat-card style="max-width: 500px" flex="50">
|
<mat-card style="max-width: 500px" flex="50">
|
||||||
<mat-card-header
|
<mat-card-header
|
||||||
style="
|
style="
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background-color: rgba(0, 0, 0, 0.03);
|
background-color: rgba(0, 0, 0, 0.03);
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<mat-card-title>{{ "Login_Title" | translate }}</mat-card-title>
|
<mat-card-title>{{ "Login_Title" | translate }}</mat-card-title>
|
||||||
|
|
||||||
<mat-select
|
<mat-select
|
||||||
(selectionChange)="switchLang($event)"
|
(selectionChange)="switchLang($event)"
|
||||||
[(value)]="selectedLanguageFlag"
|
[(value)]="selectedLanguageFlag"
|
||||||
style="width: 60px; padding-left: 30px"
|
style="width: 60px; padding-left: 30px"
|
||||||
>
|
>
|
||||||
<mat-select-trigger>
|
<mat-select-trigger>
|
||||||
<img
|
<img
|
||||||
src="{{ 'assets/img/' + selectedLanguageFlag + '.svg' }}"
|
src="{{
|
||||||
style="width: 30px"
|
'assets/img/' + selectedLanguageFlag + '.svg'
|
||||||
/>
|
}}"
|
||||||
</mat-select-trigger>
|
style="width: 30px"
|
||||||
<mat-option value="fr">
|
/>
|
||||||
<img src="assets/img/fr.svg" style="width: 30px" />
|
</mat-select-trigger>
|
||||||
</mat-option>
|
<mat-option value="fr">
|
||||||
<mat-option value="en">
|
<img src="assets/img/fr.svg" style="width: 30px" />
|
||||||
<img src="assets/img/en.svg" style="width: 30px" />
|
</mat-option>
|
||||||
</mat-option>
|
<mat-option value="en">
|
||||||
</mat-select>
|
<img src="assets/img/en.svg" style="width: 30px" />
|
||||||
</mat-card-header>
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-card-header>
|
||||||
|
|
||||||
<mat-card-content>
|
<mat-card-content>
|
||||||
<mat-tab-group mat-align-tabs="center" animationDuration="0ms">
|
<mat-tab-group mat-align-tabs="center" animationDuration="0ms">
|
||||||
<mat-tab label="{{ 'Login_Tab_WithUser' | translate }}" tabIndex="-1">
|
<mat-tab
|
||||||
<app-login-user></app-login-user>
|
label="{{ 'Login_Tab_WithUser' | translate }}"
|
||||||
</mat-tab>
|
tabIndex="-1"
|
||||||
<mat-tab label="{{ 'Login_Tab_CreateUser' | translate }}" tabIndex="-1">
|
>
|
||||||
<app-create-user></app-create-user>
|
<app-login-user></app-login-user>
|
||||||
</mat-tab>
|
</mat-tab>
|
||||||
</mat-tab-group>
|
<mat-tab
|
||||||
</mat-card-content>
|
label="{{ 'Login_Tab_CreateUser' | translate }}"
|
||||||
</mat-card>
|
tabIndex="-1"
|
||||||
|
>
|
||||||
|
<app-create-user></app-create-user>
|
||||||
|
</mat-tab>
|
||||||
|
</mat-tab-group>
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { Component, OnInit } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
import {
|
import {
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
TranslatePipe,
|
TranslatePipe,
|
||||||
TranslateService,
|
TranslateService,
|
||||||
} from "@ngx-translate/core";
|
} from "@ngx-translate/core";
|
||||||
import { CommonModule } from "@angular/common";
|
|
||||||
import { MatSelectModule } from "@angular/material/select";
|
import { MatSelectModule } from "@angular/material/select";
|
||||||
import { MatOptionModule } from "@angular/material/core";
|
import { MatOptionModule } from "@angular/material/core";
|
||||||
import { MatCardModule } from "@angular/material/card";
|
import { MatCardModule } from "@angular/material/card";
|
||||||
@@ -14,32 +14,31 @@ import { LoginUserComponent } from "../login-user/login-user.component";
|
|||||||
import { CreateUserComponent } from "../create-user/create-user.component";
|
import { CreateUserComponent } from "../create-user/create-user.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-login",
|
selector: "app-login",
|
||||||
templateUrl: "./login.component.html",
|
templateUrl: "./login.component.html",
|
||||||
styleUrls: ["./login.component.css"],
|
styleUrls: ["./login.component.css"],
|
||||||
imports: [
|
imports: [
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
CommonModule,
|
MatSelectModule,
|
||||||
MatSelectModule,
|
MatOptionModule,
|
||||||
MatOptionModule,
|
MatCardModule,
|
||||||
MatCardModule,
|
MatTabsModule,
|
||||||
MatTabsModule,
|
LoginUserComponent,
|
||||||
LoginUserComponent,
|
CreateUserComponent,
|
||||||
CreateUserComponent,
|
TranslateModule,
|
||||||
TranslateModule,
|
],
|
||||||
],
|
|
||||||
})
|
})
|
||||||
export class LoginComponent implements OnInit {
|
export class LoginComponent implements OnInit {
|
||||||
public selectedLanguageFlag: string;
|
public selectedLanguageFlag: string;
|
||||||
|
|
||||||
constructor(private translate: TranslateService) {
|
constructor(private translate: TranslateService) {
|
||||||
this.selectedLanguageFlag = "en";
|
this.selectedLanguageFlag = "en";
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {}
|
ngOnInit() {}
|
||||||
|
|
||||||
public switchLang(event: any) {
|
public switchLang(event: any) {
|
||||||
this.translate.use(event.value);
|
this.translate.use(event.value);
|
||||||
this.selectedLanguageFlag = event.value;
|
this.selectedLanguageFlag = event.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
.content {
|
.content {
|
||||||
height: 90vh;
|
height: 90vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: left;
|
justify-content: left;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: initial;
|
align-items: initial;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,23 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<form [formGroup]="addForm" (ngSubmit)="onSubmit(addForm.value)">
|
<form [formGroup]="addForm" (ngSubmit)="onSubmit(addForm.value)">
|
||||||
<p>
|
<p>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>Aircraft name</mat-label>
|
<mat-label>Aircraft name</mat-label>
|
||||||
<input matInput type="text" formControlName="aircraftName">
|
<input matInput type="text" formControlName="aircraftName" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<input type="file" #fileUpload id="fileUpload" name="fileUpload" accept="image/*" formControlName="image"
|
<input
|
||||||
(change)="onFileChanged($event)" />
|
type="file"
|
||||||
</p>
|
#fileUpload
|
||||||
|
id="fileUpload"
|
||||||
|
name="fileUpload"
|
||||||
|
accept="image/*"
|
||||||
|
formControlName="image"
|
||||||
|
(change)="onFileChanged($event)"
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
|
||||||
<button type="submit" mat-raised-button color="accent">Add</button>
|
<button type="submit" mat-raised-button color="accent">Add</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { Component, OnInit } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
import {
|
import {
|
||||||
FormControl,
|
FormControl,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
Validators,
|
Validators,
|
||||||
} from "@angular/forms";
|
} from "@angular/forms";
|
||||||
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
||||||
import { MatFormFieldModule } from "@angular/material/form-field";
|
import { MatFormFieldModule } from "@angular/material/form-field";
|
||||||
@@ -16,101 +16,106 @@ import { AircraftService } from "../../services/aircraft.service";
|
|||||||
import { ServiceComm } from "../../services/service-comm.service";
|
import { ServiceComm } from "../../services/service-comm.service";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-new-aircraft",
|
selector: "app-new-aircraft",
|
||||||
templateUrl: "./new-aircraft.component.html",
|
templateUrl: "./new-aircraft.component.html",
|
||||||
styleUrls: ["./new-aircraft.component.css"],
|
styleUrls: ["./new-aircraft.component.css"],
|
||||||
imports: [
|
imports: [
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
MatFormFieldModule,
|
MatFormFieldModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
MatFormFieldModule,
|
MatFormFieldModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
MatInputModule,
|
MatInputModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class NewAircraftComponent implements OnInit {
|
export class NewAircraftComponent implements OnInit {
|
||||||
public addForm: FormGroup;
|
public addForm: FormGroup;
|
||||||
public imageError: string;
|
public imageError: string;
|
||||||
private selectedFile: string;
|
private selectedFile: string;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private serviceComm: ServiceComm,
|
private serviceComm: ServiceComm,
|
||||||
private serviceApi: AircraftService,
|
private serviceApi: AircraftService,
|
||||||
private translateService: TranslateService,
|
private translateService: TranslateService,
|
||||||
) {
|
) {
|
||||||
this.addForm = new FormGroup(
|
this.addForm = new FormGroup(
|
||||||
{
|
{
|
||||||
aircraftName: new FormControl("", Validators.required),
|
aircraftName: new FormControl("", Validators.required),
|
||||||
},
|
},
|
||||||
{ updateOn: "blur" },
|
{ updateOn: "blur" },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.updateTitle();
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit(formData) {
|
|
||||||
if (formData.invalid) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.serviceApi
|
onSubmit(formData) {
|
||||||
.addAircraft(formData.aircraftName, this.selectedFile)
|
if (formData.invalid) {
|
||||||
.subscribe(() => {
|
return;
|
||||||
this.serviceComm.refreshData(AddAction.Aircraft);
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public onFileChanged(fileInput: any) {
|
this.serviceApi
|
||||||
const file = fileInput.dataTransfer
|
.addAircraft(formData.aircraftName, this.selectedFile)
|
||||||
? fileInput.dataTransfer.files[0]
|
.subscribe(() => {
|
||||||
: fileInput.target.files[0];
|
this.serviceComm.refreshData(AddAction.Aircraft);
|
||||||
const allowed_types = ["image/png", "image/jpeg"];
|
});
|
||||||
const max_size = 20971520;
|
|
||||||
|
|
||||||
if (!allowed_types.includes(file.type)) {
|
|
||||||
this.imageError = "Only Images are allowed ( JPG | PNG )";
|
|
||||||
} else if (file.size > max_size) {
|
|
||||||
this.imageError = "Maximum size allowed is " + max_size / 1000 + "Mb";
|
|
||||||
} else {
|
|
||||||
const reader = new FileReader();
|
|
||||||
reader.onload = this.checkAndExtractDataToBase64.bind(this);
|
|
||||||
reader.readAsDataURL(fileInput.target.files[0]);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private checkAndExtractDataToBase64(e: any) {
|
public onFileChanged(fileInput: any) {
|
||||||
const max_height = 15200;
|
const file = fileInput.dataTransfer
|
||||||
const max_width = 25600;
|
? fileInput.dataTransfer.files[0]
|
||||||
|
: fileInput.target.files[0];
|
||||||
|
const allowed_types = ["image/png", "image/jpeg"];
|
||||||
|
const max_size = 20971520;
|
||||||
|
|
||||||
const image = new Image();
|
if (!allowed_types.includes(file.type)) {
|
||||||
image.src = e.target.result;
|
this.imageError = "Only Images are allowed ( JPG | PNG )";
|
||||||
image.onload = (rs) => {
|
} else if (file.size > max_size) {
|
||||||
const img_height = rs.currentTarget["height"];
|
this.imageError =
|
||||||
const img_width = rs.currentTarget["width"];
|
"Maximum size allowed is " + max_size / 1000 + "Mb";
|
||||||
|
} else {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = this.checkAndExtractDataToBase64.bind(this);
|
||||||
|
reader.readAsDataURL(fileInput.target.files[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (img_height > max_height && img_width > max_width) {
|
private checkAndExtractDataToBase64(e: any) {
|
||||||
this.imageError =
|
const max_height = 15200;
|
||||||
"Maximum dimentions allowed " + max_height + "*" + max_width + "px";
|
const max_width = 25600;
|
||||||
} else {
|
|
||||||
const imgBase64Path = e.target.result;
|
|
||||||
this.selectedFile = imgBase64Path;
|
|
||||||
this.imageError = "OK";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private updateTitle() {
|
const image = new Image();
|
||||||
this.translateService.get("NewAircraft_Title").subscribe((data) => {
|
image.src = e.target.result;
|
||||||
this.serviceComm.updatedComponentTitle(data);
|
image.onload = (rs) => {
|
||||||
});
|
const img_height = rs.currentTarget["height"];
|
||||||
}
|
const img_width = rs.currentTarget["width"];
|
||||||
|
|
||||||
|
if (img_height > max_height && img_width > max_width) {
|
||||||
|
this.imageError =
|
||||||
|
"Maximum dimentions allowed " +
|
||||||
|
max_height +
|
||||||
|
"*" +
|
||||||
|
max_width +
|
||||||
|
"px";
|
||||||
|
} else {
|
||||||
|
const imgBase64Path = e.target.result;
|
||||||
|
this.selectedFile = imgBase64Path;
|
||||||
|
this.imageError = "OK";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateTitle() {
|
||||||
|
this.translateService.get("NewAircraft_Title").subscribe((data) => {
|
||||||
|
this.serviceComm.updatedComponentTitle(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
.content {
|
.content {
|
||||||
height: 90vh;
|
height: 90vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: left;
|
justify-content: left;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: initial;
|
align-items: initial;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,42 +1,42 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<form [formGroup]="addForm" (ngSubmit)="onSubmit(addForm.value)">
|
<form [formGroup]="addForm" (ngSubmit)="onSubmit(addForm.value)">
|
||||||
<p>
|
<p>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>Dropzone name</mat-label>
|
<mat-label>Dropzone name</mat-label>
|
||||||
<input matInput type="text" formControlName="dzName" />
|
<input matInput type="text" formControlName="dzName" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>GPS</mat-label>
|
<mat-label>GPS</mat-label>
|
||||||
<input matInput type="text" formControlName="gps" />
|
<input matInput type="text" formControlName="gps" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>Address of the DZ</mat-label>
|
<mat-label>Address of the DZ</mat-label>
|
||||||
<textarea matInput formControlName="address"></textarea>
|
<textarea matInput formControlName="address"></textarea>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>Web site</mat-label>
|
<mat-label>Web site</mat-label>
|
||||||
<input matInput type="text" formControlName="website" />
|
<input matInput type="text" formControlName="website" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>Mail of contact</mat-label>
|
<mat-label>Mail of contact</mat-label>
|
||||||
<input matInput type="text" formControlName="contactMail" />
|
<input matInput type="text" formControlName="contactMail" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<mat-checkbox formControlName="isDz">Is a dropzone</mat-checkbox>
|
<mat-checkbox formControlName="isDz">Is a dropzone</mat-checkbox>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<mat-checkbox formControlName="isTunnel">Is a tunnel</mat-checkbox>
|
<mat-checkbox formControlName="isTunnel">Is a tunnel</mat-checkbox>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<button type="submit" mat-raised-button color="accent">Add</button>
|
<button type="submit" mat-raised-button color="accent">Add</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { Component, OnInit } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
import {
|
import {
|
||||||
FormControl,
|
FormControl,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
Validators,
|
Validators,
|
||||||
} from "@angular/forms";
|
} from "@angular/forms";
|
||||||
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
||||||
import { MatFormFieldModule } from "@angular/material/form-field";
|
import { MatFormFieldModule } from "@angular/material/form-field";
|
||||||
@@ -17,87 +17,87 @@ import { ServiceComm } from "../../services/service-comm.service";
|
|||||||
import { DropzoneService } from "../../services/dropzone.service";
|
import { DropzoneService } from "../../services/dropzone.service";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-new-drop-zone",
|
selector: "app-new-drop-zone",
|
||||||
templateUrl: "./new-drop-zone.component.html",
|
templateUrl: "./new-drop-zone.component.html",
|
||||||
styleUrls: ["./new-drop-zone.component.css"],
|
styleUrls: ["./new-drop-zone.component.css"],
|
||||||
imports: [
|
imports: [
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
MatFormFieldModule,
|
MatFormFieldModule,
|
||||||
MatCheckboxModule,
|
MatCheckboxModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
MatFormFieldModule,
|
MatFormFieldModule,
|
||||||
MatInputModule,
|
MatInputModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class NewDropZoneComponent implements OnInit {
|
export class NewDropZoneComponent implements OnInit {
|
||||||
public addForm: FormGroup;
|
public addForm: FormGroup;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private serviceComm: ServiceComm,
|
private serviceComm: ServiceComm,
|
||||||
private dropzoneService: DropzoneService,
|
private dropzoneService: DropzoneService,
|
||||||
private translateService: TranslateService,
|
private translateService: TranslateService,
|
||||||
) {
|
) {
|
||||||
this.addForm = new FormGroup(
|
this.addForm = new FormGroup(
|
||||||
{
|
{
|
||||||
dzName: new FormControl("", Validators.required),
|
dzName: new FormControl("", Validators.required),
|
||||||
gps: new FormControl("x.x,y.y", [
|
gps: new FormControl("x.x,y.y", [
|
||||||
Validators.required,
|
Validators.required,
|
||||||
Validators.pattern("d+.d+,d+.d+"),
|
Validators.pattern("d+.d+,d+.d+"),
|
||||||
]),
|
]),
|
||||||
address: new FormControl("", Validators.required),
|
address: new FormControl("", Validators.required),
|
||||||
website: new FormControl("", Validators.required),
|
website: new FormControl("", Validators.required),
|
||||||
contactMail: new FormControl("", [
|
contactMail: new FormControl("", [
|
||||||
Validators.required,
|
Validators.required,
|
||||||
Validators.email,
|
Validators.email,
|
||||||
]),
|
]),
|
||||||
isDz: new FormControl(true),
|
isDz: new FormControl(true),
|
||||||
isTunnel: new FormControl(false),
|
isTunnel: new FormControl(false),
|
||||||
},
|
},
|
||||||
{ updateOn: "blur" },
|
{ updateOn: "blur" },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.updateTitle();
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit(formData) {
|
|
||||||
const splitGps: Array<string> = formData.gps.split(",");
|
|
||||||
let dzType: Array<string> = new Array<string>();
|
|
||||||
|
|
||||||
if (formData.isDz === true) {
|
|
||||||
dzType.push("dz");
|
|
||||||
}
|
|
||||||
if (formData.isTunnel === true) {
|
|
||||||
dzType.push("tunnel");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.dropzoneService
|
onSubmit(formData) {
|
||||||
.addDropZone(
|
const splitGps: Array<string> = formData.gps.split(",");
|
||||||
splitGps[0],
|
let dzType: Array<string> = new Array<string>();
|
||||||
splitGps[1],
|
|
||||||
formData.dzName,
|
|
||||||
formData.address,
|
|
||||||
formData.website,
|
|
||||||
formData.contactMail,
|
|
||||||
dzType,
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
.subscribe(() => {
|
|
||||||
this.serviceComm.refreshData(AddAction.Dropzone);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private updateTitle() {
|
if (formData.isDz === true) {
|
||||||
this.translateService.get("NewDz_Title").subscribe((data) => {
|
dzType.push("dz");
|
||||||
this.serviceComm.updatedComponentTitle(data);
|
}
|
||||||
});
|
if (formData.isTunnel === true) {
|
||||||
}
|
dzType.push("tunnel");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dropzoneService
|
||||||
|
.addDropZone(
|
||||||
|
splitGps[0],
|
||||||
|
splitGps[1],
|
||||||
|
formData.dzName,
|
||||||
|
formData.address,
|
||||||
|
formData.website,
|
||||||
|
formData.contactMail,
|
||||||
|
dzType,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.subscribe(() => {
|
||||||
|
this.serviceComm.refreshData(AddAction.Dropzone);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateTitle() {
|
||||||
|
this.translateService.get("NewDz_Title").subscribe((data) => {
|
||||||
|
this.serviceComm.updatedComponentTitle(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
.content {
|
.content {
|
||||||
height: 90vh;
|
height: 90vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: left;
|
justify-content: left;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: initial;
|
align-items: initial;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,48 +1,48 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<form [formGroup]="addForm" (ngSubmit)="onSubmit(addForm.value)">
|
<form [formGroup]="addForm" (ngSubmit)="onSubmit(addForm.value)">
|
||||||
<p>
|
<p>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>Name of gear</mat-label>
|
<mat-label>Name of gear</mat-label>
|
||||||
<input matInput type="text" formControlName="name">
|
<input matInput type="text" formControlName="name" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>Manufacturer</mat-label>
|
<mat-label>Manufacturer</mat-label>
|
||||||
<input matInput type="text" formControlName="manufacturer">
|
<input matInput type="text" formControlName="manufacturer" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>Min size of canopy</mat-label>
|
<mat-label>Min size of canopy</mat-label>
|
||||||
<input matInput type="text" formControlName="minSize">
|
<input matInput type="text" formControlName="minSize" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>Max size of canopy</mat-label>
|
<mat-label>Max size of canopy</mat-label>
|
||||||
<input matInput type="text" formControlName="maxSize">
|
<input matInput type="text" formControlName="maxSize" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>AAD system</mat-label>
|
<mat-label>AAD system</mat-label>
|
||||||
<input matInput type="text" formControlName="aad">
|
<input matInput type="text" formControlName="aad" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>Main Canopy</mat-label>
|
<mat-label>Main Canopy</mat-label>
|
||||||
<input matInput type="text" formControlName="mainCanopy">
|
<input matInput type="text" formControlName="mainCanopy" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>Reserve canopy</mat-label>
|
<mat-label>Reserve canopy</mat-label>
|
||||||
<input matInput type="text" formControlName="reserveCanopy">
|
<input matInput type="text" formControlName="reserveCanopy" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<button mat-raised-button color="accent" type="submit">Add</button>
|
<button mat-raised-button color="accent" type="submit">Add</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { Component, OnInit } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
import {
|
import {
|
||||||
FormControl,
|
FormControl,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
Validators,
|
Validators,
|
||||||
} from "@angular/forms";
|
} from "@angular/forms";
|
||||||
import { MatFormFieldModule } from "@angular/material/form-field";
|
import { MatFormFieldModule } from "@angular/material/form-field";
|
||||||
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
||||||
@@ -15,85 +15,85 @@ import { GearService } from "../../services/gear.service";
|
|||||||
import { AddAction } from "../../models/add-action.enum";
|
import { AddAction } from "../../models/add-action.enum";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-new-gear",
|
selector: "app-new-gear",
|
||||||
templateUrl: "./new-gear.component.html",
|
templateUrl: "./new-gear.component.html",
|
||||||
styleUrls: ["./new-gear.component.css"],
|
styleUrls: ["./new-gear.component.css"],
|
||||||
imports: [
|
imports: [
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
MatFormFieldModule,
|
MatFormFieldModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
MatInputModule,
|
MatInputModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class NewGearComponent implements OnInit {
|
export class NewGearComponent implements OnInit {
|
||||||
public addForm: FormGroup;
|
public addForm: FormGroup;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private serviceComm: ServiceComm,
|
private serviceComm: ServiceComm,
|
||||||
private serviceApi: GearService,
|
private serviceApi: GearService,
|
||||||
private translateService: TranslateService,
|
private translateService: TranslateService,
|
||||||
) {
|
) {
|
||||||
this.addForm = new FormGroup(
|
this.addForm = new FormGroup(
|
||||||
{
|
{
|
||||||
name: new FormControl("", Validators.required),
|
name: new FormControl("", Validators.required),
|
||||||
manufacturer: new FormControl("", Validators.required),
|
manufacturer: new FormControl("", Validators.required),
|
||||||
minSize: new FormControl("", [
|
minSize: new FormControl("", [
|
||||||
Validators.required,
|
Validators.required,
|
||||||
Validators.min(60),
|
Validators.min(60),
|
||||||
Validators.max(320),
|
Validators.max(320),
|
||||||
]),
|
]),
|
||||||
maxSize: new FormControl("", [
|
maxSize: new FormControl("", [
|
||||||
Validators.required,
|
Validators.required,
|
||||||
Validators.min(60),
|
Validators.min(60),
|
||||||
Validators.max(320),
|
Validators.max(320),
|
||||||
]),
|
]),
|
||||||
aad: new FormControl("", Validators.required),
|
aad: new FormControl("", Validators.required),
|
||||||
mainCanopy: new FormControl("", [
|
mainCanopy: new FormControl("", [
|
||||||
Validators.required,
|
Validators.required,
|
||||||
Validators.min(60),
|
Validators.min(60),
|
||||||
Validators.max(320),
|
Validators.max(320),
|
||||||
]),
|
]),
|
||||||
reserveCanopy: new FormControl("", [
|
reserveCanopy: new FormControl("", [
|
||||||
Validators.required,
|
Validators.required,
|
||||||
Validators.min(60),
|
Validators.min(60),
|
||||||
Validators.max(320),
|
Validators.max(320),
|
||||||
]),
|
]),
|
||||||
},
|
},
|
||||||
{ updateOn: "blur" },
|
{ updateOn: "blur" },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.updateTitle();
|
onSubmit(formData) {
|
||||||
}
|
this.serviceApi
|
||||||
|
.addGear(
|
||||||
|
formData.name,
|
||||||
|
formData.manufacturer,
|
||||||
|
+formData.minSize,
|
||||||
|
+formData.maxSize,
|
||||||
|
formData.aad,
|
||||||
|
formData.mainCanopy,
|
||||||
|
formData.reserveCanopy,
|
||||||
|
)
|
||||||
|
.subscribe(() => {
|
||||||
|
this.serviceComm.refreshData(AddAction.Gear);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
onSubmit(formData) {
|
private updateTitle() {
|
||||||
this.serviceApi
|
this.translateService.get("NewGear_Title").subscribe((data) => {
|
||||||
.addGear(
|
this.serviceComm.updatedComponentTitle(data);
|
||||||
formData.name,
|
});
|
||||||
formData.manufacturer,
|
}
|
||||||
+formData.minSize,
|
|
||||||
+formData.maxSize,
|
|
||||||
formData.aad,
|
|
||||||
formData.mainCanopy,
|
|
||||||
formData.reserveCanopy,
|
|
||||||
)
|
|
||||||
.subscribe(() => {
|
|
||||||
this.serviceComm.refreshData(AddAction.Gear);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private updateTitle() {
|
|
||||||
this.translateService.get("NewGear_Title").subscribe((data) => {
|
|
||||||
this.serviceComm.updatedComponentTitle(data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
.content {
|
.content {
|
||||||
height: 90vh;
|
height: 90vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: left;
|
justify-content: left;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: initial;
|
align-items: initial;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<form [formGroup]="addForm" (ngSubmit)="onSubmit(addForm.value)">
|
<form [formGroup]="addForm" (ngSubmit)="onSubmit(addForm.value)">
|
||||||
<p>
|
<p>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>Jump type name</mat-label>
|
<mat-label>Jump type name</mat-label>
|
||||||
<input matInput type="text" formControlName="jumptypeName">
|
<input matInput type="text" formControlName="jumptypeName" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<button type="submit" mat-raised-button color="accent">Add</button>
|
<button type="submit" mat-raised-button color="accent">Add</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { Component, OnInit } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
import {
|
import {
|
||||||
FormControl,
|
FormControl,
|
||||||
FormGroup,
|
FormGroup,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
Validators,
|
Validators,
|
||||||
} from "@angular/forms";
|
} from "@angular/forms";
|
||||||
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
||||||
import { MatFormFieldModule } from "@angular/material/form-field";
|
import { MatFormFieldModule } from "@angular/material/form-field";
|
||||||
@@ -15,52 +15,54 @@ import { ServiceComm } from "../../services/service-comm.service";
|
|||||||
import { JumpTypeService } from "../../services/jump-type.service";
|
import { JumpTypeService } from "../../services/jump-type.service";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-new-jump-type",
|
selector: "app-new-jump-type",
|
||||||
templateUrl: "./new-jump-type.component.html",
|
templateUrl: "./new-jump-type.component.html",
|
||||||
styleUrls: ["./new-jump-type.component.css"],
|
styleUrls: ["./new-jump-type.component.css"],
|
||||||
imports: [
|
imports: [
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
MatFormFieldModule,
|
MatFormFieldModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
MatInputModule,
|
MatInputModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class NewJumpTypeComponent implements OnInit {
|
export class NewJumpTypeComponent implements OnInit {
|
||||||
public addForm: FormGroup;
|
public addForm: FormGroup;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private serviceComm: ServiceComm,
|
private serviceComm: ServiceComm,
|
||||||
private jumpTypeService: JumpTypeService,
|
private jumpTypeService: JumpTypeService,
|
||||||
private translateService: TranslateService,
|
private translateService: TranslateService,
|
||||||
) {
|
) {
|
||||||
this.addForm = new FormGroup(
|
this.addForm = new FormGroup(
|
||||||
{
|
{
|
||||||
jumptypeName: new FormControl("", Validators.required),
|
jumptypeName: new FormControl("", Validators.required),
|
||||||
},
|
},
|
||||||
{ updateOn: "blur" },
|
{ updateOn: "blur" },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.updateTitle();
|
onSubmit(formData) {
|
||||||
}
|
this.jumpTypeService
|
||||||
|
.addJumpType(formData.jumptypeName)
|
||||||
|
.subscribe(() => {
|
||||||
|
this.serviceComm.refreshData(AddAction.JumpType);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
onSubmit(formData) {
|
private updateTitle() {
|
||||||
this.jumpTypeService.addJumpType(formData.jumptypeName).subscribe(() => {
|
this.translateService.get("NewJumpType_Title").subscribe((data) => {
|
||||||
this.serviceComm.refreshData(AddAction.JumpType);
|
this.serviceComm.updatedComponentTitle(data);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateTitle() {
|
|
||||||
this.translateService.get("NewJumpType_Title").subscribe((data) => {
|
|
||||||
this.serviceComm.updatedComponentTitle(data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
.formNewJumps {
|
.formNewJumps {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
min-width: 150px;
|
min-width: 150px;
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
min-height: 90vh;
|
min-height: 90vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: left;
|
justify-content: left;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: initial;
|
align-items: initial;
|
||||||
padding-top: 25px;
|
padding-top: 25px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,270 +1,276 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
mat-raised-button
|
mat-raised-button
|
||||||
color="accent"
|
color="accent"
|
||||||
[routerLink]="['/jumps']"
|
[routerLink]="['/jumps']"
|
||||||
[routerLinkActive]="['active']"
|
[routerLinkActive]="['active']"
|
||||||
skipLocationChange
|
skipLocationChange
|
||||||
>
|
|
||||||
{{ "NewJump_GoToJump" | translate }}
|
|
||||||
</button>
|
|
||||||
<p>
|
|
||||||
<mat-checkbox [(ngModel)]="resetForm" labelPosition="before">{{
|
|
||||||
"NewJump_ResetForm" | translate
|
|
||||||
}}</mat-checkbox>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form
|
|
||||||
class="formNewJumps"
|
|
||||||
(ngSubmit)="onFormSubmit()"
|
|
||||||
*ngIf="notLoadingToDisplay(); else loading"
|
|
||||||
>
|
|
||||||
<mat-form-field>
|
|
||||||
<mat-label>{{ "NewJump_ChooseJumpType" | translate }}</mat-label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
matInput
|
|
||||||
[matAutocomplete]="autoJumpType"
|
|
||||||
[(ngModel)]="selectedJumpType"
|
|
||||||
name="selectedJumpType"
|
|
||||||
/>
|
|
||||||
<mat-autocomplete
|
|
||||||
#autoJumpType="matAutocomplete"
|
|
||||||
[displayWith]="displayNameFn"
|
|
||||||
>
|
|
||||||
<mat-option *ngFor="let jumpType of listOfJumpType" [value]="jumpType">
|
|
||||||
{{ jumpType.name }}
|
|
||||||
</mat-option>
|
|
||||||
</mat-autocomplete>
|
|
||||||
<button
|
|
||||||
*ngIf="selectedJumpType"
|
|
||||||
matSuffix
|
|
||||||
mat-icon-button
|
|
||||||
aria-label="Clear"
|
|
||||||
(click)="selectedJumpType = undefined"
|
|
||||||
>
|
|
||||||
<mat-icon>close</mat-icon>
|
|
||||||
</button>
|
|
||||||
</mat-form-field>
|
|
||||||
|
|
||||||
<mat-form-field>
|
|
||||||
<mat-label>{{ "NewJump_ChooseAircraft" | translate }}</mat-label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
matInput
|
|
||||||
[matAutocomplete]="autoAircraft"
|
|
||||||
[(ngModel)]="selectedAircraft"
|
|
||||||
name="selectedAircraft"
|
|
||||||
/>
|
|
||||||
<mat-autocomplete
|
|
||||||
#autoAircraft="matAutocomplete"
|
|
||||||
[displayWith]="displayNameFn"
|
|
||||||
>
|
|
||||||
<mat-option *ngFor="let aircraft of listOfAircraft" [value]="aircraft">
|
|
||||||
{{ aircraft.name }}
|
|
||||||
</mat-option>
|
|
||||||
</mat-autocomplete>
|
|
||||||
<button
|
|
||||||
*ngIf="selectedAircraft"
|
|
||||||
matSuffix
|
|
||||||
mat-icon-button
|
|
||||||
aria-label="Clear"
|
|
||||||
(click)="selectedAircraft = undefined"
|
|
||||||
>
|
|
||||||
<mat-icon>close</mat-icon>
|
|
||||||
</button>
|
|
||||||
</mat-form-field>
|
|
||||||
|
|
||||||
<mat-form-field>
|
|
||||||
<mat-label>{{ "NewJump_ChooseDz" | translate }}</mat-label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
matInput
|
|
||||||
[matAutocomplete]="autoDropZone"
|
|
||||||
[(ngModel)]="selectedDz"
|
|
||||||
(ngModelChange)="onChangeDz($event)"
|
|
||||||
name="selectedDz"
|
|
||||||
/>
|
|
||||||
<mat-autocomplete
|
|
||||||
#autoDropZone="matAutocomplete"
|
|
||||||
[displayWith]="displayNameFn"
|
|
||||||
>
|
|
||||||
<mat-option
|
|
||||||
*ngFor="let dropZone of listOfFilteredDropZone"
|
|
||||||
[value]="dropZone"
|
|
||||||
>
|
>
|
||||||
{{ dropZone.name }}
|
{{ "NewJump_GoToJump" | translate }}
|
||||||
<mat-icon
|
</button>
|
||||||
aria-hidden="false"
|
<p>
|
||||||
aria-label="Favorite"
|
<mat-checkbox [(ngModel)]="resetForm" labelPosition="before">{{
|
||||||
*ngIf="dropZone.isFavorite === true"
|
"NewJump_ResetForm" | translate
|
||||||
color="primary"
|
}}</mat-checkbox>
|
||||||
>
|
</p>
|
||||||
favorite</mat-icon
|
</div>
|
||||||
>
|
|
||||||
</mat-option>
|
|
||||||
</mat-autocomplete>
|
|
||||||
<button
|
|
||||||
*ngIf="selectedDz"
|
|
||||||
matSuffix
|
|
||||||
mat-icon-button
|
|
||||||
aria-label="Clear"
|
|
||||||
(click)="resetDz()"
|
|
||||||
>
|
|
||||||
<mat-icon>close</mat-icon>
|
|
||||||
</button>
|
|
||||||
</mat-form-field>
|
|
||||||
|
|
||||||
<mat-form-field>
|
@if (notLoadingToDisplay()) {
|
||||||
<mat-label>{{ "NewJump_ChooseGear" | translate }}</mat-label>
|
<form class="formNewJumps" (ngSubmit)="onFormSubmit()">
|
||||||
<input
|
<mat-form-field>
|
||||||
type="text"
|
<mat-label>{{
|
||||||
matInput
|
"NewJump_ChooseJumpType" | translate
|
||||||
[matAutocomplete]="autoGear"
|
}}</mat-label>
|
||||||
[(ngModel)]="selectedGear"
|
<input
|
||||||
name="selectedGear"
|
type="text"
|
||||||
/>
|
matInput
|
||||||
<mat-autocomplete
|
[matAutocomplete]="autoJumpType"
|
||||||
#autoGear="matAutocomplete"
|
[(ngModel)]="selectedJumpType"
|
||||||
[displayWith]="displayGearFn"
|
name="selectedJumpType"
|
||||||
>
|
/>
|
||||||
<mat-option *ngFor="let gear of listOfGear" [value]="gear">
|
<mat-autocomplete
|
||||||
{{ gear.name }} ({{ gear.mainCanopy }})
|
#autoJumpType="matAutocomplete"
|
||||||
</mat-option>
|
[displayWith]="displayNameFn"
|
||||||
</mat-autocomplete>
|
>
|
||||||
<button
|
@for (jumpType of listOfJumpType; track jumpType) {
|
||||||
*ngIf="selectedGear"
|
<mat-option [value]="jumpType">
|
||||||
matSuffix
|
{{ jumpType.name }}
|
||||||
mat-icon-button
|
</mat-option>
|
||||||
aria-label="Clear"
|
}
|
||||||
(click)="selectedGear = undefined"
|
</mat-autocomplete>
|
||||||
>
|
@if (selectedJumpType) {
|
||||||
<mat-icon>close</mat-icon>
|
<button
|
||||||
</button>
|
matSuffix
|
||||||
</mat-form-field>
|
mat-icon-button
|
||||||
|
aria-label="Clear"
|
||||||
<mat-checkbox [(ngModel)]="withCutaway" name="withCutaway">{{
|
(click)="selectedJumpType = undefined"
|
||||||
"NewJump_Cutaway" | translate
|
>
|
||||||
}}</mat-checkbox>
|
<mat-icon svgIcon="close"></mat-icon>
|
||||||
<mat-checkbox [(ngModel)]="isSpecial" name="isSpecial">{{
|
</button>
|
||||||
"NewJump_Special" | translate
|
}
|
||||||
}}</mat-checkbox>
|
</mat-form-field>
|
||||||
|
<mat-form-field>
|
||||||
<mat-form-field>
|
<mat-label>{{
|
||||||
<input
|
"NewJump_ChooseAircraft" | translate
|
||||||
matInput
|
}}</mat-label>
|
||||||
[matDatepicker]="beginDateDp"
|
<input
|
||||||
[(ngModel)]="beginDate"
|
type="text"
|
||||||
name="beginDate"
|
matInput
|
||||||
disabled
|
[matAutocomplete]="autoAircraft"
|
||||||
(ngModelChange)="onChangeBeginDate($event)"
|
[(ngModel)]="selectedAircraft"
|
||||||
/>
|
name="selectedAircraft"
|
||||||
<mat-datepicker-toggle
|
/>
|
||||||
matSuffix
|
<mat-autocomplete
|
||||||
[for]="beginDateDp"
|
#autoAircraft="matAutocomplete"
|
||||||
></mat-datepicker-toggle>
|
[displayWith]="displayNameFn"
|
||||||
<mat-datepicker #beginDateDp disabled="false"></mat-datepicker>
|
>
|
||||||
</mat-form-field>
|
@for (aircraft of listOfAircraft; track aircraft) {
|
||||||
|
<mat-option [value]="aircraft">
|
||||||
<mat-form-field>
|
{{ aircraft.name }}
|
||||||
<input
|
</mat-option>
|
||||||
matInput
|
}
|
||||||
[matDatepicker]="endDateDp"
|
</mat-autocomplete>
|
||||||
[(ngModel)]="endDate"
|
@if (selectedAircraft) {
|
||||||
name="endDate"
|
<button
|
||||||
disabled
|
matSuffix
|
||||||
/>
|
mat-icon-button
|
||||||
<mat-datepicker-toggle
|
aria-label="Clear"
|
||||||
matSuffix
|
(click)="selectedAircraft = undefined"
|
||||||
[for]="endDateDp"
|
>
|
||||||
></mat-datepicker-toggle>
|
<mat-icon svgIcon="close"></mat-icon>
|
||||||
<mat-datepicker #endDateDp disabled="false"></mat-datepicker>
|
</button>
|
||||||
</mat-form-field>
|
}
|
||||||
|
</mat-form-field>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<input
|
<mat-label>{{ "NewJump_ChooseDz" | translate }}</mat-label>
|
||||||
matInput
|
<input
|
||||||
placeholder="{{ 'NewJump_ExitAlt' | translate }}"
|
type="text"
|
||||||
[(ngModel)]="exitAltitude"
|
matInput
|
||||||
name="exitAltitude"
|
[matAutocomplete]="autoDropZone"
|
||||||
type="number"
|
[(ngModel)]="selectedDz"
|
||||||
/>
|
(ngModelChange)="onChangeDz($event)"
|
||||||
<button
|
name="selectedDz"
|
||||||
*ngIf="exitAltitude"
|
/>
|
||||||
matSuffix
|
<mat-autocomplete
|
||||||
mat-icon-button
|
#autoDropZone="matAutocomplete"
|
||||||
aria-label="Clear"
|
[displayWith]="displayNameFn"
|
||||||
(click)="exitAltitude = undefined"
|
>
|
||||||
>
|
@for (dropZone of listOfFilteredDropZone; track dropZone) {
|
||||||
<mat-icon>close</mat-icon>
|
<mat-option [value]="dropZone">
|
||||||
</button>
|
{{ dropZone.name }}
|
||||||
</mat-form-field>
|
@if (dropZone.isFavorite === true) {
|
||||||
<mat-form-field>
|
<mat-icon
|
||||||
<input
|
aria-hidden="false"
|
||||||
matInput
|
aria-label="Favorite"
|
||||||
placeholder="{{ 'NewJump_DeployAlt' | translate }}"
|
color="primary"
|
||||||
[(ngModel)]="deployAltitude"
|
svgIcon="favorite"
|
||||||
name="deployAltitude"
|
>
|
||||||
type="number"
|
</mat-icon>
|
||||||
/>
|
}
|
||||||
<button
|
</mat-option>
|
||||||
*ngIf="deployAltitude"
|
}
|
||||||
matSuffix
|
</mat-autocomplete>
|
||||||
mat-icon-button
|
@if (selectedDz) {
|
||||||
aria-label="Clear"
|
<button
|
||||||
(click)="deployAltitude = undefined"
|
matSuffix
|
||||||
>
|
mat-icon-button
|
||||||
<mat-icon>close</mat-icon>
|
aria-label="Clear"
|
||||||
</button>
|
(click)="resetDz()"
|
||||||
</mat-form-field>
|
>
|
||||||
|
<mat-icon svgIcon="close"></mat-icon>
|
||||||
<mat-form-field>
|
</button>
|
||||||
<input
|
}
|
||||||
matInput
|
</mat-form-field>
|
||||||
placeholder="{{ 'NewJump_Count' | translate }}"
|
<mat-form-field>
|
||||||
[(ngModel)]="countOfJumps"
|
<mat-label>{{ "NewJump_ChooseGear" | translate }}</mat-label>
|
||||||
name="countOfJumps"
|
<input
|
||||||
type="number"
|
type="text"
|
||||||
/>
|
matInput
|
||||||
<button
|
[matAutocomplete]="autoGear"
|
||||||
*ngIf="countOfJumps"
|
[(ngModel)]="selectedGear"
|
||||||
matSuffix
|
name="selectedGear"
|
||||||
mat-icon-button
|
/>
|
||||||
aria-label="Clear"
|
<mat-autocomplete
|
||||||
(click)="countOfJumps = undefined"
|
#autoGear="matAutocomplete"
|
||||||
>
|
[displayWith]="displayGearFn"
|
||||||
<mat-icon>close</mat-icon>
|
>
|
||||||
</button>
|
@for (gear of listOfGear; track gear) {
|
||||||
</mat-form-field>
|
<mat-option [value]="gear">
|
||||||
|
{{ gear.name }} ({{ gear.mainCanopy }})
|
||||||
<mat-form-field>
|
</mat-option>
|
||||||
<textarea
|
}
|
||||||
matInput
|
</mat-autocomplete>
|
||||||
placeholder="{{ 'NewJump_Comments' | translate }}"
|
@if (selectedGear) {
|
||||||
[(ngModel)]="comments"
|
<button
|
||||||
name="comments"
|
matSuffix
|
||||||
type="text"
|
mat-icon-button
|
||||||
></textarea>
|
aria-label="Clear"
|
||||||
<button
|
(click)="selectedGear = undefined"
|
||||||
*ngIf="comments"
|
>
|
||||||
matSuffix
|
<mat-icon svgIcon="close"></mat-icon>
|
||||||
mat-icon-button
|
</button>
|
||||||
aria-label="Clear"
|
}
|
||||||
(click)="comments = undefined"
|
</mat-form-field>
|
||||||
>
|
<mat-checkbox [(ngModel)]="withCutaway" name="withCutaway">{{
|
||||||
<mat-icon>close</mat-icon>
|
"NewJump_Cutaway" | translate
|
||||||
</button>
|
}}</mat-checkbox>
|
||||||
</mat-form-field>
|
<mat-checkbox [(ngModel)]="isSpecial" name="isSpecial">{{
|
||||||
|
"NewJump_Special" | translate
|
||||||
<br />
|
}}</mat-checkbox>
|
||||||
<button mat-raised-button color="accent" *ngIf="isValidatedForm()">
|
<mat-form-field>
|
||||||
{{ "NewJump_Submit" | translate }}
|
<input
|
||||||
</button>
|
matInput
|
||||||
</form>
|
[matDatepicker]="beginDateDp"
|
||||||
|
[(ngModel)]="beginDate"
|
||||||
<ng-template #loading>
|
name="beginDate"
|
||||||
<mat-progress-spinner [mode]="'indeterminate'"></mat-progress-spinner>
|
disabled
|
||||||
</ng-template>
|
(ngModelChange)="onChangeBeginDate($event)"
|
||||||
|
/>
|
||||||
|
<mat-datepicker-toggle
|
||||||
|
matSuffix
|
||||||
|
[for]="beginDateDp"
|
||||||
|
></mat-datepicker-toggle>
|
||||||
|
<mat-datepicker #beginDateDp disabled="false"></mat-datepicker>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field>
|
||||||
|
<input
|
||||||
|
matInput
|
||||||
|
[matDatepicker]="endDateDp"
|
||||||
|
[(ngModel)]="endDate"
|
||||||
|
name="endDate"
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
<mat-datepicker-toggle
|
||||||
|
matSuffix
|
||||||
|
[for]="endDateDp"
|
||||||
|
></mat-datepicker-toggle>
|
||||||
|
<mat-datepicker #endDateDp disabled="false"></mat-datepicker>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field>
|
||||||
|
<input
|
||||||
|
matInput
|
||||||
|
placeholder="{{ 'NewJump_ExitAlt' | translate }}"
|
||||||
|
[(ngModel)]="exitAltitude"
|
||||||
|
name="exitAltitude"
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
|
@if (exitAltitude) {
|
||||||
|
<button
|
||||||
|
matSuffix
|
||||||
|
mat-icon-button
|
||||||
|
aria-label="Clear"
|
||||||
|
(click)="exitAltitude = undefined"
|
||||||
|
>
|
||||||
|
<mat-icon svgIcon="close"></mat-icon>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field>
|
||||||
|
<input
|
||||||
|
matInput
|
||||||
|
placeholder="{{ 'NewJump_DeployAlt' | translate }}"
|
||||||
|
[(ngModel)]="deployAltitude"
|
||||||
|
name="deployAltitude"
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
|
@if (deployAltitude) {
|
||||||
|
<button
|
||||||
|
matSuffix
|
||||||
|
mat-icon-button
|
||||||
|
aria-label="Clear"
|
||||||
|
(click)="deployAltitude = undefined"
|
||||||
|
>
|
||||||
|
<mat-icon svgIcon="close"></mat-icon>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field>
|
||||||
|
<input
|
||||||
|
matInput
|
||||||
|
placeholder="{{ 'NewJump_Count' | translate }}"
|
||||||
|
[(ngModel)]="countOfJumps"
|
||||||
|
name="countOfJumps"
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
|
@if (countOfJumps) {
|
||||||
|
<button
|
||||||
|
matSuffix
|
||||||
|
mat-icon-button
|
||||||
|
aria-label="Clear"
|
||||||
|
(click)="countOfJumps = undefined"
|
||||||
|
>
|
||||||
|
<mat-icon svgIcon="close"></mat-icon>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field>
|
||||||
|
<textarea
|
||||||
|
matInput
|
||||||
|
placeholder="{{ 'NewJump_Comments' | translate }}"
|
||||||
|
[(ngModel)]="comments"
|
||||||
|
name="comments"
|
||||||
|
type="text"
|
||||||
|
></textarea>
|
||||||
|
@if (comments) {
|
||||||
|
<button
|
||||||
|
matSuffix
|
||||||
|
mat-icon-button
|
||||||
|
aria-label="Clear"
|
||||||
|
(click)="comments = undefined"
|
||||||
|
>
|
||||||
|
<mat-icon svgIcon="close"></mat-icon>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
</mat-form-field>
|
||||||
|
<br />
|
||||||
|
@if (this.isValidatedForm()) {
|
||||||
|
<button mat-raised-button color="accent">
|
||||||
|
{{ "NewJump_Submit" | translate }}
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
</form>
|
||||||
|
} @else {
|
||||||
|
<mat-progress-spinner [mode]="'indeterminate'"></mat-progress-spinner>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ import { Component, OnInit } from "@angular/core";
|
|||||||
import { RouterLink, RouterModule } from "@angular/router";
|
import { RouterLink, RouterModule } from "@angular/router";
|
||||||
import { formatDate } from "@angular/common";
|
import { formatDate } from "@angular/common";
|
||||||
import {
|
import {
|
||||||
DateAdapter,
|
DateAdapter,
|
||||||
MAT_DATE_FORMATS,
|
MAT_DATE_FORMATS,
|
||||||
NativeDateAdapter,
|
NativeDateAdapter,
|
||||||
} from "@angular/material/core";
|
} from "@angular/material/core";
|
||||||
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
||||||
import { CommonModule } from "@angular/common";
|
|
||||||
import { MatIconModule } from "@angular/material/icon";
|
import { MatIconModule } from "@angular/material/icon";
|
||||||
import { MatOptionModule } from "@angular/material/core";
|
import { MatOptionModule } from "@angular/material/core";
|
||||||
import { MatFormFieldModule } from "@angular/material/form-field";
|
import { MatFormFieldModule } from "@angular/material/form-field";
|
||||||
@@ -34,245 +34,246 @@ import { GearService } from "../../services/gear.service";
|
|||||||
import { StatsService } from "../../services/stats.service";
|
import { StatsService } from "../../services/stats.service";
|
||||||
|
|
||||||
export const PICK_FORMATS = {
|
export const PICK_FORMATS = {
|
||||||
parse: { dateInput: "yy MM dd" },
|
parse: { dateInput: "yy MM dd" },
|
||||||
display: {
|
display: {
|
||||||
dateInput: "yyyy-MM-dd",
|
dateInput: "yyyy-MM-dd",
|
||||||
monthYearLabel: "yyyy MMM",
|
monthYearLabel: "yyyy MMM",
|
||||||
dateA11yLabel: "yyyy MM dd",
|
dateA11yLabel: "yyyy MM dd",
|
||||||
monthYearA11yLabel: "yyyy MMMM",
|
monthYearA11yLabel: "yyyy MMMM",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
class PickDateAdapter extends NativeDateAdapter {
|
class PickDateAdapter extends NativeDateAdapter {
|
||||||
override format(date: Date, displayFormat: Object): string {
|
override format(date: Date, displayFormat: Object): string {
|
||||||
return formatDate(date, displayFormat.toString(), "en");
|
return formatDate(date, displayFormat.toString(), "en");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-new-jump",
|
selector: "app-new-jump",
|
||||||
templateUrl: "./new-jump.component.html",
|
templateUrl: "./new-jump.component.html",
|
||||||
styleUrls: ["./new-jump.component.css"],
|
styleUrls: ["./new-jump.component.css"],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: DateAdapter, useClass: PickDateAdapter },
|
{ provide: DateAdapter, useClass: PickDateAdapter },
|
||||||
{ provide: MAT_DATE_FORMATS, useValue: PICK_FORMATS },
|
{ provide: MAT_DATE_FORMATS, useValue: PICK_FORMATS },
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
CommonModule,
|
RouterLink,
|
||||||
RouterLink,
|
FormsModule,
|
||||||
FormsModule,
|
RouterModule,
|
||||||
RouterModule,
|
MatIconModule,
|
||||||
MatIconModule,
|
MatOptionModule,
|
||||||
MatOptionModule,
|
MatFormFieldModule,
|
||||||
MatFormFieldModule,
|
MatCheckboxModule,
|
||||||
MatCheckboxModule,
|
MatAutocompleteModule,
|
||||||
MatAutocompleteModule,
|
MatDatepickerModule,
|
||||||
MatDatepickerModule,
|
MatProgressSpinnerModule,
|
||||||
MatProgressSpinnerModule,
|
MatFormFieldModule,
|
||||||
MatFormFieldModule,
|
ReactiveFormsModule,
|
||||||
ReactiveFormsModule,
|
MatInputModule,
|
||||||
MatInputModule,
|
MatButtonModule,
|
||||||
MatButtonModule,
|
],
|
||||||
],
|
|
||||||
})
|
})
|
||||||
export class NewJumpComponent implements OnInit {
|
export class NewJumpComponent implements OnInit {
|
||||||
public beginDate: Date;
|
public beginDate: Date;
|
||||||
public endDate: Date;
|
public endDate: Date;
|
||||||
public exitAltitude: number;
|
public exitAltitude: number;
|
||||||
public deployAltitude: number;
|
public deployAltitude: number;
|
||||||
public countOfJumps: number;
|
public countOfJumps: number;
|
||||||
public selectedDz: DropZoneResp;
|
public selectedDz: DropZoneResp;
|
||||||
public selectedGear: GearResp;
|
public selectedGear: GearResp;
|
||||||
public selectedAircraft: AircraftResp;
|
public selectedAircraft: AircraftResp;
|
||||||
public selectedJumpType: JumpTypeResp;
|
public selectedJumpType: JumpTypeResp;
|
||||||
public withCutaway: boolean;
|
public withCutaway: boolean;
|
||||||
public isSpecial: boolean;
|
public isSpecial: boolean;
|
||||||
public listOfJumpType: Array<JumpTypeResp>;
|
public listOfJumpType: Array<JumpTypeResp>;
|
||||||
public listOfAircraft: Array<AircraftResp>;
|
public listOfAircraft: Array<AircraftResp>;
|
||||||
public listOfFilteredDropZone: Array<DropZoneResp>;
|
public listOfFilteredDropZone: Array<DropZoneResp>;
|
||||||
public listOfGear: Array<GearResp>;
|
public listOfGear: Array<GearResp>;
|
||||||
public comments: string;
|
public comments: string;
|
||||||
public resetForm: boolean;
|
public resetForm: boolean;
|
||||||
private countDatasLoaded: number;
|
private countDatasLoaded: number;
|
||||||
private pendingAddRequest: boolean;
|
private pendingAddRequest: boolean;
|
||||||
private listOfDropZone: Array<DropZoneResp>;
|
private listOfDropZone: Array<DropZoneResp>;
|
||||||
public maxDate: Date;
|
public maxDate: Date;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private serviceComm: ServiceComm,
|
private serviceComm: ServiceComm,
|
||||||
private serviceJump: JumpService,
|
private serviceJump: JumpService,
|
||||||
private serviceJumpType: JumpTypeService,
|
private serviceJumpType: JumpTypeService,
|
||||||
private serviceAircraft: AircraftService,
|
private serviceAircraft: AircraftService,
|
||||||
private serviceDropzone: DropzoneService,
|
private serviceDropzone: DropzoneService,
|
||||||
private serviceGear: GearService,
|
private serviceGear: GearService,
|
||||||
private dateService: DateService,
|
private dateService: DateService,
|
||||||
private translateService: TranslateService,
|
private translateService: TranslateService,
|
||||||
private statsService: StatsService
|
private statsService: StatsService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
||||||
if (data === true) {
|
if (data === true) {
|
||||||
|
this.updateTitle();
|
||||||
|
}
|
||||||
|
});
|
||||||
this.updateTitle();
|
this.updateTitle();
|
||||||
}
|
|
||||||
});
|
|
||||||
this.updateTitle();
|
|
||||||
|
|
||||||
this.maxDate = this.dateService.addDays(new Date(), 1);
|
this.maxDate = this.dateService.addDays(new Date(), 1);
|
||||||
|
|
||||||
this.pendingAddRequest = false;
|
this.pendingAddRequest = false;
|
||||||
this.initForm();
|
this.initForm();
|
||||||
this.getListOfJumpTypes();
|
this.getListOfJumpTypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
onFormSubmit() {
|
onFormSubmit() {
|
||||||
this.pendingAddRequest = true;
|
if (this.isValidatedForm()) {
|
||||||
|
this.pendingAddRequest = true;
|
||||||
|
|
||||||
this.serviceJump
|
this.serviceJump
|
||||||
.addListOfJump(
|
.addListOfJump(
|
||||||
this.selectedJumpType.id,
|
this.selectedJumpType.id,
|
||||||
this.selectedAircraft.id,
|
this.selectedAircraft.id,
|
||||||
this.selectedDz.id,
|
this.selectedDz.id,
|
||||||
this.selectedGear.id,
|
this.selectedGear.id,
|
||||||
this.withCutaway === undefined ? false : this.withCutaway,
|
this.withCutaway === undefined ? false : this.withCutaway,
|
||||||
this.beginDate,
|
this.beginDate,
|
||||||
this.endDate,
|
this.endDate,
|
||||||
this.exitAltitude,
|
this.exitAltitude,
|
||||||
this.deployAltitude,
|
this.deployAltitude,
|
||||||
this.countOfJumps,
|
this.countOfJumps,
|
||||||
this.comments,
|
this.comments,
|
||||||
this.isSpecial === undefined ? false : this.isSpecial
|
this.isSpecial === undefined ? false : this.isSpecial,
|
||||||
)
|
)
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
this.statsService.resetStats();
|
this.statsService.resetStats();
|
||||||
|
this.comments = undefined;
|
||||||
|
this.withCutaway = false;
|
||||||
|
this.isSpecial = false;
|
||||||
|
|
||||||
|
if (this.resetForm === true) {
|
||||||
|
this.initForm();
|
||||||
|
}
|
||||||
|
this.pendingAddRequest = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public isValidatedForm(): boolean {
|
||||||
|
return (
|
||||||
|
this.selectedDz !== undefined &&
|
||||||
|
this.selectedDz.id !== undefined &&
|
||||||
|
this.selectedGear !== undefined &&
|
||||||
|
this.selectedGear.id !== undefined &&
|
||||||
|
this.selectedAircraft !== undefined &&
|
||||||
|
this.selectedAircraft.id !== undefined &&
|
||||||
|
this.selectedJumpType !== undefined &&
|
||||||
|
this.selectedJumpType.id !== undefined &&
|
||||||
|
this.exitAltitude !== undefined &&
|
||||||
|
typeof this.exitAltitude === "number" &&
|
||||||
|
this.deployAltitude !== undefined &&
|
||||||
|
typeof this.deployAltitude === "number" &&
|
||||||
|
this.countOfJumps !== undefined &&
|
||||||
|
typeof this.countOfJumps === "number"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getListOfJumpTypes() {
|
||||||
|
this.serviceJumpType.getListOfJumpTypes().subscribe((data) => {
|
||||||
|
data.sort((a, b) => a.name.localeCompare(b.name));
|
||||||
|
this.listOfJumpType = data;
|
||||||
|
this.countDatasLoaded = 1;
|
||||||
|
|
||||||
|
this.getListOfAircrafts();
|
||||||
|
this.getListOfDropZones();
|
||||||
|
this.getListOfGears();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private getListOfAircrafts() {
|
||||||
|
this.serviceAircraft.getListOfAircrafts(true).subscribe((data) => {
|
||||||
|
data.sort((a, b) => a.name.localeCompare(b.name));
|
||||||
|
this.listOfAircraft = data;
|
||||||
|
this.countDatasLoaded++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private getListOfDropZones() {
|
||||||
|
this.serviceDropzone.getListOfDropZones(true).subscribe((data) => {
|
||||||
|
data.sort(
|
||||||
|
(a, b) =>
|
||||||
|
(b.isFavorite ? 1 : 0) - (a.isFavorite ? 1 : 0) ||
|
||||||
|
a.name.localeCompare(b.name),
|
||||||
|
);
|
||||||
|
this.listOfDropZone = data;
|
||||||
|
this.listOfFilteredDropZone = data;
|
||||||
|
this.countDatasLoaded++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private getListOfGears() {
|
||||||
|
this.serviceGear.getListOfGears().subscribe((data) => {
|
||||||
|
data.sort((a, b) => b.id - a.id);
|
||||||
|
this.listOfGear = data;
|
||||||
|
this.countDatasLoaded++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private initForm() {
|
||||||
|
this.endDate = new Date();
|
||||||
|
this.endDate.setHours(0, 0, 0, 0);
|
||||||
|
this.beginDate = this.dateService.addDays(this.endDate, -1);
|
||||||
|
|
||||||
|
this.exitAltitude = 4000;
|
||||||
|
this.deployAltitude = 1000;
|
||||||
|
this.countOfJumps = 1;
|
||||||
|
|
||||||
|
this.selectedDz = undefined;
|
||||||
|
this.selectedGear = undefined;
|
||||||
|
this.selectedAircraft = undefined;
|
||||||
|
this.selectedJumpType = undefined;
|
||||||
|
|
||||||
|
this.listOfFilteredDropZone = this.listOfDropZone;
|
||||||
this.comments = undefined;
|
this.comments = undefined;
|
||||||
|
|
||||||
this.withCutaway = false;
|
this.withCutaway = false;
|
||||||
this.isSpecial = false;
|
this.isSpecial = false;
|
||||||
|
|
||||||
if (this.resetForm === true) {
|
|
||||||
this.initForm();
|
|
||||||
}
|
|
||||||
this.pendingAddRequest = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public isValidatedForm(): boolean {
|
|
||||||
return (
|
|
||||||
this.selectedDz !== undefined &&
|
|
||||||
this.selectedDz.id !== undefined &&
|
|
||||||
this.selectedGear !== undefined &&
|
|
||||||
this.selectedGear.id !== undefined &&
|
|
||||||
this.selectedAircraft !== undefined &&
|
|
||||||
this.selectedAircraft.id !== undefined &&
|
|
||||||
this.selectedJumpType !== undefined &&
|
|
||||||
this.selectedJumpType.id !== undefined &&
|
|
||||||
this.exitAltitude !== undefined &&
|
|
||||||
typeof this.exitAltitude === "number" &&
|
|
||||||
this.deployAltitude !== undefined &&
|
|
||||||
typeof this.deployAltitude === "number" &&
|
|
||||||
this.countOfJumps !== undefined &&
|
|
||||||
typeof this.countOfJumps === "number"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private getListOfJumpTypes() {
|
|
||||||
this.serviceJumpType.getListOfJumpTypes().subscribe((data) => {
|
|
||||||
data.sort((a, b) => a.name.localeCompare(b.name));
|
|
||||||
this.listOfJumpType = data;
|
|
||||||
this.countDatasLoaded = 1;
|
|
||||||
|
|
||||||
this.getListOfAircrafts();
|
|
||||||
this.getListOfDropZones();
|
|
||||||
this.getListOfGears();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private getListOfAircrafts() {
|
|
||||||
this.serviceAircraft.getListOfAircrafts(true).subscribe((data) => {
|
|
||||||
data.sort((a, b) => a.name.localeCompare(b.name));
|
|
||||||
this.listOfAircraft = data;
|
|
||||||
this.countDatasLoaded++;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private getListOfDropZones() {
|
|
||||||
this.serviceDropzone.getListOfDropZones(true).subscribe((data) => {
|
|
||||||
data.sort(
|
|
||||||
(a, b) =>
|
|
||||||
(b.isFavorite ? 1 : 0) - (a.isFavorite ? 1 : 0) ||
|
|
||||||
a.name.localeCompare(b.name)
|
|
||||||
);
|
|
||||||
this.listOfDropZone = data;
|
|
||||||
this.listOfFilteredDropZone = data;
|
|
||||||
this.countDatasLoaded++;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private getListOfGears() {
|
|
||||||
this.serviceGear.getListOfGears().subscribe((data) => {
|
|
||||||
data.sort((a, b) => b.id - a.id);
|
|
||||||
this.listOfGear = data;
|
|
||||||
this.countDatasLoaded++;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private initForm() {
|
|
||||||
this.endDate = new Date();
|
|
||||||
this.endDate.setHours(0, 0, 0, 0);
|
|
||||||
this.beginDate = this.dateService.addDays(this.endDate, -1);
|
|
||||||
|
|
||||||
this.exitAltitude = 4000;
|
|
||||||
this.deployAltitude = 1000;
|
|
||||||
this.countOfJumps = 1;
|
|
||||||
|
|
||||||
this.selectedDz = undefined;
|
|
||||||
this.selectedGear = undefined;
|
|
||||||
this.selectedAircraft = undefined;
|
|
||||||
this.selectedJumpType = undefined;
|
|
||||||
|
|
||||||
this.listOfFilteredDropZone = this.listOfDropZone;
|
|
||||||
this.comments = undefined;
|
|
||||||
|
|
||||||
this.withCutaway = false;
|
|
||||||
this.isSpecial = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public displayNameFn(data?: any): string | undefined {
|
|
||||||
return data ? data.name : undefined;
|
|
||||||
}
|
|
||||||
public displayGearFn(data?: GearResp): string | undefined {
|
|
||||||
return data ? `${data.name} (${data.mainCanopy})` : undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
public onChangeDz(event: any) {
|
|
||||||
let filterValue: string;
|
|
||||||
|
|
||||||
if (event.id === undefined) {
|
|
||||||
filterValue = event.toLowerCase();
|
|
||||||
|
|
||||||
this.listOfFilteredDropZone = this.listOfDropZone;
|
|
||||||
this.listOfFilteredDropZone = this.listOfFilteredDropZone.filter(
|
|
||||||
(option) => option.name.toLowerCase().includes(filterValue)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public onChangeBeginDate(event: any) {
|
public displayNameFn(data?: any): string | undefined {
|
||||||
this.endDate = event;
|
return data ? data.name : undefined;
|
||||||
}
|
}
|
||||||
|
public displayGearFn(data?: GearResp): string | undefined {
|
||||||
|
return data ? `${data.name} (${data.mainCanopy})` : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
public notLoadingToDisplay(): boolean {
|
public onChangeDz(event: any) {
|
||||||
return !(this.pendingAddRequest || this.countDatasLoaded !== 4);
|
let filterValue: string;
|
||||||
}
|
|
||||||
|
|
||||||
public resetDz() {
|
if (event.id === undefined) {
|
||||||
this.selectedDz = undefined;
|
filterValue = event.toLowerCase();
|
||||||
this.onChangeDz("");
|
|
||||||
}
|
|
||||||
|
|
||||||
private updateTitle() {
|
this.listOfFilteredDropZone = this.listOfDropZone;
|
||||||
this.translateService.get("NewJump_Title").subscribe((data) => {
|
this.listOfFilteredDropZone = this.listOfFilteredDropZone.filter(
|
||||||
this.serviceComm.updatedComponentTitle(data);
|
(option) => option.name.toLowerCase().includes(filterValue),
|
||||||
});
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public onChangeBeginDate(event: any) {
|
||||||
|
this.endDate = event;
|
||||||
|
}
|
||||||
|
|
||||||
|
public notLoadingToDisplay(): boolean {
|
||||||
|
return !(this.pendingAddRequest || this.countDatasLoaded !== 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public resetDz() {
|
||||||
|
this.selectedDz = undefined;
|
||||||
|
this.onChangeDz("");
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateTitle() {
|
||||||
|
this.translateService.get("NewJump_Title").subscribe((data) => {
|
||||||
|
this.serviceComm.updatedComponentTitle(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
.formNewJumps {
|
.formNewJumps {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
min-width: 150px;
|
min-width: 150px;
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
min-height: 90vh;
|
min-height: 90vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: left;
|
justify-content: left;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: initial;
|
align-items: initial;
|
||||||
padding-top: 25px;
|
padding-top: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,145 +1,153 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
mat-raised-button
|
mat-raised-button
|
||||||
color="accent"
|
color="accent"
|
||||||
[routerLink]="['/tunnelFlights']"
|
[routerLink]="['/tunnelFlights']"
|
||||||
[routerLinkActive]="['active']"
|
[routerLinkActive]="['active']"
|
||||||
skipLocationChange
|
skipLocationChange
|
||||||
>
|
|
||||||
{{ "NewTunnelFlight_GoToJump" | translate }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form
|
|
||||||
class="formNewJumps"
|
|
||||||
(ngSubmit)="onFormSubmit()"
|
|
||||||
*ngIf="notLoadingToDisplay(); else loading"
|
|
||||||
>
|
|
||||||
<mat-form-field>
|
|
||||||
<mat-label>{{ "NewTunnelFlight_ChooseJumpType" | translate }}</mat-label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
matInput
|
|
||||||
[matAutocomplete]="autoJumpType"
|
|
||||||
[(ngModel)]="selectedJumpType"
|
|
||||||
name="selectedJumpType"
|
|
||||||
/>
|
|
||||||
<mat-autocomplete
|
|
||||||
#autoJumpType="matAutocomplete"
|
|
||||||
[displayWith]="displayNameFn"
|
|
||||||
>
|
|
||||||
<mat-option *ngFor="let jumpType of listOfJumpType" [value]="jumpType">
|
|
||||||
{{ jumpType.name }}
|
|
||||||
</mat-option>
|
|
||||||
</mat-autocomplete>
|
|
||||||
<button
|
|
||||||
*ngIf="selectedJumpType"
|
|
||||||
matSuffix
|
|
||||||
mat-icon-button
|
|
||||||
aria-label="Clear"
|
|
||||||
(click)="selectedJumpType = undefined"
|
|
||||||
>
|
|
||||||
<mat-icon>close</mat-icon>
|
|
||||||
</button>
|
|
||||||
</mat-form-field>
|
|
||||||
|
|
||||||
<mat-form-field>
|
|
||||||
<mat-label>{{ "NewTunnelFlight_ChooseTunnel" | translate }}</mat-label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
matInput
|
|
||||||
[matAutocomplete]="autoDropZone"
|
|
||||||
[(ngModel)]="selectedTunnel"
|
|
||||||
(ngModelChange)="onChangeTunnel($event)"
|
|
||||||
name="selectedTunnel"
|
|
||||||
/>
|
|
||||||
<mat-autocomplete
|
|
||||||
#autoDropZone="matAutocomplete"
|
|
||||||
[displayWith]="displayNameFn"
|
|
||||||
>
|
|
||||||
<mat-option
|
|
||||||
*ngFor="let tunnel of listOfFilteredTunnel"
|
|
||||||
[value]="tunnel"
|
|
||||||
>
|
>
|
||||||
{{ tunnel.name }}
|
{{ "NewTunnelFlight_GoToJump" | translate }}
|
||||||
</mat-option>
|
</button>
|
||||||
</mat-autocomplete>
|
</div>
|
||||||
<button
|
|
||||||
*ngIf="selectedTunnel"
|
|
||||||
matSuffix
|
|
||||||
mat-icon-button
|
|
||||||
aria-label="Clear"
|
|
||||||
(click)="resetTunnel()"
|
|
||||||
>
|
|
||||||
<mat-icon>close</mat-icon>
|
|
||||||
</button>
|
|
||||||
</mat-form-field>
|
|
||||||
|
|
||||||
<mat-form-field>
|
@if (notLoadingToDisplay()) {
|
||||||
<mat-label>{{ "NewTunnelFlight_Date_Lbl" | translate }}</mat-label>
|
<form class="formNewJumps" (ngSubmit)="onFormSubmit()">
|
||||||
<input
|
<mat-form-field>
|
||||||
matInput
|
<mat-label>{{
|
||||||
[max]="maxDate"
|
"NewTunnelFlight_ChooseJumpType" | translate
|
||||||
[matDatepicker]="flightDateDp"
|
}}</mat-label>
|
||||||
[(ngModel)]="flightDate"
|
<input
|
||||||
name="flightDate"
|
type="text"
|
||||||
disabled
|
matInput
|
||||||
/>
|
[matAutocomplete]="autoJumpType"
|
||||||
<mat-datepicker-toggle
|
[(ngModel)]="selectedJumpType"
|
||||||
matSuffix
|
name="selectedJumpType"
|
||||||
[for]="flightDateDp"
|
/>
|
||||||
></mat-datepicker-toggle>
|
<mat-autocomplete
|
||||||
<mat-datepicker #flightDateDp disabled="false"></mat-datepicker>
|
#autoJumpType="matAutocomplete"
|
||||||
</mat-form-field>
|
[displayWith]="displayNameFn"
|
||||||
|
>
|
||||||
<mat-form-field>
|
@for (jumpType of listOfJumpType; track jumpType) {
|
||||||
<mat-label>{{ "NewTunnelFlight_Minutes_Lbl" | translate }}</mat-label>
|
<mat-option [value]="jumpType">
|
||||||
<input
|
{{ jumpType.name }}
|
||||||
matInput
|
</mat-option>
|
||||||
placeholder="{{ 'NewTunnelFlight_Minutes' | translate }}"
|
}
|
||||||
[(ngModel)]="minutesOfFlight"
|
</mat-autocomplete>
|
||||||
name="minutesOfFlight"
|
@if (selectedJumpType) {
|
||||||
type="number"
|
<button
|
||||||
/>
|
matSuffix
|
||||||
<button
|
mat-icon-button
|
||||||
*ngIf="minutesOfFlight"
|
aria-label="Clear"
|
||||||
matSuffix
|
(click)="selectedJumpType = undefined"
|
||||||
mat-icon-button
|
>
|
||||||
aria-label="Clear"
|
<mat-icon svgIcon="close"></mat-icon>
|
||||||
(click)="minutesOfFlight = undefined"
|
</button>
|
||||||
>
|
}
|
||||||
<mat-icon>close</mat-icon>
|
</mat-form-field>
|
||||||
</button>
|
<mat-form-field>
|
||||||
</mat-form-field>
|
<mat-label>{{
|
||||||
|
"NewTunnelFlight_ChooseTunnel" | translate
|
||||||
<mat-form-field>
|
}}</mat-label>
|
||||||
<mat-label>{{ "NewTunnelFlight_Comments_Lbl" | translate }}</mat-label>
|
<input
|
||||||
<textarea
|
type="text"
|
||||||
matInput
|
matInput
|
||||||
placeholder="{{ 'NewTunnelFlight_Comments' | translate }}"
|
[matAutocomplete]="autoDropZone"
|
||||||
[(ngModel)]="comments"
|
[(ngModel)]="selectedTunnel"
|
||||||
name="comments"
|
(ngModelChange)="onChangeTunnel($event)"
|
||||||
type="text"
|
name="selectedTunnel"
|
||||||
></textarea>
|
/>
|
||||||
<button
|
<mat-autocomplete
|
||||||
*ngIf="comments"
|
#autoDropZone="matAutocomplete"
|
||||||
matSuffix
|
[displayWith]="displayNameFn"
|
||||||
mat-icon-button
|
>
|
||||||
aria-label="Clear"
|
@for (tunnel of listOfFilteredTunnel; track tunnel) {
|
||||||
(click)="comments = undefined"
|
<mat-option [value]="tunnel">
|
||||||
>
|
{{ tunnel.name }}
|
||||||
<mat-icon>close</mat-icon>
|
</mat-option>
|
||||||
</button>
|
}
|
||||||
</mat-form-field>
|
</mat-autocomplete>
|
||||||
|
@if (selectedTunnel) {
|
||||||
<br />
|
<button
|
||||||
<button mat-raised-button color="accent" *ngIf="isValidatedForm()">
|
matSuffix
|
||||||
{{ "NewTunnelFlight_Submit" | translate }}
|
mat-icon-button
|
||||||
</button>
|
aria-label="Clear"
|
||||||
</form>
|
(click)="resetTunnel()"
|
||||||
|
>
|
||||||
<ng-template #loading>
|
<mat-icon svgIcon="close"></mat-icon>
|
||||||
<mat-progress-spinner [mode]="'indeterminate'"></mat-progress-spinner>
|
</button>
|
||||||
</ng-template>
|
}
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>{{
|
||||||
|
"NewTunnelFlight_Date_Lbl" | translate
|
||||||
|
}}</mat-label>
|
||||||
|
<input
|
||||||
|
matInput
|
||||||
|
[max]="maxDate"
|
||||||
|
[matDatepicker]="flightDateDp"
|
||||||
|
[(ngModel)]="flightDate"
|
||||||
|
name="flightDate"
|
||||||
|
disabled
|
||||||
|
/>
|
||||||
|
<mat-datepicker-toggle
|
||||||
|
matSuffix
|
||||||
|
[for]="flightDateDp"
|
||||||
|
></mat-datepicker-toggle>
|
||||||
|
<mat-datepicker #flightDateDp disabled="false"></mat-datepicker>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>{{
|
||||||
|
"NewTunnelFlight_Minutes_Lbl" | translate
|
||||||
|
}}</mat-label>
|
||||||
|
<input
|
||||||
|
matInput
|
||||||
|
placeholder="{{ 'NewTunnelFlight_Minutes' | translate }}"
|
||||||
|
[(ngModel)]="minutesOfFlight"
|
||||||
|
name="minutesOfFlight"
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
|
@if (minutesOfFlight) {
|
||||||
|
<button
|
||||||
|
matSuffix
|
||||||
|
mat-icon-button
|
||||||
|
aria-label="Clear"
|
||||||
|
(click)="minutesOfFlight = undefined"
|
||||||
|
>
|
||||||
|
<mat-icon svgIcon="close"></mat-icon>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>{{
|
||||||
|
"NewTunnelFlight_Comments_Lbl" | translate
|
||||||
|
}}</mat-label>
|
||||||
|
<textarea
|
||||||
|
matInput
|
||||||
|
placeholder="{{ 'NewTunnelFlight_Comments' | translate }}"
|
||||||
|
[(ngModel)]="comments"
|
||||||
|
name="comments"
|
||||||
|
type="text"
|
||||||
|
></textarea>
|
||||||
|
@if (comments) {
|
||||||
|
<button
|
||||||
|
matSuffix
|
||||||
|
mat-icon-button
|
||||||
|
aria-label="Clear"
|
||||||
|
(click)="comments = undefined"
|
||||||
|
>
|
||||||
|
<mat-icon svgIcon="close"></mat-icon>
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
</mat-form-field>
|
||||||
|
<br />
|
||||||
|
@if (this.isValidatedForm()) {
|
||||||
|
<button mat-raised-button color="accent">
|
||||||
|
{{ "NewTunnelFlight_Submit" | translate }}
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
</form>
|
||||||
|
} @else {
|
||||||
|
<mat-progress-spinner [mode]="'indeterminate'"></mat-progress-spinner>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ import { Component, OnInit } from "@angular/core";
|
|||||||
import { RouterLink, RouterModule } from "@angular/router";
|
import { RouterLink, RouterModule } from "@angular/router";
|
||||||
import { formatDate } from "@angular/common";
|
import { formatDate } from "@angular/common";
|
||||||
import {
|
import {
|
||||||
DateAdapter,
|
DateAdapter,
|
||||||
MAT_DATE_FORMATS,
|
MAT_DATE_FORMATS,
|
||||||
NativeDateAdapter,
|
NativeDateAdapter,
|
||||||
} from "@angular/material/core";
|
} from "@angular/material/core";
|
||||||
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
||||||
import { CommonModule } from "@angular/common";
|
|
||||||
import { MatIconModule } from "@angular/material/icon";
|
import { MatIconModule } from "@angular/material/icon";
|
||||||
import { MatOptionModule } from "@angular/material/core";
|
import { MatOptionModule } from "@angular/material/core";
|
||||||
import { MatAutocompleteModule } from "@angular/material/autocomplete";
|
import { MatAutocompleteModule } from "@angular/material/autocomplete";
|
||||||
@@ -28,170 +28,171 @@ import { JumpTypeService } from "../../services/jump-type.service";
|
|||||||
import { DateService } from "../../services/date.service";
|
import { DateService } from "../../services/date.service";
|
||||||
|
|
||||||
export const PICK_FORMATS = {
|
export const PICK_FORMATS = {
|
||||||
parse: { dateInput: "yy MM dd" },
|
parse: { dateInput: "yy MM dd" },
|
||||||
display: {
|
display: {
|
||||||
dateInput: "yyyy-MM-dd",
|
dateInput: "yyyy-MM-dd",
|
||||||
monthYearLabel: "yyyy MMM",
|
monthYearLabel: "yyyy MMM",
|
||||||
dateA11yLabel: "yyyy MM dd",
|
dateA11yLabel: "yyyy MM dd",
|
||||||
monthYearA11yLabel: "yyyy MMMM",
|
monthYearA11yLabel: "yyyy MMMM",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
class PickDateAdapter extends NativeDateAdapter {
|
class PickDateAdapter extends NativeDateAdapter {
|
||||||
override format(date: Date, displayFormat: Object): string {
|
override format(date: Date, displayFormat: Object): string {
|
||||||
return formatDate(date, displayFormat.toString(), "en");
|
return formatDate(date, displayFormat.toString(), "en");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-new-tunnel-flight",
|
selector: "app-new-tunnel-flight",
|
||||||
templateUrl: "./new-tunnel-flight.component.html",
|
templateUrl: "./new-tunnel-flight.component.html",
|
||||||
styleUrls: ["./new-tunnel-flight.component.css"],
|
styleUrls: ["./new-tunnel-flight.component.css"],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: DateAdapter, useClass: PickDateAdapter },
|
{ provide: DateAdapter, useClass: PickDateAdapter },
|
||||||
{ provide: MAT_DATE_FORMATS, useValue: PICK_FORMATS },
|
{ provide: MAT_DATE_FORMATS, useValue: PICK_FORMATS },
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
CommonModule,
|
RouterModule,
|
||||||
RouterModule,
|
RouterLink,
|
||||||
RouterLink,
|
FormsModule,
|
||||||
FormsModule,
|
MatFormFieldModule,
|
||||||
MatFormFieldModule,
|
ReactiveFormsModule,
|
||||||
ReactiveFormsModule,
|
MatAutocompleteModule,
|
||||||
MatAutocompleteModule,
|
MatInputModule,
|
||||||
MatInputModule,
|
MatButtonModule,
|
||||||
MatButtonModule,
|
MatIconModule,
|
||||||
MatIconModule,
|
MatFormFieldModule,
|
||||||
MatFormFieldModule,
|
MatOptionModule,
|
||||||
MatOptionModule,
|
MatDatepickerModule,
|
||||||
MatDatepickerModule,
|
MatProgressSpinnerModule,
|
||||||
MatProgressSpinnerModule,
|
],
|
||||||
],
|
|
||||||
})
|
})
|
||||||
export class NewTunnelFlightComponent implements OnInit {
|
export class NewTunnelFlightComponent implements OnInit {
|
||||||
public flightDate: Date;
|
public flightDate: Date;
|
||||||
public minutesOfFlight: number;
|
public minutesOfFlight: number;
|
||||||
public selectedTunnel: TunnelResp;
|
public selectedTunnel: TunnelResp;
|
||||||
public selectedJumpType: JumpTypeResp;
|
public selectedJumpType: JumpTypeResp;
|
||||||
public listOfTunnel: Array<TunnelResp>;
|
public listOfTunnel: Array<TunnelResp>;
|
||||||
public listOfFilteredTunnel: Array<TunnelResp>;
|
public listOfFilteredTunnel: Array<TunnelResp>;
|
||||||
public resetForm: boolean;
|
public resetForm: boolean;
|
||||||
public comments: string;
|
public comments: string;
|
||||||
private countDatasLoaded: number;
|
private countDatasLoaded: number;
|
||||||
private pendingAddRequest: boolean;
|
private pendingAddRequest: boolean;
|
||||||
public listOfJumpType: Array<JumpTypeResp>;
|
public listOfJumpType: Array<JumpTypeResp>;
|
||||||
public maxDate: Date;
|
public maxDate: Date;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private serviceComm: ServiceComm,
|
private serviceComm: ServiceComm,
|
||||||
private serviceTunnel: TunnelService,
|
private serviceTunnel: TunnelService,
|
||||||
private serviceTunnelFlight: TunnelFlightService,
|
private serviceTunnelFlight: TunnelFlightService,
|
||||||
private serviceJumpType: JumpTypeService,
|
private serviceJumpType: JumpTypeService,
|
||||||
private translateService: TranslateService,
|
private translateService: TranslateService,
|
||||||
private dateService: DateService
|
private dateService: DateService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
||||||
if (data === true) {
|
if (data === true) {
|
||||||
|
this.updateTitle();
|
||||||
|
}
|
||||||
|
});
|
||||||
this.updateTitle();
|
this.updateTitle();
|
||||||
}
|
|
||||||
});
|
|
||||||
this.updateTitle();
|
|
||||||
|
|
||||||
this.maxDate = this.dateService.addDays(new Date(), 1);
|
this.maxDate = this.dateService.addDays(new Date(), 1);
|
||||||
this.countDatasLoaded = 0;
|
this.countDatasLoaded = 0;
|
||||||
this.pendingAddRequest = false;
|
|
||||||
this.initForm();
|
|
||||||
this.getListOfTunnels();
|
|
||||||
this.getListOfJumpTypes();
|
|
||||||
}
|
|
||||||
|
|
||||||
public onFormSubmit() {
|
|
||||||
this.pendingAddRequest = true;
|
|
||||||
|
|
||||||
this.serviceTunnelFlight
|
|
||||||
.addFlight(
|
|
||||||
this.selectedTunnel.id,
|
|
||||||
this.selectedJumpType.id,
|
|
||||||
this.flightDate,
|
|
||||||
this.minutesOfFlight,
|
|
||||||
this.comments
|
|
||||||
)
|
|
||||||
.subscribe(() => {
|
|
||||||
this.comments = undefined;
|
|
||||||
|
|
||||||
if (this.resetForm === true) {
|
|
||||||
this.initForm();
|
|
||||||
}
|
|
||||||
this.pendingAddRequest = false;
|
this.pendingAddRequest = false;
|
||||||
});
|
this.initForm();
|
||||||
}
|
this.getListOfTunnels();
|
||||||
|
this.getListOfJumpTypes();
|
||||||
public isValidatedForm(): boolean {
|
|
||||||
return (
|
|
||||||
this.selectedTunnel !== undefined &&
|
|
||||||
this.selectedTunnel.id !== undefined &&
|
|
||||||
this.minutesOfFlight !== undefined &&
|
|
||||||
typeof this.minutesOfFlight === "number"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private getListOfTunnels() {
|
|
||||||
this.serviceTunnel.getListOfTunnels().subscribe((data) => {
|
|
||||||
data.sort((a, b) => a.name.localeCompare(b.name));
|
|
||||||
this.listOfTunnel = data;
|
|
||||||
this.listOfFilteredTunnel = data;
|
|
||||||
this.countDatasLoaded++;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private getListOfJumpTypes() {
|
|
||||||
this.serviceJumpType.getListOfJumpTypesForTunnel().subscribe((data) => {
|
|
||||||
data.sort((a, b) => a.name.localeCompare(b.name));
|
|
||||||
this.listOfJumpType = data;
|
|
||||||
this.countDatasLoaded++;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public notLoadingToDisplay(): boolean {
|
|
||||||
return !(this.pendingAddRequest || this.countDatasLoaded !== 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
private updateTitle() {
|
|
||||||
this.translateService.get("NewTunnelFlight_Title").subscribe((data) => {
|
|
||||||
this.serviceComm.updatedComponentTitle(data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private initForm() {
|
|
||||||
this.flightDate = new Date();
|
|
||||||
this.flightDate.setHours(0, 0, 0, 0);
|
|
||||||
|
|
||||||
this.minutesOfFlight = 1;
|
|
||||||
this.selectedTunnel = undefined;
|
|
||||||
this.comments = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
public resetTunnel() {
|
|
||||||
this.selectedTunnel = undefined;
|
|
||||||
this.onChangeTunnel("");
|
|
||||||
}
|
|
||||||
|
|
||||||
public onChangeTunnel(event: any) {
|
|
||||||
let filterValue: string;
|
|
||||||
|
|
||||||
if (event.id === undefined) {
|
|
||||||
filterValue = event.toLowerCase();
|
|
||||||
|
|
||||||
this.listOfFilteredTunnel = this.listOfTunnel;
|
|
||||||
this.listOfFilteredTunnel = this.listOfFilteredTunnel.filter((option) =>
|
|
||||||
option.name.toLowerCase().includes(filterValue)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public displayNameFn(data?: any): string | undefined {
|
public onFormSubmit() {
|
||||||
return data ? data.name : undefined;
|
if (this.isValidatedForm()) {
|
||||||
}
|
this.pendingAddRequest = true;
|
||||||
|
|
||||||
|
this.serviceTunnelFlight
|
||||||
|
.addFlight(
|
||||||
|
this.selectedTunnel.id,
|
||||||
|
this.selectedJumpType.id,
|
||||||
|
this.flightDate,
|
||||||
|
this.minutesOfFlight,
|
||||||
|
this.comments,
|
||||||
|
)
|
||||||
|
.subscribe(() => {
|
||||||
|
this.comments = undefined;
|
||||||
|
|
||||||
|
if (this.resetForm === true) {
|
||||||
|
this.initForm();
|
||||||
|
}
|
||||||
|
this.pendingAddRequest = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public isValidatedForm(): boolean {
|
||||||
|
return (
|
||||||
|
this.selectedTunnel !== undefined &&
|
||||||
|
this.selectedTunnel.id !== undefined &&
|
||||||
|
this.minutesOfFlight !== undefined &&
|
||||||
|
typeof this.minutesOfFlight === "number"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getListOfTunnels() {
|
||||||
|
this.serviceTunnel.getListOfTunnels().subscribe((data) => {
|
||||||
|
data.sort((a, b) => a.name.localeCompare(b.name));
|
||||||
|
this.listOfTunnel = data;
|
||||||
|
this.listOfFilteredTunnel = data;
|
||||||
|
this.countDatasLoaded++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private getListOfJumpTypes() {
|
||||||
|
this.serviceJumpType.getListOfJumpTypesForTunnel().subscribe((data) => {
|
||||||
|
data.sort((a, b) => a.name.localeCompare(b.name));
|
||||||
|
this.listOfJumpType = data;
|
||||||
|
this.countDatasLoaded++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public notLoadingToDisplay(): boolean {
|
||||||
|
return !(this.pendingAddRequest || this.countDatasLoaded !== 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateTitle() {
|
||||||
|
this.translateService.get("NewTunnelFlight_Title").subscribe((data) => {
|
||||||
|
this.serviceComm.updatedComponentTitle(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private initForm() {
|
||||||
|
this.flightDate = new Date();
|
||||||
|
this.flightDate.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
this.minutesOfFlight = 1;
|
||||||
|
this.selectedTunnel = undefined;
|
||||||
|
this.comments = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
public resetTunnel() {
|
||||||
|
this.selectedTunnel = undefined;
|
||||||
|
this.onChangeTunnel("");
|
||||||
|
}
|
||||||
|
|
||||||
|
public onChangeTunnel(event: any) {
|
||||||
|
let filterValue: string;
|
||||||
|
|
||||||
|
if (event.id === undefined) {
|
||||||
|
filterValue = event.toLowerCase();
|
||||||
|
|
||||||
|
this.listOfFilteredTunnel = this.listOfTunnel;
|
||||||
|
this.listOfFilteredTunnel = this.listOfFilteredTunnel.filter(
|
||||||
|
(option) => option.name.toLowerCase().includes(filterValue),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public displayNameFn(data?: any): string | undefined {
|
||||||
|
return data ? data.name : undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,49 +1,49 @@
|
|||||||
.mat-row td {
|
.mat-row td {
|
||||||
padding-right: 15px;
|
padding-right: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.labelTab {
|
.labelTab {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
background-color: lightgray;
|
background-color: lightgray;
|
||||||
}
|
}
|
||||||
|
|
||||||
.labelTab.selected {
|
.labelTab.selected {
|
||||||
background-color: gray !important;
|
background-color: gray !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
min-height: 90vh;
|
min-height: 90vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: left;
|
justify-content: left;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: initial;
|
align-items: initial;
|
||||||
padding-top: 25px;
|
padding-top: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.left160 {
|
.left160 {
|
||||||
clear: both;
|
clear: both;
|
||||||
float: left;
|
float: left;
|
||||||
width: 160px;
|
width: 160px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.paragraph {
|
.paragraph {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.containerFlex {
|
.containerFlex {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
.contentFlex {
|
.contentFlex {
|
||||||
flex: 45%;
|
flex: 45%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chart-container {
|
.chart-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
height: 80vh;
|
height: 80vh;
|
||||||
width: 80vw;
|
width: 80vw;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,182 +1,259 @@
|
|||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="paragraph">
|
<div class="paragraph">
|
||||||
<label class="left160">{{ "Summary_TotalJumps" | translate }}</label>
|
<label class="left160">{{ "Summary_TotalJumps" | translate }}</label>
|
||||||
<span>: {{ totalJumps }}</span>
|
<span>: {{ totalJumps }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="paragraph">
|
<div class="paragraph">
|
||||||
<label class="left160">{{ "Summary_TotalCutaways" | translate }}</label>
|
<label class="left160">{{ "Summary_TotalCutaways" | translate }}</label>
|
||||||
<span>: {{ totalCutaways }}</span>
|
<span>: {{ totalCutaways }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="paragraph">
|
<div class="paragraph">
|
||||||
<label class="left160">{{ "Summary_LastJump" | translate }}</label>
|
<label class="left160">{{ "Summary_LastJump" | translate }}</label>
|
||||||
<span>: {{ lastJump }}</span>
|
<span>: {{ lastJump }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="paragraph" style="margin-top: 20px">
|
<div class="paragraph" style="margin-top: 20px">
|
||||||
<label class="left160">{{ "Summary_Refresh" | translate }}</label>
|
<label class="left160">{{ "Summary_Refresh" | translate }}</label>
|
||||||
<mat-icon
|
<mat-icon
|
||||||
aria-hidden="false"
|
aria-hidden="false"
|
||||||
aria-label="Force the refresh of the stats"
|
aria-label="Force the refresh of the stats"
|
||||||
style="cursor: pointer"
|
style="cursor: pointer"
|
||||||
(click)="refreshStats()"
|
(click)="refreshStats()"
|
||||||
svgIcon="reset"
|
svgIcon="reset"
|
||||||
></mat-icon>
|
></mat-icon>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<mat-tab-group
|
<mat-tab-group
|
||||||
mat-align-tabs="left"
|
mat-align-tabs="left"
|
||||||
animationDuration="0ms"
|
animationDuration="0ms"
|
||||||
(selectedIndex)="(0)"
|
(selectedIndex)="(0)"
|
||||||
(selectedTabChange)="onTabChanged($event)"
|
(selectedTabChange)="onTabChanged($event)"
|
||||||
>
|
>
|
||||||
<mat-tab label="{{ 'Summary_LastMonth_Title' | translate }}">
|
<mat-tab label="{{ 'Summary_LastMonth_Title' | translate }}">
|
||||||
<ng-template matTabContent>
|
<ng-template matTabContent>
|
||||||
<div class="containerFlex">
|
<div class="containerFlex">
|
||||||
<fieldset class="contentFlex">
|
<fieldset class="contentFlex">
|
||||||
<legend>{{ "Summary_LastMonth_ByDz" | translate }}</legend>
|
<legend>
|
||||||
<table mat-table [dataSource]="dsJumpForLastMonthByDz">
|
{{ "Summary_LastMonth_ByDz" | translate }}
|
||||||
<ng-container matColumnDef="label">
|
</legend>
|
||||||
<td mat-cell *matCellDef="let element">{{ element.label }}</td>
|
<table mat-table [dataSource]="dsJumpForLastMonthByDz">
|
||||||
</ng-container>
|
<ng-container matColumnDef="label">
|
||||||
<ng-container matColumnDef="nb">
|
<td mat-cell *matCellDef="let element">
|
||||||
<td mat-cell *matCellDef="let element">{{ element.nb }}</td>
|
{{ element.label }}
|
||||||
</ng-container>
|
</td>
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
</ng-container>
|
||||||
</table>
|
<ng-container matColumnDef="nb">
|
||||||
</fieldset>
|
<td mat-cell *matCellDef="let element">
|
||||||
<fieldset class="contentFlex">
|
{{ element.nb }}
|
||||||
<legend>{{ "Summary_LastMonth_ByJumpType" | translate }}</legend>
|
</td>
|
||||||
<table mat-table [dataSource]="dsJumpForLastMonthByJumpType">
|
</ng-container>
|
||||||
<ng-container matColumnDef="label">
|
<tr
|
||||||
<td mat-cell *matCellDef="let element">{{ element.label }}</td>
|
mat-row
|
||||||
</ng-container>
|
*matRowDef="let row; columns: displayedColumns"
|
||||||
<ng-container matColumnDef="nb">
|
></tr>
|
||||||
<td mat-cell *matCellDef="let element">{{ element.nb }}</td>
|
</table>
|
||||||
</ng-container>
|
</fieldset>
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
<fieldset class="contentFlex">
|
||||||
</table>
|
<legend>
|
||||||
</fieldset>
|
{{ "Summary_LastMonth_ByJumpType" | translate }}
|
||||||
</div>
|
</legend>
|
||||||
</ng-template>
|
<table
|
||||||
</mat-tab>
|
mat-table
|
||||||
|
[dataSource]="dsJumpForLastMonthByJumpType"
|
||||||
|
>
|
||||||
|
<ng-container matColumnDef="label">
|
||||||
|
<td mat-cell *matCellDef="let element">
|
||||||
|
{{ element.label }}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container matColumnDef="nb">
|
||||||
|
<td mat-cell *matCellDef="let element">
|
||||||
|
{{ element.nb }}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
<tr
|
||||||
|
mat-row
|
||||||
|
*matRowDef="let row; columns: displayedColumns"
|
||||||
|
></tr>
|
||||||
|
</table>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
</mat-tab>
|
||||||
|
|
||||||
<mat-tab label="{{ 'Summary_LastYear_Title' | translate }}">
|
<mat-tab label="{{ 'Summary_LastYear_Title' | translate }}">
|
||||||
<ng-template matTabContent>
|
<ng-template matTabContent>
|
||||||
<div class="containerFlex">
|
<div class="containerFlex">
|
||||||
<fieldset class="contentFlex">
|
<fieldset class="contentFlex">
|
||||||
<legend>{{ "Summary_LastYear_ByDz" | translate }}</legend>
|
<legend>
|
||||||
<table mat-table [dataSource]="dsJumpForLastYearByDz">
|
{{ "Summary_LastYear_ByDz" | translate }}
|
||||||
<ng-container matColumnDef="label">
|
</legend>
|
||||||
<td mat-cell *matCellDef="let element">{{ element.label }}</td>
|
<table mat-table [dataSource]="dsJumpForLastYearByDz">
|
||||||
</ng-container>
|
<ng-container matColumnDef="label">
|
||||||
<ng-container matColumnDef="nb">
|
<td mat-cell *matCellDef="let element">
|
||||||
<td mat-cell *matCellDef="let element">{{ element.nb }}</td>
|
{{ element.label }}
|
||||||
</ng-container>
|
</td>
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
</ng-container>
|
||||||
</table>
|
<ng-container matColumnDef="nb">
|
||||||
</fieldset>
|
<td mat-cell *matCellDef="let element">
|
||||||
<fieldset class="contentFlex">
|
{{ element.nb }}
|
||||||
<legend>{{ "Summary_LastYear_ByJumpType" | translate }}</legend>
|
</td>
|
||||||
<table mat-table [dataSource]="dsJumpForLastYearByJumpType">
|
</ng-container>
|
||||||
<ng-container matColumnDef="label">
|
<tr
|
||||||
<td mat-cell *matCellDef="let element">{{ element.label }}</td>
|
mat-row
|
||||||
</ng-container>
|
*matRowDef="let row; columns: displayedColumns"
|
||||||
<ng-container matColumnDef="nb">
|
></tr>
|
||||||
<td mat-cell *matCellDef="let element">{{ element.nb }}</td>
|
</table>
|
||||||
</ng-container>
|
</fieldset>
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
<fieldset class="contentFlex">
|
||||||
</table>
|
<legend>
|
||||||
</fieldset>
|
{{ "Summary_LastYear_ByJumpType" | translate }}
|
||||||
</div>
|
</legend>
|
||||||
</ng-template>
|
<table
|
||||||
</mat-tab>
|
mat-table
|
||||||
|
[dataSource]="dsJumpForLastYearByJumpType"
|
||||||
|
>
|
||||||
|
<ng-container matColumnDef="label">
|
||||||
|
<td mat-cell *matCellDef="let element">
|
||||||
|
{{ element.label }}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container matColumnDef="nb">
|
||||||
|
<td mat-cell *matCellDef="let element">
|
||||||
|
{{ element.nb }}
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
<tr
|
||||||
|
mat-row
|
||||||
|
*matRowDef="let row; columns: displayedColumns"
|
||||||
|
></tr>
|
||||||
|
</table>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
</mat-tab>
|
||||||
|
|
||||||
<mat-tab label="{{ 'Summary_ByDz_Title' | translate }}">
|
<mat-tab label="{{ 'Summary_ByDz_Title' | translate }}">
|
||||||
<ng-template matTabContent>
|
<ng-template matTabContent>
|
||||||
<table mat-table [dataSource]="dsNbJumpByDz">
|
<table mat-table [dataSource]="dsNbJumpByDz">
|
||||||
<ng-container matColumnDef="label">
|
<ng-container matColumnDef="label">
|
||||||
<td mat-cell *matCellDef="let element">{{ element.label }}</td>
|
<td mat-cell *matCellDef="let element">
|
||||||
</ng-container>
|
{{ element.label }}
|
||||||
<ng-container matColumnDef="nb">
|
</td>
|
||||||
<td mat-cell *matCellDef="let element">{{ element.nb }}</td>
|
</ng-container>
|
||||||
</ng-container>
|
<ng-container matColumnDef="nb">
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
<td mat-cell *matCellDef="let element">
|
||||||
</table>
|
{{ element.nb }}
|
||||||
</ng-template>
|
</td>
|
||||||
</mat-tab>
|
</ng-container>
|
||||||
|
<tr
|
||||||
|
mat-row
|
||||||
|
*matRowDef="let row; columns: displayedColumns"
|
||||||
|
></tr>
|
||||||
|
</table>
|
||||||
|
</ng-template>
|
||||||
|
</mat-tab>
|
||||||
|
|
||||||
<mat-tab label="{{ 'Summary_ByAircraft_Title' | translate }}">
|
<mat-tab label="{{ 'Summary_ByAircraft_Title' | translate }}">
|
||||||
<ng-template matTabContent>
|
<ng-template matTabContent>
|
||||||
<table mat-table [dataSource]="dsNbJumpByAircraft">
|
<table mat-table [dataSource]="dsNbJumpByAircraft">
|
||||||
<ng-container matColumnDef="label">
|
<ng-container matColumnDef="label">
|
||||||
<td mat-cell *matCellDef="let element">{{ element.label }}</td>
|
<td mat-cell *matCellDef="let element">
|
||||||
</ng-container>
|
{{ element.label }}
|
||||||
<ng-container matColumnDef="nb">
|
</td>
|
||||||
<td mat-cell *matCellDef="let element">{{ element.nb }}</td>
|
</ng-container>
|
||||||
</ng-container>
|
<ng-container matColumnDef="nb">
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
<td mat-cell *matCellDef="let element">
|
||||||
</table>
|
{{ element.nb }}
|
||||||
</ng-template>
|
</td>
|
||||||
</mat-tab>
|
</ng-container>
|
||||||
|
<tr
|
||||||
|
mat-row
|
||||||
|
*matRowDef="let row; columns: displayedColumns"
|
||||||
|
></tr>
|
||||||
|
</table>
|
||||||
|
</ng-template>
|
||||||
|
</mat-tab>
|
||||||
|
|
||||||
<mat-tab label="{{ 'Summary_ByGear_Title' | translate }}">
|
<mat-tab label="{{ 'Summary_ByGear_Title' | translate }}">
|
||||||
<ng-template matTabContent>
|
<ng-template matTabContent>
|
||||||
<table mat-table [dataSource]="dsNbJumpByGear">
|
<table mat-table [dataSource]="dsNbJumpByGear">
|
||||||
<ng-container matColumnDef="label">
|
<ng-container matColumnDef="label">
|
||||||
<td mat-cell *matCellDef="let element">{{ element.label }}</td>
|
<td mat-cell *matCellDef="let element">
|
||||||
</ng-container>
|
{{ element.label }}
|
||||||
<ng-container matColumnDef="nb">
|
</td>
|
||||||
<td mat-cell *matCellDef="let element">{{ element.nb }}</td>
|
</ng-container>
|
||||||
</ng-container>
|
<ng-container matColumnDef="nb">
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
<td mat-cell *matCellDef="let element">
|
||||||
</table>
|
{{ element.nb }}
|
||||||
</ng-template>
|
</td>
|
||||||
</mat-tab>
|
</ng-container>
|
||||||
|
<tr
|
||||||
|
mat-row
|
||||||
|
*matRowDef="let row; columns: displayedColumns"
|
||||||
|
></tr>
|
||||||
|
</table>
|
||||||
|
</ng-template>
|
||||||
|
</mat-tab>
|
||||||
|
|
||||||
<mat-tab label="{{ 'Summary_ByJumpType_Title' | translate }}">
|
<mat-tab label="{{ 'Summary_ByJumpType_Title' | translate }}">
|
||||||
<ng-template matTabContent>
|
<ng-template matTabContent>
|
||||||
<table mat-table [dataSource]="dsNbJumpByType">
|
<table mat-table [dataSource]="dsNbJumpByType">
|
||||||
<ng-container matColumnDef="label">
|
<ng-container matColumnDef="label">
|
||||||
<td mat-cell *matCellDef="let element">{{ element.label }}</td>
|
<td mat-cell *matCellDef="let element">
|
||||||
</ng-container>
|
{{ element.label }}
|
||||||
<ng-container matColumnDef="nb">
|
</td>
|
||||||
<td mat-cell *matCellDef="let element">{{ element.nb }}</td>
|
</ng-container>
|
||||||
</ng-container>
|
<ng-container matColumnDef="nb">
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
<td mat-cell *matCellDef="let element">
|
||||||
</table>
|
{{ element.nb }}
|
||||||
</ng-template>
|
</td>
|
||||||
</mat-tab>
|
</ng-container>
|
||||||
|
<tr
|
||||||
|
mat-row
|
||||||
|
*matRowDef="let row; columns: displayedColumns"
|
||||||
|
></tr>
|
||||||
|
</table>
|
||||||
|
</ng-template>
|
||||||
|
</mat-tab>
|
||||||
|
|
||||||
<mat-tab label="{{ 'Summary_ByYear_Title' | translate }}">
|
<mat-tab label="{{ 'Summary_ByYear_Title' | translate }}">
|
||||||
<ng-template matTabContent>
|
<ng-template matTabContent>
|
||||||
<table mat-table [dataSource]="dsNbJumpByYear">
|
<table mat-table [dataSource]="dsNbJumpByYear">
|
||||||
<ng-container matColumnDef="label">
|
<ng-container matColumnDef="label">
|
||||||
<td mat-cell *matCellDef="let element">{{ element.label }}</td>
|
<td mat-cell *matCellDef="let element">
|
||||||
</ng-container>
|
{{ element.label }}
|
||||||
<ng-container matColumnDef="nb">
|
</td>
|
||||||
<td mat-cell *matCellDef="let element">{{ element.nb }}</td>
|
</ng-container>
|
||||||
</ng-container>
|
<ng-container matColumnDef="nb">
|
||||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
<td mat-cell *matCellDef="let element">
|
||||||
</table>
|
{{ element.nb }}
|
||||||
</ng-template>
|
</td>
|
||||||
</mat-tab>
|
</ng-container>
|
||||||
|
<tr
|
||||||
|
mat-row
|
||||||
|
*matRowDef="let row; columns: displayedColumns"
|
||||||
|
></tr>
|
||||||
|
</table>
|
||||||
|
</ng-template>
|
||||||
|
</mat-tab>
|
||||||
|
|
||||||
<mat-tab label="{{ 'Summary_ByYearByJumpType_Title' | translate }}">
|
<mat-tab label="{{ 'Summary_ByYearByJumpType_Title' | translate }}">
|
||||||
<ng-template matTabContent>
|
<ng-template matTabContent>
|
||||||
<div class="chart-container">
|
<div class="chart-container">
|
||||||
<canvas
|
<canvas
|
||||||
baseChart
|
baseChart
|
||||||
[data]="barChartData"
|
[data]="barChartData"
|
||||||
[options]="barChartOptions"
|
[options]="barChartOptions"
|
||||||
[plugins]="barChartPlugins"
|
[plugins]="barChartPlugins"
|
||||||
[legend]="barChartLegend"
|
[legend]="barChartLegend"
|
||||||
[type]="barChartType"
|
[type]="barChartType"
|
||||||
>
|
>
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</mat-tab>
|
</mat-tab>
|
||||||
</mat-tab-group>
|
</mat-tab-group>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,294 +11,297 @@ import { MatIconModule } from "@angular/material/icon";
|
|||||||
import { ServiceComm } from "../../services/service-comm.service";
|
import { ServiceComm } from "../../services/service-comm.service";
|
||||||
import { StatsService } from "../../services/stats.service";
|
import { StatsService } from "../../services/stats.service";
|
||||||
import {
|
import {
|
||||||
StatsByDzResp,
|
StatsByDzResp,
|
||||||
StatsByAircraftResp,
|
StatsByAircraftResp,
|
||||||
StatsByGearResp,
|
StatsByGearResp,
|
||||||
StatsByJumpTypeResp,
|
StatsByJumpTypeResp,
|
||||||
StatsByYearResp,
|
StatsByYearResp,
|
||||||
} from "../../models/stats";
|
} from "../../models/stats";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-summary",
|
selector: "app-summary",
|
||||||
templateUrl: "./summary.component.html",
|
templateUrl: "./summary.component.html",
|
||||||
styleUrls: ["./summary.component.css"],
|
styleUrls: ["./summary.component.css"],
|
||||||
imports: [
|
imports: [
|
||||||
MatTabsModule,
|
MatTabsModule,
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
BaseChartDirective,
|
BaseChartDirective,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
MatTableModule,
|
MatTableModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class SummaryComponent implements OnInit {
|
export class SummaryComponent implements OnInit {
|
||||||
public dsNbJumpByDz: MatTableDataSource<StatsByDzResp>;
|
public dsNbJumpByDz: MatTableDataSource<StatsByDzResp>;
|
||||||
public dsNbJumpByAircraft: MatTableDataSource<StatsByAircraftResp>;
|
public dsNbJumpByAircraft: MatTableDataSource<StatsByAircraftResp>;
|
||||||
public dsNbJumpByGear: MatTableDataSource<StatsByGearResp>;
|
public dsNbJumpByGear: MatTableDataSource<StatsByGearResp>;
|
||||||
public dsNbJumpByType: MatTableDataSource<StatsByJumpTypeResp>;
|
public dsNbJumpByType: MatTableDataSource<StatsByJumpTypeResp>;
|
||||||
public dsNbJumpByYear: MatTableDataSource<StatsByYearResp>;
|
public dsNbJumpByYear: MatTableDataSource<StatsByYearResp>;
|
||||||
public dsJumpForLastYearByDz: MatTableDataSource<StatsByDzResp>;
|
public dsJumpForLastYearByDz: MatTableDataSource<StatsByDzResp>;
|
||||||
public dsJumpForLastYearByJumpType: MatTableDataSource<StatsByJumpTypeResp>;
|
public dsJumpForLastYearByJumpType: MatTableDataSource<StatsByJumpTypeResp>;
|
||||||
public dsJumpForLastMonthByDz: MatTableDataSource<StatsByDzResp>;
|
public dsJumpForLastMonthByDz: MatTableDataSource<StatsByDzResp>;
|
||||||
public dsJumpForLastMonthByJumpType: MatTableDataSource<StatsByJumpTypeResp>;
|
public dsJumpForLastMonthByJumpType: MatTableDataSource<StatsByJumpTypeResp>;
|
||||||
public displayedColumns: Array<string> = ["label", "nb"];
|
public displayedColumns: Array<string> = ["label", "nb"];
|
||||||
public displayedColumnsByYearByJumpType: Array<string> = [
|
public displayedColumnsByYearByJumpType: Array<string> = [
|
||||||
"label",
|
"label",
|
||||||
"label2",
|
"label2",
|
||||||
"nb",
|
"nb",
|
||||||
];
|
];
|
||||||
|
|
||||||
public barChartLegend = true;
|
public barChartLegend = true;
|
||||||
public barChartPlugins: any = [];
|
public barChartPlugins: any = [];
|
||||||
public barChartData: ChartData<"line">;
|
public barChartData: ChartData<"line">;
|
||||||
public barChartOptions: ChartConfiguration["options"];
|
public barChartOptions: ChartConfiguration["options"];
|
||||||
public barChartType: ChartType;
|
public barChartType: ChartType;
|
||||||
private jumpTypeToColor: Map<string, string>;
|
private jumpTypeToColor: Map<string, string>;
|
||||||
|
|
||||||
public totalJumps: number;
|
public totalJumps: number;
|
||||||
public totalCutaways: number;
|
public totalCutaways: number;
|
||||||
public lastJump: string;
|
public lastJump: string;
|
||||||
@ViewChild(MatTabGroup) tabGroup: MatTabGroup;
|
@ViewChild(MatTabGroup) tabGroup: MatTabGroup;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private serviceApi: StatsService,
|
private serviceApi: StatsService,
|
||||||
private serviceComm: ServiceComm,
|
private serviceComm: ServiceComm,
|
||||||
private translateService: TranslateService,
|
private translateService: TranslateService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
||||||
if (data === true) {
|
if (data === true) {
|
||||||
|
this.updateTitle();
|
||||||
|
}
|
||||||
|
});
|
||||||
this.updateTitle();
|
this.updateTitle();
|
||||||
}
|
|
||||||
});
|
|
||||||
this.updateTitle();
|
|
||||||
|
|
||||||
this.serviceApi.getSimpleSummary().subscribe((data) => {
|
this.serviceApi.getSimpleSummary().subscribe((data) => {
|
||||||
this.totalJumps = data.totalJumps;
|
this.totalJumps = data.totalJumps;
|
||||||
this.totalCutaways = data.totalCutaways;
|
this.totalCutaways = data.totalCutaways;
|
||||||
|
|
||||||
const datepipe: DatePipe = new DatePipe("en-US");
|
const datepipe: DatePipe = new DatePipe("en-US");
|
||||||
let formattedDate = datepipe.transform(
|
let formattedDate = datepipe.transform(
|
||||||
data.lastJump.jumpDate,
|
data.lastJump.jumpDate,
|
||||||
"EEEE dd MMMM YYYY",
|
"EEEE dd MMMM yyyy",
|
||||||
);
|
);
|
||||||
this.lastJump = formattedDate + " (" + data.lastJump.dropZone.name + ")";
|
this.lastJump =
|
||||||
});
|
formattedDate + " (" + data.lastJump.dropZone.name + ")";
|
||||||
|
});
|
||||||
|
|
||||||
this.serviceApi.getStatsOfLastMonth().subscribe((data) => {
|
this.serviceApi.getStatsOfLastMonth().subscribe((data) => {
|
||||||
data.byDz.sort((a, b) => b.nb - a.nb);
|
data.byDz.sort((a, b) => b.nb - a.nb);
|
||||||
this.dsJumpForLastMonthByDz = new MatTableDataSource(data.byDz);
|
this.dsJumpForLastMonthByDz = new MatTableDataSource(data.byDz);
|
||||||
data.byJumpType.sort((a, b) => b.nb - a.nb);
|
data.byJumpType.sort((a, b) => b.nb - a.nb);
|
||||||
this.dsJumpForLastMonthByJumpType = new MatTableDataSource(
|
this.dsJumpForLastMonthByJumpType = new MatTableDataSource(
|
||||||
data.byJumpType,
|
data.byJumpType,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.chartConfig();
|
this.chartConfig();
|
||||||
}
|
|
||||||
|
|
||||||
public refreshStats() {
|
|
||||||
this.serviceApi.deleteAllCache();
|
|
||||||
this.tabGroup.selectedIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public onTabChanged(event: MatTabChangeEvent) {
|
|
||||||
switch (event.index) {
|
|
||||||
case 0:
|
|
||||||
this.statsLastMonth();
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
this.statsLastYear();
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
this.statsByDz();
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
this.statsByAircraft();
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
this.statsByGear();
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
this.statsByJumpType();
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
this.statsByYear();
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
this.statsByYearByJumpType();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private updateTitle() {
|
public refreshStats() {
|
||||||
this.translateService.get("Summary_Title").subscribe((data) => {
|
this.serviceApi.deleteAllCache();
|
||||||
this.serviceComm.updatedComponentTitle(data);
|
this.tabGroup.selectedIndex = 0;
|
||||||
});
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private chartConfig() {
|
public onTabChanged(event: MatTabChangeEvent) {
|
||||||
this.barChartType = "line";
|
switch (event.index) {
|
||||||
this.barChartOptions = {
|
case 0:
|
||||||
responsive: true,
|
this.statsLastMonth();
|
||||||
maintainAspectRatio: false,
|
break;
|
||||||
plugins: {
|
case 1:
|
||||||
legend: {
|
this.statsLastYear();
|
||||||
display: true,
|
break;
|
||||||
},
|
case 2:
|
||||||
colors: {
|
this.statsByDz();
|
||||||
forceOverride: false,
|
break;
|
||||||
},
|
case 3:
|
||||||
},
|
this.statsByAircraft();
|
||||||
interaction: {
|
break;
|
||||||
intersect: false,
|
case 4:
|
||||||
mode: "nearest",
|
this.statsByGear();
|
||||||
axis: "x",
|
break;
|
||||||
},
|
case 5:
|
||||||
scales: {
|
this.statsByJumpType();
|
||||||
x: {
|
break;
|
||||||
stacked: false,
|
case 6:
|
||||||
},
|
this.statsByYear();
|
||||||
y: {
|
break;
|
||||||
stacked: false,
|
case 7:
|
||||||
beginAtZero: true,
|
this.statsByYearByJumpType();
|
||||||
},
|
break;
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
this.jumpTypeToColor = new Map<string, string>([
|
|
||||||
["PAC", "#FFD700"],
|
|
||||||
["Solo", "#FFA500"],
|
|
||||||
["RW 3", "#40E0D0"],
|
|
||||||
["RW 4", "#008080"],
|
|
||||||
["RW 8", "#7FFFD4"],
|
|
||||||
["RW X", "#114556"],
|
|
||||||
["FreeFly", "#FFC0CB"],
|
|
||||||
["FreeStyle", "#FF91A4"],
|
|
||||||
["Track/Trace", "#87CEEB"],
|
|
||||||
["Canopy", "#228B22"],
|
|
||||||
["Landing accuracy", "#FF6347"],
|
|
||||||
["Wingsuit 1", "#E6E6FA"],
|
|
||||||
["Wingsuit 2", "#E0B0FF"],
|
|
||||||
["Wingsuit 3", "#9400D3"],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// #region Private methods to get stats
|
|
||||||
private statsByYearByJumpType() {
|
|
||||||
this.serviceApi.getStatsByYearByJumpType().subscribe((data) => {
|
|
||||||
data.sort((a, b) => a.label.localeCompare(b.label));
|
|
||||||
|
|
||||||
let firstYear: number = Number(data[0].label);
|
|
||||||
const now = new Date();
|
|
||||||
const currentYear = now.getFullYear();
|
|
||||||
const nbYears = currentYear - firstYear;
|
|
||||||
let listOfYears = new Array(nbYears).fill(null).map(() => firstYear++);
|
|
||||||
|
|
||||||
// Prepare the list of jump type with am empty array
|
|
||||||
let tmpResults = new Map<string, number[]>();
|
|
||||||
const listOfJumpType = [...new Set(data.map((obj) => obj.label2))];
|
|
||||||
listOfJumpType.forEach((type) => {
|
|
||||||
tmpResults.set(type, new Array(nbYears).fill(NaN));
|
|
||||||
});
|
|
||||||
|
|
||||||
for (let i = 0; i < listOfYears.length; i++) {
|
|
||||||
const year = listOfYears[i].toString();
|
|
||||||
|
|
||||||
let filteredStats = data.filter((d) => d.label == year);
|
|
||||||
|
|
||||||
if (filteredStats.length > 0) {
|
|
||||||
filteredStats.forEach((fs) => {
|
|
||||||
tmpResults.get(fs.label2)[i] = fs.nb;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const results: {
|
private updateTitle() {
|
||||||
label: string;
|
this.translateService.get("Summary_Title").subscribe((data) => {
|
||||||
data: number[];
|
this.serviceComm.updatedComponentTitle(data);
|
||||||
backgroundColor: string;
|
});
|
||||||
borderColor: string;
|
}
|
||||||
pointBackgroundColor: string;
|
|
||||||
fill: boolean;
|
private chartConfig() {
|
||||||
pointRadius: number;
|
this.barChartType = "line";
|
||||||
}[] = [];
|
this.barChartOptions = {
|
||||||
tmpResults.forEach((value, key) => {
|
responsive: true,
|
||||||
const color = this.jumpTypeToColor.get(key);
|
maintainAspectRatio: false,
|
||||||
let tmp = {
|
plugins: {
|
||||||
label: key,
|
legend: {
|
||||||
data: value,
|
display: true,
|
||||||
backgroundColor: color,
|
},
|
||||||
borderColor: color,
|
colors: {
|
||||||
pointBackgroundColor: color,
|
forceOverride: false,
|
||||||
fill: false,
|
},
|
||||||
pointRadius: 6,
|
},
|
||||||
|
interaction: {
|
||||||
|
intersect: false,
|
||||||
|
mode: "nearest",
|
||||||
|
axis: "x",
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
x: {
|
||||||
|
stacked: false,
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
stacked: false,
|
||||||
|
beginAtZero: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
results.push(tmp);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.barChartData = {
|
this.jumpTypeToColor = new Map<string, string>([
|
||||||
labels: listOfYears,
|
["PAC", "#FFD700"],
|
||||||
datasets: results,
|
["Solo", "#FFA500"],
|
||||||
};
|
["RW 3", "#40E0D0"],
|
||||||
});
|
["RW 4", "#008080"],
|
||||||
}
|
["RW 8", "#7FFFD4"],
|
||||||
|
["RW X", "#114556"],
|
||||||
|
["FreeFly", "#FFC0CB"],
|
||||||
|
["FreeStyle", "#FF91A4"],
|
||||||
|
["Track/Trace", "#87CEEB"],
|
||||||
|
["Canopy", "#228B22"],
|
||||||
|
["Landing accuracy", "#FF6347"],
|
||||||
|
["Wingsuit 1", "#E6E6FA"],
|
||||||
|
["Wingsuit 2", "#E0B0FF"],
|
||||||
|
["Wingsuit 3", "#9400D3"],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
private statsByYear() {
|
// #region Private methods to get stats
|
||||||
this.serviceApi.getStatsByYear().subscribe((data) => {
|
private statsByYearByJumpType() {
|
||||||
data.sort((a, b) => b.label.localeCompare(a.label));
|
this.serviceApi.getStatsByYearByJumpType().subscribe((data) => {
|
||||||
this.dsNbJumpByYear = new MatTableDataSource(data);
|
data.sort((a, b) => a.label.localeCompare(b.label));
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private statsByJumpType() {
|
let firstYear: number = Number(data[0].label);
|
||||||
this.serviceApi.getStatsByJumpType().subscribe((data) => {
|
const now = new Date();
|
||||||
data.sort((a, b) => b.nb - a.nb);
|
const currentYear = now.getFullYear();
|
||||||
this.dsNbJumpByType = new MatTableDataSource(data);
|
const nbYears = currentYear - firstYear;
|
||||||
});
|
let listOfYears = new Array(nbYears)
|
||||||
}
|
.fill(null)
|
||||||
|
.map(() => firstYear++);
|
||||||
|
|
||||||
private statsByGear() {
|
// Prepare the list of jump type with am empty array
|
||||||
this.serviceApi.getStatsByGear().subscribe((data) => {
|
let tmpResults = new Map<string, number[]>();
|
||||||
data.sort((a, b) => b.nb - a.nb);
|
const listOfJumpType = [...new Set(data.map((obj) => obj.label2))];
|
||||||
this.dsNbJumpByGear = new MatTableDataSource(data);
|
listOfJumpType.forEach((type) => {
|
||||||
});
|
tmpResults.set(type, new Array(nbYears).fill(NaN));
|
||||||
}
|
});
|
||||||
|
|
||||||
private statsByAircraft() {
|
for (let i = 0; i < listOfYears.length; i++) {
|
||||||
this.serviceApi.getStatsByAircraft().subscribe((data) => {
|
const year = listOfYears[i].toString();
|
||||||
data.sort((a, b) => b.nb - a.nb);
|
|
||||||
this.dsNbJumpByAircraft = new MatTableDataSource(data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private statsByDz() {
|
let filteredStats = data.filter((d) => d.label == year);
|
||||||
this.serviceApi.getStatsByDz().subscribe((data) => {
|
|
||||||
data.sort((a, b) => b.nb - a.nb);
|
|
||||||
this.dsNbJumpByDz = new MatTableDataSource(data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private statsLastYear() {
|
if (filteredStats.length > 0) {
|
||||||
this.serviceApi.getStatsOfLastYear().subscribe((data) => {
|
filteredStats.forEach((fs) => {
|
||||||
data.byDz.sort((a, b) => b.nb - a.nb);
|
tmpResults.get(fs.label2)[i] = fs.nb;
|
||||||
this.dsJumpForLastYearByDz = new MatTableDataSource(data.byDz);
|
});
|
||||||
data.byJumpType.sort((a, b) => b.nb - a.nb);
|
}
|
||||||
this.dsJumpForLastYearByJumpType = new MatTableDataSource(
|
}
|
||||||
data.byJumpType,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private statsLastMonth() {
|
const results: {
|
||||||
this.serviceApi.getStatsOfLastMonth().subscribe((data) => {
|
label: string;
|
||||||
data.byDz.sort((a, b) => b.nb - a.nb);
|
data: number[];
|
||||||
this.dsJumpForLastMonthByDz = new MatTableDataSource(data.byDz);
|
backgroundColor: string;
|
||||||
data.byJumpType.sort((a, b) => b.nb - a.nb);
|
borderColor: string;
|
||||||
this.dsJumpForLastMonthByJumpType = new MatTableDataSource(
|
pointBackgroundColor: string;
|
||||||
data.byJumpType,
|
fill: boolean;
|
||||||
);
|
pointRadius: number;
|
||||||
});
|
}[] = [];
|
||||||
}
|
tmpResults.forEach((value, key) => {
|
||||||
//#endregion
|
const color = this.jumpTypeToColor.get(key);
|
||||||
|
let tmp = {
|
||||||
|
label: key,
|
||||||
|
data: value,
|
||||||
|
backgroundColor: color,
|
||||||
|
borderColor: color,
|
||||||
|
pointBackgroundColor: color,
|
||||||
|
fill: false,
|
||||||
|
pointRadius: 6,
|
||||||
|
};
|
||||||
|
results.push(tmp);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.barChartData = {
|
||||||
|
labels: listOfYears,
|
||||||
|
datasets: results,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private statsByYear() {
|
||||||
|
this.serviceApi.getStatsByYear().subscribe((data) => {
|
||||||
|
data.sort((a, b) => b.label.localeCompare(a.label));
|
||||||
|
this.dsNbJumpByYear = new MatTableDataSource(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private statsByJumpType() {
|
||||||
|
this.serviceApi.getStatsByJumpType().subscribe((data) => {
|
||||||
|
data.sort((a, b) => b.nb - a.nb);
|
||||||
|
this.dsNbJumpByType = new MatTableDataSource(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private statsByGear() {
|
||||||
|
this.serviceApi.getStatsByGear().subscribe((data) => {
|
||||||
|
data.sort((a, b) => b.nb - a.nb);
|
||||||
|
this.dsNbJumpByGear = new MatTableDataSource(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private statsByAircraft() {
|
||||||
|
this.serviceApi.getStatsByAircraft().subscribe((data) => {
|
||||||
|
data.sort((a, b) => b.nb - a.nb);
|
||||||
|
this.dsNbJumpByAircraft = new MatTableDataSource(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private statsByDz() {
|
||||||
|
this.serviceApi.getStatsByDz().subscribe((data) => {
|
||||||
|
data.sort((a, b) => b.nb - a.nb);
|
||||||
|
this.dsNbJumpByDz = new MatTableDataSource(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private statsLastYear() {
|
||||||
|
this.serviceApi.getStatsOfLastYear().subscribe((data) => {
|
||||||
|
data.byDz.sort((a, b) => b.nb - a.nb);
|
||||||
|
this.dsJumpForLastYearByDz = new MatTableDataSource(data.byDz);
|
||||||
|
data.byJumpType.sort((a, b) => b.nb - a.nb);
|
||||||
|
this.dsJumpForLastYearByJumpType = new MatTableDataSource(
|
||||||
|
data.byJumpType,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private statsLastMonth() {
|
||||||
|
this.serviceApi.getStatsOfLastMonth().subscribe((data) => {
|
||||||
|
data.byDz.sort((a, b) => b.nb - a.nb);
|
||||||
|
this.dsJumpForLastMonthByDz = new MatTableDataSource(data.byDz);
|
||||||
|
data.byJumpType.sort((a, b) => b.nb - a.nb);
|
||||||
|
this.dsJumpForLastMonthByJumpType = new MatTableDataSource(
|
||||||
|
data.byJumpType,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
.content {
|
.content {
|
||||||
min-height: 90vh;
|
min-height: 90vh;
|
||||||
justify-content: left;
|
justify-content: left;
|
||||||
align-items: initial;
|
align-items: initial;
|
||||||
padding-top: 25px;
|
padding-top: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.containerFlex {
|
.containerFlex {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
.contentFlex {
|
.contentFlex {
|
||||||
flex: 45%;
|
flex: 45%;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,53 +1,70 @@
|
|||||||
<div class="content containerFlex">
|
<div class="content containerFlex">
|
||||||
<fieldset class="contentFlex">
|
<fieldset class="contentFlex">
|
||||||
<legend>Profile</legend>
|
<legend>Profile</legend>
|
||||||
<form [formGroup]="userForm" (ngSubmit)="onSubmit(userForm.value)">
|
<form [formGroup]="userForm" (ngSubmit)="onSubmit(userForm.value)">
|
||||||
<p>
|
<p>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>Login</mat-label>
|
<mat-label>{{ "UserProfile_Login" | translate }}</mat-label>
|
||||||
<input matInput type="text" formControlName="login" readonly />
|
<input
|
||||||
</mat-form-field>
|
matInput
|
||||||
</p>
|
type="text"
|
||||||
<p>
|
formControlName="login"
|
||||||
<mat-form-field>
|
readonly
|
||||||
<mat-label>Firstname</mat-label>
|
/>
|
||||||
<input matInput type="text" formControlName="firstName" />
|
</mat-form-field>
|
||||||
</mat-form-field>
|
</p>
|
||||||
</p>
|
<p>
|
||||||
<p>
|
<mat-form-field>
|
||||||
<mat-form-field>
|
<mat-label>{{
|
||||||
<mat-label>Lastname</mat-label>
|
"UserProfile_Firstname" | translate
|
||||||
<input matInput type="text" formControlName="lastName" />
|
}}</mat-label>
|
||||||
</mat-form-field>
|
<input matInput type="text" formControlName="firstName" />
|
||||||
</p>
|
</mat-form-field>
|
||||||
<p>
|
</p>
|
||||||
<mat-form-field>
|
<p>
|
||||||
<mat-label>E-mail</mat-label>
|
<mat-form-field>
|
||||||
<input matInput type="text" formControlName="email" />
|
<mat-label>{{
|
||||||
</mat-form-field>
|
"UserProfile_Lastname" | translate
|
||||||
</p>
|
}}</mat-label>
|
||||||
|
<input matInput type="text" formControlName="lastName" />
|
||||||
|
</mat-form-field>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>{{ "UserProfile_Mail" | translate }}</mat-label>
|
||||||
|
<input matInput type="text" formControlName="email" />
|
||||||
|
</mat-form-field>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>Current password</mat-label>
|
<mat-label>{{
|
||||||
<input matInput type="text" formControlName="currentPassword" />
|
"UserProfile_CurrentPassword" | translate
|
||||||
</mat-form-field>
|
}}</mat-label>
|
||||||
</p>
|
<input
|
||||||
<p>
|
matInput
|
||||||
<mat-form-field>
|
type="text"
|
||||||
<mat-label>New password</mat-label>
|
formControlName="currentPassword"
|
||||||
<input matInput type="text" formControlName="newPassword" />
|
/>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>{{
|
||||||
|
"UserProfile_NewPassword" | translate
|
||||||
|
}}</mat-label>
|
||||||
|
<input matInput type="text" formControlName="newPassword" />
|
||||||
|
</mat-form-field>
|
||||||
|
</p>
|
||||||
|
|
||||||
<button type="submit" mat-raised-button color="accent">
|
<button type="submit" mat-raised-button color="accent">
|
||||||
Update my profile
|
{{ "UserProfile_Update" | translate }}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<fieldset class="contentFlex">
|
<fieldset class="contentFlex">
|
||||||
<legend>Images</legend>
|
<legend>Images</legend>
|
||||||
<app-list-of-images></app-list-of-images>
|
<app-list-of-images></app-list-of-images>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import { Component, OnInit } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
import {
|
import {
|
||||||
FormGroup,
|
FormGroup,
|
||||||
FormControl,
|
FormControl,
|
||||||
Validators,
|
Validators,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
} from "@angular/forms";
|
} from "@angular/forms";
|
||||||
import { MatLabel, MatFormFieldModule } from "@angular/material/form-field";
|
import { MatLabel, MatFormFieldModule } from "@angular/material/form-field";
|
||||||
import {
|
import {
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
TranslatePipe,
|
TranslatePipe,
|
||||||
TranslateService,
|
TranslateService,
|
||||||
} from "@ngx-translate/core";
|
} from "@ngx-translate/core";
|
||||||
import { MatInputModule } from "@angular/material/input";
|
import { MatInputModule } from "@angular/material/input";
|
||||||
import { MatButtonModule } from "@angular/material/button";
|
import { MatButtonModule } from "@angular/material/button";
|
||||||
@@ -19,137 +19,138 @@ import { ListOfImagesComponent } from "../list-of-images/list-of-images.componen
|
|||||||
import { ServiceComm } from "../../services/service-comm.service";
|
import { ServiceComm } from "../../services/service-comm.service";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-user-profile",
|
selector: "app-user-profile",
|
||||||
templateUrl: "./user-profile.component.html",
|
templateUrl: "./user-profile.component.html",
|
||||||
styleUrls: ["./user-profile.component.css"],
|
styleUrls: ["./user-profile.component.css"],
|
||||||
imports: [
|
imports: [
|
||||||
ListOfImagesComponent,
|
ListOfImagesComponent,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
MatLabel,
|
MatLabel,
|
||||||
MatFormFieldModule,
|
MatFormFieldModule,
|
||||||
MatInputModule,
|
MatInputModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
],
|
TranslatePipe,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
export class UserProfileComponent implements OnInit {
|
export class UserProfileComponent implements OnInit {
|
||||||
public userForm: FormGroup;
|
public userForm: FormGroup;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private authenticationService: AuthenticationService,
|
private authenticationService: AuthenticationService,
|
||||||
private translateService: TranslateService,
|
private translateService: TranslateService,
|
||||||
private serviceComm: ServiceComm,
|
private serviceComm: ServiceComm,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
||||||
if (data === true) {
|
if (data === true) {
|
||||||
|
this.updateTitle();
|
||||||
|
}
|
||||||
|
});
|
||||||
this.updateTitle();
|
this.updateTitle();
|
||||||
}
|
|
||||||
});
|
|
||||||
this.updateTitle();
|
|
||||||
|
|
||||||
const currentUser = this.authenticationService.currentUserValue;
|
const currentUser = this.authenticationService.currentUserValue;
|
||||||
|
|
||||||
this.userForm = new FormGroup(
|
this.userForm = new FormGroup(
|
||||||
{
|
{
|
||||||
login: new FormControl(currentUser.login, Validators.required),
|
login: new FormControl(currentUser.login, Validators.required),
|
||||||
firstName: new FormControl(currentUser.firstName, [
|
firstName: new FormControl(currentUser.firstName, [
|
||||||
Validators.required,
|
Validators.required,
|
||||||
Validators.minLength(3),
|
Validators.minLength(3),
|
||||||
]),
|
]),
|
||||||
lastName: new FormControl(currentUser.lastName, [
|
lastName: new FormControl(currentUser.lastName, [
|
||||||
Validators.required,
|
Validators.required,
|
||||||
Validators.minLength(3),
|
Validators.minLength(3),
|
||||||
]),
|
]),
|
||||||
email: new FormControl(currentUser.email, [
|
email: new FormControl(currentUser.email, [
|
||||||
Validators.required,
|
Validators.required,
|
||||||
Validators.email,
|
Validators.email,
|
||||||
]),
|
]),
|
||||||
currentPassword: new FormControl(
|
currentPassword: new FormControl(
|
||||||
"",
|
"",
|
||||||
Validators.pattern("^[A-Za-z0-9_-]{8,15}$"),
|
Validators.pattern("^[A-Za-z0-9_-]{8,15}$"),
|
||||||
),
|
),
|
||||||
newPassword: new FormControl(
|
newPassword: new FormControl(
|
||||||
"",
|
"",
|
||||||
Validators.pattern("^[A-Za-z0-9_-]{8,15}$"),
|
Validators.pattern("^[A-Za-z0-9_-]{8,15}$"),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{ updateOn: "blur" },
|
{ updateOn: "blur" },
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit(formData) {
|
|
||||||
if (this.userForm.invalid) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// const updatedUser = new User();
|
onSubmit(formData) {
|
||||||
// updatedUser.firstName = formData.firstName;
|
if (this.userForm.invalid) {
|
||||||
// updatedUser.lastName = formData.lastName;
|
return;
|
||||||
// updatedUser.email = formData.email;
|
}
|
||||||
|
|
||||||
// this.authenticationService.update(updatedUser);
|
// const updatedUser = new User();
|
||||||
}
|
// updatedUser.firstName = formData.firstName;
|
||||||
|
// updatedUser.lastName = formData.lastName;
|
||||||
|
// updatedUser.email = formData.email;
|
||||||
|
|
||||||
private calculTailleVoile() {
|
// this.authenticationService.update(updatedUser);
|
||||||
let tailleVoile = new Map<string, Array<number>>();
|
}
|
||||||
tailleVoile.set("60", [175, 161, 147, 133, 124, 115, 107, 97, 89]);
|
|
||||||
tailleVoile.set("61", [178, 163, 149, 135, 126, 116, 108, 98, 90]);
|
|
||||||
tailleVoile.set("62", [180, 166, 151, 137, 127, 118, 109, 99, 91]);
|
|
||||||
tailleVoile.set("63", [183, 168, 153, 138, 129, 119, 111, 100, 91]);
|
|
||||||
tailleVoile.set("64", [185, 170, 155, 140, 130, 121, 112, 101, 92]);
|
|
||||||
tailleVoile.set("65", [188, 173, 157, 142, 132, 122, 113, 102, 93]);
|
|
||||||
tailleVoile.set("66", [190, 175, 159, 144, 134, 123, 114, 103, 94]);
|
|
||||||
tailleVoile.set("67", [193, 177, 161, 146, 135, 125, 116, 104, 94]);
|
|
||||||
tailleVoile.set("68", [195, 179, 164, 147, 137, 126, 117, 105, 95]);
|
|
||||||
tailleVoile.set("69", [198, 182, 166, 149, 138, 128, 118, 106, 96]);
|
|
||||||
tailleVoile.set("70", [200, 184, 168, 151, 140, 129, 119, 107, 96]);
|
|
||||||
tailleVoile.set("71", [203, 186, 170, 153, 142, 130, 120, 107, 97]);
|
|
||||||
tailleVoile.set("72", [205, 189, 172, 155, 143, 132, 121, 108, 98]);
|
|
||||||
tailleVoile.set("73", [208, 191, 174, 156, 145, 133, 123, 109, 99]);
|
|
||||||
tailleVoile.set("74", [210, 193, 176, 158, 146, 134, 124, 110, 99]);
|
|
||||||
tailleVoile.set("75", [213, 196, 178, 160, 148, 136, 125, 111, 100]);
|
|
||||||
tailleVoile.set("76", [215, 198, 180, 162, 150, 137, 126, 112, 101]);
|
|
||||||
tailleVoile.set("77", [218, 200, 182, 163, 151, 139, 127, 113, 101]);
|
|
||||||
tailleVoile.set("78", [220, 202, 184, 165, 153, 140, 128, 114, 102]);
|
|
||||||
tailleVoile.set("79", [223, 205, 186, 167, 154, 141, 129, 115, 103]);
|
|
||||||
tailleVoile.set("80", [225, 207, 188, 169, 156, 143, 131, 115, 103]);
|
|
||||||
tailleVoile.set("81", [228, 209, 190, 170, 157, 144, 132, 116, 104]);
|
|
||||||
tailleVoile.set("82", [230, 212, 192, 172, 159, 145, 133, 117, 104]);
|
|
||||||
tailleVoile.set("83", [233, 214, 194, 174, 160, 146, 134, 118, 105]);
|
|
||||||
tailleVoile.set("84", [235, 216, 196, 176, 162, 148, 135, 119, 106]);
|
|
||||||
tailleVoile.set("85", [238, 219, 198, 177, 163, 149, 136, 120, 106]);
|
|
||||||
tailleVoile.set("86", [240, 221, 201, 179, 165, 150, 137, 120, 107]);
|
|
||||||
tailleVoile.set("87", [243, 223, 203, 181, 166, 152, 138, 121, 108]);
|
|
||||||
tailleVoile.set("88", [245, 225, 205, 183, 168, 153, 139, 122, 108]);
|
|
||||||
tailleVoile.set("89", [248, 228, 207, 184, 170, 154, 140, 123, 109]);
|
|
||||||
tailleVoile.set("90", [250, 230, 209, 186, 171, 156, 141, 124, 109]);
|
|
||||||
tailleVoile.set("91", [253, 232, 211, 188, 173, 157, 143, 124, 110]);
|
|
||||||
tailleVoile.set("92", [255, 235, 213, 190, 174, 158, 144, 125, 110]);
|
|
||||||
tailleVoile.set("93", [258, 237, 215, 191, 176, 159, 145, 126, 111]);
|
|
||||||
tailleVoile.set("94", [260, 239, 217, 193, 177, 161, 146, 127, 112]);
|
|
||||||
tailleVoile.set("95", [263, 242, 219, 195, 179, 162, 147, 128, 112]);
|
|
||||||
tailleVoile.set("96", [265, 244, 221, 197, 180, 163, 148, 128, 113]);
|
|
||||||
tailleVoile.set("97", [268, 246, 223, 198, 182, 164, 149, 129, 113]);
|
|
||||||
tailleVoile.set("98", [270, 248, 225, 200, 183, 166, 150, 130, 114]);
|
|
||||||
tailleVoile.set("99", [273, 251, 227, 202, 185, 167, 151, 131, 114]);
|
|
||||||
tailleVoile.set("100", [275, 253, 229, 203, 186, 168, 152, 131, 115]);
|
|
||||||
tailleVoile.set("101", [278, 255, 231, 205, 188, 169, 153, 132, 115]);
|
|
||||||
tailleVoile.set("102", [280, 258, 233, 207, 189, 171, 154, 133, 116]);
|
|
||||||
tailleVoile.set("103", [283, 260, 235, 209, 190, 172, 155, 134, 116]);
|
|
||||||
tailleVoile.set("104", [285, 262, 237, 210, 192, 173, 156, 134, 117]);
|
|
||||||
tailleVoile.set("105", [288, 265, 239, 212, 193, 174, 157, 135, 118]);
|
|
||||||
tailleVoile.set("106", [290, 267, 241, 214, 195, 175, 158, 136, 118]);
|
|
||||||
tailleVoile.set("107", [293, 269, 243, 215, 196, 177, 159, 136, 119]);
|
|
||||||
tailleVoile.set("108", [295, 271, 245, 217, 198, 178, 160, 137, 119]);
|
|
||||||
tailleVoile.set("109", [298, 274, 247, 219, 199, 179, 161, 138, 120]);
|
|
||||||
tailleVoile.set("110", [300, 276, 249, 220, 201, 180, 162, 138, 120]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private updateTitle() {
|
private calculTailleVoile() {
|
||||||
this.translateService.get("UserProfile_Title").subscribe((data) => {
|
let tailleVoile = new Map<string, Array<number>>();
|
||||||
this.serviceComm.updatedComponentTitle(data);
|
tailleVoile.set("60", [175, 161, 147, 133, 124, 115, 107, 97, 89]);
|
||||||
});
|
tailleVoile.set("61", [178, 163, 149, 135, 126, 116, 108, 98, 90]);
|
||||||
}
|
tailleVoile.set("62", [180, 166, 151, 137, 127, 118, 109, 99, 91]);
|
||||||
|
tailleVoile.set("63", [183, 168, 153, 138, 129, 119, 111, 100, 91]);
|
||||||
|
tailleVoile.set("64", [185, 170, 155, 140, 130, 121, 112, 101, 92]);
|
||||||
|
tailleVoile.set("65", [188, 173, 157, 142, 132, 122, 113, 102, 93]);
|
||||||
|
tailleVoile.set("66", [190, 175, 159, 144, 134, 123, 114, 103, 94]);
|
||||||
|
tailleVoile.set("67", [193, 177, 161, 146, 135, 125, 116, 104, 94]);
|
||||||
|
tailleVoile.set("68", [195, 179, 164, 147, 137, 126, 117, 105, 95]);
|
||||||
|
tailleVoile.set("69", [198, 182, 166, 149, 138, 128, 118, 106, 96]);
|
||||||
|
tailleVoile.set("70", [200, 184, 168, 151, 140, 129, 119, 107, 96]);
|
||||||
|
tailleVoile.set("71", [203, 186, 170, 153, 142, 130, 120, 107, 97]);
|
||||||
|
tailleVoile.set("72", [205, 189, 172, 155, 143, 132, 121, 108, 98]);
|
||||||
|
tailleVoile.set("73", [208, 191, 174, 156, 145, 133, 123, 109, 99]);
|
||||||
|
tailleVoile.set("74", [210, 193, 176, 158, 146, 134, 124, 110, 99]);
|
||||||
|
tailleVoile.set("75", [213, 196, 178, 160, 148, 136, 125, 111, 100]);
|
||||||
|
tailleVoile.set("76", [215, 198, 180, 162, 150, 137, 126, 112, 101]);
|
||||||
|
tailleVoile.set("77", [218, 200, 182, 163, 151, 139, 127, 113, 101]);
|
||||||
|
tailleVoile.set("78", [220, 202, 184, 165, 153, 140, 128, 114, 102]);
|
||||||
|
tailleVoile.set("79", [223, 205, 186, 167, 154, 141, 129, 115, 103]);
|
||||||
|
tailleVoile.set("80", [225, 207, 188, 169, 156, 143, 131, 115, 103]);
|
||||||
|
tailleVoile.set("81", [228, 209, 190, 170, 157, 144, 132, 116, 104]);
|
||||||
|
tailleVoile.set("82", [230, 212, 192, 172, 159, 145, 133, 117, 104]);
|
||||||
|
tailleVoile.set("83", [233, 214, 194, 174, 160, 146, 134, 118, 105]);
|
||||||
|
tailleVoile.set("84", [235, 216, 196, 176, 162, 148, 135, 119, 106]);
|
||||||
|
tailleVoile.set("85", [238, 219, 198, 177, 163, 149, 136, 120, 106]);
|
||||||
|
tailleVoile.set("86", [240, 221, 201, 179, 165, 150, 137, 120, 107]);
|
||||||
|
tailleVoile.set("87", [243, 223, 203, 181, 166, 152, 138, 121, 108]);
|
||||||
|
tailleVoile.set("88", [245, 225, 205, 183, 168, 153, 139, 122, 108]);
|
||||||
|
tailleVoile.set("89", [248, 228, 207, 184, 170, 154, 140, 123, 109]);
|
||||||
|
tailleVoile.set("90", [250, 230, 209, 186, 171, 156, 141, 124, 109]);
|
||||||
|
tailleVoile.set("91", [253, 232, 211, 188, 173, 157, 143, 124, 110]);
|
||||||
|
tailleVoile.set("92", [255, 235, 213, 190, 174, 158, 144, 125, 110]);
|
||||||
|
tailleVoile.set("93", [258, 237, 215, 191, 176, 159, 145, 126, 111]);
|
||||||
|
tailleVoile.set("94", [260, 239, 217, 193, 177, 161, 146, 127, 112]);
|
||||||
|
tailleVoile.set("95", [263, 242, 219, 195, 179, 162, 147, 128, 112]);
|
||||||
|
tailleVoile.set("96", [265, 244, 221, 197, 180, 163, 148, 128, 113]);
|
||||||
|
tailleVoile.set("97", [268, 246, 223, 198, 182, 164, 149, 129, 113]);
|
||||||
|
tailleVoile.set("98", [270, 248, 225, 200, 183, 166, 150, 130, 114]);
|
||||||
|
tailleVoile.set("99", [273, 251, 227, 202, 185, 167, 151, 131, 114]);
|
||||||
|
tailleVoile.set("100", [275, 253, 229, 203, 186, 168, 152, 131, 115]);
|
||||||
|
tailleVoile.set("101", [278, 255, 231, 205, 188, 169, 153, 132, 115]);
|
||||||
|
tailleVoile.set("102", [280, 258, 233, 207, 189, 171, 154, 133, 116]);
|
||||||
|
tailleVoile.set("103", [283, 260, 235, 209, 190, 172, 155, 134, 116]);
|
||||||
|
tailleVoile.set("104", [285, 262, 237, 210, 192, 173, 156, 134, 117]);
|
||||||
|
tailleVoile.set("105", [288, 265, 239, 212, 193, 174, 157, 135, 118]);
|
||||||
|
tailleVoile.set("106", [290, 267, 241, 214, 195, 175, 158, 136, 118]);
|
||||||
|
tailleVoile.set("107", [293, 269, 243, 215, 196, 177, 159, 136, 119]);
|
||||||
|
tailleVoile.set("108", [295, 271, 245, 217, 198, 178, 160, 137, 119]);
|
||||||
|
tailleVoile.set("109", [298, 274, 247, 219, 199, 179, 161, 138, 120]);
|
||||||
|
tailleVoile.set("110", [300, 276, 249, 220, 201, 180, 162, 138, 120]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateTitle() {
|
||||||
|
this.translateService.get("UserProfile_Title").subscribe((data) => {
|
||||||
|
this.serviceComm.updatedComponentTitle(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,139 +1,147 @@
|
|||||||
{
|
{
|
||||||
"Login_Title": "Login to the Skydive log",
|
"Login_Title": "Login to the Skydive log",
|
||||||
"Login_Tab_CreateUser": "Create and login a user",
|
"Login_Tab_CreateUser": "Create and login a user",
|
||||||
"Login_Tab_WithUser": "Login with a user",
|
"Login_Tab_WithUser": "Login with a user",
|
||||||
|
|
||||||
"LoginUser_BtnLogin": "Login",
|
"LoginUser_BtnLogin": "Login",
|
||||||
"LoginUser_PasswordPattern": "The pattern of the password ([A-Za-z0-9_-] {{ '{' }}8,15{{ '}' }})",
|
"LoginUser_PasswordPattern": "The pattern of the password ([A-Za-z0-9_-] {{ '{' }}8,15{{ '}' }})",
|
||||||
"LoginUser_PasswordRequired": "Password is required",
|
"LoginUser_PasswordRequired": "Password is required",
|
||||||
"LoginUser_Password": "Password",
|
"LoginUser_Password": "Password",
|
||||||
"LoginUser_Username": "Username",
|
"LoginUser_Username": "Username",
|
||||||
"LoginUser_UsernamePattern": "Username must have min 3 characters",
|
"LoginUser_UsernamePattern": "Username must have min 3 characters",
|
||||||
"LoginUser_UsernameRequired": "Username is required",
|
"LoginUser_UsernameRequired": "Username is required",
|
||||||
|
|
||||||
"LoginCreateUser_Firstname": "Firstname",
|
"CreateUser_Firstname": "Firstname",
|
||||||
"LoginCreateUser_FirstnameRequired": "Firstname is required",
|
"CreateUser_FirstnameRequired": "Firstname is required",
|
||||||
"LoginCreateUser_FirstnamePattern": "Firstname must have min 3 characters",
|
"CreateUser_FirstnamePattern": "Firstname must have min 3 characters",
|
||||||
"LoginCreateUser_Lastname": "Lastname",
|
"CreateUser_Lastname": "Lastname",
|
||||||
"LoginCreateUser_LastnameRequired": "Lastname is required",
|
"CreateUser_LastnameRequired": "Lastname is required",
|
||||||
"LoginCreateUser_LastnamePattern": "Lastname must have min 3 characters",
|
"CreateUser_LastnamePattern": "Lastname must have min 3 characters",
|
||||||
"LoginCreateUser_Email": "E-mail",
|
"CreateUser_Email": "E-mail",
|
||||||
"LoginCreateUser_EmailRequired": "E-mail is required",
|
"CreateUser_EmailRequired": "E-mail is required",
|
||||||
"LoginCreateUser_EmailPattern": "It's not a e-mail",
|
"CreateUser_EmailPattern": "It's not a e-mail",
|
||||||
"LoginCreateUser_Username": "Username",
|
"CreateUser_Username": "Username",
|
||||||
"LoginCreateUser_UsernameRequired": "Username is required",
|
"CreateUser_UsernameRequired": "Username is required",
|
||||||
"LoginCreateUser_UsernamePattern": "Username must have min 3 characters",
|
"CreateUser_UsernamePattern": "Username must have min 3 characters",
|
||||||
"LoginCreateUser_Password": "Password",
|
"CreateUser_Password": "Password",
|
||||||
"LoginCreateUser_PasswordRequired": "Password is required",
|
"CreateUser_PasswordRequired": "Password is required",
|
||||||
"LoginCreateUser_PasswordPattern": "The pattern of the password ([A-Za-z0-9_-|/]{{ '{' }}8,15{{ '}' }})",
|
"CreateUser_PasswordPattern": "The pattern of the password ([A-Za-z0-9_-|/]{{ '{' }}8,15{{ '}' }})",
|
||||||
"LoginCreateUser_BtnLogin": "Create user and login",
|
"CreateUser_BtnLogin": "Create user and login",
|
||||||
|
|
||||||
"Default_Title": "Home",
|
"Default_Title": "Home",
|
||||||
"ListDz_Title": "List of DZs",
|
"ListDz_Title": "List of DZs",
|
||||||
"Summary_Title": "Summary",
|
"Summary_Title": "Summary",
|
||||||
"NewJump_Title": "New jumps",
|
"NewJump_Title": "New jumps",
|
||||||
"ListJumps_Title": "List of jumps",
|
"ListJumps_Title": "List of jumps",
|
||||||
"ListJumpTypes_Title": "List of jump types",
|
"ListJumpTypes_Title": "List of jump types",
|
||||||
"ListGears_Title": "List of gears",
|
"ListGears_Title": "List of gears",
|
||||||
"ListAircrafts_Title": "List of aircrafts",
|
"ListAircrafts_Title": "List of aircrafts",
|
||||||
"NewTunnelFlight_Title": "New tunnel flights",
|
"NewTunnelFlight_Title": "New tunnel flights",
|
||||||
"ListTunnelFlight_Title": "List of hours of tunnel",
|
"ListTunnelFlight_Title": "List of hours of tunnel",
|
||||||
"UserProfile_Title": "User profile",
|
"UserProfile_Title": "User profile",
|
||||||
"NewJumpType_Title": "New jmp type",
|
"NewJumpType_Title": "New jmp type",
|
||||||
"NewGear_Title": "New gear",
|
"NewGear_Title": "New gear",
|
||||||
"NewDz_Title": "New drop zone",
|
"NewDz_Title": "New drop zone",
|
||||||
"NewAircraft_Title": "New aircraft",
|
"NewAircraft_Title": "New aircraft",
|
||||||
|
|
||||||
"App_Footer": "Web software to log your skydive jumps - v",
|
"App_Footer": "Web software to log your skydive jumps - v",
|
||||||
"App_Nav_Summary": "Summary",
|
"App_Nav_Summary": "Summary",
|
||||||
"App_Nav_Jumps": "List of jumps",
|
"App_Nav_Jumps": "List of jumps",
|
||||||
"App_Nav_NewJump": "Add a new jump",
|
"App_Nav_NewJump": "Add a new jump",
|
||||||
"App_Nav_Dzs": "List of DZs",
|
"App_Nav_Dzs": "List of DZs",
|
||||||
"App_Nav_Aircrafts": "List of aircrafts",
|
"App_Nav_Aircrafts": "List of aircrafts",
|
||||||
"App_Nav_JumpTypes": "List of jump types",
|
"App_Nav_JumpTypes": "List of jump types",
|
||||||
"App_Nav_Gears": "List of gears",
|
"App_Nav_Gears": "List of gears",
|
||||||
"App_Nav_Logout": "Logout",
|
"App_Nav_Logout": "Logout",
|
||||||
"App_Nav_NewTunnelFlight": "Add tunnel time",
|
"App_Nav_NewTunnelFlight": "Add tunnel time",
|
||||||
"App_Nav_TunnelFlights": "The tunnel flights",
|
"App_Nav_TunnelFlights": "The tunnel flights",
|
||||||
|
|
||||||
"ListAircrafts_Add": "Add a aircraft",
|
"ListAircrafts_Add": "Add a aircraft",
|
||||||
"ListAircrafts_Header_Id": "ID",
|
"ListAircrafts_Header_Id": "ID",
|
||||||
"ListAircrafts_Header_Name": "Name",
|
"ListAircrafts_Header_Name": "Name",
|
||||||
"ListAircrafts_Header_Image": "Image",
|
"ListAircrafts_Header_Image": "Image",
|
||||||
|
|
||||||
"ListGears_Add": "Add a gear",
|
"ListGears_Add": "Add a gear",
|
||||||
"ListGears_Header_Id": "ID",
|
"ListGears_Header_Id": "ID",
|
||||||
"ListGears_Header_Name": "Name",
|
"ListGears_Header_Name": "Name",
|
||||||
"ListGears_Header_Manufacturer": "Manufacturer",
|
"ListGears_Header_Manufacturer": "Manufacturer",
|
||||||
"ListGears_Header_CanopySize": "Canopy size",
|
"ListGears_Header_CanopySize": "Canopy size",
|
||||||
"ListGears_Header_Aad": "AAD system",
|
"ListGears_Header_Aad": "AAD system",
|
||||||
"ListGears_Header_Main": "Main canopy",
|
"ListGears_Header_Main": "Main canopy",
|
||||||
"ListGears_Header_Reserve": "Reserve canopy",
|
"ListGears_Header_Reserve": "Reserve canopy",
|
||||||
|
|
||||||
"ListJumpType_Add": "Add a jump type",
|
"ListJumpType_Add": "Add a jump type",
|
||||||
"ListJumpType_Header_Id": "ID",
|
"ListJumpType_Header_Id": "ID",
|
||||||
"ListJumpType_Header_Name": "Name",
|
"ListJumpType_Header_Name": "Name",
|
||||||
|
|
||||||
"ListJump_Add": "Add jumps",
|
"ListJump_Add": "Add jumps",
|
||||||
"ListJump_Header_Num": "Num",
|
"ListJump_Header_Num": "Num",
|
||||||
"ListJump_Header_Date": "Date",
|
"ListJump_Header_Date": "Date",
|
||||||
"ListJump_Header_JumpType": "Jump Type",
|
"ListJump_Header_JumpType": "Jump Type",
|
||||||
"ListJump_Header_Aircraft": "Aircraft",
|
"ListJump_Header_Aircraft": "Aircraft",
|
||||||
"ListJump_Header_Dz": "Drop Zone",
|
"ListJump_Header_Dz": "Drop Zone",
|
||||||
"ListJump_Header_Gear": "Gear",
|
"ListJump_Header_Gear": "Gear",
|
||||||
|
|
||||||
"ListDz_Add": "Add a drop zone",
|
"ListDz_Add": "Add a drop zone",
|
||||||
"ListDz_Header_ID": "ID",
|
"ListDz_Header_ID": "ID",
|
||||||
"ListDz_Header_Name": "Name",
|
"ListDz_Header_Name": "Name",
|
||||||
"ListDz_Header_Address": "Address",
|
"ListDz_Header_Address": "Address",
|
||||||
"ListDz_Header_Type": "Type",
|
"ListDz_Header_Type": "Type",
|
||||||
"ListDz_Filter": "Filter",
|
"ListDz_Filter": "Filter",
|
||||||
"ListDz_Filter_PlaceHolder": "Filter on the name or address of center",
|
"ListDz_Filter_PlaceHolder": "Filter on the name or address of center",
|
||||||
|
|
||||||
"Summary_TotalJumps": "Total jumps",
|
"Summary_TotalJumps": "Total jumps",
|
||||||
"Summary_TotalCutaways": "Total cutaways",
|
"Summary_TotalCutaways": "Total cutaways",
|
||||||
"Summary_LastJump": "Last jump",
|
"Summary_LastJump": "Last jump",
|
||||||
"Summary_Refresh": "Refresh",
|
"Summary_Refresh": "Refresh",
|
||||||
"Summary_LastMonth_Title": "Jumps in the last month",
|
"Summary_LastMonth_Title": "Jumps in the last month",
|
||||||
"Summary_LastMonth_ByDz": "By DZ",
|
"Summary_LastMonth_ByDz": "By DZ",
|
||||||
"Summary_LastMonth_ByJumpType": "By jump type",
|
"Summary_LastMonth_ByJumpType": "By jump type",
|
||||||
"Summary_LastYear_Title": "Jumps in the last year",
|
"Summary_LastYear_Title": "Jumps in the last year",
|
||||||
"Summary_LastYear_ByDz": "By DZ",
|
"Summary_LastYear_ByDz": "By DZ",
|
||||||
"Summary_LastYear_ByJumpType": "By jump type",
|
"Summary_LastYear_ByJumpType": "By jump type",
|
||||||
"Summary_ByDz_Title": "By DZ",
|
"Summary_ByDz_Title": "By DZ",
|
||||||
"Summary_ByAircraft_Title": "By aircraft",
|
"Summary_ByAircraft_Title": "By aircraft",
|
||||||
"Summary_ByGear_Title": "By gear",
|
"Summary_ByGear_Title": "By gear",
|
||||||
"Summary_ByJumpType_Title": "By jump type",
|
"Summary_ByJumpType_Title": "By jump type",
|
||||||
"Summary_ByYear_Title": "By year",
|
"Summary_ByYear_Title": "By year",
|
||||||
"Summary_ByYearByJumpType_Title": "By year and by type",
|
"Summary_ByYearByJumpType_Title": "By year and by type",
|
||||||
|
|
||||||
"NewJump_GoToJump": "View the jumps",
|
"NewJump_GoToJump": "View the jumps",
|
||||||
"NewJump_ResetForm": "Reset form after adding",
|
"NewJump_ResetForm": "Reset form after adding",
|
||||||
"NewJump_ChooseJumpType": "Choose the jump type",
|
"NewJump_ChooseJumpType": "Choose the jump type",
|
||||||
"NewJump_ChooseAircraft": "Choose the aircraft",
|
"NewJump_ChooseAircraft": "Choose the aircraft",
|
||||||
"NewJump_ChooseDz": "Choose the DZ",
|
"NewJump_ChooseDz": "Choose the DZ",
|
||||||
"NewJump_ChooseGear": "Choose the used gear",
|
"NewJump_ChooseGear": "Choose the used gear",
|
||||||
"NewJump_Cutaway": "With a cutaway ?",
|
"NewJump_Cutaway": "With a cutaway ?",
|
||||||
"NewJump_Special": "Is a special jump ?",
|
"NewJump_Special": "Is a special jump ?",
|
||||||
"NewJump_ExitAlt": "Exit altitude",
|
"NewJump_ExitAlt": "Exit altitude",
|
||||||
"NewJump_DeployAlt": "Deploy altitude",
|
"NewJump_DeployAlt": "Deploy altitude",
|
||||||
"NewJump_Count": "Count of jumps",
|
"NewJump_Count": "Count of jumps",
|
||||||
"NewJump_Comments": "Comments",
|
"NewJump_Comments": "Comments",
|
||||||
"NewJump_Submit": "Submit",
|
"NewJump_Submit": "Submit",
|
||||||
|
|
||||||
"NewTunnelFlight_ChooseTunnel": "Choose the tunnel",
|
"NewTunnelFlight_ChooseTunnel": "Choose the tunnel",
|
||||||
"NewTunnelFlight_Minutes": "Minutes of the flight",
|
"NewTunnelFlight_Minutes": "Minutes of the flight",
|
||||||
"NewTunnelFlight_Comments": "Comments",
|
"NewTunnelFlight_Comments": "Comments",
|
||||||
"NewTunnelFlight_Submit": "Submit",
|
"NewTunnelFlight_Submit": "Submit",
|
||||||
"NewTunnelFlight_Comments_Lbl": "Comments",
|
"NewTunnelFlight_Comments_Lbl": "Comments",
|
||||||
"NewTunnelFlight_Minutes_Lbl": "Time of flight (minutes)",
|
"NewTunnelFlight_Minutes_Lbl": "Time of flight (minutes)",
|
||||||
"NewTunnelFlight_Date_Lbl": "Date of flight",
|
"NewTunnelFlight_Date_Lbl": "Date of flight",
|
||||||
"NewTunnelFlight_GoToJump": "View the tunnel flights",
|
"NewTunnelFlight_GoToJump": "View the tunnel flights",
|
||||||
"NewTunnelFlight_ChooseJumpType": "Choose the jump type",
|
"NewTunnelFlight_ChooseJumpType": "Choose the jump type",
|
||||||
|
|
||||||
"ListTunnelFlight_CurrentYear": "On the current year",
|
"ListTunnelFlight_CurrentYear": "On the current year",
|
||||||
"ListTunnelFlight_12Months": "On 12 last months",
|
"ListTunnelFlight_12Months": "On 12 last months",
|
||||||
"ListTunnelFlight_Add": "Add tunnel flights",
|
"ListTunnelFlight_Add": "Add tunnel flights",
|
||||||
"ListTunnelFlight_LoadTable": "Load the tunnel flights",
|
"ListTunnelFlight_LoadTable": "Load the tunnel flights",
|
||||||
"ListTunnelFlight_AllFlights": "All"
|
"ListTunnelFlight_AllFlights": "All",
|
||||||
|
|
||||||
|
"UserProfile_Update": "Update my profile",
|
||||||
|
"UserProfile_NewPassword": "New password",
|
||||||
|
"UserProfile_CurrentPassword": "Current password",
|
||||||
|
"UserProfile_Mail": "E-mail",
|
||||||
|
"UserProfile_Lastname": "Lastname",
|
||||||
|
"UserProfile_Firstname": "Firstname",
|
||||||
|
"UserProfile_Login": "Login"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,139 +1,147 @@
|
|||||||
{
|
{
|
||||||
"Login_Title": "Connexion à Skydive log",
|
"Login_Title": "Connexion à Skydive log",
|
||||||
"Login_Tab_CreateUser": "Créer et se connecter",
|
"Login_Tab_CreateUser": "Créer et se connecter",
|
||||||
"Login_Tab_WithUser": "Se connecter",
|
"Login_Tab_WithUser": "Se connecter",
|
||||||
|
|
||||||
"LoginUser_BtnLogin": "Connecter",
|
"LoginUser_BtnLogin": "Connecter",
|
||||||
"LoginUser_PasswordPattern": "Le mot de passe doit contenir lettres minuscule/majuscule et entre 8 et 15 caractères.",
|
"LoginUser_PasswordPattern": "Le mot de passe doit contenir lettres minuscule/majuscule et entre 8 et 15 caractères.",
|
||||||
"LoginUser_PasswordRequired": "Le mot de passe est obligatoire",
|
"LoginUser_PasswordRequired": "Le mot de passe est obligatoire",
|
||||||
"LoginUser_Password": "Mot de passe",
|
"LoginUser_Password": "Mot de passe",
|
||||||
"LoginUser_Username": "Identifiant",
|
"LoginUser_Username": "Identifiant",
|
||||||
"LoginUser_UsernamePattern": "L'identifiant doit être minimum de 3 caractères",
|
"LoginUser_UsernamePattern": "L'identifiant doit être minimum de 3 caractères",
|
||||||
"LoginUser_UsernameRequired": "L'identifiant est obligatoire",
|
"LoginUser_UsernameRequired": "L'identifiant est obligatoire",
|
||||||
|
|
||||||
"LoginCreateUser_Firstname": "Prénom",
|
"CreateUser_Firstname": "Prénom",
|
||||||
"LoginCreateUser_FirstnameRequired": "Le prénom est obligatoire",
|
"CreateUser_FirstnameRequired": "Le prénom est obligatoire",
|
||||||
"LoginCreateUser_FirstnamePattern": "Le prénom doit être minimum de 3 caractères",
|
"CreateUser_FirstnamePattern": "Le prénom doit être minimum de 3 caractères",
|
||||||
"LoginCreateUser_Lastname": "Nom",
|
"CreateUser_Lastname": "Nom",
|
||||||
"LoginCreateUser_LastnameRequired": "Le nom est obligatoire",
|
"CreateUser_LastnameRequired": "Le nom est obligatoire",
|
||||||
"LoginCreateUser_LastnamePattern": "Le nom doit être minimum de 3 caractères",
|
"CreateUser_LastnamePattern": "Le nom doit être minimum de 3 caractères",
|
||||||
"LoginCreateUser_Email": "E-mail",
|
"CreateUser_Email": "E-mail",
|
||||||
"LoginCreateUser_EmailRequired": "E-mail est obligatoire",
|
"CreateUser_EmailRequired": "E-mail est obligatoire",
|
||||||
"LoginCreateUser_EmailPattern": "Ceci n'est pas un adresse mail",
|
"CreateUser_EmailPattern": "Ceci n'est pas un adresse mail",
|
||||||
"LoginCreateUser_Username": "Identifiant",
|
"CreateUser_Username": "Identifiant",
|
||||||
"LoginCreateUser_UsernameRequired": "L'identifiant est obligatoire",
|
"CreateUser_UsernameRequired": "L'identifiant est obligatoire",
|
||||||
"LoginCreateUser_UsernamePattern": "L'identifiant doit être minimum de 3 caractères",
|
"CreateUser_UsernamePattern": "L'identifiant doit être minimum de 3 caractères",
|
||||||
"LoginCreateUser_Password": "Mot de passe",
|
"CreateUser_Password": "Mot de passe",
|
||||||
"LoginCreateUser_PasswordRequired": "Le mot de passe est obligatoire",
|
"CreateUser_PasswordRequired": "Le mot de passe est obligatoire",
|
||||||
"LoginCreateUser_PasswordPattern": "Le mot de passe doit contenir lettres minuscule/majuscule et entre 8 et 15 caractères.",
|
"CreateUser_PasswordPattern": "Le mot de passe doit contenir lettres minuscule/majuscule et entre 8 et 15 caractères.",
|
||||||
"LoginCreateUser_BtnLogin": "Créer et se connecter",
|
"CreateUser_BtnLogin": "Créer et se connecter",
|
||||||
|
|
||||||
"Default_Title": "Accueil",
|
"Default_Title": "Accueil",
|
||||||
"ListDz_Title": "Liste des centres de parachutisme",
|
"ListDz_Title": "Liste des centres de parachutisme",
|
||||||
"Summary_Title": "Récapitulatif",
|
"Summary_Title": "Récapitulatif",
|
||||||
"NewJump_Title": "Nouveaux sauts",
|
"NewJump_Title": "Nouveaux sauts",
|
||||||
"ListJumps_Title": "Liste des sauts",
|
"ListJumps_Title": "Liste des sauts",
|
||||||
"ListJumpTypes_Title": "Liste des types de saut",
|
"ListJumpTypes_Title": "Liste des types de saut",
|
||||||
"ListGears_Title": "Liste des pièges",
|
"ListGears_Title": "Liste des pièges",
|
||||||
"ListAircrafts_Title": "Liste des avions",
|
"ListAircrafts_Title": "Liste des avions",
|
||||||
"NewTunnelFlight_Title": "Nouveaux créneaux de soufflerie",
|
"NewTunnelFlight_Title": "Nouveaux créneaux de soufflerie",
|
||||||
"ListTunnelFlight_Title": "Heures de tunnel",
|
"ListTunnelFlight_Title": "Heures de tunnel",
|
||||||
"UserProfile_Title": "Profile utilisateur",
|
"UserProfile_Title": "Profile utilisateur",
|
||||||
"NewJumpType_Title": "Nouveau type de saut",
|
"NewJumpType_Title": "Nouveau type de saut",
|
||||||
"NewGear_Title": "Nouveau piège",
|
"NewGear_Title": "Nouveau piège",
|
||||||
"NewDz_Title": "Nouveau centre",
|
"NewDz_Title": "Nouveau centre",
|
||||||
"NewAircraft_Title": "Nouvel avion",
|
"NewAircraft_Title": "Nouvel avion",
|
||||||
|
|
||||||
"App_Footer": "Application pour enregistrer ses sauts de parachutisme - v",
|
"App_Footer": "Application pour enregistrer ses sauts de parachutisme - v",
|
||||||
"App_Nav_Summary": "Récapitulatif",
|
"App_Nav_Summary": "Récapitulatif",
|
||||||
"App_Nav_Jumps": "Les sauts",
|
"App_Nav_Jumps": "Les sauts",
|
||||||
"App_Nav_NewJump": "Ajouter un saut",
|
"App_Nav_NewJump": "Ajouter un saut",
|
||||||
"App_Nav_Dzs": "Centre de parachutisme",
|
"App_Nav_Dzs": "Centre de parachutisme",
|
||||||
"App_Nav_Aircrafts": "Avions",
|
"App_Nav_Aircrafts": "Avions",
|
||||||
"App_Nav_JumpTypes": "Type de saut",
|
"App_Nav_JumpTypes": "Type de saut",
|
||||||
"App_Nav_Gears": "Pièges",
|
"App_Nav_Gears": "Pièges",
|
||||||
"App_Nav_Logout": "Se déconnecter",
|
"App_Nav_Logout": "Se déconnecter",
|
||||||
"App_Nav_NewTunnelFlight": "Ajouter du temps en tunnel",
|
"App_Nav_NewTunnelFlight": "Ajouter du temps en tunnel",
|
||||||
"App_Nav_TunnelFlights": "Les vols en soufflerie",
|
"App_Nav_TunnelFlights": "Les vols en soufflerie",
|
||||||
|
|
||||||
"ListAircrafts_Add": "Ajouter un avion",
|
"ListAircrafts_Add": "Ajouter un avion",
|
||||||
"ListAircrafts_Header_Id": "ID",
|
"ListAircrafts_Header_Id": "ID",
|
||||||
"ListAircrafts_Header_Name": "Nom",
|
"ListAircrafts_Header_Name": "Nom",
|
||||||
"ListAircrafts_Header_Image": "Image",
|
"ListAircrafts_Header_Image": "Image",
|
||||||
|
|
||||||
"ListGears_Add": "Ajouter un piège",
|
"ListGears_Add": "Ajouter un piège",
|
||||||
"ListGears_Header_Id": "ID",
|
"ListGears_Header_Id": "ID",
|
||||||
"ListGears_Header_Name": "Nom",
|
"ListGears_Header_Name": "Nom",
|
||||||
"ListGears_Header_Manufacturer": "Fabriquant",
|
"ListGears_Header_Manufacturer": "Fabriquant",
|
||||||
"ListGears_Header_CanopySize": "Taille de voile",
|
"ListGears_Header_CanopySize": "Taille de voile",
|
||||||
"ListGears_Header_Aad": "Système de sécurité",
|
"ListGears_Header_Aad": "Système de sécurité",
|
||||||
"ListGears_Header_Main": "Principale",
|
"ListGears_Header_Main": "Principale",
|
||||||
"ListGears_Header_Reserve": "Réserve",
|
"ListGears_Header_Reserve": "Réserve",
|
||||||
|
|
||||||
"ListJumpType_Add": "Ajouter un type de saut",
|
"ListJumpType_Add": "Ajouter un type de saut",
|
||||||
"ListJumpType_Header_Id": "ID",
|
"ListJumpType_Header_Id": "ID",
|
||||||
"ListJumpType_Header_Name": "Nom",
|
"ListJumpType_Header_Name": "Nom",
|
||||||
|
|
||||||
"ListJump_Add": "Ajouter des sauts",
|
"ListJump_Add": "Ajouter des sauts",
|
||||||
"ListJump_Header_Num": "Numéro",
|
"ListJump_Header_Num": "Numéro",
|
||||||
"ListJump_Header_Date": "Date",
|
"ListJump_Header_Date": "Date",
|
||||||
"ListJump_Header_JumpType": "Type de saut",
|
"ListJump_Header_JumpType": "Type de saut",
|
||||||
"ListJump_Header_Aircraft": "Avion",
|
"ListJump_Header_Aircraft": "Avion",
|
||||||
"ListJump_Header_Dz": "Centre",
|
"ListJump_Header_Dz": "Centre",
|
||||||
"ListJump_Header_Gear": "Piège",
|
"ListJump_Header_Gear": "Piège",
|
||||||
|
|
||||||
"ListDz_Add": "Ajouter un centre de parachutisme",
|
"ListDz_Add": "Ajouter un centre de parachutisme",
|
||||||
"ListDz_Header_ID": "ID",
|
"ListDz_Header_ID": "ID",
|
||||||
"ListDz_Header_Name": "Nom",
|
"ListDz_Header_Name": "Nom",
|
||||||
"ListDz_Header_Address": "Adresse",
|
"ListDz_Header_Address": "Adresse",
|
||||||
"ListDz_Header_Type": "Type",
|
"ListDz_Header_Type": "Type",
|
||||||
"ListDz_Filter": "Filtrer",
|
"ListDz_Filter": "Filtrer",
|
||||||
"ListDz_Filter_PlaceHolder": "Filtrer sur le nom ou l'adresse du centre",
|
"ListDz_Filter_PlaceHolder": "Filtrer sur le nom ou l'adresse du centre",
|
||||||
|
|
||||||
"Summary_TotalJumps": "Nombre de sauts",
|
"Summary_TotalJumps": "Nombre de sauts",
|
||||||
"Summary_TotalCutaways": "Nombre de libération",
|
"Summary_TotalCutaways": "Nombre de libération",
|
||||||
"Summary_LastJump": "Le dernier saut",
|
"Summary_LastJump": "Le dernier saut",
|
||||||
"Summary_Refresh": "Refresh",
|
"Summary_Refresh": "Refresh",
|
||||||
"Summary_LastMonth_Title": "Les sauts du dernier mois",
|
"Summary_LastMonth_Title": "Les sauts du dernier mois",
|
||||||
"Summary_LastMonth_ByDz": "Par centre",
|
"Summary_LastMonth_ByDz": "Par centre",
|
||||||
"Summary_LastMonth_ByJumpType": "Par type de saut",
|
"Summary_LastMonth_ByJumpType": "Par type de saut",
|
||||||
"Summary_LastYear_Title": "Les sauts de la dernière année",
|
"Summary_LastYear_Title": "Les sauts de la dernière année",
|
||||||
"Summary_LastYear_ByDz": "Par centre",
|
"Summary_LastYear_ByDz": "Par centre",
|
||||||
"Summary_LastYear_ByJumpType": "Par type de saut",
|
"Summary_LastYear_ByJumpType": "Par type de saut",
|
||||||
"Summary_ByDz_Title": "Par centre",
|
"Summary_ByDz_Title": "Par centre",
|
||||||
"Summary_ByAircraft_Title": "Par avion",
|
"Summary_ByAircraft_Title": "Par avion",
|
||||||
"Summary_ByGear_Title": "Par piège",
|
"Summary_ByGear_Title": "Par piège",
|
||||||
"Summary_ByJumpType_Title": "Par type de saut",
|
"Summary_ByJumpType_Title": "Par type de saut",
|
||||||
"Summary_ByYear_Title": "Par an",
|
"Summary_ByYear_Title": "Par an",
|
||||||
"Summary_ByYearByJumpType_Title": "Par an et par type",
|
"Summary_ByYearByJumpType_Title": "Par an et par type",
|
||||||
|
|
||||||
"NewJump_GoToJump": "Voir les sauts",
|
"NewJump_GoToJump": "Voir les sauts",
|
||||||
"NewJump_ResetForm": "Reset du formulaire après l'ajout",
|
"NewJump_ResetForm": "Reset du formulaire après l'ajout",
|
||||||
"NewJump_ChooseJumpType": "Choisir le type de saut",
|
"NewJump_ChooseJumpType": "Choisir le type de saut",
|
||||||
"NewJump_ChooseAircraft": "Choisir l'avion largueur",
|
"NewJump_ChooseAircraft": "Choisir l'avion largueur",
|
||||||
"NewJump_ChooseDz": "Choisir le centre",
|
"NewJump_ChooseDz": "Choisir le centre",
|
||||||
"NewJump_ChooseGear": "Choisir le piège",
|
"NewJump_ChooseGear": "Choisir le piège",
|
||||||
"NewJump_Cutaway": "Libération ?",
|
"NewJump_Cutaway": "Libération ?",
|
||||||
"NewJump_Special": "Saut spécial ?",
|
"NewJump_Special": "Saut spécial ?",
|
||||||
"NewJump_ExitAlt": "Altitude de sortie",
|
"NewJump_ExitAlt": "Altitude de sortie",
|
||||||
"NewJump_DeployAlt": "Altitude d'ouverture",
|
"NewJump_DeployAlt": "Altitude d'ouverture",
|
||||||
"NewJump_Count": "Nombre de sauts",
|
"NewJump_Count": "Nombre de sauts",
|
||||||
"NewJump_Comments": "Commentaires",
|
"NewJump_Comments": "Commentaires",
|
||||||
"NewJump_Submit": "Ajouter",
|
"NewJump_Submit": "Ajouter",
|
||||||
|
|
||||||
"NewTunnelFlight_ChooseTunnel": "Choisir le tunnel",
|
"NewTunnelFlight_ChooseTunnel": "Choisir le tunnel",
|
||||||
"NewTunnelFlight_Minutes": "Temps de vol(minutes)",
|
"NewTunnelFlight_Minutes": "Temps de vol(minutes)",
|
||||||
"NewTunnelFlight_Comments": "Commentaires",
|
"NewTunnelFlight_Comments": "Commentaires",
|
||||||
"NewTunnelFlight_Submit": "Ajouter",
|
"NewTunnelFlight_Submit": "Ajouter",
|
||||||
"NewTunnelFlight_Comments_Lbl": "Commentaires",
|
"NewTunnelFlight_Comments_Lbl": "Commentaires",
|
||||||
"NewTunnelFlight_Minutes_Lbl": "Temps de vol(minutes)",
|
"NewTunnelFlight_Minutes_Lbl": "Temps de vol(minutes)",
|
||||||
"NewTunnelFlight_Date_Lbl": "Date des vols",
|
"NewTunnelFlight_Date_Lbl": "Date des vols",
|
||||||
"NewTunnelFlight_GoToJump": "Voir les temps de vol en soufflerie",
|
"NewTunnelFlight_GoToJump": "Voir les temps de vol en soufflerie",
|
||||||
"NewTunnelFlight_ChooseJumpType": "Choisir le type de saut",
|
"NewTunnelFlight_ChooseJumpType": "Choisir le type de saut",
|
||||||
|
|
||||||
"ListTunnelFlight_CurrentYear": "Dans l'année en cours",
|
"ListTunnelFlight_CurrentYear": "Dans l'année en cours",
|
||||||
"ListTunnelFlight_12Months": "Sur 12 derniers mois",
|
"ListTunnelFlight_12Months": "Sur 12 derniers mois",
|
||||||
"ListTunnelFlight_Add": "Ajouter du temps en soufflerie",
|
"ListTunnelFlight_Add": "Ajouter du temps en soufflerie",
|
||||||
"ListTunnelFlight_LoadTable": "Charger les vols en tunnel",
|
"ListTunnelFlight_LoadTable": "Charger les vols en tunnel",
|
||||||
"ListTunnelFlight_AllFlights": "Tous les vols"
|
"ListTunnelFlight_AllFlights": "Tous les vols",
|
||||||
|
|
||||||
|
"UserProfile_Update": "Mise à jour",
|
||||||
|
"UserProfile_NewPassword": "Nouveau mot de passe",
|
||||||
|
"UserProfile_CurrentPassword": "Actuel mot de passe",
|
||||||
|
"UserProfile_Mail": "E-mail",
|
||||||
|
"UserProfile_Lastname": "Nom",
|
||||||
|
"UserProfile_Firstname": "Prénom",
|
||||||
|
"UserProfile_Login": "Identifiant"
|
||||||
}
|
}
|
||||||
|
|||||||
12
doc.txt
12
doc.txt
@@ -1,7 +1,11 @@
|
|||||||
To build an image "toto" with the version "0.1": podman build . -t skydivelogs:1.5.0
|
To build an image "skydivelogs" with the version "1.5.5":
|
||||||
|
podman build . -t skydivelogs:1.5.5
|
||||||
|
|
||||||
To run ab image to container with volume :
|
To run ab image to container with volume :
|
||||||
podman run -v C:\toto\config:/app/Front/config -v C:\toto\db:/app/API/Data -d -p 5080:80/tcp --name Test -it skydivelogs:1.5.0
|
podman run -v ./Front/skydivelogs-app/src/config:/usr/share/nginx/html/config:z -v ./Back/skydiveLogs-api/Data:/app/Data:z -d -p 5080:80/tcp --name Skydivelogs-1.5.5 -it skydivelogs:1.5.5
|
||||||
|
|
||||||
podman save --output skydivelogs-1.5.0.tar skydivelogs:1.5.0
|
To save the image before to updload to the server :
|
||||||
|
podman save --output skydivelogs-1.5.5.tar skydivelogs:1.5.5
|
||||||
|
|
||||||
scp -P 5022 skydivelogs-1.5.0.tar administrator@51.75.68.58:~
|
Updload to the server :
|
||||||
|
scp -P 5022 skydivelogs-1.5.5.tar administrator@51.75.68.58:~
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
service nginx start
|
|
||||||
|
|
||||||
cd /app/API/
|
|
||||||
dotnet skydiveLogs-api.dll
|
|
||||||
Reference in New Issue
Block a user