chore(deps): upgrade Angular 19 → 20

- ng update @angular/core@20 @angular/cli@20 @angular/material@20 @angular-eslint@20 @angular/google-maps@20
- Remove ng-chartist (abandoned, incompatible with Angular 20): replace <x-chartist> with <app-bars-chart> in dropzones-bar and jumps-by-month
- Migrate all constructor injection to inject() function (ng generate @angular/core:inject, 67 files)
- TypeScript 5.5 → 5.9.3
- DOCUMENT import moved from @angular/common to @angular/core (automatic migration)
- tsconfig moduleResolution updated to "bundler"
This commit is contained in:
2026-04-26 06:40:13 +02:00
parent 5400294d45
commit be5f5775ef
78 changed files with 5080 additions and 3886 deletions
+2 -1
View File
@@ -9,7 +9,8 @@
"Bash(node -e \"const c = require\\('chart.js'\\); console.log\\(Object.keys\\(c\\).filter\\(k => k.includes\\('Doughnut'\\) || k.includes\\('Controller'\\)\\)\\)\")", "Bash(node -e \"const c = require\\('chart.js'\\); console.log\\(Object.keys\\(c\\).filter\\(k => k.includes\\('Doughnut'\\) || k.includes\\('Controller'\\)\\)\\)\")",
"Bash(npm list *)", "Bash(npm list *)",
"Bash(ng update *)", "Bash(ng update *)",
"Bash(npm run *)" "Bash(npm run *)",
"Bash(nvm ls *)"
] ]
} }
} }
+26
View File
@@ -151,5 +151,31 @@
} }
} }
} }
},
"schematics": {
"@schematics/angular:component": {
"type": "component"
},
"@schematics/angular:directive": {
"type": "directive"
},
"@schematics/angular:service": {
"type": "service"
},
"@schematics/angular:guard": {
"typeSeparator": "."
},
"@schematics/angular:interceptor": {
"typeSeparator": "."
},
"@schematics/angular:module": {
"typeSeparator": "."
},
"@schematics/angular:pipe": {
"typeSeparator": "."
},
"@schematics/angular:resolver": {
"typeSeparator": "."
}
} }
} }
+3750 -2503
View File
File diff suppressed because it is too large Load Diff
+21 -22
View File
@@ -21,22 +21,21 @@
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {
"@angular/animations": "^19.2.21", "@angular/animations": "^20.3.19",
"@angular/cdk": "^19.2.19", "@angular/cdk": "^20.2.14",
"@angular/common": "^19.2.21", "@angular/common": "^20.3.19",
"@angular/compiler": "^19.2.21", "@angular/compiler": "^20.3.19",
"@angular/core": "^19.2.21", "@angular/core": "^20.3.19",
"@angular/forms": "^19.2.21", "@angular/forms": "^20.3.19",
"@angular/google-maps": "^17.3.8", "@angular/google-maps": "^20.2.14",
"@angular/localize": "^19.2.21", "@angular/localize": "^20.3.19",
"@angular/material": "^19.2.19", "@angular/material": "^20.2.14",
"@angular/platform-browser": "^19.2.21", "@angular/platform-browser": "^20.3.19",
"@angular/platform-browser-dynamic": "^19.2.21", "@angular/platform-browser-dynamic": "^20.3.19",
"@angular/router": "^19.2.21", "@angular/router": "^20.3.19",
"bootstrap": "^5.3.7", "bootstrap": "^5.3.7",
"chart.js": "^4.4.2", "chart.js": "^4.4.2",
"chartist": "^1.3.0", "chartist": "^1.3.0",
"ng-chartist": "^8.2.0",
"ng2-charts": "^6.0.1", "ng2-charts": "^6.0.1",
"ngx-skeleton-loader": "^9.0.0", "ngx-skeleton-loader": "^9.0.0",
"rxjs": "~7.8.0", "rxjs": "~7.8.0",
@@ -44,14 +43,14 @@
"zone.js": "^0.15.1" "zone.js": "^0.15.1"
}, },
"devDependencies": { "devDependencies": {
"@angular-devkit/build-angular": "^19.2.24", "@angular-devkit/build-angular": "^20.3.24",
"@angular-eslint/builder": "19.8.1", "@angular-eslint/builder": "20.7.0",
"@angular-eslint/eslint-plugin": "19.8.1", "@angular-eslint/eslint-plugin": "20.7.0",
"@angular-eslint/eslint-plugin-template": "19.8.1", "@angular-eslint/eslint-plugin-template": "20.7.0",
"@angular-eslint/schematics": "19.8.1", "@angular-eslint/schematics": "20.7.0",
"@angular-eslint/template-parser": "19.8.1", "@angular-eslint/template-parser": "20.7.0",
"@angular/cli": "^19.2.24", "@angular/cli": "^20.3.24",
"@angular/compiler-cli": "^19.2.21", "@angular/compiler-cli": "^20.3.19",
"@types/jasmine": "~5.1.0", "@types/jasmine": "~5.1.0",
"@typescript-eslint/eslint-plugin": "7.2.0", "@typescript-eslint/eslint-plugin": "7.2.0",
"@typescript-eslint/parser": "7.2.0", "@typescript-eslint/parser": "7.2.0",
@@ -65,7 +64,7 @@
"karma-jasmine-html-reporter": "~2.1.0", "karma-jasmine-html-reporter": "~2.1.0",
"lint-staged": "^16.4.0", "lint-staged": "^16.4.0",
"prettier": "^3.8.3", "prettier": "^3.8.3",
"typescript": "~5.5.4" "typescript": "~5.9.3"
}, },
"lint-staged": { "lint-staged": {
"*.{ts,html,scss,json,md}": [ "*.{ts,html,scss,json,md}": [
+4 -6
View File
@@ -1,4 +1,4 @@
import { Component, OnInit, AfterContentInit } from '@angular/core'; import { Component, OnInit, AfterContentInit, inject } from '@angular/core';
import { MAT_DATE_LOCALE, MAT_DATE_FORMATS, provideNativeDateAdapter } from '@angular/material/core'; import { MAT_DATE_LOCALE, MAT_DATE_FORMATS, provideNativeDateAdapter } from '@angular/material/core';
import { Title } from '@angular/platform-browser'; import { Title } from '@angular/platform-browser';
@@ -29,14 +29,12 @@ export const MY_FORMATS = {
styleUrl: './app.component.scss', styleUrl: './app.component.scss',
}) })
export class AppComponent implements OnInit, AfterContentInit { export class AppComponent implements OnInit, AfterContentInit {
private userService = inject(UserService);
private titleService = inject(Title);
public title = 'Ad Astra'; public title = 'Ad Astra';
public appClass = 'grayscale'; public appClass = 'grayscale';
constructor(
private userService: UserService,
private titleService: Title,
) {}
ngOnInit() { ngOnInit() {
this.userService.populate(); this.userService.populate();
this.titleService.setTitle(this.title); this.titleService.setTitle(this.title);
@@ -47,6 +47,10 @@ import { AeronefByImat, AeronefByYear } from '@models';
], ],
}) })
export class AeronefsComponent implements OnInit, OnDestroy { export class AeronefsComponent implements OnInit, OnDestroy {
private route = inject(ActivatedRoute);
private _utilitiesService = inject(UtilitiesService);
menuItems = inject(MenuItems);
private _data: Subscription = new Subscription(); private _data: Subscription = new Subscription();
private _aeronefsByImat!: Array<AeronefByImat>; private _aeronefsByImat!: Array<AeronefByImat>;
private _aeronefsByYear!: Array<AeronefByYear>; private _aeronefsByYear!: Array<AeronefByYear>;
@@ -68,12 +72,6 @@ export class AeronefsComponent implements OnInit, OnDestroy {
}; };
public seriesColorClass: string[] = this._utilitiesService.getChartColors(); public seriesColorClass: string[] = this._utilitiesService.getChartColors();
constructor(
private route: ActivatedRoute,
private _utilitiesService: UtilitiesService,
public menuItems: MenuItems,
) {}
ngOnInit() { ngOnInit() {
const data$: Observable<{ aeronefsPageData: AeronefsPageData }> = this.route.data as Observable<{ const data$: Observable<{ aeronefsPageData: AeronefsPageData }> = this.route.data as Observable<{
aeronefsPageData: AeronefsPageData; aeronefsPageData: AeronefsPageData;
+7 -7
View File
@@ -39,6 +39,12 @@ import { ListErrorsComponent, ShowAuthedDirective } from '@components/shared';
styleUrl: './auth.component.scss', styleUrl: './auth.component.scss',
}) })
export class AuthComponent implements OnInit, OnDestroy { export class AuthComponent implements OnInit, OnDestroy {
private route = inject(ActivatedRoute);
private router = inject(Router);
private titleService = inject(Title);
private userService = inject(UserService);
private fb = inject(UntypedFormBuilder);
private _url: Subscription = new Subscription(); private _url: Subscription = new Subscription();
private _user: Subscription = new Subscription(); private _user: Subscription = new Subscription();
authType = ''; authType = '';
@@ -49,13 +55,7 @@ export class AuthComponent implements OnInit, OnDestroy {
authForm!: UntypedFormGroup; authForm!: UntypedFormGroup;
destroyRef = inject(DestroyRef); destroyRef = inject(DestroyRef);
constructor( constructor() {
private route: ActivatedRoute,
private router: Router,
private titleService: Title,
private userService: UserService,
private fb: UntypedFormBuilder,
) {
this._resetErrors(); this._resetErrors();
// use FormBuilder to create a form group // use FormBuilder to create a form group
const controlsConfig = { const controlsConfig = {
@@ -1,4 +1,4 @@
import { Component, Input, OnInit, OnDestroy, ViewChild } from '@angular/core'; import { Component, Input, OnInit, OnDestroy, ViewChild, inject } from '@angular/core';
import { trigger, state, style, animate, transition } from '@angular/animations'; import { trigger, state, style, animate, transition } from '@angular/animations';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
@@ -63,6 +63,12 @@ import { CalculatorService, JumpsService, UserService, UtilitiesService } from '
], ],
}) })
export class CalculatorComponent implements OnInit, OnDestroy { export class CalculatorComponent implements OnInit, OnDestroy {
private _calculatorService = inject(CalculatorService);
private _jumpsService = inject(JumpsService);
private _userService = inject(UserService);
private _utilitiesService = inject(UtilitiesService);
menuItems = inject(MenuItems);
//private _lastjump!: Subscription; // = new Subscription(); //private _lastjump!: Subscription; // = new Subscription();
//private _currentUser!: Subscription; // = new Subscription(); //private _currentUser!: Subscription; // = new Subscription();
private _subscriptions: Array<Subscription> = []; private _subscriptions: Array<Subscription> = [];
@@ -100,14 +106,6 @@ export class CalculatorComponent implements OnInit, OnDestroy {
@ViewChild(MatSort) sort!: MatSort; @ViewChild(MatSort) sort!: MatSort;
@ViewChild(MatPaginator) paginator!: MatPaginator; @ViewChild(MatPaginator) paginator!: MatPaginator;
constructor(
private _calculatorService: CalculatorService,
private _jumpsService: JumpsService,
private _userService: UserService,
private _utilitiesService: UtilitiesService,
public menuItems: MenuItems,
) {}
ngOnInit() { ngOnInit() {
const currentUser$: Observable<User> = this._userService.currentUser; const currentUser$: Observable<User> = this._userService.currentUser;
const lastjump$: Observable<Jump> = this._jumpsService.getLastJump(); const lastjump$: Observable<Jump> = this._jumpsService.getLastJump();
@@ -45,6 +45,10 @@ import { CanopyBySize, CanopyByYear, CanopyModelBySize, CanopyModelByYear } from
], ],
}) })
export class CanopiesComponent implements OnInit, OnDestroy { export class CanopiesComponent implements OnInit, OnDestroy {
private route = inject(ActivatedRoute);
private _utilitiesService = inject(UtilitiesService);
menuItems = inject(MenuItems);
private _data: Subscription = new Subscription(); private _data: Subscription = new Subscription();
private _canopiesModelBySize!: Array<CanopyModelBySize>; private _canopiesModelBySize!: Array<CanopyModelBySize>;
private _canopiesModelByYear!: Array<CanopyModelByYear>; private _canopiesModelByYear!: Array<CanopyModelByYear>;
@@ -72,12 +76,6 @@ export class CanopiesComponent implements OnInit, OnDestroy {
}; };
public seriesColorClass: string[] = this._utilitiesService.getChartColors(); public seriesColorClass: string[] = this._utilitiesService.getChartColors();
constructor(
private route: ActivatedRoute,
private _utilitiesService: UtilitiesService,
public menuItems: MenuItems,
) {}
ngOnInit() { ngOnInit() {
const data$: Observable<{ canopiesPageData: CanopiesPageData }> = this.route.data as Observable<{ const data$: Observable<{ canopiesPageData: CanopiesPageData }> = this.route.data as Observable<{
canopiesPageData: CanopiesPageData; canopiesPageData: CanopiesPageData;
@@ -1,4 +1,4 @@
import { Component, OnInit, OnDestroy } from '@angular/core'; import { Component, OnInit, OnDestroy, inject } from '@angular/core';
import { DatePipe } from '@angular/common'; import { DatePipe } from '@angular/common';
import { Title } from '@angular/platform-browser'; import { Title } from '@angular/platform-browser';
import { MatDividerModule } from '@angular/material/divider'; import { MatDividerModule } from '@angular/material/divider';
@@ -49,6 +49,12 @@ import {
styleUrl: './dashboard.component.scss', styleUrl: './dashboard.component.scss',
}) })
export class DashboardComponent implements OnInit, OnDestroy { export class DashboardComponent implements OnInit, OnDestroy {
private route = inject(ActivatedRoute);
private router = inject(Router);
private titleService = inject(Title);
private _userService = inject(UserService);
private _jumpsService = inject(JumpsService);
private _currentUser: Subscription = new Subscription(); private _currentUser: Subscription = new Subscription();
private _data: Subscription = new Subscription(); private _data: Subscription = new Subscription();
private _lastjump: Subscription = new Subscription(); private _lastjump: Subscription = new Subscription();
@@ -73,18 +79,7 @@ export class DashboardComponent implements OnInit, OnDestroy {
public dropzonesCount = 0; public dropzonesCount = 0;
public lastJump: Jump = {} as Jump; public lastJump: Jump = {} as Jump;
constructor( constructor() {
private route: ActivatedRoute,
private router: Router,
private titleService: Title,
private _userService: UserService,
private _jumpsService: JumpsService,
/*
private aeronefsService: AeronefsService,
private canopiesService: CanopiesService,
private dropzonesService: DropZonesService
*/
) {
this._resetErrors(); this._resetErrors();
} }
+4 -6
View File
@@ -1,4 +1,4 @@
import { Component, OnInit, OnDestroy } from '@angular/core'; import { Component, OnInit, OnDestroy, inject } from '@angular/core';
import { CdkDragDrop, CdkDropList, CdkDrag, CdkDragPlaceholder, moveItemInArray } from '@angular/cdk/drag-drop'; import { CdkDragDrop, CdkDropList, CdkDrag, CdkDragPlaceholder, moveItemInArray } from '@angular/cdk/drag-drop';
import { Title } from '@angular/platform-browser'; import { Title } from '@angular/platform-browser';
import { RouterLink } from '@angular/router'; import { RouterLink } from '@angular/router';
@@ -34,6 +34,9 @@ import { ListErrorsComponent } from '@components/shared';
styleUrl: './demo.component.scss', styleUrl: './demo.component.scss',
}) })
export class DemoComponent implements OnInit, OnDestroy { export class DemoComponent implements OnInit, OnDestroy {
private titleService = inject(Title);
private userService = inject(UserService);
private _user: Subscription = new Subscription(); private _user: Subscription = new Subscription();
private _colors: string[] = [ private _colors: string[] = [
'primary', 'primary',
@@ -104,11 +107,6 @@ export class DemoComponent implements OnInit, OnDestroy {
errors: Errors = { errors: {} }; errors: Errors = { errors: {} };
btnSettingsTitle = 'Paramètres'; btnSettingsTitle = 'Paramètres';
constructor(
private titleService: Title,
private userService: UserService,
) {}
ngOnInit() { ngOnInit() {
this.titleService.setTitle(`Ad Astra - ${this.title}`); this.titleService.setTitle(`Ad Astra - ${this.title}`);
Object.assign(this.user, this.userService.getCurrentUser()); Object.assign(this.user, this.userService.getCurrentUser());
@@ -50,6 +50,10 @@ import { UtilitiesService } from '@services';
], ],
}) })
export class DropzonesComponent implements OnInit, OnDestroy { export class DropzonesComponent implements OnInit, OnDestroy {
private route = inject(ActivatedRoute);
private _utilitiesService = inject(UtilitiesService);
menuItems = inject(MenuItems);
private _data: Subscription = new Subscription(); private _data: Subscription = new Subscription();
private _lastjump: Subscription = new Subscription(); private _lastjump: Subscription = new Subscription();
private _dropzonesByOaci!: Array<DropZoneByOaci>; private _dropzonesByOaci!: Array<DropZoneByOaci>;
@@ -86,22 +90,6 @@ export class DropzonesComponent implements OnInit, OnDestroy {
maxZoom: 20, maxZoom: 20,
minZoom: 3, minZoom: 3,
}; };
// Arcachon : 44.596408,-1.115958
// La Réole : 44.566309,-0.054606
// Soulac : 45.495395,-1.081039
// Royan : 45.632660,-0.977096
// Rochefort : 45.888477,-0.984551
// Sables : 46.475393,-1.722160
// Pamiers : 43.091951,1.698546
// Pau : 43.426255,-0.288453
// Cahors : 44.348635,1.478898
// Béni : 32.394218,-6.327999
constructor(
private route: ActivatedRoute,
private _utilitiesService: UtilitiesService,
public menuItems: MenuItems,
) {}
ngOnInit() { ngOnInit() {
const data$: Observable<{ dropZonesPageData: DropZonesPageData }> = this.route.data as Observable<{ const data$: Observable<{ dropZonesPageData: DropZonesPageData }> = this.route.data as Observable<{
@@ -52,6 +52,8 @@ export class GuildRaidStepperIntl extends MatStepperIntl {
], ],
}) })
export class HerowarsGuildraidComponent implements OnInit { export class HerowarsGuildraidComponent implements OnInit {
private _titleService = inject(Title);
public title = 'Guild Raids'; public title = 'Guild Raids';
public subtitle = 'Log'; public subtitle = 'Log';
public description = 'Tools in working progress.'; public description = 'Tools in working progress.';
@@ -69,8 +71,6 @@ export class HerowarsGuildraidComponent implements OnInit {
{ num: 3, name: 'Stage 3', maxPower: 0, duration: 0, startTime: 0, endTime: 0 }, { num: 3, name: 'Stage 3', maxPower: 0, duration: 0, startTime: 0, endTime: 0 },
]; ];
constructor(private _titleService: Title) {}
ngOnInit() { ngOnInit() {
this._titleService.setTitle(this.title); this._titleService.setTitle(this.title);
this._guildMembers.map((data) => { this._guildMembers.map((data) => {
@@ -54,6 +54,11 @@ import guildStatistics from '@data/hw-guild-statistics.json'; // page Overview -
], ],
}) })
export class HerowarsGuildwarComponent implements OnInit { export class HerowarsGuildwarComponent implements OnInit {
private _titleService = inject(Title);
private _utilitiesService = inject(UtilitiesService);
private _clanService = inject(HWClanService);
private _memberService = inject(HWMemberService);
public destroyRef = inject(DestroyRef); public destroyRef = inject(DestroyRef);
public title = 'Guild War'; public title = 'Guild War';
public subtitle = 'Log'; public subtitle = 'Log';
@@ -71,13 +76,6 @@ export class HerowarsGuildwarComponent implements OnInit {
private _guildMembers: HWMember[] = []; private _guildMembers: HWMember[] = [];
private _guildInfo: HWActivityStat = {} as HWActivityStat; private _guildInfo: HWActivityStat = {} as HWActivityStat;
constructor(
private _titleService: Title,
private _utilitiesService: UtilitiesService,
private _clanService: HWClanService,
private _memberService: HWMemberService,
) {}
ngOnInit() { ngOnInit() {
this._titleService.setTitle(this.title); this._titleService.setTitle(this.title);
} }
@@ -52,6 +52,8 @@ import guildData from 'src/files-data/hw-guild-data.json'; // page Membres
], ],
}) })
export class HerowarsComponent implements OnInit { export class HerowarsComponent implements OnInit {
private _titleService = inject(Title);
public title = 'HeroWars GM Tools'; public title = 'HeroWars GM Tools';
public description = 'Tools in working progress.'; public description = 'Tools in working progress.';
public errors: Errors = { errors: {} }; public errors: Errors = { errors: {} };
@@ -59,8 +61,6 @@ export class HerowarsComponent implements OnInit {
public now = new Date(); public now = new Date();
private _guildMembers: HWMember[] = []; private _guildMembers: HWMember[] = [];
constructor(private _titleService: Title) {}
ngOnInit() { ngOnInit() {
try { try {
this._titleService.setTitle(this.title); this._titleService.setTitle(this.title);
+2 -6
View File
@@ -24,18 +24,14 @@ import { Errors } from '@models';
], ],
}) })
export class HomeComponent implements OnInit { export class HomeComponent implements OnInit {
private _titleService = inject(Title);
public title = 'Shop bientôt disponible!'; public title = 'Shop bientôt disponible!';
public description = "Encore un peu de patience, notre shop sera mis en ligne d'ici peu."; public description = "Encore un peu de patience, notre shop sera mis en ligne d'ici peu.";
public errors: Errors = { errors: {} }; public errors: Errors = { errors: {} };
public destroyRef = inject(DestroyRef); public destroyRef = inject(DestroyRef);
public now = new Date(); public now = new Date();
constructor(
private _titleService: Title,
//private _utilitiesService: UtilitiesService
//private _userService: UserService
) {}
ngOnInit() { ngOnInit() {
this._titleService.setTitle(this.title); this._titleService.setTitle(this.title);
/* /*
+3 -5
View File
@@ -29,6 +29,9 @@ import { Errors, Jump, JumpPageData } from '@models';
styleUrl: './jump.component.scss', styleUrl: './jump.component.scss',
}) })
export class JumpComponent implements OnInit, OnDestroy { export class JumpComponent implements OnInit, OnDestroy {
private route = inject(ActivatedRoute);
menuItems = inject(MenuItems);
private _data: Subscription = new Subscription(); private _data: Subscription = new Subscription();
public title: string = ''; public title: string = '';
public errors: Errors = { errors: {} }; public errors: Errors = { errors: {} };
@@ -37,11 +40,6 @@ export class JumpComponent implements OnInit, OnDestroy {
public prevSlug: string = ''; public prevSlug: string = '';
public nextSlug: string = ''; public nextSlug: string = '';
constructor(
private route: ActivatedRoute,
public menuItems: MenuItems,
) {}
ngOnInit() { ngOnInit() {
const data$: Observable<{ pageData: JumpPageData }> = this.route.data as Observable<{ pageData: JumpPageData }>; const data$: Observable<{ pageData: JumpPageData }> = this.route.data as Observable<{ pageData: JumpPageData }>;
this._data = data$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { pageData: JumpPageData }) => { this._data = data$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { pageData: JumpPageData }) => {
+4 -6
View File
@@ -48,6 +48,10 @@ import { Jump, JumpByCategorie, JumpByDate, JumpByDateByModule, JumpByModule, Ju
], ],
}) })
export class JumpsComponent implements OnInit, OnDestroy { export class JumpsComponent implements OnInit, OnDestroy {
private route = inject(ActivatedRoute);
private _utilitiesService = inject(UtilitiesService);
menuItems = inject(MenuItems);
private _data: Subscription = new Subscription(); private _data: Subscription = new Subscription();
private _jumpsByCategorie: Array<JumpByCategorie> = []; private _jumpsByCategorie: Array<JumpByCategorie> = [];
private _jumpsByModule: Array<JumpByModule> = []; private _jumpsByModule: Array<JumpByModule> = [];
@@ -91,12 +95,6 @@ export class JumpsComponent implements OnInit, OnDestroy {
public seriesColTotalClosed: number[] = []; public seriesColTotalClosed: number[] = [];
public seriesColTotalLastYears: number[] = []; public seriesColTotalLastYears: number[] = [];
constructor(
private route: ActivatedRoute,
private _utilitiesService: UtilitiesService,
public menuItems: MenuItems,
) {}
ngOnInit() { ngOnInit() {
const data$: Observable<{ pageData: JumpsPageData }> = this.route.data as Observable<{ const data$: Observable<{ pageData: JumpsPageData }> = this.route.data as Observable<{
pageData: JumpsPageData; pageData: JumpsPageData;
@@ -1,4 +1,4 @@
import { Component, Inject, OnDestroy } from '@angular/core'; import { Component, OnDestroy, inject } from '@angular/core';
import { AsyncPipe, DatePipe } from '@angular/common'; import { AsyncPipe, DatePipe } from '@angular/common';
import { FormBuilder, FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; import { FormBuilder, FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatAutocompleteModule } from '@angular/material/autocomplete';
@@ -48,6 +48,17 @@ import { AeronefsService, CanopiesService, DropZonesService, JumpsService } from
], ],
}) })
export class JumpAddDialogComponent implements OnDestroy { export class JumpAddDialogComponent implements OnDestroy {
dialogRef = inject<MatDialogRef<JumpAddDialogComponent>>(MatDialogRef);
private fb = inject(FormBuilder);
private _aeronefsService = inject(AeronefsService);
private _canopiesService = inject(CanopiesService);
private _dropZonesService = inject(DropZonesService);
private _jumpsService = inject(JumpsService);
data = inject<{
jump: Jump;
lastJump: Jump;
}>(MAT_DIALOG_DATA);
private _formChanges: Array<Subscription> = []; private _formChanges: Array<Subscription> = [];
private _subscriptions: Array<Subscription> = []; private _subscriptions: Array<Subscription> = [];
private _aeronefByImat: Subscription = new Subscription(); private _aeronefByImat: Subscription = new Subscription();
@@ -101,15 +112,9 @@ export class JumpAddDialogComponent implements OnDestroy {
modules: Observable<Array<JumpByModule>>; modules: Observable<Array<JumpByModule>>;
}; };
constructor( constructor() {
public dialogRef: MatDialogRef<JumpAddDialogComponent>, const data = this.data;
private fb: FormBuilder,
private _aeronefsService: AeronefsService,
private _canopiesService: CanopiesService,
private _dropZonesService: DropZonesService,
private _jumpsService: JumpsService,
@Inject(MAT_DIALOG_DATA) public data: { jump: Jump; lastJump: Jump },
) {
this.inputOptions = { aeronefs: [], canopies: [], dropzones: [], categories: [] }; this.inputOptions = { aeronefs: [], canopies: [], dropzones: [], categories: [] };
//this.filteredOptions.aeronefs = this._aeronefsService.getAllByImat(); //this.filteredOptions.aeronefs = this._aeronefsService.getAllByImat();
this.jump = data.jump; this.jump = data.jump;
@@ -1,4 +1,4 @@
import { Component, Inject } from '@angular/core'; import { Component, inject } from '@angular/core';
import { DatePipe } from '@angular/common'; import { DatePipe } from '@angular/common';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog'; import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
@@ -12,10 +12,8 @@ import { Jump } from '@models';
imports: [DatePipe, MatDialogModule, MatButtonModule, MatIconModule], imports: [DatePipe, MatDialogModule, MatButtonModule, MatIconModule],
}) })
export class JumpDeleteDialogComponent { export class JumpDeleteDialogComponent {
constructor( dialogRef = inject<MatDialogRef<JumpDeleteDialogComponent>>(MatDialogRef);
public dialogRef: MatDialogRef<JumpDeleteDialogComponent>, jump = inject<Jump>(MAT_DIALOG_DATA);
@Inject(MAT_DIALOG_DATA) public jump: Jump,
) {}
closeDialog(): void { closeDialog(): void {
this.dialogRef.close(); this.dialogRef.close();
@@ -1,4 +1,4 @@
import { Component, Inject, OnDestroy } from '@angular/core'; import { Component, OnDestroy, inject } from '@angular/core';
import { AsyncPipe, DatePipe } from '@angular/common'; import { AsyncPipe, DatePipe } from '@angular/common';
import { FormBuilder, FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; import { FormBuilder, FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatAutocompleteModule } from '@angular/material/autocomplete';
@@ -38,6 +38,14 @@ import { AeronefsService, CanopiesService, DropZonesService, JumpsService } from
], ],
}) })
export class JumpEditDialogComponent implements OnDestroy { export class JumpEditDialogComponent implements OnDestroy {
dialogRef = inject<MatDialogRef<JumpEditDialogComponent>>(MatDialogRef);
private fb = inject(FormBuilder);
private _aeronefsService = inject(AeronefsService);
private _canopiesService = inject(CanopiesService);
private _dropZonesService = inject(DropZonesService);
private _jumpsService = inject(JumpsService);
jump = inject<Jump>(MAT_DIALOG_DATA);
private _aeronefByImat: Subscription = new Subscription(); private _aeronefByImat: Subscription = new Subscription();
private _canopyModelBySize: Subscription = new Subscription(); private _canopyModelBySize: Subscription = new Subscription();
private _dropZoneByOaci: Subscription = new Subscription(); private _dropZoneByOaci: Subscription = new Subscription();
@@ -61,15 +69,7 @@ export class JumpEditDialogComponent implements OnDestroy {
modules: Observable<Array<JumpByModule>>; modules: Observable<Array<JumpByModule>>;
}; };
constructor( constructor() {
public dialogRef: MatDialogRef<JumpEditDialogComponent>,
private fb: FormBuilder,
private _aeronefsService: AeronefsService,
private _canopiesService: CanopiesService,
private _dropZonesService: DropZonesService,
private _jumpsService: JumpsService,
@Inject(MAT_DIALOG_DATA) public jump: Jump,
) {
this.inputOptions = { aeronefs: [], canopies: [], dropzones: [], categories: [] }; this.inputOptions = { aeronefs: [], canopies: [], dropzones: [], categories: [] };
const controlsConfig = { const controlsConfig = {
slug: [this.jump.slug, Validators.required], slug: [this.jump.slug, Validators.required],
@@ -1,4 +1,4 @@
import { Component, Inject } from '@angular/core'; import { Component, inject } from '@angular/core';
import { DatePipe, DecimalPipe } from '@angular/common'; import { DatePipe, DecimalPipe } from '@angular/common';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog'; import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
@@ -13,10 +13,8 @@ import { Jump } from '@models';
imports: [DatePipe, DecimalPipe, MatButtonModule, MatDialogModule, MatDividerModule, MatIconModule], imports: [DatePipe, DecimalPipe, MatButtonModule, MatDialogModule, MatDividerModule, MatIconModule],
}) })
export class JumpViewDialogComponent { export class JumpViewDialogComponent {
constructor( dialogRef = inject<MatDialogRef<JumpViewDialogComponent>>(MatDialogRef);
public dialogRef: MatDialogRef<JumpViewDialogComponent>, jump = inject<Jump>(MAT_DIALOG_DATA);
@Inject(MAT_DIALOG_DATA) public jump: Jump,
) {}
closeDialog(): void { closeDialog(): void {
// close the dialog without result // close the dialog without result
+10 -12
View File
@@ -1,6 +1,6 @@
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { trigger, state, style, animate, transition } from '@angular/animations'; import { trigger, state, style, animate, transition } from '@angular/animations';
import { Component, AfterContentChecked, OnInit, OnDestroy, computed, signal, Signal } from '@angular/core'; import { Component, AfterContentChecked, OnInit, OnDestroy, computed, signal, Signal, inject } from '@angular/core';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { ActivatedRoute, Router, RouterModule } from '@angular/router'; import { ActivatedRoute, Router, RouterModule } from '@angular/router';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
@@ -58,6 +58,15 @@ import data from 'src/jumps.json';
], ],
}) })
export class LogbookComponent implements OnInit, OnDestroy, AfterContentChecked { export class LogbookComponent implements OnInit, OnDestroy, AfterContentChecked {
private route = inject(ActivatedRoute);
private router = inject(Router);
private dialog = inject(MatDialog);
private snackBar = inject(MatSnackBar);
private _jumpsService = inject(JumpsService);
private _jumpTableService = inject(JumpTableService);
private _userService = inject(UserService);
menuItems = inject(MenuItems);
private _currentUser: Subscription = new Subscription(); private _currentUser: Subscription = new Subscription();
private _subscriptions: Array<Subscription> = []; private _subscriptions: Array<Subscription> = [];
private _data: Subscription = new Subscription(); private _data: Subscription = new Subscription();
@@ -92,17 +101,6 @@ export class LogbookComponent implements OnInit, OnDestroy, AfterContentChecked
year: { start: 1970, end: 2020 }, year: { start: 1970, end: 2020 },
}; };
constructor(
private route: ActivatedRoute,
private router: Router,
private dialog: MatDialog,
private snackBar: MatSnackBar,
private _jumpsService: JumpsService,
private _jumpTableService: JumpTableService,
private _userService: UserService,
public menuItems: MenuItems,
) {}
ngOnInit() { ngOnInit() {
//this.importJumps(); //this.importJumps();
const data$: Observable<{ isAuthenticated: boolean; lastjump: Jump }> = this.route.data as Observable<{ const data$: Observable<{ isAuthenticated: boolean; lastjump: Jump }> = this.route.data as Observable<{
+3 -5
View File
@@ -26,6 +26,9 @@ import { Errors, Article, ArticlePageData } from '@models';
], ],
}) })
export class PageComponent implements OnInit, OnDestroy { export class PageComponent implements OnInit, OnDestroy {
private route = inject(ActivatedRoute);
private titleService = inject(Title);
private _data: Subscription = new Subscription(); private _data: Subscription = new Subscription();
public title = 'Shop bientôt disponible!'; public title = 'Shop bientôt disponible!';
public description = "Encore un peu de patience, notre shop sera mis en ligne d'ici peu."; public description = "Encore un peu de patience, notre shop sera mis en ligne d'ici peu.";
@@ -33,11 +36,6 @@ export class PageComponent implements OnInit, OnDestroy {
public destroyRef = inject(DestroyRef); public destroyRef = inject(DestroyRef);
public article: Article = {} as Article; public article: Article = {} as Article;
constructor(
private route: ActivatedRoute,
private titleService: Title,
) {}
ngOnInit() { ngOnInit() {
const data$: Observable<{ pageData: ArticlePageData }> = this.route.data as Observable<{ const data$: Observable<{ pageData: ArticlePageData }> = this.route.data as Observable<{
pageData: ArticlePageData; pageData: ArticlePageData;
@@ -26,6 +26,9 @@ import { Errors, Product, ProductPageData } from '@models';
], ],
}) })
export class ProductComponent implements OnInit, OnDestroy { export class ProductComponent implements OnInit, OnDestroy {
private route = inject(ActivatedRoute);
private titleService = inject(Title);
private _data: Subscription = new Subscription(); private _data: Subscription = new Subscription();
public title = 'Ad Astra - Produit'; public title = 'Ad Astra - Produit';
public description = "Encore un peu de patience, notre shop sera mis en ligne d'ici peu."; public description = "Encore un peu de patience, notre shop sera mis en ligne d'ici peu.";
@@ -33,11 +36,6 @@ export class ProductComponent implements OnInit, OnDestroy {
public destroyRef = inject(DestroyRef); public destroyRef = inject(DestroyRef);
public product: Product = {} as Product; public product: Product = {} as Product;
constructor(
private route: ActivatedRoute,
private titleService: Title,
) {}
ngOnInit() { ngOnInit() {
const data$: Observable<{ pageData: ProductPageData }> = this.route.data as Observable<{ const data$: Observable<{ pageData: ProductPageData }> = this.route.data as Observable<{
pageData: ProductPageData; pageData: ProductPageData;
@@ -36,6 +36,9 @@ import { Errors, Product, ProductsPageData } from '@models';
], ],
}) })
export class ProductsComponent implements OnInit, OnDestroy { export class ProductsComponent implements OnInit, OnDestroy {
private route = inject(ActivatedRoute);
private titleService = inject(Title);
private _data: Subscription = new Subscription(); private _data: Subscription = new Subscription();
public title = 'Ad Astra - Produit'; public title = 'Ad Astra - Produit';
public description = "Encore un peu de patience, notre shop sera mis en ligne d'ici peu."; public description = "Encore un peu de patience, notre shop sera mis en ligne d'ici peu.";
@@ -44,11 +47,6 @@ export class ProductsComponent implements OnInit, OnDestroy {
public products: Array<Product> = []; public products: Array<Product> = [];
public productsCount = 0; public productsCount = 0;
constructor(
private route: ActivatedRoute,
private titleService: Title,
) {}
ngOnInit() { ngOnInit() {
const data$: Observable<{ pageData: ProductsPageData }> = this.route.data as Observable<{ const data$: Observable<{ pageData: ProductsPageData }> = this.route.data as Observable<{
pageData: ProductsPageData; pageData: ProductsPageData;
@@ -1,4 +1,4 @@
import { Component, OnInit, OnDestroy } from '@angular/core'; import { Component, OnInit, OnDestroy, inject } from '@angular/core';
import { Title } from '@angular/platform-browser'; import { Title } from '@angular/platform-browser';
import { RouterLink } from '@angular/router'; import { RouterLink } from '@angular/router';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
@@ -19,6 +19,9 @@ import { ListErrorsComponent } from '@components/shared';
styleUrl: './profile.component.scss', styleUrl: './profile.component.scss',
}) })
export class ProfileComponent implements OnInit, OnDestroy { export class ProfileComponent implements OnInit, OnDestroy {
private titleService = inject(Title);
private userService = inject(UserService);
private _user: Subscription = new Subscription(); private _user: Subscription = new Subscription();
title = 'Mon compte'; title = 'Mon compte';
bannerTitle = ''; bannerTitle = '';
@@ -26,11 +29,6 @@ export class ProfileComponent implements OnInit, OnDestroy {
errors: Errors = { errors: {} }; errors: Errors = { errors: {} };
btnSettingsTitle = 'Paramètres'; btnSettingsTitle = 'Paramètres';
constructor(
private titleService: Title,
private userService: UserService,
) {}
ngOnInit() { ngOnInit() {
this.titleService.setTitle(`Ad Astra - ${this.title}`); this.titleService.setTitle(`Ad Astra - ${this.title}`);
Object.assign(this.user, this.userService.getCurrentUser()); Object.assign(this.user, this.userService.getCurrentUser());
+7 -7
View File
@@ -40,6 +40,12 @@ import data from 'src/qcm-bpa.json';
styleUrl: './qcm.component.scss', styleUrl: './qcm.component.scss',
}) })
export class QcmComponent implements OnInit, OnDestroy { export class QcmComponent implements OnInit, OnDestroy {
private route = inject(ActivatedRoute);
private fb = inject(FormBuilder);
private _qcmService = inject(QcmService);
private _userService = inject(UserService);
menuItems = inject(MenuItems);
private _currentUser: Subscription = new Subscription(); private _currentUser: Subscription = new Subscription();
private _data: Subscription = new Subscription(); private _data: Subscription = new Subscription();
private _timer: Subscription = new Subscription(); private _timer: Subscription = new Subscription();
@@ -61,13 +67,7 @@ export class QcmComponent implements OnInit, OnDestroy {
public timeProgressColor = 'primary'; public timeProgressColor = 'primary';
public timeMax = 60 * 45; public timeMax = 60 * 45;
constructor( constructor() {
private route: ActivatedRoute,
private fb: FormBuilder,
private _qcmService: QcmService,
private _userService: UserService,
public menuItems: MenuItems,
) {
this.qcmForm = this.fb.group({ this.qcmForm = this.fb.group({
questions: this.fb.array([]), questions: this.fb.array([]),
}); });
@@ -41,6 +41,11 @@ import { ListErrorsComponent } from '@components/shared';
styleUrl: './credentials.component.scss', styleUrl: './credentials.component.scss',
}) })
export class CredentialsComponent implements OnInit, OnDestroy { export class CredentialsComponent implements OnInit, OnDestroy {
private router = inject(Router);
private titleService = inject(Title);
private userService = inject(UserService);
private fb = inject(UntypedFormBuilder);
private _user: Subscription = new Subscription(); private _user: Subscription = new Subscription();
title = 'Modifier le mot de passe'; title = 'Modifier le mot de passe';
bannerTitle = ''; bannerTitle = '';
@@ -52,12 +57,7 @@ export class CredentialsComponent implements OnInit, OnDestroy {
isSubmitting = false; isSubmitting = false;
destroyRef = inject(DestroyRef); destroyRef = inject(DestroyRef);
constructor( constructor() {
private router: Router,
private titleService: Title,
private userService: UserService,
private fb: UntypedFormBuilder,
) {
this.credentialsForm = this.fb.group( this.credentialsForm = this.fb.group(
{ {
password: ['', Validators.required], password: ['', Validators.required],
@@ -34,6 +34,11 @@ import { ListErrorsComponent } from '@components/shared';
templateUrl: './settings.component.html', templateUrl: './settings.component.html',
}) })
export class SettingsComponent implements OnInit, OnDestroy { export class SettingsComponent implements OnInit, OnDestroy {
private router = inject(Router);
private titleService = inject(Title);
private userService = inject(UserService);
private fb = inject(UntypedFormBuilder);
private _user: Subscription = new Subscription(); private _user: Subscription = new Subscription();
title = 'Vos paramètres'; title = 'Vos paramètres';
bannerTitle = ''; bannerTitle = '';
@@ -66,12 +71,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
`${this.imgPath}animal_016${this.imgExt}`, `${this.imgPath}animal_016${this.imgExt}`,
]; ];
constructor( constructor() {
private router: Router,
private titleService: Title,
private userService: UserService,
private fb: UntypedFormBuilder,
) {
// create form group using the form builder // create form group using the form builder
this.settingsForm = this.fb.group({ this.settingsForm = this.fb.group({
username: ['', Validators.required], username: ['', Validators.required],
@@ -1,55 +1,57 @@
import { Directive, AfterContentChecked } from '@angular/core'; import { Directive, AfterContentChecked, inject } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router'; import { Router, NavigationEnd } from '@angular/router';
import { AccordionLinkDirective } from './accordionlink.directive'; import { AccordionLinkDirective } from './accordionlink.directive';
import { filter } from 'rxjs/operators'; import { filter } from 'rxjs/operators';
@Directive({ @Directive({
selector: '[appAccordion]', selector: '[appAccordion]',
standalone: true standalone: true,
}) })
export class AccordionDirective implements AfterContentChecked { export class AccordionDirective implements AfterContentChecked {
protected navlinks: Array<AccordionLinkDirective> = []; private router = inject(Router);
closeOtherLinks(selectedLink: AccordionLinkDirective): void { protected navlinks: Array<AccordionLinkDirective> = [];
this.navlinks.forEach((link: AccordionLinkDirective) => {
if (link !== selectedLink) { closeOtherLinks(selectedLink: AccordionLinkDirective): void {
link.selected = false; this.navlinks.forEach((link: AccordionLinkDirective) => {
} if (link !== selectedLink) {
}); link.selected = false;
} }
});
addLink(link: AccordionLinkDirective): void { }
this.navlinks.push(link);
} addLink(link: AccordionLinkDirective): void {
this.navlinks.push(link);
removeGroup(link: AccordionLinkDirective): void { }
const index = this.navlinks.indexOf(link);
if (index !== -1) { removeGroup(link: AccordionLinkDirective): void {
this.navlinks.splice(index, 1); const index = this.navlinks.indexOf(link);
} if (index !== -1) {
} this.navlinks.splice(index, 1);
}
checkOpenLinks() { }
this.navlinks.forEach((link: AccordionLinkDirective) => {
if (link.group) { checkOpenLinks() {
const routeUrl = this.router.url; this.navlinks.forEach((link: AccordionLinkDirective) => {
const currentUrl = routeUrl.split('/'); if (link.group) {
if (currentUrl.indexOf(link.group) > 0) { const routeUrl = this.router.url;
link.selected = true; const currentUrl = routeUrl.split('/');
this.closeOtherLinks(link); if (currentUrl.indexOf(link.group) > 0) {
} link.selected = true;
} this.closeOtherLinks(link);
}); }
} }
});
ngAfterContentChecked(): void { }
this.router.events
.pipe(filter(event => event instanceof NavigationEnd)) ngAfterContentChecked(): void {
.subscribe(() => this.checkOpenLinks()); this.router.events
} .pipe(filter((event) => event instanceof NavigationEnd))
.subscribe(() => this.checkOpenLinks());
constructor(private router: Router) { }
setTimeout(() => this.checkOpenLinks());
} constructor() {
} setTimeout(() => this.checkOpenLinks());
}
}
@@ -1,20 +1,22 @@
import { Directive, HostListener, Inject } from '@angular/core'; import { Directive, HostListener, inject } from '@angular/core';
import { AccordionLinkDirective } from './accordionlink.directive'; import { AccordionLinkDirective } from './accordionlink.directive';
@Directive({ @Directive({
selector: '[appAccordionToggle]', selector: '[appAccordionToggle]',
standalone: true standalone: true,
}) })
export class AccordionAnchorDirective { export class AccordionAnchorDirective {
protected navlink: AccordionLinkDirective; protected navlink: AccordionLinkDirective;
constructor(@Inject(AccordionLinkDirective) navlink: AccordionLinkDirective) { constructor() {
this.navlink = navlink; const navlink = inject<AccordionLinkDirective>(AccordionLinkDirective);
}
this.navlink = navlink;
@HostListener('click', ['$event']) }
onClick() {
this.navlink.toggle(); @HostListener('click', ['$event'])
} onClick() {
} this.navlink.toggle();
}
}
@@ -1,51 +1,46 @@
import { import { Directive, HostBinding, Input, OnInit, OnDestroy, inject } from '@angular/core';
Directive,
HostBinding, import { AccordionDirective } from './accordion.directive';
Inject,
Input, @Directive({
OnInit, selector: '[appAccordionLink]',
OnDestroy standalone: true,
} from '@angular/core'; })
export class AccordionLinkDirective implements OnInit, OnDestroy {
import { AccordionDirective } from './accordion.directive'; @Input()
public group!: string;
@Directive({
selector: '[appAccordionLink]', @HostBinding('class.selected')
standalone: true @Input()
}) get selected(): boolean {
export class AccordionLinkDirective implements OnInit, OnDestroy { return this._selected;
@Input() }
public group!: string;
set selected(value: boolean) {
@HostBinding('class.selected') this._selected = value;
@Input() if (value) {
get selected(): boolean { this.nav.closeOtherLinks(this);
return this._selected; }
} }
set selected(value: boolean) { protected _selected: boolean = false;
this._selected = value; protected nav: AccordionDirective;
if (value) {
this.nav.closeOtherLinks(this); constructor() {
} const nav = inject<AccordionDirective>(AccordionDirective);
}
this.nav = nav;
protected _selected: boolean = false; }
protected nav: AccordionDirective;
ngOnInit() {
constructor(@Inject(AccordionDirective) nav: AccordionDirective) { this.nav.addLink(this);
this.nav = nav; }
}
ngOnDestroy() {
ngOnInit() { this.nav.removeGroup(this);
this.nav.addLink(this); }
}
toggle() {
ngOnDestroy(){ this.selected = !this.selected;
this.nav.removeGroup(this); }
} }
toggle() {
this.selected = !this.selected;
}
}
@@ -29,6 +29,10 @@ import { AeronefByImat, AeronefByYear } from '@models';
templateUrl: './aeronefs-bar.component.html', templateUrl: './aeronefs-bar.component.html',
}) })
export class AeronefsBarComponent implements OnInit, OnDestroy { export class AeronefsBarComponent implements OnInit, OnDestroy {
private _aeronefsService = inject(AeronefsService);
private _utilitiesService = inject(UtilitiesService);
menuItems = inject(MenuItems);
private _aeronefByImat: Subscription = new Subscription(); private _aeronefByImat: Subscription = new Subscription();
private _aeronefByYear: Subscription = new Subscription(); private _aeronefByYear: Subscription = new Subscription();
private _aeronefsByImat!: Array<AeronefByImat>; private _aeronefsByImat!: Array<AeronefByImat>;
@@ -50,12 +54,6 @@ export class AeronefsBarComponent implements OnInit, OnDestroy {
public displayCharts = false; public displayCharts = false;
public destroyRef = inject(DestroyRef); public destroyRef = inject(DestroyRef);
constructor(
private _aeronefsService: AeronefsService,
private _utilitiesService: UtilitiesService,
public menuItems: MenuItems,
) {}
ngOnInit() { ngOnInit() {
this._loadAeronefByImat(); this._loadAeronefByImat();
} }
@@ -31,6 +31,10 @@ import { AeronefByImat, AeronefByYear } from '@models';
templateUrl: './aeronefs-pie.component.html', templateUrl: './aeronefs-pie.component.html',
}) })
export class AeronefsPieComponent implements OnInit, OnDestroy { export class AeronefsPieComponent implements OnInit, OnDestroy {
private _aeronefsService = inject(AeronefsService);
private _utilitiesService = inject(UtilitiesService);
menuItems = inject(MenuItems);
private _aeronefByImat: Subscription = new Subscription(); private _aeronefByImat: Subscription = new Subscription();
private _aeronefByYear: Subscription = new Subscription(); private _aeronefByYear: Subscription = new Subscription();
private _aeronefsByImat!: Array<AeronefByImat>; private _aeronefsByImat!: Array<AeronefByImat>;
@@ -51,12 +55,6 @@ export class AeronefsPieComponent implements OnInit, OnDestroy {
public seriesColorClass: string[] = this._utilitiesService.getChartColors(); public seriesColorClass: string[] = this._utilitiesService.getChartColors();
public destroyRef = inject(DestroyRef); public destroyRef = inject(DestroyRef);
constructor(
private _aeronefsService: AeronefsService,
private _utilitiesService: UtilitiesService,
public menuItems: MenuItems,
) {}
ngOnInit() { ngOnInit() {
this._loadAeronefByImat(); this._loadAeronefByImat();
} }
@@ -29,6 +29,10 @@ import { CanopyModelBySize, CanopyModelByYear } from '@models';
templateUrl: './canopies-models.component.html', templateUrl: './canopies-models.component.html',
}) })
export class CanopiesModelsComponent implements OnInit, OnDestroy { export class CanopiesModelsComponent implements OnInit, OnDestroy {
private _canopiesService = inject(CanopiesService);
private _utilitiesService = inject(UtilitiesService);
menuItems = inject(MenuItems);
private _canopyBySize: Subscription = new Subscription(); private _canopyBySize: Subscription = new Subscription();
private _canopyByYear: Subscription = new Subscription(); private _canopyByYear: Subscription = new Subscription();
private _canopiesBySize!: Array<CanopyModelBySize>; private _canopiesBySize!: Array<CanopyModelBySize>;
@@ -49,12 +53,6 @@ export class CanopiesModelsComponent implements OnInit, OnDestroy {
public seriesColorClass: string[] = this._utilitiesService.getChartColors(); public seriesColorClass: string[] = this._utilitiesService.getChartColors();
public destroyRef = inject(DestroyRef); public destroyRef = inject(DestroyRef);
constructor(
private _canopiesService: CanopiesService,
private _utilitiesService: UtilitiesService,
public menuItems: MenuItems,
) {}
ngOnInit() { ngOnInit() {
this._loadCanopyModelBySize(); this._loadCanopyModelBySize();
} }
@@ -30,6 +30,10 @@ import { CanopyBySize, CanopyByYear } from '@models';
templateUrl: './canopies-sizes.component.html', templateUrl: './canopies-sizes.component.html',
}) })
export class CanopiesSizesComponent implements OnInit, OnDestroy { export class CanopiesSizesComponent implements OnInit, OnDestroy {
private _canopiesService = inject(CanopiesService);
private _utilitiesService = inject(UtilitiesService);
menuItems = inject(MenuItems);
private _canopyBySize: Subscription = new Subscription(); private _canopyBySize: Subscription = new Subscription();
private _canopyByYear: Subscription = new Subscription(); private _canopyByYear: Subscription = new Subscription();
private _canopiesBySize!: Array<CanopyBySize>; private _canopiesBySize!: Array<CanopyBySize>;
@@ -50,12 +54,6 @@ export class CanopiesSizesComponent implements OnInit, OnDestroy {
public seriesColorClass: string[] = this._utilitiesService.getChartColors(); public seriesColorClass: string[] = this._utilitiesService.getChartColors();
public destroyRef = inject(DestroyRef); public destroyRef = inject(DestroyRef);
constructor(
private _canopiesService: CanopiesService,
private _utilitiesService: UtilitiesService,
public menuItems: MenuItems,
) {}
ngOnInit() { ngOnInit() {
this._loadCanopyBySize(); this._loadCanopyBySize();
} }
@@ -8,19 +8,22 @@
</button> </button>
<mat-menu #menuDropzoneBar="matMenu"> <mat-menu #menuDropzoneBar="matMenu">
@for (menuitem of menuItems.getMenuPanel(); track menuitem) { @for (menuitem of menuItems.getMenuPanel(); track menuitem) {
<button mat-menu-item> <button mat-menu-item>
<mat-icon [fontIcon]="menuitem.icon"></mat-icon> <mat-icon [fontIcon]="menuitem.icon"></mat-icon>
<span>{{ menuitem.name }}</span> <span>{{ menuitem.name }}</span>
</button> </button>
} }
</mat-menu> </mat-menu>
</mat-card-header> </mat-card-header>
<mat-divider class="my-3"></mat-divider> <mat-divider class="my-3"></mat-divider>
<mat-card-content> <mat-card-content>
@if (displayCharts) { @if (displayCharts) {
<div class="barchart position-relative w-100 my-1"> <app-bars-chart
<x-chartist [configuration]="barChartDropZones"></x-chartist> [names]="seriesName"
</div> [values]="seriesRow"
[headers]="seriesHeader"
[colors]="seriesColor"
></app-bars-chart>
} }
</mat-card-content> </mat-card-content>
<mat-divider class="mt-3 mb-0"></mat-divider> <mat-divider class="mt-3 mb-0"></mat-divider>
@@ -29,7 +32,13 @@
<mat-expansion-panel-header> <mat-expansion-panel-header>
<mat-panel-title>Historique annuel</mat-panel-title> <mat-panel-title>Historique annuel</mat-panel-title>
</mat-expansion-panel-header> </mat-expansion-panel-header>
<app-history-table [headers]="seriesHeader" [names]="seriesName" [values]="seriesValue" [rows]="seriesRow" [colors]="seriesColorClass"></app-history-table> <app-history-table
[headers]="seriesHeader"
[names]="seriesName"
[values]="seriesValue"
[rows]="seriesRow"
[colors]="seriesColorClass"
></app-history-table>
</mat-expansion-panel> </mat-expansion-panel>
</mat-accordion> </mat-accordion>
</mat-card> </mat-card>
@@ -6,12 +6,10 @@ import { MatDividerModule } from '@angular/material/divider';
import { MatExpansionModule } from '@angular/material/expansion'; import { MatExpansionModule } from '@angular/material/expansion';
import { MatIconModule } from '@angular/material/icon'; import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu'; import { MatMenuModule } from '@angular/material/menu';
import { BaseChartDirective } from 'ng2-charts';
import { ChartistModule, Configuration } from 'ng-chartist';
import { AxisOptions, Label } from 'chartist';
import { Observable, Subscription } from 'rxjs'; import { Observable, Subscription } from 'rxjs';
import { MenuItems } from '@components/shared'; import { MenuItems } from '@components/shared';
import { BarsChartComponent } from '@components/shared/helpers-chart';
import { HistoryTableComponent } from '@components/shared/helpers-jump'; import { HistoryTableComponent } from '@components/shared/helpers-jump';
import { UtilitiesService, DropZonesService } from '@services'; import { UtilitiesService, DropZonesService } from '@services';
import { DropZoneByOaci, DropZoneByYear } from '@models'; import { DropZoneByOaci, DropZoneByYear } from '@models';
@@ -25,13 +23,16 @@ import { DropZoneByOaci, DropZoneByYear } from '@models';
MatExpansionModule, MatExpansionModule,
MatIconModule, MatIconModule,
MatMenuModule, MatMenuModule,
BaseChartDirective, BarsChartComponent,
ChartistModule,
HistoryTableComponent, HistoryTableComponent,
], ],
templateUrl: './dropzones-bar.component.html', templateUrl: './dropzones-bar.component.html',
}) })
export class DropzonesBarComponent implements OnInit, OnDestroy { export class DropzonesBarComponent implements OnInit, OnDestroy {
private _dropzonesService = inject(DropZonesService);
private _utilitiesService = inject(UtilitiesService);
menuItems = inject(MenuItems);
private _dropzoneByOaci: Subscription = new Subscription(); private _dropzoneByOaci: Subscription = new Subscription();
private _dropzoneByYear: Subscription = new Subscription(); private _dropzoneByYear: Subscription = new Subscription();
private _dropzonesByOaci!: Array<DropZoneByOaci>; private _dropzonesByOaci!: Array<DropZoneByOaci>;
@@ -51,15 +52,8 @@ export class DropzonesBarComponent implements OnInit, OnDestroy {
}; };
public seriesColorClass: string[] = this._utilitiesService.getChartColors(); public seriesColorClass: string[] = this._utilitiesService.getChartColors();
public displayCharts = false; public displayCharts = false;
public barChartDropZones: Configuration = this._utilitiesService.getBarConfig();
public destroyRef = inject(DestroyRef); public destroyRef = inject(DestroyRef);
constructor(
private _dropzonesService: DropZonesService,
private _utilitiesService: UtilitiesService,
public menuItems: MenuItems,
) {}
ngOnInit() { ngOnInit() {
this._loadDropZoneByOaci(); this._loadDropZoneByOaci();
} }
@@ -101,60 +95,6 @@ export class DropzonesBarComponent implements OnInit, OnDestroy {
row.count; row.count;
return row; return row;
}); });
const axisX: AxisOptions = {
labelInterpolationFnc: function (value: Label, index: number): string {
return index % 1 === 0 ? `${value.toString()}` : '';
},
};
this.barChartDropZones = {
type: 'Bar',
data: {
labels: this.seriesHeader,
series: this.seriesRow,
},
options: {
seriesBarDistance: 15,
horizontalBars: false,
high: 180,
axisX: {
showGrid: false,
offset: 20,
},
axisY: {
showGrid: true,
offset: 40,
},
height: 300,
},
responsiveOptions: [
[
'screen and (min-width: 1024px)',
{
axisX: axisX,
},
],
[
'screen and (min-width: 641px) and (max-width: 1024px)',
{
seriesBarDistance: 7,
axisY: {
offset: 30,
},
axisX: axisX,
},
],
[
'screen and (max-width: 640px)',
{
seriesBarDistance: 5,
axisY: {
offset: 20,
},
axisX: axisX,
},
],
],
};
this.displayCharts = true; this.displayCharts = true;
}); });
} }
@@ -30,6 +30,10 @@ import { DropZoneByOaci, DropZoneByYear } from '@models';
templateUrl: './dropzones-pie.component.html', templateUrl: './dropzones-pie.component.html',
}) })
export class DropzonesPieComponent implements OnInit, OnDestroy { export class DropzonesPieComponent implements OnInit, OnDestroy {
private _dropzonesService = inject(DropZonesService);
private _utilitiesService = inject(UtilitiesService);
menuItems = inject(MenuItems);
private _dropzoneByOaci: Subscription = new Subscription(); private _dropzoneByOaci: Subscription = new Subscription();
private _dropzoneByYear: Subscription = new Subscription(); private _dropzoneByYear: Subscription = new Subscription();
private _dropzonesByOaci!: Array<DropZoneByOaci>; private _dropzonesByOaci!: Array<DropZoneByOaci>;
@@ -50,12 +54,6 @@ export class DropzonesPieComponent implements OnInit, OnDestroy {
public seriesColorClass: string[] = this._utilitiesService.getChartColors(); public seriesColorClass: string[] = this._utilitiesService.getChartColors();
public destroyRef = inject(DestroyRef); public destroyRef = inject(DestroyRef);
constructor(
private _dropzonesService: DropZonesService,
private _utilitiesService: UtilitiesService,
public menuItems: MenuItems,
) {}
ngOnInit() { ngOnInit() {
this._loadDropZoneByOaci(); this._loadDropZoneByOaci();
} }
@@ -1,86 +1,88 @@
<mat-card> <mat-card>
<mat-card-header> <mat-card-header>
<mat-card-title>{{ title }}</mat-card-title> <mat-card-title>{{ title }}</mat-card-title>
<mat-card-subtitle>{{ subtitle }} de {{min}} à {{max}}</mat-card-subtitle> <mat-card-subtitle>{{ subtitle }} de {{ min }} à {{ max }}</mat-card-subtitle>
<span class="flex-spacer"></span> <span class="flex-spacer"></span>
<button mat-icon-button [matMenuTriggerFor]="menuJumpBar" aria-label="Menu Dropzone Bar"> <button mat-icon-button [matMenuTriggerFor]="menuJumpBar" aria-label="Menu Dropzone Bar">
<mat-icon fontIcon="more_vert"></mat-icon> <mat-icon fontIcon="more_vert"></mat-icon>
</button> </button>
<mat-menu #menuJumpBar="matMenu"> <mat-menu #menuJumpBar="matMenu">
<button mat-menu-item *ngFor="let menuitem of menuItems.getMenuPanel()"> <button mat-menu-item *ngFor="let menuitem of menuItems.getMenuPanel()">
<mat-icon [fontIcon]="menuitem.icon"></mat-icon> <mat-icon [fontIcon]="menuitem.icon"></mat-icon>
<span>{{ menuitem.name }}</span> <span>{{ menuitem.name }}</span>
</button> </button>
</mat-menu> </mat-menu>
</mat-card-header> </mat-card-header>
<mat-divider class="my-3"></mat-divider> <mat-divider class="my-3"></mat-divider>
<mat-card-content> <mat-card-content>
<!-- @if (displayCharts) {
<div class="text-center mb-3"> <app-bars-chart
<ul class="list-inline my-0"> [names]="seriesName"
<li *ngFor='let name of seriesName; let i=index' class="list-inline-item me-lg-3 me-sm-2"> [values]="seriesRow"
<span class="{{seriesColor[i]}} fs-6 m-0"> [headers]="seriesHeader"
● {{name}} [colors]="seriesColor"
</span> ></app-bars-chart>
</li> }
</ul> </mat-card-content>
</div> <mat-divider class="mt-3 mb-0"></mat-divider>
--> <mat-accordion>
<div *ngIf="displayCharts" class="barchart position-relative w-100 my-1"> <mat-expansion-panel>
<x-chartist [configuration]="barChartJumps"></x-chartist> <mat-expansion-panel-header>
</div> <mat-panel-title>Historique annuel</mat-panel-title>
</mat-card-content> </mat-expansion-panel-header>
<mat-divider class="mt-3 mb-0"></mat-divider> <table class="table table-striped table-dark table-hover">
<mat-accordion> <thead>
<mat-expansion-panel> <tr>
<mat-expansion-panel-header> <th></th>
<mat-panel-title>Historique annuel</mat-panel-title> <th *ngFor="let name of seriesHeader; let i = index" class="text-end">{{ name }}</th>
</mat-expansion-panel-header> <th class="text-end">Total</th>
<table class="table table-striped table-dark table-hover"> </tr>
<thead> </thead>
<tr> <tbody>
<th></th> <tr *ngFor="let values of seriesRow; let i = index">
<th *ngFor='let name of seriesHeader; let i=index' class="text-end"> {{ name }} </th> <th class="{{ seriesColorClass[i] }} text-end"> {{ seriesName[i] }}</th>
<th class="text-end">Total</th> <td *ngFor="let value of values; let i = index" class="font-monospace text-end">
</tr> <span *ngIf="value; else elseBlock" class="pr-1">{{ value }}</span>
</thead> <ng-template #elseBlock
<tbody> ><span class="text-empty pr-1">{{ value }}</span></ng-template
<tr *ngFor='let values of seriesRow; let i=index'> >
<th class="{{seriesColorClass[i]}} text-end"> ● {{ seriesName[i] }} </th> </td>
<td *ngFor='let value of values; let i=index' class="font-monospace text-end"> <th class="{{ seriesColorClass[i] }} font-monospace text-end">{{ seriesRowTotal[i] }}</th>
<span *ngIf="value; else elseBlock" class="pr-1">{{ value }}</span> </tr>
<ng-template #elseBlock><span class="text-empty pr-1">{{ value }}</span></ng-template> </tbody>
</td> <tfoot>
<th class="{{seriesColorClass[i]}} font-monospace text-end">{{ seriesRowTotal[i] }}</th> <tr>
</tr> <th class="text-end">Total</th>
</tbody> <th *ngFor="let value of seriesColTotal; let i = index" class="font-monospace text-end">
<tfoot> <span *ngIf="value; else elseBlock" class="pr-1">{{ value }}</span>
<tr> <ng-template #elseBlock
<th class="text-end">Total</th> ><span class="text-empty pr-1">{{ value }}</span></ng-template
<th *ngFor='let value of seriesColTotal; let i=index' class="font-monospace text-end"> >
<span *ngIf="value; else elseBlock" class="pr-1">{{ value }}</span> </th>
<ng-template #elseBlock><span class="text-empty pr-1">{{ value }}</span></ng-template> <th class="font-monospace text-end">{{ grandTotal }}</th>
</th> </tr>
<th class="font-monospace text-end">{{ grandTotal }}</th> <tr>
</tr> <th class="text-end">Moyenne</th>
<tr> <th *ngFor="let value of seriesRowAvg; let i = index" class="font-monospace text-end">
<th class="text-end">Moyenne</th> <span *ngIf="value; else elseBlock" class="pr-1">{{ value | number: "1.0-1" }}</span>
<th *ngFor='let value of seriesRowAvg; let i=index' class="font-monospace text-end"> <ng-template #elseBlock
<span *ngIf="value; else elseBlock" class="pr-1">{{ value | number : '1.0-1' }}</span> ><span class="text-empty pr-1">{{ value | number: "1.0-1" }}</span></ng-template
<ng-template #elseBlock><span class="text-empty pr-1">{{ value | number : '1.0-1' }}</span></ng-template> >
</th> </th>
<th class="font-monospace text-end">{{ grandAvg | number : '1.0-1' }}</th> <th class="font-monospace text-end">{{ grandAvg | number: "1.0-1" }}</th>
</tr> </tr>
<tr> <tr>
<th class="text-end">Moyenne <small>3 dernières années</small></th> <th class="text-end">Moyenne <small>3 dernières années</small></th>
<th *ngFor='let value of seriesRowAvgLastYears; let i=index' class="font-monospace text-end"> <th *ngFor="let value of seriesRowAvgLastYears; let i = index" class="font-monospace text-end">
<span *ngIf="value; else elseBlock" class="pr-1">{{ value | number : '1.0-1' }}</span> <span *ngIf="value; else elseBlock" class="pr-1">{{ value | number: "1.0-1" }}</span>
<ng-template #elseBlock><span class="text-empty pr-1">{{ value | number : '1.0-1' }}</span></ng-template> <ng-template #elseBlock
</th> ><span class="text-empty pr-1">{{ value | number: "1.0-1" }}</span></ng-template
<th class="font-monospace text-end">{{ grandAvgLastYears | number : '1.0-1' }}</th> >
</tr> </th>
</tfoot> <th class="font-monospace text-end">{{ grandAvgLastYears | number: "1.0-1" }}</th>
</table> </tr>
</mat-expansion-panel> </tfoot>
</mat-accordion> </table>
</mat-card> </mat-expansion-panel>
</mat-accordion>
</mat-card>
@@ -1,36 +1,40 @@
import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core'; import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { CommonModule } from '@angular/common'; import { NgFor, NgIf, DecimalPipe } from '@angular/common';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card'; import { MatCardModule } from '@angular/material/card';
import { MatDividerModule } from '@angular/material/divider'; import { MatDividerModule } from '@angular/material/divider';
import { MatExpansionModule } from '@angular/material/expansion'; import { MatExpansionModule } from '@angular/material/expansion';
import { MatIconModule } from '@angular/material/icon'; import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu'; import { MatMenuModule } from '@angular/material/menu';
import { ChartistModule, Configuration } from 'ng-chartist';
import { AxisOptions, Label } from 'chartist';
import { Observable, Subscription } from 'rxjs'; import { Observable, Subscription } from 'rxjs';
import { MenuItems } from '@components/shared'; import { MenuItems } from '@components/shared';
import { BarsChartComponent } from '@components/shared/helpers-chart';
import { UtilitiesService, JumpsService } from '@services'; import { UtilitiesService, JumpsService } from '@services';
import { JumpByDate } from '@models'; import { JumpByDate } from '@models';
@Component({ @Component({
selector: 'app-jumps-by-month', selector: 'app-jumps-by-month',
imports: [ imports: [
CommonModule, NgFor,
NgIf,
DecimalPipe,
MatButtonModule, MatButtonModule,
MatCardModule, MatCardModule,
MatDividerModule, MatDividerModule,
MatExpansionModule, MatExpansionModule,
MatIconModule, MatIconModule,
MatMenuModule, MatMenuModule,
ChartistModule, BarsChartComponent,
], ],
templateUrl: './jumps-by-month.component.html', templateUrl: './jumps-by-month.component.html',
}) })
export class JumpsByMonthComponent implements OnInit, OnDestroy { export class JumpsByMonthComponent implements OnInit, OnDestroy {
private _jumpsService = inject(JumpsService);
private _utilitiesService = inject(UtilitiesService);
menuItems = inject(MenuItems);
private _jumpByDate: Subscription = new Subscription(); private _jumpByDate: Subscription = new Subscription();
private _jumpsByDate!: Array<JumpByDate>; private _jumpsByDate!: Array<JumpByDate>;
private _jumpsByDateCount = 0; private _jumpsByDateCount = 0;
@@ -59,15 +63,8 @@ export class JumpsByMonthComponent implements OnInit, OnDestroy {
public seriesColTotalClosed: number[] = []; public seriesColTotalClosed: number[] = [];
public seriesColTotalLastYears: number[] = []; public seriesColTotalLastYears: number[] = [];
public displayCharts = false; public displayCharts = false;
public barChartJumps: Configuration = this._utilitiesService.getBarConfig();
public destroyRef = inject(DestroyRef); public destroyRef = inject(DestroyRef);
constructor(
private _jumpsService: JumpsService,
private _utilitiesService: UtilitiesService,
public menuItems: MenuItems,
) {}
ngOnInit() { ngOnInit() {
this._loadJumpByDate(); this._loadJumpByDate();
} }
@@ -130,59 +127,6 @@ export class JumpsByMonthComponent implements OnInit, OnDestroy {
0, 0,
); );
this.grandTotal = this.seriesColTotal.reduce((partialSum, accumulated) => partialSum + accumulated, 0); this.grandTotal = this.seriesColTotal.reduce((partialSum, accumulated) => partialSum + accumulated, 0);
const axisX: AxisOptions = {
labelInterpolationFnc: function (value: Label, index: number): string {
return index % 1 === 0 ? `${value.toString()}` : '';
},
};
this.barChartJumps = {
type: 'Bar',
data: {
labels: this.seriesHeader,
series: this.seriesRow,
},
options: {
seriesBarDistance: 15,
high: 70,
axisX: {
showGrid: false,
offset: 20,
},
axisY: {
showGrid: true,
offset: 40,
},
height: 300,
},
responsiveOptions: [
[
'screen and (min-width: 1024px)',
{
axisX: axisX,
},
],
[
'screen and (min-width: 641px) and (max-width: 1024px)',
{
seriesBarDistance: 10,
axisY: {
offset: 30,
},
axisX: axisX,
},
],
[
'screen and (max-width: 640px)',
{
seriesBarDistance: 5,
axisY: {
offset: 20,
},
axisX: axisX,
},
],
],
};
this.displayCharts = true; this.displayCharts = true;
}); });
} }
@@ -1,4 +1,4 @@
import { Component, Input, OnChanges } from '@angular/core'; import { Component, Input, OnChanges, inject } from '@angular/core';
import { ChartDataset } from 'chart.js'; import { ChartDataset } from 'chart.js';
import { BaseChartDirective } from 'ng2-charts'; import { BaseChartDirective } from 'ng2-charts';
@@ -11,11 +11,11 @@ import { BarConfig } from '@models';
templateUrl: './bar-chart.component.html', templateUrl: './bar-chart.component.html',
}) })
export class BarChartComponent implements OnChanges { export class BarChartComponent implements OnChanges {
private _utilitiesService = inject(UtilitiesService);
public displayCharts = false; public displayCharts = false;
public chartConfig: BarConfig = this._utilitiesService.getBarChartConfig(); public chartConfig: BarConfig = this._utilitiesService.getBarChartConfig();
constructor(private _utilitiesService: UtilitiesService) {}
@Input() names: string[] = []; @Input() names: string[] = [];
@Input() values: number[] = []; @Input() values: number[] = [];
@Input() headers: string[] = []; @Input() headers: string[] = [];
@@ -1,4 +1,4 @@
import { Component, Input, OnChanges } from '@angular/core'; import { Component, Input, OnChanges, inject } from '@angular/core';
import { ChartDataset } from 'chart.js'; import { ChartDataset } from 'chart.js';
import { BaseChartDirective } from 'ng2-charts'; import { BaseChartDirective } from 'ng2-charts';
@@ -11,11 +11,11 @@ import { BarConfig } from '@models';
templateUrl: './bar-horizontal-chart.component.html', templateUrl: './bar-horizontal-chart.component.html',
}) })
export class BarHorizontalChartComponent implements OnChanges { export class BarHorizontalChartComponent implements OnChanges {
private _utilitiesService = inject(UtilitiesService);
public displayCharts = false; public displayCharts = false;
public chartConfig: BarConfig = this._utilitiesService.getHorizontalBarChartConfig(); public chartConfig: BarConfig = this._utilitiesService.getHorizontalBarChartConfig();
constructor(private _utilitiesService: UtilitiesService) {}
@Input() names: string[] = []; @Input() names: string[] = [];
@Input() values: number[] = []; @Input() values: number[] = [];
@Input() headers: string[] = []; @Input() headers: string[] = [];
@@ -1,4 +1,4 @@
import { Component, Input, OnChanges, AfterContentChecked } from '@angular/core'; import { Component, Input, OnChanges, AfterContentChecked, inject } from '@angular/core';
import { ChartDataset } from 'chart.js'; import { ChartDataset } from 'chart.js';
import { BaseChartDirective } from 'ng2-charts'; import { BaseChartDirective } from 'ng2-charts';
@@ -11,11 +11,11 @@ import { BarConfig } from '@models';
templateUrl: './bars-chart.component.html', templateUrl: './bars-chart.component.html',
}) })
export class BarsChartComponent implements OnChanges, AfterContentChecked { export class BarsChartComponent implements OnChanges, AfterContentChecked {
private _utilitiesService = inject(UtilitiesService);
public displayCharts = false; public displayCharts = false;
public chartConfig: BarConfig = this._utilitiesService.getBarChartConfig(); public chartConfig: BarConfig = this._utilitiesService.getBarChartConfig();
constructor(private _utilitiesService: UtilitiesService) {}
@Input() names: string[] = []; @Input() names: string[] = [];
@Input() values: Array<Array<number>> = []; @Input() values: Array<Array<number>> = [];
@Input() headers: string[] = []; @Input() headers: string[] = [];
@@ -1,4 +1,4 @@
import { Component, Input, OnChanges } from '@angular/core'; import { Component, Input, OnChanges, inject } from '@angular/core';
//import { ChartDataset } from 'chart.js'; //import { ChartDataset } from 'chart.js';
import { BaseChartDirective } from 'ng2-charts'; import { BaseChartDirective } from 'ng2-charts';
@@ -11,11 +11,11 @@ import { CircleConfig } from '@models';
templateUrl: './circle-chart.component.html', templateUrl: './circle-chart.component.html',
}) })
export class CircleChartComponent implements OnChanges { export class CircleChartComponent implements OnChanges {
private _utilitiesService = inject(UtilitiesService);
public displayCharts = false; public displayCharts = false;
public chartConfig: CircleConfig = this._utilitiesService.getCircleChartConfig(); public chartConfig: CircleConfig = this._utilitiesService.getCircleChartConfig();
constructor(private _utilitiesService: UtilitiesService) {}
@Input() names: string[] = []; @Input() names: string[] = [];
@Input() values: number[] = []; @Input() values: number[] = [];
@Input() headers: string[] = []; @Input() headers: string[] = [];
@@ -1,4 +1,4 @@
import { Component, Input, OnChanges } from '@angular/core'; import { Component, Input, OnChanges, inject } from '@angular/core';
import { ChartDataset, Point } from 'chart.js'; import { ChartDataset, Point } from 'chart.js';
import { BaseChartDirective } from 'ng2-charts'; import { BaseChartDirective } from 'ng2-charts';
@@ -11,11 +11,11 @@ import { LineConfig } from '@models';
templateUrl: './line-chart.component.html', templateUrl: './line-chart.component.html',
}) })
export class LineChartComponent implements OnChanges { export class LineChartComponent implements OnChanges {
private _utilitiesService = inject(UtilitiesService);
public displayCharts = false; public displayCharts = false;
public chartConfig: LineConfig = this._utilitiesService.getLineChartConfig(); public chartConfig: LineConfig = this._utilitiesService.getLineChartConfig();
constructor(private _utilitiesService: UtilitiesService) {}
@Input() headers: string[] = []; @Input() headers: string[] = [];
@Input() names: string[] = []; @Input() names: string[] = [];
@Input() values: Array<Array<number>> = []; @Input() values: Array<Array<number>> = [];
@@ -1,4 +1,4 @@
import { Component, Input, OnChanges } from '@angular/core'; import { Component, Input, OnChanges, inject } from '@angular/core';
import { ChartDataset } from 'chart.js'; import { ChartDataset } from 'chart.js';
import { BaseChartDirective } from 'ng2-charts'; import { BaseChartDirective } from 'ng2-charts';
@@ -11,11 +11,11 @@ import { LineConfig } from '@models';
templateUrl: './linearea-chart.component.html', templateUrl: './linearea-chart.component.html',
}) })
export class LineAreaChartComponent implements OnChanges { export class LineAreaChartComponent implements OnChanges {
private _utilitiesService = inject(UtilitiesService);
public displayCharts = false; public displayCharts = false;
public chartConfig: LineConfig = this._utilitiesService.getStackedLineAreaChartConfig(); public chartConfig: LineConfig = this._utilitiesService.getStackedLineAreaChartConfig();
constructor(private _utilitiesService: UtilitiesService) {}
@Input() headers: string[] = []; @Input() headers: string[] = [];
@Input() names: string[] = []; @Input() names: string[] = [];
@Input() values: Array<Array<number>> = []; @Input() values: Array<Array<number>> = [];
@@ -1,4 +1,4 @@
import { Component, Input, OnChanges } from '@angular/core'; import { Component, Input, OnChanges, inject } from '@angular/core';
//import { ChartDataset } from 'chart.js'; //import { ChartDataset } from 'chart.js';
import { BaseChartDirective } from 'ng2-charts'; import { BaseChartDirective } from 'ng2-charts';
@@ -11,11 +11,11 @@ import { DoughnutConfig } from '@models';
templateUrl: './pie-chart.component.html', templateUrl: './pie-chart.component.html',
}) })
export class PieChartComponent implements OnChanges { export class PieChartComponent implements OnChanges {
private _utilitiesService = inject(UtilitiesService);
public displayCharts = false; public displayCharts = false;
public chartConfig: DoughnutConfig = this._utilitiesService.getDoughnutChartConfig(); public chartConfig: DoughnutConfig = this._utilitiesService.getDoughnutChartConfig();
constructor(private _utilitiesService: UtilitiesService) {}
@Input() names: string[] = []; @Input() names: string[] = [];
@Input() values: number[] = []; @Input() values: number[] = [];
@Input() headers: string[] = []; @Input() headers: string[] = [];
@@ -1,4 +1,4 @@
import { Component, OnInit, OnDestroy, Input } from '@angular/core'; import { Component, OnInit, OnDestroy, Input, inject } from '@angular/core';
import { NgClass, DatePipe } from '@angular/common'; import { NgClass, DatePipe } from '@angular/common';
import { RouterLink } from '@angular/router'; import { RouterLink } from '@angular/router';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
@@ -24,6 +24,8 @@ import { JumpPreviewComponent } from './jump-preview.component';
], ],
}) })
export class JumpListComponent implements OnInit, OnDestroy { export class JumpListComponent implements OnInit, OnDestroy {
private jumpsService = inject(JumpsService);
private _jumps: Subscription = new Subscription(); private _jumps: Subscription = new Subscription();
errors: Errors = { errors: {} }; errors: Errors = { errors: {} };
query!: JumpListConfig; query!: JumpListConfig;
@@ -34,8 +36,6 @@ export class JumpListComponent implements OnInit, OnDestroy {
pages: Array<number> = [1]; pages: Array<number> = [1];
lastUpdate: Date = new Date(); lastUpdate: Date = new Date();
constructor(private jumpsService: JumpsService) {}
@Input() limit = 0; @Input() limit = 0;
@Input() refresh = 30000; @Input() refresh = 30000;
@Input() title = ''; @Input() title = '';
@@ -1,4 +1,4 @@
import { Component, OnDestroy, Input } from '@angular/core'; import { Component, OnDestroy, Input, inject } from '@angular/core';
import { DecimalPipe } from '@angular/common'; import { DecimalPipe } from '@angular/common';
import { Router, RouterLink } from '@angular/router'; import { Router, RouterLink } from '@angular/router';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
@@ -17,17 +17,15 @@ import { JumpsService } from '@services';
templateUrl: './jump-preview.component.html', templateUrl: './jump-preview.component.html',
}) })
export class JumpPreviewComponent implements OnDestroy { export class JumpPreviewComponent implements OnDestroy {
private router = inject(Router);
private jumpsService = inject(JumpsService);
@Input() jump!: Jump; @Input() jump!: Jump;
@Input() isUser!: boolean; @Input() isUser!: boolean;
@Input() showMeta!: boolean; @Input() showMeta!: boolean;
private _jump: Subscription = new Subscription(); private _jump: Subscription = new Subscription();
isDeleting = false; isDeleting = false;
constructor(
private router: Router,
private jumpsService: JumpsService,
) {}
ngOnDestroy() { ngOnDestroy() {
this._jump.unsubscribe(); this._jump.unsubscribe();
} }
@@ -7,6 +7,7 @@ import {
OnChanges, OnChanges,
OnDestroy, OnDestroy,
ViewChild, ViewChild,
inject,
} from '@angular/core'; } from '@angular/core';
import { CommonModule, DecimalPipe, DatePipe } from '@angular/common'; import { CommonModule, DecimalPipe, DatePipe } from '@angular/common';
import { UntypedFormBuilder, UntypedFormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { UntypedFormBuilder, UntypedFormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
@@ -88,6 +89,13 @@ import {
providers: [{ provide: MatPaginatorIntl, useClass: FrenchPaginator }], providers: [{ provide: MatPaginatorIntl, useClass: FrenchPaginator }],
}) })
export class JumpTableComponent implements OnChanges, OnDestroy, AfterContentChecked { export class JumpTableComponent implements OnChanges, OnDestroy, AfterContentChecked {
private router = inject(Router);
private _jumpsService = inject(JumpsService);
private _jumpTableService = inject(JumpTableService);
private dialog = inject(MatDialog);
private fb = inject(UntypedFormBuilder);
private snackBar = inject(MatSnackBar);
private _jumps: Subscription = new Subscription(); private _jumps: Subscription = new Subscription();
private _subscriptions: Array<Subscription> = []; private _subscriptions: Array<Subscription> = [];
//private _jump: Subscription = new Subscription(); //private _jump: Subscription = new Subscription();
@@ -131,14 +139,7 @@ export class JumpTableComponent implements OnChanges, OnDestroy, AfterContentChe
@ViewChild(MatSort) sort!: MatSort; @ViewChild(MatSort) sort!: MatSort;
@ViewChild(MatPaginator) paginator!: MatPaginator; @ViewChild(MatPaginator) paginator!: MatPaginator;
constructor( constructor() {
private router: Router,
private _jumpsService: JumpsService,
private _jumpTableService: JumpTableService,
private dialog: MatDialog,
private fb: UntypedFormBuilder,
private snackBar: MatSnackBar,
) {
this._resetErrors(); this._resetErrors();
this.searchForm = this.fb.group({ this.searchForm = this.fb.group({
//numero: ['', Validators.required] //numero: ['', Validators.required]
@@ -3,11 +3,11 @@
display: inline-block; display: inline-block;
} }
.mat-mdc-standard-chip { .mat-mdc-standard-chip {
--mdc-chip-container-height: 28px; --mat-chip-container-height: 28px;
--mdc-chip-container-shape-radius: 8px 8px 8px 8px; --mat-chip-container-shape-radius: 8px 8px 8px 8px;
--mdc-chip-label-text-color: inherit; --mat-chip-label-text-color: inherit;
--mdc-chip-label-text-line-height: 20px; --mat-chip-label-text-line-height: 20px;
--mdc-chip-label-text-size: 13px; --mat-chip-label-text-size: 13px;
--mdc-chip-label-text-weight: 400; --mat-chip-label-text-weight: 400;
--mdc-chip-with-avatar-avatar-shape-radius: 6px 6px 6px 6px; --mat-chip-with-avatar-avatar-shape-radius: 6px 6px 6px 6px;
} }
@@ -48,6 +48,8 @@ export class StepperIntl extends MatStepperIntl {
styleUrl: './guildraids-log.component.scss', styleUrl: './guildraids-log.component.scss',
}) })
export class GuildraidsLogComponent implements OnInit { export class GuildraidsLogComponent implements OnInit {
private fb = inject(FormBuilder);
public now: Date; public now: Date;
public raidsForm: FormGroup; public raidsForm: FormGroup;
public guildMembers: HWMember[] = []; public guildMembers: HWMember[] = [];
@@ -66,7 +68,7 @@ export class GuildraidsLogComponent implements OnInit {
this.guildMembers = value; this.guildMembers = value;
} }
constructor(private fb: FormBuilder) { constructor() {
this.now = new Date(); this.now = new Date();
const raidsDate = new Date(); const raidsDate = new Date();
const startHour = 4; const startHour = 4;
@@ -1,4 +1,4 @@
import { Component, Input, OnInit } from '@angular/core'; import { Component, Input, OnInit, inject } from '@angular/core';
import { DatePipe, DecimalPipe } from '@angular/common'; import { DatePipe, DecimalPipe } from '@angular/common';
import { MatCardModule } from '@angular/material/card'; import { MatCardModule } from '@angular/material/card';
import { MatDividerModule } from '@angular/material/divider'; import { MatDividerModule } from '@angular/material/divider';
@@ -17,6 +17,8 @@ import guildStatistics from 'src/files-data/hw-guild-statistics.json'; // page O
styleUrl: './members-statistics.component.scss', styleUrl: './members-statistics.component.scss',
}) })
export class MembersStatisticsComponent implements OnInit { export class MembersStatisticsComponent implements OnInit {
private _utilitiesService = inject(UtilitiesService);
public guildMembers: HWMember[] = []; public guildMembers: HWMember[] = [];
public title = 'Members'; public title = 'Members';
public subtitle = 'statistics'; public subtitle = 'statistics';
@@ -82,8 +84,6 @@ export class MembersStatisticsComponent implements OnInit {
this.guildMembers = value; this.guildMembers = value;
} }
constructor(private _utilitiesService: UtilitiesService) {}
ngOnInit() { ngOnInit() {
const oneDayInSec = 24 * 60 * 60; const oneDayInSec = 24 * 60 * 60;
const today = new Date(); const today = new Date();
@@ -1,4 +1,4 @@
import { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core'; import { Component, OnInit, OnDestroy, ChangeDetectorRef, inject } from '@angular/core';
import { Router, RouterOutlet, RouterModule } from '@angular/router'; import { Router, RouterOutlet, RouterModule } from '@angular/router';
import { MediaMatcher } from '@angular/cdk/layout'; import { MediaMatcher } from '@angular/cdk/layout';
import { MatBadgeModule } from '@angular/material/badge'; import { MatBadgeModule } from '@angular/material/badge';
@@ -51,6 +51,10 @@ import { FooterComponent } from '@components/shared/layout';
styleUrls: [], styleUrls: [],
}) })
export class FullComponent implements OnInit, OnDestroy { export class FullComponent implements OnInit, OnDestroy {
private router = inject(Router);
private userService = inject(UserService);
menuItems = inject(MenuItems);
private _currentUser: Subscription = new Subscription(); private _currentUser: Subscription = new Subscription();
private _mobileQueryListener: () => void; private _mobileQueryListener: () => void;
mobileQuery: MediaQueryList; mobileQuery: MediaQueryList;
@@ -63,13 +67,10 @@ export class FullComponent implements OnInit, OnDestroy {
//visibleMenu: string[] = ['products', 'page']; //visibleMenu: string[] = ['products', 'page'];
//visibleMenu: string[] = ['products']; //visibleMenu: string[] = ['products'];
constructor( constructor() {
private router: Router, const changeDetectorRef = inject(ChangeDetectorRef);
private userService: UserService, const media = inject(MediaMatcher);
changeDetectorRef: ChangeDetectorRef,
media: MediaMatcher,
public menuItems: MenuItems,
) {
this.mobileQuery = media.matchMedia('(min-width: 768px)'); this.mobileQuery = media.matchMedia('(min-width: 768px)');
this._mobileQueryListener = () => changeDetectorRef.detectChanges(); this._mobileQueryListener = () => changeDetectorRef.detectChanges();
this.mobileQuery.addListener(this._mobileQueryListener); this.mobileQuery.addListener(this._mobileQueryListener);
@@ -26,17 +26,15 @@ import { UserService } from '@services';
], ],
}) })
export class HeaderComponent implements OnInit { export class HeaderComponent implements OnInit {
private router = inject(Router);
private userService = inject(UserService);
private _currentUser: Subscription = new Subscription(); private _currentUser: Subscription = new Subscription();
private _isAuthenticated: Subscription = new Subscription(); private _isAuthenticated: Subscription = new Subscription();
private isAuthenticated = false; private isAuthenticated = false;
currentUser: User = {} as User; currentUser: User = {} as User;
destroyRef = inject(DestroyRef); destroyRef = inject(DestroyRef);
constructor(
private router: Router,
private userService: UserService,
) {}
ngOnInit() { ngOnInit() {
const user$: Observable<User> = this.userService.currentUser.pipe(takeUntilDestroyed(this.destroyRef)); const user$: Observable<User> = this.userService.currentUser.pipe(takeUntilDestroyed(this.destroyRef));
this._currentUser = user$.subscribe((userData) => { this._currentUser = user$.subscribe((userData) => {
@@ -1,21 +1,18 @@
import { Directive, Input, OnInit, OnDestroy, TemplateRef, ViewContainerRef } from '@angular/core'; import { Directive, Input, OnInit, OnDestroy, TemplateRef, ViewContainerRef, inject } from '@angular/core';
import { Observable, Subscription } from 'rxjs'; import { Observable, Subscription } from 'rxjs';
import { UserService } from '@services'; import { UserService } from '@services';
@Directive({ @Directive({
selector: '[appShowAuthed]', selector: '[appShowAuthed]',
standalone: true standalone: true,
}) })
export class ShowAuthedDirective implements OnInit, OnDestroy { export class ShowAuthedDirective implements OnInit, OnDestroy {
private _auth: Subscription = new Subscription(); private templateRef = inject<TemplateRef<never>>(TemplateRef);
private userService = inject(UserService);
private viewContainer = inject(ViewContainerRef);
constructor( private _auth: Subscription = new Subscription();
//private templateRef: TemplateRef<any>,
private templateRef: TemplateRef<never>,
private userService: UserService,
private viewContainer: ViewContainerRef
) { }
@Input() set appShowAuthed(condition: boolean) { @Input() set appShowAuthed(condition: boolean) {
this.condition = condition; this.condition = condition;
@@ -25,21 +22,17 @@ export class ShowAuthedDirective implements OnInit, OnDestroy {
//condition: boolean; //condition: boolean;
ngOnInit() { ngOnInit() {
const isAuthenticated$: Observable<boolean> = this.userService.isAuthenticated; // .pipe(take(1)); const isAuthenticated$: Observable<boolean> = this.userService.isAuthenticated; // .pipe(take(1));
this._auth = isAuthenticated$.subscribe( this._auth = isAuthenticated$.subscribe((isAuthenticated) => {
(isAuthenticated) => { if ((isAuthenticated && this.condition) || (!isAuthenticated && !this.condition)) {
if (isAuthenticated && this.condition || !isAuthenticated && !this.condition) { this.viewContainer.createEmbeddedView(this.templateRef);
this.viewContainer.createEmbeddedView(this.templateRef); } else {
} else { this.viewContainer.clear();
this.viewContainer.clear();
}
} }
); });
} }
ngOnDestroy() { ngOnDestroy() {
this._auth.unsubscribe(); this._auth.unsubscribe();
} }
} }
@@ -1,7 +1,6 @@
import { Component, Input, OnDestroy, Inject, ViewEncapsulation } from '@angular/core'; import { Component, Input, OnDestroy, ViewEncapsulation, DOCUMENT, inject } from '@angular/core';
import { Router, NavigationStart, NavigationEnd, NavigationCancel, NavigationError } from '@angular/router'; import { Router, NavigationStart, NavigationEnd, NavigationCancel, NavigationError } from '@angular/router';
import { DOCUMENT } from '@angular/common';
@Component({ @Component({
selector: 'app-spinner', selector: 'app-spinner',
@@ -10,15 +9,15 @@ import { DOCUMENT } from '@angular/common';
encapsulation: ViewEncapsulation.None, encapsulation: ViewEncapsulation.None,
}) })
export class SpinnerComponent implements OnDestroy { export class SpinnerComponent implements OnDestroy {
private router = inject(Router);
private document = inject<Document>(DOCUMENT);
public isSpinnerVisible = true; public isSpinnerVisible = true;
@Input() @Input()
public backgroundColor = 'rgba(0, 115, 170, 0.69)'; public backgroundColor = 'rgba(0, 115, 170, 0.69)';
constructor( constructor() {
private router: Router,
@Inject(DOCUMENT) private document: Document,
) {
this.router.events.subscribe( this.router.events.subscribe(
(event) => { (event) => {
if (event instanceof NavigationStart) { if (event instanceof NavigationStart) {
+2 -4
View File
@@ -1,13 +1,11 @@
/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-explicit-any */
import { Injectable } from '@angular/core'; import { Injectable, inject } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http'; import { HttpClient, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class ApiService { export class ApiService {
constructor( private http = inject(HttpClient);
private http: HttpClient
) { }
/*private formatErrors(error: any) { /*private formatErrors(error: any) {
return throwError(error.error); return throwError(error.error);
+20 -20
View File
@@ -1,4 +1,4 @@
import { Injectable } from '@angular/core'; import { Injectable, inject } from '@angular/core';
import { HttpParams } from '@angular/common/http'; import { HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
@@ -8,10 +8,9 @@ import { map } from 'rxjs/operators';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class ApplicationsService { export class ApplicationsService {
private apiService = inject(ApiService);
private _apiDomain = '/skydive'; private _apiDomain = '/skydive';
constructor(
private apiService: ApiService
) { }
query(config: ApplicationListConfig): Observable<ApplicationList> { query(config: ApplicationListConfig): Observable<ApplicationList> {
// Convert any filters over to Angular's URLSearchParams // Convert any filters over to Angular's URLSearchParams
@@ -19,36 +18,37 @@ export class ApplicationsService {
apikey: config.filters.apikey, apikey: config.filters.apikey,
author: config.filters.author, author: config.filters.author,
limit: config.filters.limit, limit: config.filters.limit,
offset: config.filters.offset offset: config.filters.offset,
}; };
return this.apiService return this.apiService.get(
.get( `${this._apiDomain}/applications` + (config.type === 'feed' ? '/feed' : ''),
`${this._apiDomain}/applications` + ((config.type === 'feed') ? '/feed' : ''), new HttpParams({ fromObject: <
new HttpParams({ fromObject: <{ {
[param: string]: string | number | boolean | readonly (string | number | boolean)[]; [param: string]: string | number | boolean | readonly (string | number | boolean)[];
}>params }) }
); >params }),
);
} }
get(slug: string): Observable<Application> { get(slug: string): Observable<Application> {
return this.apiService.get(`${this._apiDomain}/applications/${slug}`) return this.apiService.get(`${this._apiDomain}/applications/${slug}`).pipe(map((data) => data.application));
.pipe(map(data => data.application));
} }
destroy(slug: string): Observable<boolean> { destroy(slug: string): Observable<boolean> {
return this.apiService.delete(`${this._apiDomain}/applications/${slug}`).pipe(map(data => data.deleted)); return this.apiService.delete(`${this._apiDomain}/applications/${slug}`).pipe(map((data) => data.deleted));
} }
save(application: Application): Observable<Application> { save(application: Application): Observable<Application> {
if (application.slug) { if (application.slug) {
// If we're updating an existing application // If we're updating an existing application
return this.apiService.put(`${this._apiDomain}/applications/${application.slug}`, { application: application }) return this.apiService
.pipe(map(data => data.application)); .put(`${this._apiDomain}/applications/${application.slug}`, { application: application })
.pipe(map((data) => data.application));
} else { } else {
// Otherwise, create a new application // Otherwise, create a new application
return this.apiService.post(`${this._apiDomain}/applications/`, { application: application }) return this.apiService
.pipe(map(data => data.application)); .post(`${this._apiDomain}/applications/`, { application: application })
.pipe(map((data) => data.application));
} }
} }
} }
+27 -22
View File
@@ -1,4 +1,4 @@
import { Injectable } from '@angular/core'; import { Injectable, inject } from '@angular/core';
import { HttpParams } from '@angular/common/http'; import { HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
@@ -8,22 +8,22 @@ import { Article, ArticleList, ArticleListConfig, ArticleListFilters, ArticlePag
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class ArticlesService { export class ArticlesService {
private apiService = inject(ApiService);
private _apiDomain = '/cms'; private _apiDomain = '/cms';
constructor(
private apiService: ApiService
) { }
query(config: ArticleListConfig): Observable<ArticleList> { query(config: ArticleListConfig): Observable<ArticleList> {
// Convert any filters over to Angular's URLSearchParams // Convert any filters over to Angular's URLSearchParams
const params: ArticleListFilters = {} as ArticleListFilters; const params: ArticleListFilters = {} as ArticleListFilters;
Object.assign(params, config.filters); Object.assign(params, config.filters);
return this.apiService return this.apiService.get(
.get( `${this._apiDomain}/articles` + (config.type === 'feed' ? '/feed' : ''),
`${this._apiDomain}/articles` + ((config.type === 'feed') ? '/feed' : ''), new HttpParams({ fromObject: <
new HttpParams({ fromObject: <{ {
[param: string]: string | number | boolean | readonly (string | number | boolean)[]; [param: string]: string | number | boolean | readonly (string | number | boolean)[];
}>params }) }
); >params }),
);
} }
get(slug: string): Observable<ArticlePageData> { get(slug: string): Observable<ArticlePageData> {
@@ -34,33 +34,39 @@ export class ArticlesService {
}));*/ }));*/
return this.apiService.get(`${this._apiDomain}/articles/${slug}`); return this.apiService.get(`${this._apiDomain}/articles/${slug}`);
} }
getAll(): Observable<Array<Article>> { getAll(): Observable<Array<Article>> {
return this.apiService.get(`${this._apiDomain}/articles`).pipe(map(data => data.articles)); return this.apiService.get(`${this._apiDomain}/articles`).pipe(map((data) => data.articles));
} }
create(article: Article): Observable<Article> { create(article: Article): Observable<Article> {
return this.apiService.post(`${this._apiDomain}/articles/`, { article: article }).pipe(map(data => data.article)); return this.apiService
.post(`${this._apiDomain}/articles/`, { article: article })
.pipe(map((data) => data.article));
} }
update(article: Article): Observable<Article> { update(article: Article): Observable<Article> {
return this.apiService.put(`${this._apiDomain}/articles/${article.slug}`, { article: article }).pipe(map(data => data.article)); return this.apiService
.put(`${this._apiDomain}/articles/${article.slug}`, { article: article })
.pipe(map((data) => data.article));
} }
destroy(slug: string): Observable<boolean> { destroy(slug: string): Observable<boolean> {
return this.apiService.delete(`${this._apiDomain}/articles/${slug}`).pipe(map(data => data.deleted)); return this.apiService.delete(`${this._apiDomain}/articles/${slug}`).pipe(map((data) => data.deleted));
} }
save(article: Article): Observable<Article> { save(article: Article): Observable<Article> {
// If we're updating an existing article // If we're updating an existing article
if (article.slug) { if (article.slug) {
return this.apiService.put(`${this._apiDomain}/articles/${article.slug}`, { article: article }) return this.apiService
.pipe(map(data => data.article)); .put(`${this._apiDomain}/articles/${article.slug}`, { article: article })
.pipe(map((data) => data.article));
// Otherwise, create a new article // Otherwise, create a new article
} else { } else {
return this.apiService.post(`${this._apiDomain}/articles/`, { article: article }) return this.apiService
.pipe(map(data => data.article)); .post(`${this._apiDomain}/articles/`, { article: article })
.pipe(map((data) => data.article));
} }
} }
@@ -71,5 +77,4 @@ export class ArticlesService {
unfavorite(slug: string): Observable<Article> { unfavorite(slug: string): Observable<Article> {
return this.apiService.delete(`${this._apiDomain}/articles/${slug}/favorite`); return this.apiService.delete(`${this._apiDomain}/articles/${slug}/favorite`);
} }
} }
@@ -1,26 +1,41 @@
import { Injectable } from '@angular/core'; import { Injectable, inject } from '@angular/core';
import { HttpParams } from '@angular/common/http'; import { HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { ApiService } from '../api.service'; import { ApiService } from '../api.service';
import { import {
HWActivityStat, HWClan, HWClanList, HWClanListConfig, HWActivityStat,
HWClanListFilters, HWClanPageData, HWGuildClan, HWClan,
HWMember HWClanList,
HWClanListConfig,
HWClanListFilters,
HWClanPageData,
HWGuildClan,
HWMember,
} from '@models'; } from '@models';
import guildData from 'src/files-data/hw-guild-data.json'; // page Membres import guildData from 'src/files-data/hw-guild-data.json'; // page Membres
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class HWClanService { export class HWClanService {
private apiService = inject(ApiService);
private _apiDomain = '/herowars'; private _apiDomain = '/herowars';
constructor(
private apiService: ApiService
) { }
private _resetActivity(): HWActivityStat { private _resetActivity(): HWActivityStat {
const activity: HWActivityStat = { activity: 0, prestige: 0, titanite: 0, war: 0, adventure: 0, gifts: 0, score: 0, scoreGifts: 0, warGifts: 0, rewards: 0 }; const activity: HWActivityStat = {
activity: 0,
prestige: 0,
titanite: 0,
war: 0,
adventure: 0,
gifts: 0,
score: 0,
scoreGifts: 0,
warGifts: 0,
rewards: 0,
};
return activity; return activity;
} }
@@ -28,13 +43,14 @@ export class HWClanService {
// Convert any filters over to Angular's URLSearchParams // Convert any filters over to Angular's URLSearchParams
const params: HWClanListFilters = {} as HWClanListFilters; const params: HWClanListFilters = {} as HWClanListFilters;
Object.assign(params, config.filters); Object.assign(params, config.filters);
return this.apiService return this.apiService.get(
.get( `${this._apiDomain}/clans`,
`${this._apiDomain}/clans`, new HttpParams({ fromObject: <
new HttpParams({ fromObject: <{ {
[param: string]: string | number | boolean | readonly (string | number | boolean)[]; [param: string]: string | number | boolean | readonly (string | number | boolean)[];
}>params }) }
); >params }),
);
} }
get(id: string): Observable<HWClanPageData> { get(id: string): Observable<HWClanPageData> {
@@ -42,31 +58,35 @@ export class HWClanService {
} }
getAll(): Observable<Array<HWClan>> { getAll(): Observable<Array<HWClan>> {
return this.apiService.get(`${this._apiDomain}/clans`).pipe(map(data => data.clans)); return this.apiService.get(`${this._apiDomain}/clans`).pipe(map((data) => data.clans));
} }
create(clan: HWClan): Observable<HWClan> { create(clan: HWClan): Observable<HWClan> {
return this.apiService.post(`${this._apiDomain}/clans/`, { clan: clan }).pipe(map(data => data.clan)); return this.apiService.post(`${this._apiDomain}/clans/`, { clan: clan }).pipe(map((data) => data.clan));
} }
update(clan: HWClan): Observable<HWClan> { update(clan: HWClan): Observable<HWClan> {
return this.apiService.put(`${this._apiDomain}/clans/${clan.id}`, { clan: clan }).pipe(map(data => data.clan)); return this.apiService
.put(`${this._apiDomain}/clans/${clan.id}`, { clan: clan })
.pipe(map((data) => data.clan));
} }
destroy(id: string): Observable<boolean> { destroy(id: string): Observable<boolean> {
return this.apiService.delete(`${this._apiDomain}/clans/${id}`).pipe(map(data => data.deleted)); return this.apiService.delete(`${this._apiDomain}/clans/${id}`).pipe(map((data) => data.deleted));
} }
save(clan: HWClan): Observable<HWClan> { save(clan: HWClan): Observable<HWClan> {
// If we're updating an existing clan // If we're updating an existing clan
if (clan.id) { if (clan.id) {
return this.apiService.put(`${this._apiDomain}/clans/${clan.id}`, { clan: clan }).pipe(map(data => data.clan)); return this.apiService
.put(`${this._apiDomain}/clans/${clan.id}`, { clan: clan })
.pipe(map((data) => data.clan));
// Otherwise, create a new clan // Otherwise, create a new clan
} else { } else {
return this.apiService.post(`${this._apiDomain}/clans/`, { clan: clan }).pipe(map(data => data.clan)); return this.apiService.post(`${this._apiDomain}/clans/`, { clan: clan }).pipe(map((data) => data.clan));
} }
} }
loadClan(): HWGuildClan { loadClan(): HWGuildClan {
const guildClan: HWGuildClan = {} as HWGuildClan; const guildClan: HWGuildClan = {} as HWGuildClan;
Object.assign(guildClan, guildData.clan); Object.assign(guildClan, guildData.clan);
@@ -77,7 +97,7 @@ export class HWClanService {
return guildClan; return guildClan;
} }
loadClanStats(clan: HWGuildClan, members: HWMember[]): HWGuildClan { loadClanStats(clan: HWGuildClan, members: HWMember[]): HWGuildClan {
members.map((member: HWMember) => { members.map((member: HWMember) => {
clan.sumTotal.adventure += member.adventureSum; clan.sumTotal.adventure += member.adventureSum;
@@ -86,42 +106,42 @@ export class HWClanService {
clan.todayTotal.activity += member.stat.todayActivity; clan.todayTotal.activity += member.stat.todayActivity;
clan.todayTotal.prestige += member.stat.todayPrestige; clan.todayTotal.prestige += member.stat.todayPrestige;
clan.todayTotal.titanite += member.stat.todayDungeonActivity; clan.todayTotal.titanite += member.stat.todayDungeonActivity;
clan.todayTotal.score += (member.stat.todayDungeonActivity + member.stat.todayActivity + member.stat.todayPrestige); clan.todayTotal.score +=
member.stat.todayDungeonActivity + member.stat.todayActivity + member.stat.todayPrestige;
clan.sumTotal.activity += member.stat.activitySum; clan.sumTotal.activity += member.stat.activitySum;
clan.sumTotal.prestige += member.stat.prestigeSum; clan.sumTotal.prestige += member.stat.prestigeSum;
clan.sumTotal.titanite += member.stat.dungeonActivitySum; clan.sumTotal.titanite += member.stat.dungeonActivitySum;
clan.sumTotal.score += member.score; clan.sumTotal.score += member.score;
clan.sumTotal.warGifts += member.warGifts; clan.sumTotal.warGifts += member.warGifts;
}); });
clan.sumTotal.scoreGifts = (clan.giftsCount - Math.floor(clan.sumTotal.warGifts)); clan.sumTotal.scoreGifts = clan.giftsCount - Math.floor(clan.sumTotal.warGifts);
clan.todayAverages.activity = (clan.todayTotal.activity / members.length); clan.todayAverages.activity = clan.todayTotal.activity / members.length;
clan.todayAverages.prestige = (clan.todayTotal.prestige / members.length); clan.todayAverages.prestige = clan.todayTotal.prestige / members.length;
clan.todayAverages.titanite = (clan.todayTotal.titanite / members.length); clan.todayAverages.titanite = clan.todayTotal.titanite / members.length;
clan.todayAverages.score = (clan.todayTotal.score / members.length); clan.todayAverages.score = clan.todayTotal.score / members.length;
clan.sumAverages.activity = (clan.sumTotal.activity / members.length); clan.sumAverages.activity = clan.sumTotal.activity / members.length;
clan.sumAverages.prestige = (clan.sumTotal.prestige / members.length); clan.sumAverages.prestige = clan.sumTotal.prestige / members.length;
clan.sumAverages.titanite = (clan.sumTotal.titanite / members.length); clan.sumAverages.titanite = clan.sumTotal.titanite / members.length;
if (clan.league === '3') { if (clan.league === '3') {
clan.sumAverages.war = (clan.sumTotal.war / 10); clan.sumAverages.war = clan.sumTotal.war / 10;
} else if (clan.league === '2') { } else if (clan.league === '2') {
clan.sumAverages.war = (clan.sumTotal.war / 15); clan.sumAverages.war = clan.sumTotal.war / 15;
} else if (clan.league === '1') { } else if (clan.league === '1') {
clan.sumAverages.war = (clan.sumTotal.war / 20); clan.sumAverages.war = clan.sumTotal.war / 20;
} }
clan.sumAverages.adventure = (clan.sumTotal.adventure / members.length); clan.sumAverages.adventure = clan.sumTotal.adventure / members.length;
clan.sumAverages.gifts = (clan.sumTotal.gifts / members.length); clan.sumAverages.gifts = clan.sumTotal.gifts / members.length;
clan.sumAverages.score = (clan.sumTotal.score / members.length); clan.sumAverages.score = clan.sumTotal.score / members.length;
clan.sumAverages.scoreGifts = (clan.sumTotal.scoreGifts / members.length); clan.sumAverages.scoreGifts = clan.sumTotal.scoreGifts / members.length;
clan.sumAverages.warGifts = (clan.sumTotal.warGifts / members.length); clan.sumAverages.warGifts = clan.sumTotal.warGifts / members.length;
members.map((data) => { members.map((data) => {
data.scoreGifts = ((data.score / clan.sumTotal.score) * clan.sumTotal.scoreGifts); data.scoreGifts = (data.score / clan.sumTotal.score) * clan.sumTotal.scoreGifts;
data.rewards = Math.floor((data.scoreGifts + data.warGifts)); data.rewards = Math.floor(data.scoreGifts + data.warGifts);
clan.sumTotal.rewards += data.rewards; clan.sumTotal.rewards += data.rewards;
return data; return data;
}); });
clan.sumAverages.rewards = (clan.sumTotal.rewards / members.length); clan.sumAverages.rewards = clan.sumTotal.rewards / members.length;
return clan; return clan;
} }
} }
@@ -1,36 +1,41 @@
import { Injectable } from '@angular/core'; import { Injectable, inject } from '@angular/core';
import { HttpParams } from '@angular/common/http'; import { HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { ApiService, UtilitiesService } from '@services'; import { ApiService, UtilitiesService } from '@services';
import { import {
HWGuildClan, HWWeekStat, HWGuildClan,
HWMember, HWMemberList, HWMemberListConfig, HWWeekStat,
HWMemberListFilters, HWMemberPageData, HWMemberStat HWMember,
HWMemberList,
HWMemberListConfig,
HWMemberListFilters,
HWMemberPageData,
HWMemberStat,
} from '@models'; } from '@models';
import guildData from 'src/files-data/hw-guild-data.json'; // page Membres import guildData from 'src/files-data/hw-guild-data.json'; // page Membres
import guildStatistics from 'src/files-data/hw-guild-statistics.json'; // page Overview -> Statistics import guildStatistics from 'src/files-data/hw-guild-statistics.json'; // page Overview -> Statistics
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class HWMemberService { export class HWMemberService {
private _apiService = inject(ApiService);
private _utilitiesService = inject(UtilitiesService);
private _apiDomain = '/herowars'; private _apiDomain = '/herowars';
constructor(
private _apiService: ApiService,
private _utilitiesService: UtilitiesService
) { }
query(config: HWMemberListConfig): Observable<HWMemberList> { query(config: HWMemberListConfig): Observable<HWMemberList> {
// Convert any filters over to Angular's URLSearchParams // Convert any filters over to Angular's URLSearchParams
const params: HWMemberListFilters = {} as HWMemberListFilters; const params: HWMemberListFilters = {} as HWMemberListFilters;
Object.assign(params, config.filters); Object.assign(params, config.filters);
return this._apiService return this._apiService.get(
.get( `${this._apiDomain}/members`,
`${this._apiDomain}/members`, new HttpParams({ fromObject: <
new HttpParams({ fromObject: <{ {
[param: string]: string | number | boolean | readonly (string | number | boolean)[]; [param: string]: string | number | boolean | readonly (string | number | boolean)[];
}>params }) }
); >params }),
);
} }
get(id: string): Observable<HWMemberPageData> { get(id: string): Observable<HWMemberPageData> {
@@ -38,35 +43,43 @@ export class HWMemberService {
} }
getAll(): Observable<Array<HWMember>> { getAll(): Observable<Array<HWMember>> {
return this._apiService.get(`${this._apiDomain}/members`).pipe(map(data => data.members)); return this._apiService.get(`${this._apiDomain}/members`).pipe(map((data) => data.members));
} }
create(member: HWMember): Observable<HWMember> { create(member: HWMember): Observable<HWMember> {
return this._apiService.post(`${this._apiDomain}/members/`, { member: member }).pipe(map(data => data.member)); return this._apiService
.post(`${this._apiDomain}/members/`, { member: member })
.pipe(map((data) => data.member));
} }
update(member: HWMember): Observable<HWMember> { update(member: HWMember): Observable<HWMember> {
return this._apiService.put(`${this._apiDomain}/members/${member.id}`, { member: member }).pipe(map(data => data.member)); return this._apiService
.put(`${this._apiDomain}/members/${member.id}`, { member: member })
.pipe(map((data) => data.member));
} }
destroy(id: string): Observable<boolean> { destroy(id: string): Observable<boolean> {
return this._apiService.delete(`${this._apiDomain}/members/${id}`).pipe(map(data => data.deleted)); return this._apiService.delete(`${this._apiDomain}/members/${id}`).pipe(map((data) => data.deleted));
} }
save(member: HWMember): Observable<HWMember> { save(member: HWMember): Observable<HWMember> {
// If we're updating an existing member // If we're updating an existing member
if (member.id) { if (member.id) {
return this._apiService.put(`${this._apiDomain}/members/${member.id}`, { member: member }).pipe(map(data => data.member)); return this._apiService
.put(`${this._apiDomain}/members/${member.id}`, { member: member })
.pipe(map((data) => data.member));
// Otherwise, create a new member // Otherwise, create a new member
} else { } else {
return this._apiService.post(`${this._apiDomain}/members/`, { member: member }).pipe(map(data => data.member)); return this._apiService
.post(`${this._apiDomain}/members/`, { member: member })
.pipe(map((data) => data.member));
} }
} }
loadMembers(clan: HWGuildClan): HWMember[] { loadMembers(clan: HWGuildClan): HWMember[] {
const guildMembers: HWMember[] = []; const guildMembers: HWMember[] = [];
const now = new Date(); const now = new Date();
const oneDayInSec = (24 * 60 * 60); const oneDayInSec = 24 * 60 * 60;
const daysToKick = parseInt(guildData.clan.daysToKick); const daysToKick = parseInt(guildData.clan.daysToKick);
for (const data of Object.entries(guildData.clan.members)) { for (const data of Object.entries(guildData.clan.members)) {
const member: HWMember = {} as HWMember; const member: HWMember = {} as HWMember;
@@ -76,47 +89,56 @@ export class HWMemberService {
} else { } else {
member.champion = false; member.champion = false;
} }
member.heroes = { power: 0, teams: []}; member.heroes = { power: 0, teams: [] };
member.titans = { power: 0, teams: []}; member.titans = { power: 0, teams: [] };
guildMembers.push(member); guildMembers.push(member);
} }
guildMembers.map((data: HWMember) => { guildMembers.map((data: HWMember) => {
const last = new Date((parseInt(data.lastLoginTime) * 1000)); const last = new Date(parseInt(data.lastLoginTime) * 1000);
const exp = new Date(last.getTime() + ((daysToKick * oneDayInSec) * 1000)); const exp = new Date(last.getTime() + daysToKick * oneDayInSec * 1000);
const diff = Math.floor(((exp.getTime() - now.getTime()) / 1000)); const diff = Math.floor((exp.getTime() - now.getTime()) / 1000);
const daysLeft = Math.floor((diff / oneDayInSec)); const daysLeft = Math.floor(diff / oneDayInSec);
let timeLeft = diff; let timeLeft = diff;
if (daysLeft >= 1) { if (daysLeft >= 1) {
timeLeft = (diff - (daysLeft * oneDayInSec)); timeLeft = diff - daysLeft * oneDayInSec;
} }
data.inactivity = { data.inactivity = {
daysLeft: daysLeft, daysLeft: daysLeft,
timeLeft: timeLeft, timeLeft: timeLeft,
dropDelay: `${daysLeft}d, ${this._utilitiesService.secondsToDuration(timeLeft)}`, dropDelay: `${daysLeft}d, ${this._utilitiesService.secondsToDuration(timeLeft)}`,
dropDate: Math.floor((exp.getTime() / 1000)) dropDate: Math.floor(exp.getTime() / 1000),
}; };
data.raids = []; data.raids = [];
data.raidsInfo = { data.raidsInfo = {
variationAvg: 0, variationAvg: 0,
variationSum: 0 variationSum: 0,
}; };
data.stat = {} as HWMemberStat; data.stat = {} as HWMemberStat;
let index = guildData.membersStat.findIndex(stat => stat.userId === data.id); let index = guildData.membersStat.findIndex((stat) => stat.userId === data.id);
if (index !== -1) { if (index !== -1) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
const { userId, ...memberStatWithoutUserId } = guildData.membersStat[index] as any; const { userId, ...memberStatWithoutUserId } = guildData.membersStat[index] as any;
Object.assign(data.stat, memberStatWithoutUserId); Object.assign(data.stat, memberStatWithoutUserId);
} }
index = guildStatistics.stat.findIndex(stat => stat.id === data.id); index = guildStatistics.stat.findIndex((stat) => stat.id === data.id);
if (index !== -1) { if (index !== -1) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
const { id, ...weekStatSource } = guildStatistics.stat[index] as any; const { id, ...weekStatSource } = guildStatistics.stat[index] as any;
const stat: HWWeekStat = {} as HWWeekStat; const stat: HWWeekStat = {} as HWWeekStat;
Object.assign(stat, weekStatSource); Object.assign(stat, weekStatSource);
data.weekStat = stat; data.weekStat = stat;
data.adventureSum = guildStatistics.stat[index].adventureStat.reduce((accumulator, currentValue) => accumulator + currentValue, 0); data.adventureSum = guildStatistics.stat[index].adventureStat.reduce(
data.clanGiftsSum = guildStatistics.stat[index].clanGifts.reduce((accumulator, currentValue) => accumulator + currentValue, 0); (accumulator, currentValue) => accumulator + currentValue,
data.clanWarSum = guildStatistics.stat[index].clanWarStat.reduce((accumulator, currentValue) => accumulator + currentValue, 0); 0,
);
data.clanGiftsSum = guildStatistics.stat[index].clanGifts.reduce(
(accumulator, currentValue) => accumulator + currentValue,
0,
);
data.clanWarSum = guildStatistics.stat[index].clanWarStat.reduce(
(accumulator, currentValue) => accumulator + currentValue,
0,
);
} else { } else {
data.weekStat = {} as HWWeekStat; data.weekStat = {} as HWWeekStat;
data.adventureSum = 0; data.adventureSum = 0;
@@ -124,8 +146,8 @@ export class HWMemberService {
data.clanWarSum = 0; data.clanWarSum = 0;
} }
data.score = (data.stat.dungeonActivitySum + data.stat.activitySum + data.stat.prestigeSum); data.score = data.stat.dungeonActivitySum + data.stat.activitySum + data.stat.prestigeSum;
data.warGifts = (((clan.giftsCount / 2) * ((data.clanWarSum * 10) / 100)) / 20); data.warGifts = ((clan.giftsCount / 2) * ((data.clanWarSum * 10) / 100)) / 20;
data.scoreGifts = 0; data.scoreGifts = 0;
data.rewards = 0; data.rewards = 0;
return data; return data;
@@ -133,5 +155,4 @@ export class HWMemberService {
return guildMembers; return guildMembers;
} }
} }
+3 -5
View File
@@ -1,4 +1,4 @@
import { Injectable } from '@angular/core'; import { Injectable, inject } from '@angular/core';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { take } from 'rxjs/operators'; import { take } from 'rxjs/operators';
@@ -7,10 +7,9 @@ import { AeronefsPageData, CanopiesPageData, DropZonesPageData, JumpsPageData }
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class PagesService { export class PagesService {
private apiService = inject(ApiService);
private _apiDomain = '/skydive'; private _apiDomain = '/skydive';
constructor(
private apiService: ApiService
) { }
getAeronefsPage(): Observable<AeronefsPageData> { getAeronefsPage(): Observable<AeronefsPageData> {
return this.apiService.get(`${this._apiDomain}/pages/aeronefs`).pipe(take(1)); return this.apiService.get(`${this._apiDomain}/pages/aeronefs`).pipe(take(1));
@@ -27,5 +26,4 @@ export class PagesService {
getJumpsPage(): Observable<JumpsPageData> { getJumpsPage(): Observable<JumpsPageData> {
return this.apiService.get(`${this._apiDomain}/pages/jumps`).pipe(take(1)); return this.apiService.get(`${this._apiDomain}/pages/jumps`).pipe(take(1));
} }
} }
+33 -19
View File
@@ -1,29 +1,36 @@
import { Injectable } from '@angular/core'; import { Injectable, inject } from '@angular/core';
import { HttpParams } from '@angular/common/http'; import { HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { ApiService } from './api.service'; import { ApiService } from './api.service';
import { Product, ProductList, ProductListConfig, ProductListFilters, ProductPageData, ProductsPageData } from '@models'; import {
Product,
ProductList,
ProductListConfig,
ProductListFilters,
ProductPageData,
ProductsPageData,
} from '@models';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class ProductsService { export class ProductsService {
private apiService = inject(ApiService);
private _apiDomain = '/ecommerce'; private _apiDomain = '/ecommerce';
constructor(
private apiService: ApiService
) { }
query(config: ProductListConfig): Observable<ProductList> { query(config: ProductListConfig): Observable<ProductList> {
// Convert any filters over to Angular's URLSearchParams // Convert any filters over to Angular's URLSearchParams
const params: ProductListFilters = {} as ProductListFilters; const params: ProductListFilters = {} as ProductListFilters;
Object.assign(params, config.filters); Object.assign(params, config.filters);
return this.apiService return this.apiService.get(
.get( `${this._apiDomain}/products` + (config.type === 'feed' ? '/feed' : ''),
`${this._apiDomain}/products` + ((config.type === 'feed') ? '/feed' : ''), new HttpParams({ fromObject: <
new HttpParams({ fromObject: <{ {
[param: string]: string | number | boolean | readonly (string | number | boolean)[]; [param: string]: string | number | boolean | readonly (string | number | boolean)[];
}>params }) }
); >params }),
);
} }
get(slug: string): Observable<ProductsPageData> { get(slug: string): Observable<ProductsPageData> {
@@ -35,7 +42,7 @@ export class ProductsService {
} }
getAll(): Observable<Array<Product>> { getAll(): Observable<Array<Product>> {
return this.apiService.get(`${this._apiDomain}/products`).pipe(map(data => data.products)); return this.apiService.get(`${this._apiDomain}/products`).pipe(map((data) => data.products));
} }
getAllByCategory(category: string): Observable<ProductsPageData> { getAllByCategory(category: string): Observable<ProductsPageData> {
@@ -43,26 +50,33 @@ export class ProductsService {
} }
create(product: Product): Observable<Product> { create(product: Product): Observable<Product> {
return this.apiService.post(`${this._apiDomain}/products/`, { product: product }).pipe(map(data => data.product)); return this.apiService
.post(`${this._apiDomain}/products/`, { product: product })
.pipe(map((data) => data.product));
} }
update(product: Product): Observable<Product> { update(product: Product): Observable<Product> {
return this.apiService.put(`${this._apiDomain}/products/${product.slug}`, { product: product }).pipe(map(data => data.product)); return this.apiService
.put(`${this._apiDomain}/products/${product.slug}`, { product: product })
.pipe(map((data) => data.product));
} }
destroy(slug: string): Observable<boolean> { destroy(slug: string): Observable<boolean> {
return this.apiService.delete(`${this._apiDomain}/products/${slug}`).pipe(map(data => data.deleted)); return this.apiService.delete(`${this._apiDomain}/products/${slug}`).pipe(map((data) => data.deleted));
} }
save(product: Product): Observable<Product> { save(product: Product): Observable<Product> {
// If we're updating an existing product // If we're updating an existing product
if (product.slug) { if (product.slug) {
return this.apiService.put(`${this._apiDomain}/products/${product.slug}`, { product: product }).pipe(map(data => data.product)); return this.apiService
.put(`${this._apiDomain}/products/${product.slug}`, { product: product })
.pipe(map((data) => data.product));
// Otherwise, create a new product // Otherwise, create a new product
} else { } else {
return this.apiService.post(`${this._apiDomain}/products/`, { product: product }).pipe(map(data => data.product)); return this.apiService
.post(`${this._apiDomain}/products/`, { product: product })
.pipe(map((data) => data.product));
} }
} }
} }
+5 -6
View File
@@ -1,4 +1,4 @@
import { Injectable } from '@angular/core'; import { Injectable, inject } from '@angular/core';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { ApiService } from '@services'; import { ApiService } from '@services';
@@ -7,13 +7,13 @@ import { map } from 'rxjs/operators';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class ProfilesService { export class ProfilesService {
private apiService = inject(ApiService);
private _apiDomain = '/cms'; private _apiDomain = '/cms';
constructor(
private apiService: ApiService
) { }
get(username: string): Observable<Profile> { get(username: string): Observable<Profile> {
return this.apiService.get(`${this._apiDomain}/profiles/${username}`) return this.apiService
.get(`${this._apiDomain}/profiles/${username}`)
.pipe(map((data: { profile: Profile }) => data.profile)); .pipe(map((data: { profile: Profile }) => data.profile));
} }
@@ -24,5 +24,4 @@ export class ProfilesService {
unfollow(username: string): Observable<Profile> { unfollow(username: string): Observable<Profile> {
return this.apiService.delete(`${this._apiDomain}/profiles/${username}/follow`); return this.apiService.delete(`${this._apiDomain}/profiles/${username}/follow`);
} }
} }
@@ -1,4 +1,4 @@
import { Injectable } from '@angular/core'; import { Injectable, inject } from '@angular/core';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
@@ -7,19 +7,15 @@ import { AeronefByImat, AeronefByYear } from '@models';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class AeronefsService { export class AeronefsService {
private apiService = inject(ApiService);
private _apiDomain = '/skydive'; private _apiDomain = '/skydive';
constructor(
private apiService: ApiService
) { }
getAllByImat(): Observable<Array<AeronefByImat>> { getAllByImat(): Observable<Array<AeronefByImat>> {
return this.apiService.get(`${this._apiDomain}/aeronefs/allByImat`) return this.apiService.get(`${this._apiDomain}/aeronefs/allByImat`).pipe(map((data) => data.aeronefs));
.pipe(map(data => data.aeronefs));
} }
getAllByImatByYear(): Observable<Array<AeronefByYear>> { getAllByImatByYear(): Observable<Array<AeronefByYear>> {
return this.apiService.get(`${this._apiDomain}/aeronefs/allByImatByYear`) return this.apiService.get(`${this._apiDomain}/aeronefs/allByImatByYear`).pipe(map((data) => data.aeronefs));
.pipe(map(data => data.aeronefs));
} }
}
}
@@ -1,22 +1,20 @@
import { Injectable } from '@angular/core'; import { Injectable, inject } from '@angular/core';
import { CalculatorResult, WeightSizeRange, weightSizes } from '@models'; import { CalculatorResult, WeightSizeRange, weightSizes } from '@models';
import { UtilitiesService } from '@services'; import { UtilitiesService } from '@services';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class CalculatorService { export class CalculatorService {
private _utilitiesService = inject(UtilitiesService);
public coeffKgLbs: number = this._utilitiesService.getCoeffKgLbs(); public coeffKgLbs: number = this._utilitiesService.getCoeffKgLbs();
public coeffFtM: number = this._utilitiesService.getCoeffFtM(); public coeffFtM: number = this._utilitiesService.getCoeffFtM();
constructor(
private _utilitiesService: UtilitiesService
) { }
private _getTableColumn(jumps: number): number { private _getTableColumn(jumps: number): number {
let column: number = 0; let column: number = 0;
weightSizes[0].ranges.some((range: WeightSizeRange) => { weightSizes[0].ranges.some((range: WeightSizeRange) => {
if (jumps >= range.start && jumps <= range.end) { if (jumps >= range.start && jumps <= range.end) {
column = (range.num-1) column = range.num - 1;
return true; return true;
} }
return false; return false;
@@ -40,11 +38,11 @@ export class CalculatorService {
} }
private _isInRange(nb: number, range: WeightSizeRange): boolean { private _isInRange(nb: number, range: WeightSizeRange): boolean {
return (nb >= range.start && nb <= range.end); return nb >= range.start && nb <= range.end;
} }
private _reduceLimit(surface: number, percentOff: number): number { private _reduceLimit(surface: number, percentOff: number): number {
return Math.ceil(surface * (100 - percentOff) / 100); return Math.ceil((surface * (100 - percentOff)) / 100);
} }
public canopySizeCalc(weight: number, jumps: number): CalculatorResult { public canopySizeCalc(weight: number, jumps: number): CalculatorResult {
@@ -54,12 +52,12 @@ export class CalculatorService {
const maxRange = 1600; const maxRange = 1600;
const result: CalculatorResult = { const result: CalculatorResult = {
min: 59, min: 59,
min11: 34 min11: 34,
}; };
if (jumps > maxRange) { if (jumps > maxRange) {
return result; return result;
} }
const index: number = (this._getTableLine(weight) - this._getTableLine(0)); const index: number = this._getTableLine(weight) - this._getTableLine(0);
result.min = weightSizes[index].ranges[this._getTableColumn(jumps)].value!; result.min = weightSizes[index].ranges[this._getTableColumn(jumps)].value!;
result.min11 = this._reduceLimit(result.min, 11); result.min11 = this._reduceLimit(result.min, 11);
@@ -67,7 +65,7 @@ export class CalculatorService {
} }
public convertFeet2Meters(size: number): number { public convertFeet2Meters(size: number): number {
return (size * this._utilitiesService.getCoeffFtM()); return size * this._utilitiesService.getCoeffFtM();
} }
public getCanopySizes(weight: number, reduce = false): number[] { public getCanopySizes(weight: number, reduce = false): number[] {
@@ -77,11 +75,11 @@ export class CalculatorService {
if (weight > 110) { if (weight > 110) {
weight = 110; weight = 110;
} }
const line = (weight - this._getTableLine(0)); const line = weight - this._getTableLine(0);
const data = weightSizes[line]; const data = weightSizes[line];
if (reduce) { if (reduce) {
return data.ranges.map((range: WeightSizeRange): number => { return data.ranges.map((range: WeightSizeRange): number => {
return Math.ceil(range.value! * (100 - 11) / 100); return Math.ceil((range.value! * (100 - 11)) / 100);
}); });
} else { } else {
return data.ranges.map((range: WeightSizeRange): number => { return data.ranges.map((range: WeightSizeRange): number => {
@@ -91,7 +89,7 @@ export class CalculatorService {
} }
public getCharge(canopySize: number, nakedWeight: number, equipementWeight: number): number { public getCharge(canopySize: number, nakedWeight: number, equipementWeight: number): number {
return (((nakedWeight + equipementWeight) * this.coeffKgLbs) / canopySize); return ((nakedWeight + equipementWeight) * this.coeffKgLbs) / canopySize;
} }
public getRangeNum(jumps: number): number { public getRangeNum(jumps: number): number {
@@ -125,5 +123,4 @@ export class CalculatorService {
return color; return color;
} }
}
}
@@ -1,4 +1,4 @@
import { Injectable } from '@angular/core'; import { Injectable, inject } from '@angular/core';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
@@ -7,29 +7,25 @@ import { CanopyBySize, CanopyByYear, CanopyModelBySize, CanopyModelByYear } from
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class CanopiesService { export class CanopiesService {
private apiService = inject(ApiService);
private _apiDomain = '/skydive'; private _apiDomain = '/skydive';
constructor(
private apiService: ApiService
) { }
getAllBySize(): Observable<Array<CanopyBySize>> { getAllBySize(): Observable<Array<CanopyBySize>> {
return this.apiService.get(`${this._apiDomain}/canopies/allBySize`) return this.apiService.get(`${this._apiDomain}/canopies/allBySize`).pipe(map((data) => data.canopies));
.pipe(map(data => data.canopies));
} }
getAllBySizeByYear(): Observable<Array<CanopyByYear>> { getAllBySizeByYear(): Observable<Array<CanopyByYear>> {
return this.apiService.get(`${this._apiDomain}/canopies/allBySizeByYear`) return this.apiService.get(`${this._apiDomain}/canopies/allBySizeByYear`).pipe(map((data) => data.canopies));
.pipe(map(data => data.canopies));
} }
getAllBySizeByModel(): Observable<Array<CanopyModelBySize>> { getAllBySizeByModel(): Observable<Array<CanopyModelBySize>> {
return this.apiService.get(`${this._apiDomain}/canopies/allBySizeByModel`) return this.apiService.get(`${this._apiDomain}/canopies/allBySizeByModel`).pipe(map((data) => data.canopies));
.pipe(map(data => data.canopies));
} }
getAllBySizeByModelByYear(): Observable<Array<CanopyModelByYear>> { getAllBySizeByModelByYear(): Observable<Array<CanopyModelByYear>> {
return this.apiService.get(`${this._apiDomain}/canopies/allBySizeByModelByYear`) return this.apiService
.pipe(map(data => data.canopies)); .get(`${this._apiDomain}/canopies/allBySizeByModelByYear`)
.pipe(map((data) => data.canopies));
} }
}
}
@@ -1,4 +1,4 @@
import { Injectable } from '@angular/core'; import { Injectable, inject } from '@angular/core';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
@@ -7,19 +7,15 @@ import { DropZoneByOaci, DropZoneByYear } from '@models';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class DropZonesService { export class DropZonesService {
private apiService = inject(ApiService);
private _apiDomain = '/skydive'; private _apiDomain = '/skydive';
constructor(
private apiService: ApiService
) { }
getAllByOaci(): Observable<Array<DropZoneByOaci>> { getAllByOaci(): Observable<Array<DropZoneByOaci>> {
return this.apiService.get(`${this._apiDomain}/dropzones/allByOaci`) return this.apiService.get(`${this._apiDomain}/dropzones/allByOaci`).pipe(map((data) => data.dropzones));
.pipe(map(data => data.dropzones));
} }
getAllByOaciByYear(): Observable<Array<DropZoneByYear>> { getAllByOaciByYear(): Observable<Array<DropZoneByYear>> {
return this.apiService.get(`${this._apiDomain}/dropzones/allByOaciByYear`) return this.apiService.get(`${this._apiDomain}/dropzones/allByOaciByYear`).pipe(map((data) => data.dropzones));
.pipe(map(data => data.dropzones));
} }
}
}
+66 -39
View File
@@ -1,21 +1,29 @@
import { Injectable } from '@angular/core'; import { Injectable, inject } from '@angular/core';
import { HttpParams } from '@angular/common/http'; import { HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { ApiService } from '../api.service'; import { ApiService } from '../api.service';
import { import {
Jump, JumpByCategorie, JumpByDate, JumpByDay, JumpByModule, JumpFile, Jump,
JumpList, JumpListConfig, JumpListFilters, JumpPageData, JumpByCategorie,
X2Data, SkydiverIdJumps JumpByDate,
JumpByDay,
JumpByModule,
JumpFile,
JumpList,
JumpListConfig,
JumpListFilters,
JumpPageData,
X2Data,
SkydiverIdJumps,
} from '@models'; } from '@models';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class JumpsService { export class JumpsService {
private apiService = inject(ApiService);
private _apiDomain = '/skydive'; private _apiDomain = '/skydive';
constructor(
private apiService: ApiService
) { }
query(config: JumpListConfig): Observable<JumpList> { query(config: JumpListConfig): Observable<JumpList> {
// Convert any filters over to Angular's URLSearchParams // Convert any filters over to Angular's URLSearchParams
@@ -49,13 +57,14 @@ export class JumpsService {
*/ */
const params: JumpListFilters = {} as JumpListFilters; const params: JumpListFilters = {} as JumpListFilters;
Object.assign(params, config.filters); Object.assign(params, config.filters);
return this.apiService return this.apiService.get(
.get( `${this._apiDomain}/jumps`,
`${this._apiDomain}/jumps`, new HttpParams({ fromObject: <
new HttpParams({ fromObject: <{ {
[param: string]: string | number | boolean | readonly (string | number | boolean)[]; [param: string]: string | number | boolean | readonly (string | number | boolean)[];
}>params }) }
); >params }),
);
} }
get(slug: string): Observable<JumpPageData> { get(slug: string): Observable<JumpPageData> {
@@ -67,79 +76,98 @@ export class JumpsService {
} }
getAll(): Observable<Array<Jump>> { getAll(): Observable<Array<Jump>> {
return this.apiService.get(`${this._apiDomain}/jumps`).pipe(map(data => data.jumps)); return this.apiService.get(`${this._apiDomain}/jumps`).pipe(map((data) => data.jumps));
} }
getAllByDate(): Observable<Array<JumpByDate>> { getAllByDate(): Observable<Array<JumpByDate>> {
return this.apiService.get(`${this._apiDomain}/jumps/allByDate`).pipe(map(data => data.jumps)); return this.apiService.get(`${this._apiDomain}/jumps/allByDate`).pipe(map((data) => data.jumps));
} }
getAllByCategorie(): Observable<Array<JumpByCategorie>> { getAllByCategorie(): Observable<Array<JumpByCategorie>> {
return this.apiService.get(`${this._apiDomain}/jumps/allByCategorie`).pipe(map(data => data.jumps)); return this.apiService.get(`${this._apiDomain}/jumps/allByCategorie`).pipe(map((data) => data.jumps));
} }
getAllByDay(config: JumpListConfig): Observable<Array<JumpByDay>> { getAllByDay(config: JumpListConfig): Observable<Array<JumpByDay>> {
const params: JumpListFilters = {} as JumpListFilters; const params: JumpListFilters = {} as JumpListFilters;
Object.assign(params, config.filters); Object.assign(params, config.filters);
return this.apiService.get(`${this._apiDomain}/jumps/allByDay`, new HttpParams({ fromObject: <{ return this.apiService
[param: string]: string | number | boolean | readonly (string | number | boolean)[]; .get(
}>params })) `${this._apiDomain}/jumps/allByDay`,
.pipe(map(data => data.days)); new HttpParams({ fromObject: <
{
[param: string]: string | number | boolean | readonly (string | number | boolean)[];
}
>params }),
)
.pipe(map((data) => data.days));
} }
getAllByModule(): Observable<Array<JumpByModule>> { getAllByModule(): Observable<Array<JumpByModule>> {
return this.apiService.get(`${this._apiDomain}/jumps/allByModule`).pipe(map(data => data.jumps)); return this.apiService.get(`${this._apiDomain}/jumps/allByModule`).pipe(map((data) => data.jumps));
} }
getAllFromSkydiverIdApi(config: JumpListConfig): Observable<SkydiverIdJumps> { getAllFromSkydiverIdApi(config: JumpListConfig): Observable<SkydiverIdJumps> {
const params: JumpListFilters = {} as JumpListFilters; const params: JumpListFilters = {} as JumpListFilters;
Object.assign(params, config.filters); Object.assign(params, config.filters);
return this.apiService.get(`${this._apiDomain}/jumps/allFromSkydiverIdApi`, new HttpParams({ fromObject: <{ return this.apiService
[param: string]: string | number | boolean | readonly (string | number | boolean)[]; .get(
}>params })) `${this._apiDomain}/jumps/allFromSkydiverIdApi`,
.pipe(map(data => data.jumps)); new HttpParams({ fromObject: <
{
[param: string]: string | number | boolean | readonly (string | number | boolean)[];
}
>params }),
)
.pipe(map((data) => data.jumps));
} }
getLastJump(): Observable<Jump> { getLastJump(): Observable<Jump> {
return this.apiService.get(`${this._apiDomain}/jumps/last`).pipe(map(data => data.jump)); return this.apiService.get(`${this._apiDomain}/jumps/last`).pipe(map((data) => data.jump));
} }
create(jump: Jump): Observable<Jump> { create(jump: Jump): Observable<Jump> {
return this.apiService.post(`${this._apiDomain}/jumps/`, { jump: jump }).pipe(map(data => data.jump)); return this.apiService.post(`${this._apiDomain}/jumps/`, { jump: jump }).pipe(map((data) => data.jump));
} }
update(jump: Jump): Observable<Jump> { update(jump: Jump): Observable<Jump> {
return this.apiService.put(`${this._apiDomain}/jumps/${jump.slug}`, { jump: jump }).pipe(map(data => data.jump)); return this.apiService
.put(`${this._apiDomain}/jumps/${jump.slug}`, { jump: jump })
.pipe(map((data) => data.jump));
} }
destroy(slug: string): Observable<boolean> { destroy(slug: string): Observable<boolean> {
return this.apiService.delete(`${this._apiDomain}/jumps/${slug}`).pipe(map(data => data.deleted)); return this.apiService.delete(`${this._apiDomain}/jumps/${slug}`).pipe(map((data) => data.deleted));
} }
save(jump: Jump): Observable<Jump> { save(jump: Jump): Observable<Jump> {
// If we're updating an existing jump // If we're updating an existing jump
if (jump.slug) { if (jump.slug) {
return this.apiService.put(`${this._apiDomain}/jumps/${jump.slug}`, { jump: jump }).pipe(map(data => data.jump)); return this.apiService
.put(`${this._apiDomain}/jumps/${jump.slug}`, { jump: jump })
.pipe(map((data) => data.jump));
// Otherwise, create a new jump // Otherwise, create a new jump
} else { } else {
return this.apiService.post(`${this._apiDomain}/jumps/`, { jump: jump }).pipe(map(data => data.jump)); return this.apiService.post(`${this._apiDomain}/jumps/`, { jump: jump }).pipe(map((data) => data.jump));
} }
} }
saveX2Data(slug: string, file: JumpFile, data: X2Data): Observable<Jump> { saveX2Data(slug: string, file: JumpFile, data: X2Data): Observable<Jump> {
return this.apiService.post(`${this._apiDomain}/jumps/data/${slug}`, { file: file, data: data }) return this.apiService
.pipe(map(data => data.jump)); .post(`${this._apiDomain}/jumps/data/${slug}`, { file: file, data: data })
.pipe(map((data) => data.jump));
} }
saveFile(slug: string, file: JumpFile): Observable<JumpFile> { saveFile(slug: string, file: JumpFile): Observable<JumpFile> {
return this.apiService.post(`${this._apiDomain}/jumps/file/${slug}`, { file: file }) return this.apiService
.pipe(map(data => data.file)); .post(`${this._apiDomain}/jumps/file/${slug}`, { file: file })
.pipe(map((data) => data.file));
} }
saveKml(slug: string, file: JumpFile): Observable<JumpFile> { saveKml(slug: string, file: JumpFile): Observable<JumpFile> {
return this.apiService.post(`${this._apiDomain}/jumps/kml/${slug}`, { file: file }) return this.apiService
.pipe(map(data => data.file)); .post(`${this._apiDomain}/jumps/kml/${slug}`, { file: file })
.pipe(map((data) => data.file));
} }
getAeronefs() { getAeronefs() {
@@ -163,5 +191,4 @@ export class JumpsService {
] ]
*/ */
} }
} }
+10 -9
View File
@@ -1,4 +1,4 @@
import { Injectable } from '@angular/core'; import { Injectable, inject } from '@angular/core';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
@@ -7,22 +7,23 @@ import { Qcm, QcmCategory, QcmQuestion } from '@models';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class QcmService { export class QcmService {
private apiService = inject(ApiService);
private _apiDomain = '/skydive'; private _apiDomain = '/skydive';
constructor(
private apiService: ApiService
) { }
get(type: string): Observable<Qcm> { get(type: string): Observable<Qcm> {
return this.apiService.get(`${this._apiDomain}/qcm/type/${type}`).pipe(map(data => data.qcm)); return this.apiService.get(`${this._apiDomain}/qcm/type/${type}`).pipe(map((data) => data.qcm));
} }
saveChoices(question: object): Observable<QcmQuestion> { saveChoices(question: object): Observable<QcmQuestion> {
return this.apiService.post(`${this._apiDomain}/qcm/choices`, { question: question }) return this.apiService
.pipe(map(data => data.question)); .post(`${this._apiDomain}/qcm/choices`, { question: question })
.pipe(map((data) => data.question));
} }
saveQuestions(category: object): Observable<QcmCategory> { saveQuestions(category: object): Observable<QcmCategory> {
return this.apiService.post(`${this._apiDomain}/qcm/questions`, { category: category }) return this.apiService
.pipe(map(data => data.category)); .post(`${this._apiDomain}/qcm/questions`, { category: category })
.pipe(map((data) => data.category));
} }
} }
+15 -14
View File
@@ -1,5 +1,5 @@
import { Injectable, OnDestroy } from '@angular/core'; import { Injectable, OnDestroy, inject } from '@angular/core';
import { HttpClient } from "@angular/common/http"; import { HttpClient } from '@angular/common/http';
import { Observable, BehaviorSubject, ReplaySubject, Subscription } from 'rxjs'; import { Observable, BehaviorSubject, ReplaySubject, Subscription } from 'rxjs';
import { distinctUntilChanged, take, tap } from 'rxjs/operators'; import { distinctUntilChanged, take, tap } from 'rxjs/operators';
@@ -8,6 +8,9 @@ import { JwtService } from '@services';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class UserService implements OnDestroy { export class UserService implements OnDestroy {
private readonly http = inject(HttpClient);
private readonly jwtService = inject(JwtService);
private _subcriptions: Array<Subscription> = new Array<Subscription>(); private _subcriptions: Array<Subscription> = new Array<Subscription>();
private _user: Subscription = new Subscription(); private _user: Subscription = new Subscription();
private currentUserSubject = new BehaviorSubject<User>({} as User); private currentUserSubject = new BehaviorSubject<User>({} as User);
@@ -16,12 +19,7 @@ export class UserService implements OnDestroy {
private isAuthenticatedSubject = new ReplaySubject<boolean>(1); private isAuthenticatedSubject = new ReplaySubject<boolean>(1);
public isAuthenticated = this.isAuthenticatedSubject.asObservable(); public isAuthenticated = this.isAuthenticatedSubject.asObservable();
private _apiDomain = '/cms'; private _apiDomain = '/cms';
constructor(
private readonly http: HttpClient,
private readonly jwtService: JwtService
) { }
ngOnDestroy() { ngOnDestroy() {
this._subcriptions.forEach((subscription: Subscription) => subscription.unsubscribe()); this._subcriptions.forEach((subscription: Subscription) => subscription.unsubscribe());
@@ -32,10 +30,12 @@ export class UserService implements OnDestroy {
populate() { populate() {
// If JWT detected, attempt to get & store user's info // If JWT detected, attempt to get & store user's info
if (this.jwtService.getToken()) { if (this.jwtService.getToken()) {
const user$: Observable<{ user: User }> = this.http.get<{ user: User }>(`${this._apiDomain}/user`).pipe(take(1)); const user$: Observable<{ user: User }> = this.http
.get<{ user: User }>(`${this._apiDomain}/user`)
.pipe(take(1));
this._user = user$.subscribe({ this._user = user$.subscribe({
next: (data) => this.setAuth(data.user), next: (data) => this.setAuth(data.user),
error: () => this.purgeAuth() error: () => this.purgeAuth(),
}); });
this._subcriptions.push(this._user); this._subcriptions.push(this._user);
} else { } else {
@@ -62,9 +62,11 @@ export class UserService implements OnDestroy {
this.isAuthenticatedSubject.next(false); this.isAuthenticatedSubject.next(false);
} }
attemptAuth(type: string, credentials?: { email: string; password: string; }): Observable<{ user: User }> { attemptAuth(type: string, credentials?: { email: string; password: string }): Observable<{ user: User }> {
const route = (type === 'login') ? '/login' : ''; const route = type === 'login' ? '/login' : '';
const user$: Observable<{ user: User }> = this.http.post<{ user: User }>(`${this._apiDomain}/user${route}`, { user: credentials }); const user$: Observable<{ user: User }> = this.http.post<{ user: User }>(`${this._apiDomain}/user${route}`, {
user: credentials,
});
/*return user$.pipe(map( /*return user$.pipe(map(
(data: any) => { (data: any) => {
this.setAuth(data.user); this.setAuth(data.user);
@@ -79,7 +81,7 @@ export class UserService implements OnDestroy {
} }
canAdministrate(): boolean { canAdministrate(): boolean {
return (this.currentUserSubject.value.role == 'Admin') ? true : false; return this.currentUserSubject.value.role == 'Admin' ? true : false;
} }
// Update the user on the server (email, pass, etc) // Update the user on the server (email, pass, etc)
@@ -90,5 +92,4 @@ export class UserService implements OnDestroy {
}), }),
); );
} }
} }
+124 -100
View File
@@ -1,6 +1,5 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Chart } from 'chart.js'; import { Chart } from 'chart.js';
import { Configuration } from 'ng-chartist';
import { BarConfig, CircleConfig, DoughnutConfig, LineConfig } from '@models'; import { BarConfig, CircleConfig, DoughnutConfig, LineConfig } from '@models';
@@ -9,7 +8,7 @@ export class UtilitiesService {
private _coeffKgLbs: number = 2.20462; private _coeffKgLbs: number = 2.20462;
private _coeffFtM: number = 0.092903; private _coeffFtM: number = 0.092903;
constructor() { } constructor() {}
getCoeffKgLbs(): number { getCoeffKgLbs(): number {
return this._coeffKgLbs; return this._coeffKgLbs;
@@ -19,19 +18,6 @@ export class UtilitiesService {
return this._coeffFtM; return this._coeffFtM;
} }
getBarConfig(): Configuration {
const config: Configuration = {
type: 'Bar',
data: {
'labels': [],
'series': []
},
options: {},
responsiveOptions: []
};
return config;
}
getChartColors(): string[] { getChartColors(): string[] {
const colors: string[] = [ const colors: string[] = [
'ct-color-a', 'ct-color-a',
@@ -59,22 +45,19 @@ export class UtilitiesService {
'ct-color-w', 'ct-color-w',
'ct-color-x', 'ct-color-x',
'ct-color-y', 'ct-color-y',
'ct-color-z' 'ct-color-z',
]; ];
return colors; return colors;
} }
getCurrentDateFr(): string { getCurrentDateFr(): string {
return new Date().toLocaleDateString('fr'); return new Date().toLocaleDateString('fr');
} }
secondsToDuration(seconds: number, delimiter: string = ':'): string { secondsToDuration(seconds: number, delimiter: string = ':'): string {
return [ return [Math.floor(seconds / 60 / 60), Math.floor((seconds / 60) % 60), Math.floor(seconds % 60)]
Math.floor(seconds / 60 / 60), .join(delimiter)
Math.floor(seconds / 60 % 60), .replace(/\b(\d)\b/g, '0$1'); //.replace(/^00\:/, '')
Math.floor(seconds % 60)
].join(delimiter)
.replace(/\b(\d)\b/g, "0$1")//.replace(/^00\:/, '')
} }
getSeriesColors(opacity: number, palette: string = 'all', offset: number = 0): string[] { getSeriesColors(opacity: number, palette: string = 'all', offset: number = 0): string[] {
@@ -101,7 +84,7 @@ export class UtilitiesService {
`rgba(143, 202, 202, ${opacity})`, `rgba(143, 202, 202, ${opacity})`,
`rgba(204, 226, 203, ${opacity})`, `rgba(204, 226, 203, ${opacity})`,
`rgba(182, 207, 182, ${opacity})`, `rgba(182, 207, 182, ${opacity})`,
`rgba(151, 193, 169, ${opacity})` `rgba(151, 193, 169, ${opacity})`,
]; ];
break; break;
case 'red': case 'red':
@@ -114,7 +97,7 @@ export class UtilitiesService {
`rgba(228, 145, 122, ${opacity})`, `rgba(228, 145, 122, ${opacity})`,
`rgba(238, 168, 148, ${opacity})`, `rgba(238, 168, 148, ${opacity})`,
`rgba(247, 192, 175, ${opacity})`, `rgba(247, 192, 175, ${opacity})`,
`rgba(255, 215, 203, ${opacity})` `rgba(255, 215, 203, ${opacity})`,
]; ];
break; break;
case 'green': case 'green':
@@ -127,7 +110,7 @@ export class UtilitiesService {
`rgba(134, 187, 142, ${opacity})`, `rgba(134, 187, 142, ${opacity})`,
`rgba(156, 203, 163, ${opacity})`, `rgba(156, 203, 163, ${opacity})`,
`rgba(179, 219, 184, ${opacity})`, `rgba(179, 219, 184, ${opacity})`,
`rgba(201, 235, 205, ${opacity})` `rgba(201, 235, 205, ${opacity})`,
]; ];
break; break;
case 'blue': case 'blue':
@@ -140,7 +123,7 @@ export class UtilitiesService {
`rgba(127, 170, 198, ${opacity})`, `rgba(127, 170, 198, ${opacity})`,
`rgba(148, 190, 217, ${opacity})`, `rgba(148, 190, 217, ${opacity})`,
`rgba(171, 210, 236, ${opacity})`, `rgba(171, 210, 236, ${opacity})`,
`rgba(193, 231, 255, ${opacity})` `rgba(193, 231, 255, ${opacity})`,
]; ];
break; break;
case 'all': case 'all':
@@ -197,7 +180,7 @@ export class UtilitiesService {
`rgba(217, 202, 174, ${opacity})`, `rgba(217, 202, 174, ${opacity})`,
`rgba(151, 136, 199, ${opacity})`, `rgba(151, 136, 199, ${opacity})`,
`rgba(212, 206, 112, ${opacity})`, `rgba(212, 206, 112, ${opacity})`,
`rgba(255, 255, 255, ${opacity})` `rgba(255, 255, 255, ${opacity})`,
]; ];
if (offset > 0 && offset < colors.length) { if (offset > 0 && offset < colors.length) {
colors = colors.slice(offset); colors = colors.slice(offset);
@@ -216,8 +199,8 @@ export class UtilitiesService {
label: 'Nombre total de sauts', label: 'Nombre total de sauts',
backgroundColor: this.getSeriesColors(0.8), backgroundColor: this.getSeriesColors(0.8),
borderColor: this.getSeriesColors(1), // 'rgba(255, 255, 255, 1)' borderColor: this.getSeriesColors(1), // 'rgba(255, 255, 255, 1)'
borderWidth: 2 borderWidth: 2,
} },
], ],
circleChartOptions: { circleChartOptions: {
cutout: '90%', cutout: '90%',
@@ -226,25 +209,27 @@ export class UtilitiesService {
//spacing: -10, //spacing: -10,
borderJoinStyle: 'round', borderJoinStyle: 'round',
borderRadius: 10, borderRadius: 10,
borderWidth: 0 borderWidth: 0,
} },
}, },
plugins: { plugins: {
legend: { legend: {
display: false, display: false,
position: 'left' position: 'left',
} },
}, },
responsive: true, responsive: true,
maintainAspectRatio: false, maintainAspectRatio: false,
animation: { animation: {
onProgress: function (this: Chart) { onProgress: function (this: Chart) {
const width = this.width, height = this.height, ctx = this.ctx; const width = this.width,
height = this.height,
ctx = this.ctx;
const count: number = parseInt(this.data.datasets[0].data[0]!.toString()); const count: number = parseInt(this.data.datasets[0].data[0]!.toString());
const diff: number = parseInt(this.data.datasets[0].data[1]!.toString()); const diff: number = parseInt(this.data.datasets[0].data[1]!.toString());
const total: number = (count + diff); const total: number = count + diff;
const percent: number = Math.round((count/total*100)); const percent: number = Math.round((count / total) * 100);
const lineHeight = (height / 8); const lineHeight = height / 8;
ctx.restore(); ctx.restore();
let fontSize = (height / 120).toFixed(2); let fontSize = (height / 120).toFixed(2);
ctx.font = `${fontSize}em sans-serif`; ctx.font = `${fontSize}em sans-serif`;
@@ -255,7 +240,7 @@ export class UtilitiesService {
let text = this.data.datasets[0].label!; let text = this.data.datasets[0].label!;
let textX = Math.round((width - ctx.measureText(text).width) / 2); let textX = Math.round((width - ctx.measureText(text).width) / 2);
let textY = height / 2; let textY = height / 2;
ctx.fillText(text, textX, (textY-lineHeight)); ctx.fillText(text, textX, textY - lineHeight);
text = `${percent}%`; text = `${percent}%`;
textX = Math.round((width - ctx.measureText(text).width) / 2); textX = Math.round((width - ctx.measureText(text).width) / 2);
textY = height / 2; textY = height / 2;
@@ -269,17 +254,19 @@ export class UtilitiesService {
text = `${count} / ${total}`; text = `${count} / ${total}`;
textX = Math.round((width - ctx.measureText(text).width) / 2); textX = Math.round((width - ctx.measureText(text).width) / 2);
textY = height / 2; textY = height / 2;
ctx.fillText(text, textX, (textY+lineHeight)); ctx.fillText(text, textX, textY + lineHeight);
ctx.save(); ctx.save();
//console.log(width, height, fontSize); //console.log(width, height, fontSize);
}, },
onComplete: function (this: Chart) { onComplete: function (this: Chart) {
const width = this.width, height = this.height, ctx = this.ctx; const width = this.width,
height = this.height,
ctx = this.ctx;
const count: number = parseInt(this.data.datasets[0].data[0]!.toString()); const count: number = parseInt(this.data.datasets[0].data[0]!.toString());
const diff: number = parseInt(this.data.datasets[0].data[1]!.toString()); const diff: number = parseInt(this.data.datasets[0].data[1]!.toString());
const total: number = (count + diff); const total: number = count + diff;
const percent: number = Math.round((count/total*100)); const percent: number = Math.round((count / total) * 100);
const lineHeight = (height / 8); const lineHeight = height / 8;
ctx.restore(); ctx.restore();
let fontSize = (height / 120).toFixed(2); let fontSize = (height / 120).toFixed(2);
ctx.font = `${fontSize}em sans-serif`; ctx.font = `${fontSize}em sans-serif`;
@@ -291,7 +278,7 @@ export class UtilitiesService {
let text = this.data.datasets[0].label!; let text = this.data.datasets[0].label!;
let textX = Math.round((width - ctx.measureText(text).width) / 2); let textX = Math.round((width - ctx.measureText(text).width) / 2);
let textY = height / 2; let textY = height / 2;
ctx.fillText(text, textX, (textY-lineHeight)); ctx.fillText(text, textX, textY - lineHeight);
text = `${percent}%`; text = `${percent}%`;
textX = Math.round((width - ctx.measureText(text).width) / 2); textX = Math.round((width - ctx.measureText(text).width) / 2);
textY = height / 2; textY = height / 2;
@@ -305,7 +292,7 @@ export class UtilitiesService {
text = `${count} / ${total}`; text = `${count} / ${total}`;
textX = Math.round((width - ctx.measureText(text).width) / 2); textX = Math.round((width - ctx.measureText(text).width) / 2);
textY = height / 2; textY = height / 2;
ctx.fillText(text, textX, (textY+lineHeight)); ctx.fillText(text, textX, textY + lineHeight);
ctx.save(); ctx.save();
//console.log(width, height, fontSize); //console.log(width, height, fontSize);
}, },
@@ -321,22 +308,26 @@ export class UtilitiesService {
id: 'beforeinit' id: 'beforeinit'
},*/ },*/
{ {
beforeDatasetDraw: (chart: Chart<"doughnut", number[], unknown>) => { beforeDatasetDraw: (chart: Chart<'doughnut', number[], unknown>) => {
const width = chart.width, height = chart.height, ctx = chart.ctx; const width = chart.width,
height = chart.height,
ctx = chart.ctx;
ctx.restore(); ctx.restore();
const fontSize = (height / 150).toFixed(2); const fontSize = (height / 150).toFixed(2);
ctx.font = fontSize + "em sans-serif"; ctx.font = fontSize + 'em sans-serif';
ctx.fillStyle = "#ffffff"; ctx.fillStyle = '#ffffff';
ctx.textBaseline = "middle"; ctx.textBaseline = 'middle';
const text = chart.data.datasets[0].data[0] + "%", textX = Math.round((width - ctx.measureText(text).width) / 2), textY = height / 2; const text = chart.data.datasets[0].data[0] + '%',
textX = Math.round((width - ctx.measureText(text).width) / 2),
textY = height / 2;
ctx.fillText(text, textX, textY); ctx.fillText(text, textX, textY);
ctx.save(); ctx.save();
console.log(width, height, fontSize); console.log(width, height, fontSize);
}, },
id: 'doughnutlabel' id: 'doughnutlabel',
} },
], ],
circleChartLegend: false circleChartLegend: false,
}; };
return config; return config;
} }
@@ -350,25 +341,25 @@ export class UtilitiesService {
label: 'Nombre total de sauts', label: 'Nombre total de sauts',
backgroundColor: this.getSeriesColors(0.8), backgroundColor: this.getSeriesColors(0.8),
borderColor: this.getSeriesColors(1), // 'rgba(255, 255, 255, 1)' borderColor: this.getSeriesColors(1), // 'rgba(255, 255, 255, 1)'
borderWidth: 2 borderWidth: 2,
} },
], ],
doughnutChartOptions: { doughnutChartOptions: {
elements: { elements: {
arc: { arc: {
borderWidth: 2, borderWidth: 2,
} },
}, },
plugins: { plugins: {
legend: { legend: {
display: true, display: true,
position: 'left' position: 'left',
} },
}, },
responsive: true, responsive: true,
maintainAspectRatio: false maintainAspectRatio: false,
}, },
doughnutChartLegend: false doughnutChartLegend: false,
}; };
return config; return config;
} }
@@ -377,19 +368,19 @@ export class UtilitiesService {
const config: BarConfig = { const config: BarConfig = {
barChartData: { barChartData: {
labels: [''], labels: [''],
datasets: [] datasets: [],
}, },
barChartOptions: { barChartOptions: {
plugins: { plugins: {
legend: { legend: {
display: true, display: true,
position: 'top' position: 'top',
} },
}, },
elements: { elements: {
bar: { bar: {
borderWidth: 1, borderWidth: 1,
} },
}, },
/*interaction: { /*interaction: {
intersect: false, intersect: false,
@@ -400,20 +391,30 @@ export class UtilitiesService {
display: false, display: false,
beginAtZero: true, beginAtZero: true,
ticks: { color: 'rgba(255,255,255,0.3)' }, ticks: { color: 'rgba(255,255,255,0.3)' },
grid: { display: true, color: 'rgba(255,255,255,0.1)', tickBorderDash: [1,2], tickBorderDashOffset: 2 } grid: {
display: true,
color: 'rgba(255,255,255,0.1)',
tickBorderDash: [1, 2],
tickBorderDashOffset: 2,
},
}, },
y: { y: {
display: true, display: true,
beginAtZero: true, beginAtZero: true,
ticks: { color: 'rgba(255,255,255,0.3)' }, ticks: { color: 'rgba(255,255,255,0.3)' },
grid: { display: true, color: 'rgba(255,255,255,0.2)', tickBorderDash: [1,2], tickBorderDashOffset: 2 } grid: {
} display: true,
color: 'rgba(255,255,255,0.2)',
tickBorderDash: [1, 2],
tickBorderDashOffset: 2,
},
},
}, },
responsive: true, responsive: true,
maintainAspectRatio: false maintainAspectRatio: false,
}, },
barChartPlugins: [], barChartPlugins: [],
barChartLegend: true barChartLegend: true,
}; };
return config; return config;
} }
@@ -422,24 +423,24 @@ export class UtilitiesService {
const config: BarConfig = { const config: BarConfig = {
barChartData: { barChartData: {
labels: [''], labels: [''],
datasets: [] datasets: [],
}, },
barChartOptions: { barChartOptions: {
indexAxis: 'y', indexAxis: 'y',
elements: { elements: {
bar: { bar: {
borderWidth: 1, borderWidth: 1,
} },
}, },
plugins: { plugins: {
legend: { legend: {
display: true, display: true,
position: 'left' position: 'left',
}, },
title: { title: {
display: false, display: false,
text: 'Nombre total de sauts' text: 'Nombre total de sauts',
} },
}, },
responsive: true, responsive: true,
aspectRatio: 3, aspectRatio: 3,
@@ -447,17 +448,17 @@ export class UtilitiesService {
x: { x: {
beginAtZero: true, beginAtZero: true,
ticks: { color: 'rgba(255,255,255,0.3)' }, ticks: { color: 'rgba(255,255,255,0.3)' },
grid: { display: true, color: 'rgba(255,255,255,0.1)', tickBorderDash: [1,2] } grid: { display: true, color: 'rgba(255,255,255,0.1)', tickBorderDash: [1, 2] },
}, },
y: { y: {
beginAtZero: true, beginAtZero: true,
ticks: { color: 'rgba(255,255,255,0.3)' }, ticks: { color: 'rgba(255,255,255,0.3)' },
grid: { display: false, color: 'rgba(255,255,255,0.2)' } grid: { display: false, color: 'rgba(255,255,255,0.2)' },
} },
} },
}, },
barChartPlugins: [], barChartPlugins: [],
barChartLegend: false barChartLegend: false,
}; };
return config; return config;
} }
@@ -466,14 +467,14 @@ export class UtilitiesService {
const config: LineConfig = { const config: LineConfig = {
lineChartData: { lineChartData: {
labels: [], labels: [],
datasets: [] datasets: [],
}, },
lineChartOptions: { lineChartOptions: {
plugins: { plugins: {
legend: { legend: {
display: true, display: true,
position: 'top' position: 'top',
} },
}, },
/*interaction: { /*interaction: {
intersect: false, intersect: false,
@@ -484,64 +485,87 @@ export class UtilitiesService {
display: true, display: true,
beginAtZero: true, beginAtZero: true,
ticks: { color: 'rgba(255,255,255,0.3)' }, ticks: { color: 'rgba(255,255,255,0.3)' },
grid: { display: true, color: 'rgba(255,255,255,0.1)', tickBorderDash: [1,2], tickBorderDashOffset: 2 } grid: {
display: true,
color: 'rgba(255,255,255,0.1)',
tickBorderDash: [1, 2],
tickBorderDashOffset: 2,
},
}, },
y: { y: {
display: true, display: true,
beginAtZero: true, beginAtZero: true,
ticks: { color: 'rgba(255,255,255,0.3)' }, ticks: { color: 'rgba(255,255,255,0.3)' },
grid: { display: true, color: 'rgba(255,255,255,0.2)', tickBorderDash: [1,2], tickBorderDashOffset: 2 } grid: {
} display: true,
color: 'rgba(255,255,255,0.2)',
tickBorderDash: [1, 2],
tickBorderDashOffset: 2,
},
},
}, },
responsive: true, responsive: true,
maintainAspectRatio: false maintainAspectRatio: false,
}, },
lineChartLegend: true lineChartLegend: true,
}; };
return config; return config;
} }
getMonthsList(): Array<string> { getMonthsList(): Array<string> {
return ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre']; return [
'Janvier',
'Février',
'Mars',
'Avril',
'Mai',
'Juin',
'Juillet',
'Août',
'Septembre',
'Octobre',
'Novembre',
'Décembre',
];
} }
getStackedLineAreaChartConfig(): LineConfig { getStackedLineAreaChartConfig(): LineConfig {
const config: LineConfig = { const config: LineConfig = {
lineChartData: { lineChartData: {
labels: [], labels: [],
datasets: [] datasets: [],
}, },
lineChartOptions: { lineChartOptions: {
plugins: { plugins: {
legend: { legend: {
display: true, display: true,
position: 'top' position: 'top',
} },
}, },
interaction: { interaction: {
mode: 'nearest', mode: 'nearest',
axis: 'x', axis: 'x',
intersect: false intersect: false,
}, },
scales: { scales: {
x: { x: {
display: true, display: true,
beginAtZero: true, beginAtZero: true,
ticks: { color: 'rgba(255,255,255,0.3)' }, ticks: { color: 'rgba(255,255,255,0.3)' },
grid: { display: true, color: 'rgba(255,255,255,0.1)', tickBorderDash: [1,2] } grid: { display: true, color: 'rgba(255,255,255,0.1)', tickBorderDash: [1, 2] },
}, },
y: { y: {
display: true, display: true,
beginAtZero: true, beginAtZero: true,
stacked: true, stacked: true,
ticks: { color: 'rgba(255,255,255,0.3)' }, ticks: { color: 'rgba(255,255,255,0.3)' },
grid: { display: true, color: 'rgba(255,255,255,0.2)', tickBorderDash: [1,2] } grid: { display: true, color: 'rgba(255,255,255,0.2)', tickBorderDash: [1, 2] },
} },
}, },
responsive: true, responsive: true,
maintainAspectRatio: false maintainAspectRatio: false,
}, },
lineChartLegend: true lineChartLegend: true,
}; };
return config; return config;
} }
+4 -4
View File
@@ -1,12 +1,12 @@
@use 'sass:meta'; @use "sass:meta";
@use '@angular/material' as mat; @use "@angular/material" as mat;
@mixin _progress-bar-color($config-or-theme, $variants) { @mixin _progress-bar-color($config-or-theme, $variants) {
$config: mat.m2-get-color-config($config-or-theme); $config: mat.m2-get-color-config($config-or-theme);
@each $variant, $variant-palette in $variants { @each $variant, $variant-palette in $variants {
&.mat-#{"" + $variant} { &.mat-#{"" + $variant} {
#{--mdc-linear-progress-active-indicator-color}: mat.m2-get-color-from-palette($variant-palette); #{--mat-progress-bar-active-indicator-color}: mat.m2-get-color-from-palette($variant-palette);
#{--mdc-linear-progress-track-color}: mat.m2-get-color-from-palette($variant-palette, 500, 0.25); #{--mat-progress-bar-track-color}: mat.m2-get-color-from-palette($variant-palette, 500, 0.25);
} }
} }
} }
+278 -277
View File
@@ -24,25 +24,26 @@ Table
} }
} }
table { table {
background-color:transparent; background-color: transparent;
&.table { &.table {
border-spacing: 0; border-spacing: 0;
border-collapse: collapse; border-collapse: collapse;
margin-bottom:20px; margin-bottom: 20px;
max-width:100%; max-width: 100%;
width:100%; width: 100%;
text-align: left; text-align: left;
td, th { td,
th {
padding: 0; padding: 0;
} }
th { th {
text-align:left text-align: left;
} }
} }
.mat-mdc-icon-button.mat-mdc-button-base { .mat-mdc-icon-button.mat-mdc-button-base {
--mdc-icon-button-state-layer-size: 38px; --mat-icon-button-state-layer-size: 38px;
width: var(--mdc-icon-button-state-layer-size); width: var(--mat-icon-button-state-layer-size);
height: var(--mdc-icon-button-state-layer-size); height: var(--mat-icon-button-state-layer-size);
padding: 7px; padding: 7px;
.material-icons { .material-icons {
font-size: 22px; font-size: 22px;
@@ -54,269 +55,269 @@ table {
} }
} }
caption { caption {
padding-top:8px; padding-top: 8px;
padding-bottom:8px; padding-bottom: 8px;
color:#777; color: #777;
text-align:left text-align: left;
} }
.table>tbody>tr>td, .table > tbody > tr > td,
.table>tbody>tr>th, .table > tbody > tr > th,
.table>tfoot>tr>td, .table > tfoot > tr > td,
.table>tfoot>tr>th, .table > tfoot > tr > th,
.table>thead>tr>td, .table > thead > tr > td,
.table>thead>tr>th { .table > thead > tr > th {
padding:8px; padding: 8px;
line-height:1.42857143; line-height: 1.42857143;
vertical-align:top; vertical-align: top;
border-top:1px solid #ddd border-top: 1px solid #ddd;
} }
.table>thead>tr>th { .table > thead > tr > th {
vertical-align:bottom; vertical-align: bottom;
border-bottom:2px solid #ddd border-bottom: 2px solid #ddd;
} }
.table>caption+thead>tr:first-child>td, .table > caption + thead > tr:first-child > td,
.table>caption+thead>tr:first-child>th, .table > caption + thead > tr:first-child > th,
.table>colgroup+thead>tr:first-child>td, .table > colgroup + thead > tr:first-child > td,
.table>colgroup+thead>tr:first-child>th, .table > colgroup + thead > tr:first-child > th,
.table>thead:first-child>tr:first-child>td, .table > thead:first-child > tr:first-child > td,
.table>thead:first-child>tr:first-child>th { .table > thead:first-child > tr:first-child > th {
border-top:0 border-top: 0;
} }
.table>tbody+tbody { .table > tbody + tbody {
border-top:2px solid #ddd border-top: 2px solid #ddd;
} }
.table .table { .table .table {
background-color:#fff background-color: #fff;
} }
.table-condensed>tbody>tr>td, .table-condensed > tbody > tr > td,
.table-condensed>tbody>tr>th, .table-condensed > tbody > tr > th,
.table-condensed>tfoot>tr>td, .table-condensed > tfoot > tr > td,
.table-condensed>tfoot>tr>th, .table-condensed > tfoot > tr > th,
.table-condensed>thead>tr>td, .table-condensed > thead > tr > td,
.table-condensed>thead>tr>th { .table-condensed > thead > tr > th {
padding:5px padding: 5px;
} }
.table-bordered { .table-bordered {
border:1px solid #ddd border: 1px solid #ddd;
} }
.table-bordered>tbody>tr>td, .table-bordered > tbody > tr > td,
.table-bordered>tbody>tr>th, .table-bordered > tbody > tr > th,
.table-bordered>tfoot>tr>td, .table-bordered > tfoot > tr > td,
.table-bordered>tfoot>tr>th, .table-bordered > tfoot > tr > th,
.table-bordered>thead>tr>td, .table-bordered > thead > tr > td,
.table-bordered>thead>tr>th { .table-bordered > thead > tr > th {
border:1px solid #ddd border: 1px solid #ddd;
} }
.table-bordered>thead>tr>td, .table-bordered > thead > tr > td,
.table-bordered>thead>tr>th { .table-bordered > thead > tr > th {
border-bottom-width:2px border-bottom-width: 2px;
} }
.table-striped>tbody>tr:nth-of-type(odd) { .table-striped > tbody > tr:nth-of-type(odd) {
background-color:#f9f9f9 background-color: #f9f9f9;
} }
.table-hover>tbody>tr:hover { .table-hover > tbody > tr:hover {
background-color:#f5f5f5 background-color: #f5f5f5;
} }
table col[class*=col-] { table col[class*="col-"] {
position:static; position: static;
display:table-column; display: table-column;
float:none float: none;
} }
table td[class*=col-], table td[class*="col-"],
table th[class*=col-] { table th[class*="col-"] {
position:static; position: static;
display:table-cell; display: table-cell;
float:none float: none;
} }
.table>tbody>tr.active>td, .table > tbody > tr.active > td,
.table>tbody>tr.active>th, .table > tbody > tr.active > th,
.table>tbody>tr>td.active, .table > tbody > tr > td.active,
.table>tbody>tr>th.active, .table > tbody > tr > th.active,
.table>tfoot>tr.active>td, .table > tfoot > tr.active > td,
.table>tfoot>tr.active>th, .table > tfoot > tr.active > th,
.table>tfoot>tr>td.active, .table > tfoot > tr > td.active,
.table>tfoot>tr>th.active, .table > tfoot > tr > th.active,
.table>thead>tr.active>td, .table > thead > tr.active > td,
.table>thead>tr.active>th, .table > thead > tr.active > th,
.table>thead>tr>td.active, .table > thead > tr > td.active,
.table>thead>tr>th.active { .table > thead > tr > th.active {
background-color:#f5f5f5; background-color: #f5f5f5;
} }
.table-hover>tbody>tr.active:hover>td, .table-hover > tbody > tr.active:hover > td,
.table-hover>tbody>tr.active:hover>th, .table-hover > tbody > tr.active:hover > th,
.table-hover>tbody>tr:hover>.active, .table-hover > tbody > tr:hover > .active,
.table-hover>tbody>tr>td.active:hover, .table-hover > tbody > tr > td.active:hover,
.table-hover>tbody>tr>th.active:hover { .table-hover > tbody > tr > th.active:hover {
background-color:#e8e8e8; background-color: #e8e8e8;
} }
.table>tbody>tr.success>td, .table > tbody > tr.success > td,
.table>tbody>tr.success>th, .table > tbody > tr.success > th,
.table>tbody>tr>td.success, .table > tbody > tr > td.success,
.table>tbody>tr>th.success, .table > tbody > tr > th.success,
.table>tfoot>tr.success>td, .table > tfoot > tr.success > td,
.table>tfoot>tr.success>th, .table > tfoot > tr.success > th,
.table>tfoot>tr>td.success, .table > tfoot > tr > td.success,
.table>tfoot>tr>th.success, .table > tfoot > tr > th.success,
.table>thead>tr.success>td, .table > thead > tr.success > td,
.table>thead>tr.success>th, .table > thead > tr.success > th,
.table>thead>tr>td.success, .table > thead > tr > td.success,
.table>thead>tr>th.success { .table > thead > tr > th.success {
background-color:#dff0d8; background-color: #dff0d8;
} }
.table-hover>tbody>tr.success:hover>td, .table-hover > tbody > tr.success:hover > td,
.table-hover>tbody>tr.success:hover>th, .table-hover > tbody > tr.success:hover > th,
.table-hover>tbody>tr:hover>.success, .table-hover > tbody > tr:hover > .success,
.table-hover>tbody>tr>td.success:hover, .table-hover > tbody > tr > td.success:hover,
.table-hover>tbody>tr>th.success:hover { .table-hover > tbody > tr > th.success:hover {
background-color:#d0e9c6; background-color: #d0e9c6;
} }
.table>tbody>tr.info>td, .table > tbody > tr.info > td,
.table>tbody>tr.info>th, .table > tbody > tr.info > th,
.table>tbody>tr>td.info, .table > tbody > tr > td.info,
.table>tbody>tr>th.info, .table > tbody > tr > th.info,
.table>tfoot>tr.info>td, .table > tfoot > tr.info > td,
.table>tfoot>tr.info>th, .table > tfoot > tr.info > th,
.table>tfoot>tr>td.info, .table > tfoot > tr > td.info,
.table>tfoot>tr>th.info, .table > tfoot > tr > th.info,
.table>thead>tr.info>td, .table > thead > tr.info > td,
.table>thead>tr.info>th, .table > thead > tr.info > th,
.table>thead>tr>td.info, .table > thead > tr > td.info,
.table>thead>tr>th.info { .table > thead > tr > th.info {
background-color:#d9edf7; background-color: #d9edf7;
} }
.table-hover>tbody>tr.info:hover>td, .table-hover > tbody > tr.info:hover > td,
.table-hover>tbody>tr.info:hover>th, .table-hover > tbody > tr.info:hover > th,
.table-hover>tbody>tr:hover>.info, .table-hover > tbody > tr:hover > .info,
.table-hover>tbody>tr>td.info:hover, .table-hover > tbody > tr > td.info:hover,
.table-hover>tbody>tr>th.info:hover { .table-hover > tbody > tr > th.info:hover {
background-color:#c4e3f3; background-color: #c4e3f3;
} }
.table>tbody>tr.warning>td, .table > tbody > tr.warning > td,
.table>tbody>tr.warning>th, .table > tbody > tr.warning > th,
.table>tbody>tr>td.warning, .table > tbody > tr > td.warning,
.table>tbody>tr>th.warning, .table > tbody > tr > th.warning,
.table>tfoot>tr.warning>td, .table > tfoot > tr.warning > td,
.table>tfoot>tr.warning>th, .table > tfoot > tr.warning > th,
.table>tfoot>tr>td.warning, .table > tfoot > tr > td.warning,
.table>tfoot>tr>th.warning, .table > tfoot > tr > th.warning,
.table>thead>tr.warning>td, .table > thead > tr.warning > td,
.table>thead>tr.warning>th, .table > thead > tr.warning > th,
.table>thead>tr>td.warning, .table > thead > tr > td.warning,
.table>thead>tr>th.warning { .table > thead > tr > th.warning {
background-color:#fcf8e3; background-color: #fcf8e3;
} }
.table-hover>tbody>tr.warning:hover>td, .table-hover > tbody > tr.warning:hover > td,
.table-hover>tbody>tr.warning:hover>th, .table-hover > tbody > tr.warning:hover > th,
.table-hover>tbody>tr:hover>.warning, .table-hover > tbody > tr:hover > .warning,
.table-hover>tbody>tr>td.warning:hover, .table-hover > tbody > tr > td.warning:hover,
.table-hover>tbody>tr>th.warning:hover { .table-hover > tbody > tr > th.warning:hover {
background-color:#faf2cc; background-color: #faf2cc;
} }
.table>tbody>tr.danger>td, .table > tbody > tr.danger > td,
.table>tbody>tr.danger>th, .table > tbody > tr.danger > th,
.table>tbody>tr>td.danger, .table > tbody > tr > td.danger,
.table>tbody>tr>th.danger, .table > tbody > tr > th.danger,
.table>tfoot>tr.danger>td, .table > tfoot > tr.danger > td,
.table>tfoot>tr.danger>th, .table > tfoot > tr.danger > th,
.table>tfoot>tr>td.danger, .table > tfoot > tr > td.danger,
.table>tfoot>tr>th.danger, .table > tfoot > tr > th.danger,
.table>thead>tr.danger>td, .table > thead > tr.danger > td,
.table>thead>tr.danger>th, .table > thead > tr.danger > th,
.table>thead>tr>td.danger, .table > thead > tr > td.danger,
.table>thead>tr>th.danger { .table > thead > tr > th.danger {
background-color:#f2dede; background-color: #f2dede;
} }
.table-hover>tbody>tr.danger:hover>td, .table-hover > tbody > tr.danger:hover > td,
.table-hover>tbody>tr.danger:hover>th, .table-hover > tbody > tr.danger:hover > th,
.table-hover>tbody>tr:hover>.danger, .table-hover > tbody > tr:hover > .danger,
.table-hover>tbody>tr>td.danger:hover, .table-hover > tbody > tr > td.danger:hover,
.table-hover>tbody>tr>th.danger:hover { .table-hover > tbody > tr > th.danger:hover {
background-color:#ebcccc; background-color: #ebcccc;
} }
tr.mat-mdc-header-row.primary, tr.mat-mdc-header-row.primary,
.table>thead>tr.primary { .table > thead > tr.primary {
background-color: rgba(167, 212, 196, 0.1); // #a5d492; background-color: rgba(167, 212, 196, 0.1); // #a5d492;
} }
.table>tbody>tr.primary.active>td, .table > tbody > tr.primary.active > td,
.table>tbody>tr.primary.active>th, .table > tbody > tr.primary.active > th,
.table>tbody>tr.primary>td.active, .table > tbody > tr.primary > td.active,
.table>tbody>tr.primary>th.active, .table > tbody > tr.primary > th.active,
.table>tfoot>tr.primary.active>td, .table > tfoot > tr.primary.active > td,
.table>tfoot>tr.primary.active>th, .table > tfoot > tr.primary.active > th,
.table>tfoot>tr.primary>td.active, .table > tfoot > tr.primary > td.active,
.table>tfoot>tr.primary>th.active, .table > tfoot > tr.primary > th.active,
.table>thead>tr.primary.active>td, .table > thead > tr.primary.active > td,
.table>thead>tr.primary.active>th, .table > thead > tr.primary.active > th,
.table>thead>tr.primary>td.active, .table > thead > tr.primary > td.active,
.table>thead>tr.primary>th.active { .table > thead > tr.primary > th.active {
background-color: rgba(165, 212, 146, 0.2); background-color: rgba(165, 212, 146, 0.2);
} }
.table-hover>tbody>tr.primary.active:hover>td, .table-hover > tbody > tr.primary.active:hover > td,
.table-hover>tbody>tr.primary.active:hover>th, .table-hover > tbody > tr.primary.active:hover > th,
.table-hover>tbody>tr.primary:hover>.active, .table-hover > tbody > tr.primary:hover > .active,
.table-hover>tbody>tr.primary>td.active:hover, .table-hover > tbody > tr.primary > td.active:hover,
.table-hover>tbody>tr.primary>th.active:hover { .table-hover > tbody > tr.primary > th.active:hover {
background-color: rgba(165, 212, 146, 0.3); background-color: rgba(165, 212, 146, 0.3);
} }
tr.mat-mdc-header-row.warn, tr.mat-mdc-header-row.warn,
.table>thead>tr.warn { .table > thead > tr.warn {
background-color: rgba(151, 136, 199, 0.1); // #9788c7 background-color: rgba(151, 136, 199, 0.1); // #9788c7
} }
.table>tbody>tr.warn.active>td, .table > tbody > tr.warn.active > td,
.table>tbody>tr.warn.active>th, .table > tbody > tr.warn.active > th,
.table>tbody>tr.warn>td.active, .table > tbody > tr.warn > td.active,
.table>tbody>tr.warn>th.active, .table > tbody > tr.warn > th.active,
.table>tfoot>tr.warn.active>td, .table > tfoot > tr.warn.active > td,
.table>tfoot>tr.warn.active>th, .table > tfoot > tr.warn.active > th,
.table>tfoot>tr.warn>td.active, .table > tfoot > tr.warn > td.active,
.table>tfoot>tr.warn>th.active, .table > tfoot > tr.warn > th.active,
.table>thead>tr.warn.active>td, .table > thead > tr.warn.active > td,
.table>thead>tr.warn.active>th, .table > thead > tr.warn.active > th,
.table>thead>tr.warn>td.active, .table > thead > tr.warn > td.active,
.table>thead>tr.warn>th.active { .table > thead > tr.warn > th.active {
background-color: rgba(151, 136, 199, 0.2); background-color: rgba(151, 136, 199, 0.2);
} }
.table-hover>tbody>tr.warn.active:hover>td, .table-hover > tbody > tr.warn.active:hover > td,
.table-hover>tbody>tr.warn.active:hover>th, .table-hover > tbody > tr.warn.active:hover > th,
.table-hover>tbody>tr.warn:hover>.active, .table-hover > tbody > tr.warn:hover > .active,
.table-hover>tbody>tr.warn>td.active:hover, .table-hover > tbody > tr.warn > td.active:hover,
.table-hover>tbody>tr.warn>th.active:hover { .table-hover > tbody > tr.warn > th.active:hover {
background-color: rgba(151, 136, 199, 0.3); background-color: rgba(151, 136, 199, 0.3);
} }
tr.mat-mdc-header-row.accent, tr.mat-mdc-header-row.accent,
.table>thead>tr.accent { .table > thead > tr.accent {
background-color: rgba(205, 186, 152, 0.1); // #cdba98 background-color: rgba(205, 186, 152, 0.1); // #cdba98
} }
.table>tbody>tr.accent.active>td, .table > tbody > tr.accent.active > td,
.table>tbody>tr.accent.active>th, .table > tbody > tr.accent.active > th,
.table>tbody>tr.accent>td.active, .table > tbody > tr.accent > td.active,
.table>tbody>tr.accent>th.active, .table > tbody > tr.accent > th.active,
.table>tfoot>tr.accent.active>td, .table > tfoot > tr.accent.active > td,
.table>tfoot>tr.accent.active>th, .table > tfoot > tr.accent.active > th,
.table>tfoot>tr.accent>td.active, .table > tfoot > tr.accent > td.active,
.table>tfoot>tr.accent>th.active, .table > tfoot > tr.accent > th.active,
.table>thead>tr.accent.active>td, .table > thead > tr.accent.active > td,
.table>thead>tr.accent.active>th, .table > thead > tr.accent.active > th,
.table>thead>tr.accent>td.active, .table > thead > tr.accent > td.active,
.table>thead>tr.accent>th.active { .table > thead > tr.accent > th.active {
background-color: rgba(205, 186, 152, 0.2); background-color: rgba(205, 186, 152, 0.2);
} }
.table-hover>tbody>tr.accent.active:hover>td, .table-hover > tbody > tr.accent.active:hover > td,
.table-hover>tbody>tr.accent.active:hover>th, .table-hover > tbody > tr.accent.active:hover > th,
.table-hover>tbody>tr.accent:hover>.active, .table-hover > tbody > tr.accent:hover > .active,
.table-hover>tbody>tr.accent>td.active:hover, .table-hover > tbody > tr.accent > td.active:hover,
.table-hover>tbody>tr.accent>th.active:hover { .table-hover > tbody > tr.accent > th.active:hover {
background-color: rgba(205, 186, 152, 0.3); background-color: rgba(205, 186, 152, 0.3);
} }
.table-responsive { .table-responsive {
min-height:.01%; min-height: 0.01%;
overflow-x:auto overflow-x: auto;
} }
.table .mat-mdc-row { .table .mat-mdc-row {
height: auto; height: auto;
@@ -327,83 +328,83 @@ tr.mat-mdc-header-row.accent,
} }
body.dark-theme { body.dark-theme {
.table.table-dark>thead>tr>th, .table.table-dark > thead > tr > th,
.table.table-dark>tbody>tr>th, .table.table-dark > tbody > tr > th,
.table.table-dark>tfoot>tr>th { .table.table-dark > tfoot > tr > th {
background-color: rgba(0, 0, 0, 0.25); background-color: rgba(0, 0, 0, 0.25);
font-weight: normal; font-weight: normal;
} }
.table.table-dark>tbody>tr>td, .table.table-dark > tbody > tr > td,
.table.table-dark>tbody>tr>th, .table.table-dark > tbody > tr > th,
.table.table-dark>tfoot>tr>td, .table.table-dark > tfoot > tr > td,
.table.table-dark>tfoot>tr>th, .table.table-dark > tfoot > tr > th,
.table.table-dark>thead>tr>td, .table.table-dark > thead > tr > td,
.table.table-dark>thead>tr>th { .table.table-dark > thead > tr > th {
border-top:1px solid rgba(221, 221, 221, 0.3); border-top: 1px solid rgba(221, 221, 221, 0.3);
} }
.table.table-dark>thead>tr>th { .table.table-dark > thead > tr > th {
border-bottom:2px solid rgba(221, 221, 221, 0.3); border-bottom: 2px solid rgba(221, 221, 221, 0.3);
padding-top: 0.7rem; padding-top: 0.7rem;
} }
.table.table-dark>tfoot>tr>th { .table.table-dark > tfoot > tr > th {
border-top:2px solid rgba(221, 221, 221, 0.3); border-top: 2px solid rgba(221, 221, 221, 0.3);
} }
.table.table-dark>tbody+tbody { .table.table-dark > tbody + tbody {
border-top:2px solid rgb(221, 221, 221, 0.3); border-top: 2px solid rgb(221, 221, 221, 0.3);
} }
.table-striped.table-dark>tbody>tr:nth-of-type(odd) { .table-striped.table-dark > tbody > tr:nth-of-type(odd) {
background-color:rgba(255, 255, 255, 0.03); background-color: rgba(255, 255, 255, 0.03);
} }
.table-striped.table-dark>tbody>tr:nth-of-type(even) { .table-striped.table-dark > tbody > tr:nth-of-type(even) {
background-color:rgba(255, 255, 255, 0.01); background-color: rgba(255, 255, 255, 0.01);
} }
.table-hover.table-dark>tbody>tr:hover { .table-hover.table-dark > tbody > tr:hover {
background-color:rgba(0, 0, 0, 0.02); background-color: rgba(0, 0, 0, 0.02);
} }
} }
@media screen and (max-width:767px) { @media screen and (max-width: 767px) {
.table-responsive { .table-responsive {
width:100%; width: 100%;
margin-bottom:15px; margin-bottom: 15px;
overflow-y:hidden; overflow-y: hidden;
-ms-overflow-style:-ms-autohiding-scrollbar; -ms-overflow-style: -ms-autohiding-scrollbar;
border:1px solid #ddd border: 1px solid #ddd;
} }
.table-responsive>.table { .table-responsive > .table {
margin-bottom:0 margin-bottom: 0;
} }
.table-responsive>.table>tbody>tr>td, .table-responsive > .table > tbody > tr > td,
.table-responsive>.table>tbody>tr>th, .table-responsive > .table > tbody > tr > th,
.table-responsive>.table>tfoot>tr>td, .table-responsive > .table > tfoot > tr > td,
.table-responsive>.table>tfoot>tr>th, .table-responsive > .table > tfoot > tr > th,
.table-responsive>.table>thead>tr>td, .table-responsive > .table > thead > tr > td,
.table-responsive>.table>thead>tr>th { .table-responsive > .table > thead > tr > th {
white-space:nowrap white-space: nowrap;
} }
.table-responsive>.table-bordered { .table-responsive > .table-bordered {
border:0 border: 0;
} }
.table-responsive>.table-bordered>tbody>tr>td:first-child, .table-responsive > .table-bordered > tbody > tr > td:first-child,
.table-responsive>.table-bordered>tbody>tr>th:first-child, .table-responsive > .table-bordered > tbody > tr > th:first-child,
.table-responsive>.table-bordered>tfoot>tr>td:first-child, .table-responsive > .table-bordered > tfoot > tr > td:first-child,
.table-responsive>.table-bordered>tfoot>tr>th:first-child, .table-responsive > .table-bordered > tfoot > tr > th:first-child,
.table-responsive>.table-bordered>thead>tr>td:first-child, .table-responsive > .table-bordered > thead > tr > td:first-child,
.table-responsive>.table-bordered>thead>tr>th:first-child { .table-responsive > .table-bordered > thead > tr > th:first-child {
border-left:0 border-left: 0;
} }
.table-responsive>.table-bordered>tbody>tr>td:last-child, .table-responsive > .table-bordered > tbody > tr > td:last-child,
.table-responsive>.table-bordered>tbody>tr>th:last-child, .table-responsive > .table-bordered > tbody > tr > th:last-child,
.table-responsive>.table-bordered>tfoot>tr>td:last-child, .table-responsive > .table-bordered > tfoot > tr > td:last-child,
.table-responsive>.table-bordered>tfoot>tr>th:last-child, .table-responsive > .table-bordered > tfoot > tr > th:last-child,
.table-responsive>.table-bordered>thead>tr>td:last-child, .table-responsive > .table-bordered > thead > tr > td:last-child,
.table-responsive>.table-bordered>thead>tr>th:last-child { .table-responsive > .table-bordered > thead > tr > th:last-child {
border-right:0 border-right: 0;
} }
.table-responsive>.table-bordered>tbody>tr:last-child>td, .table-responsive > .table-bordered > tbody > tr:last-child > td,
.table-responsive>.table-bordered>tbody>tr:last-child>th, .table-responsive > .table-bordered > tbody > tr:last-child > th,
.table-responsive>.table-bordered>tfoot>tr:last-child>td, .table-responsive > .table-bordered > tfoot > tr:last-child > td,
.table-responsive>.table-bordered>tfoot>tr:last-child>th { .table-responsive > .table-bordered > tfoot > tr:last-child > th {
border-bottom:0 border-bottom: 0;
} }
} }
+55 -58
View File
@@ -1,62 +1,59 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */ /* To learn more about this file see: https://angular.io/config/tsconfig. */
{ {
"compileOnSave": false, "compileOnSave": false,
"compilerOptions": { "compilerOptions": {
"baseUrl": "./", "baseUrl": "./",
"rootDir": "./", "rootDir": "./",
"paths": { "paths": {
"@app/*": ["src/app/*"], "@app/*": ["src/app/*"],
"@components/*": ["src/app/components/*"], "@components/*": ["src/app/components/*"],
"@components": ["src/app/components"], "@components": ["src/app/components"],
"@core/*": ["src/app/core/*"], "@core/*": ["src/app/core/*"],
"@models": ["src/app/core/models"], "@models": ["src/app/core/models"],
"@models/*": ["src/app/core/models/*"], "@models/*": ["src/app/core/models/*"],
"@services": ["src/app/core/services"], "@services": ["src/app/core/services"],
"@services/*": ["src/app/core/services/*"], "@services/*": ["src/app/core/services/*"],
"@guards": ["src/app/core/guards"], "@guards": ["src/app/core/guards"],
"@guards/*": ["src/app/core/guards/*"], "@guards/*": ["src/app/core/guards/*"],
"@interceptors": ["src/app/core/interceptors"], "@interceptors": ["src/app/core/interceptors"],
"@interceptors/*": ["src/app/core/interceptors/*"], "@interceptors/*": ["src/app/core/interceptors/*"],
"@resolvers": ["src/app/core/resolvers"], "@resolvers": ["src/app/core/resolvers"],
"@resolvers/*": ["src/app/core/resolvers/*"], "@resolvers/*": ["src/app/core/resolvers/*"],
"@viewmodels": ["src/app/core/viewmodels"], "@viewmodels": ["src/app/core/viewmodels"],
"@viewmodels/*": ["src/app/core/viewmodels/*"], "@viewmodels/*": ["src/app/core/viewmodels/*"],
"@interfaces": ["src/app/core/interfaces"], "@interfaces": ["src/app/core/interfaces"],
"@interfaces/*": ["src/app/core/interfaces/*"], "@interfaces/*": ["src/app/core/interfaces/*"],
"@constants": ["src/app/core/constants"], "@constants": ["src/app/core/constants"],
"@constants/*": ["src/app/core/constants/*"], "@constants/*": ["src/app/core/constants/*"],
"@environments/*": ["src/environments/*"], "@environments/*": ["src/environments/*"],
"@data/*": ["src/files-data/*"], "@data/*": ["src/files-data/*"],
"@assets/*": ["src/assets/*"], "@assets/*": ["src/assets/*"],
"@styles/*": ["src/styles/*"] "@styles/*": ["src/styles/*"]
},
"outDir": "./dist/out-tsc",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"sourceMap": true,
"declaration": false,
"experimentalDecorators": true,
"moduleResolution": "bundler",
"importHelpers": true,
"target": "ES2022",
"module": "ES2022",
"useDefineForClassFields": false,
"lib": ["ES2022", "dom"],
"skipLibCheck": true,
"esModuleInterop": true,
"resolveJsonModule": true
}, },
"outDir": "./dist/out-tsc", "angularCompilerOptions": {
"forceConsistentCasingInFileNames": true, "enableI18nLegacyMessageIdFormat": false,
"strict": true, "strictInjectionParameters": true,
"noImplicitOverride": true, "strictInputAccessModifiers": true,
"noPropertyAccessFromIndexSignature": true, "strictTemplates": true
"noImplicitReturns": true, }
"noFallthroughCasesInSwitch": true,
"sourceMap": true,
"declaration": false,
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "ES2022",
"module": "ES2022",
"useDefineForClassFields": false,
"lib": [
"ES2022",
"dom"
],
"skipLibCheck": true,
"esModuleInterop": true,
"resolveJsonModule": true
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
}
} }