diff --git a/Dockerfile b/Dockerfile index 2e766bb..c4e5f72 100644 --- a/Dockerfile +++ b/Dockerfile @@ -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 diff --git a/Front/skydivelogs-app/angular.json b/Front/skydivelogs-app/angular.json index 80b4071..43fa29c 100644 --- a/Front/skydivelogs-app/angular.json +++ b/Front/skydivelogs-app/angular.json @@ -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" - ] - } - }, - "lint": { - "builder": "@angular-devkit/build-angular:tslint", - "options": { - "tsConfig": [ - "src/tsconfig.app.json", - "src/tsconfig.spec.json" + { + "glob": "**/*", + "input": "public" + } ], - "exclude": [ - "**/node_modules/**" - ] - } - } - } - }, - "skydivelogs-app-e2e": { - "root": "e2e", - "sourceRoot": "e2e", - "projectType": "application", - "architect": { - "e2e": { - "builder": "@angular-devkit/build-angular:protractor", - "options": { - "protractorConfig": "./protractor.conf.js", - "devServerTarget": "skydivelogs-app:serve" - } - }, - "lint": { - "builder": "@angular-devkit/build-angular:tslint", - "options": { - "tsConfig": [ - "e2e/tsconfig.e2e.json" - ], - "exclude": [ - "**/node_modules/**" - ] + "styles": ["src/styles.scss"], + "scripts": [] } } } } - }, - "schematics": { - "@schematics/angular:component": { - "prefix": "app" - }, - "@schematics/angular:directive": { - "prefix": "app" - } - }, - "cli": { - "analytics": false } } diff --git a/Front/skydivelogs-app/package-lock.json b/Front/skydivelogs-app/package-lock.json index 46c223f..23ece89 100644 --- a/Front/skydivelogs-app/package-lock.json +++ b/Front/skydivelogs-app/package-lock.json @@ -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" } diff --git a/Front/skydivelogs-app/package.json b/Front/skydivelogs-app/package.json index 3ed2027..9b65578 100644 --- a/Front/skydivelogs-app/package.json +++ b/Front/skydivelogs-app/package.json @@ -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" @@ -43,4 +43,4 @@ "karma-jasmine-html-reporter": "~2.1.0", "typescript": "~5.5.4" } -} \ No newline at end of file +} diff --git a/Front/skydivelogs-app/src/app/app.base.component.ts b/Front/skydivelogs-app/src/app/app.base.component.ts new file mode 100644 index 0000000..4673b50 --- /dev/null +++ b/Front/skydivelogs-app/src/app/app.base.component.ts @@ -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 {} diff --git a/Front/skydivelogs-app/src/app/app.component.css b/Front/skydivelogs-app/src/app/app.component.css index 8742655..f506723 100644 --- a/Front/skydivelogs-app/src/app/app.component.css +++ b/Front/skydivelogs-app/src/app/app.component.css @@ -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; @@ -53,4 +53,4 @@ .mat-icon { margin-right: 15px; -} \ No newline at end of file +} diff --git a/Front/skydivelogs-app/src/app/app.component.html b/Front/skydivelogs-app/src/app/app.component.html index 6c61f30..de07832 100644 --- a/Front/skydivelogs-app/src/app/app.component.html +++ b/Front/skydivelogs-app/src/app/app.component.html @@ -1,76 +1,190 @@ - -

{{ title }}

- + +

{{ translatedTitle }}

+ + - + - + - +
- + - timeline - {{ 'App_Nav_Summary' | translate }} -
+ + {{ "App_Nav_Summary" | translate }} +
- list_alt - {{ 'App_Nav_Jumps' | translate }} + + {{ "App_Nav_Jumps" | translate }} - add_circle - {{ 'App_Nav_NewJump' | translate }} -
+ + {{ "App_Nav_NewJump" | translate }} +
- list_alt - {{ 'App_Nav_TunnelFlights' | translate }} + + {{ "App_Nav_TunnelFlights" | translate }} - add_circle - {{ 'App_Nav_NewTunnelFlight' | translate }} -
+ + {{ "App_Nav_NewTunnelFlight" | translate }} +
- store - {{ 'App_Nav_Dzs' | translate }} + + {{ "App_Nav_Dzs" | translate }} - airplanemode_active - {{ 'App_Nav_Aircrafts' | translate }} + + {{ "App_Nav_Aircrafts" | translate }} - flight_land - {{ 'App_Nav_JumpTypes' | translate }} + + {{ "App_Nav_JumpTypes" | translate }} - settings_input_antenna - {{ 'App_Nav_Gears' | translate }} + + {{ "App_Nav_Gears" | translate }} -
- account_box - +
+ +
{{ this.currentUser.firstName }} {{ this.currentUser.lastName }}
- logout - {{ 'App_Nav_Logout' | translate }} + + {{ + "App_Nav_Logout" | translate + }}
-
{{ 'App_Footer' | translate }}{{ version }} - @Séb
+
-
\ No newline at end of file + diff --git a/Front/skydivelogs-app/src/app/app.component.ts b/Front/skydivelogs-app/src/app/app.component.ts index 5769b5e..fe08a5e 100644 --- a/Front/skydivelogs-app/src/app/app.component.ts +++ b/Front/skydivelogs-app/src/app/app.component.ts @@ -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"; @@ -11,42 +27,62 @@ import { ConfigurationHelper } from "../services/configuration-helper"; import { ServiceCacheApi } from "../services/service-cache-api.service"; @Component({ - selector: "app-root", - templateUrl: "./app.component.html", - styleUrls: ["./app.component.css"], - standalone: false + selector: "app-root", + templateUrl: "./app.component.html", + styleUrls: ["./app.component.css"], + 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, - private authenticationService: AuthenticationService, - private serviceComm: ServiceComm, - private serviceCacheApi : ServiceCacheApi, - private translateService: TranslateService) - { - this.authenticationService.currentUser.subscribe(user => { + constructor( + private router: Router, + private authenticationService: AuthenticationService, + private serviceComm: ServiceComm, + private serviceCacheApi: ServiceCacheApi, + 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 => - { - if (settings != null) { - this.version = settings.version; - } + ConfigurationHelper.settings.subscribe((settings) => { + if (settings != null) { + this.version = settings.version; + } }); } ngOnInit() { - this.serviceComm.componentTitle.subscribe(title => (this.title = title)); + this.serviceComm.componentTitle.subscribe( + (title) => (this.translatedTitle = title), + ); } public show() { diff --git a/Front/skydivelogs-app/src/app/app.config.ts b/Front/skydivelogs-app/src/app/app.config.ts new file mode 100644 index 0000000..46428cd --- /dev/null +++ b/Front/skydivelogs-app/src/app/app.config.ts @@ -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", + }), + ], +}; diff --git a/Front/skydivelogs-app/src/app/app.module.ts b/Front/skydivelogs-app/src/app/app.module.ts deleted file mode 100644 index 9afb822..0000000 --- a/Front/skydivelogs-app/src/app/app.module.ts +++ /dev/null @@ -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 {} diff --git a/Front/skydivelogs-app/src/app/app.routes.ts b/Front/skydivelogs-app/src/app/app.routes.ts new file mode 100644 index 0000000..cfcb433 --- /dev/null +++ b/Front/skydivelogs-app/src/app/app.routes.ts @@ -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), + }, +]; diff --git a/Front/skydivelogs-app/src/app/create-user/create-user.component.html b/Front/skydivelogs-app/src/app/create-user/create-user.component.html index 9628b7c..1ea23d3 100644 --- a/Front/skydivelogs-app/src/app/create-user/create-user.component.html +++ b/Front/skydivelogs-app/src/app/create-user/create-user.component.html @@ -1,72 +1,104 @@ -
+

- {{ 'LoginCreateUser_Firstname' | translate }} - - - {{ 'LoginCreateUser_FirstnameRequired' | translate }} + {{ "LoginCreateUser_Firstname" | translate }} + + + {{ "LoginCreateUser_FirstnameRequired" | translate }} - - {{ 'LoginCreateUser_FirstnamePattern' | translate }} + + {{ "LoginCreateUser_FirstnamePattern" | translate }}

- {{ 'LoginCreateUser_Lastname' | translate }} - - - {{ 'LoginCreateUser_LastnameRequired' | translate }} + {{ "LoginCreateUser_Lastname" | translate }} + + + {{ "LoginCreateUser_LastnameRequired" | translate }} - - {{ 'LoginCreateUser_LastnamePattern' | translate }} + + {{ "LoginCreateUser_LastnamePattern" | translate }}

- {{ 'LoginCreateUser_Email' | translate }} - - - {{ 'LoginCreateUser_EmailRequired' | translate }} + {{ "LoginCreateUser_Email" | translate }} + + + {{ "LoginCreateUser_EmailRequired" | translate }} - - {{ 'LoginCreateUser_EmailPattern' | translate }} + + {{ "LoginCreateUser_EmailPattern" | translate }}

- {{ 'LoginCreateUser_Username' | translate }} - - - {{ 'LoginCreateUser_UsernameRequired' | translate }} + {{ "LoginCreateUser_Username" | translate }} + + + {{ "LoginCreateUser_UsernameRequired" | translate }} - - {{ 'LoginCreateUser_UsernamePattern' | translate }} + + {{ "LoginCreateUser_UsernamePattern" | translate }}

- {{ 'LoginCreateUser_Password' | translate }} - - - {{ 'LoginCreateUser_PasswordRequired' | translate }} + {{ "LoginCreateUser_Password" | translate }} + + + {{ "LoginCreateUser_PasswordRequired" | translate }} - - {{ 'LoginCreateUser_PasswordPattern' | translate }} + + {{ "LoginCreateUser_PasswordPattern" | translate }}

-
{{error}}
+
{{ error }}
diff --git a/Front/skydivelogs-app/src/app/create-user/create-user.component.ts b/Front/skydivelogs-app/src/app/create-user/create-user.component.ts index cef19b9..90b5cf5 100644 --- a/Front/skydivelogs-app/src/app/create-user/create-user.component.ts +++ b/Front/skydivelogs-app/src/app/create-user/create-user.component.ts @@ -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"; @@ -9,23 +22,33 @@ import { AuthenticationService } from "../../services/authentication.service"; import { User } from "../../models/user"; @Component({ - selector: "app-create-user", - templateUrl: "./create-user.component.html", - styleUrls: ["./create-user.component.css"], - standalone: false + selector: "app-create-user", + templateUrl: "./create-user.component.html", + styleUrls: ["./create-user.component.css"], + 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, - private route: ActivatedRoute, - private router: Router, - private authenticationService: AuthenticationService, - private translateService: TranslateService) { + constructor( + private formBuilder: FormBuilder, + private route: ActivatedRoute, + private router: Router, + private authenticationService: AuthenticationService, + private translateService: TranslateService, + ) { // redirect to home if already logged in if (this.authenticationService.currentUserValue) { this.router.navigate(["/"]); @@ -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) - .pipe(first()) - .subscribe( - data => { - this.router.navigate([this.returnUrl]); - }, - error => { - this.error = error; - this.invalidForm = false; - } - ); + createUser.login = this.formCtrls["username"].value; + createUser.password = this.formCtrls["password"].value; + createUser.firstName = this.formCtrls["firstname"].value; + createUser.lastName = this.formCtrls["lastname"].value; + createUser.email = this.formCtrls["email"].value; + createUser.language = this.translateService.getCurrentLang(); + this.authenticationService + .create(createUser) + .pipe(first()) + .subscribe({ + complete: () => this.router.navigate([this.returnUrl]), + error: (error) => { + this.error = error.message; + this.invalidForm = false; + }, + }); } } diff --git a/Front/skydivelogs-app/src/app/default/default.component.html b/Front/skydivelogs-app/src/app/default/default.component.html index be75a6e..fb7fe86 100644 --- a/Front/skydivelogs-app/src/app/default/default.component.html +++ b/Front/skydivelogs-app/src/app/default/default.component.html @@ -1,23 +1,62 @@
-

- - timeline - -

-

- - add_circle - -

-

- - list_alt - -

-

- - Tunnel flights - -

+

+ + + +

+

+ + + +

+

+ + + +

+

+ + + +

- \ No newline at end of file diff --git a/Front/skydivelogs-app/src/app/default/default.component.ts b/Front/skydivelogs-app/src/app/default/default.component.ts index 7c8ff93..7a28d1b 100644 --- a/Front/skydivelogs-app/src/app/default/default.component.ts +++ b/Front/skydivelogs-app/src/app/default/default.component.ts @@ -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"; @@ -10,27 +12,31 @@ import { JumpTypeService } from "../../services/jump-type.service"; import { ServiceComm } from "../../services/service-comm.service"; @Component({ - selector: "app-default", - templateUrl: "./default.component.html", - styleUrls: ["./default.component.css"], - standalone: false + selector: "app-default", + templateUrl: "./default.component.html", + styleUrls: ["./default.component.css"], + imports: [TranslateModule, MatIconModule, RouterLink], }) export class DefaultComponent implements OnInit { - constructor(private serviceComm: ServiceComm, - private translateService: TranslateService, - private authenticationService: AuthenticationService, - private serviceApiAircraft : AircraftService, - private serviceApiJumpType : JumpTypeService, - private serviceApiDropzone : DropzoneService, - private serviceApiGear : GearService) {} + constructor( + private serviceComm: ServiceComm, + private translateService: TranslateService, + private authenticationService: AuthenticationService, + private serviceApiAircraft: AircraftService, + private serviceApiJumpType: JumpTypeService, + private serviceApiDropzone: DropzoneService, + 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){ + this.serviceComm.forceTranslateTitle.subscribe((data) => { + if (data === true) { this.updateTitle(); } }); @@ -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); + }); } -} \ No newline at end of file +} diff --git a/Front/skydivelogs-app/src/app/jump-infos/jump-infos.component.html b/Front/skydivelogs-app/src/app/jump-infos/jump-infos.component.html index 2f1f54d..ba26a16 100644 --- a/Front/skydivelogs-app/src/app/jump-infos/jump-infos.component.html +++ b/Front/skydivelogs-app/src/app/jump-infos/jump-infos.component.html @@ -1,11 +1,34 @@
-

Gear : {{jump.gear.name}} ({{jump.gear.mainCanopy}})

-

Special jump

-

Cutaway

- - - +

+ Gear : {{ jump.gear.name }} ({{ jump.gear.mainCanopy }}) +

+

+ Special jump +

+

+ Cutaway +

+ + + -
- -
\ No newline at end of file +
+ + diff --git a/Front/skydivelogs-app/src/app/jump-infos/jump-infos.component.ts b/Front/skydivelogs-app/src/app/jump-infos/jump-infos.component.ts index ee73f15..c995166 100644 --- a/Front/skydivelogs-app/src/app/jump-infos/jump-infos.component.ts +++ b/Front/skydivelogs-app/src/app/jump-infos/jump-infos.component.ts @@ -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, - private serviceJump: JumpService, - private serviceComm: ServiceComm) { + constructor( + @Inject(MAT_DIALOG_DATA) public data: any, + private serviceJump: JumpService, + private serviceComm: ServiceComm + ) { this.jump = new JumpResp(data.jump); this.editMode = data.editMode; } @@ -26,12 +45,15 @@ export class JumpInfosComponent implements OnInit { ngOnInit(): void {} public updateJump() { - this.serviceJump.updateJump(this.jump.id, - this.jump.isSpecial, - this.jump.withCutaway, - this.jump.notes) - .subscribe(() => { - this.serviceComm.refreshData(AddAction.Jump); - }); + this.serviceJump + .updateJump( + this.jump.id, + this.jump.isSpecial, + this.jump.withCutaway, + this.jump.notes + ) + .subscribe(() => { + this.serviceComm.refreshData(AddAction.Jump); + }); } } diff --git a/Front/skydivelogs-app/src/app/list-of-aircrafts/list-of-aircrafts.component.html b/Front/skydivelogs-app/src/app/list-of-aircrafts/list-of-aircrafts.component.html index 80f7c19..b990242 100644 --- a/Front/skydivelogs-app/src/app/list-of-aircrafts/list-of-aircrafts.component.html +++ b/Front/skydivelogs-app/src/app/list-of-aircrafts/list-of-aircrafts.component.html @@ -1,25 +1,44 @@
-
- +
+ - - + + - - + + - - + + - +
{{ 'List_Aircrafts_Header_Id' | translate }}{{element.id}} + {{ "ListAircrafts_Header_Id" | translate }} + {{ element.id }} {{ 'List_Aircrafts_Header_Name' | translate }}{{element.name}} + {{ "ListAircrafts_Header_Name" | translate }} + {{ element.name }} {{ 'List_Aircrafts_Header_Image' | translate }}No image + {{ "ListAircrafts_Header_Image" | translate }} + + No image +
diff --git a/Front/skydivelogs-app/src/app/list-of-aircrafts/list-of-aircrafts.component.ts b/Front/skydivelogs-app/src/app/list-of-aircrafts/list-of-aircrafts.component.ts index b791c91..a793ecd 100644 --- a/Front/skydivelogs-app/src/app/list-of-aircrafts/list-of-aircrafts.component.ts +++ b/Front/skydivelogs-app/src/app/list-of-aircrafts/list-of-aircrafts.component.ts @@ -1,56 +1,69 @@ -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 = ['name', 'imageData']; + public displayedColumns: Array = ["name", "imageData"]; public dataSourceTable: MatTableDataSource; public resultsLength = 0; public isUserAdmin: boolean; @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator; - constructor(private serviceApi: AircraftService, - private serviceComm: ServiceComm, - private authenticationService: AuthenticationService, - public dialog: MatDialog, - private translateService: TranslateService) { - this.isUserAdmin = this.authenticationService.currentUserValue.roles === "admin"; + constructor( + private serviceApi: AircraftService, + private serviceComm: ServiceComm, + private authenticationService: AuthenticationService, + public dialog: MatDialog, + 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(); } }); - this.serviceComm.forceTranslateTitle.subscribe((data)=> { - if (data === true){ + this.serviceComm.forceTranslateTitle.subscribe((data) => { + if (data === true) { this.updateTitle(); } }); - + this.updateTitle(); this.getListOfAircrafts(); } 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(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); + }); } } diff --git a/Front/skydivelogs-app/src/app/list-of-dzs/list-of-dzs.component.html b/Front/skydivelogs-app/src/app/list-of-dzs/list-of-dzs.component.html index d9ac87c..912a252 100644 --- a/Front/skydivelogs-app/src/app/list-of-dzs/list-of-dzs.component.html +++ b/Front/skydivelogs-app/src/app/list-of-dzs/list-of-dzs.component.html @@ -1,59 +1,113 @@
-
- +
+ - {{ 'List_Dz_Filter' | translate }} - + {{ "ListDz_Filter" | translate }} + - - + - - + + - + - + - - + + - +
- favorite - favorite_border - - link + + + + + - - map + + - - mail_outline + + {{ 'List_Dz_Header_ID' | translate }}{{element.id}} + {{ "ListDz_Header_ID" | translate }} + {{ element.id }} {{ 'List_Dz_Header_Name' | translate }} + {{ "ListDz_Header_Name" | translate }} + {{ 'List_Dz_Header_Address' | translate }} + {{ "ListDz_Header_Address" | translate }} + {{ 'List_Dz_Header_Type' | translate }}{{element.type}} + {{ "ListDz_Header_Type" | translate }} + {{ element.type }}
diff --git a/Front/skydivelogs-app/src/app/list-of-dzs/list-of-dzs.component.ts b/Front/skydivelogs-app/src/app/list-of-dzs/list-of-dzs.component.ts index 1c9b165..117b8ce 100644 --- a/Front/skydivelogs-app/src/app/list-of-dzs/list-of-dzs.component.ts +++ b/Front/skydivelogs-app/src/app/list-of-dzs/list-of-dzs.component.ts @@ -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 = [ - 'isfavorite', - 'name', - 'address', - 'type', + "isfavorite", + "name", + "address", + "type", ]; public dataSourceTable: MatTableDataSource; public isUserAdmin: boolean; public resultsLength = 0; @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator; - constructor(private serviceApi: DropzoneService, - private serviceComm: ServiceComm, - private authenticationService: AuthenticationService, - public dialog: MatDialog, - private translateService: TranslateService) { - this.isUserAdmin = this.authenticationService.currentUserValue.roles === "admin"; + constructor( + private serviceApi: DropzoneService, + private serviceComm: ServiceComm, + private authenticationService: AuthenticationService, + public dialog: MatDialog, + private translateService: TranslateService + ) { + this.isUserAdmin = + this.authenticationService.currentUserValue.roles === "admin"; } ngOnInit() { @@ -44,32 +65,35 @@ export class ListOfDzsComponent implements OnInit { this.getListOfDropZones(); } }); - this.serviceComm.forceTranslateTitle.subscribe((data)=> { - if (data === true){ + this.serviceComm.forceTranslateTitle.subscribe((data) => { + if (data === true) { this.updateTitle(); } }); - + this.updateTitle(); this.getListOfDropZones(); } private getListOfDropZones() { - this.serviceApi.getListOfDropZones() - .subscribe((data) => { - setTimeout(() => { - data.sort((a, b) => (b.isFavorite ? 1 : 0) - (a.isFavorite ? 1 : 0) || a.name.localeCompare(b.name)); - this.dataSourceTable = new MatTableDataSource(data); - this.dataSourceTable.paginator = this.paginator; - this.resultsLength = data.length; - }, 500); - }); + this.serviceApi.getListOfDropZones().subscribe((data) => { + setTimeout(() => { + data.sort( + (a, b) => + (b.isFavorite ? 1 : 0) - (a.isFavorite ? 1 : 0) || + a.name.localeCompare(b.name) + ); + this.dataSourceTable = new MatTableDataSource(data); + this.dataSourceTable.paginator = this.paginator; + this.resultsLength = data.length; + }, 500); + }); } public setToFavorite(dropzone: DropZoneResp) { dropzone.isFavorite = true; this.serviceApi.setFavoriteDropZone(dropzone); - + const data = this.dataSourceTable.data; data.sort((a, b) => (b.isFavorite ? 1 : 0) - (a.isFavorite ? 1 : 0)); this.dataSourceTable = new MatTableDataSource(data); @@ -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); + }); } } diff --git a/Front/skydivelogs-app/src/app/list-of-gears/list-of-gears.component.html b/Front/skydivelogs-app/src/app/list-of-gears/list-of-gears.component.html index 6ffcadc..9f60c58 100644 --- a/Front/skydivelogs-app/src/app/list-of-gears/list-of-gears.component.html +++ b/Front/skydivelogs-app/src/app/list-of-gears/list-of-gears.component.html @@ -1,45 +1,63 @@
-
- +
+ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - +
{{ 'List_Gears_Header_Id' | translate }}{{element.id}} + {{ "ListGears_Header_Id" | translate }} + {{ element.id }} {{ 'List_Gears_Header_Name' | translate }}{{element.name}} + {{ "ListGears_Header_Name" | translate }} + {{ element.name }} {{ 'List_Gears_Header_Manufacturer' | translate }}{{element.manufacturer}} + {{ "ListGears_Header_Manufacturer" | translate }} + {{ element.manufacturer }} {{ 'List_Gears_Header_CanopySize' | translate }}{{element.minSize}} - {{element.maxSize}} + {{ "ListGears_Header_CanopySize" | translate }} + + {{ element.minSize }} - {{ element.maxSize }} + {{ 'List_Gears_Header_Aad' | translate }}{{element.aad}} + {{ "ListGears_Header_Aad" | translate }} + {{ element.aad }} {{ 'List_Gears_Header_Main' | translate }}{{element.mainCanopy}} + {{ "ListGears_Header_Main" | translate }} + {{ element.mainCanopy }} {{ 'List_Gears_Header_Reserve' | translate }}{{element.reserveCanopy}} + {{ "ListGears_Header_Reserve" | translate }} + {{ element.reserveCanopy }}
diff --git a/Front/skydivelogs-app/src/app/list-of-gears/list-of-gears.component.ts b/Front/skydivelogs-app/src/app/list-of-gears/list-of-gears.component.ts index 053e9b6..0dd0353 100644 --- a/Front/skydivelogs-app/src/app/list-of-gears/list-of-gears.component.ts +++ b/Front/skydivelogs-app/src/app/list-of-gears/list-of-gears.component.ts @@ -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"; @@ -11,10 +14,17 @@ import { AddAction } from "../../models/add-action.enum"; import { NewGearComponent } from "../new-gear/new-gear.component"; @Component({ - selector: "app-list-of-gears", - templateUrl: "./list-of-gears.component.html", - styleUrls: ["./list-of-gears.component.css"], - standalone: false + selector: "app-list-of-gears", + templateUrl: "./list-of-gears.component.html", + styleUrls: ["./list-of-gears.component.css"], + imports: [ + TranslateModule, + CommonModule, + MatPaginatorModule, + MatProgressSpinnerModule, + MatTableModule, + MatButtonModule, + ], }) export class ListOfGearsComponent implements OnInit { public displayedColumns: Array = [ @@ -23,37 +33,38 @@ export class ListOfGearsComponent implements OnInit { "maxSize", "aad", "mainCanopy", - "reserveCanopy" + "reserveCanopy", ]; public dataSourceTable: MatTableDataSource; public resultsLength = 0; @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator; - constructor(private serviceApi: GearService, - private serviceComm: ServiceComm, - public dialog: MatDialog, - private translateService: TranslateService) {} + constructor( + private serviceApi: GearService, + private serviceComm: ServiceComm, + public dialog: MatDialog, + private translateService: TranslateService + ) {} ngOnInit() { - this.serviceComm.refreshRequest.subscribe(action => { + this.serviceComm.refreshRequest.subscribe((action) => { if (action === AddAction.Gear) { this.dialog.closeAll(); this.getListOfGears(); } }); - this.serviceComm.forceTranslateTitle.subscribe((data)=> { - if (data === true){ + this.serviceComm.forceTranslateTitle.subscribe((data) => { + if (data === true) { this.updateTitle(); } }); - + this.updateTitle(); this.getListOfGears(); } getListOfGears() { - this.serviceApi.getListOfGears() - .subscribe(data => { + this.serviceApi.getListOfGears().subscribe((data) => { setTimeout(() => { data.sort((a, b) => b.id - a.id); this.dataSourceTable = new MatTableDataSource(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); + }); } } diff --git a/Front/skydivelogs-app/src/app/list-of-images/list-of-images.component.html b/Front/skydivelogs-app/src/app/list-of-images/list-of-images.component.html index d189843..2d5e7db 100644 --- a/Front/skydivelogs-app/src/app/list-of-images/list-of-images.component.html +++ b/Front/skydivelogs-app/src/app/list-of-images/list-of-images.component.html @@ -1,8 +1,20 @@
-
+

- +

@@ -12,7 +24,7 @@

@@ -22,28 +34,54 @@
- - + + - - + - +
Comments{{element.comment}} + Comments + + {{ element.comment }} + Image - image + + Image + + image
-
+
× - undo +
- +
diff --git a/Front/skydivelogs-app/src/app/list-of-images/list-of-images.component.ts b/Front/skydivelogs-app/src/app/list-of-images/list-of-images.component.ts index 3478c43..bc99f85 100644 --- a/Front/skydivelogs-app/src/app/list-of-images/list-of-images.component.ts +++ b/Front/skydivelogs-app/src/app/list-of-images/list-of-images.component.ts @@ -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'], - 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)' })), - ]) - ], - standalone: false + 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)" })), + ]), + ], + imports: [ + TranslateModule, + CommonModule, + MatIconModule, + MatPaginatorModule, + MatFormFieldModule, + ReactiveFormsModule, + MatTableModule, + MatButtonModule, + MatInputModule, + ], }) export class ListOfImagesComponent implements OnInit { - public displayedColumns: Array = ['comment', 'data']; + public displayedColumns: Array = ["comment", "data"]; public imgForm: FormGroup; public imageError: string; private selectedFile: string; @@ -32,13 +53,13 @@ export class ListOfImagesComponent implements OnInit { public showPopin: boolean; public dataSourceTable: MatTableDataSource; 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 { this.serviceComm.refreshRequest.subscribe((action) => { @@ -49,33 +70,32 @@ 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) => { - setTimeout(() => { - this.dataSourceTable = new MatTableDataSource(data); - this.dataSourceTable.paginator = this.paginator; - this.resultsLength = data.length; - }, 500); - }); + this.serviceApi.getListOfImages().subscribe((data) => { + setTimeout(() => { + this.dataSourceTable = new MatTableDataSource(data); + this.dataSourceTable.paginator = this.paginator; + this.resultsLength = data.length; + }, 500); + }); } public onFileChanged(fileInput: any) { const file = fileInput.dataTransfer ? fileInput.dataTransfer.files[0] : fileInput.target.files[0]; - const allowed_types = ['image/png', 'image/jpeg']; + const 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,13 +129,14 @@ 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){ + openModal(image: ImageResp) { this.popinImage = image.data; this.showPopin = true; } @@ -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"; } } } diff --git a/Front/skydivelogs-app/src/app/list-of-jump-types/list-of-jump-types.component.html b/Front/skydivelogs-app/src/app/list-of-jump-types/list-of-jump-types.component.html index a88b804..4c35577 100644 --- a/Front/skydivelogs-app/src/app/list-of-jump-types/list-of-jump-types.component.html +++ b/Front/skydivelogs-app/src/app/list-of-jump-types/list-of-jump-types.component.html @@ -1,20 +1,31 @@
-
- +
+ - - + + - - + + - +
{{ 'List_JumpType_Header_Id' | translate }}{{element.id}} + {{ "ListJumpType_Header_Id" | translate }} + {{ element.id }} {{ 'List_JumpType_Header_Name' | translate }}{{element.name}} + {{ "ListJumpType_Header_Name" | translate }} + {{ element.name }}
diff --git a/Front/skydivelogs-app/src/app/list-of-jump-types/list-of-jump-types.component.ts b/Front/skydivelogs-app/src/app/list-of-jump-types/list-of-jump-types.component.ts index ffc5802..2b8b565 100644 --- a/Front/skydivelogs-app/src/app/list-of-jump-types/list-of-jump-types.component.ts +++ b/Front/skydivelogs-app/src/app/list-of-jump-types/list-of-jump-types.component.ts @@ -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 + selector: "app-list-of-jump-types", + templateUrl: "./list-of-jump-types.component.html", + styleUrls: ["./list-of-jump-types.component.css"], + imports: [ + TranslateModule, + CommonModule, + MatPaginatorModule, + MatProgressSpinnerModule, + MatTableModule, + MatButtonModule, + ], }) export class ListOfJumpTypesComponent implements OnInit { public displayedColumns: Array = ["name"]; @@ -24,33 +34,36 @@ export class ListOfJumpTypesComponent implements OnInit { public resultsLength = 0; @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator; - constructor(private serviceApi: JumpTypeService, - private serviceComm: ServiceComm, - private authenticationService: AuthenticationService, - public dialog: MatDialog, - private translateService: TranslateService) { - this.isUserAdmin = this.authenticationService.currentUserValue.roles === "admin"; + constructor( + private serviceApi: JumpTypeService, + private serviceComm: ServiceComm, + private authenticationService: AuthenticationService, + public dialog: MatDialog, + 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(); } }); - this.serviceComm.forceTranslateTitle.subscribe((data)=> { - if (data === true){ + this.serviceComm.forceTranslateTitle.subscribe((data) => { + if (data === true) { this.updateTitle(); } }); - + this.updateTitle(); this.getListOfJumpTypes(); } 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(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); + }); } } diff --git a/Front/skydivelogs-app/src/app/list-of-jumps/list-of-jumps.component.html b/Front/skydivelogs-app/src/app/list-of-jumps/list-of-jumps.component.html index b06a525..e1a81e4 100644 --- a/Front/skydivelogs-app/src/app/list-of-jumps/list-of-jumps.component.html +++ b/Front/skydivelogs-app/src/app/list-of-jumps/list-of-jumps.component.html @@ -1,82 +1,165 @@
-
- -
+
+ +
- + -
- - - - - +
+
- info - sticky_note_2 - celebration -
+ + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - -
+ + + + {{ 'List_Jump_Header_Num' | translate }} - - {{ paginator.length - ( (paginator.pageIndex * paginator.pageSize ) + i ) }} - + {{ "ListJump_Header_Num" | translate }} + + {{ + paginator.length - (paginator.pageIndex * paginator.pageSize + i) + }} + {{ 'List_Jump_Header_Date' | translate }} - - + {{ "ListJump_Header_Date" | translate }} + + + {{ 'List_Jump_Header_JumpType' | - translate }} - - + {{ "ListJump_Header_JumpType" | translate }} + + + {{ 'List_Jump_Header_Aircraft' | - translate }} - - + {{ "ListJump_Header_Aircraft" | translate }} + + + {{ 'List_Jump_Header_Dz' | translate }} - - + {{ "ListJump_Header_Dz" | translate }} + + + {{ 'List_Jump_Header_Id' | translate }}{{element.gear.name}} + {{ "ListJump_Header_Id" | translate }} + {{ element.gear.name }} - delete - edit - + + +
-
+ + + +
- -
\ No newline at end of file + +
diff --git a/Front/skydivelogs-app/src/app/list-of-jumps/list-of-jumps.component.ts b/Front/skydivelogs-app/src/app/list-of-jumps/list-of-jumps.component.ts index f30f173..15aafc9 100644 --- a/Front/skydivelogs-app/src/app/list-of-jumps/list-of-jumps.component.ts +++ b/Front/skydivelogs-app/src/app/list-of-jumps/list-of-jumps.component.ts @@ -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"; @@ -12,10 +25,24 @@ import { JumpInfosComponent } from "../jump-infos/jump-infos.component"; import { StatsService } from "../../services/stats.service"; @Component({ - selector: "app-list-of-jumps", - templateUrl: "./list-of-jumps.component.html", - styleUrls: ["./list-of-jumps.component.css"], - standalone: false + selector: "app-list-of-jumps", + templateUrl: "./list-of-jumps.component.html", + styleUrls: ["./list-of-jumps.component.css"], + imports: [ + TranslateModule, + CommonModule, + RouterLink, + RouterModule, + MatIconModule, + MatPaginatorModule, + MatProgressSpinnerModule, + MatProgressBarModule, + MatTableModule, + MatFormFieldModule, + ReactiveFormsModule, + MatInputModule, + MatButtonModule, + ], }) export class ListOfJumpsComponent implements OnInit { public displayedColumns: Array = [ @@ -31,11 +58,12 @@ export class ListOfJumpsComponent implements OnInit { @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator; public isLoading: boolean = false; - constructor(private serviceApi: JumpService, - private serviceComm: ServiceComm, - public dialog: MatDialog, - private translateService: TranslateService, - private statsService: StatsService + constructor( + private serviceApi: JumpService, + private serviceComm: ServiceComm, + public dialog: MatDialog, + private translateService: TranslateService, + private statsService: StatsService ) {} ngAferViewInit(): void { @@ -62,15 +90,16 @@ export class ListOfJumpsComponent implements OnInit { getListOfJumps(pageSize: number = 20, pageIndex: number = 0) { this.isLoading = true; - this.serviceApi.getJumps(pageIndex * pageSize, pageIndex * pageSize + pageSize) - .subscribe((data) => { - this.dataSourceTable.data = data.rows; - setTimeout(() => { - this.paginator.length = data.count; - this.paginator.pageIndex = pageIndex; - this.isLoading = false; - }, 500); - }); + this.serviceApi + .getJumps(pageIndex * pageSize, pageIndex * pageSize + pageSize) + .subscribe((data) => { + this.dataSourceTable.data = data.rows; + setTimeout(() => { + this.paginator.length = data.count; + this.paginator.pageIndex = pageIndex; + this.isLoading = false; + }, 500); + }); } openDialog(item: Jump, editMode: boolean) { diff --git a/Front/skydivelogs-app/src/app/list-of-tunnel-flights/list-of-tunnel-flights.component.html b/Front/skydivelogs-app/src/app/list-of-tunnel-flights/list-of-tunnel-flights.component.html index 8d54f86..8e8b25d 100644 --- a/Front/skydivelogs-app/src/app/list-of-tunnel-flights/list-of-tunnel-flights.component.html +++ b/Front/skydivelogs-app/src/app/list-of-tunnel-flights/list-of-tunnel-flights.component.html @@ -38,11 +38,11 @@
+ @@ -111,7 +111,7 @@ @@ -124,8 +124,8 @@ aria-label="Delete this jump" style="cursor: pointer" (click)="delete(element)" - >delete + svgIcon="delete" + > diff --git a/Front/skydivelogs-app/src/app/list-of-tunnel-flights/list-of-tunnel-flights.component.ts b/Front/skydivelogs-app/src/app/list-of-tunnel-flights/list-of-tunnel-flights.component.ts index 033ed82..a2e820e 100644 --- a/Front/skydivelogs-app/src/app/list-of-tunnel-flights/list-of-tunnel-flights.component.ts +++ b/Front/skydivelogs-app/src/app/list-of-tunnel-flights/list-of-tunnel-flights.component.ts @@ -1,233 +1,278 @@ -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 barChartType: ChartType; - public isLoading: boolean = false; - public selectedPeriod: string; - public dataSourceTable: MatTableDataSource = new MatTableDataSource(); - public displayedColumns: Array = [ - "id", - "tunnel", - "jumpType", - "nbMinutes", - "notes", - "flightDate", - "actions" - ]; - public stats: Array<{id: String|Number, values: String|Number}> = []; + public barChartLegend = true; + public barChartData: ChartData<"bar">; + public barChartOptions: ChartConfiguration["options"]; + public barChartType: ChartType; + public isLoading: boolean = false; + public selectedPeriod: string; + public dataSourceTable: MatTableDataSource = + new MatTableDataSource(); + public displayedColumns: Array = [ + "id", + "tunnel", + "jumpType", + "nbMinutes", + "notes", + "flightDate", + "actions", + ]; + public stats: Array<{ id: String | Number; values: String | Number }> = []; - constructor(private serviceComm: ServiceComm, - private serviceTunnelFlight: TunnelFlightService, - private translateService: TranslateService, - private dateService: DateService) { } + constructor( + private serviceComm: ServiceComm, + private serviceTunnelFlight: TunnelFlightService, + private translateService: TranslateService, + private dateService: DateService + ) {} - ngOnInit() { - this.serviceComm.forceTranslateTitle.subscribe((data) => { - if (data === true) { - this.updateTitle(); - } - }); + ngOnInit() { + this.serviceComm.forceTranslateTitle.subscribe((data) => { + if (data === true) { this.updateTitle(); + } + }); + this.updateTitle(); - this.chartConfig(); - this.selectedPeriod = "currentYear" - this.getDataForGraph(); - } - - public onPeriodChange() { - this.getDataForGraph(); - if (this.dataSourceTable?.data.length > 0){ - this.getDataForTable(); - } + this.chartConfig(); + this.selectedPeriod = "currentYear"; + this.getDataForGraph(); + } + + public onPeriodChange() { + this.getDataForGraph(); + if (this.dataSourceTable?.data.length > 0) { + this.getDataForTable(); } + } - public onLoadTable() { - this.getDataForTable(); - } + public onLoadTable() { + this.getDataForTable(); + } - private chartConfig() { - this.barChartType = "bar"; - this.barChartOptions = { - responsive: true, - maintainAspectRatio: true, - plugins: { - legend: { - display: true - }, - tooltip: { - callbacks: { - footer: this.footer, - } - } - }, - interaction: { - intersect: false, - mode: 'nearest', - axis: 'x' - }, - scales: { - x: { - stacked: true - }, - y: { - stacked: true - } - } - }; - } - - private updateTitle() { - this.translateService.get("ListTunnelFlight_Title").subscribe( - data => { this.serviceComm.updatedComponentTitle(data); } - ); - } - - private getDataForTable(): void { - this.isLoading = true; - - // Get data to show in a table - let endDate = new Date(); - endDate.setHours(0, 0, 0, 0); - let beginDate = this.computeBeginDateByPeriod(this.selectedPeriod, endDate); - - this.serviceTunnelFlight.getTunnelFlights(beginDate, endDate) - .subscribe((data) => { - this.dataSourceTable.data = data; - this.isLoading = false; - }); - } - - private getDataForGraph(): void { - this.isLoading = true; - - // Get data to show in a table - let endDate = new Date(); - endDate.setHours(0, 0, 0, 0); - let beginDate = this.computeBeginDateByPeriod(this.selectedPeriod, endDate); - - this.serviceTunnelFlight.getTunnelFlightsByMonth(beginDate, endDate) - .subscribe((data) => { - const allMonths = this.getMontsBetweenDates(beginDate, endDate) - const cumulatedTime = this.getCumulatedTimeByTypeByMonth(data, allMonths); - this.computeTimeByType(data); - this.barChartData = { - labels: allMonths, - datasets: cumulatedTime - }; - - this.isLoading = false; - }); - } - - private computeTimeByType(stats: TunnelFlightByMonth[]) { - this.stats = []; - from(stats).pipe( - groupBy((type) => type.type, { element: (p) => p.nb }), - mergeMap((group$) => - group$.pipe(reduce((acc, cur) => [...acc, cur], [`${group$.key}`])) - ), - map((arr) => ({ id: arr[0], values: arr.slice(1).reduce((a, b) => Number(a) + Number(b), 0) })) - ) - .subscribe((p) => { - console.log(p); - this.stats.push(p); - }); - } - - private getMontsBetweenDates(beginDate: Date, endDate: Date): Array { - let results: Array = []; - let tmpBeginDate = new Date(beginDate.getTime()); - const tmpEndDate = new Date(endDate.getTime()); - - while (tmpBeginDate < tmpEndDate) { - results.push(formatDate(tmpBeginDate, "yy-MM", "en")); - tmpBeginDate.setMonth(tmpBeginDate.getMonth() + 1); - } - - return results; - } - - private getCumulatedTimeByTypeByMonth(stats: TunnelFlightByMonth[], allMonths: string[]): Array { - let tmpResults = new Map(); - - const disctintType = Array.from(new Set(stats.map((item) => item.type))); - disctintType.forEach(type => { - tmpResults.set(type, Array.from({length: allMonths.length}, (v, k) => 0)); - }); - - for (let i = 0; i < allMonths.length; i++) { - const month = allMonths[i]; - let filteredStats = stats.filter((d) => d.month == month); - - if (filteredStats.length > 0){ - filteredStats.forEach(fs => { - tmpResults.get(fs.type)[i] += fs.nb; - }); - } - } - - const results = Array.from(tmpResults, function (item) { - return { label: item[0], data: item[1] } - }); - - return results; - } - - private footer = (tooltipItems) => { - let sum = 0; - - tooltipItems.forEach(function (tooltipItem) { - sum += tooltipItem.parsed.y; - }); - - return 'Sum: ' + sum; + private chartConfig() { + this.barChartType = "bar"; + this.barChartOptions = { + responsive: true, + maintainAspectRatio: true, + plugins: { + legend: { + display: true, + }, + tooltip: { + callbacks: { + footer: this.footer, + }, + }, + }, + interaction: { + intersect: false, + mode: "nearest", + axis: "x", + }, + scales: { + x: { + stacked: true, + }, + y: { + stacked: true, + }, + }, }; + } - private computeBeginDateByPeriod(selectedPeriod: String, endDate: Date): Date { - let beginDate = new Date(); - - switch (selectedPeriod) { - case "currentYear": - beginDate = new Date(endDate.getFullYear(), 0, 1); - break; - case "12Months": - beginDate = this.dateService.addMonths(endDate, -12); - beginDate.setDate(1); - break; - case "all": - beginDate = this.dateService.addMonths(endDate, -120); - beginDate.setDate(1); - break; - } + private updateTitle() { + this.translateService.get("ListTunnelFlight_Title").subscribe((data) => { + this.serviceComm.updatedComponentTitle(data); + }); + } - return beginDate; - } + private getDataForTable(): void { + this.isLoading = true; - public delete(item: TunnelFlight) { - let data: Array = this.dataSourceTable.data; - data = data.filter((d) => d.id !== item.id); + // Get data to show in a table + let endDate = new Date(); + endDate.setHours(0, 0, 0, 0); + let beginDate = this.computeBeginDateByPeriod(this.selectedPeriod, endDate); + this.serviceTunnelFlight + .getTunnelFlights(beginDate, endDate) + .subscribe((data) => { this.dataSourceTable.data = data; - this.serviceTunnelFlight.deleteTunnelFlight(item); + this.isLoading = false; + }); + } + + private getDataForGraph(): void { + this.isLoading = true; + + // Get data to show in a table + let endDate = new Date(); + endDate.setHours(0, 0, 0, 0); + let beginDate = this.computeBeginDateByPeriod(this.selectedPeriod, endDate); + + this.serviceTunnelFlight + .getTunnelFlightsByMonth(beginDate, endDate) + .subscribe((data) => { + const allMonths = this.getMontsBetweenDates(beginDate, endDate); + const cumulatedTime = this.getCumulatedTimeByTypeByMonth( + data, + allMonths + ); + this.computeTimeByType(data); + this.barChartData = { + labels: allMonths, + datasets: cumulatedTime, + }; + + this.isLoading = false; + }); + } + + private computeTimeByType(stats: TunnelFlightByMonth[]) { + this.stats = []; + from(stats) + .pipe( + groupBy((type) => type.type, { element: (p) => p.nb }), + mergeMap((group$) => + group$.pipe(reduce((acc, cur) => [...acc, cur], [`${group$.key}`])) + ), + map((arr) => ({ + id: arr[0], + values: arr.slice(1).reduce((a, b) => Number(a) + Number(b), 0), + })) + ) + .subscribe((p) => { + console.log(p); + this.stats.push(p); + }); + } + + private getMontsBetweenDates(beginDate: Date, endDate: Date): Array { + let results: Array = []; + let tmpBeginDate = new Date(beginDate.getTime()); + const tmpEndDate = new Date(endDate.getTime()); + + while (tmpBeginDate < tmpEndDate) { + results.push(formatDate(tmpBeginDate, "yy-MM", "en")); + tmpBeginDate.setMonth(tmpBeginDate.getMonth() + 1); } + + return results; + } + + private getCumulatedTimeByTypeByMonth( + stats: TunnelFlightByMonth[], + allMonths: string[] + ): Array { + let tmpResults = new Map(); + + const disctintType = Array.from(new Set(stats.map((item) => item.type))); + disctintType.forEach((type) => { + tmpResults.set( + type, + Array.from({ length: allMonths.length }, (v, k) => 0) + ); + }); + + for (let i = 0; i < allMonths.length; i++) { + const month = allMonths[i]; + let filteredStats = stats.filter((d) => d.month == month); + + if (filteredStats.length > 0) { + filteredStats.forEach((fs) => { + tmpResults.get(fs.type)[i] += fs.nb; + }); + } + } + + const results = Array.from(tmpResults, function (item) { + return { label: item[0], data: item[1] }; + }); + + return results; + } + + private footer = (tooltipItems: any) => { + let sum = 0; + + tooltipItems.forEach(function (tooltipItem: any) { + sum += tooltipItem.parsed.y; + }); + + return "Sum: " + sum; + }; + + private computeBeginDateByPeriod( + selectedPeriod: String, + endDate: Date + ): Date { + let beginDate = new Date(); + + switch (selectedPeriod) { + case "currentYear": + beginDate = new Date(endDate.getFullYear(), 0, 1); + break; + case "12Months": + beginDate = this.dateService.addMonths(endDate, -12); + beginDate.setDate(1); + break; + case "all": + beginDate = this.dateService.addMonths(endDate, -120); + beginDate.setDate(1); + break; + } + + return beginDate; + } + + public delete(item: TunnelFlight) { + let data: Array = this.dataSourceTable.data; + data = data.filter((d) => d.id !== item.id); + + this.dataSourceTable.data = data; + this.serviceTunnelFlight.deleteTunnelFlight(item); + } } diff --git a/Front/skydivelogs-app/src/app/login-user/login-user.component.html b/Front/skydivelogs-app/src/app/login-user/login-user.component.html index 4e92fc6..885a037 100644 --- a/Front/skydivelogs-app/src/app/login-user/login-user.component.html +++ b/Front/skydivelogs-app/src/app/login-user/login-user.component.html @@ -1,36 +1,50 @@ - +

- {{ 'LoginUser_Username' | translate }} - - - {{ 'LoginUser_UsernameRequired' | translate }} + {{ "LoginUser_Username" | translate }} + + + {{ "LoginUser_UsernameRequired" | translate }} - + {{ 'LoginUser_UsernamePattern | translate }}

- {{ 'LoginUser_Password' | translate }} - - - {{ 'LoginUser_PasswordRequired' | translate }} + {{ "LoginUser_Password" | translate }} + + + {{ "LoginUser_PasswordRequired" | translate }} - - {{ 'LoginUser_PasswordPattern' | translate }} + + {{ "LoginUser_PasswordPattern" | translate }}

-
{{error}}
+
{{ error }}
diff --git a/Front/skydivelogs-app/src/app/login-user/login-user.component.ts b/Front/skydivelogs-app/src/app/login-user/login-user.component.ts index 171db28..38831a4 100644 --- a/Front/skydivelogs-app/src/app/login-user/login-user.component.ts +++ b/Front/skydivelogs-app/src/app/login-user/login-user.component.ts @@ -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, - private route: ActivatedRoute, - private router: Router, - private authenticationService: AuthenticationService) { + constructor( + private formBuilder: FormBuilder, + private route: ActivatedRoute, + private router: Router, + private authenticationService: AuthenticationService + ) { if (this.authenticationService.currentUserValue) { - this.router.navigate(['/']); + this.router.navigate(["/"]); } } - 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) - .pipe(first()) - .subscribe( - data => { - this.router.navigate([this.returnUrl]); - }, - error => { - this.error = error; - this.loading = false; - } - ); + this.authenticationService + .login( + this.formCtrls["username"].value, + this.formCtrls["password"].value + ) + .pipe(first()) + .subscribe({ + complete: () => this.router.navigate([this.returnUrl]), + error: (error) => { + this.error = error.message; + this.loading = false; + }, + }); } } } diff --git a/Front/skydivelogs-app/src/app/login/login.component.html b/Front/skydivelogs-app/src/app/login/login.component.html index b373540..f712a7a 100644 --- a/Front/skydivelogs-app/src/app/login/login.component.html +++ b/Front/skydivelogs-app/src/app/login/login.component.html @@ -1,18 +1,30 @@
- - - {{ 'Login_Title' | translate }} + + + {{ "Login_Title" | translate }} - + - + - + - + diff --git a/Front/skydivelogs-app/src/app/login/login.component.ts b/Front/skydivelogs-app/src/app/login/login.component.ts index 19093c6..5a57f3d 100644 --- a/Front/skydivelogs-app/src/app/login/login.component.ts +++ b/Front/skydivelogs-app/src/app/login/login.component.ts @@ -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 + selector: "app-login", + templateUrl: "./login.component.html", + styleUrls: ["./login.component.css"], + 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"; } diff --git a/Front/skydivelogs-app/src/app/new-aircraft/new-aircraft.component.ts b/Front/skydivelogs-app/src/app/new-aircraft/new-aircraft.component.ts index 61c4b6e..63731de 100644 --- a/Front/skydivelogs-app/src/app/new-aircraft/new-aircraft.component.ts +++ b/Front/skydivelogs-app/src/app/new-aircraft/new-aircraft.component.ts @@ -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) - .subscribe(() => { - this.serviceComm.refreshData(AddAction.Aircraft); - }); + 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); + }); + } } diff --git a/Front/skydivelogs-app/src/app/new-drop-zone/new-drop-zone.component.ts b/Front/skydivelogs-app/src/app/new-drop-zone/new-drop-zone.component.ts index 71eb6e4..e519f5b 100644 --- a/Front/skydivelogs-app/src/app/new-drop-zone/new-drop-zone.component.ts +++ b/Front/skydivelogs-app/src/app/new-drop-zone/new-drop-zone.component.ts @@ -1,43 +1,72 @@ 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"; @Component({ - selector: "app-new-drop-zone", - templateUrl: "./new-drop-zone.component.html", - styleUrls: ["./new-drop-zone.component.css"], - standalone: false + selector: "app-new-drop-zone", + templateUrl: "./new-drop-zone.component.html", + styleUrls: ["./new-drop-zone.component.css"], + 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 = formData.gps.split(","); @@ -50,16 +79,25 @@ export class NewDropZoneComponent implements OnInit { dzType.push("tunnel"); } - this.dropzoneService.addDropZone(splitGps[0], - splitGps[1], - formData.dzName, - formData.address, - formData.website, - formData.contactMail, - dzType, - false) - .subscribe(() => { - this.serviceComm.refreshData(AddAction.Dropzone); - }); + this.dropzoneService + .addDropZone( + splitGps[0], + splitGps[1], + formData.dzName, + formData.address, + formData.website, + formData.contactMail, + dzType, + false, + ) + .subscribe(() => { + this.serviceComm.refreshData(AddAction.Dropzone); + }); + } + + private updateTitle() { + this.translateService.get("NewDz_Title").subscribe((data) => { + this.serviceComm.updatedComponentTitle(data); + }); } } diff --git a/Front/skydivelogs-app/src/app/new-gear/new-gear.component.ts b/Front/skydivelogs-app/src/app/new-gear/new-gear.component.ts index 3e5e86e..0d26ca6 100644 --- a/Front/skydivelogs-app/src/app/new-gear/new-gear.component.ts +++ b/Front/skydivelogs-app/src/app/new-gear/new-gear.component.ts @@ -1,22 +1,40 @@ 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"; import { AddAction } from "../../models/add-action.enum"; @Component({ - selector: "app-new-gear", - templateUrl: "./new-gear.component.html", - styleUrls: ["./new-gear.component.css"], - standalone: false + selector: "app-new-gear", + templateUrl: "./new-gear.component.html", + styleUrls: ["./new-gear.component.css"], + 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, - formData.manufacturer, - +formData.minSize, - +formData.maxSize, - formData.aad, - formData.mainCanopy, - formData.reserveCanopy) - .subscribe(() => { - this.serviceComm.refreshData(AddAction.Gear); - }); + this.serviceApi + .addGear( + formData.name, + formData.manufacturer, + +formData.minSize, + +formData.maxSize, + formData.aad, + formData.mainCanopy, + formData.reserveCanopy, + ) + .subscribe(() => { + this.serviceComm.refreshData(AddAction.Gear); + }); + } + + private updateTitle() { + this.translateService.get("NewGear_Title").subscribe((data) => { + this.serviceComm.updatedComponentTitle(data); + }); } } diff --git a/Front/skydivelogs-app/src/app/new-jump-type/new-jump-type.component.ts b/Front/skydivelogs-app/src/app/new-jump-type/new-jump-type.component.ts index c9fb29e..86f3c2c 100644 --- a/Front/skydivelogs-app/src/app/new-jump-type/new-jump-type.component.ts +++ b/Front/skydivelogs-app/src/app/new-jump-type/new-jump-type.component.ts @@ -1,34 +1,66 @@ 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"; @Component({ - selector: "app-new-jump-type", - templateUrl: "./new-jump-type.component.html", - styleUrls: ["./new-jump-type.component.css"], - standalone: false + selector: "app-new-jump-type", + templateUrl: "./new-jump-type.component.html", + styleUrls: ["./new-jump-type.component.css"], + 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.serviceComm.refreshData(AddAction.JumpType); - }); + this.jumpTypeService.addJumpType(formData.jumptypeName).subscribe(() => { + this.serviceComm.refreshData(AddAction.JumpType); + }); + } + + private updateTitle() { + this.translateService.get("NewJumpType_Title").subscribe((data) => { + this.serviceComm.updatedComponentTitle(data); + }); } } diff --git a/Front/skydivelogs-app/src/app/new-jump/new-jump.component.html b/Front/skydivelogs-app/src/app/new-jump/new-jump.component.html index 680d2bf..7b640e5 100644 --- a/Front/skydivelogs-app/src/app/new-jump/new-jump.component.html +++ b/Front/skydivelogs-app/src/app/new-jump/new-jump.component.html @@ -1,119 +1,267 @@
- -

{{ 'NewJump_ResetForm' | translate }}

+ +

+ {{ + "NewJump_ResetForm" | translate + }} +

- -
+ + - {{ 'NewJump_ChooseJumpType' | translate }} - - + {{ "NewJump_ChooseJumpType" | translate }} + + - {{jumpType.name}} + {{ jumpType.name }} - - {{ 'NewJump_ChooseAircraft' | translate }} - - + {{ "NewJump_ChooseAircraft" | translate }} + + - {{aircraft.name}} + {{ aircraft.name }} - - {{ 'NewJump_ChooseDz' | translate }} - - - - {{dropZone.name}} - - favorite + {{ "NewJump_ChooseDz" | translate }} + + + + {{ dropZone.name }} + + favorite - - {{ 'NewJump_ChooseGear' | translate }} - - + {{ "NewJump_ChooseGear" | translate }} + + - {{gear.name}} ({{gear.mainCanopy}}) + {{ gear.name }} ({{ gear.mainCanopy }}) - - {{ 'NewJump_Cutaway' | translate }} - {{ 'NewJump_Special' | translate }} + {{ + "NewJump_Cutaway" | translate + }} + {{ + "NewJump_Special" | translate + }} - - + + - - + + - - - - - - - -
- +
diff --git a/Front/skydivelogs-app/src/app/new-jump/new-jump.component.ts b/Front/skydivelogs-app/src/app/new-jump/new-jump.component.ts index dafc885..3d487d1 100644 --- a/Front/skydivelogs-app/src/app/new-jump/new-jump.component.ts +++ b/Front/skydivelogs-app/src/app/new-jump/new-jump.component.ts @@ -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,31 +33,47 @@ 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 { - return formatDate(date, displayFormat.toString(), "en"); + override format(date: Date, displayFormat: Object): string { + return formatDate(date, displayFormat.toString(), "en"); } } @Component({ - selector: "app-new-jump", - templateUrl: "./new-jump.component.html", - styleUrls: ["./new-jump.component.css"], - providers: [ - { provide: DateAdapter, useClass: PickDateAdapter }, - { provide: MAT_DATE_FORMATS, useValue: PICK_FORMATS } - ], - standalone: false + selector: "app-new-jump", + templateUrl: "./new-jump.component.html", + styleUrls: ["./new-jump.component.css"], + providers: [ + { provide: DateAdapter, useClass: PickDateAdapter }, + { provide: MAT_DATE_FORMATS, useValue: PICK_FORMATS }, + ], + imports: [ + TranslateModule, + CommonModule, + RouterLink, + FormsModule, + RouterModule, + MatIconModule, + MatOptionModule, + MatFormFieldModule, + MatCheckboxModule, + MatAutocompleteModule, + MatDatepickerModule, + MatProgressSpinnerModule, + MatFormFieldModule, + ReactiveFormsModule, + MatInputModule, + MatButtonModule, + ], }) export class NewJumpComponent implements OnInit { public beginDate: Date; @@ -66,26 +98,28 @@ export class NewJumpComponent implements OnInit { private listOfDropZone: Array; public maxDate: Date; - constructor(private serviceComm: ServiceComm, - private serviceJump: JumpService, - private serviceJumpType: JumpTypeService, - private serviceAircraft: AircraftService, - private serviceDropzone: DropzoneService, - private serviceGear: GearService, - private dateService: DateService, - private translateService: TranslateService, - private statsService : StatsService) {} + constructor( + private serviceComm: ServiceComm, + private serviceJump: JumpService, + private serviceJumpType: JumpTypeService, + private serviceAircraft: AircraftService, + private serviceDropzone: DropzoneService, + private serviceGear: GearService, + private dateService: DateService, + private translateService: TranslateService, + private statsService: StatsService + ) {} ngOnInit() { - this.serviceComm.forceTranslateTitle.subscribe((data)=> { - if (data === true){ + this.serviceComm.forceTranslateTitle.subscribe((data) => { + if (data === true) { this.updateTitle(); } }); this.updateTitle(); this.maxDate = this.dateService.addDays(new Date(), 1); - + this.pendingAddRequest = false; this.initForm(); this.getListOfJumpTypes(); @@ -94,87 +128,92 @@ export class NewJumpComponent implements OnInit { onFormSubmit() { this.pendingAddRequest = true; - this.serviceJump.addListOfJump(this.selectedJumpType.id, - this.selectedAircraft.id, - this.selectedDz.id, - this.selectedGear.id, - this.withCutaway === undefined ? false : this.withCutaway, - this.beginDate, - this.endDate, - this.exitAltitude, - this.deployAltitude, - this.countOfJumps, - this.comments, - this.isSpecial === undefined ? false : this.isSpecial) - .subscribe(() => { - this.statsService.resetStats(); - this.comments = undefined; - this.withCutaway = false; - this.isSpecial = false; + this.serviceJump + .addListOfJump( + this.selectedJumpType.id, + this.selectedAircraft.id, + this.selectedDz.id, + this.selectedGear.id, + this.withCutaway === undefined ? false : this.withCutaway, + this.beginDate, + this.endDate, + this.exitAltitude, + this.deployAltitude, + this.countOfJumps, + this.comments, + this.isSpecial === undefined ? false : this.isSpecial + ) + .subscribe(() => { + this.statsService.resetStats(); + this.comments = undefined; + this.withCutaway = false; + this.isSpecial = false; - if (this.resetForm === true) { - this.initForm(); - } - this.pendingAddRequest = false; - }); + if (this.resetForm === true) { + this.initForm(); + } + this.pendingAddRequest = false; + }); } public isValidatedForm(): boolean { - return (this.selectedDz !== undefined && - this.selectedDz.id !== undefined && - this.selectedGear !== undefined && - this.selectedGear.id !== undefined && - this.selectedAircraft !== undefined && - this.selectedAircraft.id !== undefined && - this.selectedJumpType !== undefined && - this.selectedJumpType.id !== undefined && - this.exitAltitude !== undefined && - typeof this.exitAltitude === "number" && - this.deployAltitude !== undefined && - typeof this.deployAltitude === "number" && - this.countOfJumps !== undefined && - typeof this.countOfJumps === "number"); + return ( + this.selectedDz !== undefined && + this.selectedDz.id !== undefined && + this.selectedGear !== undefined && + this.selectedGear.id !== undefined && + this.selectedAircraft !== undefined && + this.selectedAircraft.id !== undefined && + this.selectedJumpType !== undefined && + this.selectedJumpType.id !== undefined && + this.exitAltitude !== undefined && + typeof this.exitAltitude === "number" && + this.deployAltitude !== undefined && + typeof this.deployAltitude === "number" && + this.countOfJumps !== undefined && + typeof this.countOfJumps === "number" + ); } private getListOfJumpTypes() { - this.serviceJumpType.getListOfJumpTypes() - .subscribe((data) => { - data.sort((a, b) => a.name.localeCompare(b.name)); - this.listOfJumpType = data; - this.countDatasLoaded = 1; + this.serviceJumpType.getListOfJumpTypes().subscribe((data) => { + data.sort((a, b) => a.name.localeCompare(b.name)); + this.listOfJumpType = data; + this.countDatasLoaded = 1; - this.getListOfAircrafts(); - this.getListOfDropZones(); - this.getListOfGears(); - }); + this.getListOfAircrafts(); + this.getListOfDropZones(); + this.getListOfGears(); + }); } private getListOfAircrafts() { - this.serviceAircraft.getListOfAircrafts(true) - .subscribe((data) => { - data.sort((a, b) => a.name.localeCompare(b.name)); - this.listOfAircraft = data; - this.countDatasLoaded++; - }); + this.serviceAircraft.getListOfAircrafts(true).subscribe((data) => { + data.sort((a, b) => a.name.localeCompare(b.name)); + this.listOfAircraft = data; + this.countDatasLoaded++; + }); } private getListOfDropZones() { - this.serviceDropzone.getListOfDropZones(true) - .subscribe((data) => { - data.sort((a, b) => (b.isFavorite ? 1 : 0) - (a.isFavorite ? 1 : 0) || a.name.localeCompare(b.name)); - this.listOfDropZone = data; - this.listOfFilteredDropZone = data; - this.countDatasLoaded++; - }); + this.serviceDropzone.getListOfDropZones(true).subscribe((data) => { + data.sort( + (a, b) => + (b.isFavorite ? 1 : 0) - (a.isFavorite ? 1 : 0) || + a.name.localeCompare(b.name) + ); + this.listOfDropZone = data; + this.listOfFilteredDropZone = data; + this.countDatasLoaded++; + }); } private getListOfGears() { - this.serviceGear.getListOfGears() - .subscribe((data) => { - data.sort((a, b) => b.id - a.id); - this.listOfGear = data; - this.countDatasLoaded++; - }); + this.serviceGear.getListOfGears().subscribe((data) => { + data.sort((a, b) => b.id - a.id); + this.listOfGear = data; + this.countDatasLoaded++; + }); } private initForm() { @@ -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); + }); } } diff --git a/Front/skydivelogs-app/src/app/new-tunnel-flight/new-tunnel-flight.component.html b/Front/skydivelogs-app/src/app/new-tunnel-flight/new-tunnel-flight.component.html index f17874c..86de9b0 100644 --- a/Front/skydivelogs-app/src/app/new-tunnel-flight/new-tunnel-flight.component.html +++ b/Front/skydivelogs-app/src/app/new-tunnel-flight/new-tunnel-flight.component.html @@ -1,66 +1,145 @@
- +
-
+ - {{ 'NewTunnelFlight_ChooseJumpType' | translate }} - - + {{ "NewTunnelFlight_ChooseJumpType" | translate }} + + - {{jumpType.name}} + {{ jumpType.name }} - - {{ 'NewTunnelFlight_ChooseTunnel' | translate }} - - - - {{tunnel.name}} + {{ "NewTunnelFlight_ChooseTunnel" | translate }} + + + + {{ tunnel.name }} - - {{ 'NewTunnelFlight_Date_Lbl' | translate }} - - + {{ "NewTunnelFlight_Date_Lbl" | translate }} + + - {{ 'NewTunnelFlight_Minutes_Lbl' | translate }} - - - {{ 'NewTunnelFlight_Comments_Lbl' | translate }} - -
- +
-
\ No newline at end of file +
diff --git a/Front/skydivelogs-app/src/app/new-tunnel-flight/new-tunnel-flight.component.ts b/Front/skydivelogs-app/src/app/new-tunnel-flight/new-tunnel-flight.component.ts index 466a291..7bf9e5c 100644 --- a/Front/skydivelogs-app/src/app/new-tunnel-flight/new-tunnel-flight.component.ts +++ b/Front/skydivelogs-app/src/app/new-tunnel-flight/new-tunnel-flight.component.ts @@ -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'], - providers: [ - { provide: DateAdapter, useClass: PickDateAdapter }, - { provide: MAT_DATE_FORMATS, useValue: PICK_FORMATS } - ], - standalone: false + 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 }, + ], + imports: [ + TranslateModule, + CommonModule, + RouterModule, + RouterLink, + FormsModule, + MatFormFieldModule, + ReactiveFormsModule, + MatAutocompleteModule, + MatInputModule, + MatButtonModule, + MatIconModule, + MatFormFieldModule, + MatOptionModule, + MatDatepickerModule, + MatProgressSpinnerModule, + ], }) export class NewTunnelFlightComponent implements OnInit { public flightDate: Date; @@ -51,12 +82,14 @@ export class NewTunnelFlightComponent implements OnInit { public listOfJumpType: Array; public maxDate: Date; - constructor(private serviceComm: ServiceComm, - private serviceTunnel: TunnelService, - private serviceTunnelFlight: TunnelFlightService, - private serviceJumpType: JumpTypeService, - private translateService: TranslateService, - private dateService: DateService) { } + constructor( + private serviceComm: ServiceComm, + private serviceTunnel: TunnelService, + private serviceTunnelFlight: TunnelFlightService, + private serviceJumpType: JumpTypeService, + private translateService: TranslateService, + private dateService: DateService + ) {} ngOnInit() { this.serviceComm.forceTranslateTitle.subscribe((data) => { @@ -77,45 +110,48 @@ export class NewTunnelFlightComponent implements OnInit { public onFormSubmit() { this.pendingAddRequest = true; - this.serviceTunnelFlight.addFlight(this.selectedTunnel.id, - this.selectedJumpType.id, - this.flightDate, - this.minutesOfFlight, - this.comments) - .subscribe(() => { - this.comments = undefined; + this.serviceTunnelFlight + .addFlight( + this.selectedTunnel.id, + this.selectedJumpType.id, + this.flightDate, + this.minutesOfFlight, + this.comments + ) + .subscribe(() => { + this.comments = undefined; - if (this.resetForm === true) { - this.initForm(); - } - this.pendingAddRequest = false; - }); + if (this.resetForm === true) { + this.initForm(); + } + this.pendingAddRequest = false; + }); } public isValidatedForm(): boolean { - return (this.selectedTunnel !== undefined && - this.selectedTunnel.id !== undefined && - this.minutesOfFlight !== undefined && - typeof this.minutesOfFlight === "number"); + return ( + this.selectedTunnel !== undefined && + this.selectedTunnel.id !== undefined && + this.minutesOfFlight !== undefined && + typeof this.minutesOfFlight === "number" + ); } private getListOfTunnels() { - this.serviceTunnel.getListOfTunnels() - .subscribe((data) => { - data.sort((a, b) => a.name.localeCompare(b.name)); - this.listOfTunnel = data; - this.listOfFilteredTunnel = data; - this.countDatasLoaded++; - }); + this.serviceTunnel.getListOfTunnels().subscribe((data) => { + data.sort((a, b) => a.name.localeCompare(b.name)); + this.listOfTunnel = data; + this.listOfFilteredTunnel = data; + this.countDatasLoaded++; + }); } private getListOfJumpTypes() { - this.serviceJumpType.getListOfJumpTypesForTunnel() - .subscribe((data) => { - data.sort((a, b) => a.name.localeCompare(b.name)); - this.listOfJumpType = data; - this.countDatasLoaded++; - }); + this.serviceJumpType.getListOfJumpTypesForTunnel().subscribe((data) => { + data.sort((a, b) => a.name.localeCompare(b.name)); + this.listOfJumpType = data; + this.countDatasLoaded++; + }); } public notLoadingToDisplay(): boolean { @@ -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) { diff --git a/Front/skydivelogs-app/src/app/summary/summary.component.html b/Front/skydivelogs-app/src/app/summary/summary.component.html index 4fc6ceb..967a7fe 100644 --- a/Front/skydivelogs-app/src/app/summary/summary.component.html +++ b/Front/skydivelogs-app/src/app/summary/summary.component.html @@ -21,8 +21,8 @@ aria-label="Force the refresh of the stats" style="cursor: pointer" (click)="refreshStats()" - >cached + svgIcon="reset" + >
; @@ -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(); - 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(); + 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 } diff --git a/Front/skydivelogs-app/src/app/user-profile/user-profile.component.html b/Front/skydivelogs-app/src/app/user-profile/user-profile.component.html index 5ce4c9c..ce4b431 100644 --- a/Front/skydivelogs-app/src/app/user-profile/user-profile.component.html +++ b/Front/skydivelogs-app/src/app/user-profile/user-profile.component.html @@ -26,7 +26,7 @@

- +

Current password @@ -39,8 +39,10 @@

- - + + diff --git a/Front/skydivelogs-app/src/app/user-profile/user-profile.component.ts b/Front/skydivelogs-app/src/app/user-profile/user-profile.component.ts index 27553f6..8b1cca5 100644 --- a/Front/skydivelogs-app/src/app/user-profile/user-profile.component.ts +++ b/Front/skydivelogs-app/src/app/user-profile/user-profile.component.ts @@ -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" }, ); } @@ -60,56 +94,62 @@ export class UserProfileComponent implements OnInit { private calculTailleVoile() { let tailleVoile = new Map>(); - tailleVoile.set("60", [ 175, 161, 147, 133, 124, 115, 107, 97, 89 ]); - tailleVoile.set("61", [ 178, 163, 149, 135, 126, 116, 108, 98, 90 ]); - tailleVoile.set("62", [ 180, 166, 151, 137, 127, 118, 109, 99, 91 ]); - tailleVoile.set("63", [ 183, 168, 153, 138, 129, 119, 111, 100, 91 ]); - tailleVoile.set("64", [ 185, 170, 155, 140, 130, 121, 112, 101, 92 ]); - tailleVoile.set("65", [ 188, 173, 157, 142, 132, 122, 113, 102, 93 ]); - tailleVoile.set("66", [ 190, 175, 159, 144, 134, 123, 114, 103, 94 ]); - tailleVoile.set("67", [ 193, 177, 161, 146, 135, 125, 116, 104, 94 ]); - tailleVoile.set("68", [ 195, 179, 164, 147, 137, 126, 117, 105, 95 ]); - tailleVoile.set("69", [ 198, 182, 166, 149, 138, 128, 118, 106, 96 ]); - tailleVoile.set("70", [ 200, 184, 168, 151, 140, 129, 119, 107, 96 ]); - tailleVoile.set("71", [ 203, 186, 170, 153, 142, 130, 120, 107, 97 ]); - tailleVoile.set("72", [ 205, 189, 172, 155, 143, 132, 121, 108, 98 ]); - tailleVoile.set("73", [ 208, 191, 174, 156, 145, 133, 123, 109, 99 ]); - tailleVoile.set("74", [ 210, 193, 176, 158, 146, 134, 124, 110, 99 ]); - tailleVoile.set("75", [ 213, 196, 178, 160, 148, 136, 125, 111, 100 ]); - tailleVoile.set("76", [ 215, 198, 180, 162, 150, 137, 126, 112, 101 ]); - tailleVoile.set("77", [ 218, 200, 182, 163, 151, 139, 127, 113, 101 ]); - tailleVoile.set("78", [ 220, 202, 184, 165, 153, 140, 128, 114, 102 ]); - tailleVoile.set("79", [ 223, 205, 186, 167, 154, 141, 129, 115, 103 ]); - tailleVoile.set("80", [ 225, 207, 188, 169, 156, 143, 131, 115, 103 ]); - tailleVoile.set("81", [ 228, 209, 190, 170, 157, 144, 132, 116, 104 ]); - tailleVoile.set("82", [ 230, 212, 192, 172, 159, 145, 133, 117, 104 ]); - tailleVoile.set("83", [ 233, 214, 194, 174, 160, 146, 134, 118, 105 ]); - tailleVoile.set("84", [ 235, 216, 196, 176, 162, 148, 135, 119, 106 ]); - tailleVoile.set("85", [ 238, 219, 198, 177, 163, 149, 136, 120, 106 ]); - tailleVoile.set("86", [ 240, 221, 201, 179, 165, 150, 137, 120, 107 ]); - tailleVoile.set("87", [ 243, 223, 203, 181, 166, 152, 138, 121, 108 ]); - tailleVoile.set("88", [ 245, 225, 205, 183, 168, 153, 139, 122, 108 ]); - tailleVoile.set("89", [ 248, 228, 207, 184, 170, 154, 140, 123, 109 ]); - tailleVoile.set("90", [ 250, 230, 209, 186, 171, 156, 141, 124, 109 ]); - tailleVoile.set("91", [ 253, 232, 211, 188, 173, 157, 143, 124, 110 ]); - tailleVoile.set("92", [ 255, 235, 213, 190, 174, 158, 144, 125, 110 ]); - tailleVoile.set("93", [ 258, 237, 215, 191, 176, 159, 145, 126, 111 ]); - tailleVoile.set("94", [ 260, 239, 217, 193, 177, 161, 146, 127, 112 ]); - tailleVoile.set("95", [ 263, 242, 219, 195, 179, 162, 147, 128, 112 ]); - tailleVoile.set("96", [ 265, 244, 221, 197, 180, 163, 148, 128, 113 ]); - tailleVoile.set("97", [ 268, 246, 223, 198, 182, 164, 149, 129, 113 ]); - tailleVoile.set("98", [ 270, 248, 225, 200, 183, 166, 150, 130, 114 ]); - tailleVoile.set("99", [ 273, 251, 227, 202, 185, 167, 151, 131, 114 ]); - tailleVoile.set("100", [ 275, 253, 229, 203, 186, 168, 152, 131, 115 ]); - tailleVoile.set("101", [ 278, 255, 231, 205, 188, 169, 153, 132, 115 ]); - tailleVoile.set("102", [ 280, 258, 233, 207, 189, 171, 154, 133, 116 ]); - tailleVoile.set("103", [ 283, 260, 235, 209, 190, 172, 155, 134, 116 ]); - tailleVoile.set("104", [ 285, 262, 237, 210, 192, 173, 156, 134, 117 ]); - tailleVoile.set("105", [ 288, 265, 239, 212, 193, 174, 157, 135, 118 ]); - tailleVoile.set("106", [ 290, 267, 241, 214, 195, 175, 158, 136, 118 ]); - tailleVoile.set("107", [ 293, 269, 243, 215, 196, 177, 159, 136, 119 ]); - tailleVoile.set("108", [ 295, 271, 245, 217, 198, 178, 160, 137, 119 ]); - tailleVoile.set("109", [ 298, 274, 247, 219, 199, 179, 161, 138, 120 ]); - tailleVoile.set("110", [ 300, 276, 249, 220, 201, 180, 162, 138, 120 ]); + tailleVoile.set("60", [175, 161, 147, 133, 124, 115, 107, 97, 89]); + tailleVoile.set("61", [178, 163, 149, 135, 126, 116, 108, 98, 90]); + tailleVoile.set("62", [180, 166, 151, 137, 127, 118, 109, 99, 91]); + tailleVoile.set("63", [183, 168, 153, 138, 129, 119, 111, 100, 91]); + tailleVoile.set("64", [185, 170, 155, 140, 130, 121, 112, 101, 92]); + tailleVoile.set("65", [188, 173, 157, 142, 132, 122, 113, 102, 93]); + tailleVoile.set("66", [190, 175, 159, 144, 134, 123, 114, 103, 94]); + tailleVoile.set("67", [193, 177, 161, 146, 135, 125, 116, 104, 94]); + tailleVoile.set("68", [195, 179, 164, 147, 137, 126, 117, 105, 95]); + tailleVoile.set("69", [198, 182, 166, 149, 138, 128, 118, 106, 96]); + tailleVoile.set("70", [200, 184, 168, 151, 140, 129, 119, 107, 96]); + tailleVoile.set("71", [203, 186, 170, 153, 142, 130, 120, 107, 97]); + tailleVoile.set("72", [205, 189, 172, 155, 143, 132, 121, 108, 98]); + tailleVoile.set("73", [208, 191, 174, 156, 145, 133, 123, 109, 99]); + tailleVoile.set("74", [210, 193, 176, 158, 146, 134, 124, 110, 99]); + tailleVoile.set("75", [213, 196, 178, 160, 148, 136, 125, 111, 100]); + tailleVoile.set("76", [215, 198, 180, 162, 150, 137, 126, 112, 101]); + tailleVoile.set("77", [218, 200, 182, 163, 151, 139, 127, 113, 101]); + tailleVoile.set("78", [220, 202, 184, 165, 153, 140, 128, 114, 102]); + tailleVoile.set("79", [223, 205, 186, 167, 154, 141, 129, 115, 103]); + tailleVoile.set("80", [225, 207, 188, 169, 156, 143, 131, 115, 103]); + tailleVoile.set("81", [228, 209, 190, 170, 157, 144, 132, 116, 104]); + tailleVoile.set("82", [230, 212, 192, 172, 159, 145, 133, 117, 104]); + tailleVoile.set("83", [233, 214, 194, 174, 160, 146, 134, 118, 105]); + tailleVoile.set("84", [235, 216, 196, 176, 162, 148, 135, 119, 106]); + tailleVoile.set("85", [238, 219, 198, 177, 163, 149, 136, 120, 106]); + tailleVoile.set("86", [240, 221, 201, 179, 165, 150, 137, 120, 107]); + tailleVoile.set("87", [243, 223, 203, 181, 166, 152, 138, 121, 108]); + tailleVoile.set("88", [245, 225, 205, 183, 168, 153, 139, 122, 108]); + tailleVoile.set("89", [248, 228, 207, 184, 170, 154, 140, 123, 109]); + tailleVoile.set("90", [250, 230, 209, 186, 171, 156, 141, 124, 109]); + tailleVoile.set("91", [253, 232, 211, 188, 173, 157, 143, 124, 110]); + tailleVoile.set("92", [255, 235, 213, 190, 174, 158, 144, 125, 110]); + tailleVoile.set("93", [258, 237, 215, 191, 176, 159, 145, 126, 111]); + tailleVoile.set("94", [260, 239, 217, 193, 177, 161, 146, 127, 112]); + tailleVoile.set("95", [263, 242, 219, 195, 179, 162, 147, 128, 112]); + tailleVoile.set("96", [265, 244, 221, 197, 180, 163, 148, 128, 113]); + tailleVoile.set("97", [268, 246, 223, 198, 182, 164, 149, 129, 113]); + tailleVoile.set("98", [270, 248, 225, 200, 183, 166, 150, 130, 114]); + tailleVoile.set("99", [273, 251, 227, 202, 185, 167, 151, 131, 114]); + tailleVoile.set("100", [275, 253, 229, 203, 186, 168, 152, 131, 115]); + tailleVoile.set("101", [278, 255, 231, 205, 188, 169, 153, 132, 115]); + tailleVoile.set("102", [280, 258, 233, 207, 189, 171, 154, 133, 116]); + tailleVoile.set("103", [283, 260, 235, 209, 190, 172, 155, 134, 116]); + tailleVoile.set("104", [285, 262, 237, 210, 192, 173, 156, 134, 117]); + tailleVoile.set("105", [288, 265, 239, 212, 193, 174, 157, 135, 118]); + tailleVoile.set("106", [290, 267, 241, 214, 195, 175, 158, 136, 118]); + tailleVoile.set("107", [293, 269, 243, 215, 196, 177, 159, 136, 119]); + tailleVoile.set("108", [295, 271, 245, 217, 198, 178, 160, 137, 119]); + tailleVoile.set("109", [298, 274, 247, 219, 199, 179, 161, 138, 120]); + tailleVoile.set("110", [300, 276, 249, 220, 201, 180, 162, 138, 120]); + } + + private updateTitle() { + this.translateService.get("UserProfile_Title").subscribe((data) => { + this.serviceComm.updatedComponentTitle(data); + }); } } diff --git a/Front/skydivelogs-app/src/assets/css/Material-Icons.css b/Front/skydivelogs-app/src/assets/css/Material-Icons.css deleted file mode 100644 index dfb4526..0000000 --- a/Front/skydivelogs-app/src/assets/css/Material-Icons.css +++ /dev/null @@ -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'; -} diff --git a/Front/skydivelogs-app/src/assets/css/Roboto.css b/Front/skydivelogs-app/src/assets/css/Roboto.css deleted file mode 100644 index 879effc..0000000 --- a/Front/skydivelogs-app/src/assets/css/Roboto.css +++ /dev/null @@ -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; -} diff --git a/Front/skydivelogs-app/src/assets/css/new-theme.scss b/Front/skydivelogs-app/src/assets/css/new-theme.scss index 02fcdcc..58363a1 100644 --- a/Front/skydivelogs-app/src/assets/css/new-theme.scss +++ b/Front/skydivelogs-app/src/assets/css/new-theme.scss @@ -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 `` of html */ +/* + + +OR + + +*/ @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); - } - */ \ No newline at end of file +} diff --git a/Front/skydivelogs-app/src/assets/font/300/Cyrillic-ext.woff2 b/Front/skydivelogs-app/src/assets/font/300/Cyrillic-ext.woff2 deleted file mode 100644 index 082312b..0000000 Binary files a/Front/skydivelogs-app/src/assets/font/300/Cyrillic-ext.woff2 and /dev/null differ diff --git a/Front/skydivelogs-app/src/assets/font/300/Cyrillic.woff2 b/Front/skydivelogs-app/src/assets/font/300/Cyrillic.woff2 deleted file mode 100644 index 88ef721..0000000 Binary files a/Front/skydivelogs-app/src/assets/font/300/Cyrillic.woff2 and /dev/null differ diff --git a/Front/skydivelogs-app/src/assets/font/300/Greek-ext.woff2 b/Front/skydivelogs-app/src/assets/font/300/Greek-ext.woff2 deleted file mode 100644 index 6f8c2a7..0000000 Binary files a/Front/skydivelogs-app/src/assets/font/300/Greek-ext.woff2 and /dev/null differ diff --git a/Front/skydivelogs-app/src/assets/font/300/Greek.woff2 b/Front/skydivelogs-app/src/assets/font/300/Greek.woff2 deleted file mode 100644 index f1e82f1..0000000 Binary files a/Front/skydivelogs-app/src/assets/font/300/Greek.woff2 and /dev/null differ diff --git a/Front/skydivelogs-app/src/assets/font/300/Latin-ext.woff2 b/Front/skydivelogs-app/src/assets/font/300/Latin-ext.woff2 deleted file mode 100644 index f113c08..0000000 Binary files a/Front/skydivelogs-app/src/assets/font/300/Latin-ext.woff2 and /dev/null differ diff --git a/Front/skydivelogs-app/src/assets/font/300/Latin.woff2 b/Front/skydivelogs-app/src/assets/font/300/Latin.woff2 deleted file mode 100644 index 46445bf..0000000 Binary files a/Front/skydivelogs-app/src/assets/font/300/Latin.woff2 and /dev/null differ diff --git a/Front/skydivelogs-app/src/assets/font/300/Vietnamese.woff2 b/Front/skydivelogs-app/src/assets/font/300/Vietnamese.woff2 deleted file mode 100644 index 99c38c0..0000000 Binary files a/Front/skydivelogs-app/src/assets/font/300/Vietnamese.woff2 and /dev/null differ diff --git a/Front/skydivelogs-app/src/assets/font/400/Cyrillic-ext.woff2 b/Front/skydivelogs-app/src/assets/font/400/Cyrillic-ext.woff2 deleted file mode 100644 index c6d7d06..0000000 Binary files a/Front/skydivelogs-app/src/assets/font/400/Cyrillic-ext.woff2 and /dev/null differ diff --git a/Front/skydivelogs-app/src/assets/font/400/Cyrillic.woff2 b/Front/skydivelogs-app/src/assets/font/400/Cyrillic.woff2 deleted file mode 100644 index f1b8ed7..0000000 Binary files a/Front/skydivelogs-app/src/assets/font/400/Cyrillic.woff2 and /dev/null differ diff --git a/Front/skydivelogs-app/src/assets/font/400/Greek-ext.woff2 b/Front/skydivelogs-app/src/assets/font/400/Greek-ext.woff2 deleted file mode 100644 index 84fcce1..0000000 Binary files a/Front/skydivelogs-app/src/assets/font/400/Greek-ext.woff2 and /dev/null differ diff --git a/Front/skydivelogs-app/src/assets/font/400/Greek.woff2 b/Front/skydivelogs-app/src/assets/font/400/Greek.woff2 deleted file mode 100644 index fa0d664..0000000 Binary files a/Front/skydivelogs-app/src/assets/font/400/Greek.woff2 and /dev/null differ diff --git a/Front/skydivelogs-app/src/assets/font/400/Latin-ext.woff2 b/Front/skydivelogs-app/src/assets/font/400/Latin-ext.woff2 deleted file mode 100644 index e2f7d27..0000000 Binary files a/Front/skydivelogs-app/src/assets/font/400/Latin-ext.woff2 and /dev/null differ diff --git a/Front/skydivelogs-app/src/assets/font/400/Latin.woff2 b/Front/skydivelogs-app/src/assets/font/400/Latin.woff2 deleted file mode 100644 index ebe1795..0000000 Binary files a/Front/skydivelogs-app/src/assets/font/400/Latin.woff2 and /dev/null differ diff --git a/Front/skydivelogs-app/src/assets/font/400/Vietnamese.woff2 b/Front/skydivelogs-app/src/assets/font/400/Vietnamese.woff2 deleted file mode 100644 index d5ca3ce..0000000 Binary files a/Front/skydivelogs-app/src/assets/font/400/Vietnamese.woff2 and /dev/null differ diff --git a/Front/skydivelogs-app/src/assets/font/500/Cyrillic-ext.woff2 b/Front/skydivelogs-app/src/assets/font/500/Cyrillic-ext.woff2 deleted file mode 100644 index e6f9427..0000000 Binary files a/Front/skydivelogs-app/src/assets/font/500/Cyrillic-ext.woff2 and /dev/null differ diff --git a/Front/skydivelogs-app/src/assets/font/500/Cyrillic.woff2 b/Front/skydivelogs-app/src/assets/font/500/Cyrillic.woff2 deleted file mode 100644 index f1bfb05..0000000 Binary files a/Front/skydivelogs-app/src/assets/font/500/Cyrillic.woff2 and /dev/null differ diff --git a/Front/skydivelogs-app/src/assets/font/500/Greek-ext.woff2 b/Front/skydivelogs-app/src/assets/font/500/Greek-ext.woff2 deleted file mode 100644 index 67e5402..0000000 Binary files a/Front/skydivelogs-app/src/assets/font/500/Greek-ext.woff2 and /dev/null differ diff --git a/Front/skydivelogs-app/src/assets/font/500/Greek.woff2 b/Front/skydivelogs-app/src/assets/font/500/Greek.woff2 deleted file mode 100644 index ccd9633..0000000 Binary files a/Front/skydivelogs-app/src/assets/font/500/Greek.woff2 and /dev/null differ diff --git a/Front/skydivelogs-app/src/assets/font/500/Latin-ext.woff2 b/Front/skydivelogs-app/src/assets/font/500/Latin-ext.woff2 deleted file mode 100644 index 7ef9a92..0000000 Binary files a/Front/skydivelogs-app/src/assets/font/500/Latin-ext.woff2 and /dev/null differ diff --git a/Front/skydivelogs-app/src/assets/font/500/Latin.woff2 b/Front/skydivelogs-app/src/assets/font/500/Latin.woff2 deleted file mode 100644 index ce795fa..0000000 Binary files a/Front/skydivelogs-app/src/assets/font/500/Latin.woff2 and /dev/null differ diff --git a/Front/skydivelogs-app/src/assets/font/500/Vietnamese.woff2 b/Front/skydivelogs-app/src/assets/font/500/Vietnamese.woff2 deleted file mode 100644 index 01c0cc8..0000000 Binary files a/Front/skydivelogs-app/src/assets/font/500/Vietnamese.woff2 and /dev/null differ diff --git a/Front/skydivelogs-app/src/assets/i18n/en.json b/Front/skydivelogs-app/src/assets/i18n/en.json index 2530eb2..24e7e96 100644 --- a/Front/skydivelogs-app/src/assets/i18n/en.json +++ b/Front/skydivelogs-app/src/assets/i18n/en.json @@ -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", diff --git a/Front/skydivelogs-app/src/assets/i18n/fr.json b/Front/skydivelogs-app/src/assets/i18n/fr.json index d03cdd1..a828ff1 100644 --- a/Front/skydivelogs-app/src/assets/i18n/fr.json +++ b/Front/skydivelogs-app/src/assets/i18n/fr.json @@ -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", diff --git a/Front/skydivelogs-app/src/assets/icon/account.svg b/Front/skydivelogs-app/src/assets/icon/account.svg new file mode 100644 index 0000000..6d5c9c0 --- /dev/null +++ b/Front/skydivelogs-app/src/assets/icon/account.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/skydivelogs-app/src/assets/icon/add.svg b/Front/skydivelogs-app/src/assets/icon/add.svg new file mode 100644 index 0000000..020cc3d --- /dev/null +++ b/Front/skydivelogs-app/src/assets/icon/add.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/skydivelogs-app/src/assets/icon/aircraft.svg b/Front/skydivelogs-app/src/assets/icon/aircraft.svg new file mode 100644 index 0000000..47895c8 --- /dev/null +++ b/Front/skydivelogs-app/src/assets/icon/aircraft.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/skydivelogs-app/src/assets/icon/celebration.svg b/Front/skydivelogs-app/src/assets/icon/celebration.svg new file mode 100644 index 0000000..0b63c15 --- /dev/null +++ b/Front/skydivelogs-app/src/assets/icon/celebration.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/skydivelogs-app/src/assets/icon/close.svg b/Front/skydivelogs-app/src/assets/icon/close.svg new file mode 100644 index 0000000..854953c --- /dev/null +++ b/Front/skydivelogs-app/src/assets/icon/close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/skydivelogs-app/src/assets/icon/delete.svg b/Front/skydivelogs-app/src/assets/icon/delete.svg new file mode 100644 index 0000000..172f367 --- /dev/null +++ b/Front/skydivelogs-app/src/assets/icon/delete.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/skydivelogs-app/src/assets/icon/dz.svg b/Front/skydivelogs-app/src/assets/icon/dz.svg new file mode 100644 index 0000000..12bb30d --- /dev/null +++ b/Front/skydivelogs-app/src/assets/icon/dz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/skydivelogs-app/src/assets/icon/edit.svg b/Front/skydivelogs-app/src/assets/icon/edit.svg new file mode 100644 index 0000000..826f83e --- /dev/null +++ b/Front/skydivelogs-app/src/assets/icon/edit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/skydivelogs-app/src/assets/icon/fan.svg b/Front/skydivelogs-app/src/assets/icon/fan.svg new file mode 100644 index 0000000..4de42cd --- /dev/null +++ b/Front/skydivelogs-app/src/assets/icon/fan.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/skydivelogs-app/src/assets/icon/favorite.svg b/Front/skydivelogs-app/src/assets/icon/favorite.svg new file mode 100644 index 0000000..60caff0 --- /dev/null +++ b/Front/skydivelogs-app/src/assets/icon/favorite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/skydivelogs-app/src/assets/icon/file_upload.svg b/Front/skydivelogs-app/src/assets/icon/file_upload.svg new file mode 100644 index 0000000..7854949 --- /dev/null +++ b/Front/skydivelogs-app/src/assets/icon/file_upload.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/skydivelogs-app/src/assets/icon/flight_land.svg b/Front/skydivelogs-app/src/assets/icon/flight_land.svg new file mode 100644 index 0000000..16fbf98 --- /dev/null +++ b/Front/skydivelogs-app/src/assets/icon/flight_land.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/skydivelogs-app/src/assets/icon/gear.svg b/Front/skydivelogs-app/src/assets/icon/gear.svg new file mode 100644 index 0000000..1e79e22 --- /dev/null +++ b/Front/skydivelogs-app/src/assets/icon/gear.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/skydivelogs-app/src/assets/icon/info.svg b/Front/skydivelogs-app/src/assets/icon/info.svg new file mode 100644 index 0000000..9ae001c --- /dev/null +++ b/Front/skydivelogs-app/src/assets/icon/info.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/skydivelogs-app/src/assets/icon/link.svg b/Front/skydivelogs-app/src/assets/icon/link.svg new file mode 100644 index 0000000..c30d6a0 --- /dev/null +++ b/Front/skydivelogs-app/src/assets/icon/link.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/skydivelogs-app/src/assets/icon/list.svg b/Front/skydivelogs-app/src/assets/icon/list.svg new file mode 100644 index 0000000..e0c1a44 --- /dev/null +++ b/Front/skydivelogs-app/src/assets/icon/list.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/skydivelogs-app/src/assets/icon/logout.svg b/Front/skydivelogs-app/src/assets/icon/logout.svg new file mode 100644 index 0000000..e1f576a --- /dev/null +++ b/Front/skydivelogs-app/src/assets/icon/logout.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/skydivelogs-app/src/assets/icon/mail.svg b/Front/skydivelogs-app/src/assets/icon/mail.svg new file mode 100644 index 0000000..ba8e68d --- /dev/null +++ b/Front/skydivelogs-app/src/assets/icon/mail.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/skydivelogs-app/src/assets/icon/map.svg b/Front/skydivelogs-app/src/assets/icon/map.svg new file mode 100644 index 0000000..87eb846 --- /dev/null +++ b/Front/skydivelogs-app/src/assets/icon/map.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/skydivelogs-app/src/assets/icon/menu.svg b/Front/skydivelogs-app/src/assets/icon/menu.svg new file mode 100644 index 0000000..c375ef7 --- /dev/null +++ b/Front/skydivelogs-app/src/assets/icon/menu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/skydivelogs-app/src/assets/icon/not_favorite.svg b/Front/skydivelogs-app/src/assets/icon/not_favorite.svg new file mode 100644 index 0000000..2f0669d --- /dev/null +++ b/Front/skydivelogs-app/src/assets/icon/not_favorite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/skydivelogs-app/src/assets/icon/note.svg b/Front/skydivelogs-app/src/assets/icon/note.svg new file mode 100644 index 0000000..64738f6 --- /dev/null +++ b/Front/skydivelogs-app/src/assets/icon/note.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/skydivelogs-app/src/assets/icon/reset.svg b/Front/skydivelogs-app/src/assets/icon/reset.svg new file mode 100644 index 0000000..dcb3919 --- /dev/null +++ b/Front/skydivelogs-app/src/assets/icon/reset.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/skydivelogs-app/src/assets/icon/rotate.svg b/Front/skydivelogs-app/src/assets/icon/rotate.svg new file mode 100644 index 0000000..48a8b09 --- /dev/null +++ b/Front/skydivelogs-app/src/assets/icon/rotate.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/skydivelogs-app/src/assets/icon/summary.svg b/Front/skydivelogs-app/src/assets/icon/summary.svg new file mode 100644 index 0000000..f5dc456 --- /dev/null +++ b/Front/skydivelogs-app/src/assets/icon/summary.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/skydivelogs-app/src/assets/icon/wind.svg b/Front/skydivelogs-app/src/assets/icon/wind.svg new file mode 100644 index 0000000..a422180 --- /dev/null +++ b/Front/skydivelogs-app/src/assets/icon/wind.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/skydivelogs-app/src/config/config.dev.json b/Front/skydivelogs-app/src/config/config.dev.json index a7a9f70..ba49219 100644 --- a/Front/skydivelogs-app/src/config/config.dev.json +++ b/Front/skydivelogs-app/src/config/config.dev.json @@ -1,4 +1,4 @@ { - "apiUrl": "http://localhost:5000", - "version": "0.28.0" -} \ No newline at end of file + "apiUrl": "http://localhost:5000", + "version": "0.28.0 DEV" +} diff --git a/Front/skydivelogs-app/src/config/config.prod.json b/Front/skydivelogs-app/src/config/config.prod.json index 8db6d9b..ffc98f9 100644 --- a/Front/skydivelogs-app/src/config/config.prod.json +++ b/Front/skydivelogs-app/src/config/config.prod.json @@ -1,4 +1,4 @@ { - "apiUrl": "https://test-divelog.sebastienandre.com", - "version": "0.28.0" -} \ No newline at end of file + "apiUrl": "https://test-divelog.sebastienandre.com", + "version": "0.28.0 PROD" +} diff --git a/Front/skydivelogs-app/src/environments/environment.dev.ts b/Front/skydivelogs-app/src/environments/environment.dev.ts new file mode 100644 index 0000000..8b0b5c0 --- /dev/null +++ b/Front/skydivelogs-app/src/environments/environment.dev.ts @@ -0,0 +1,10 @@ +// The file contents for the current environment will overwrite these during build. +// The build system defaults to the dev environment which uses `environment.ts`, but if you do +// `ng build --env=prod` then `environment.prod.ts` will be used instead. +// The list of which env maps to which file can be found in `.angular-cli.json`. + +export const environment = { + production: false, + debugMode: true, + env: "dev" +}; diff --git a/Front/skydivelogs-app/src/index.html b/Front/skydivelogs-app/src/index.html index ce3b1fb..95e31ed 100644 --- a/Front/skydivelogs-app/src/index.html +++ b/Front/skydivelogs-app/src/index.html @@ -1,23 +1,32 @@ + + + SkydivelogsApp + + + + - - - SkydivelogsApp - - - - - - - -
- - - - -
-
- - + + +
+ + + + +
+
+ diff --git a/Front/skydivelogs-app/src/interceptor/error.interceptor.ts b/Front/skydivelogs-app/src/interceptor/error.interceptor.ts index 8380160..85b566d 100644 --- a/Front/skydivelogs-app/src/interceptor/error.interceptor.ts +++ b/Front/skydivelogs-app/src/interceptor/error.interceptor.ts @@ -1,29 +1,59 @@ -import { Injectable } from '@angular/core'; -import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http'; -import { Observable, throwError } from 'rxjs'; -import { catchError } from 'rxjs/operators'; +// import { Injectable } from "@angular/core"; +// import { +// HttpRequest, +// HttpHandler, +// HttpEvent, +// HttpInterceptor, +// } from "@angular/common/http"; +// import { Observable, throwError } from "rxjs"; +// import { catchError } from "rxjs/operators"; -import { AuthenticationService } from '../services/authentication.service'; +// import { AuthenticationService } from "../services/authentication.service"; +// @Injectable() +// export class ErrorInterceptor implements HttpInterceptor { +// constructor(private authenticationService: AuthenticationService) {} -@Injectable() -export class ErrorInterceptor implements HttpInterceptor { +// intercept( +// request: HttpRequest, +// next: HttpHandler +// ): Observable> { +// return next.handle(request).pipe( +// catchError((err) => { +// if (err.status === 401) { +// // auto logout if 401 response returned from api +// this.authenticationService.logout(); +// location.reload(); +// } - constructor(private authenticationService: AuthenticationService) { } +// const error = err.error.message || err.statusText; +// return throwError(() => error); +// }) +// ); +// } +// } - intercept(request: HttpRequest, next: HttpHandler): Observable> { - return next.handle(request) - .pipe( - catchError(err => { - if (err.status === 401) { - // auto logout if 401 response returned from api - this.authenticationService.logout(); - location.reload(); - } +import { HttpEvent, HttpHandlerFn, HttpRequest } from "@angular/common/http"; +import { inject } from "@angular/core"; +import { catchError, Observable, throwError } from "rxjs"; +import { AuthenticationService } from "../services/authentication.service"; - const error = err.error.message || err.statusText; - return throwError(error); - }) - ); - } +export function ErrorInterceptor( + request: HttpRequest, + next: HttpHandlerFn +): Observable> { + const authenticationService = inject(AuthenticationService); + + return next(request).pipe( + catchError((err) => { + if (err.status === 401) { + // auto logout if 401 response returned from api + authenticationService.logout(); + location.reload(); + } + + const error = err.error.message || err.statusText; + return throwError(() => error); + }) + ); } diff --git a/Front/skydivelogs-app/src/interceptor/jwt-auth.interceptor.ts b/Front/skydivelogs-app/src/interceptor/jwt-auth.interceptor.ts index 250f257..7aa11d3 100644 --- a/Front/skydivelogs-app/src/interceptor/jwt-auth.interceptor.ts +++ b/Front/skydivelogs-app/src/interceptor/jwt-auth.interceptor.ts @@ -1,27 +1,21 @@ -import { Injectable } from "@angular/core"; -import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from "@angular/common/http"; +import { HttpEvent, HttpHandlerFn, HttpRequest } from "@angular/common/http"; +import { inject } from "@angular/core"; import { Observable } from "rxjs"; - import { AuthenticationService } from "../services/authentication.service"; +export function JwtAuthInterceptor( + request: HttpRequest, + next: HttpHandlerFn +): Observable> { + const currentUser = inject(AuthenticationService).currentUserValue; -@Injectable() -export class JwtAuthInterceptor implements HttpInterceptor { - - constructor(private authenticationService: AuthenticationService) {} - - intercept(request: HttpRequest, next: HttpHandler): Observable> { - // add authorization header with basic auth credentials if available - const currentUser = this.authenticationService.currentUserValue; - - if (currentUser && currentUser.token) { - request = request.clone({ - setHeaders: { - Authorization: `Bearer ${currentUser.token}` - } - }); - } - - return next.handle(request); + if (currentUser && currentUser.token) { + request = request.clone({ + setHeaders: { + Authorization: `Bearer ${currentUser.token}`, + }, + }); } + + return next(request); } diff --git a/Front/skydivelogs-app/src/main.ts b/Front/skydivelogs-app/src/main.ts index 3ecea68..a6690d2 100644 --- a/Front/skydivelogs-app/src/main.ts +++ b/Front/skydivelogs-app/src/main.ts @@ -1,13 +1,15 @@ +import { enableProdMode } from "@angular/core"; +import { bootstrapApplication } from "@angular/platform-browser"; -import { enableProdMode } from '@angular/core'; -import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { appConfig } from "./app/app.config"; +import { AppComponent } from "./app/app.component"; -import { AppModule } from './app/app.module'; -import { environment } from './environments/environment'; +import { environment } from "./environments/environment"; if (environment.production) { enableProdMode(); } -platformBrowserDynamic().bootstrapModule(AppModule) - .catch(err => console.log(err)); +bootstrapApplication(AppComponent, appConfig).catch((err) => + console.error(err) +); diff --git a/Front/skydivelogs-app/src/services/base.service.ts b/Front/skydivelogs-app/src/services/base.service.ts index 14e2860..137f2b0 100644 --- a/Front/skydivelogs-app/src/services/base.service.ts +++ b/Front/skydivelogs-app/src/services/base.service.ts @@ -1,26 +1,25 @@ -import { HttpHeaders } from '@angular/common/http'; +import { HttpHeaders } from "@angular/common/http"; -import { ConfigurationHelper } from './configuration-helper'; -import { ServiceCacheApi } from './service-cache-api.service'; +import { ConfigurationHelper } from "./configuration-helper"; +import { ServiceCacheApi } from "./service-cache-api.service"; export class BaseService { - protected headers: HttpHeaders; - protected apiUrl: string; - protected serviceCacheApi : ServiceCacheApi; + protected headers: HttpHeaders; + protected apiUrl: string; + protected serviceCacheApi: ServiceCacheApi; - constructor() { - ConfigurationHelper.settings.subscribe(settings => - { - if (settings != null) { - let tmpApiUrl : string = settings.apiUrl; - - this.headers = new HttpHeaders({ - 'Access-Control-Allow-Origin': tmpApiUrl - }); - this.apiUrl = tmpApiUrl + '/api'; - } + constructor() { + ConfigurationHelper.settings.subscribe((settings) => { + if (settings != null) { + let tmpApiUrl: string = settings.apiUrl; + + this.headers = new HttpHeaders({ + "Access-Control-Allow-Origin": tmpApiUrl, }); + this.apiUrl = tmpApiUrl + "/api"; + } + }); - this.serviceCacheApi = new ServiceCacheApi(); - } + this.serviceCacheApi = new ServiceCacheApi(); + } } diff --git a/Front/skydivelogs-app/src/services/configuration-helper.ts b/Front/skydivelogs-app/src/services/configuration-helper.ts index f6bb2b6..2857747 100644 --- a/Front/skydivelogs-app/src/services/configuration-helper.ts +++ b/Front/skydivelogs-app/src/services/configuration-helper.ts @@ -1,31 +1,33 @@ -import { Injectable } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; +import { Injectable } from "@angular/core"; +import { HttpClient } from "@angular/common/http"; -import { BehaviorSubject } from 'rxjs'; - -import { IAppSettings } from '../models/app-settings'; +import { BehaviorSubject } from "rxjs"; +import { IAppSettings } from "../models/app-settings"; @Injectable({ providedIn: "root" }) export class ConfigurationHelper { - private static settingsSource = new BehaviorSubject(null); - public static settings = ConfigurationHelper.settingsSource.asObservable(); - - constructor(private http: HttpClient) {} + private static settingsSource = new BehaviorSubject(null); + public static settings = ConfigurationHelper.settingsSource.asObservable(); - load(env: string) { - const jsonFile = `/config/config.${env}.json`; + constructor(private http: HttpClient) {} - return new Promise((resolve, reject) => { - this.http.get(jsonFile) - .toPromise() - .then((response : IAppSettings) => { - ConfigurationHelper.settingsSource.next(response); - resolve(); - }) - .catch((response: any) => { - reject(`Could not load file '${jsonFile}': ${JSON.stringify(response)}`); - }); + load(env: string) { + const jsonFile = `/config/config.${env}.json`; + + return new Promise((resolve, reject) => { + this.http + .get(jsonFile) + .toPromise() + .then((response: IAppSettings) => { + ConfigurationHelper.settingsSource.next(response); + resolve(); + }) + .catch((response: any) => { + reject( + `Could not load file '${jsonFile}': ${JSON.stringify(response)}` + ); }); - } -} \ No newline at end of file + }); + } +} diff --git a/Front/skydivelogs-app/src/services/request-cache.service.ts b/Front/skydivelogs-app/src/services/request-cache.service.ts index 589c22f..85b21bc 100644 --- a/Front/skydivelogs-app/src/services/request-cache.service.ts +++ b/Front/skydivelogs-app/src/services/request-cache.service.ts @@ -1,5 +1,5 @@ -import { Injectable } from '@angular/core'; -import { HttpRequest, HttpResponse } from '@angular/common/http'; +import { Injectable } from "@angular/core"; +import { HttpRequest, HttpResponse } from "@angular/common/http"; @Injectable() export class RequestCache { @@ -10,8 +10,8 @@ export class RequestCache { } get(req: HttpRequest): HttpResponse | undefined { - const splittedUrl = req.urlWithParams.split('/'); - const url = splittedUrl[splittedUrl.length - 1] + '_' + req.method; + const splittedUrl = req.urlWithParams.split("/"); + const url = splittedUrl[splittedUrl.length - 1] + "_" + req.method; this.clearExpiredEntries(); const cached = this.cache.get(url); @@ -24,8 +24,8 @@ export class RequestCache { } put(req: HttpRequest, response: HttpResponse): void { - const splittedUrl = req.urlWithParams.split('/'); - const url = splittedUrl[splittedUrl.length - 1] + '_' + req.method; + const splittedUrl = req.urlWithParams.split("/"); + const url = splittedUrl[splittedUrl.length - 1] + "_" + req.method; const entry = { url, response, lastRead: Date.now() }; this.cache.set(url, entry); @@ -36,7 +36,7 @@ export class RequestCache { const maxAge = 30000; const expired = Date.now() - maxAge; - this.cache.forEach(expiredEntry => { + this.cache.forEach((expiredEntry) => { if (expiredEntry.lastRead < expired) { this.cache.delete(expiredEntry.url); } diff --git a/Front/skydivelogs-app/src/services/service-cache-api.service.ts b/Front/skydivelogs-app/src/services/service-cache-api.service.ts index c40d9fc..9cbdcff 100644 --- a/Front/skydivelogs-app/src/services/service-cache-api.service.ts +++ b/Front/skydivelogs-app/src/services/service-cache-api.service.ts @@ -1,29 +1,28 @@ -import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs'; -import { tap } from 'rxjs/operators'; -import { CacheApiKey } from '../models/cache-api-key.enum'; -import { of } from 'rxjs'; +import { Injectable } from "@angular/core"; +import { Observable } from "rxjs"; +import { tap } from "rxjs/operators"; +import { CacheApiKey } from "../models/cache-api-key.enum"; +import { of } from "rxjs"; -@Injectable({ - providedIn: 'root', -}) +@Injectable({ providedIn: "root" }) export class ServiceCacheApi { private cache: Map>; - constructor() { + constructor() { this.cache = new Map>(); } - public get(key: CacheApiKey, callToApi: Observable) : Observable { + public get(key: CacheApiKey, callToApi: Observable): Observable { const cached = this.cache.get(key); if (cached) { return cached; } else { return callToApi.pipe( - tap(event => { - this.cache.set(key, of(event)); - })); + tap((event) => { + this.cache.set(key, of(event)); + }) + ); } } @@ -31,7 +30,7 @@ export class ServiceCacheApi { this.cache.delete(key); } - public getByKey(key: CacheApiKey) : Observable { + public getByKey(key: CacheApiKey): Observable { return this.cache.get(key); } } diff --git a/Front/skydivelogs-app/src/tsconfig.app.json b/Front/skydivelogs-app/src/tsconfig.app.json deleted file mode 100644 index c1c97c7..0000000 --- a/Front/skydivelogs-app/src/tsconfig.app.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "../tsconfig.json", - "compilerOptions": { - "outDir": "../out-tsc/app", - "baseUrl": "./", - "types": [] - }, - "files": [ - "main.ts", - "polyfills.ts" - ] -} diff --git a/Front/skydivelogs-app/src/tsconfig.spec.json b/Front/skydivelogs-app/src/tsconfig.spec.json deleted file mode 100644 index c89454b..0000000 --- a/Front/skydivelogs-app/src/tsconfig.spec.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "extends": "../tsconfig.json", - "compilerOptions": { - "outDir": "../out-tsc/spec", - "baseUrl": "./", - "types": [ - "jasmine", - "node" - ] - }, - "files": [ - "test.ts", - "polyfills.ts" - ], - "include": [ - "**/*.spec.ts", - "**/*.d.ts" - ] -} diff --git a/Front/skydivelogs-app/src/typings.d.ts b/Front/skydivelogs-app/src/typings.d.ts deleted file mode 100644 index ef5c7bd..0000000 --- a/Front/skydivelogs-app/src/typings.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -/* SystemJS module definition */ -declare var module: NodeModule; -interface NodeModule { - id: string; -} diff --git a/Front/skydivelogs-app/tsconfig.app.json b/Front/skydivelogs-app/tsconfig.app.json new file mode 100644 index 0000000..3775b37 --- /dev/null +++ b/Front/skydivelogs-app/tsconfig.app.json @@ -0,0 +1,15 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": [] + }, + "files": [ + "src/main.ts" + ], + "include": [ + "src/**/*.d.ts" + ] +} diff --git a/Front/skydivelogs-app/tsconfig.json b/Front/skydivelogs-app/tsconfig.json index 4a3997b..c91b0d2 100644 --- a/Front/skydivelogs-app/tsconfig.json +++ b/Front/skydivelogs-app/tsconfig.json @@ -1,25 +1,29 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ { "compileOnSave": false, - "angularCompilerOptions": { - "strictTemplates": true, - }, "compilerOptions": { - "importHelpers": true, "outDir": "./dist/out-tsc", + "strict": false, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "skipLibCheck": true, + "isolatedModules": true, "esModuleInterop": true, - "sourceMap": true, - "declaration": false, - "moduleResolution": "node", "experimentalDecorators": true, - "target": "es2015", - "typeRoots": [ - "node_modules/@types" - ], - "lib": [ - "es2017", - "dom" - ], - "module": "esnext", - "baseUrl": "./" + "moduleResolution": "bundler", + "importHelpers": true, + "target": "ES2022", + "module": "ES2022", + "strictPropertyInitialization": false, + "strictNullChecks": false + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true } -} \ No newline at end of file +} diff --git a/Front/skydivelogs-app/tsconfig.spec.json b/Front/skydivelogs-app/tsconfig.spec.json new file mode 100644 index 0000000..5fb748d --- /dev/null +++ b/Front/skydivelogs-app/tsconfig.spec.json @@ -0,0 +1,15 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "types": [ + "jasmine" + ] + }, + "include": [ + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/doc.txt b/doc.txt index 1573890..e847648 100644 --- a/doc.txt +++ b/doc.txt @@ -1,7 +1,7 @@ -To build an image "toto" with the version "0.1": docker build . -t skydivelogs:1.4.2 +To build an image "toto" with the version "0.1": podman build . -t skydivelogs:1.5.0 To run ab image to container with volume : - docker run -v C:\toto\config:/app/Front/config -v C:\toto\db:/app/API/Data -d -p 5080:80/tcp --name Test -it skydivelogs:1.4.0 + podman run -v C:\toto\config:/app/Front/config -v C:\toto\db:/app/API/Data -d -p 5080:80/tcp --name Test -it skydivelogs:1.5.0 -docker save --output skydivelogs-1.4.2.tar skydivelogs:1.4.2 +podman save --output skydivelogs-1.5.0.tar skydivelogs:1.5.0 -scp -P 5022 skydivelogs-1.4.2.tar administrator@51.75.68.58:~ +scp -P 5022 skydivelogs-1.5.0.tar administrator@51.75.68.58:~