Update to Angular v19 and fixing (#3)
Reviewed-on: #3 Co-authored-by: sandre <perso@sebastienandre.com> Co-committed-by: sandre <perso@sebastienandre.com>
@@ -27,7 +27,7 @@ COPY nginx.conf /etc/nginx/sites-available/default
|
||||
RUN rm -rf /usr/share/nginx/html/*
|
||||
|
||||
# Copy frontend dist folder to nginx html directory
|
||||
COPY --from=build-frontend /app/dist /usr/share/nginx/html
|
||||
COPY --from=build-frontend /app/dist/browser /usr/share/nginx/html
|
||||
|
||||
# Copy backend from the correct build stage
|
||||
COPY --from=build-backend /app/publish /app
|
||||
|
||||
@@ -4,25 +4,33 @@
|
||||
"newProjectRoot": "projects",
|
||||
"projects": {
|
||||
"skydivelogs-app": {
|
||||
"projectType": "application",
|
||||
"schematics": {
|
||||
"@schematics/angular:component": {
|
||||
"style": "scss"
|
||||
}
|
||||
},
|
||||
"root": "",
|
||||
"sourceRoot": "src",
|
||||
"projectType": "application",
|
||||
"prefix": "app",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:application",
|
||||
"options": {
|
||||
"outputPath": {
|
||||
"base": "dist"
|
||||
},
|
||||
"outputPath": "dist",
|
||||
"index": "src/index.html",
|
||||
"tsConfig": "src/tsconfig.app.json",
|
||||
"polyfills": [
|
||||
"src/polyfills.ts"
|
||||
],
|
||||
"browser": "src/main.ts",
|
||||
"polyfills": ["zone.js"],
|
||||
"tsConfig": "tsconfig.app.json",
|
||||
"inlineStyleLanguage": "scss",
|
||||
"assets": [
|
||||
"src/assets",
|
||||
"src/config",
|
||||
"src/favicon.ico"
|
||||
"src/favicon.ico",
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "public"
|
||||
}
|
||||
],
|
||||
"styles": [
|
||||
"src/assets/css/styles-app-loading.scss",
|
||||
@@ -30,118 +38,86 @@
|
||||
"src/assets/css/new-theme.scss",
|
||||
"@angular/material/prebuilt-themes/pink-bluegrey.css"
|
||||
],
|
||||
"scripts": [],
|
||||
"extractLicenses": false,
|
||||
"sourceMap": true,
|
||||
"optimization": false,
|
||||
"namedChunks": true,
|
||||
"browser": "src/main.ts"
|
||||
"scripts": []
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"budgets": [
|
||||
{
|
||||
"type": "initial",
|
||||
"maximumWarning": "2mb",
|
||||
"maximumError": "5mb"
|
||||
},
|
||||
{
|
||||
"type": "bundle",
|
||||
"name": "main",
|
||||
"baseline": "1mb",
|
||||
"maximumWarning": "1.5mb",
|
||||
"maximumError": "2mb"
|
||||
},
|
||||
{
|
||||
"type": "anyComponentStyle",
|
||||
"maximumWarning": "6kb"
|
||||
"maximumWarning": "2kb",
|
||||
"maximumError": "4kb"
|
||||
}
|
||||
],
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"namedChunks": false,
|
||||
"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",
|
||||
"options": {
|
||||
"buildTarget": "skydivelogs-app:build"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"buildTarget": "skydivelogs-app:build:production"
|
||||
}
|
||||
},
|
||||
"development": {
|
||||
"buildTarget": "skydivelogs-app:build:development"
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": "development"
|
||||
},
|
||||
"extract-i18n": {
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||
"options": {
|
||||
"buildTarget": "skydivelogs-app:build"
|
||||
}
|
||||
"builder": "@angular-devkit/build-angular:extract-i18n"
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "src/test.ts",
|
||||
"karmaConfig": "./karma.conf.js",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "src/tsconfig.spec.json",
|
||||
"scripts": [],
|
||||
"styles": [
|
||||
"src/styles.css"
|
||||
],
|
||||
"polyfills": ["zone.js", "zone.js/testing"],
|
||||
"tsConfig": "tsconfig.spec.json",
|
||||
"inlineStyleLanguage": "scss",
|
||||
"assets": [
|
||||
"src/assets",
|
||||
"src/favicon.ico"
|
||||
]
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "public"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"src/tsconfig.app.json",
|
||||
"src/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"skydivelogs-app-e2e": {
|
||||
"root": "e2e",
|
||||
"sourceRoot": "e2e",
|
||||
"projectType": "application",
|
||||
"architect": {
|
||||
"e2e": {
|
||||
"builder": "@angular-devkit/build-angular:protractor",
|
||||
"options": {
|
||||
"protractorConfig": "./protractor.conf.js",
|
||||
"devServerTarget": "skydivelogs-app:serve"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"e2e/tsconfig.e2e.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
"styles": ["src/styles.scss"],
|
||||
"scripts": []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"schematics": {
|
||||
"@schematics/angular:component": {
|
||||
"prefix": "app"
|
||||
},
|
||||
"@schematics/angular:directive": {
|
||||
"prefix": "app"
|
||||
}
|
||||
},
|
||||
"cli": {
|
||||
"analytics": false
|
||||
}
|
||||
}
|
||||
|
||||
443
Front/skydivelogs-app/package-lock.json
generated
@@ -19,10 +19,10 @@
|
||||
"@angular/platform-browser": "^19.2.6",
|
||||
"@angular/platform-browser-dynamic": "^19.2.6",
|
||||
"@angular/router": "^19.2.6",
|
||||
"@ngx-translate/core": "^15.0.0",
|
||||
"@ngx-translate/http-loader": "^8.0.0",
|
||||
"@ngx-translate/core": "^17.0.0",
|
||||
"@ngx-translate/http-loader": "^17.0.0",
|
||||
"chart.js": "^4.3.0",
|
||||
"ng2-charts": "^5.0.2",
|
||||
"ng2-charts": "^8.0.0",
|
||||
"rxjs": "~7.8.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.15.0"
|
||||
@@ -680,13 +680,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
|
||||
"integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz",
|
||||
"integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-validator-identifier": "^7.27.1",
|
||||
"@babel/helper-validator-identifier": "^7.28.5",
|
||||
"js-tokens": "^4.0.0",
|
||||
"picocolors": "^1.1.1"
|
||||
},
|
||||
@@ -695,9 +695,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/compat-data": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz",
|
||||
"integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.6.tgz",
|
||||
"integrity": "sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@@ -783,13 +783,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-compilation-targets": {
|
||||
"version": "7.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz",
|
||||
"integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz",
|
||||
"integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/compat-data": "^7.27.2",
|
||||
"@babel/compat-data": "^7.28.6",
|
||||
"@babel/helper-validator-option": "^7.27.1",
|
||||
"browserslist": "^4.24.0",
|
||||
"lru-cache": "^5.1.1",
|
||||
@@ -810,18 +810,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-create-class-features-plugin": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.5.tgz",
|
||||
"integrity": "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.6.tgz",
|
||||
"integrity": "sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-annotate-as-pure": "^7.27.3",
|
||||
"@babel/helper-member-expression-to-functions": "^7.28.5",
|
||||
"@babel/helper-optimise-call-expression": "^7.27.1",
|
||||
"@babel/helper-replace-supers": "^7.27.1",
|
||||
"@babel/helper-replace-supers": "^7.28.6",
|
||||
"@babel/helper-skip-transparent-expression-wrappers": "^7.27.1",
|
||||
"@babel/traverse": "^7.28.5",
|
||||
"@babel/traverse": "^7.28.6",
|
||||
"semver": "^6.3.1"
|
||||
},
|
||||
"engines": {
|
||||
@@ -937,29 +937,29 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-module-imports": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz",
|
||||
"integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz",
|
||||
"integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/traverse": "^7.27.1",
|
||||
"@babel/types": "^7.27.1"
|
||||
"@babel/traverse": "^7.28.6",
|
||||
"@babel/types": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-module-transforms": {
|
||||
"version": "7.28.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz",
|
||||
"integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz",
|
||||
"integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-module-imports": "^7.27.1",
|
||||
"@babel/helper-validator-identifier": "^7.27.1",
|
||||
"@babel/traverse": "^7.28.3"
|
||||
"@babel/helper-module-imports": "^7.28.6",
|
||||
"@babel/helper-validator-identifier": "^7.28.5",
|
||||
"@babel/traverse": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -982,9 +982,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-plugin-utils": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz",
|
||||
"integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz",
|
||||
"integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@@ -1023,15 +1023,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-replace-supers": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz",
|
||||
"integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz",
|
||||
"integrity": "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-member-expression-to-functions": "^7.27.1",
|
||||
"@babel/helper-member-expression-to-functions": "^7.28.5",
|
||||
"@babel/helper-optimise-call-expression": "^7.27.1",
|
||||
"@babel/traverse": "^7.27.1"
|
||||
"@babel/traverse": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1098,42 +1098,42 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-wrap-function": {
|
||||
"version": "7.28.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz",
|
||||
"integrity": "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.6.tgz",
|
||||
"integrity": "sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/template": "^7.27.2",
|
||||
"@babel/traverse": "^7.28.3",
|
||||
"@babel/types": "^7.28.2"
|
||||
"@babel/template": "^7.28.6",
|
||||
"@babel/traverse": "^7.28.6",
|
||||
"@babel/types": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helpers": {
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz",
|
||||
"integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz",
|
||||
"integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/template": "^7.27.2",
|
||||
"@babel/types": "^7.28.4"
|
||||
"@babel/template": "^7.28.6",
|
||||
"@babel/types": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/parser": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz",
|
||||
"integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.6.tgz",
|
||||
"integrity": "sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.28.5"
|
||||
"@babel/types": "^7.28.6"
|
||||
},
|
||||
"bin": {
|
||||
"parser": "bin/babel-parser.js"
|
||||
@@ -1210,14 +1210,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": {
|
||||
"version": "7.28.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.3.tgz",
|
||||
"integrity": "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.6.tgz",
|
||||
"integrity": "sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1",
|
||||
"@babel/traverse": "^7.28.3"
|
||||
"@babel/helper-plugin-utils": "^7.28.6",
|
||||
"@babel/traverse": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1240,13 +1240,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-syntax-import-assertions": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz",
|
||||
"integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.28.6.tgz",
|
||||
"integrity": "sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
"@babel/helper-plugin-utils": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1357,13 +1357,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-block-scoping": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.5.tgz",
|
||||
"integrity": "sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.6.tgz",
|
||||
"integrity": "sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
"@babel/helper-plugin-utils": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1373,14 +1373,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-class-properties": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz",
|
||||
"integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.28.6.tgz",
|
||||
"integrity": "sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-create-class-features-plugin": "^7.27.1",
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
"@babel/helper-create-class-features-plugin": "^7.28.6",
|
||||
"@babel/helper-plugin-utils": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1390,14 +1390,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-class-static-block": {
|
||||
"version": "7.28.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz",
|
||||
"integrity": "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.6.tgz",
|
||||
"integrity": "sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-create-class-features-plugin": "^7.28.3",
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
"@babel/helper-create-class-features-plugin": "^7.28.6",
|
||||
"@babel/helper-plugin-utils": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1407,18 +1407,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-classes": {
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz",
|
||||
"integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.6.tgz",
|
||||
"integrity": "sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-annotate-as-pure": "^7.27.3",
|
||||
"@babel/helper-compilation-targets": "^7.27.2",
|
||||
"@babel/helper-compilation-targets": "^7.28.6",
|
||||
"@babel/helper-globals": "^7.28.0",
|
||||
"@babel/helper-plugin-utils": "^7.27.1",
|
||||
"@babel/helper-replace-supers": "^7.27.1",
|
||||
"@babel/traverse": "^7.28.4"
|
||||
"@babel/helper-plugin-utils": "^7.28.6",
|
||||
"@babel/helper-replace-supers": "^7.28.6",
|
||||
"@babel/traverse": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1441,14 +1441,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-computed-properties": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz",
|
||||
"integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.28.6.tgz",
|
||||
"integrity": "sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1",
|
||||
"@babel/template": "^7.27.1"
|
||||
"@babel/helper-plugin-utils": "^7.28.6",
|
||||
"@babel/template": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1475,14 +1475,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-dotall-regex": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz",
|
||||
"integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.28.6.tgz",
|
||||
"integrity": "sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.27.1",
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.28.5",
|
||||
"@babel/helper-plugin-utils": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1508,14 +1508,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz",
|
||||
"integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.28.6.tgz",
|
||||
"integrity": "sha512-5suVoXjC14lUN6ZL9OLKIHCNVWCrqGqlmEp/ixdXjvgnEl/kauLvvMO/Xw9NyMc95Joj1AeLVPVMvibBgSoFlA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.27.1",
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.28.5",
|
||||
"@babel/helper-plugin-utils": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1541,13 +1541,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-exponentiation-operator": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.5.tgz",
|
||||
"integrity": "sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.6.tgz",
|
||||
"integrity": "sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
"@babel/helper-plugin-utils": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1608,13 +1608,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-json-strings": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz",
|
||||
"integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.28.6.tgz",
|
||||
"integrity": "sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
"@babel/helper-plugin-utils": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1640,13 +1640,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-logical-assignment-operators": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz",
|
||||
"integrity": "sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.6.tgz",
|
||||
"integrity": "sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
"@babel/helper-plugin-utils": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1689,14 +1689,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-modules-commonjs": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz",
|
||||
"integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.28.6.tgz",
|
||||
"integrity": "sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-module-transforms": "^7.27.1",
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
"@babel/helper-module-transforms": "^7.28.6",
|
||||
"@babel/helper-plugin-utils": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1775,13 +1775,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz",
|
||||
"integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.28.6.tgz",
|
||||
"integrity": "sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
"@babel/helper-plugin-utils": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1791,13 +1791,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-numeric-separator": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz",
|
||||
"integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.28.6.tgz",
|
||||
"integrity": "sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
"@babel/helper-plugin-utils": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1807,17 +1807,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-object-rest-spread": {
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz",
|
||||
"integrity": "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.6.tgz",
|
||||
"integrity": "sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-compilation-targets": "^7.27.2",
|
||||
"@babel/helper-plugin-utils": "^7.27.1",
|
||||
"@babel/plugin-transform-destructuring": "^7.28.0",
|
||||
"@babel/helper-compilation-targets": "^7.28.6",
|
||||
"@babel/helper-plugin-utils": "^7.28.6",
|
||||
"@babel/plugin-transform-destructuring": "^7.28.5",
|
||||
"@babel/plugin-transform-parameters": "^7.27.7",
|
||||
"@babel/traverse": "^7.28.4"
|
||||
"@babel/traverse": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1844,13 +1844,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-optional-catch-binding": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz",
|
||||
"integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.28.6.tgz",
|
||||
"integrity": "sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
"@babel/helper-plugin-utils": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1860,13 +1860,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-optional-chaining": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.5.tgz",
|
||||
"integrity": "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.6.tgz",
|
||||
"integrity": "sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1",
|
||||
"@babel/helper-plugin-utils": "^7.28.6",
|
||||
"@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
|
||||
},
|
||||
"engines": {
|
||||
@@ -1893,14 +1893,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-private-methods": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz",
|
||||
"integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.28.6.tgz",
|
||||
"integrity": "sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-create-class-features-plugin": "^7.27.1",
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
"@babel/helper-create-class-features-plugin": "^7.28.6",
|
||||
"@babel/helper-plugin-utils": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1910,15 +1910,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-private-property-in-object": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz",
|
||||
"integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.28.6.tgz",
|
||||
"integrity": "sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-annotate-as-pure": "^7.27.1",
|
||||
"@babel/helper-create-class-features-plugin": "^7.27.1",
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
"@babel/helper-annotate-as-pure": "^7.27.3",
|
||||
"@babel/helper-create-class-features-plugin": "^7.28.6",
|
||||
"@babel/helper-plugin-utils": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1957,13 +1957,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-regenerator": {
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz",
|
||||
"integrity": "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.6.tgz",
|
||||
"integrity": "sha512-eZhoEZHYQLL5uc1gS5e9/oTknS0sSSAtd5TkKMUp3J+S/CaUjagc0kOUPsEbDmMeva0nC3WWl4SxVY6+OBuxfw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
"@babel/helper-plugin-utils": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1973,14 +1973,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-regexp-modifiers": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz",
|
||||
"integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.28.6.tgz",
|
||||
"integrity": "sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.27.1",
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.28.5",
|
||||
"@babel/helper-plugin-utils": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -2053,13 +2053,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-spread": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz",
|
||||
"integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.28.6.tgz",
|
||||
"integrity": "sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1",
|
||||
"@babel/helper-plugin-utils": "^7.28.6",
|
||||
"@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
|
||||
},
|
||||
"engines": {
|
||||
@@ -2134,14 +2134,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-unicode-property-regex": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz",
|
||||
"integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.28.6.tgz",
|
||||
"integrity": "sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.27.1",
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.28.5",
|
||||
"@babel/helper-plugin-utils": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -2168,14 +2168,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-unicode-sets-regex": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz",
|
||||
"integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.28.6.tgz",
|
||||
"integrity": "sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.27.1",
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
"@babel/helper-create-regexp-features-plugin": "^7.28.5",
|
||||
"@babel/helper-plugin-utils": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -2307,33 +2307,33 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/template": {
|
||||
"version": "7.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
|
||||
"integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz",
|
||||
"integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.27.1",
|
||||
"@babel/parser": "^7.27.2",
|
||||
"@babel/types": "^7.27.1"
|
||||
"@babel/code-frame": "^7.28.6",
|
||||
"@babel/parser": "^7.28.6",
|
||||
"@babel/types": "^7.28.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/traverse": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz",
|
||||
"integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.6.tgz",
|
||||
"integrity": "sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.27.1",
|
||||
"@babel/generator": "^7.28.5",
|
||||
"@babel/code-frame": "^7.28.6",
|
||||
"@babel/generator": "^7.28.6",
|
||||
"@babel/helper-globals": "^7.28.0",
|
||||
"@babel/parser": "^7.28.5",
|
||||
"@babel/template": "^7.27.2",
|
||||
"@babel/types": "^7.28.5",
|
||||
"@babel/parser": "^7.28.6",
|
||||
"@babel/template": "^7.28.6",
|
||||
"@babel/types": "^7.28.6",
|
||||
"debug": "^4.3.1"
|
||||
},
|
||||
"engines": {
|
||||
@@ -2341,14 +2341,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/traverse/node_modules/@babel/generator": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz",
|
||||
"integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.6.tgz",
|
||||
"integrity": "sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.28.5",
|
||||
"@babel/types": "^7.28.5",
|
||||
"@babel/parser": "^7.28.6",
|
||||
"@babel/types": "^7.28.6",
|
||||
"@jridgewell/gen-mapping": "^0.3.12",
|
||||
"@jridgewell/trace-mapping": "^0.3.28",
|
||||
"jsesc": "^3.0.2"
|
||||
@@ -2358,9 +2358,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/types": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz",
|
||||
"integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.6.tgz",
|
||||
"integrity": "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -3994,32 +3994,29 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@ngx-translate/core": {
|
||||
"version": "15.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-15.0.0.tgz",
|
||||
"integrity": "sha512-Am5uiuR0bOOxyoercDnAA3rJVizo4RRqJHo8N3RqJ+XfzVP/I845yEnMADykOHvM6HkVm4SZSnJBOiz0Anx5BA==",
|
||||
"license": "SEE LICENSE IN LICENSE",
|
||||
"engines": {
|
||||
"node": "^16.13.0 || >=18.10.0"
|
||||
"version": "17.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-17.0.0.tgz",
|
||||
"integrity": "sha512-Rft2D5ns2pq4orLZjEtx1uhNuEBerUdpFUG1IcqtGuipj6SavgB8SkxtNQALNDA+EVlvsNCCjC2ewZVtUeN6rg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": ">=16.0.0",
|
||||
"@angular/core": ">=16.0.0",
|
||||
"rxjs": "^6.5.5 || ^7.4.0"
|
||||
"@angular/common": ">=16",
|
||||
"@angular/core": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/@ngx-translate/http-loader": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@ngx-translate/http-loader/-/http-loader-8.0.0.tgz",
|
||||
"integrity": "sha512-SFMsdUcmHF5OdZkL1CHEoSAwbP5EbAOPTLLboOCRRoOg21P4GJx+51jxGdJeGve6LSKLf4Pay7BkTwmE6vxYlg==",
|
||||
"license": "SEE LICENSE IN LICENSE",
|
||||
"engines": {
|
||||
"node": "^16.13.0 || >=18.10.0"
|
||||
"version": "17.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@ngx-translate/http-loader/-/http-loader-17.0.0.tgz",
|
||||
"integrity": "sha512-hgS8sa0ARjH9ll3PhkLTufeVXNI2DNR2uFKDhBgq13siUXzzVr/a31M6zgecrtwbA34iaBV01hsTMbMS8V7iIw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": ">=16.0.0",
|
||||
"@angular/core": ">=16.0.0",
|
||||
"@ngx-translate/core": ">=15.0.0",
|
||||
"rxjs": "^6.5.5 || ^7.4.0"
|
||||
"@angular/common": ">=16",
|
||||
"@angular/core": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/@nodelib/fs.scandir": {
|
||||
@@ -5370,9 +5367,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "25.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.6.tgz",
|
||||
"integrity": "sha512-NNu0sjyNxpoiW3YuVFfNz7mxSQ+S4X2G28uqg2s+CzoqoQjLPsWSbsFFyztIAqt2vb8kfEAsJNepMGPTxFDx3Q==",
|
||||
"version": "25.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.8.tgz",
|
||||
"integrity": "sha512-powIePYMmC3ibL0UJ2i2s0WIbq6cg6UyVFQxSCpaPxxzAaziRfimGivjdF943sSGV6RADVbk0Nvlm5P/FB44Zg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -10714,19 +10711,19 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ng2-charts": {
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/ng2-charts/-/ng2-charts-5.0.4.tgz",
|
||||
"integrity": "sha512-AnOZ2KSRw7QjiMMNtXz9tdnO+XrIKP/2MX1TfqEEo2fwFU5c8LFJIYqmkMPkIzAEm/U9y/1psA5TDNmxxjEdgA==",
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ng2-charts/-/ng2-charts-8.0.0.tgz",
|
||||
"integrity": "sha512-nofsNHI2Zt+EAwT+BJBVg0kgOhNo9ukO4CxULlaIi7VwZSr7I1km38kWSoU41Oq6os6qqIh5srnL+CcV+RFPFA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"lodash-es": "^4.17.15",
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/cdk": ">=16.0.0",
|
||||
"@angular/common": ">=16.0.0",
|
||||
"@angular/core": ">=16.0.0",
|
||||
"@angular/platform-browser": ">=16.0.0",
|
||||
"@angular/cdk": ">=19.0.0",
|
||||
"@angular/common": ">=19.0.0",
|
||||
"@angular/core": ">=19.0.0",
|
||||
"@angular/platform-browser": ">=19.0.0",
|
||||
"chart.js": "^3.4.0 || ^4.0.0",
|
||||
"rxjs": "^6.5.3 || ^7.4.0"
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build --configuration production --build-optimizer=true --aot=true --optimization=true --progress=true",
|
||||
"build": "ng build",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e"
|
||||
@@ -22,10 +22,10 @@
|
||||
"@angular/platform-browser": "^19.2.6",
|
||||
"@angular/platform-browser-dynamic": "^19.2.6",
|
||||
"@angular/router": "^19.2.6",
|
||||
"@ngx-translate/core": "^15.0.0",
|
||||
"@ngx-translate/http-loader": "^8.0.0",
|
||||
"@ngx-translate/core": "^17.0.0",
|
||||
"@ngx-translate/http-loader": "^17.0.0",
|
||||
"chart.js": "^4.3.0",
|
||||
"ng2-charts": "^5.0.2",
|
||||
"ng2-charts": "^8.0.0",
|
||||
"rxjs": "~7.8.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zone.js": "~0.15.0"
|
||||
|
||||
33
Front/skydivelogs-app/src/app/app.base.component.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
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,4 +1,4 @@
|
||||
.hamburger__icon {
|
||||
/* .hamburger__icon {
|
||||
position: relative;
|
||||
height: 1rem;
|
||||
margin-right: 1rem;
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
.hamburger__icon__fill {
|
||||
fill: #424242
|
||||
}
|
||||
} */
|
||||
|
||||
.navigation.side-menu-active {
|
||||
left: 0px;
|
||||
|
||||
@@ -1,76 +1,190 @@
|
||||
<mat-toolbar *ngIf="this.show()">
|
||||
<button mat-icon-button (click)="snav.toggle()"><mat-icon>menu</mat-icon></button>
|
||||
<h2>{{ title }}</h2>
|
||||
<mat-select (selectionChange)="switchLang($event)" [(value)]="selectedLanguageFlag"
|
||||
style="margin-left:50px; width: 60px;" >
|
||||
<mat-icon svgIcon="menu" (click)="snav.toggle()"></mat-icon>
|
||||
<h2>{{ translatedTitle }}</h2>
|
||||
|
||||
<mat-select
|
||||
[(value)]="selectedLanguageFlag"
|
||||
(selectionChange)="switchLang($event)"
|
||||
style="margin-left: 50px; width: 100px"
|
||||
>
|
||||
<mat-select-trigger>
|
||||
<img src="{{ 'assets/img/' + selectedLanguageFlag + '.svg' }}" style="width: 30px;">
|
||||
<img
|
||||
src="{{ 'assets/img/' + selectedLanguageFlag + '.svg' }}"
|
||||
style="width: 30px"
|
||||
/>
|
||||
</mat-select-trigger>
|
||||
<mat-option value="fr">
|
||||
<img src="assets/img/fr.svg" style="width: 30px;">
|
||||
<img src="assets/img/fr.svg" style="width: 30px" />
|
||||
</mat-option>
|
||||
<mat-option value="en">
|
||||
<img src="assets/img/en.svg" style="width: 30px;">
|
||||
<img src="assets/img/en.svg" style="width: 30px" />
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-toolbar>
|
||||
|
||||
<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-icon aria-hidden="false" aria-label="Summary">timeline</mat-icon>
|
||||
<a routerLink="/summary" routerLinkActive="active" (click)="snav.toggle()" skipLocationChange>{{ 'App_Nav_Summary' | translate }}</a>
|
||||
<hr class="splitter">
|
||||
<mat-icon
|
||||
aria-hidden="false"
|
||||
aria-label="Summary"
|
||||
svgIcon="summary"
|
||||
></mat-icon>
|
||||
<a
|
||||
routerLink="/summary"
|
||||
routerLinkActive="active"
|
||||
(click)="snav.toggle()"
|
||||
skipLocationChange
|
||||
>{{ "App_Nav_Summary" | translate }}</a
|
||||
>
|
||||
<hr class="splitter" />
|
||||
</mat-nav-list>
|
||||
<mat-nav-list>
|
||||
<mat-icon aria-hidden="false" aria-label="List of jumps">list_alt</mat-icon>
|
||||
<a routerLink="/jumps" routerLinkActive="active" (click)="snav.toggle()" skipLocationChange>{{ 'App_Nav_Jumps' | translate }}</a>
|
||||
<mat-icon
|
||||
aria-hidden="false"
|
||||
aria-label="List of jumps"
|
||||
svgIcon="list"
|
||||
></mat-icon>
|
||||
<a
|
||||
routerLink="/jumps"
|
||||
routerLinkActive="active"
|
||||
(click)="snav.toggle()"
|
||||
skipLocationChange
|
||||
>{{ "App_Nav_Jumps" | translate }}</a
|
||||
>
|
||||
</mat-nav-list>
|
||||
<mat-nav-list>
|
||||
<mat-icon aria-hidden="false" aria-label="Add jumps">add_circle</mat-icon>
|
||||
<a routerLink="/newjump" routerLinkActive="active" (click)="snav.toggle()" skipLocationChange>{{ 'App_Nav_NewJump' | translate }}</a>
|
||||
<hr class="splitter">
|
||||
<mat-icon
|
||||
aria-hidden="false"
|
||||
aria-label="Add jumps"
|
||||
svgIcon="add"
|
||||
></mat-icon>
|
||||
<a
|
||||
routerLink="/newjump"
|
||||
routerLinkActive="active"
|
||||
(click)="snav.toggle()"
|
||||
skipLocationChange
|
||||
>{{ "App_Nav_NewJump" | translate }}</a
|
||||
>
|
||||
<hr class="splitter" />
|
||||
</mat-nav-list>
|
||||
<mat-nav-list>
|
||||
<mat-icon aria-hidden="false" aria-label="List of tunnel flights">list_alt</mat-icon>
|
||||
<a routerLink="/tunnelFlights" routerLinkActive="active" (click)="snav.toggle()" skipLocationChange>{{ 'App_Nav_TunnelFlights' | translate }}</a>
|
||||
<mat-icon
|
||||
aria-hidden="false"
|
||||
aria-label="List of tunnel flights"
|
||||
svgIcon="list"
|
||||
></mat-icon>
|
||||
<a
|
||||
routerLink="/tunnelFlights"
|
||||
routerLinkActive="active"
|
||||
(click)="snav.toggle()"
|
||||
skipLocationChange
|
||||
>{{ "App_Nav_TunnelFlights" | translate }}</a
|
||||
>
|
||||
</mat-nav-list>
|
||||
<mat-nav-list>
|
||||
<mat-icon aria-hidden="false" aria-label="Add flights in tunnel">add_circle</mat-icon>
|
||||
<a routerLink="/newTunnelFlight" routerLinkActive="active" (click)="snav.toggle()" skipLocationChange>{{ 'App_Nav_NewTunnelFlight' | translate }}</a>
|
||||
<hr class="splitter">
|
||||
<mat-icon
|
||||
aria-hidden="false"
|
||||
aria-label="Add flights in tunnel"
|
||||
svgIcon="add"
|
||||
></mat-icon>
|
||||
<a
|
||||
routerLink="/newTunnelFlight"
|
||||
routerLinkActive="active"
|
||||
(click)="snav.toggle()"
|
||||
skipLocationChange
|
||||
>{{ "App_Nav_NewTunnelFlight" | translate }}</a
|
||||
>
|
||||
<hr class="splitter" />
|
||||
</mat-nav-list>
|
||||
<mat-nav-list>
|
||||
<mat-icon aria-hidden="false" aria-label="Dropzones">store</mat-icon>
|
||||
<a routerLink="/dzs" routerLinkActive="active" (click)="snav.toggle()" skipLocationChange>{{ 'App_Nav_Dzs' | translate }}</a>
|
||||
<mat-icon
|
||||
aria-hidden="false"
|
||||
aria-label="Dropzones"
|
||||
svgIcon="dz"
|
||||
></mat-icon>
|
||||
<a
|
||||
routerLink="/dzs"
|
||||
routerLinkActive="active"
|
||||
(click)="snav.toggle()"
|
||||
skipLocationChange
|
||||
>{{ "App_Nav_Dzs" | translate }}</a
|
||||
>
|
||||
</mat-nav-list>
|
||||
<mat-nav-list>
|
||||
<mat-icon aria-hidden="false" aria-label="Aircrafts">airplanemode_active</mat-icon>
|
||||
<a routerLink="/aircrafts" routerLinkActive="active" (click)="snav.toggle()" skipLocationChange>{{ 'App_Nav_Aircrafts' | translate }}</a>
|
||||
<mat-icon
|
||||
aria-hidden="false"
|
||||
aria-label="Aircrafts"
|
||||
svgIcon="aircraft"
|
||||
></mat-icon>
|
||||
<a
|
||||
routerLink="/aircrafts"
|
||||
routerLinkActive="active"
|
||||
(click)="snav.toggle()"
|
||||
skipLocationChange
|
||||
>{{ "App_Nav_Aircrafts" | translate }}</a
|
||||
>
|
||||
</mat-nav-list>
|
||||
<mat-nav-list>
|
||||
<mat-icon aria-hidden="false" aria-label="List of jump types">flight_land</mat-icon>
|
||||
<a routerLink="/jumpTypes" routerLinkActive="active" (click)="snav.toggle()" skipLocationChange>{{ 'App_Nav_JumpTypes' | translate }}</a>
|
||||
<mat-icon
|
||||
aria-hidden="false"
|
||||
aria-label="List of jump types"
|
||||
svgIcon="flight_land"
|
||||
></mat-icon>
|
||||
<a
|
||||
routerLink="/jumpTypes"
|
||||
routerLinkActive="active"
|
||||
(click)="snav.toggle()"
|
||||
skipLocationChange
|
||||
>{{ "App_Nav_JumpTypes" | translate }}</a
|
||||
>
|
||||
</mat-nav-list>
|
||||
<mat-nav-list>
|
||||
<mat-icon aria-hidden="false" aria-label="List of gears">settings_input_antenna</mat-icon>
|
||||
<a routerLink="/gears" routerLinkActive="active" (click)="snav.toggle()" skipLocationChange>{{ 'App_Nav_Gears' | translate }}</a>
|
||||
<mat-icon
|
||||
aria-hidden="false"
|
||||
aria-label="List of gears"
|
||||
svgIcon="gear"
|
||||
></mat-icon>
|
||||
<a
|
||||
routerLink="/gears"
|
||||
routerLinkActive="active"
|
||||
(click)="snav.toggle()"
|
||||
skipLocationChange
|
||||
>{{ "App_Nav_Gears" | translate }}</a
|
||||
>
|
||||
</mat-nav-list>
|
||||
<mat-nav-list *ngIf="currentUser">
|
||||
<hr class="splitter">
|
||||
<mat-icon aria-hidden="false" aria-label="User account">account_box</mat-icon>
|
||||
<a routerLink="/user" routerLinkActive="active" (click)="snav.toggle()" skipLocationChange>
|
||||
<hr class="splitter" />
|
||||
<mat-icon
|
||||
aria-hidden="false"
|
||||
aria-label="User account"
|
||||
svgIcon="account"
|
||||
></mat-icon>
|
||||
<a
|
||||
routerLink="/user"
|
||||
routerLinkActive="active"
|
||||
(click)="snav.toggle()"
|
||||
skipLocationChange
|
||||
>
|
||||
{{ this.currentUser.firstName }} {{ this.currentUser.lastName }}
|
||||
</a>
|
||||
</mat-nav-list>
|
||||
<mat-nav-list *ngIf="currentUser">
|
||||
<mat-icon aria-hidden="false" aria-label="To logout">logout</mat-icon>
|
||||
<span (click)="snav.toggle(); logout()" style="cursor: pointer;">{{ 'App_Nav_Logout' | translate }}</span>
|
||||
<mat-icon
|
||||
aria-hidden="false"
|
||||
aria-label="To logout"
|
||||
svgIcon="logout"
|
||||
></mat-icon>
|
||||
<span (click)="snav.toggle(); logout()" style="cursor: pointer">{{
|
||||
"App_Nav_Logout" | translate
|
||||
}}</span>
|
||||
</mat-nav-list>
|
||||
</mat-sidenav>
|
||||
|
||||
<mat-sidenav-content>
|
||||
<router-outlet></router-outlet>
|
||||
<footer style="text-align: right;">{{ 'App_Footer' | translate }}{{ version }} - @Séb</footer>
|
||||
<footer style="text-align: right">
|
||||
{{ "App_Footer" | translate }}{{ version }} - @Séb
|
||||
</footer>
|
||||
</mat-sidenav-content>
|
||||
</mat-sidenav-container>
|
||||
@@ -1,6 +1,22 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { Router } from "@angular/router";
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
import { Component, inject, OnInit } from "@angular/core";
|
||||
import { Router, RouterLink, RouterOutlet } from "@angular/router";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { DomSanitizer } from "@angular/platform-browser";
|
||||
import { MatToolbarModule } from "@angular/material/toolbar";
|
||||
import {
|
||||
IconResolver,
|
||||
MatIconModule,
|
||||
MatIconRegistry,
|
||||
} from "@angular/material/icon";
|
||||
import { MatSelectModule } from "@angular/material/select";
|
||||
import { MatOptionModule } from "@angular/material/core";
|
||||
import { MatSidenavModule } from "@angular/material/sidenav";
|
||||
import { MatListModule } from "@angular/material/list";
|
||||
import {
|
||||
TranslateService,
|
||||
TranslateModule,
|
||||
TranslatePipe,
|
||||
} from "@ngx-translate/core";
|
||||
|
||||
import { User } from "../models/user";
|
||||
import { CacheApiKey } from "../models/cache-api-key.enum";
|
||||
@@ -14,31 +30,49 @@ import { ServiceCacheApi } from "../services/service-cache-api.service";
|
||||
selector: "app-root",
|
||||
templateUrl: "./app.component.html",
|
||||
styleUrls: ["./app.component.css"],
|
||||
standalone: false
|
||||
imports: [
|
||||
CommonModule,
|
||||
MatToolbarModule,
|
||||
MatIconModule,
|
||||
MatSelectModule,
|
||||
MatOptionModule,
|
||||
MatSidenavModule,
|
||||
MatListModule,
|
||||
RouterOutlet,
|
||||
RouterLink,
|
||||
TranslateModule,
|
||||
TranslatePipe,
|
||||
],
|
||||
})
|
||||
export class AppComponent implements OnInit {
|
||||
public title = "app";
|
||||
public translatedTitle = "???";
|
||||
public currentUser: User;
|
||||
public version: string;
|
||||
public selectedLanguageFlag: string;
|
||||
|
||||
constructor(private router: Router,
|
||||
constructor(
|
||||
private router: Router,
|
||||
private authenticationService: AuthenticationService,
|
||||
private serviceComm: ServiceComm,
|
||||
private serviceCacheApi: ServiceCacheApi,
|
||||
private translateService: TranslateService)
|
||||
{
|
||||
this.authenticationService.currentUser.subscribe(user => {
|
||||
private translateService: TranslateService,
|
||||
) {
|
||||
const sanitizer = inject(DomSanitizer);
|
||||
const resolver: IconResolver = (name) =>
|
||||
sanitizer.bypassSecurityTrustResourceUrl(`/assets/icon/${name}.svg`);
|
||||
const iconRegistry = inject(MatIconRegistry);
|
||||
iconRegistry.addSvgIconResolver(resolver);
|
||||
|
||||
this.authenticationService.currentUser.subscribe((user) => {
|
||||
if (user) {
|
||||
this.currentUser = user;
|
||||
this.translateService.addLangs(['en', 'fr']);
|
||||
this.translateService.addLangs(["en", "fr"]);
|
||||
this.translateService.use(user.language);
|
||||
this.selectedLanguageFlag = user.language;
|
||||
}
|
||||
});
|
||||
|
||||
ConfigurationHelper.settings.subscribe(settings =>
|
||||
{
|
||||
ConfigurationHelper.settings.subscribe((settings) => {
|
||||
if (settings != null) {
|
||||
this.version = settings.version;
|
||||
}
|
||||
@@ -46,7 +80,9 @@ export class AppComponent implements OnInit {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.serviceComm.componentTitle.subscribe(title => (this.title = title));
|
||||
this.serviceComm.componentTitle.subscribe(
|
||||
(title) => (this.translatedTitle = title),
|
||||
);
|
||||
}
|
||||
|
||||
public show() {
|
||||
|
||||
73
Front/skydivelogs-app/src/app/app.config.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import { inject, provideAppInitializer } from "@angular/core";
|
||||
import { ApplicationConfig, provideZoneChangeDetection } from "@angular/core";
|
||||
import { provideRouter } from "@angular/router";
|
||||
import { DatePipe } from "@angular/common";
|
||||
import { provideHttpClient, withInterceptors } from "@angular/common/http";
|
||||
|
||||
import { DateService } from "../services/date.service";
|
||||
import { AircraftService } from "../services/aircraft.service";
|
||||
import { DropzoneService } from "../services/dropzone.service";
|
||||
import { GearService } from "../services/gear.service";
|
||||
import { JumpService } from "../services/jump.service";
|
||||
import { JumpTypeService } from "../services/jump-type.service";
|
||||
import { StatsService } from "../services/stats.service";
|
||||
import { ServiceComm } from "../services/service-comm.service";
|
||||
import { RequestCache } from "../services/request-cache.service";
|
||||
import { ImageService } from "../services/image.service";
|
||||
import { ConfigurationHelper } from "../services/configuration-helper";
|
||||
import { ServiceCacheApi } from "../services/service-cache-api.service";
|
||||
import { TunnelService } from "../services/tunnel.service";
|
||||
import { TunnelFlightService } from "../services/tunnel-flight.service";
|
||||
|
||||
import { provideCharts, withDefaultRegisterables } from "ng2-charts";
|
||||
|
||||
import { JwtAuthInterceptor } from "../interceptor/jwt-auth.interceptor";
|
||||
import { ErrorInterceptor } from "../interceptor/error.interceptor";
|
||||
import { environment } from "../environments/environment";
|
||||
|
||||
import { routes } from "./app.routes";
|
||||
|
||||
import { provideTranslateService } from "@ngx-translate/core";
|
||||
import { provideTranslateHttpLoader } from "@ngx-translate/http-loader";
|
||||
|
||||
// Déclaration de la fonction d'initialisation de la configuration
|
||||
export function initConfig(configService: ConfigurationHelper) {
|
||||
return () => configService.load(environment.env);
|
||||
}
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [
|
||||
TunnelService,
|
||||
TunnelFlightService,
|
||||
ImageService,
|
||||
AircraftService,
|
||||
DropzoneService,
|
||||
GearService,
|
||||
JumpService,
|
||||
JumpTypeService,
|
||||
StatsService,
|
||||
ServiceComm,
|
||||
DateService,
|
||||
RequestCache,
|
||||
ConfigurationHelper,
|
||||
DatePipe,
|
||||
ServiceCacheApi,
|
||||
provideAppInitializer(() => {
|
||||
const initializerFn = initConfig(inject(ConfigurationHelper));
|
||||
return initializerFn();
|
||||
}),
|
||||
provideHttpClient(withInterceptors([JwtAuthInterceptor, ErrorInterceptor])),
|
||||
provideCharts(withDefaultRegisterables()),
|
||||
provideZoneChangeDetection({ eventCoalescing: true }),
|
||||
provideRouter(routes),
|
||||
provideHttpClient(),
|
||||
provideTranslateService({
|
||||
loader: provideTranslateHttpLoader({
|
||||
prefix: "/assets/i18n/",
|
||||
suffix: ".json",
|
||||
}),
|
||||
fallbackLang: "en",
|
||||
lang: "en",
|
||||
}),
|
||||
],
|
||||
};
|
||||
@@ -1,240 +0,0 @@
|
||||
import { BrowserModule } from "@angular/platform-browser";
|
||||
import { NgModule, inject, provideAppInitializer } from "@angular/core";
|
||||
import { RouterModule, Routes } from "@angular/router";
|
||||
import {
|
||||
HttpClient,
|
||||
HttpClientModule,
|
||||
HTTP_INTERCEPTORS,
|
||||
} from "@angular/common/http";
|
||||
import { DatePipe } from "@angular/common";
|
||||
import { TranslateLoader, TranslateModule } from "@ngx-translate/core";
|
||||
import { TranslateHttpLoader } from "@ngx-translate/http-loader";
|
||||
|
||||
import { AppComponent } from "./app.component";
|
||||
import { environment } from "../environments/environment";
|
||||
|
||||
import { SummaryComponent } from "./summary/summary.component";
|
||||
import { ListOfJumpsComponent } from "./list-of-jumps/list-of-jumps.component";
|
||||
import { ListOfDzsComponent } from "./list-of-dzs/list-of-dzs.component";
|
||||
import { NewJumpComponent } from "./new-jump/new-jump.component";
|
||||
import { ListOfAircraftsComponent } from "./list-of-aircrafts/list-of-aircrafts.component";
|
||||
import { ListOfJumpTypesComponent } from "./list-of-jump-types/list-of-jump-types.component";
|
||||
import { ListOfGearsComponent } from "./list-of-gears/list-of-gears.component";
|
||||
import { NewAircraftComponent } from "./new-aircraft/new-aircraft.component";
|
||||
import { NewGearComponent } from "./new-gear/new-gear.component";
|
||||
import { NewDropZoneComponent } from "./new-drop-zone/new-drop-zone.component";
|
||||
import { NewJumpTypeComponent } from "./new-jump-type/new-jump-type.component";
|
||||
import { DefaultComponent } from "./default/default.component";
|
||||
import { LoginComponent } from "./login/login.component";
|
||||
import { CreateUserComponent } from "./create-user/create-user.component";
|
||||
import { LoginUserComponent } from "./login-user/login-user.component";
|
||||
import { UserProfileComponent } from "./user-profile/user-profile.component";
|
||||
import { ListOfImagesComponent } from "./list-of-images/list-of-images.component";
|
||||
import { JumpInfosComponent } from "./jump-infos/jump-infos.component";
|
||||
import { NewTunnelFlightComponent } from "./new-tunnel-flight/new-tunnel-flight.component";
|
||||
import { ListOfTunnelFlightsComponent } from "./list-of-tunnel-flights/list-of-tunnel-flights.component";
|
||||
|
||||
import { DateService } from "../services/date.service";
|
||||
import { AircraftService } from "../services/aircraft.service";
|
||||
import { DropzoneService } from "../services/dropzone.service";
|
||||
import { GearService } from "../services/gear.service";
|
||||
import { JumpService } from "../services/jump.service";
|
||||
import { JumpTypeService } from "../services/jump-type.service";
|
||||
import { StatsService } from "../services/stats.service";
|
||||
import { ServiceComm } from "../services/service-comm.service";
|
||||
import { RequestCache } from "../services/request-cache.service";
|
||||
import { AuthGuardService } from "../services/auth-guard.service";
|
||||
import { ImageService } from "../services/image.service";
|
||||
import { ConfigurationHelper } from "../services/configuration-helper";
|
||||
import { ServiceCacheApi } from "../services/service-cache-api.service";
|
||||
import { TunnelService } from "../services/tunnel.service";
|
||||
import { TunnelFlightService } from "../services/tunnel-flight.service";
|
||||
|
||||
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
||||
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
|
||||
import { MatAutocompleteModule } from "@angular/material/autocomplete";
|
||||
import { MatButtonModule } from "@angular/material/button";
|
||||
import { MatCheckboxModule } from "@angular/material/checkbox";
|
||||
import { MatOptionModule, MatNativeDateModule } from "@angular/material/core";
|
||||
import { MatDatepickerModule } from "@angular/material/datepicker";
|
||||
import { MatFormFieldModule } from "@angular/material/form-field";
|
||||
import { MatIconModule } from "@angular/material/icon";
|
||||
import { MatInputModule } from "@angular/material/input";
|
||||
import { MatPaginatorModule } from "@angular/material/paginator";
|
||||
import { MatProgressSpinnerModule } from "@angular/material/progress-spinner";
|
||||
import { MatProgressBarModule } from "@angular/material/progress-bar";
|
||||
import { MatSelectModule } from "@angular/material/select";
|
||||
import { MatTableModule } from "@angular/material/table";
|
||||
import { MatTabsModule } from "@angular/material/tabs";
|
||||
import { MatDialogModule } from "@angular/material/dialog";
|
||||
import { MatCardModule } from "@angular/material/card";
|
||||
import { MatRadioModule } from "@angular/material/radio";
|
||||
import { MatSidenavModule } from "@angular/material/sidenav";
|
||||
import { MatListModule } from "@angular/material/list";
|
||||
import { MatToolbarModule } from "@angular/material/toolbar";
|
||||
import { NgChartsModule } from "ng2-charts";
|
||||
|
||||
import { JwtAuthInterceptor } from "../interceptor/jwt-auth.interceptor";
|
||||
import { ErrorInterceptor } from "../interceptor/error.interceptor";
|
||||
|
||||
const appRoutes: Routes = [
|
||||
{
|
||||
path: "",
|
||||
component: DefaultComponent,
|
||||
canActivate: [AuthGuardService],
|
||||
},
|
||||
{
|
||||
path: "summary",
|
||||
component: SummaryComponent,
|
||||
canActivate: [AuthGuardService],
|
||||
},
|
||||
{
|
||||
path: "jumps",
|
||||
component: ListOfJumpsComponent,
|
||||
canActivate: [AuthGuardService],
|
||||
},
|
||||
{
|
||||
path: "dzs",
|
||||
component: ListOfDzsComponent,
|
||||
canActivate: [AuthGuardService],
|
||||
},
|
||||
{
|
||||
path: "newjump",
|
||||
component: NewJumpComponent,
|
||||
canActivate: [AuthGuardService],
|
||||
},
|
||||
{
|
||||
path: "aircrafts",
|
||||
component: ListOfAircraftsComponent,
|
||||
canActivate: [AuthGuardService],
|
||||
},
|
||||
{
|
||||
path: "jumpTypes",
|
||||
component: ListOfJumpTypesComponent,
|
||||
canActivate: [AuthGuardService],
|
||||
},
|
||||
{
|
||||
path: "gears",
|
||||
component: ListOfGearsComponent,
|
||||
canActivate: [AuthGuardService],
|
||||
},
|
||||
{
|
||||
path: "user",
|
||||
component: UserProfileComponent,
|
||||
canActivate: [AuthGuardService],
|
||||
},
|
||||
{
|
||||
path: "newTunnelFlight",
|
||||
component: NewTunnelFlightComponent,
|
||||
canActivate: [AuthGuardService],
|
||||
},
|
||||
{
|
||||
path: "tunnelFlights",
|
||||
component: ListOfTunnelFlightsComponent,
|
||||
canActivate: [AuthGuardService],
|
||||
},
|
||||
|
||||
{ path: "login", component: LoginComponent },
|
||||
];
|
||||
|
||||
// AOT compilation support
|
||||
export function httpTranslateLoader(http: HttpClient) {
|
||||
return new TranslateHttpLoader(http);
|
||||
}
|
||||
|
||||
// Déclaration de la fonction d'initialisation de la configuration
|
||||
export function initConfig(configService: ConfigurationHelper) {
|
||||
return () => configService.load(environment.env);
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
SummaryComponent,
|
||||
ListOfJumpsComponent,
|
||||
ListOfDzsComponent,
|
||||
NewJumpComponent,
|
||||
ListOfAircraftsComponent,
|
||||
ListOfJumpTypesComponent,
|
||||
ListOfGearsComponent,
|
||||
NewAircraftComponent,
|
||||
NewGearComponent,
|
||||
NewDropZoneComponent,
|
||||
NewJumpTypeComponent,
|
||||
DefaultComponent,
|
||||
LoginComponent,
|
||||
CreateUserComponent,
|
||||
LoginUserComponent,
|
||||
UserProfileComponent,
|
||||
ListOfImagesComponent,
|
||||
JumpInfosComponent,
|
||||
NewTunnelFlightComponent,
|
||||
ListOfTunnelFlightsComponent,
|
||||
],
|
||||
imports: [
|
||||
RouterModule.forRoot(
|
||||
appRoutes,
|
||||
{ enableTracing: !environment.production } // <-- debugging purposes only
|
||||
// { enableTracing: !environment.production, relativeLinkResolution: 'legacy' } // <-- debugging purposes only
|
||||
),
|
||||
TranslateModule.forRoot({
|
||||
loader: {
|
||||
provide: TranslateLoader,
|
||||
useFactory: httpTranslateLoader,
|
||||
deps: [HttpClient],
|
||||
},
|
||||
}),
|
||||
ReactiveFormsModule,
|
||||
FormsModule,
|
||||
BrowserModule,
|
||||
BrowserAnimationsModule,
|
||||
MatPaginatorModule,
|
||||
MatTableModule,
|
||||
MatSelectModule,
|
||||
MatOptionModule,
|
||||
MatFormFieldModule,
|
||||
MatCheckboxModule,
|
||||
MatDatepickerModule,
|
||||
MatNativeDateModule,
|
||||
MatInputModule,
|
||||
MatButtonModule,
|
||||
MatIconModule,
|
||||
MatAutocompleteModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatProgressBarModule,
|
||||
MatTabsModule,
|
||||
MatDialogModule,
|
||||
MatCardModule,
|
||||
MatRadioModule,
|
||||
MatSidenavModule,
|
||||
MatListModule,
|
||||
MatToolbarModule,
|
||||
NgChartsModule,
|
||||
],
|
||||
exports: [HttpClientModule],
|
||||
providers: [
|
||||
TunnelService,
|
||||
TunnelFlightService,
|
||||
ImageService,
|
||||
AircraftService,
|
||||
DropzoneService,
|
||||
GearService,
|
||||
JumpService,
|
||||
JumpTypeService,
|
||||
StatsService,
|
||||
ServiceComm,
|
||||
DateService,
|
||||
RequestCache,
|
||||
ConfigurationHelper,
|
||||
DatePipe,
|
||||
ServiceCacheApi,
|
||||
provideAppInitializer(() => {
|
||||
const initializerFn = (initConfig)(inject(ConfigurationHelper));
|
||||
return initializerFn();
|
||||
}),
|
||||
{ provide: HTTP_INTERCEPTORS, useClass: JwtAuthInterceptor, multi: true },
|
||||
{ provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true },
|
||||
],
|
||||
bootstrap: [AppComponent],
|
||||
})
|
||||
export class AppModule {}
|
||||
93
Front/skydivelogs-app/src/app/app.routes.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import { Routes } from "@angular/router";
|
||||
|
||||
import { AuthGuardService } from "../services/auth-guard.service";
|
||||
|
||||
export const routes: Routes = [
|
||||
{
|
||||
path: "",
|
||||
loadComponent: () =>
|
||||
import("./default/default.component").then((m) => m.DefaultComponent),
|
||||
canActivate: [AuthGuardService],
|
||||
},
|
||||
{
|
||||
path: "summary",
|
||||
loadComponent: () =>
|
||||
import("./summary/summary.component").then((m) => m.SummaryComponent),
|
||||
canActivate: [AuthGuardService],
|
||||
},
|
||||
{
|
||||
path: "jumps",
|
||||
loadComponent: () =>
|
||||
import("./list-of-jumps/list-of-jumps.component").then(
|
||||
(m) => m.ListOfJumpsComponent,
|
||||
),
|
||||
canActivate: [AuthGuardService],
|
||||
},
|
||||
{
|
||||
path: "dzs",
|
||||
loadComponent: () =>
|
||||
import("./list-of-dzs/list-of-dzs.component").then(
|
||||
(m) => m.ListOfDzsComponent,
|
||||
),
|
||||
canActivate: [AuthGuardService],
|
||||
},
|
||||
{
|
||||
path: "newjump",
|
||||
loadComponent: () =>
|
||||
import("./new-jump/new-jump.component").then((m) => m.NewJumpComponent),
|
||||
canActivate: [AuthGuardService],
|
||||
},
|
||||
{
|
||||
path: "aircrafts",
|
||||
loadComponent: () =>
|
||||
import("./list-of-aircrafts/list-of-aircrafts.component").then(
|
||||
(m) => m.ListOfAircraftsComponent,
|
||||
),
|
||||
canActivate: [AuthGuardService],
|
||||
},
|
||||
{
|
||||
path: "jumpTypes",
|
||||
loadComponent: () =>
|
||||
import("./list-of-jump-types/list-of-jump-types.component").then(
|
||||
(m) => m.ListOfJumpTypesComponent,
|
||||
),
|
||||
canActivate: [AuthGuardService],
|
||||
},
|
||||
{
|
||||
path: "gears",
|
||||
loadComponent: () =>
|
||||
import("./list-of-gears/list-of-gears.component").then(
|
||||
(m) => m.ListOfGearsComponent,
|
||||
),
|
||||
canActivate: [AuthGuardService],
|
||||
},
|
||||
{
|
||||
path: "user",
|
||||
loadComponent: () =>
|
||||
import("./user-profile/user-profile.component").then(
|
||||
(m) => m.UserProfileComponent,
|
||||
),
|
||||
canActivate: [AuthGuardService],
|
||||
},
|
||||
{
|
||||
path: "newTunnelFlight",
|
||||
loadComponent: () =>
|
||||
import("./new-tunnel-flight/new-tunnel-flight.component").then(
|
||||
(m) => m.NewTunnelFlightComponent,
|
||||
),
|
||||
canActivate: [AuthGuardService],
|
||||
},
|
||||
{
|
||||
path: "tunnelFlights",
|
||||
loadComponent: () =>
|
||||
import("./list-of-tunnel-flights/list-of-tunnel-flights.component").then(
|
||||
(m) => m.ListOfTunnelFlightsComponent,
|
||||
),
|
||||
canActivate: [AuthGuardService],
|
||||
},
|
||||
{
|
||||
path: "login",
|
||||
loadComponent: () =>
|
||||
import("./login/login.component").then((m) => m.LoginComponent),
|
||||
},
|
||||
];
|
||||
@@ -1,72 +1,104 @@
|
||||
<form [formGroup]="createForm" (ngSubmit)="onCreateSubmit()" autocomplete="off" style="padding: 10px;">
|
||||
<form
|
||||
focusInvalidInput
|
||||
autocomplete="off"
|
||||
style="padding: 10px"
|
||||
(ngSubmit)="onCreateSubmit()"
|
||||
[formGroup]="createForm"
|
||||
>
|
||||
<p>
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'LoginCreateUser_Firstname' | translate }}</mat-label>
|
||||
<input matInput type="text" formControlName="firstname"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls.firstname.errors }" tabindex="0" />
|
||||
<mat-error *ngIf="formCtrls.firstname.hasError('required')">
|
||||
{{ 'LoginCreateUser_FirstnameRequired' | translate }}
|
||||
<mat-label>{{ "LoginCreateUser_Firstname" | translate }}</mat-label>
|
||||
<input
|
||||
type="text"
|
||||
matInput
|
||||
#firstname="matInput"
|
||||
formControlName="firstname"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls['firstname'].errors }"
|
||||
tabindex="0"
|
||||
/>
|
||||
<mat-error *ngIf="formCtrls['firstname'].hasError('required')">
|
||||
{{ "LoginCreateUser_FirstnameRequired" | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="formCtrls.firstname.hasError('minlength')">
|
||||
{{ 'LoginCreateUser_FirstnamePattern' | translate }}
|
||||
<mat-error *ngIf="formCtrls['firstname'].hasError('minlength')">
|
||||
{{ "LoginCreateUser_FirstnamePattern" | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</p>
|
||||
<p>
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'LoginCreateUser_Lastname' | translate }}</mat-label>
|
||||
<input matInput type="text" formControlName="lastname"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls.lastname.errors }" tabindex="1" />
|
||||
<mat-error *ngIf="formCtrls.lastname.hasError('required')">
|
||||
{{ 'LoginCreateUser_LastnameRequired' | translate }}
|
||||
<mat-label>{{ "LoginCreateUser_Lastname" | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
type="text"
|
||||
formControlName="lastname"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls['lastname'].errors }"
|
||||
tabindex="1"
|
||||
/>
|
||||
<mat-error *ngIf="formCtrls['lastname'].hasError('required')">
|
||||
{{ "LoginCreateUser_LastnameRequired" | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="formCtrls.lastname.hasError('minlength')">
|
||||
{{ 'LoginCreateUser_LastnamePattern' | translate }}
|
||||
<mat-error *ngIf="formCtrls['lastname'].hasError('minlength')">
|
||||
{{ "LoginCreateUser_LastnamePattern" | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</p>
|
||||
<p>
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'LoginCreateUser_Email' | translate }}</mat-label>
|
||||
<input matInput type="email" formControlName="email"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls.email.errors }" tabindex="3" />
|
||||
<mat-error *ngIf="formCtrls.email.hasError('required')">
|
||||
{{ 'LoginCreateUser_EmailRequired' | translate }}
|
||||
<mat-label>{{ "LoginCreateUser_Email" | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
type="email"
|
||||
formControlName="email"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls['email'].errors }"
|
||||
tabindex="3"
|
||||
/>
|
||||
<mat-error *ngIf="formCtrls['email'].hasError('required')">
|
||||
{{ "LoginCreateUser_EmailRequired" | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="formCtrls.email.hasError('email')">
|
||||
{{ 'LoginCreateUser_EmailPattern' | translate }}
|
||||
<mat-error *ngIf="formCtrls['email'].hasError('email')">
|
||||
{{ "LoginCreateUser_EmailPattern" | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</p>
|
||||
<p>
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'LoginCreateUser_Username' | translate }}</mat-label>
|
||||
<input matInput type="text" formControlName="username"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls.username.errors }" tabindex="4" />
|
||||
<mat-error *ngIf="formCtrls.username.hasError('required')">
|
||||
{{ 'LoginCreateUser_UsernameRequired' | translate }}
|
||||
<mat-label>{{ "LoginCreateUser_Username" | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
type="text"
|
||||
formControlName="username"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls['username'].errors }"
|
||||
tabindex="4"
|
||||
/>
|
||||
<mat-error *ngIf="formCtrls['username'].hasError('required')">
|
||||
{{ "LoginCreateUser_UsernameRequired" | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="formCtrls.username.hasError('minlength')">
|
||||
{{ 'LoginCreateUser_UsernamePattern' | translate }}
|
||||
<mat-error *ngIf="formCtrls['username'].hasError('minlength')">
|
||||
{{ "LoginCreateUser_UsernamePattern" | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</p>
|
||||
<p>
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'LoginCreateUser_Password' | translate }}</mat-label>
|
||||
<input matInput type="password" formControlName="password"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls.password.errors }" tabindex="5" />
|
||||
<mat-error *ngIf="formCtrls.password.hasError('required')">
|
||||
{{ 'LoginCreateUser_PasswordRequired' | translate }}
|
||||
<mat-label>{{ "LoginCreateUser_Password" | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
type="password"
|
||||
formControlName="password"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls['password'].errors }"
|
||||
tabindex="5"
|
||||
/>
|
||||
<mat-error *ngIf="formCtrls['password'].hasError('required')">
|
||||
{{ "LoginCreateUser_PasswordRequired" | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="formCtrls.password.hasError('pattern')">
|
||||
{{ 'LoginCreateUser_PasswordPattern' | translate }}
|
||||
<mat-error *ngIf="formCtrls['password'].hasError('pattern')">
|
||||
{{ "LoginCreateUser_PasswordPattern" | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</p>
|
||||
|
||||
<button [disabled]="!createForm.valid" mat-raised-button color="accent">
|
||||
{{ 'LoginCreateUser_BtnLogin' | translate }}
|
||||
{{ "LoginCreateUser_BtnLogin" | translate }}
|
||||
</button>
|
||||
<div *ngIf="error" class="alert alert-danger mt-3 mb-0">{{ error }}</div>
|
||||
</form>
|
||||
|
||||
@@ -1,7 +1,20 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { Component, OnInit, ViewChild } from "@angular/core";
|
||||
import { Router, ActivatedRoute } from "@angular/router";
|
||||
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
import {
|
||||
FormBuilder,
|
||||
FormGroup,
|
||||
ReactiveFormsModule,
|
||||
Validators,
|
||||
} from "@angular/forms";
|
||||
import {
|
||||
TranslateModule,
|
||||
TranslatePipe,
|
||||
TranslateService,
|
||||
} from "@ngx-translate/core";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { MatFormFieldModule } from "@angular/material/form-field";
|
||||
import { MatInputModule } from "@angular/material/input";
|
||||
import { MatButtonModule } from "@angular/material/button";
|
||||
|
||||
import { first } from "rxjs/operators";
|
||||
|
||||
@@ -12,20 +25,30 @@ import { User } from "../../models/user";
|
||||
selector: "app-create-user",
|
||||
templateUrl: "./create-user.component.html",
|
||||
styleUrls: ["./create-user.component.css"],
|
||||
standalone: false
|
||||
imports: [
|
||||
CommonModule,
|
||||
MatFormFieldModule,
|
||||
ReactiveFormsModule,
|
||||
MatInputModule,
|
||||
MatButtonModule,
|
||||
TranslateModule,
|
||||
TranslatePipe,
|
||||
],
|
||||
})
|
||||
export class CreateUserComponent implements OnInit {
|
||||
createForm: FormGroup;
|
||||
invalidForm = true;
|
||||
submitted = false;
|
||||
returnUrl: string;
|
||||
error = "";
|
||||
public createForm: FormGroup;
|
||||
public invalidForm = true;
|
||||
public submitted = false;
|
||||
public returnUrl: string;
|
||||
public error: string = "";
|
||||
|
||||
constructor(private formBuilder: FormBuilder,
|
||||
constructor(
|
||||
private formBuilder: FormBuilder,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private authenticationService: AuthenticationService,
|
||||
private translateService: TranslateService) {
|
||||
private translateService: TranslateService,
|
||||
) {
|
||||
// redirect to home if already logged in
|
||||
if (this.authenticationService.currentUserValue) {
|
||||
this.router.navigate(["/"]);
|
||||
@@ -35,16 +58,21 @@ export class CreateUserComponent implements OnInit {
|
||||
ngOnInit() {
|
||||
this.createForm = this.formBuilder.group(
|
||||
{
|
||||
firstname: ["", [Validators.required, Validators.minLength(3)]],
|
||||
lastname: ["", [Validators.required, Validators.minLength(3)]],
|
||||
email: ["", [Validators.required, Validators.email]],
|
||||
username: ["", [Validators.required, Validators.minLength(3)]],
|
||||
password: [
|
||||
"",
|
||||
[Validators.required, Validators.pattern("^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[@$!%*#?&\-_|]).{8,}$")]
|
||||
[
|
||||
Validators.required,
|
||||
Validators.pattern(
|
||||
"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[@$!%*#?&-_|]).{8,}$",
|
||||
),
|
||||
],
|
||||
],
|
||||
firstname: ["", [Validators.required, Validators.minLength(3)]],
|
||||
lastname: ["", [Validators.required, Validators.minLength(3)]],
|
||||
email: ["", [Validators.required, Validators.email]]
|
||||
},
|
||||
{ updateOn: "blur" }
|
||||
{ updateOn: "blur" },
|
||||
);
|
||||
|
||||
// get return url from route parameters or default to '/'
|
||||
@@ -58,30 +86,26 @@ export class CreateUserComponent implements OnInit {
|
||||
onCreateSubmit() {
|
||||
this.invalidForm = false;
|
||||
this.submitted = true;
|
||||
|
||||
if (this.createForm.invalid) {
|
||||
this.invalidForm = true;
|
||||
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.currentLang;
|
||||
|
||||
this.authenticationService.create(createUser)
|
||||
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(
|
||||
data => {
|
||||
this.router.navigate([this.returnUrl]);
|
||||
},
|
||||
error => {
|
||||
this.error = error;
|
||||
.subscribe({
|
||||
complete: () => this.router.navigate([this.returnUrl]),
|
||||
error: (error) => {
|
||||
this.error = error.message;
|
||||
this.invalidForm = false;
|
||||
}
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,62 @@
|
||||
<div class="content">
|
||||
<p>
|
||||
<a class="nostyle" routerLink="/summary" routerLinkActive="active" skipLocationChange>
|
||||
<mat-icon aria-hidden="false" aria-label="Summary" style="width: 128px; height:128px; font-size: 128px;">timeline</mat-icon>
|
||||
<a
|
||||
class="nostyle"
|
||||
routerLink="/summary"
|
||||
routerLinkActive="active"
|
||||
skipLocationChange
|
||||
>
|
||||
<mat-icon
|
||||
aria-hidden="false"
|
||||
aria-label="Summary"
|
||||
style="width: 128px; height: 128px; font-size: 128px"
|
||||
svgIcon="summary"
|
||||
></mat-icon>
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
<a class="nostyle" routerLink="/newjump" routerLinkActive="active" skipLocationChange>
|
||||
<mat-icon aria-hidden="false" aria-label="Add jumps" style="width: 128px; height:128px; font-size: 128px;">add_circle</mat-icon>
|
||||
<a
|
||||
class="nostyle"
|
||||
routerLink="/newjump"
|
||||
routerLinkActive="active"
|
||||
skipLocationChange
|
||||
>
|
||||
<mat-icon
|
||||
aria-hidden="false"
|
||||
aria-label="Add jumps"
|
||||
style="width: 128px; height: 128px; font-size: 128px"
|
||||
svgIcon="add"
|
||||
></mat-icon>
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
<a class="nostyle" routerLink="/jumps" routerLinkActive="active" skipLocationChange>
|
||||
<mat-icon aria-hidden="false" aria-label="List of jumps" style="width: 128px; height:128px; font-size: 128px;">list_alt</mat-icon>
|
||||
<a
|
||||
class="nostyle"
|
||||
routerLink="/jumps"
|
||||
routerLinkActive="active"
|
||||
skipLocationChange
|
||||
>
|
||||
<mat-icon
|
||||
aria-hidden="false"
|
||||
aria-label="List of jumps"
|
||||
style="width: 128px; height: 128px; font-size: 128px"
|
||||
svgIcon="list"
|
||||
></mat-icon>
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
<a class="nostyle" routerLink="/tunnelFlights" routerLinkActive="active" skipLocationChange>
|
||||
<img src="assets/img/tunnel.jpg" alt="Tunnel flights" style="width: 128px; height:128px; font-size: 128px;" />
|
||||
<a
|
||||
class="nostyle"
|
||||
routerLink="/tunnelFlights"
|
||||
routerLinkActive="active"
|
||||
skipLocationChange
|
||||
>
|
||||
<mat-icon
|
||||
aria-hidden="false"
|
||||
aria-label="List of tunnel flights"
|
||||
style="width: 128px; height: 128px; font-size: 128px"
|
||||
svgIcon="wind"
|
||||
></mat-icon>
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
import { RouterLink } from "@angular/router";
|
||||
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
||||
import { Observable, forkJoin } from "rxjs";
|
||||
import { MatIconModule } from "@angular/material/icon";
|
||||
|
||||
import { AircraftService } from "../../services/aircraft.service";
|
||||
import { AuthenticationService } from "../../services/authentication.service";
|
||||
@@ -13,21 +15,25 @@ import { ServiceComm } from "../../services/service-comm.service";
|
||||
selector: "app-default",
|
||||
templateUrl: "./default.component.html",
|
||||
styleUrls: ["./default.component.css"],
|
||||
standalone: false
|
||||
imports: [TranslateModule, MatIconModule, RouterLink],
|
||||
})
|
||||
export class DefaultComponent implements OnInit {
|
||||
constructor(private serviceComm: ServiceComm,
|
||||
constructor(
|
||||
private serviceComm: ServiceComm,
|
||||
private translateService: TranslateService,
|
||||
private authenticationService: AuthenticationService,
|
||||
private serviceApiAircraft: AircraftService,
|
||||
private serviceApiJumpType: JumpTypeService,
|
||||
private serviceApiDropzone: DropzoneService,
|
||||
private serviceApiGear : GearService) {}
|
||||
private serviceApiGear: GearService,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.authenticationService.alwaysLogin();
|
||||
|
||||
this.putToCacheRefDatas().subscribe(() => { console.log("Push to cache the referentiel datas"); });
|
||||
this.putToCacheRefDatas().subscribe(() => {
|
||||
console.log("Push to cache the referentiel datas");
|
||||
});
|
||||
this.updateTitle();
|
||||
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
||||
if (data === true) {
|
||||
@@ -46,8 +52,8 @@ export class DefaultComponent implements OnInit {
|
||||
}
|
||||
|
||||
private updateTitle() {
|
||||
this.translateService.get("Default_Title").subscribe(
|
||||
data => { this.serviceComm.updatedComponentTitle(data); }
|
||||
);
|
||||
this.translateService.get("Default_Title").subscribe((data) => {
|
||||
this.serviceComm.updatedComponentTitle(data);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,32 @@
|
||||
<form (ngSubmit)="updateJump()">
|
||||
<p><span>Gear : {{jump.gear.name}} ({{jump.gear.mainCanopy}})</span></p>
|
||||
<p><mat-checkbox [(ngModel)]="jump.isSpecial" name="isSpecial" labelPosition="before">Special jump</mat-checkbox></p>
|
||||
<p><mat-checkbox [(ngModel)]="jump.withCutaway" name="withCutaway" labelPosition="before">Cutaway</mat-checkbox></p>
|
||||
<p>
|
||||
<span>Gear : {{ jump.gear.name }} ({{ jump.gear.mainCanopy }})</span>
|
||||
</p>
|
||||
<p>
|
||||
<mat-checkbox
|
||||
[(ngModel)]="jump.isSpecial"
|
||||
name="isSpecial"
|
||||
labelPosition="before"
|
||||
>Special jump</mat-checkbox
|
||||
>
|
||||
</p>
|
||||
<p>
|
||||
<mat-checkbox
|
||||
[(ngModel)]="jump.withCutaway"
|
||||
name="withCutaway"
|
||||
labelPosition="before"
|
||||
>Cutaway</mat-checkbox
|
||||
>
|
||||
</p>
|
||||
<mat-form-field>
|
||||
<textarea matInput placeholder="Comments" name="comments" [(ngModel)]="jump.notes" name="comments" type="text"></textarea>
|
||||
<textarea
|
||||
matInput
|
||||
placeholder="Comments"
|
||||
name="comments"
|
||||
[(ngModel)]="jump.notes"
|
||||
name="comments"
|
||||
type="text"
|
||||
></textarea>
|
||||
</mat-form-field>
|
||||
|
||||
<br />
|
||||
|
||||
@@ -1,24 +1,43 @@
|
||||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { Component, Inject, OnInit } from "@angular/core";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { MAT_DIALOG_DATA } from "@angular/material/dialog";
|
||||
import { TranslateModule } from "@ngx-translate/core";
|
||||
import { MatCheckboxModule } from "@angular/material/checkbox";
|
||||
import { MatFormFieldModule } from "@angular/material/form-field";
|
||||
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
|
||||
import { MatInputModule } from "@angular/material/input";
|
||||
import { MatButtonModule } from "@angular/material/button";
|
||||
|
||||
import { AddAction } from '../../models/add-action.enum';
|
||||
import { JumpResp } from '../../models/jump';
|
||||
import { JumpService } from '../../services/jump.service';
|
||||
import { ServiceComm } from '../../services/service-comm.service';
|
||||
import { AddAction } from "../../models/add-action.enum";
|
||||
import { JumpResp } from "../../models/jump";
|
||||
|
||||
import { JumpService } from "../../services/jump.service";
|
||||
import { ServiceComm } from "../../services/service-comm.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-jump-infos',
|
||||
templateUrl: './jump-infos.component.html',
|
||||
styleUrls: ['./jump-infos.component.css'],
|
||||
standalone: false
|
||||
selector: "app-jump-infos",
|
||||
templateUrl: "./jump-infos.component.html",
|
||||
styleUrls: ["./jump-infos.component.css"],
|
||||
imports: [
|
||||
TranslateModule,
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
MatCheckboxModule,
|
||||
MatFormFieldModule,
|
||||
ReactiveFormsModule,
|
||||
MatInputModule,
|
||||
MatButtonModule,
|
||||
],
|
||||
})
|
||||
export class JumpInfosComponent implements OnInit {
|
||||
public editMode: boolean;
|
||||
public jump: JumpResp
|
||||
public jump: JumpResp;
|
||||
|
||||
constructor(@Inject(MAT_DIALOG_DATA) public data: any,
|
||||
constructor(
|
||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||
private serviceJump: JumpService,
|
||||
private serviceComm: ServiceComm) {
|
||||
private serviceComm: ServiceComm
|
||||
) {
|
||||
this.jump = new JumpResp(data.jump);
|
||||
this.editMode = data.editMode;
|
||||
}
|
||||
@@ -26,10 +45,13 @@ export class JumpInfosComponent implements OnInit {
|
||||
ngOnInit(): void {}
|
||||
|
||||
public updateJump() {
|
||||
this.serviceJump.updateJump(this.jump.id,
|
||||
this.serviceJump
|
||||
.updateJump(
|
||||
this.jump.id,
|
||||
this.jump.isSpecial,
|
||||
this.jump.withCutaway,
|
||||
this.jump.notes)
|
||||
this.jump.notes
|
||||
)
|
||||
.subscribe(() => {
|
||||
this.serviceComm.refreshData(AddAction.Jump);
|
||||
});
|
||||
|
||||
@@ -1,25 +1,44 @@
|
||||
<div class="content">
|
||||
<div *ngIf="dataSourceTable != null else loading">
|
||||
<button mat-raised-button color="accent" (click)="openDialogToAdd()" *ngIf="isUserAdmin == true">{{ 'List_Aircrafts_Add' | translate }}</button>
|
||||
<div *ngIf="dataSourceTable != null; else loading">
|
||||
<button
|
||||
mat-raised-button
|
||||
color="accent"
|
||||
(click)="openDialogToAdd()"
|
||||
*ngIf="isUserAdmin == true"
|
||||
>
|
||||
{{ "ListAircrafts_Add" | translate }}
|
||||
</button>
|
||||
|
||||
<table mat-table [dataSource]="dataSourceTable">
|
||||
<ng-container matColumnDef="id">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'List_Aircrafts_Header_Id' | translate }}</th>
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
{{ "ListAircrafts_Header_Id" | translate }}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.id }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'List_Aircrafts_Header_Name' | translate }}</th>
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
{{ "ListAircrafts_Header_Name" | translate }}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.name }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="imageData">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'List_Aircrafts_Header_Image' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let element"><img src="{{element.imageData}}" alt="No image" style="width: 128px;"></td>
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
{{ "ListAircrafts_Header_Image" | translate }}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<img
|
||||
src="{{ element.imageData }}"
|
||||
alt="No image"
|
||||
style="width: 128px"
|
||||
/>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
</div>
|
||||
<mat-paginator [length]="resultsLength" [pageSize]="10"></mat-paginator>
|
||||
|
||||
@@ -1,39 +1,52 @@
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { MatPaginator } from '@angular/material/paginator';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Component, OnInit, ViewChild } from "@angular/core";
|
||||
import { MatPaginator, MatPaginatorModule } from "@angular/material/paginator";
|
||||
import { MatTableDataSource, MatTableModule } from "@angular/material/table";
|
||||
import { MatDialog } from "@angular/material/dialog";
|
||||
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { MatProgressSpinnerModule } from "@angular/material/progress-spinner";
|
||||
import { MatButtonModule } from "@angular/material/button";
|
||||
|
||||
import { AircraftService } from '../../services/aircraft.service';
|
||||
import { ServiceComm } from '../../services/service-comm.service';
|
||||
import { AuthenticationService } from '../../services/authentication.service';
|
||||
import { NewAircraftComponent } from '../new-aircraft/new-aircraft.component';
|
||||
import { AddAction } from '../../models/add-action.enum';
|
||||
import { AircraftResp } from '../../models/aircraft';
|
||||
import { AircraftService } from "../../services/aircraft.service";
|
||||
import { ServiceComm } from "../../services/service-comm.service";
|
||||
import { AuthenticationService } from "../../services/authentication.service";
|
||||
import { NewAircraftComponent } from "../new-aircraft/new-aircraft.component";
|
||||
import { AddAction } from "../../models/add-action.enum";
|
||||
import { AircraftResp } from "../../models/aircraft";
|
||||
|
||||
@Component({
|
||||
selector: 'app-list-of-aircrafts',
|
||||
templateUrl: './list-of-aircrafts.component.html',
|
||||
styleUrls: ['./list-of-aircrafts.component.css'],
|
||||
standalone: false
|
||||
selector: "app-list-of-aircrafts",
|
||||
templateUrl: "./list-of-aircrafts.component.html",
|
||||
styleUrls: ["./list-of-aircrafts.component.css"],
|
||||
imports: [
|
||||
TranslateModule,
|
||||
CommonModule,
|
||||
MatPaginatorModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatTableModule,
|
||||
MatButtonModule,
|
||||
],
|
||||
})
|
||||
export class ListOfAircraftsComponent implements OnInit {
|
||||
public displayedColumns: Array<string> = ['name', 'imageData'];
|
||||
public displayedColumns: Array<string> = ["name", "imageData"];
|
||||
public dataSourceTable: MatTableDataSource<AircraftResp>;
|
||||
public resultsLength = 0;
|
||||
public isUserAdmin: boolean;
|
||||
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
|
||||
|
||||
constructor(private serviceApi: AircraftService,
|
||||
constructor(
|
||||
private serviceApi: AircraftService,
|
||||
private serviceComm: ServiceComm,
|
||||
private authenticationService: AuthenticationService,
|
||||
public dialog: MatDialog,
|
||||
private translateService: TranslateService) {
|
||||
this.isUserAdmin = this.authenticationService.currentUserValue.roles === "admin";
|
||||
private translateService: TranslateService
|
||||
) {
|
||||
this.isUserAdmin =
|
||||
this.authenticationService.currentUserValue.roles === "admin";
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.serviceComm.refreshRequest.subscribe(action => {
|
||||
this.serviceComm.refreshRequest.subscribe((action) => {
|
||||
if (action === AddAction.Aircraft) {
|
||||
this.dialog.closeAll();
|
||||
this.getListOfAircrafts();
|
||||
@@ -50,7 +63,7 @@ export class ListOfAircraftsComponent implements OnInit {
|
||||
}
|
||||
|
||||
private getListOfAircrafts() {
|
||||
this.serviceApi.getListOfAircrafts().subscribe(data => {
|
||||
this.serviceApi.getListOfAircrafts().subscribe((data) => {
|
||||
setTimeout(() => {
|
||||
data.sort((a, b) => a.name.localeCompare(b.name));
|
||||
this.dataSourceTable = new MatTableDataSource<AircraftResp>(data);
|
||||
@@ -65,8 +78,8 @@ export class ListOfAircraftsComponent implements OnInit {
|
||||
}
|
||||
|
||||
private updateTitle() {
|
||||
this.translateService.get("ListAircrafts_Title").subscribe(
|
||||
data => { this.serviceComm.updatedComponentTitle(data); }
|
||||
);
|
||||
this.translateService.get("ListAircrafts_Title").subscribe((data) => {
|
||||
this.serviceComm.updatedComponentTitle(data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,59 +1,113 @@
|
||||
<div class="content">
|
||||
<div *ngIf="dataSourceTable != null else loading">
|
||||
<button mat-raised-button color="accent" (click)="openDialogToAdd()" *ngIf="isUserAdmin == true">{{ 'List_Dz_Add' | translate }}</button>
|
||||
<div *ngIf="dataSourceTable != null; else loading">
|
||||
<button
|
||||
mat-raised-button
|
||||
color="accent"
|
||||
(click)="openDialogToAdd()"
|
||||
*ngIf="isUserAdmin == true"
|
||||
>
|
||||
{{ "ListDz_Add" | translate }}
|
||||
</button>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'List_Dz_Filter' | translate }}</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event)" placeholder="{{ 'List_Dz_Filter_PlaceHolder' | translate }}" #input>
|
||||
<mat-label>{{ "ListDz_Filter" | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
(keyup)="applyFilter($event)"
|
||||
placeholder="{{ 'ListDz_Filter_PlaceHolder' | translate }}"
|
||||
#input
|
||||
/>
|
||||
</mat-form-field>
|
||||
|
||||
<table mat-table [dataSource]="dataSourceTable">
|
||||
<ng-container matColumnDef="isfavorite">
|
||||
<th mat-header-cell *matHeaderCellDef style="min-width: 144px;"></th>
|
||||
<td mat-cell *matCellDef="let element" style="text-align: left;">
|
||||
<mat-icon aria-hidden="false" aria-label="Favorite" *ngIf="element.isFavorite === true"
|
||||
(click)="removeToFavorite(element)" color="primary" style="cursor: pointer;">favorite</mat-icon>
|
||||
<mat-icon aria-hidden="false" aria-label="Not favorite" *ngIf="element.isFavorite === false"
|
||||
(click)="setToFavorite(element)" style="cursor: pointer;">favorite_border</mat-icon>
|
||||
<a href='http://{{element.website}}' target="_blank">
|
||||
<mat-icon aria-hidden="false" aria-label="URL to the DZ website" style="color: white;">link</mat-icon>
|
||||
<th mat-header-cell *matHeaderCellDef style="min-width: 144px"></th>
|
||||
<td mat-cell *matCellDef="let element" style="text-align: left">
|
||||
<mat-icon
|
||||
aria-hidden="false"
|
||||
aria-label="Favorite"
|
||||
*ngIf="element.isFavorite === true"
|
||||
(click)="removeToFavorite(element)"
|
||||
color="primary"
|
||||
style="cursor: pointer"
|
||||
svgIcon="favorite"
|
||||
></mat-icon>
|
||||
<mat-icon
|
||||
aria-hidden="false"
|
||||
aria-label="Not favorite"
|
||||
*ngIf="element.isFavorite === false"
|
||||
(click)="setToFavorite(element)"
|
||||
style="cursor: pointer"
|
||||
svgIcon="not_favorite"
|
||||
></mat-icon>
|
||||
<a href="http://{{ element.website }}" target="_blank">
|
||||
<mat-icon
|
||||
aria-hidden="false"
|
||||
aria-label="URL to the DZ website"
|
||||
style="color: white"
|
||||
svgIcon="link"
|
||||
></mat-icon>
|
||||
</a>
|
||||
<a href='https://www.openstreetmap.org/?mlat={{element.latitude}}&mlon={{element.longitude}}#map=14/{{element.latitude}}/{{element.longitude}}'
|
||||
target="_blank">
|
||||
<mat-icon aria-hidden="false" aria-label="Location of the DZ" style="color: white;">map</mat-icon>
|
||||
<a
|
||||
href="https://www.openstreetmap.org/?mlat={{
|
||||
element.latitude
|
||||
}}&mlon={{ element.longitude }}#map=14/{{ element.latitude }}/{{
|
||||
element.longitude
|
||||
}}"
|
||||
target="_blank"
|
||||
>
|
||||
<mat-icon
|
||||
aria-hidden="false"
|
||||
aria-label="Location of the DZ"
|
||||
style="color: white"
|
||||
svgIcon="map"
|
||||
></mat-icon>
|
||||
</a>
|
||||
<a href="mailto:{{ element.email }}" *ngIf="element.email">
|
||||
<mat-icon aria-hidden="false" aria-label="Contact mail of the DZ" style="color: white;">mail_outline</mat-icon>
|
||||
<mat-icon
|
||||
aria-hidden="false"
|
||||
aria-label="Contact mail of the DZ"
|
||||
style="color: white"
|
||||
svgIcon="mail"
|
||||
></mat-icon>
|
||||
</a>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="id">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'List_Dz_Header_ID' | translate }}</th>
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
{{ "ListDz_Header_ID" | translate }}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.id }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'List_Dz_Header_Name' | translate }}</th>
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
{{ "ListDz_Header_Name" | translate }}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<span class="spanWithBreakWord" [innerHTML]="element.name"></span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="address">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'List_Dz_Header_Address' | translate }}</th>
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
{{ "ListDz_Header_Address" | translate }}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<span class="spanWithBreakWord" [innerHTML]="element.address"></span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="type">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'List_Dz_Header_Type' | translate }}</th>
|
||||
<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>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
</div>
|
||||
<mat-paginator [length]="resultsLength" [pageSize]="20"></mat-paginator>
|
||||
|
||||
@@ -1,40 +1,61 @@
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { MatPaginator } from '@angular/material/paginator';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { Component, OnInit, ViewChild } from "@angular/core";
|
||||
import { MatPaginator, MatPaginatorModule } from "@angular/material/paginator";
|
||||
import { MatTableDataSource, MatTableModule } from "@angular/material/table";
|
||||
import { MatDialog } from "@angular/material/dialog";
|
||||
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { MatIconModule } from "@angular/material/icon";
|
||||
import { MatProgressSpinnerModule } from "@angular/material/progress-spinner";
|
||||
import { MatFormFieldModule } from "@angular/material/form-field";
|
||||
import { MatButtonModule } from "@angular/material/button";
|
||||
import { MatInputModule } from "@angular/material/input";
|
||||
import { ReactiveFormsModule } from "@angular/forms";
|
||||
|
||||
import { AddAction } from '../../models/add-action.enum';
|
||||
import { DropZoneResp } from '../../models/dropzone';
|
||||
import { DropzoneService } from '../../services/dropzone.service';
|
||||
import { ServiceComm } from '../../services/service-comm.service';
|
||||
import { AuthenticationService } from '../../services/authentication.service';
|
||||
import { NewDropZoneComponent } from '../new-drop-zone/new-drop-zone.component';
|
||||
import { AddAction } from "../../models/add-action.enum";
|
||||
import { DropZoneResp } from "../../models/dropzone";
|
||||
import { DropzoneService } from "../../services/dropzone.service";
|
||||
import { ServiceComm } from "../../services/service-comm.service";
|
||||
import { AuthenticationService } from "../../services/authentication.service";
|
||||
import { NewDropZoneComponent } from "../new-drop-zone/new-drop-zone.component";
|
||||
|
||||
@Component({
|
||||
selector: 'app-list-of-dzs',
|
||||
templateUrl: './list-of-dzs.component.html',
|
||||
styleUrls: ['./list-of-dzs.component.css'],
|
||||
standalone: false
|
||||
selector: "app-list-of-dzs",
|
||||
templateUrl: "./list-of-dzs.component.html",
|
||||
styleUrls: ["./list-of-dzs.component.css"],
|
||||
imports: [
|
||||
TranslateModule,
|
||||
CommonModule,
|
||||
MatIconModule,
|
||||
MatPaginatorModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatTableModule,
|
||||
MatFormFieldModule,
|
||||
ReactiveFormsModule,
|
||||
MatInputModule,
|
||||
MatButtonModule,
|
||||
],
|
||||
})
|
||||
export class ListOfDzsComponent implements OnInit {
|
||||
public displayedColumns: Array<string> = [
|
||||
'isfavorite',
|
||||
'name',
|
||||
'address',
|
||||
'type',
|
||||
"isfavorite",
|
||||
"name",
|
||||
"address",
|
||||
"type",
|
||||
];
|
||||
public dataSourceTable: MatTableDataSource<DropZoneResp>;
|
||||
public isUserAdmin: boolean;
|
||||
public resultsLength = 0;
|
||||
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
|
||||
|
||||
constructor(private serviceApi: DropzoneService,
|
||||
constructor(
|
||||
private serviceApi: DropzoneService,
|
||||
private serviceComm: ServiceComm,
|
||||
private authenticationService: AuthenticationService,
|
||||
public dialog: MatDialog,
|
||||
private translateService: TranslateService) {
|
||||
this.isUserAdmin = this.authenticationService.currentUserValue.roles === "admin";
|
||||
private translateService: TranslateService
|
||||
) {
|
||||
this.isUserAdmin =
|
||||
this.authenticationService.currentUserValue.roles === "admin";
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
@@ -55,10 +76,13 @@ export class ListOfDzsComponent implements OnInit {
|
||||
}
|
||||
|
||||
private getListOfDropZones() {
|
||||
this.serviceApi.getListOfDropZones()
|
||||
.subscribe((data) => {
|
||||
this.serviceApi.getListOfDropZones().subscribe((data) => {
|
||||
setTimeout(() => {
|
||||
data.sort((a, b) => (b.isFavorite ? 1 : 0) - (a.isFavorite ? 1 : 0) || a.name.localeCompare(b.name));
|
||||
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;
|
||||
@@ -88,8 +112,8 @@ export class ListOfDzsComponent implements OnInit {
|
||||
|
||||
openDialogToAdd() {
|
||||
this.dialog.open(NewDropZoneComponent, {
|
||||
height: '400px',
|
||||
width: '600px',
|
||||
height: "400px",
|
||||
width: "600px",
|
||||
});
|
||||
}
|
||||
|
||||
@@ -99,8 +123,8 @@ export class ListOfDzsComponent implements OnInit {
|
||||
}
|
||||
|
||||
private updateTitle() {
|
||||
this.translateService.get("ListDz_Title").subscribe(
|
||||
data => { this.serviceComm.updatedComponentTitle(data); }
|
||||
);
|
||||
this.translateService.get("ListDz_Title").subscribe((data) => {
|
||||
this.serviceComm.updatedComponentTitle(data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,45 +1,63 @@
|
||||
<div class="content">
|
||||
<div *ngIf="dataSourceTable != null else loading">
|
||||
<button mat-raised-button color="accent" (click)="openDialogToAdd()">{{ 'List_Gears_Add' | translate }}</button>
|
||||
<div *ngIf="dataSourceTable != null; else loading">
|
||||
<button mat-raised-button color="accent" (click)="openDialogToAdd()">
|
||||
{{ "ListGears_Add" | translate }}
|
||||
</button>
|
||||
|
||||
<table mat-table [dataSource]="dataSourceTable">
|
||||
<ng-container matColumnDef="id">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'List_Gears_Header_Id' | translate }}</th>
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
{{ "ListGears_Header_Id" | translate }}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.id }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef style="min-width: 130px;">{{ 'List_Gears_Header_Name' | translate }}</th>
|
||||
<th mat-header-cell *matHeaderCellDef style="min-width: 130px">
|
||||
{{ "ListGears_Header_Name" | translate }}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.name }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="manufacturer">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'List_Gears_Header_Manufacturer' | translate }}</th>
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
{{ "ListGears_Header_Manufacturer" | translate }}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.manufacturer }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="maxSize">
|
||||
<th mat-header-cell *matHeaderCellDef style="min-width: 90px;">{{ 'List_Gears_Header_CanopySize' | translate }}</th>
|
||||
<td mat-cell *matCellDef="let element">{{element.minSize}} - {{element.maxSize}}</td>
|
||||
<th mat-header-cell *matHeaderCellDef style="min-width: 90px">
|
||||
{{ "ListGears_Header_CanopySize" | translate }}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
{{ element.minSize }} - {{ element.maxSize }}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="aad">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'List_Gears_Header_Aad' | translate }}</th>
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
{{ "ListGears_Header_Aad" | translate }}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.aad }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="mainCanopy">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'List_Gears_Header_Main' | translate }}</th>
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
{{ "ListGears_Header_Main" | translate }}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.mainCanopy }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="reserveCanopy">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'List_Gears_Header_Reserve' | translate }}</th>
|
||||
<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>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
</div>
|
||||
<mat-paginator [length]="resultsLength" [pageSize]="10"></mat-paginator>
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import { Component, OnInit, ViewChild } from "@angular/core";
|
||||
import { MatPaginator } from "@angular/material/paginator";
|
||||
import { MatTableDataSource } from "@angular/material/table";
|
||||
import { MatPaginator, MatPaginatorModule } from "@angular/material/paginator";
|
||||
import { MatTableDataSource, MatTableModule } from "@angular/material/table";
|
||||
import { MatDialog } from "@angular/material/dialog";
|
||||
import { 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 { MatButtonModule } from "@angular/material/button";
|
||||
|
||||
import { GearService } from "../../services/gear.service";
|
||||
import { ServiceComm } from "../../services/service-comm.service";
|
||||
@@ -14,7 +17,14 @@ import { NewGearComponent } from "../new-gear/new-gear.component";
|
||||
selector: "app-list-of-gears",
|
||||
templateUrl: "./list-of-gears.component.html",
|
||||
styleUrls: ["./list-of-gears.component.css"],
|
||||
standalone: false
|
||||
imports: [
|
||||
TranslateModule,
|
||||
CommonModule,
|
||||
MatPaginatorModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatTableModule,
|
||||
MatButtonModule,
|
||||
],
|
||||
})
|
||||
export class ListOfGearsComponent implements OnInit {
|
||||
public displayedColumns: Array<string> = [
|
||||
@@ -23,19 +33,21 @@ export class ListOfGearsComponent implements OnInit {
|
||||
"maxSize",
|
||||
"aad",
|
||||
"mainCanopy",
|
||||
"reserveCanopy"
|
||||
"reserveCanopy",
|
||||
];
|
||||
public dataSourceTable: MatTableDataSource<GearResp>;
|
||||
public resultsLength = 0;
|
||||
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
|
||||
|
||||
constructor(private serviceApi: GearService,
|
||||
constructor(
|
||||
private serviceApi: GearService,
|
||||
private serviceComm: ServiceComm,
|
||||
public dialog: MatDialog,
|
||||
private translateService: TranslateService) {}
|
||||
private translateService: TranslateService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.serviceComm.refreshRequest.subscribe(action => {
|
||||
this.serviceComm.refreshRequest.subscribe((action) => {
|
||||
if (action === AddAction.Gear) {
|
||||
this.dialog.closeAll();
|
||||
this.getListOfGears();
|
||||
@@ -52,8 +64,7 @@ export class ListOfGearsComponent implements OnInit {
|
||||
}
|
||||
|
||||
getListOfGears() {
|
||||
this.serviceApi.getListOfGears()
|
||||
.subscribe(data => {
|
||||
this.serviceApi.getListOfGears().subscribe((data) => {
|
||||
setTimeout(() => {
|
||||
data.sort((a, b) => b.id - a.id);
|
||||
this.dataSourceTable = new MatTableDataSource<GearResp>(data);
|
||||
@@ -66,13 +77,13 @@ export class ListOfGearsComponent implements OnInit {
|
||||
openDialogToAdd() {
|
||||
this.dialog.open(NewGearComponent, {
|
||||
height: "400px",
|
||||
width: "600px"
|
||||
width: "600px",
|
||||
});
|
||||
}
|
||||
|
||||
private updateTitle() {
|
||||
this.translateService.get("ListGears_Title").subscribe(
|
||||
data => { this.serviceComm.updatedComponentTitle(data); }
|
||||
);
|
||||
this.translateService.get("ListGears_Title").subscribe((data) => {
|
||||
this.serviceComm.updatedComponentTitle(data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,20 @@
|
||||
<div>
|
||||
<form [formGroup]="imgForm" (ngSubmit)="onSubmit(imgForm.value)" autocomplete="off" style="padding: 10px;">
|
||||
<form
|
||||
[formGroup]="imgForm"
|
||||
(ngSubmit)="onSubmit(imgForm.value)"
|
||||
autocomplete="off"
|
||||
style="padding: 10px"
|
||||
>
|
||||
<p>
|
||||
<input type="file" #fileUpload id="fileUpload" name="fileUpload" accept="image/*" formControlName="image"
|
||||
(change)="onFileChanged($event)" />
|
||||
<input
|
||||
type="file"
|
||||
#fileUpload
|
||||
id="fileUpload"
|
||||
name="fileUpload"
|
||||
accept="image/*"
|
||||
formControlName="image"
|
||||
(change)="onFileChanged($event)"
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<mat-form-field>
|
||||
@@ -12,7 +24,7 @@
|
||||
</p>
|
||||
|
||||
<button mat-icon-button color="warn" type="submit">
|
||||
<mat-icon>file_upload</mat-icon>
|
||||
<mat-icon svgIcon="file_upload"></mat-icon>
|
||||
Upload image
|
||||
</button>
|
||||
<label>{{ imageError }}</label>
|
||||
@@ -22,28 +34,54 @@
|
||||
<div *ngIf="resultsLength > 0">
|
||||
<table mat-table [dataSource]="dataSourceTable">
|
||||
<ng-container matColumnDef="comment">
|
||||
<th mat-header-cell *matHeaderCellDef style="text-align: center;">Comments</th>
|
||||
<td mat-cell *matCellDef="let element" style="text-align: left;"><span style="white-space:nowrap;">{{element.comment}}</span></td>
|
||||
<th mat-header-cell *matHeaderCellDef style="text-align: center">
|
||||
Comments
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element" style="text-align: left">
|
||||
<span style="white-space: nowrap">{{ element.comment }}</span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="data">
|
||||
<th mat-header-cell *matHeaderCellDef style="text-align: center;">Image</th>
|
||||
<td mat-cell *matCellDef="let element" style="text-align: center;">
|
||||
<img src="{{element.data}}" alt="image" style="width:50%;" (click)="openModal(element)" class="cursor">
|
||||
<th mat-header-cell *matHeaderCellDef style="text-align: center">
|
||||
Image
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element" style="text-align: center">
|
||||
<img
|
||||
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>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
|
||||
<mat-paginator [length]="resultsLength" [pageSize]="10"></mat-paginator>
|
||||
</div>
|
||||
|
||||
<div class="imgmodal" [ngStyle]="{'display': (showPopin === true) ? 'block' : 'none'}">
|
||||
<div
|
||||
class="imgmodal"
|
||||
[ngStyle]="{ display: showPopin === true ? 'block' : 'none' }"
|
||||
>
|
||||
<span class="close cursor" (click)="closeModal()">×</span>
|
||||
<mat-icon aria-hidden="false" aria-label="Rotation" (click)="rotate()" class="rotate cursor">undo</mat-icon>
|
||||
<mat-icon
|
||||
aria-hidden="false"
|
||||
aria-label="Rotation"
|
||||
(click)="rotate()"
|
||||
class="rotate cursor"
|
||||
svgIcon="rotate"
|
||||
></mat-icon>
|
||||
<div class="imgbox">
|
||||
<img class="center-fit cursor" src="{{ popinImage }}" (click)="closeModal()" [@rotatedState]='stateRotation'>
|
||||
<img
|
||||
class="center-fit cursor"
|
||||
src="{{ popinImage }}"
|
||||
(click)="closeModal()"
|
||||
[@rotatedState]="stateRotation"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,30 +1,51 @@
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { FormGroup, FormControl, Validators } from '@angular/forms';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { MatPaginator } from '@angular/material/paginator';
|
||||
import { trigger,state, style } from '@angular/animations';
|
||||
import { Component, OnInit, ViewChild } from "@angular/core";
|
||||
import {
|
||||
FormGroup,
|
||||
FormControl,
|
||||
Validators,
|
||||
ReactiveFormsModule,
|
||||
} from "@angular/forms";
|
||||
import { MatTableDataSource, MatTableModule } from "@angular/material/table";
|
||||
import { MatPaginator, MatPaginatorModule } from "@angular/material/paginator";
|
||||
import { trigger, state, style } from "@angular/animations";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { MatIconModule } from "@angular/material/icon";
|
||||
import { MatFormFieldModule } from "@angular/material/form-field";
|
||||
import { TranslateModule } from "@ngx-translate/core";
|
||||
import { MatButtonModule } from "@angular/material/button";
|
||||
import { MatInputModule } from "@angular/material/input";
|
||||
|
||||
import { ImageService } from '../../services/image.service';
|
||||
import { ServiceComm } from '../../services/service-comm.service';
|
||||
import { ImageResp } from '../../models/image';
|
||||
import { AddAction } from '../../models/add-action.enum';
|
||||
import { ImageService } from "../../services/image.service";
|
||||
import { ServiceComm } from "../../services/service-comm.service";
|
||||
import { ImageResp } from "../../models/image";
|
||||
import { AddAction } from "../../models/add-action.enum";
|
||||
|
||||
@Component({
|
||||
selector: 'app-list-of-images',
|
||||
templateUrl: './list-of-images.component.html',
|
||||
styleUrls: ['./list-of-images.component.css'],
|
||||
selector: "app-list-of-images",
|
||||
templateUrl: "./list-of-images.component.html",
|
||||
styleUrls: ["./list-of-images.component.css"],
|
||||
animations: [
|
||||
trigger('rotatedState', [
|
||||
state('default', style({ transform: 'rotate(0)' })),
|
||||
state('rot90', style({ transform: 'rotate(-90deg)' })),
|
||||
state('rot180', style({ transform: 'rotate(-180deg)' })),
|
||||
state('rot270', style({ transform: 'rotate(-270deg)' })),
|
||||
])
|
||||
trigger("rotatedState", [
|
||||
state("default", style({ transform: "rotate(0)" })),
|
||||
state("rot90", style({ transform: "rotate(-90deg)" })),
|
||||
state("rot180", style({ transform: "rotate(-180deg)" })),
|
||||
state("rot270", style({ transform: "rotate(-270deg)" })),
|
||||
]),
|
||||
],
|
||||
imports: [
|
||||
TranslateModule,
|
||||
CommonModule,
|
||||
MatIconModule,
|
||||
MatPaginatorModule,
|
||||
MatFormFieldModule,
|
||||
ReactiveFormsModule,
|
||||
MatTableModule,
|
||||
MatButtonModule,
|
||||
MatInputModule,
|
||||
],
|
||||
standalone: false
|
||||
})
|
||||
export class ListOfImagesComponent implements OnInit {
|
||||
public displayedColumns: Array<string> = ['comment', 'data'];
|
||||
public displayedColumns: Array<string> = ["comment", "data"];
|
||||
public imgForm: FormGroup;
|
||||
public imageError: string;
|
||||
private selectedFile: string;
|
||||
@@ -32,12 +53,12 @@ export class ListOfImagesComponent implements OnInit {
|
||||
public showPopin: boolean;
|
||||
public dataSourceTable: MatTableDataSource<ImageResp>;
|
||||
public resultsLength = 0;
|
||||
public stateRotation: string = 'default';
|
||||
public stateRotation: string = "default";
|
||||
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
|
||||
|
||||
constructor(
|
||||
private serviceApi: ImageService,
|
||||
private serviceComm: ServiceComm
|
||||
private serviceComm: ServiceComm,
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
@@ -49,14 +70,13 @@ export class ListOfImagesComponent implements OnInit {
|
||||
this.getListOfImages();
|
||||
|
||||
this.imgForm = new FormGroup({
|
||||
comment: new FormControl('', Validators.required),
|
||||
image: new FormControl('', Validators.required),
|
||||
comment: new FormControl("", Validators.required),
|
||||
image: new FormControl("", Validators.required),
|
||||
});
|
||||
}
|
||||
|
||||
private getListOfImages() {
|
||||
this.serviceApi.getListOfImages()
|
||||
.subscribe((data) => {
|
||||
this.serviceApi.getListOfImages().subscribe((data) => {
|
||||
setTimeout(() => {
|
||||
this.dataSourceTable = new MatTableDataSource<ImageResp>(data);
|
||||
this.dataSourceTable.paginator = this.paginator;
|
||||
@@ -69,13 +89,13 @@ export class ListOfImagesComponent implements OnInit {
|
||||
const file = fileInput.dataTransfer
|
||||
? fileInput.dataTransfer.files[0]
|
||||
: fileInput.target.files[0];
|
||||
const allowed_types = ['image/png', 'image/jpeg'];
|
||||
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 )';
|
||||
this.imageError = "Only Images are allowed ( JPG | PNG )";
|
||||
} else if (file.size > max_size) {
|
||||
this.imageError = 'Maximum size allowed is ' + max_size / 1000 + 'Mb';
|
||||
this.imageError = "Maximum size allowed is " + max_size / 1000 + "Mb";
|
||||
} else {
|
||||
const reader = new FileReader();
|
||||
reader.onload = this.checkAndExtractDataToBase64.bind(this);
|
||||
@@ -90,16 +110,16 @@ export class ListOfImagesComponent implements OnInit {
|
||||
const image = new Image();
|
||||
image.src = e.target.result;
|
||||
image.onload = (rs) => {
|
||||
const img_height = rs.currentTarget['height'];
|
||||
const img_width = rs.currentTarget['width'];
|
||||
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';
|
||||
"Maximum dimentions allowed " + max_height + "*" + max_width + "px";
|
||||
} else {
|
||||
const imgBase64Path = e.target.result;
|
||||
this.selectedFile = imgBase64Path;
|
||||
this.imageError = 'OK';
|
||||
this.imageError = "OK";
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -109,10 +129,11 @@ export class ListOfImagesComponent implements OnInit {
|
||||
return;
|
||||
}
|
||||
|
||||
this.serviceApi.addImage(formData.comment, this.selectedFile)
|
||||
.subscribe(
|
||||
() => { this.getListOfImages(); }
|
||||
);
|
||||
this.serviceApi
|
||||
.addImage(formData.comment, this.selectedFile)
|
||||
.subscribe(() => {
|
||||
this.getListOfImages();
|
||||
});
|
||||
}
|
||||
|
||||
openModal(image: ImageResp) {
|
||||
@@ -125,14 +146,14 @@ export class ListOfImagesComponent implements OnInit {
|
||||
}
|
||||
|
||||
rotate() {
|
||||
if (this.stateRotation === 'default') {
|
||||
this.stateRotation = 'rot90';
|
||||
} else if (this.stateRotation === 'rot90') {
|
||||
this.stateRotation = 'rot180';
|
||||
} else if (this.stateRotation === 'rot180') {
|
||||
this.stateRotation = 'rot270';
|
||||
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';
|
||||
this.stateRotation = "default";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,31 @@
|
||||
<div class="content">
|
||||
<div *ngIf="dataSourceTable != null else loading">
|
||||
<button mat-raised-button color="accent" (click)="openDialogToAdd()" *ngIf="isUserAdmin == true">{{ 'List_JumpType_Add' | translate }}</button>
|
||||
<div *ngIf="dataSourceTable != null; else loading">
|
||||
<button
|
||||
mat-raised-button
|
||||
color="accent"
|
||||
(click)="openDialogToAdd()"
|
||||
*ngIf="isUserAdmin == true"
|
||||
>
|
||||
{{ "ListJumpType_Add" | translate }}
|
||||
</button>
|
||||
|
||||
<table mat-table [dataSource]="dataSourceTable">
|
||||
<ng-container matColumnDef="id">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'List_JumpType_Header_Id' | translate }}</th>
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
{{ "ListJumpType_Header_Id" | translate }}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.id }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'List_JumpType_Header_Name' | translate }}</th>
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
{{ "ListJumpType_Header_Name" | translate }}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.name }}</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
</div>
|
||||
<mat-paginator [length]="resultsLength" [pageSize]="20"></mat-paginator>
|
||||
|
||||
@@ -1,21 +1,31 @@
|
||||
import { Component, OnInit, ViewChild } from "@angular/core";
|
||||
import { MatPaginator } from "@angular/material/paginator";
|
||||
import { MatTableDataSource } from "@angular/material/table";
|
||||
import { MatPaginator, MatPaginatorModule } from "@angular/material/paginator";
|
||||
import { MatTableDataSource, MatTableModule } from "@angular/material/table";
|
||||
import { MatDialog } from "@angular/material/dialog";
|
||||
import { 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 { MatButtonModule } from "@angular/material/button";
|
||||
|
||||
import { AddAction } from "../../models/add-action.enum";
|
||||
import { JumpTypeResp } from "../../models/jumpType";
|
||||
import { JumpTypeService } from "../../services/jump-type.service";
|
||||
import { ServiceComm } from "../../services/service-comm.service";
|
||||
import { AuthenticationService } from '../../services/authentication.service';
|
||||
import { AuthenticationService } from "../../services/authentication.service";
|
||||
import { NewJumpTypeComponent } from "../new-jump-type/new-jump-type.component";
|
||||
|
||||
@Component({
|
||||
selector: "app-list-of-jump-types",
|
||||
templateUrl: "./list-of-jump-types.component.html",
|
||||
styleUrls: ["./list-of-jump-types.component.css"],
|
||||
standalone: false
|
||||
imports: [
|
||||
TranslateModule,
|
||||
CommonModule,
|
||||
MatPaginatorModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatTableModule,
|
||||
MatButtonModule,
|
||||
],
|
||||
})
|
||||
export class ListOfJumpTypesComponent implements OnInit {
|
||||
public displayedColumns: Array<string> = ["name"];
|
||||
@@ -24,16 +34,19 @@ export class ListOfJumpTypesComponent implements OnInit {
|
||||
public resultsLength = 0;
|
||||
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
|
||||
|
||||
constructor(private serviceApi: JumpTypeService,
|
||||
constructor(
|
||||
private serviceApi: JumpTypeService,
|
||||
private serviceComm: ServiceComm,
|
||||
private authenticationService: AuthenticationService,
|
||||
public dialog: MatDialog,
|
||||
private translateService: TranslateService) {
|
||||
this.isUserAdmin = this.authenticationService.currentUserValue.roles === "admin";
|
||||
private translateService: TranslateService
|
||||
) {
|
||||
this.isUserAdmin =
|
||||
this.authenticationService.currentUserValue.roles === "admin";
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.serviceComm.refreshRequest.subscribe(action => {
|
||||
this.serviceComm.refreshRequest.subscribe((action) => {
|
||||
if (action === AddAction.JumpType) {
|
||||
this.dialog.closeAll();
|
||||
this.getListOfJumpTypes();
|
||||
@@ -50,7 +63,7 @@ export class ListOfJumpTypesComponent implements OnInit {
|
||||
}
|
||||
|
||||
getListOfJumpTypes() {
|
||||
this.serviceApi.getListOfJumpTypes().subscribe(data => {
|
||||
this.serviceApi.getListOfJumpTypes().subscribe((data) => {
|
||||
setTimeout(() => {
|
||||
data.sort((a, b) => a.name.localeCompare(b.name));
|
||||
this.dataSourceTable = new MatTableDataSource<JumpTypeResp>(data);
|
||||
@@ -65,8 +78,8 @@ export class ListOfJumpTypesComponent implements OnInit {
|
||||
}
|
||||
|
||||
private updateTitle() {
|
||||
this.translateService.get("ListJumpTypes_Title").subscribe(
|
||||
data => { this.serviceComm.updatedComponentTitle(data); }
|
||||
);
|
||||
this.translateService.get("ListJumpTypes_Title").subscribe((data) => {
|
||||
this.serviceComm.updatedComponentTitle(data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,82 +1,165 @@
|
||||
<div class="content">
|
||||
<div>
|
||||
<button mat-raised-button color="accent" [routerLink]="['/newjump']" [routerLinkActive]="['active']"
|
||||
skipLocationChange>{{ 'List_Jump_Add' | translate }}</button>
|
||||
<button
|
||||
mat-raised-button
|
||||
color="accent"
|
||||
[routerLink]="['/newjump']"
|
||||
[routerLinkActive]="['active']"
|
||||
skipLocationChange
|
||||
>
|
||||
{{ "ListJump_Add" | translate }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<mat-progress-bar [mode]="'indeterminate'" *ngIf="isLoading"></mat-progress-bar>
|
||||
<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 aria-hidden="false" aria-label="Additional informations of the jump"
|
||||
style="cursor: pointer;" (click)='openDialog(element, false)'>info</mat-icon>
|
||||
<mat-icon aria-hidden="false" aria-label="Special jump"
|
||||
[style.visibility]="element.notes != undefined ? 'visible' : 'hidden'">sticky_note_2</mat-icon>
|
||||
<mat-icon aria-hidden="false" aria-label="Special jump"
|
||||
[style.visibility]="element.isSpecial ? 'visible' : 'hidden'">celebration</mat-icon>
|
||||
<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
|
||||
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="id">
|
||||
<th mat-header-cell *matHeaderCellDef style="min-width: 70px;">{{ 'List_Jump_Header_Num' | translate }}
|
||||
<th mat-header-cell *matHeaderCellDef style="min-width: 70px">
|
||||
{{ "ListJump_Header_Num" | translate }}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element; let i = index">
|
||||
{{ paginator.length - ( (paginator.pageIndex * paginator.pageSize ) + i ) }}
|
||||
{{
|
||||
paginator.length - (paginator.pageIndex * paginator.pageSize + i)
|
||||
}}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="jumpDate">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'List_Jump_Header_Date' | translate }}</th>
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
{{ "ListJump_Header_Date" | translate }}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<span class="smallSpanWithBreakWord" [innerHTML]="element.jumpDate | date: 'yyyy-MM-dd'"></span>
|
||||
<span
|
||||
class="smallSpanWithBreakWord"
|
||||
[innerHTML]="element.jumpDate | date: 'yyyy-MM-dd'"
|
||||
></span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="jumpType">
|
||||
<th mat-header-cell *matHeaderCellDef style="min-width: 100px;text-wrap: nowrap;">{{ 'List_Jump_Header_JumpType' |
|
||||
translate }}</th>
|
||||
<td mat-cell *matCellDef="let element" style="text-wrap: nowrap;">
|
||||
<span class="smallSpanWithBreakWord" [innerHTML]="element.jumpType.name"></span>
|
||||
<th
|
||||
mat-header-cell
|
||||
*matHeaderCellDef
|
||||
style="min-width: 100px; text-wrap: nowrap"
|
||||
>
|
||||
{{ "ListJump_Header_JumpType" | translate }}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element" style="text-wrap: nowrap">
|
||||
<span
|
||||
class="smallSpanWithBreakWord"
|
||||
[innerHTML]="element.jumpType.name"
|
||||
></span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="aircraft">
|
||||
<th mat-header-cell *matHeaderCellDef style="min-width: 110px;">{{ 'List_Jump_Header_Aircraft' |
|
||||
translate }}</th>
|
||||
<th mat-header-cell *matHeaderCellDef style="min-width: 110px">
|
||||
{{ "ListJump_Header_Aircraft" | translate }}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<span class="smallSpanWithBreakWord" [innerHTML]="element.aircraft.name"></span>
|
||||
<span
|
||||
class="smallSpanWithBreakWord"
|
||||
[innerHTML]="element.aircraft.name"
|
||||
></span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="dropZone">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'List_Jump_Header_Dz' | translate }}</th>
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
{{ "ListJump_Header_Dz" | translate }}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<span class="spanWithBreakWord" [innerHTML]="element.dropZone.name"></span>
|
||||
<span
|
||||
class="spanWithBreakWord"
|
||||
[innerHTML]="element.dropZone.name"
|
||||
></span>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="gear">
|
||||
<th mat-header-cell *matHeaderCellDef>{{ 'List_Jump_Header_Id' | translate }}</th>
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
{{ "ListJump_Header_Id" | translate }}
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let element">{{ element.gear.name }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<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 aria-hidden="false" aria-label="Delete this jump" style="cursor: pointer;"
|
||||
(click)='delete(element)'>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)'>edit</mat-icon>
|
||||
<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
|
||||
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>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<mat-paginator #paginator [pageSize]="20" (page)="pageChanged($event)" showFirstLastButtons></mat-paginator>
|
||||
<mat-paginator
|
||||
#paginator
|
||||
[pageSize]="20"
|
||||
(page)="pageChanged($event)"
|
||||
showFirstLastButtons
|
||||
></mat-paginator>
|
||||
</div>
|
||||
@@ -1,8 +1,21 @@
|
||||
import { Component, OnInit, ViewChild } from "@angular/core";
|
||||
import { MatPaginator, PageEvent } from "@angular/material/paginator";
|
||||
import { MatTableDataSource } from "@angular/material/table";
|
||||
import { RouterLink, RouterModule } from "@angular/router";
|
||||
import {
|
||||
MatPaginator,
|
||||
MatPaginatorModule,
|
||||
PageEvent,
|
||||
} from "@angular/material/paginator";
|
||||
import { MatTableDataSource, MatTableModule } from "@angular/material/table";
|
||||
import { MatDialog } from "@angular/material/dialog";
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { MatIconModule } from "@angular/material/icon";
|
||||
import { MatProgressSpinnerModule } from "@angular/material/progress-spinner";
|
||||
import { MatProgressBarModule } from "@angular/material/progress-bar";
|
||||
import { MatButtonModule } from "@angular/material/button";
|
||||
import { MatInputModule } from "@angular/material/input";
|
||||
import { ReactiveFormsModule } from "@angular/forms";
|
||||
import { MatFormFieldModule } from "@angular/material/form-field";
|
||||
|
||||
import { AddAction } from "../../models/add-action.enum";
|
||||
import { Jump } from "../../models/jump";
|
||||
@@ -15,7 +28,21 @@ import { StatsService } from "../../services/stats.service";
|
||||
selector: "app-list-of-jumps",
|
||||
templateUrl: "./list-of-jumps.component.html",
|
||||
styleUrls: ["./list-of-jumps.component.css"],
|
||||
standalone: false
|
||||
imports: [
|
||||
TranslateModule,
|
||||
CommonModule,
|
||||
RouterLink,
|
||||
RouterModule,
|
||||
MatIconModule,
|
||||
MatPaginatorModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatProgressBarModule,
|
||||
MatTableModule,
|
||||
MatFormFieldModule,
|
||||
ReactiveFormsModule,
|
||||
MatInputModule,
|
||||
MatButtonModule,
|
||||
],
|
||||
})
|
||||
export class ListOfJumpsComponent implements OnInit {
|
||||
public displayedColumns: Array<string> = [
|
||||
@@ -31,7 +58,8 @@ export class ListOfJumpsComponent implements OnInit {
|
||||
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
|
||||
public isLoading: boolean = false;
|
||||
|
||||
constructor(private serviceApi: JumpService,
|
||||
constructor(
|
||||
private serviceApi: JumpService,
|
||||
private serviceComm: ServiceComm,
|
||||
public dialog: MatDialog,
|
||||
private translateService: TranslateService,
|
||||
@@ -62,7 +90,8 @@ export class ListOfJumpsComponent implements OnInit {
|
||||
getListOfJumps(pageSize: number = 20, pageIndex: number = 0) {
|
||||
this.isLoading = true;
|
||||
|
||||
this.serviceApi.getJumps(pageIndex * pageSize, pageIndex * pageSize + pageSize)
|
||||
this.serviceApi
|
||||
.getJumps(pageIndex * pageSize, pageIndex * pageSize + pageSize)
|
||||
.subscribe((data) => {
|
||||
this.dataSourceTable.data = data.rows;
|
||||
setTimeout(() => {
|
||||
|
||||
@@ -38,11 +38,11 @@
|
||||
</mat-nav-list>
|
||||
|
||||
<div class="chart-container">
|
||||
<!-- https://www.freecodecamp.org/news/how-to-make-bar-and-line-charts-using-chartjs-in-angular/ -->
|
||||
<canvas
|
||||
baseChart
|
||||
[data]="barChartData"
|
||||
[options]="barChartOptions"
|
||||
[plugins]="barChartPlugins"
|
||||
[legend]="barChartLegend"
|
||||
[type]="barChartType"
|
||||
>
|
||||
@@ -124,8 +124,8 @@
|
||||
aria-label="Delete this jump"
|
||||
style="cursor: pointer"
|
||||
(click)="delete(element)"
|
||||
>delete</mat-icon
|
||||
>
|
||||
svgIcon="delete"
|
||||
></mat-icon>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
||||
@@ -1,30 +1,55 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { formatDate } from '@angular/common';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { ChartConfiguration, ChartData, ChartType } from 'chart.js';
|
||||
import { from, of, groupBy, mergeMap, reduce, map, Observable } from 'rxjs';
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { RouterLink, RouterModule } from "@angular/router";
|
||||
import { formatDate } from "@angular/common";
|
||||
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
||||
import { MatTableDataSource, MatTableModule } from "@angular/material/table";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { MatIconModule } from "@angular/material/icon";
|
||||
import { MatListModule } from "@angular/material/list";
|
||||
import { MatProgressSpinnerModule } from "@angular/material/progress-spinner";
|
||||
import { MatRadioModule } from "@angular/material/radio";
|
||||
import { MatProgressBarModule } from "@angular/material/progress-bar";
|
||||
import { FormsModule } from "@angular/forms";
|
||||
import { MatButtonModule } from "@angular/material/button";
|
||||
|
||||
import { ServiceComm } from '../../services/service-comm.service';
|
||||
import { ChartConfiguration, ChartData, ChartType } from "chart.js";
|
||||
import { from, groupBy, mergeMap, reduce, map } from "rxjs";
|
||||
import { BaseChartDirective } from "ng2-charts";
|
||||
|
||||
import { ServiceComm } from "../../services/service-comm.service";
|
||||
import { TunnelFlightService } from "../../services/tunnel-flight.service";
|
||||
import { DateService } from '../../services/date.service';
|
||||
import { TunnelFlight, TunnelFlightByMonth } from '../../models/tunnel-flight';
|
||||
import { DateService } from "../../services/date.service";
|
||||
import { TunnelFlight, TunnelFlightByMonth } from "../../models/tunnel-flight";
|
||||
|
||||
@Component({
|
||||
selector: 'app-list-of-tunnel-flights',
|
||||
templateUrl: './list-of-tunnel-flights.component.html',
|
||||
styleUrls: ['./list-of-tunnel-flights.component.css'],
|
||||
standalone: false
|
||||
selector: "app-list-of-tunnel-flights",
|
||||
templateUrl: "./list-of-tunnel-flights.component.html",
|
||||
styleUrls: ["./list-of-tunnel-flights.component.css"],
|
||||
imports: [
|
||||
TranslateModule,
|
||||
BaseChartDirective,
|
||||
CommonModule,
|
||||
MatIconModule,
|
||||
MatListModule,
|
||||
MatProgressSpinnerModule,
|
||||
RouterLink,
|
||||
MatRadioModule,
|
||||
MatProgressBarModule,
|
||||
FormsModule,
|
||||
RouterModule,
|
||||
MatTableModule,
|
||||
MatButtonModule,
|
||||
],
|
||||
})
|
||||
export class ListOfTunnelFlightsComponent implements OnInit {
|
||||
public barChartLegend = true;
|
||||
public barChartPlugins = [];
|
||||
public barChartData: ChartData<'bar'>;
|
||||
public barChartOptions: ChartConfiguration['options'];
|
||||
public barChartData: ChartData<"bar">;
|
||||
public barChartOptions: ChartConfiguration["options"];
|
||||
public barChartType: ChartType;
|
||||
public isLoading: boolean = false;
|
||||
public selectedPeriod: string;
|
||||
public dataSourceTable: MatTableDataSource<TunnelFlight> = new MatTableDataSource();
|
||||
public dataSourceTable: MatTableDataSource<TunnelFlight> =
|
||||
new MatTableDataSource();
|
||||
public displayedColumns: Array<string> = [
|
||||
"id",
|
||||
"tunnel",
|
||||
@@ -32,14 +57,16 @@ export class ListOfTunnelFlightsComponent implements OnInit {
|
||||
"nbMinutes",
|
||||
"notes",
|
||||
"flightDate",
|
||||
"actions"
|
||||
"actions",
|
||||
];
|
||||
public stats: Array<{id: String|Number, values: String|Number}> = [];
|
||||
public stats: Array<{ id: String | Number; values: String | Number }> = [];
|
||||
|
||||
constructor(private serviceComm: ServiceComm,
|
||||
constructor(
|
||||
private serviceComm: ServiceComm,
|
||||
private serviceTunnelFlight: TunnelFlightService,
|
||||
private translateService: TranslateService,
|
||||
private dateService: DateService) { }
|
||||
private dateService: DateService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
||||
@@ -50,7 +77,7 @@ export class ListOfTunnelFlightsComponent implements OnInit {
|
||||
this.updateTitle();
|
||||
|
||||
this.chartConfig();
|
||||
this.selectedPeriod = "currentYear"
|
||||
this.selectedPeriod = "currentYear";
|
||||
this.getDataForGraph();
|
||||
}
|
||||
|
||||
@@ -72,34 +99,34 @@ export class ListOfTunnelFlightsComponent implements OnInit {
|
||||
maintainAspectRatio: true,
|
||||
plugins: {
|
||||
legend: {
|
||||
display: true
|
||||
display: true,
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
footer: this.footer,
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
interaction: {
|
||||
intersect: false,
|
||||
mode: 'nearest',
|
||||
axis: 'x'
|
||||
mode: "nearest",
|
||||
axis: "x",
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
stacked: true
|
||||
stacked: true,
|
||||
},
|
||||
y: {
|
||||
stacked: true
|
||||
}
|
||||
}
|
||||
stacked: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
private updateTitle() {
|
||||
this.translateService.get("ListTunnelFlight_Title").subscribe(
|
||||
data => { this.serviceComm.updatedComponentTitle(data); }
|
||||
);
|
||||
this.translateService.get("ListTunnelFlight_Title").subscribe((data) => {
|
||||
this.serviceComm.updatedComponentTitle(data);
|
||||
});
|
||||
}
|
||||
|
||||
private getDataForTable(): void {
|
||||
@@ -110,7 +137,8 @@ export class ListOfTunnelFlightsComponent implements OnInit {
|
||||
endDate.setHours(0, 0, 0, 0);
|
||||
let beginDate = this.computeBeginDateByPeriod(this.selectedPeriod, endDate);
|
||||
|
||||
this.serviceTunnelFlight.getTunnelFlights(beginDate, endDate)
|
||||
this.serviceTunnelFlight
|
||||
.getTunnelFlights(beginDate, endDate)
|
||||
.subscribe((data) => {
|
||||
this.dataSourceTable.data = data;
|
||||
this.isLoading = false;
|
||||
@@ -125,14 +153,18 @@ export class ListOfTunnelFlightsComponent implements OnInit {
|
||||
endDate.setHours(0, 0, 0, 0);
|
||||
let beginDate = this.computeBeginDateByPeriod(this.selectedPeriod, endDate);
|
||||
|
||||
this.serviceTunnelFlight.getTunnelFlightsByMonth(beginDate, endDate)
|
||||
this.serviceTunnelFlight
|
||||
.getTunnelFlightsByMonth(beginDate, endDate)
|
||||
.subscribe((data) => {
|
||||
const allMonths = this.getMontsBetweenDates(beginDate, endDate)
|
||||
const cumulatedTime = this.getCumulatedTimeByTypeByMonth(data, allMonths);
|
||||
const allMonths = this.getMontsBetweenDates(beginDate, endDate);
|
||||
const cumulatedTime = this.getCumulatedTimeByTypeByMonth(
|
||||
data,
|
||||
allMonths
|
||||
);
|
||||
this.computeTimeByType(data);
|
||||
this.barChartData = {
|
||||
labels: allMonths,
|
||||
datasets: cumulatedTime
|
||||
datasets: cumulatedTime,
|
||||
};
|
||||
|
||||
this.isLoading = false;
|
||||
@@ -141,12 +173,16 @@ export class ListOfTunnelFlightsComponent implements OnInit {
|
||||
|
||||
private computeTimeByType(stats: TunnelFlightByMonth[]) {
|
||||
this.stats = [];
|
||||
from(stats).pipe(
|
||||
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) }))
|
||||
map((arr) => ({
|
||||
id: arr[0],
|
||||
values: arr.slice(1).reduce((a, b) => Number(a) + Number(b), 0),
|
||||
}))
|
||||
)
|
||||
.subscribe((p) => {
|
||||
console.log(p);
|
||||
@@ -167,12 +203,18 @@ export class ListOfTunnelFlightsComponent implements OnInit {
|
||||
return results;
|
||||
}
|
||||
|
||||
private getCumulatedTimeByTypeByMonth(stats: TunnelFlightByMonth[], allMonths: string[]): Array<any> {
|
||||
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));
|
||||
disctintType.forEach((type) => {
|
||||
tmpResults.set(
|
||||
type,
|
||||
Array.from({ length: allMonths.length }, (v, k) => 0)
|
||||
);
|
||||
});
|
||||
|
||||
for (let i = 0; i < allMonths.length; i++) {
|
||||
@@ -180,30 +222,33 @@ export class ListOfTunnelFlightsComponent implements OnInit {
|
||||
let filteredStats = stats.filter((d) => d.month == month);
|
||||
|
||||
if (filteredStats.length > 0) {
|
||||
filteredStats.forEach(fs => {
|
||||
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 { label: item[0], data: item[1] };
|
||||
});
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private footer = (tooltipItems) => {
|
||||
private footer = (tooltipItems: any) => {
|
||||
let sum = 0;
|
||||
|
||||
tooltipItems.forEach(function (tooltipItem) {
|
||||
tooltipItems.forEach(function (tooltipItem: any) {
|
||||
sum += tooltipItem.parsed.y;
|
||||
});
|
||||
|
||||
return 'Sum: ' + sum;
|
||||
return "Sum: " + sum;
|
||||
};
|
||||
|
||||
private computeBeginDateByPeriod(selectedPeriod: String, endDate: Date): Date {
|
||||
private computeBeginDateByPeriod(
|
||||
selectedPeriod: String,
|
||||
endDate: Date
|
||||
): Date {
|
||||
let beginDate = new Date();
|
||||
|
||||
switch (selectedPeriod) {
|
||||
|
||||
@@ -1,35 +1,49 @@
|
||||
<form focusInvalidInput autocomplete="off" style="padding: 10px;"
|
||||
[formGroup]="loginForm" (ngSubmit)="onLoginSubmit()">
|
||||
<form
|
||||
focusInvalidInput
|
||||
autocomplete="off"
|
||||
style="padding: 10px"
|
||||
[formGroup]="loginForm"
|
||||
(ngSubmit)="onLoginSubmit()"
|
||||
>
|
||||
<p>
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'LoginUser_Username' | translate }}</mat-label>
|
||||
<input type="text" matInput #username="matInput" formControlName="username"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls.username.errors }">
|
||||
<mat-error *ngIf="formCtrls.username.hasError('required')">
|
||||
{{ 'LoginUser_UsernameRequired' | translate }}
|
||||
<mat-label>{{ "LoginUser_Username" | translate }}</mat-label>
|
||||
<input
|
||||
type="text"
|
||||
matInput
|
||||
#username="matInput"
|
||||
formControlName="username"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls['username'].errors }"
|
||||
/>
|
||||
<mat-error *ngIf="formCtrls['username'].hasError('required')">
|
||||
{{ "LoginUser_UsernameRequired" | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="formCtrls.username.hasError('minlength')">
|
||||
<mat-error *ngIf="formCtrls['username'].hasError('minlength')">
|
||||
{{ 'LoginUser_UsernamePattern | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</p>
|
||||
<p>
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'LoginUser_Password' | translate }}</mat-label>
|
||||
<input type="password" matInput formControlName="password"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls.password.errors }">
|
||||
<mat-error *ngIf="formCtrls.password.hasError('required')">
|
||||
{{ 'LoginUser_PasswordRequired' | translate }}
|
||||
<mat-label>{{ "LoginUser_Password" | translate }}</mat-label>
|
||||
<input
|
||||
type="password"
|
||||
matInput
|
||||
formControlName="password"
|
||||
[ngClass]="{ 'is-invalid': submitted && formCtrls['password'].errors }"
|
||||
/>
|
||||
<mat-error *ngIf="formCtrls['password'].hasError('required')">
|
||||
{{ "LoginUser_PasswordRequired" | translate }}
|
||||
</mat-error>
|
||||
<mat-error *ngIf="formCtrls.password.hasError('pattern')">
|
||||
{{ 'LoginUser_PasswordPattern' | translate }}
|
||||
<mat-error *ngIf="formCtrls['password'].hasError('pattern')">
|
||||
{{ "LoginUser_PasswordPattern" | translate }}
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
</p>
|
||||
|
||||
<button [disabled]="loading" mat-raised-button color="accent">
|
||||
<span *ngIf="loading" class="spinner-border spinner-border-sm mr-1"></span>
|
||||
{{ 'LoginUser_BtnLogin' | translate }}
|
||||
{{ "LoginUser_BtnLogin" | translate }}
|
||||
</button>
|
||||
|
||||
<div *ngIf="error" class="alert alert-danger mt-3 mb-0">{{ error }}</div>
|
||||
|
||||
@@ -1,73 +1,88 @@
|
||||
import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
|
||||
import { Router, ActivatedRoute } from '@angular/router';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { MatInput } from '@angular/material/input';
|
||||
import { Component, OnInit, ViewChild, AfterViewInit } from "@angular/core";
|
||||
import { Router, ActivatedRoute } from "@angular/router";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import {
|
||||
FormBuilder,
|
||||
FormGroup,
|
||||
ReactiveFormsModule,
|
||||
Validators,
|
||||
} from "@angular/forms";
|
||||
import { TranslateModule, TranslatePipe } from "@ngx-translate/core";
|
||||
import { MatInput, MatInputModule } from "@angular/material/input";
|
||||
import { MatFormFieldModule } from "@angular/material/form-field";
|
||||
import { MatButtonModule } from "@angular/material/button";
|
||||
|
||||
import { first } from 'rxjs/operators';
|
||||
import { first } from "rxjs/operators";
|
||||
|
||||
import { AuthenticationService } from '../../services/authentication.service';
|
||||
import { AuthenticationService } from "../../services/authentication.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-login-user',
|
||||
templateUrl: './login-user.component.html',
|
||||
styleUrls: ['./login-user.component.css'],
|
||||
standalone: false
|
||||
selector: "app-login-user",
|
||||
templateUrl: "./login-user.component.html",
|
||||
styleUrls: ["./login-user.component.css"],
|
||||
imports: [
|
||||
CommonModule,
|
||||
MatFormFieldModule,
|
||||
ReactiveFormsModule,
|
||||
MatInputModule,
|
||||
TranslateModule,
|
||||
TranslatePipe,
|
||||
MatButtonModule,
|
||||
],
|
||||
})
|
||||
export class LoginUserComponent implements OnInit, AfterViewInit {
|
||||
loginForm: FormGroup;
|
||||
loading = false;
|
||||
submitted = false;
|
||||
returnUrl: string;
|
||||
error = '';
|
||||
@ViewChild('username') userNameInput: MatInput;
|
||||
export class LoginUserComponent implements OnInit {
|
||||
public loginForm: FormGroup;
|
||||
public loading = false;
|
||||
public submitted = false;
|
||||
public returnUrl: string;
|
||||
public error: string = "";
|
||||
|
||||
constructor(private formBuilder: FormBuilder,
|
||||
constructor(
|
||||
private formBuilder: FormBuilder,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private authenticationService: AuthenticationService) {
|
||||
private authenticationService: AuthenticationService
|
||||
) {
|
||||
if (this.authenticationService.currentUserValue) {
|
||||
this.router.navigate(['/']);
|
||||
this.router.navigate(["/"]);
|
||||
}
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.userNameInput.focus();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.loginForm = this.formBuilder.group(
|
||||
{
|
||||
username: ['', [Validators.required, Validators.minLength(3)]],
|
||||
password: ['', [Validators.required]]
|
||||
username: ["", [Validators.required, Validators.minLength(3)]],
|
||||
password: ["", [Validators.required]],
|
||||
},
|
||||
{ updateOn: 'submit' }
|
||||
{ updateOn: "submit" }
|
||||
);
|
||||
|
||||
// get return url from route parameters or default to '/'
|
||||
this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
|
||||
|
||||
this.returnUrl = this.route.snapshot.queryParams["returnUrl"] || "/";
|
||||
}
|
||||
|
||||
get formCtrls() {
|
||||
return this.loginForm.controls;
|
||||
}
|
||||
|
||||
onLoginSubmit() {
|
||||
public onLoginSubmit() {
|
||||
this.submitted = true;
|
||||
|
||||
if (this.loginForm.valid) {
|
||||
this.loading = true;
|
||||
this.authenticationService.login(this.formCtrls.username.value, this.formCtrls.password.value)
|
||||
this.authenticationService
|
||||
.login(
|
||||
this.formCtrls["username"].value,
|
||||
this.formCtrls["password"].value
|
||||
)
|
||||
.pipe(first())
|
||||
.subscribe(
|
||||
data => {
|
||||
this.router.navigate([this.returnUrl]);
|
||||
},
|
||||
error => {
|
||||
this.error = error;
|
||||
.subscribe({
|
||||
complete: () => this.router.navigate([this.returnUrl]),
|
||||
error: (error) => {
|
||||
this.error = error.message;
|
||||
this.loading = false;
|
||||
}
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,30 @@
|
||||
<div class="content">
|
||||
<mat-card style="max-width: 500px;" flex="50">
|
||||
<mat-card-header style="align-items: center; justify-content: center; background-color: rgba(0,0,0,.03);">
|
||||
<mat-card-title>{{ 'Login_Title' | translate }}</mat-card-title>
|
||||
<mat-card style="max-width: 500px" flex="50">
|
||||
<mat-card-header
|
||||
style="
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(0, 0, 0, 0.03);
|
||||
"
|
||||
>
|
||||
<mat-card-title>{{ "Login_Title" | translate }}</mat-card-title>
|
||||
|
||||
<mat-select (selectionChange)="switchLang($event)" [(value)]="selectedLanguageFlag"
|
||||
style="width: 60px; padding-left: 30px;" >
|
||||
<mat-select
|
||||
(selectionChange)="switchLang($event)"
|
||||
[(value)]="selectedLanguageFlag"
|
||||
style="width: 60px; padding-left: 30px"
|
||||
>
|
||||
<mat-select-trigger>
|
||||
<img src="{{ 'assets/img/' + selectedLanguageFlag + '.svg' }}" style="width: 30px;">
|
||||
<img
|
||||
src="{{ 'assets/img/' + selectedLanguageFlag + '.svg' }}"
|
||||
style="width: 30px"
|
||||
/>
|
||||
</mat-select-trigger>
|
||||
<mat-option value="fr">
|
||||
<img src="assets/img/fr.svg" style="width: 30px;">
|
||||
<img src="assets/img/fr.svg" style="width: 30px" />
|
||||
</mat-option>
|
||||
<mat-option value="en">
|
||||
<img src="assets/img/en.svg" style="width: 30px;">
|
||||
<img src="assets/img/en.svg" style="width: 30px" />
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-card-header>
|
||||
|
||||
@@ -1,18 +1,38 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
import {
|
||||
TranslateModule,
|
||||
TranslatePipe,
|
||||
TranslateService,
|
||||
} from "@ngx-translate/core";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { MatSelectModule } from "@angular/material/select";
|
||||
import { MatOptionModule } from "@angular/material/core";
|
||||
import { MatCardModule } from "@angular/material/card";
|
||||
import { MatTabsModule } from "@angular/material/tabs";
|
||||
|
||||
import { LoginUserComponent } from "../login-user/login-user.component";
|
||||
import { CreateUserComponent } from "../create-user/create-user.component";
|
||||
|
||||
@Component({
|
||||
selector: "app-login",
|
||||
templateUrl: "./login.component.html",
|
||||
styleUrls: ["./login.component.css"],
|
||||
standalone: false
|
||||
imports: [
|
||||
TranslateModule,
|
||||
CommonModule,
|
||||
MatSelectModule,
|
||||
MatOptionModule,
|
||||
MatCardModule,
|
||||
MatTabsModule,
|
||||
LoginUserComponent,
|
||||
CreateUserComponent,
|
||||
TranslateModule,
|
||||
],
|
||||
})
|
||||
export class LoginComponent implements OnInit {
|
||||
public selectedLanguageFlag: string;
|
||||
|
||||
constructor(private translate: TranslateService) {
|
||||
translate.addLangs(['en', 'fr']);
|
||||
translate.setDefaultLang('en');
|
||||
this.selectedLanguageFlag = "en";
|
||||
}
|
||||
|
||||
|
||||
@@ -1,52 +1,85 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { FormControl, FormGroup, Validators } from '@angular/forms';
|
||||
import { AircraftService } from '../../services/aircraft.service';
|
||||
import { ServiceComm } from '../../services/service-comm.service';
|
||||
import { AddAction } from '../../models/add-action.enum';
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import {
|
||||
FormControl,
|
||||
FormGroup,
|
||||
ReactiveFormsModule,
|
||||
Validators,
|
||||
} from "@angular/forms";
|
||||
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
||||
import { MatFormFieldModule } from "@angular/material/form-field";
|
||||
import { MatInputModule } from "@angular/material/input";
|
||||
import { MatButtonModule } from "@angular/material/button";
|
||||
|
||||
import { AddAction } from "../../models/add-action.enum";
|
||||
|
||||
import { AircraftService } from "../../services/aircraft.service";
|
||||
import { ServiceComm } from "../../services/service-comm.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-new-aircraft',
|
||||
templateUrl: './new-aircraft.component.html',
|
||||
styleUrls: ['./new-aircraft.component.css'],
|
||||
standalone: false
|
||||
selector: "app-new-aircraft",
|
||||
templateUrl: "./new-aircraft.component.html",
|
||||
styleUrls: ["./new-aircraft.component.css"],
|
||||
imports: [
|
||||
TranslateModule,
|
||||
MatFormFieldModule,
|
||||
ReactiveFormsModule,
|
||||
MatFormFieldModule,
|
||||
ReactiveFormsModule,
|
||||
MatInputModule,
|
||||
MatButtonModule,
|
||||
],
|
||||
})
|
||||
export class NewAircraftComponent implements OnInit {
|
||||
public addForm: FormGroup;
|
||||
public imageError: string;
|
||||
private selectedFile: string;
|
||||
|
||||
constructor(private serviceComm: ServiceComm,
|
||||
private serviceApi: AircraftService) {
|
||||
constructor(
|
||||
private serviceComm: ServiceComm,
|
||||
private serviceApi: AircraftService,
|
||||
private translateService: TranslateService,
|
||||
) {
|
||||
this.addForm = new FormGroup(
|
||||
{
|
||||
aircraftName: new FormControl('', Validators.required)
|
||||
aircraftName: new FormControl("", Validators.required),
|
||||
},
|
||||
{ updateOn: 'blur' }
|
||||
{ updateOn: "blur" },
|
||||
);
|
||||
}
|
||||
|
||||
ngOnInit() { }
|
||||
ngOnInit() {
|
||||
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
||||
if (data === true) {
|
||||
this.updateTitle();
|
||||
}
|
||||
});
|
||||
|
||||
this.updateTitle();
|
||||
}
|
||||
|
||||
onSubmit(formData) {
|
||||
if (formData.invalid) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.serviceApi.addAircraft(formData.aircraftName, this.selectedFile)
|
||||
this.serviceApi
|
||||
.addAircraft(formData.aircraftName, this.selectedFile)
|
||||
.subscribe(() => {
|
||||
this.serviceComm.refreshData(AddAction.Aircraft);
|
||||
});
|
||||
}
|
||||
|
||||
public onFileChanged(fileInput: any) {
|
||||
const file = fileInput.dataTransfer ? fileInput.dataTransfer.files[0] : fileInput.target.files[0];
|
||||
const allowed_types = ['image/png', 'image/jpeg'];
|
||||
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 )';
|
||||
this.imageError = "Only Images are allowed ( JPG | PNG )";
|
||||
} else if (file.size > max_size) {
|
||||
this.imageError = 'Maximum size allowed is ' + max_size / 1000 + 'Mb';
|
||||
this.imageError = "Maximum size allowed is " + max_size / 1000 + "Mb";
|
||||
} else {
|
||||
const reader = new FileReader();
|
||||
reader.onload = this.checkAndExtractDataToBase64.bind(this);
|
||||
@@ -61,17 +94,23 @@ export class NewAircraftComponent implements OnInit {
|
||||
const image = new Image();
|
||||
image.src = e.target.result;
|
||||
image.onload = (rs) => {
|
||||
const img_height = rs.currentTarget['height'];
|
||||
const img_width = rs.currentTarget['width'];
|
||||
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';
|
||||
"Maximum dimentions allowed " + max_height + "*" + max_width + "px";
|
||||
} else {
|
||||
const imgBase64Path = e.target.result;
|
||||
this.selectedFile = imgBase64Path;
|
||||
this.imageError = 'OK';
|
||||
this.imageError = "OK";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private updateTitle() {
|
||||
this.translateService.get("NewAircraft_Title").subscribe((data) => {
|
||||
this.serviceComm.updatedComponentTitle(data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { FormControl, FormGroup, Validators } from "@angular/forms";
|
||||
import {
|
||||
FormControl,
|
||||
FormGroup,
|
||||
ReactiveFormsModule,
|
||||
Validators,
|
||||
} from "@angular/forms";
|
||||
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
||||
import { MatFormFieldModule } from "@angular/material/form-field";
|
||||
import { MatCheckboxModule } from "@angular/material/checkbox";
|
||||
import { MatInputModule } from "@angular/material/input";
|
||||
import { MatButtonModule } from "@angular/material/button";
|
||||
|
||||
import { AddAction } from "../../models/add-action.enum";
|
||||
|
||||
import { ServiceComm } from "../../services/service-comm.service";
|
||||
import { DropzoneService } from "../../services/dropzone.service";
|
||||
|
||||
@@ -8,36 +20,53 @@ import { DropzoneService } from "../../services/dropzone.service";
|
||||
selector: "app-new-drop-zone",
|
||||
templateUrl: "./new-drop-zone.component.html",
|
||||
styleUrls: ["./new-drop-zone.component.css"],
|
||||
standalone: false
|
||||
imports: [
|
||||
TranslateModule,
|
||||
MatFormFieldModule,
|
||||
MatCheckboxModule,
|
||||
ReactiveFormsModule,
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
MatButtonModule,
|
||||
],
|
||||
})
|
||||
export class NewDropZoneComponent implements OnInit {
|
||||
public addForm: FormGroup;
|
||||
|
||||
constructor(
|
||||
private serviceComm: ServiceComm,
|
||||
private dropzoneService: DropzoneService
|
||||
private dropzoneService: DropzoneService,
|
||||
private translateService: TranslateService,
|
||||
) {
|
||||
this.addForm = new FormGroup(
|
||||
{
|
||||
dzName: new FormControl("", Validators.required),
|
||||
gps: new FormControl("x.x,y.y", [
|
||||
Validators.required,
|
||||
Validators.pattern("d+.d+,d+.d+")
|
||||
Validators.pattern("d+.d+,d+.d+"),
|
||||
]),
|
||||
address: new FormControl("", Validators.required),
|
||||
website: new FormControl("", Validators.required),
|
||||
contactMail: new FormControl("", [
|
||||
Validators.required,
|
||||
Validators.email
|
||||
Validators.email,
|
||||
]),
|
||||
isDz: new FormControl(true),
|
||||
isTunnel: new FormControl(false)
|
||||
isTunnel: new FormControl(false),
|
||||
},
|
||||
{ updateOn: "blur" }
|
||||
{ updateOn: "blur" },
|
||||
);
|
||||
}
|
||||
|
||||
ngOnInit() {}
|
||||
ngOnInit() {
|
||||
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
||||
if (data === true) {
|
||||
this.updateTitle();
|
||||
}
|
||||
});
|
||||
|
||||
this.updateTitle();
|
||||
}
|
||||
|
||||
onSubmit(formData) {
|
||||
const splitGps: Array<string> = formData.gps.split(",");
|
||||
@@ -50,16 +79,25 @@ export class NewDropZoneComponent implements OnInit {
|
||||
dzType.push("tunnel");
|
||||
}
|
||||
|
||||
this.dropzoneService.addDropZone(splitGps[0],
|
||||
this.dropzoneService
|
||||
.addDropZone(
|
||||
splitGps[0],
|
||||
splitGps[1],
|
||||
formData.dzName,
|
||||
formData.address,
|
||||
formData.website,
|
||||
formData.contactMail,
|
||||
dzType,
|
||||
false)
|
||||
false,
|
||||
)
|
||||
.subscribe(() => {
|
||||
this.serviceComm.refreshData(AddAction.Dropzone);
|
||||
});
|
||||
}
|
||||
|
||||
private updateTitle() {
|
||||
this.translateService.get("NewDz_Title").subscribe((data) => {
|
||||
this.serviceComm.updatedComponentTitle(data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { FormControl, FormGroup, Validators } from "@angular/forms";
|
||||
import {
|
||||
FormControl,
|
||||
FormGroup,
|
||||
ReactiveFormsModule,
|
||||
Validators,
|
||||
} from "@angular/forms";
|
||||
import { MatFormFieldModule } from "@angular/material/form-field";
|
||||
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
||||
import { MatInputModule } from "@angular/material/input";
|
||||
import { MatButtonModule } from "@angular/material/button";
|
||||
|
||||
import { ServiceComm } from "../../services/service-comm.service";
|
||||
import { GearService } from "../../services/gear.service";
|
||||
@@ -9,14 +18,23 @@ import { AddAction } from "../../models/add-action.enum";
|
||||
selector: "app-new-gear",
|
||||
templateUrl: "./new-gear.component.html",
|
||||
styleUrls: ["./new-gear.component.css"],
|
||||
standalone: false
|
||||
imports: [
|
||||
TranslateModule,
|
||||
MatFormFieldModule,
|
||||
ReactiveFormsModule,
|
||||
ReactiveFormsModule,
|
||||
MatInputModule,
|
||||
MatButtonModule,
|
||||
],
|
||||
})
|
||||
export class NewGearComponent implements OnInit {
|
||||
public addForm: FormGroup;
|
||||
|
||||
constructor(private serviceComm: ServiceComm,
|
||||
private serviceApi: GearService)
|
||||
{
|
||||
constructor(
|
||||
private serviceComm: ServiceComm,
|
||||
private serviceApi: GearService,
|
||||
private translateService: TranslateService,
|
||||
) {
|
||||
this.addForm = new FormGroup(
|
||||
{
|
||||
name: new FormControl("", Validators.required),
|
||||
@@ -24,41 +42,58 @@ export class NewGearComponent implements OnInit {
|
||||
minSize: new FormControl("", [
|
||||
Validators.required,
|
||||
Validators.min(60),
|
||||
Validators.max(320)
|
||||
Validators.max(320),
|
||||
]),
|
||||
maxSize: new FormControl("", [
|
||||
Validators.required,
|
||||
Validators.min(60),
|
||||
Validators.max(320)
|
||||
Validators.max(320),
|
||||
]),
|
||||
aad: new FormControl("", Validators.required),
|
||||
mainCanopy: new FormControl("", [
|
||||
Validators.required,
|
||||
Validators.min(60),
|
||||
Validators.max(320)
|
||||
Validators.max(320),
|
||||
]),
|
||||
reserveCanopy: new FormControl("", [
|
||||
Validators.required,
|
||||
Validators.min(60),
|
||||
Validators.max(320)
|
||||
])
|
||||
Validators.max(320),
|
||||
]),
|
||||
},
|
||||
{ updateOn: "blur" }
|
||||
{ updateOn: "blur" },
|
||||
);
|
||||
}
|
||||
|
||||
ngOnInit() { }
|
||||
ngOnInit() {
|
||||
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
||||
if (data === true) {
|
||||
this.updateTitle();
|
||||
}
|
||||
});
|
||||
|
||||
this.updateTitle();
|
||||
}
|
||||
|
||||
onSubmit(formData) {
|
||||
this.serviceApi.addGear(formData.name,
|
||||
this.serviceApi
|
||||
.addGear(
|
||||
formData.name,
|
||||
formData.manufacturer,
|
||||
+formData.minSize,
|
||||
+formData.maxSize,
|
||||
formData.aad,
|
||||
formData.mainCanopy,
|
||||
formData.reserveCanopy)
|
||||
formData.reserveCanopy,
|
||||
)
|
||||
.subscribe(() => {
|
||||
this.serviceComm.refreshData(AddAction.Gear);
|
||||
});
|
||||
}
|
||||
|
||||
private updateTitle() {
|
||||
this.translateService.get("NewGear_Title").subscribe((data) => {
|
||||
this.serviceComm.updatedComponentTitle(data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { FormControl, FormGroup, Validators } from "@angular/forms";
|
||||
import {
|
||||
FormControl,
|
||||
FormGroup,
|
||||
ReactiveFormsModule,
|
||||
Validators,
|
||||
} from "@angular/forms";
|
||||
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
||||
import { MatFormFieldModule } from "@angular/material/form-field";
|
||||
import { MatInputModule } from "@angular/material/input";
|
||||
import { MatButtonModule } from "@angular/material/button";
|
||||
|
||||
import { AddAction } from "../../models/add-action.enum";
|
||||
import { ServiceComm } from "../../services/service-comm.service";
|
||||
import { JumpTypeService } from "../../services/jump-type.service";
|
||||
@@ -8,27 +18,49 @@ import { JumpTypeService } from "../../services/jump-type.service";
|
||||
selector: "app-new-jump-type",
|
||||
templateUrl: "./new-jump-type.component.html",
|
||||
styleUrls: ["./new-jump-type.component.css"],
|
||||
standalone: false
|
||||
imports: [
|
||||
TranslateModule,
|
||||
MatFormFieldModule,
|
||||
ReactiveFormsModule,
|
||||
MatInputModule,
|
||||
MatButtonModule,
|
||||
],
|
||||
})
|
||||
export class NewJumpTypeComponent implements OnInit {
|
||||
public addForm: FormGroup;
|
||||
|
||||
constructor(private serviceComm: ServiceComm,
|
||||
private jumpTypeService: JumpTypeService) {
|
||||
constructor(
|
||||
private serviceComm: ServiceComm,
|
||||
private jumpTypeService: JumpTypeService,
|
||||
private translateService: TranslateService,
|
||||
) {
|
||||
this.addForm = new FormGroup(
|
||||
{
|
||||
jumptypeName: new FormControl("", Validators.required)
|
||||
jumptypeName: new FormControl("", Validators.required),
|
||||
},
|
||||
{ updateOn: "blur" }
|
||||
{ updateOn: "blur" },
|
||||
);
|
||||
}
|
||||
|
||||
ngOnInit() { }
|
||||
ngOnInit() {
|
||||
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
||||
if (data === true) {
|
||||
this.updateTitle();
|
||||
}
|
||||
});
|
||||
|
||||
this.updateTitle();
|
||||
}
|
||||
|
||||
onSubmit(formData) {
|
||||
this.jumpTypeService.addJumpType(formData.jumptypeName)
|
||||
.subscribe(() => {
|
||||
this.jumpTypeService.addJumpType(formData.jumptypeName).subscribe(() => {
|
||||
this.serviceComm.refreshData(AddAction.JumpType);
|
||||
});
|
||||
}
|
||||
|
||||
private updateTitle() {
|
||||
this.translateService.get("NewJumpType_Title").subscribe((data) => {
|
||||
this.serviceComm.updatedComponentTitle(data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,119 +1,267 @@
|
||||
<div class="content">
|
||||
<div>
|
||||
<button mat-raised-button color="accent" [routerLink]="['/jumps']" [routerLinkActive]="['active']" skipLocationChange>{{ 'NewJump_GoToJump' | translate }}</button>
|
||||
<p><mat-checkbox [(ngModel)]="resetForm" labelPosition="before">{{ 'NewJump_ResetForm' | translate }}</mat-checkbox></p>
|
||||
<button
|
||||
mat-raised-button
|
||||
color="accent"
|
||||
[routerLink]="['/jumps']"
|
||||
[routerLinkActive]="['active']"
|
||||
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">
|
||||
<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-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">
|
||||
<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-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">
|
||||
<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">
|
||||
<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 }}
|
||||
<mat-icon aria-hidden="false" aria-label="Favorite" *ngIf="dropZone.isFavorite === true" color="primary">
|
||||
favorite</mat-icon>
|
||||
<mat-icon
|
||||
aria-hidden="false"
|
||||
aria-label="Favorite"
|
||||
*ngIf="dropZone.isFavorite === true"
|
||||
color="primary"
|
||||
>
|
||||
favorite</mat-icon
|
||||
>
|
||||
</mat-option>
|
||||
</mat-autocomplete>
|
||||
<button *ngIf="selectedDz" matSuffix mat-icon-button aria-label="Clear" (click)="resetDz()">
|
||||
<button
|
||||
*ngIf="selectedDz"
|
||||
matSuffix
|
||||
mat-icon-button
|
||||
aria-label="Clear"
|
||||
(click)="resetDz()"
|
||||
>
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>{{ 'NewJump_ChooseGear' | translate }}</mat-label>
|
||||
<input type="text" matInput [matAutocomplete]="autoGear" [(ngModel)]="selectedGear" name="selectedGear">
|
||||
<mat-autocomplete #autoGear="matAutocomplete" [displayWith]="displayGearFn">
|
||||
<mat-label>{{ "NewJump_ChooseGear" | translate }}</mat-label>
|
||||
<input
|
||||
type="text"
|
||||
matInput
|
||||
[matAutocomplete]="autoGear"
|
||||
[(ngModel)]="selectedGear"
|
||||
name="selectedGear"
|
||||
/>
|
||||
<mat-autocomplete
|
||||
#autoGear="matAutocomplete"
|
||||
[displayWith]="displayGearFn"
|
||||
>
|
||||
<mat-option *ngFor="let gear of listOfGear" [value]="gear">
|
||||
{{ gear.name }} ({{ gear.mainCanopy }})
|
||||
</mat-option>
|
||||
</mat-autocomplete>
|
||||
<button *ngIf="selectedGear" matSuffix mat-icon-button aria-label="Clear"
|
||||
(click)="selectedGear=undefined">
|
||||
<button
|
||||
*ngIf="selectedGear"
|
||||
matSuffix
|
||||
mat-icon-button
|
||||
aria-label="Clear"
|
||||
(click)="selectedGear = undefined"
|
||||
>
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-checkbox [(ngModel)]="withCutaway" name="withCutaway">{{ 'NewJump_Cutaway' | translate }}</mat-checkbox>
|
||||
<mat-checkbox [(ngModel)]="isSpecial" name="isSpecial">{{ 'NewJump_Special' | translate }}</mat-checkbox>
|
||||
<mat-checkbox [(ngModel)]="withCutaway" name="withCutaway">{{
|
||||
"NewJump_Cutaway" | translate
|
||||
}}</mat-checkbox>
|
||||
<mat-checkbox [(ngModel)]="isSpecial" name="isSpecial">{{
|
||||
"NewJump_Special" | translate
|
||||
}}</mat-checkbox>
|
||||
|
||||
<mat-form-field>
|
||||
<input matInput [matDatepicker]="beginDateDp" [(ngModel)]="beginDate"
|
||||
name="beginDate" disabled (ngModelChange)="onChangeBeginDate($event)">
|
||||
<mat-datepicker-toggle matSuffix [for]="beginDateDp"></mat-datepicker-toggle>
|
||||
<input
|
||||
matInput
|
||||
[matDatepicker]="beginDateDp"
|
||||
[(ngModel)]="beginDate"
|
||||
name="beginDate"
|
||||
disabled
|
||||
(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>
|
||||
<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">
|
||||
<button *ngIf="exitAltitude" matSuffix mat-icon-button aria-label="Clear"
|
||||
(click)="exitAltitude=undefined">
|
||||
<input
|
||||
matInput
|
||||
placeholder="{{ 'NewJump_ExitAlt' | translate }}"
|
||||
[(ngModel)]="exitAltitude"
|
||||
name="exitAltitude"
|
||||
type="number"
|
||||
/>
|
||||
<button
|
||||
*ngIf="exitAltitude"
|
||||
matSuffix
|
||||
mat-icon-button
|
||||
aria-label="Clear"
|
||||
(click)="exitAltitude = undefined"
|
||||
>
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{ 'NewJump_DeployAlt' | translate }}" [(ngModel)]="deployAltitude" name="deployAltitude" type="number">
|
||||
<button *ngIf="deployAltitude" matSuffix mat-icon-button aria-label="Clear"
|
||||
(click)="deployAltitude=undefined">
|
||||
<input
|
||||
matInput
|
||||
placeholder="{{ 'NewJump_DeployAlt' | translate }}"
|
||||
[(ngModel)]="deployAltitude"
|
||||
name="deployAltitude"
|
||||
type="number"
|
||||
/>
|
||||
<button
|
||||
*ngIf="deployAltitude"
|
||||
matSuffix
|
||||
mat-icon-button
|
||||
aria-label="Clear"
|
||||
(click)="deployAltitude = undefined"
|
||||
>
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="{{ 'NewJump_Count' | translate }}" [(ngModel)]="countOfJumps" name="countOfJumps" type="number">
|
||||
<button *ngIf="countOfJumps" matSuffix mat-icon-button aria-label="Clear"
|
||||
(click)="countOfJumps=undefined">
|
||||
<input
|
||||
matInput
|
||||
placeholder="{{ 'NewJump_Count' | translate }}"
|
||||
[(ngModel)]="countOfJumps"
|
||||
name="countOfJumps"
|
||||
type="number"
|
||||
/>
|
||||
<button
|
||||
*ngIf="countOfJumps"
|
||||
matSuffix
|
||||
mat-icon-button
|
||||
aria-label="Clear"
|
||||
(click)="countOfJumps = undefined"
|
||||
>
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<textarea matInput placeholder="{{ 'NewJump_Comments' | translate }}" [(ngModel)]="comments" name="comments" type="text"></textarea>
|
||||
<button *ngIf="comments" matSuffix mat-icon-button aria-label="Clear"
|
||||
(click)="comments=undefined">
|
||||
<textarea
|
||||
matInput
|
||||
placeholder="{{ 'NewJump_Comments' | translate }}"
|
||||
[(ngModel)]="comments"
|
||||
name="comments"
|
||||
type="text"
|
||||
></textarea>
|
||||
<button
|
||||
*ngIf="comments"
|
||||
matSuffix
|
||||
mat-icon-button
|
||||
aria-label="Clear"
|
||||
(click)="comments = undefined"
|
||||
>
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</mat-form-field>
|
||||
|
||||
<br />
|
||||
<button mat-raised-button color="accent" *ngIf="isValidatedForm()">{{ 'NewJump_Submit' | translate }}</button>
|
||||
<button mat-raised-button color="accent" *ngIf="isValidatedForm()">
|
||||
{{ "NewJump_Submit" | translate }}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<ng-template #loading>
|
||||
|
||||
@@ -1,7 +1,23 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { formatDate } from '@angular/common';
|
||||
import { DateAdapter, MAT_DATE_FORMATS, NativeDateAdapter } from "@angular/material/core";
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { RouterLink, RouterModule } from "@angular/router";
|
||||
import { formatDate } from "@angular/common";
|
||||
import {
|
||||
DateAdapter,
|
||||
MAT_DATE_FORMATS,
|
||||
NativeDateAdapter,
|
||||
} from "@angular/material/core";
|
||||
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { MatIconModule } from "@angular/material/icon";
|
||||
import { MatOptionModule } from "@angular/material/core";
|
||||
import { MatFormFieldModule } from "@angular/material/form-field";
|
||||
import { MatCheckboxModule } from "@angular/material/checkbox";
|
||||
import { MatAutocompleteModule } from "@angular/material/autocomplete";
|
||||
import { MatDatepickerModule } from "@angular/material/datepicker";
|
||||
import { MatProgressSpinnerModule } from "@angular/material/progress-spinner";
|
||||
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
|
||||
import { MatInputModule } from "@angular/material/input";
|
||||
import { MatButtonModule } from "@angular/material/button";
|
||||
|
||||
import { JumpTypeResp } from "../../models/jumpType";
|
||||
import { AircraftResp } from "../../models/aircraft";
|
||||
@@ -17,18 +33,17 @@ import { JumpTypeService } from "../../services/jump-type.service";
|
||||
import { GearService } from "../../services/gear.service";
|
||||
import { StatsService } from "../../services/stats.service";
|
||||
|
||||
|
||||
export const PICK_FORMATS = {
|
||||
parse: { dateInput: 'yy MM dd' },
|
||||
parse: { dateInput: "yy MM dd" },
|
||||
display: {
|
||||
dateInput: 'yyyy-MM-dd',
|
||||
monthYearLabel: 'yyyy MMM',
|
||||
dateA11yLabel: 'yyyy MM dd',
|
||||
monthYearA11yLabel: 'yyyy MMMM',
|
||||
}
|
||||
dateInput: "yyyy-MM-dd",
|
||||
monthYearLabel: "yyyy MMM",
|
||||
dateA11yLabel: "yyyy MM dd",
|
||||
monthYearA11yLabel: "yyyy MMMM",
|
||||
},
|
||||
};
|
||||
class PickDateAdapter extends NativeDateAdapter {
|
||||
format(date: Date, displayFormat: Object): string {
|
||||
override format(date: Date, displayFormat: Object): string {
|
||||
return formatDate(date, displayFormat.toString(), "en");
|
||||
}
|
||||
}
|
||||
@@ -39,9 +54,26 @@ class PickDateAdapter extends NativeDateAdapter {
|
||||
styleUrls: ["./new-jump.component.css"],
|
||||
providers: [
|
||||
{ provide: DateAdapter, useClass: PickDateAdapter },
|
||||
{ provide: MAT_DATE_FORMATS, useValue: PICK_FORMATS }
|
||||
{ provide: MAT_DATE_FORMATS, useValue: PICK_FORMATS },
|
||||
],
|
||||
imports: [
|
||||
TranslateModule,
|
||||
CommonModule,
|
||||
RouterLink,
|
||||
FormsModule,
|
||||
RouterModule,
|
||||
MatIconModule,
|
||||
MatOptionModule,
|
||||
MatFormFieldModule,
|
||||
MatCheckboxModule,
|
||||
MatAutocompleteModule,
|
||||
MatDatepickerModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatFormFieldModule,
|
||||
ReactiveFormsModule,
|
||||
MatInputModule,
|
||||
MatButtonModule,
|
||||
],
|
||||
standalone: false
|
||||
})
|
||||
export class NewJumpComponent implements OnInit {
|
||||
public beginDate: Date;
|
||||
@@ -66,7 +98,8 @@ export class NewJumpComponent implements OnInit {
|
||||
private listOfDropZone: Array<DropZoneResp>;
|
||||
public maxDate: Date;
|
||||
|
||||
constructor(private serviceComm: ServiceComm,
|
||||
constructor(
|
||||
private serviceComm: ServiceComm,
|
||||
private serviceJump: JumpService,
|
||||
private serviceJumpType: JumpTypeService,
|
||||
private serviceAircraft: AircraftService,
|
||||
@@ -74,7 +107,8 @@ export class NewJumpComponent implements OnInit {
|
||||
private serviceGear: GearService,
|
||||
private dateService: DateService,
|
||||
private translateService: TranslateService,
|
||||
private statsService : StatsService) {}
|
||||
private statsService: StatsService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
||||
@@ -94,7 +128,9 @@ export class NewJumpComponent implements OnInit {
|
||||
onFormSubmit() {
|
||||
this.pendingAddRequest = true;
|
||||
|
||||
this.serviceJump.addListOfJump(this.selectedJumpType.id,
|
||||
this.serviceJump
|
||||
.addListOfJump(
|
||||
this.selectedJumpType.id,
|
||||
this.selectedAircraft.id,
|
||||
this.selectedDz.id,
|
||||
this.selectedGear.id,
|
||||
@@ -105,7 +141,8 @@ export class NewJumpComponent implements OnInit {
|
||||
this.deployAltitude,
|
||||
this.countOfJumps,
|
||||
this.comments,
|
||||
this.isSpecial === undefined ? false : this.isSpecial)
|
||||
this.isSpecial === undefined ? false : this.isSpecial
|
||||
)
|
||||
.subscribe(() => {
|
||||
this.statsService.resetStats();
|
||||
this.comments = undefined;
|
||||
@@ -120,7 +157,8 @@ export class NewJumpComponent implements OnInit {
|
||||
}
|
||||
|
||||
public isValidatedForm(): boolean {
|
||||
return (this.selectedDz !== undefined &&
|
||||
return (
|
||||
this.selectedDz !== undefined &&
|
||||
this.selectedDz.id !== undefined &&
|
||||
this.selectedGear !== undefined &&
|
||||
this.selectedGear.id !== undefined &&
|
||||
@@ -133,12 +171,12 @@ export class NewJumpComponent implements OnInit {
|
||||
this.deployAltitude !== undefined &&
|
||||
typeof this.deployAltitude === "number" &&
|
||||
this.countOfJumps !== undefined &&
|
||||
typeof this.countOfJumps === "number");
|
||||
typeof this.countOfJumps === "number"
|
||||
);
|
||||
}
|
||||
|
||||
private getListOfJumpTypes() {
|
||||
this.serviceJumpType.getListOfJumpTypes()
|
||||
.subscribe((data) => {
|
||||
this.serviceJumpType.getListOfJumpTypes().subscribe((data) => {
|
||||
data.sort((a, b) => a.name.localeCompare(b.name));
|
||||
this.listOfJumpType = data;
|
||||
this.countDatasLoaded = 1;
|
||||
@@ -150,8 +188,7 @@ export class NewJumpComponent implements OnInit {
|
||||
}
|
||||
|
||||
private getListOfAircrafts() {
|
||||
this.serviceAircraft.getListOfAircrafts(true)
|
||||
.subscribe((data) => {
|
||||
this.serviceAircraft.getListOfAircrafts(true).subscribe((data) => {
|
||||
data.sort((a, b) => a.name.localeCompare(b.name));
|
||||
this.listOfAircraft = data;
|
||||
this.countDatasLoaded++;
|
||||
@@ -159,9 +196,12 @@ export class NewJumpComponent implements OnInit {
|
||||
}
|
||||
|
||||
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.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++;
|
||||
@@ -169,8 +209,7 @@ export class NewJumpComponent implements OnInit {
|
||||
}
|
||||
|
||||
private getListOfGears() {
|
||||
this.serviceGear.getListOfGears()
|
||||
.subscribe((data) => {
|
||||
this.serviceGear.getListOfGears().subscribe((data) => {
|
||||
data.sort((a, b) => b.id - a.id);
|
||||
this.listOfGear = data;
|
||||
this.countDatasLoaded++;
|
||||
@@ -212,8 +251,8 @@ export class NewJumpComponent implements OnInit {
|
||||
filterValue = event.toLowerCase();
|
||||
|
||||
this.listOfFilteredDropZone = this.listOfDropZone;
|
||||
this.listOfFilteredDropZone = this.listOfFilteredDropZone.filter((option) =>
|
||||
option.name.toLowerCase().includes(filterValue)
|
||||
this.listOfFilteredDropZone = this.listOfFilteredDropZone.filter(
|
||||
(option) => option.name.toLowerCase().includes(filterValue)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -228,12 +267,12 @@ export class NewJumpComponent implements OnInit {
|
||||
|
||||
public resetDz() {
|
||||
this.selectedDz = undefined;
|
||||
this.onChangeDz('');
|
||||
this.onChangeDz("");
|
||||
}
|
||||
|
||||
private updateTitle() {
|
||||
this.translateService.get("NewJump_Title").subscribe(
|
||||
data => { this.serviceComm.updatedComponentTitle(data); }
|
||||
);
|
||||
this.translateService.get("NewJump_Title").subscribe((data) => {
|
||||
this.serviceComm.updatedComponentTitle(data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,63 +1,142 @@
|
||||
<div class="content">
|
||||
<div>
|
||||
<button mat-raised-button color="accent" [routerLink]="['/tunnelFlights']" [routerLinkActive]="['active']" skipLocationChange>{{ 'NewTunnelFlight_GoToJump' | translate }}</button>
|
||||
<button
|
||||
mat-raised-button
|
||||
color="accent"
|
||||
[routerLink]="['/tunnelFlights']"
|
||||
[routerLinkActive]="['active']"
|
||||
skipLocationChange
|
||||
>
|
||||
{{ "NewTunnelFlight_GoToJump" | translate }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<form class="formNewJumps" (ngSubmit)="onFormSubmit()" *ngIf="notLoadingToDisplay() else loading">
|
||||
<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-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">
|
||||
<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">
|
||||
<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 }}
|
||||
</mat-option>
|
||||
</mat-autocomplete>
|
||||
<button *ngIf="selectedTunnel" matSuffix mat-icon-button aria-label="Clear" (click)="resetTunnel()">
|
||||
<button
|
||||
*ngIf="selectedTunnel"
|
||||
matSuffix
|
||||
mat-icon-button
|
||||
aria-label="Clear"
|
||||
(click)="resetTunnel()"
|
||||
>
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</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-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">
|
||||
<button *ngIf="minutesOfFlight" matSuffix mat-icon-button aria-label="Clear" (click)="minutesOfFlight=undefined">
|
||||
<mat-label>{{ "NewTunnelFlight_Minutes_Lbl" | translate }}</mat-label>
|
||||
<input
|
||||
matInput
|
||||
placeholder="{{ 'NewTunnelFlight_Minutes' | translate }}"
|
||||
[(ngModel)]="minutesOfFlight"
|
||||
name="minutesOfFlight"
|
||||
type="number"
|
||||
/>
|
||||
<button
|
||||
*ngIf="minutesOfFlight"
|
||||
matSuffix
|
||||
mat-icon-button
|
||||
aria-label="Clear"
|
||||
(click)="minutesOfFlight = undefined"
|
||||
>
|
||||
<mat-icon>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>
|
||||
<button *ngIf="comments" matSuffix mat-icon-button aria-label="Clear" (click)="comments=undefined">
|
||||
<mat-label>{{ "NewTunnelFlight_Comments_Lbl" | translate }}</mat-label>
|
||||
<textarea
|
||||
matInput
|
||||
placeholder="{{ 'NewTunnelFlight_Comments' | translate }}"
|
||||
[(ngModel)]="comments"
|
||||
name="comments"
|
||||
type="text"
|
||||
></textarea>
|
||||
<button
|
||||
*ngIf="comments"
|
||||
matSuffix
|
||||
mat-icon-button
|
||||
aria-label="Clear"
|
||||
(click)="comments = undefined"
|
||||
>
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</mat-form-field>
|
||||
|
||||
<br />
|
||||
<button mat-raised-button color="accent" *ngIf="isValidatedForm()">{{ 'NewTunnelFlight_Submit' | translate }}</button>
|
||||
<button mat-raised-button color="accent" *ngIf="isValidatedForm()">
|
||||
{{ "NewTunnelFlight_Submit" | translate }}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<ng-template #loading>
|
||||
|
||||
@@ -1,41 +1,72 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { formatDate } from '@angular/common';
|
||||
import { DateAdapter, MAT_DATE_FORMATS, NativeDateAdapter } from "@angular/material/core";
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { RouterLink, RouterModule } from "@angular/router";
|
||||
import { formatDate } from "@angular/common";
|
||||
import {
|
||||
DateAdapter,
|
||||
MAT_DATE_FORMATS,
|
||||
NativeDateAdapter,
|
||||
} from "@angular/material/core";
|
||||
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { MatIconModule } from "@angular/material/icon";
|
||||
import { MatOptionModule } from "@angular/material/core";
|
||||
import { MatAutocompleteModule } from "@angular/material/autocomplete";
|
||||
import { MatFormFieldModule } from "@angular/material/form-field";
|
||||
import { MatDatepickerModule } from "@angular/material/datepicker";
|
||||
import { MatProgressSpinnerModule } from "@angular/material/progress-spinner";
|
||||
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
|
||||
import { MatInputModule } from "@angular/material/input";
|
||||
import { MatButtonModule } from "@angular/material/button";
|
||||
|
||||
import { TunnelResp } from "../../models/tunnel";
|
||||
|
||||
import { JumpTypeResp } from "../../models/jumpType";
|
||||
import { TunnelService } from '../../services/tunnel.service';
|
||||
import { ServiceComm } from '../../services/service-comm.service';
|
||||
import { TunnelService } from "../../services/tunnel.service";
|
||||
import { ServiceComm } from "../../services/service-comm.service";
|
||||
import { TunnelFlightService } from "../../services/tunnel-flight.service";
|
||||
import { JumpTypeService } from "../../services/jump-type.service";
|
||||
import { DateService } from "../../services/date.service";
|
||||
|
||||
export const PICK_FORMATS = {
|
||||
parse: { dateInput: 'yy MM dd' },
|
||||
parse: { dateInput: "yy MM dd" },
|
||||
display: {
|
||||
dateInput: 'yyyy-MM-dd',
|
||||
monthYearLabel: 'yyyy MMM',
|
||||
dateA11yLabel: 'yyyy MM dd',
|
||||
monthYearA11yLabel: 'yyyy MMMM',
|
||||
}
|
||||
dateInput: "yyyy-MM-dd",
|
||||
monthYearLabel: "yyyy MMM",
|
||||
dateA11yLabel: "yyyy MM dd",
|
||||
monthYearA11yLabel: "yyyy MMMM",
|
||||
},
|
||||
};
|
||||
class PickDateAdapter extends NativeDateAdapter {
|
||||
format(date: Date, displayFormat: Object): string {
|
||||
override format(date: Date, displayFormat: Object): string {
|
||||
return formatDate(date, displayFormat.toString(), "en");
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-new-tunnel-flight',
|
||||
templateUrl: './new-tunnel-flight.component.html',
|
||||
styleUrls: ['./new-tunnel-flight.component.css'],
|
||||
selector: "app-new-tunnel-flight",
|
||||
templateUrl: "./new-tunnel-flight.component.html",
|
||||
styleUrls: ["./new-tunnel-flight.component.css"],
|
||||
providers: [
|
||||
{ provide: DateAdapter, useClass: PickDateAdapter },
|
||||
{ provide: MAT_DATE_FORMATS, useValue: PICK_FORMATS }
|
||||
{ provide: MAT_DATE_FORMATS, useValue: PICK_FORMATS },
|
||||
],
|
||||
imports: [
|
||||
TranslateModule,
|
||||
CommonModule,
|
||||
RouterModule,
|
||||
RouterLink,
|
||||
FormsModule,
|
||||
MatFormFieldModule,
|
||||
ReactiveFormsModule,
|
||||
MatAutocompleteModule,
|
||||
MatInputModule,
|
||||
MatButtonModule,
|
||||
MatIconModule,
|
||||
MatFormFieldModule,
|
||||
MatOptionModule,
|
||||
MatDatepickerModule,
|
||||
MatProgressSpinnerModule,
|
||||
],
|
||||
standalone: false
|
||||
})
|
||||
export class NewTunnelFlightComponent implements OnInit {
|
||||
public flightDate: Date;
|
||||
@@ -51,12 +82,14 @@ export class NewTunnelFlightComponent implements OnInit {
|
||||
public listOfJumpType: Array<JumpTypeResp>;
|
||||
public maxDate: Date;
|
||||
|
||||
constructor(private serviceComm: ServiceComm,
|
||||
constructor(
|
||||
private serviceComm: ServiceComm,
|
||||
private serviceTunnel: TunnelService,
|
||||
private serviceTunnelFlight: TunnelFlightService,
|
||||
private serviceJumpType: JumpTypeService,
|
||||
private translateService: TranslateService,
|
||||
private dateService: DateService) { }
|
||||
private dateService: DateService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
||||
@@ -77,11 +110,14 @@ export class NewTunnelFlightComponent implements OnInit {
|
||||
public onFormSubmit() {
|
||||
this.pendingAddRequest = true;
|
||||
|
||||
this.serviceTunnelFlight.addFlight(this.selectedTunnel.id,
|
||||
this.serviceTunnelFlight
|
||||
.addFlight(
|
||||
this.selectedTunnel.id,
|
||||
this.selectedJumpType.id,
|
||||
this.flightDate,
|
||||
this.minutesOfFlight,
|
||||
this.comments)
|
||||
this.comments
|
||||
)
|
||||
.subscribe(() => {
|
||||
this.comments = undefined;
|
||||
|
||||
@@ -93,15 +129,16 @@ export class NewTunnelFlightComponent implements OnInit {
|
||||
}
|
||||
|
||||
public isValidatedForm(): boolean {
|
||||
return (this.selectedTunnel !== undefined &&
|
||||
return (
|
||||
this.selectedTunnel !== undefined &&
|
||||
this.selectedTunnel.id !== undefined &&
|
||||
this.minutesOfFlight !== undefined &&
|
||||
typeof this.minutesOfFlight === "number");
|
||||
typeof this.minutesOfFlight === "number"
|
||||
);
|
||||
}
|
||||
|
||||
private getListOfTunnels() {
|
||||
this.serviceTunnel.getListOfTunnels()
|
||||
.subscribe((data) => {
|
||||
this.serviceTunnel.getListOfTunnels().subscribe((data) => {
|
||||
data.sort((a, b) => a.name.localeCompare(b.name));
|
||||
this.listOfTunnel = data;
|
||||
this.listOfFilteredTunnel = data;
|
||||
@@ -110,8 +147,7 @@ export class NewTunnelFlightComponent implements OnInit {
|
||||
}
|
||||
|
||||
private getListOfJumpTypes() {
|
||||
this.serviceJumpType.getListOfJumpTypesForTunnel()
|
||||
.subscribe((data) => {
|
||||
this.serviceJumpType.getListOfJumpTypesForTunnel().subscribe((data) => {
|
||||
data.sort((a, b) => a.name.localeCompare(b.name));
|
||||
this.listOfJumpType = data;
|
||||
this.countDatasLoaded++;
|
||||
@@ -123,9 +159,9 @@ export class NewTunnelFlightComponent implements OnInit {
|
||||
}
|
||||
|
||||
private updateTitle() {
|
||||
this.translateService.get("NewTunnelFlight_Title").subscribe(
|
||||
data => { this.serviceComm.updatedComponentTitle(data); }
|
||||
);
|
||||
this.translateService.get("NewTunnelFlight_Title").subscribe((data) => {
|
||||
this.serviceComm.updatedComponentTitle(data);
|
||||
});
|
||||
}
|
||||
|
||||
private initForm() {
|
||||
@@ -139,7 +175,7 @@ export class NewTunnelFlightComponent implements OnInit {
|
||||
|
||||
public resetTunnel() {
|
||||
this.selectedTunnel = undefined;
|
||||
this.onChangeTunnel('');
|
||||
this.onChangeTunnel("");
|
||||
}
|
||||
|
||||
public onChangeTunnel(event: any) {
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
aria-label="Force the refresh of the stats"
|
||||
style="cursor: pointer"
|
||||
(click)="refreshStats()"
|
||||
>cached</mat-icon
|
||||
>
|
||||
svgIcon="reset"
|
||||
></mat-icon>
|
||||
</div>
|
||||
|
||||
<mat-tab-group
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import { Component, OnInit, ViewChild } from "@angular/core";
|
||||
import { MatTableDataSource } from "@angular/material/table";
|
||||
import { MatTableDataSource, MatTableModule } from "@angular/material/table";
|
||||
import { MatTabChangeEvent, MatTabGroup } from "@angular/material/tabs";
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
import { TranslateModule, TranslateService } from "@ngx-translate/core";
|
||||
import { DatePipe } from "@angular/common";
|
||||
import { ChartConfiguration, ChartData, ChartType, Colors } from "chart.js";
|
||||
import { ChartConfiguration, ChartData, ChartType } from "chart.js";
|
||||
import { BaseChartDirective } from "ng2-charts";
|
||||
import { MatTabsModule } from "@angular/material/tabs";
|
||||
import { MatIconModule } from "@angular/material/icon";
|
||||
|
||||
import { ServiceComm } from "../../services/service-comm.service";
|
||||
import { StatsService } from "../../services/stats.service";
|
||||
@@ -19,7 +22,13 @@ import {
|
||||
selector: "app-summary",
|
||||
templateUrl: "./summary.component.html",
|
||||
styleUrls: ["./summary.component.css"],
|
||||
standalone: false,
|
||||
imports: [
|
||||
MatTabsModule,
|
||||
TranslateModule,
|
||||
BaseChartDirective,
|
||||
MatIconModule,
|
||||
MatTableModule,
|
||||
],
|
||||
})
|
||||
export class SummaryComponent implements OnInit {
|
||||
public dsNbJumpByDz: MatTableDataSource<StatsByDzResp>;
|
||||
@@ -39,7 +48,7 @@ export class SummaryComponent implements OnInit {
|
||||
];
|
||||
|
||||
public barChartLegend = true;
|
||||
public barChartPlugins = [];
|
||||
public barChartPlugins: any = [];
|
||||
public barChartData: ChartData<"line">;
|
||||
public barChartOptions: ChartConfiguration["options"];
|
||||
public barChartType: ChartType;
|
||||
@@ -53,7 +62,7 @@ export class SummaryComponent implements OnInit {
|
||||
constructor(
|
||||
private serviceApi: StatsService,
|
||||
private serviceComm: ServiceComm,
|
||||
private translateService: TranslateService
|
||||
private translateService: TranslateService,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
@@ -71,7 +80,7 @@ export class SummaryComponent implements OnInit {
|
||||
const datepipe: DatePipe = new DatePipe("en-US");
|
||||
let formattedDate = datepipe.transform(
|
||||
data.lastJump.jumpDate,
|
||||
"EEEE dd MMMM YYYY"
|
||||
"EEEE dd MMMM YYYY",
|
||||
);
|
||||
this.lastJump = formattedDate + " (" + data.lastJump.dropZone.name + ")";
|
||||
});
|
||||
@@ -81,7 +90,7 @@ export class SummaryComponent implements OnInit {
|
||||
this.dsJumpForLastMonthByDz = new MatTableDataSource(data.byDz);
|
||||
data.byJumpType.sort((a, b) => b.nb - a.nb);
|
||||
this.dsJumpForLastMonthByJumpType = new MatTableDataSource(
|
||||
data.byJumpType
|
||||
data.byJumpType,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -96,106 +105,28 @@ export class SummaryComponent implements OnInit {
|
||||
public onTabChanged(event: MatTabChangeEvent) {
|
||||
switch (event.index) {
|
||||
case 0:
|
||||
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
|
||||
);
|
||||
});
|
||||
this.statsLastMonth();
|
||||
break;
|
||||
case 1:
|
||||
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
|
||||
);
|
||||
});
|
||||
this.statsLastYear();
|
||||
break;
|
||||
case 2:
|
||||
this.serviceApi.getStatsByDz().subscribe((data) => {
|
||||
data.sort((a, b) => b.nb - a.nb);
|
||||
this.dsNbJumpByDz = new MatTableDataSource(data);
|
||||
});
|
||||
this.statsByDz();
|
||||
break;
|
||||
case 3:
|
||||
this.serviceApi.getStatsByAircraft().subscribe((data) => {
|
||||
data.sort((a, b) => b.nb - a.nb);
|
||||
this.dsNbJumpByAircraft = new MatTableDataSource(data);
|
||||
});
|
||||
this.statsByAircraft();
|
||||
break;
|
||||
case 4:
|
||||
this.serviceApi.getStatsByGear().subscribe((data) => {
|
||||
data.sort((a, b) => b.nb - a.nb);
|
||||
this.dsNbJumpByGear = new MatTableDataSource(data);
|
||||
});
|
||||
this.statsByGear();
|
||||
break;
|
||||
case 5:
|
||||
this.serviceApi.getStatsByJumpType().subscribe((data) => {
|
||||
data.sort((a, b) => b.nb - a.nb);
|
||||
this.dsNbJumpByType = new MatTableDataSource(data);
|
||||
});
|
||||
this.statsByJumpType();
|
||||
break;
|
||||
case 6:
|
||||
this.serviceApi.getStatsByYear().subscribe((data) => {
|
||||
data.sort((a, b) => b.label.localeCompare(a.label));
|
||||
this.dsNbJumpByYear = new MatTableDataSource(data);
|
||||
});
|
||||
this.statsByYear();
|
||||
break;
|
||||
case 7:
|
||||
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 = [];
|
||||
tmpResults.forEach((value, key) => {
|
||||
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,
|
||||
};
|
||||
});
|
||||
this.statsByYearByJumpType();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -216,7 +147,7 @@ export class SummaryComponent implements OnInit {
|
||||
display: true,
|
||||
},
|
||||
colors: {
|
||||
forceOverride: true,
|
||||
forceOverride: false,
|
||||
},
|
||||
},
|
||||
interaction: {
|
||||
@@ -252,4 +183,122 @@ export class SummaryComponent implements OnInit {
|
||||
["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: {
|
||||
label: string;
|
||||
data: number[];
|
||||
backgroundColor: string;
|
||||
borderColor: string;
|
||||
pointBackgroundColor: string;
|
||||
fill: boolean;
|
||||
pointRadius: number;
|
||||
}[] = [];
|
||||
tmpResults.forEach((value, key) => {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -40,7 +40,9 @@
|
||||
</mat-form-field>
|
||||
</p>
|
||||
|
||||
<button type="submit" mat-raised-button color="accent">Update my profile</button>
|
||||
<button type="submit" mat-raised-button color="accent">
|
||||
Update my profile
|
||||
</button>
|
||||
</form>
|
||||
</fieldset>
|
||||
|
||||
|
||||
@@ -1,20 +1,54 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { FormGroup, FormControl, Validators } from '@angular/forms';
|
||||
import { AuthenticationService } from '../../services/authentication.service';
|
||||
import { User } from '../../models/user';
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import {
|
||||
FormGroup,
|
||||
FormControl,
|
||||
Validators,
|
||||
ReactiveFormsModule,
|
||||
} from "@angular/forms";
|
||||
import { MatLabel, MatFormFieldModule } from "@angular/material/form-field";
|
||||
import {
|
||||
TranslateModule,
|
||||
TranslatePipe,
|
||||
TranslateService,
|
||||
} from "@ngx-translate/core";
|
||||
import { MatInputModule } from "@angular/material/input";
|
||||
import { MatButtonModule } from "@angular/material/button";
|
||||
|
||||
import { AuthenticationService } from "../../services/authentication.service";
|
||||
import { ListOfImagesComponent } from "../list-of-images/list-of-images.component";
|
||||
import { ServiceComm } from "../../services/service-comm.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-user-profile',
|
||||
templateUrl: './user-profile.component.html',
|
||||
styleUrls: ['./user-profile.component.css'],
|
||||
standalone: false
|
||||
selector: "app-user-profile",
|
||||
templateUrl: "./user-profile.component.html",
|
||||
styleUrls: ["./user-profile.component.css"],
|
||||
imports: [
|
||||
ListOfImagesComponent,
|
||||
ReactiveFormsModule,
|
||||
MatLabel,
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
MatButtonModule,
|
||||
TranslateModule,
|
||||
],
|
||||
})
|
||||
export class UserProfileComponent implements OnInit {
|
||||
public userForm: FormGroup;
|
||||
|
||||
constructor(private authenticationService: AuthenticationService) { }
|
||||
constructor(
|
||||
private authenticationService: AuthenticationService,
|
||||
private translateService: TranslateService,
|
||||
private serviceComm: ServiceComm,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.serviceComm.forceTranslateTitle.subscribe((data) => {
|
||||
if (data === true) {
|
||||
this.updateTitle();
|
||||
}
|
||||
});
|
||||
this.updateTitle();
|
||||
|
||||
ngOnInit(): void {
|
||||
const currentUser = this.authenticationService.currentUserValue;
|
||||
|
||||
this.userForm = new FormGroup(
|
||||
@@ -33,15 +67,15 @@ export class UserProfileComponent implements OnInit {
|
||||
Validators.email,
|
||||
]),
|
||||
currentPassword: new FormControl(
|
||||
'',
|
||||
Validators.pattern('^[A-Za-z0-9_-]{8,15}$')
|
||||
"",
|
||||
Validators.pattern("^[A-Za-z0-9_-]{8,15}$"),
|
||||
),
|
||||
newPassword: new FormControl(
|
||||
'',
|
||||
Validators.pattern('^[A-Za-z0-9_-]{8,15}$')
|
||||
"",
|
||||
Validators.pattern("^[A-Za-z0-9_-]{8,15}$"),
|
||||
),
|
||||
},
|
||||
{ updateOn: 'blur' }
|
||||
{ updateOn: "blur" },
|
||||
);
|
||||
}
|
||||
|
||||
@@ -112,4 +146,10 @@ export class UserProfileComponent implements OnInit {
|
||||
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,48 +0,0 @@
|
||||
/* fallback */
|
||||
@font-face {
|
||||
font-family: 'Material Icons';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url(../font/Material-Icons-Fallback.woff2) format('woff2');
|
||||
}
|
||||
|
||||
/* .material-icons {
|
||||
font-family: 'Material Icons';
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 24px;
|
||||
line-height: 1;
|
||||
letter-spacing: normal;
|
||||
text-transform: none;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
direction: ltr;
|
||||
-moz-font-feature-settings: 'liga';
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
} */
|
||||
|
||||
.material-icons {
|
||||
font-family: 'Material Icons';
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 24px; /* Preferred icon size */
|
||||
display: inline-block;
|
||||
line-height: 1;
|
||||
text-transform: none;
|
||||
letter-spacing: normal;
|
||||
word-wrap: normal;
|
||||
white-space: nowrap;
|
||||
direction: ltr;
|
||||
|
||||
/* Support for all WebKit browsers. */
|
||||
-webkit-font-smoothing: antialiased;
|
||||
/* Support for Safari and Chrome. */
|
||||
text-rendering: optimizeLegibility;
|
||||
|
||||
/* Support for Firefox. */
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
/* Support for IE. */
|
||||
font-feature-settings: 'liga';
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: url(../font/300/Cyrillic-ext.woff2) format('woff2');
|
||||
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||
}
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: url(../font/300/Cyrillic.woff2) format('woff2');
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: url(../font/300/Greek-ext.woff2) format('woff2');
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: url(../font/300/Greek.woff2) format('woff2');
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: url(../font/300/Vietnamese.woff2) format('woff2');
|
||||
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: url(../font/300/Latin-ext.woff2) format('woff2');
|
||||
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: url(../font/300/Latin.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url(../font/400/Cyrillic-ext.woff2) format('woff2');
|
||||
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||
}
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url(../font/400/Cyrillic.woff2) format('woff2');
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url(../font/400/Greek-ext.woff2) format('woff2');
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url(../font/400/Greek.woff2) format('woff2');
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url(../font/400/Vietnamese.woff2) format('woff2');
|
||||
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url(../font/400/Latin-ext.woff2) format('woff2');
|
||||
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url(../font/400/Latin.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: url(../font/500/Cyrillic-ext.woff2) format('woff2');
|
||||
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||
}
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: url(../font/500/Cyrillic.woff2) format('woff2');
|
||||
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: url(../font/500/Greek-ext.woff2) format('woff2');
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: url(../font/500/Greek.woff2) format('woff2');
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: url(../font/500/Vietnamese.woff2) format('woff2');
|
||||
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: url(../font/500/Latin-ext.woff2) format('woff2');
|
||||
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: url(../font/500/Latin.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
@@ -1,6 +1,18 @@
|
||||
/* These tokens are generated using https://themes.angular-material.dev/ */
|
||||
/* Preview: https://themes.angular-material.dev/?seed-error=%23FF5449&seed-neutral=%23938F94&seed-neutral-variant=%23948F99&seed-primary=%236750A4&seed-secondary=%23958DA4&seed-tertiary=%23B58392 */
|
||||
/* Preview: https://themes.angular-material.dev/?bold-font-weight=700&brand-font-family=Roboto&medium-font-weight=500&plain-font-family=Roboto®ular-font-weight=400&seed-error=%23FF5449&seed-neutral=%23938F94&seed-neutral-variant=%23948F99&seed-primary=%236750A4&seed-secondary=%23958DA4&seed-tertiary=%23B58392 */
|
||||
/* Seed Colors: primary: #6750A4, secondary: #958DA4, tertiary: #B58392, error: #FF5449, neutral: #938F94, neutral-variant: #948F99 */
|
||||
/* Seed Typography: plain-font-family: Roboto, brand-font-family: Roboto, bold-font-weight: 700, medium-font-weight: 500, regular-font-weight: 400 */
|
||||
|
||||
/* Make sure to import fonts in `<head>` of html */
|
||||
/*
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=Roboto&family=Roboto&display=swap');
|
||||
</style>
|
||||
|
||||
OR
|
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto&family=Roboto&display=swap">
|
||||
*/
|
||||
|
||||
@use "@angular/material" as mat;
|
||||
|
||||
@@ -127,122 +139,67 @@
|
||||
));
|
||||
}
|
||||
|
||||
/* Typography */
|
||||
:root, :host {
|
||||
/* core typography tokens are not generating css variables, hence below */
|
||||
--mat-sys-brand-font-family: Roboto;
|
||||
--mat-sys-plain-font-family: Roboto;
|
||||
--mat-sys-bold-font-weight: 700;
|
||||
--mat-sys-medium-font-weight: 500;
|
||||
--mat-sys-regular-font-weight: 400;
|
||||
|
||||
// https://theme-builder-1623190217839.web.app/
|
||||
|
||||
// @use '@angular/material' as mat;
|
||||
|
||||
// @import "Material-Icons";
|
||||
// @import "Roboto";
|
||||
|
||||
/*
|
||||
// Be sure that you only ever include this mixin once!
|
||||
@include mat.core();
|
||||
|
||||
// Define your theme with color palettes, typography and density
|
||||
|
||||
$mat-theme-primary-palette: map-merge(mat.$cyan-palette, ( contrast: (100: #150c4a,)));
|
||||
$mat-theme-primary: mat.define-palette(
|
||||
$mat-theme-primary-palette,
|
||||
$default: 100,
|
||||
$lighter: 100,
|
||||
$darker: 700,
|
||||
$text: 500
|
||||
);
|
||||
|
||||
$mat-theme-accent-palette: map-merge(mat.$teal-palette, ( 501: #4d77b6,contrast: (501: white,A100: white,A200: white,)));
|
||||
$mat-theme-accent: mat.define-palette(
|
||||
$mat-theme-accent-palette,
|
||||
$default: 501,
|
||||
$lighter: A100,
|
||||
$darker: A200,
|
||||
$text: 600
|
||||
);
|
||||
|
||||
$mat-theme-warn-palette: map-merge(mat.$pink-palette, ( ));
|
||||
$mat-theme-warn: mat.define-palette(
|
||||
$mat-theme-warn-palette,
|
||||
$default: A200,
|
||||
$lighter: 500,
|
||||
$darker: 500,
|
||||
$text: A700
|
||||
);
|
||||
|
||||
$mat-dark-theme-primary-palette: map-merge(mat.$lime-palette, ( contrast: (200: #030844,A100: rgba(0,0,0, 0.87),A700: rgba(0,0,0, 0.87),)));
|
||||
$mat-dark-theme-primary: mat.define-palette(
|
||||
$mat-dark-theme-primary-palette,
|
||||
$default: 200,
|
||||
$lighter: A100,
|
||||
$darker: A700,
|
||||
$text: 700
|
||||
);
|
||||
|
||||
$mat-dark-theme-accent-palette: map-merge(mat.$green-palette, ( contrast: (A200: black,50: black,A400: black,)));
|
||||
$mat-dark-theme-accent: mat.define-palette(
|
||||
$mat-dark-theme-accent-palette,
|
||||
$default: A200,
|
||||
$lighter: 50,
|
||||
$darker: A400,
|
||||
$text: A100
|
||||
);
|
||||
|
||||
$mat-dark-theme-warn-palette: map-merge(mat.$pink-palette, ( contrast: (A100: black,100: white,)));
|
||||
$mat-dark-theme-warn: mat.define-palette(
|
||||
$mat-dark-theme-warn-palette,
|
||||
$default: A100,
|
||||
$lighter: 100,
|
||||
$darker: A700,
|
||||
$text: 100
|
||||
);
|
||||
|
||||
// @import url('https://fonts.googleapis.com/css2?family=Rubik:wght@300&display=swap');
|
||||
|
||||
$mat-typography: mat.define-typography-config(
|
||||
$font-family: 'Rubik',
|
||||
$display-4: mat.define-typography-level($font-size: 96px, $font-weight: 300, $font-family: Rubik),
|
||||
$display-3: mat.define-typography-level($font-size: 60px, $font-weight: 500, $font-family: Rubik),
|
||||
$display-2: mat.define-typography-level($font-size: 48px, $font-weight: 500, $font-family: Rubik),
|
||||
$display-1: mat.define-typography-level($font-size: 34px, $font-weight: 500, $font-family: Rubik),
|
||||
$headline: mat.define-typography-level($font-size: 24px, $font-weight: 500, $font-family: Rubik),
|
||||
$title: mat.define-typography-level($font-size: 20px, $font-weight: 500, $font-family: Rubik),
|
||||
$subheading-2: mat.define-typography-level($font-size: 18px, $font-weight: 500, $font-family: Rubik),
|
||||
$subheading-1: mat.define-typography-level($font-size: 20px, $font-weight: 500, $font-family: Rubik),
|
||||
$body-2: mat.define-typography-level($font-size: 16px, $font-weight: 400, $font-family: Rubik),
|
||||
$body-1: mat.define-typography-level($font-size: 18px, $font-weight: 400, $font-family: Rubik),
|
||||
$caption: mat.define-typography-level($font-size: 16px, $font-weight: Medium, $font-family: Rubik),
|
||||
$button: mat.define-typography-level($font-size: 16px, $font-weight: 500, $font-family: Rubik),
|
||||
// Line-height must be unit-less fraction of the font-size.
|
||||
$input: mat.define-typography-level($font-size: inherit, $line-height: 1.125, $font-weight: 500, $font-family: Rubik),
|
||||
);
|
||||
|
||||
$mat-density: 0;
|
||||
// @include mat.elevation(
|
||||
// $zValue: 12,
|
||||
// $color: #000,
|
||||
// $opacity: 0.5
|
||||
// );
|
||||
|
||||
$mat-core-theme: mat.define-light-theme((
|
||||
color: (
|
||||
primary: $mat-theme-primary,
|
||||
accent: $mat-theme-accent,
|
||||
warn: $mat-theme-warn
|
||||
),
|
||||
typography: $mat-typography,
|
||||
density: $mat-density
|
||||
@include mat.theme-overrides((
|
||||
brand-family: Roboto,
|
||||
plain-family: Roboto,
|
||||
bold-weight: 700,
|
||||
medium-weight: 500,
|
||||
regular-weight: 400,
|
||||
headline-large-font: var(--mat-sys-brand-font-family),
|
||||
headline-medium-font: var(--mat-sys-brand-font-family),
|
||||
headline-small-font: var(--mat-sys-brand-font-family),
|
||||
display-large-font: var(--mat-sys-brand-font-family),
|
||||
display-medium-font: var(--mat-sys-brand-font-family),
|
||||
display-small-font: var(--mat-sys-brand-font-family),
|
||||
title-large-font: var(--mat-sys-brand-font-family),
|
||||
body-large: var(--mat-sys-body-large-weight) var(--mat-sys-body-large-size) / var(--mat-sys-body-large-line-height) var(--mat-sys-body-large-font),
|
||||
body-medium: var(--mat-sys-body-medium-weight) var(--mat-sys-body-medium-size) / var(--mat-sys-body-medium-line-height) var(--mat-sys-body-medium-font),
|
||||
body-small: var(--mat-sys-body-small-weight) var(--mat-sys-body-small-size) / var(--mat-sys-body-small-line-height) var(--mat-sys-body-small-font),
|
||||
label-large: var(--mat-sys-label-large-weight) var(--mat-sys-label-large-size) / var(--mat-sys-label-large-line-height) var(--mat-sys-label-large-font),
|
||||
label-medium: var(--mat-sys-label-medium-weight) var(--mat-sys-label-medium-size) / var(--mat-sys-label-medium-line-height) var(--mat-sys-label-medium-font),
|
||||
label-small: var(--mat-sys-label-small-weight) var(--mat-sys-label-small-size) / var(--mat-sys-label-small-line-height) var(--mat-sys-label-small-font),
|
||||
title-large: var(--mat-sys-title-large-weight) var(--mat-sys-title-large-size) / var(--mat-sys-title-large-line-height) var(--mat-sys-title-large-font),
|
||||
title-medium: var(--mat-sys-title-medium-weight) var(--mat-sys-title-medium-size) / var(--mat-sys-title-medium-line-height) var(--mat-sys-title-medium-font),
|
||||
title-small: var(--mat-sys-title-small-weight) var(--mat-sys-title-small-size) / var(--mat-sys-title-small-line-height) var(--mat-sys-title-small-font),
|
||||
headline-large: var(--mat-sys-headline-large-weight) var(--mat-sys-headline-large-size) / var(--mat-sys-headline-large-line-height) var(--mat-sys-headline-large-font),
|
||||
headline-medium: var(--mat-sys-headline-medium-weight) var(--mat-sys-headline-medium-size) / var(--mat-sys-headline-medium-line-height) var(--mat-sys-headline-medium-font),
|
||||
headline-small: var(--mat-sys-headline-small-weight) var(--mat-sys-headline-small-size) / var(--mat-sys-headline-small-line-height) var(--mat-sys-headline-small-font),
|
||||
display-large: var(--mat-sys-display-large-weight) var(--mat-sys-display-large-size) / var(--mat-sys-display-large-line-height) var(--mat-sys-display-large-font),
|
||||
display-medium: var(--mat-sys-display-medium-weight) var(--mat-sys-display-medium-size) / var(--mat-sys-display-medium-line-height) var(--mat-sys-display-medium-font),
|
||||
display-small: var(--mat-sys-display-small-weight) var(--mat-sys-display-small-size) / var(--mat-sys-display-small-line-height) var(--mat-sys-display-small-font),
|
||||
body-large-font: var(--mat-sys-plain-font-family),
|
||||
body-medium-font: var(--mat-sys-plain-font-family),
|
||||
body-small-font: var(--mat-sys-plain-font-family),
|
||||
label-large-font: var(--mat-sys-plain-font-family),
|
||||
label-medium-font: var(--mat-sys-plain-font-family),
|
||||
label-small-font: var(--mat-sys-plain-font-family),
|
||||
title-medium-font: var(--mat-sys-plain-font-family),
|
||||
title-small-font: var(--mat-sys-plain-font-family),
|
||||
label-large-weight-prominent: var(--mat-sys-bold-font-weight),
|
||||
label-medium-weight-prominent: var(--mat-sys-bold-font-weight),
|
||||
label-large-weight: var(--mat-sys-medium-font-weight),
|
||||
label-medium-weight: var(--mat-sys-medium-font-weight),
|
||||
label-small-weight: var(--mat-sys-medium-font-weight),
|
||||
title-medium-weight: var(--mat-sys-medium-font-weight),
|
||||
title-small-weight: var(--mat-sys-medium-font-weight),
|
||||
body-large-weight: var(--mat-sys-regular-font-weight),
|
||||
body-medium-weight: var(--mat-sys-regular-font-weight),
|
||||
body-small-weight: var(--mat-sys-regular-font-weight),
|
||||
display-large-weight: var(--mat-sys-regular-font-weight),
|
||||
display-medium-weight: var(--mat-sys-regular-font-weight),
|
||||
display-small-weight: var(--mat-sys-regular-font-weight),
|
||||
headline-large-weight: var(--mat-sys-regular-font-weight),
|
||||
headline-medium-weight: var(--mat-sys-regular-font-weight),
|
||||
headline-small-weight: var(--mat-sys-regular-font-weight),
|
||||
title-large-weight: var(--mat-sys-regular-font-weight),
|
||||
));
|
||||
|
||||
$mat-dark-theme: mat.define-dark-theme((
|
||||
color: (
|
||||
primary: $mat-dark-theme-primary,
|
||||
accent: $mat-dark-theme-accent,
|
||||
warn: $mat-dark-theme-warn,
|
||||
)
|
||||
));
|
||||
|
||||
@include mat.all-component-themes($mat-core-theme);
|
||||
|
||||
.dark-theme {
|
||||
@include mat.all-component-colors($mat-dark-theme);
|
||||
}
|
||||
*/
|
||||
@@ -38,6 +38,11 @@
|
||||
"ListAircrafts_Title": "List of aircrafts",
|
||||
"NewTunnelFlight_Title": "New tunnel flights",
|
||||
"ListTunnelFlight_Title": "List of hours of tunnel",
|
||||
"UserProfile_Title": "User profile",
|
||||
"NewJumpType_Title": "New jmp type",
|
||||
"NewGear_Title": "New gear",
|
||||
"NewDz_Title": "New drop zone",
|
||||
"NewAircraft_Title": "New aircraft",
|
||||
|
||||
"App_Footer": "Web software to log your skydive jumps - v",
|
||||
"App_Nav_Summary": "Summary",
|
||||
@@ -51,39 +56,39 @@
|
||||
"App_Nav_NewTunnelFlight": "Add tunnel time",
|
||||
"App_Nav_TunnelFlights": "The tunnel flights",
|
||||
|
||||
"List_Aircrafts_Add": "Add a aircraft",
|
||||
"List_Aircrafts_Header_Id": "ID",
|
||||
"List_Aircrafts_Header_Name": "Name",
|
||||
"List_Aircrafts_Header_Image": "Image",
|
||||
"ListAircrafts_Add": "Add a aircraft",
|
||||
"ListAircrafts_Header_Id": "ID",
|
||||
"ListAircrafts_Header_Name": "Name",
|
||||
"ListAircrafts_Header_Image": "Image",
|
||||
|
||||
"List_Gears_Add": "Add a gear",
|
||||
"List_Gears_Header_Id": "ID",
|
||||
"List_Gears_Header_Name": "Name",
|
||||
"List_Gears_Header_Manufacturer": "Manufacturer",
|
||||
"List_Gears_Header_CanopySize": "Canopy size",
|
||||
"List_Gears_Header_Aad": "AAD system",
|
||||
"List_Gears_Header_Main": "Main canopy",
|
||||
"List_Gears_Header_Reserve": "Reserve canopy",
|
||||
"ListGears_Add": "Add a gear",
|
||||
"ListGears_Header_Id": "ID",
|
||||
"ListGears_Header_Name": "Name",
|
||||
"ListGears_Header_Manufacturer": "Manufacturer",
|
||||
"ListGears_Header_CanopySize": "Canopy size",
|
||||
"ListGears_Header_Aad": "AAD system",
|
||||
"ListGears_Header_Main": "Main canopy",
|
||||
"ListGears_Header_Reserve": "Reserve canopy",
|
||||
|
||||
"List_JumpType_Add": "Add a jump type",
|
||||
"List_JumpType_Header_Id": "ID",
|
||||
"List_JumpType_Header_Name": "Name",
|
||||
"ListJumpType_Add": "Add a jump type",
|
||||
"ListJumpType_Header_Id": "ID",
|
||||
"ListJumpType_Header_Name": "Name",
|
||||
|
||||
"List_Jump_Add": "Add jumps",
|
||||
"List_Jump_Header_Num": "Num",
|
||||
"List_Jump_Header_Date": "Date",
|
||||
"List_Jump_Header_JumpType": "Jump Type",
|
||||
"List_Jump_Header_Aircraft": "Aircraft",
|
||||
"List_Jump_Header_Dz": "Drop Zone",
|
||||
"List_Jump_Header_Gear": "Gear",
|
||||
"ListJump_Add": "Add jumps",
|
||||
"ListJump_Header_Num": "Num",
|
||||
"ListJump_Header_Date": "Date",
|
||||
"ListJump_Header_JumpType": "Jump Type",
|
||||
"ListJump_Header_Aircraft": "Aircraft",
|
||||
"ListJump_Header_Dz": "Drop Zone",
|
||||
"ListJump_Header_Gear": "Gear",
|
||||
|
||||
"List_Dz_Add": "Add a drop zone",
|
||||
"List_Dz_Header_ID": "ID",
|
||||
"List_Dz_Header_Name": "Name",
|
||||
"List_Dz_Header_Address": "Address",
|
||||
"List_Dz_Header_Type": "Type",
|
||||
"List_Dz_Filter": "Filter",
|
||||
"List_Dz_Filter_PlaceHolder": "Filter on the name or address of center",
|
||||
"ListDz_Add": "Add a drop zone",
|
||||
"ListDz_Header_ID": "ID",
|
||||
"ListDz_Header_Name": "Name",
|
||||
"ListDz_Header_Address": "Address",
|
||||
"ListDz_Header_Type": "Type",
|
||||
"ListDz_Filter": "Filter",
|
||||
"ListDz_Filter_PlaceHolder": "Filter on the name or address of center",
|
||||
|
||||
"Summary_TotalJumps": "Total jumps",
|
||||
"Summary_TotalCutaways": "Total cutaways",
|
||||
|
||||
@@ -38,6 +38,11 @@
|
||||
"ListAircrafts_Title": "Liste des avions",
|
||||
"NewTunnelFlight_Title": "Nouveaux créneaux de soufflerie",
|
||||
"ListTunnelFlight_Title": "Heures de tunnel",
|
||||
"UserProfile_Title": "Profile utilisateur",
|
||||
"NewJumpType_Title": "Nouveau type de saut",
|
||||
"NewGear_Title": "Nouveau piège",
|
||||
"NewDz_Title": "Nouveau centre",
|
||||
"NewAircraft_Title": "Nouvel avion",
|
||||
|
||||
"App_Footer": "Application pour enregistrer ses sauts de parachutisme - v",
|
||||
"App_Nav_Summary": "Récapitulatif",
|
||||
@@ -51,39 +56,39 @@
|
||||
"App_Nav_NewTunnelFlight": "Ajouter du temps en tunnel",
|
||||
"App_Nav_TunnelFlights": "Les vols en soufflerie",
|
||||
|
||||
"List_Aircrafts_Add": "Ajouter un avion",
|
||||
"List_Aircrafts_Header_Id": "ID",
|
||||
"List_Aircrafts_Header_Name": "Nom",
|
||||
"List_Aircrafts_Header_Image": "Image",
|
||||
"ListAircrafts_Add": "Ajouter un avion",
|
||||
"ListAircrafts_Header_Id": "ID",
|
||||
"ListAircrafts_Header_Name": "Nom",
|
||||
"ListAircrafts_Header_Image": "Image",
|
||||
|
||||
"List_Gears_Add": "Ajouter un piège",
|
||||
"List_Gears_Header_Id": "ID",
|
||||
"List_Gears_Header_Name": "Nom",
|
||||
"List_Gears_Header_Manufacturer": "Fabriquant",
|
||||
"List_Gears_Header_CanopySize": "Taille de voile",
|
||||
"List_Gears_Header_Aad": "Système de sécurité",
|
||||
"List_Gears_Header_Main": "Principale",
|
||||
"List_Gears_Header_Reserve": "Réserve",
|
||||
"ListGears_Add": "Ajouter un piège",
|
||||
"ListGears_Header_Id": "ID",
|
||||
"ListGears_Header_Name": "Nom",
|
||||
"ListGears_Header_Manufacturer": "Fabriquant",
|
||||
"ListGears_Header_CanopySize": "Taille de voile",
|
||||
"ListGears_Header_Aad": "Système de sécurité",
|
||||
"ListGears_Header_Main": "Principale",
|
||||
"ListGears_Header_Reserve": "Réserve",
|
||||
|
||||
"List_JumpType_Add": "Ajouter un type de saut",
|
||||
"List_JumpType_Header_Id": "ID",
|
||||
"List_JumpType_Header_Name": "Nom",
|
||||
"ListJumpType_Add": "Ajouter un type de saut",
|
||||
"ListJumpType_Header_Id": "ID",
|
||||
"ListJumpType_Header_Name": "Nom",
|
||||
|
||||
"List_Jump_Add": "Ajouter des sauts",
|
||||
"List_Jump_Header_Num": "Numéro",
|
||||
"List_Jump_Header_Date": "Date",
|
||||
"List_Jump_Header_JumpType": "Type de saut",
|
||||
"List_Jump_Header_Aircraft": "Avion",
|
||||
"List_Jump_Header_Dz": "Centre",
|
||||
"List_Jump_Header_Gear": "Piège",
|
||||
"ListJump_Add": "Ajouter des sauts",
|
||||
"ListJump_Header_Num": "Numéro",
|
||||
"ListJump_Header_Date": "Date",
|
||||
"ListJump_Header_JumpType": "Type de saut",
|
||||
"ListJump_Header_Aircraft": "Avion",
|
||||
"ListJump_Header_Dz": "Centre",
|
||||
"ListJump_Header_Gear": "Piège",
|
||||
|
||||
"List_Dz_Add": "Ajouter un centre de parachutisme",
|
||||
"List_Dz_Header_ID": "ID",
|
||||
"List_Dz_Header_Name": "Nom",
|
||||
"List_Dz_Header_Address": "Adresse",
|
||||
"List_Dz_Header_Type": "Type",
|
||||
"List_Dz_Filter": "Filtrer",
|
||||
"List_Dz_Filter_PlaceHolder": "Filtrer sur le nom ou l'adresse du centre",
|
||||
"ListDz_Add": "Ajouter un centre de parachutisme",
|
||||
"ListDz_Header_ID": "ID",
|
||||
"ListDz_Header_Name": "Nom",
|
||||
"ListDz_Header_Address": "Adresse",
|
||||
"ListDz_Header_Type": "Type",
|
||||
"ListDz_Filter": "Filtrer",
|
||||
"ListDz_Filter_PlaceHolder": "Filtrer sur le nom ou l'adresse du centre",
|
||||
|
||||
"Summary_TotalJumps": "Nombre de sauts",
|
||||
"Summary_TotalCutaways": "Nombre de libération",
|
||||
@@ -100,7 +105,7 @@
|
||||
"Summary_ByGear_Title": "Par piège",
|
||||
"Summary_ByJumpType_Title": "Par type de saut",
|
||||
"Summary_ByYear_Title": "Par an",
|
||||
"Summary_ByYear_Title": "Par an et par type",
|
||||
"Summary_ByYearByJumpType_Title": "Par an et par type",
|
||||
|
||||
"NewJump_GoToJump": "Voir les sauts",
|
||||
"NewJump_ResetForm": "Reset du formulaire après l'ajout",
|
||||
|
||||
1
Front/skydivelogs-app/src/assets/icon/account.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M200-246q54-53 125.5-83.5T480-360q83 0 154.5 30.5T760-246v-514H200v514Zm280-194q58 0 99-41t41-99q0-58-41-99t-99-41q-58 0-99 41t-41 99q0 58 41 99t99 41ZM200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm69-80h422q-44-39-99.5-59.5T480-280q-56 0-112.5 20.5T269-200Zm211-320q-25 0-42.5-17.5T420-580q0-25 17.5-42.5T480-640q25 0 42.5 17.5T540-580q0 25-17.5 42.5T480-520Zm0 17Z"/></svg>
|
||||
|
After Width: | Height: | Size: 564 B |
1
Front/skydivelogs-app/src/assets/icon/add.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M440-280h80v-160h160v-80H520v-160h-80v160H280v80h160v160Zm40 200q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>
|
||||
|
After Width: | Height: | Size: 467 B |
1
Front/skydivelogs-app/src/assets/icon/aircraft.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="m397-115-99-184-184-99 71-70 145 25 102-102-317-135 84-86 385 68 124-124q23-23 57-23t57 23q23 23 23 56.5T822-709L697-584l68 384-85 85-136-317-102 102 26 144-71 71Z"/></svg>
|
||||
|
After Width: | Height: | Size: 288 B |
1
Front/skydivelogs-app/src/assets/icon/celebration.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="m80-80 200-560 360 360L80-80Zm132-132 282-100-182-182-100 282Zm370-246-42-42 224-224q32-32 77-32t77 32l24 24-42 42-24-24q-14-14-35-14t-35 14L582-458ZM422-618l-42-42 24-24q14-14 14-34t-14-34l-26-26 42-42 26 26q32 32 32 76t-32 76l-24 24Zm80 80-42-42 144-144q14-14 14-35t-14-35l-64-64 42-42 64 64q32 32 32 77t-32 77L502-538Zm160 160-42-42 64-64q32-32 77-32t77 32l64 64-42 42-64-64q-14-14-35-14t-35 14l-64 64ZM212-212Z"/></svg>
|
||||
|
After Width: | Height: | Size: 539 B |
1
Front/skydivelogs-app/src/assets/icon/close.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="m256-236-20-20 224-224-224-224 20-20 224 224 224-224 20 20-224 224 224 224-20 20-224-224-224 224Z"/></svg>
|
||||
|
After Width: | Height: | Size: 222 B |
1
Front/skydivelogs-app/src/assets/icon/delete.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M312-172q-25 0-42.5-17.5T252-232v-488h-40v-28h148v-28h240v28h148v28h-40v488q0 26-17 43t-43 17H312Zm368-548H280v488q0 14 9 23t23 9h336q12 0 22-10t10-22v-488ZM402-280h28v-360h-28v360Zm128 0h28v-360h-28v360ZM280-720v520-520Z"/></svg>
|
||||
|
After Width: | Height: | Size: 346 B |
1
Front/skydivelogs-app/src/assets/icon/dz.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M160-720v-80h640v80H160Zm0 560v-240h-40v-80l40-200h640l40 200v80h-40v240h-80v-240H560v240H160Zm80-80h240v-160H240v160Zm-38-240h556-556Zm0 0h556l-24-120H226l-24 120Z"/></svg>
|
||||
|
After Width: | Height: | Size: 289 B |
1
Front/skydivelogs-app/src/assets/icon/edit.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M200-200h40l439-439-40-40-439 439v40Zm-28 28v-80l527-528q4.39-3.83 9.7-5.91Q714-788 719.68-788q5.67 0 11 1.5Q736-785 741-780l39 39q5 5 6.5 10.41t1.5 10.82q0 5.77-1.91 11.07-1.92 5.31-6.09 9.7L252-172h-80Zm589-548-41-41 41 41Zm-102.35 61.35L639-679l40 40-20.35-19.65Z"/></svg>
|
||||
|
After Width: | Height: | Size: 391 B |
1
Front/skydivelogs-app/src/assets/icon/fan.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M424-80q-51 0-77.5-30.5T320-180q0-26 11.5-50.5T367-271q22-14 35.5-36t18.5-47l-12-6q-6-3-11-7l-92 33q-17 6-33 10t-33 4q-63 0-111.5-55T80-536q0-51 30.5-77.5T179-640q26 0 51 11.5t41 35.5q14 22 36 35.5t47 18.5l6-12q3-6 7-11l-33-92q-6-17-10-33t-4-32q0-64 55-112.5T536-880q51 0 77.5 30.5T640-781q0 26-11.5 51T593-689q-22 14-35.5 36T539-606l12 6q6 3 11 7l92-34q17-6 32.5-9.5T719-640q81 0 121 67t40 149q0 51-32 77.5T777-320q-25 0-48.5-11.5T689-367q-14-22-36-35.5T606-421l-6 12q-3 6-7 11l33 92q6 16 10 30.5t4 30.5q1 65-54 115T424-80Zm56-340q25 0 42.5-17.5T540-480q0-25-17.5-42.5T480-540q-25 0-42.5 17.5T420-480q0 25 17.5 42.5T480-420Zm-46-192q6-2 12.5-3.5T459-618q8-42 30.5-78t59.5-60q5-4 8-10t3-15q0-8-6-13.5t-18-5.5q-38 0-86 16.5T400-719q0 9 2.5 17t4.5 15l27 75ZM240-400q14 0 33-7l75-27q-2-6-3.5-12.5T342-459q-42-8-78-30.5T204-549q-4-5-10.5-8t-14.5-3q-9 0-14 6t-5 18q0 54 20.5 95t59.5 41Zm184 240q47 0 92.5-19t43.5-66q0-8-2.5-15t-4.5-13l-27-75q-6 2-12.5 3.5T501-342q-8 42-30.5 78T411-204q-5 4-8.5 10.5T400-180q1 8 6 14t18 6Zm353-240q9 0 16-5t7-19q0-38-16-86.5T719-560q-9 0-17 2t-15 4l-75 28q2 6 3.5 12.5T618-501q42 8 78 30.5t60 59.5q3 5 9 8t12 3ZM618-501ZM459-618ZM342-459Zm159 117Z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
1
Front/skydivelogs-app/src/assets/icon/favorite.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="m480-120-58-52q-101-91-167-157T150-447.5Q111-500 95.5-544T80-634q0-94 63-157t157-63q52 0 99 22t81 62q34-40 81-62t99-22q94 0 157 63t63 157q0 46-15.5 90T810-447.5Q771-395 705-329T538-172l-58 52Z"/></svg>
|
||||
|
After Width: | Height: | Size: 317 B |
1
Front/skydivelogs-app/src/assets/icon/file_upload.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M440-320v-326L336-542l-56-58 200-200 200 200-56 58-104-104v326h-80ZM240-160q-33 0-56.5-23.5T160-240v-120h80v120h480v-120h80v120q0 33-23.5 56.5T720-160H240Z"/></svg>
|
||||
|
After Width: | Height: | Size: 280 B |
1
Front/skydivelogs-app/src/assets/icon/flight_land.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M120-120v-80h720v80H120Zm622-202L120-499v-291l96 27 48 139 138 39-35-343 115 34 128 369 172 49q25 8 41.5 29t16.5 48q0 35-28.5 61.5T742-322Z"/></svg>
|
||||
|
After Width: | Height: | Size: 264 B |
1
Front/skydivelogs-app/src/assets/icon/gear.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M40-480q0-92 34.5-172T169-791.5q60-59.5 140-94T480-920q91 0 171 34.5t140 94Q851-732 885.5-652T920-480h-80q0-75-28.5-140.5T734-735q-49-49-114.5-77T480-840q-74 0-139.5 28T226-735q-49 49-77.5 114.5T120-480H40Zm160 0q0-118 82-199t198-81q116 0 198 81t82 199h-80q0-83-58.5-141.5T480-680q-83 0-141.5 58.5T280-480h-80ZM360-64l-56-56 136-136v-132q-27-12-43.5-37T380-480q0-42 29-71t71-29q42 0 71 29t29 71q0 30-16.5 55T520-388v132l136 136-56 56-120-120L360-64Z"/></svg>
|
||||
|
After Width: | Height: | Size: 574 B |
1
Front/skydivelogs-app/src/assets/icon/info.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M440-280h80v-240h-80v240Zm40-320q17 0 28.5-11.5T520-640q0-17-11.5-28.5T480-680q-17 0-28.5 11.5T440-640q0 17 11.5 28.5T480-600Zm0 520q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>
|
||||
|
After Width: | Height: | Size: 535 B |
1
Front/skydivelogs-app/src/assets/icon/link.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M440-280H280q-83 0-141.5-58.5T80-480q0-83 58.5-141.5T280-680h160v80H280q-50 0-85 35t-35 85q0 50 35 85t85 35h160v80ZM320-440v-80h320v80H320Zm200 160v-80h160q50 0 85-35t35-85q0-50-35-85t-85-35H520v-80h160q83 0 141.5 58.5T880-480q0 83-58.5 141.5T680-280H520Z"/></svg>
|
||||
|
After Width: | Height: | Size: 380 B |
1
Front/skydivelogs-app/src/assets/icon/list.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M320-280q17 0 28.5-11.5T360-320q0-17-11.5-28.5T320-360q-17 0-28.5 11.5T280-320q0 17 11.5 28.5T320-280Zm0-160q17 0 28.5-11.5T360-480q0-17-11.5-28.5T320-520q-17 0-28.5 11.5T280-480q0 17 11.5 28.5T320-440Zm0-160q17 0 28.5-11.5T360-640q0-17-11.5-28.5T320-680q-17 0-28.5 11.5T280-640q0 17 11.5 28.5T320-600Zm120 320h240v-80H440v80Zm0-160h240v-80H440v80Zm0-160h240v-80H440v80ZM200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm0-80h560v-560H200v560Zm0-560v560-560Z"/></svg>
|
||||
|
After Width: | Height: | Size: 652 B |
1
Front/skydivelogs-app/src/assets/icon/logout.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h280v80H200v560h280v80H200Zm440-160-55-58 102-102H360v-80h327L585-622l55-58 200 200-200 200Z"/></svg>
|
||||
|
After Width: | Height: | Size: 277 B |
1
Front/skydivelogs-app/src/assets/icon/mail.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M160-160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h640q33 0 56.5 23.5T880-720v480q0 33-23.5 56.5T800-160H160Zm320-280L160-640v400h640v-400L480-440Zm0-80 320-200H160l320 200ZM160-640v-80 480-400Z"/></svg>
|
||||
|
After Width: | Height: | Size: 328 B |
1
Front/skydivelogs-app/src/assets/icon/map.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="m600-120-240-84-186 72q-20 8-37-4.5T120-170v-560q0-13 7.5-23t20.5-15l212-72 240 84 186-72q20-8 37 4.5t17 33.5v560q0 13-7.5 23T812-192l-212 72Zm-40-98v-468l-160-56v468l160 56Zm80 0 120-40v-474l-120 46v468Zm-440-10 120-46v-468l-120 40v474Zm440-458v468-468Zm-320-56v468-468Z"/></svg>
|
||||
|
After Width: | Height: | Size: 396 B |
1
Front/skydivelogs-app/src/assets/icon/menu.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M172-278v-28h616v28H172Zm0-188v-28h616v28H172Zm0-188v-28h616v28H172Z"/></svg>
|
||||
|
After Width: | Height: | Size: 193 B |
1
Front/skydivelogs-app/src/assets/icon/not_favorite.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="m480-120-58-52q-101-91-167-157T150-447.5Q111-500 95.5-544T80-634q0-94 63-157t157-63q52 0 99 22t81 62q34-40 81-62t99-22q94 0 157 63t63 157q0 46-15.5 90T810-447.5Q771-395 705-329T538-172l-58 52Zm0-108q96-86 158-147.5t98-107q36-45.5 50-81t14-70.5q0-60-40-100t-100-40q-47 0-87 26.5T518-680h-76q-15-41-55-67.5T300-774q-60 0-100 40t-40 100q0 35 14 70.5t50 81q36 45.5 98 107T480-228Zm0-273Z"/></svg>
|
||||
|
After Width: | Height: | Size: 508 B |
1
Front/skydivelogs-app/src/assets/icon/note.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M200-200h360v-200h200v-360H200v560Zm0 80q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v400L600-120H200Zm80-280v-80h200v80H280Zm0-160v-80h400v80H280Zm-80 360v-560 560Z"/></svg>
|
||||
|
After Width: | Height: | Size: 324 B |
1
Front/skydivelogs-app/src/assets/icon/reset.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M482-186q-123 0-209.5-86T186-480v-70l-90 90-20-20 124-124 124 124-20 20-90-90v70q0 111 78 188.5T482-214q23 0 47.5-4.5T577-232l21 21q-27 12-56.5 18.5T482-186Zm278-170L636-480l20-20 90 90v-70q0-111-78-188.5T478-746q-23 0-47.5 4.5T383-728l-21-21q27-12 56.5-18.5T478-774q123 0 209.5 86T774-480v70l90-90 20 20-124 124Z"/></svg>
|
||||
|
After Width: | Height: | Size: 438 B |
1
Front/skydivelogs-app/src/assets/icon/rotate.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M440-80q-50-5-96-24.5T256-156l56-58q29 21 61.5 34t66.5 18v82Zm80 0v-82q104-15 172-93.5T760-438q0-117-81.5-198.5T480-718h-8l64 64-56 56-160-160 160-160 56 58-62 62h6q75 0 140.5 28.5t114 77q48.5 48.5 77 114T840-438q0 137-91 238.5T520-80ZM198-214q-32-42-51.5-88T122-398h82q5 34 18 66.5t34 61.5l-58 56Zm-76-264q6-51 25-98t51-86l58 56q-21 29-34 61.5T204-478h-82Z"/></svg>
|
||||
|
After Width: | Height: | Size: 482 B |
1
Front/skydivelogs-app/src/assets/icon/summary.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M120-120v-80l80-80v160h-80Zm160 0v-240l80-80v320h-80Zm160 0v-320l80 81v239h-80Zm160 0v-239l80-80v319h-80Zm160 0v-400l80-80v480h-80ZM120-327v-113l280-280 160 160 280-280v113L560-447 400-607 120-327Z"/></svg>
|
||||
|
After Width: | Height: | Size: 322 B |
1
Front/skydivelogs-app/src/assets/icon/wind.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M460-160q-50 0-85-35t-35-85h80q0 17 11.5 28.5T460-240q17 0 28.5-11.5T500-280q0-17-11.5-28.5T460-320H80v-80h380q50 0 85 35t35 85q0 50-35 85t-85 35ZM80-560v-80h540q26 0 43-17t17-43q0-26-17-43t-43-17q-26 0-43 17t-17 43h-80q0-59 40.5-99.5T620-840q59 0 99.5 40.5T760-700q0 59-40.5 99.5T620-560H80Zm660 320v-80q26 0 43-17t17-43q0-26-17-43t-43-17H80v-80h660q59 0 99.5 40.5T880-380q0 59-40.5 99.5T740-240Z"/></svg>
|
||||
|
After Width: | Height: | Size: 522 B |
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"apiUrl": "http://localhost:5000",
|
||||
"version": "0.28.0"
|
||||
"version": "0.28.0 DEV"
|
||||
}
|
||||