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:
@@ -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 { Title } from '@angular/platform-browser';
|
||||
|
||||
@@ -29,14 +29,12 @@ export const MY_FORMATS = {
|
||||
styleUrl: './app.component.scss',
|
||||
})
|
||||
export class AppComponent implements OnInit, AfterContentInit {
|
||||
private userService = inject(UserService);
|
||||
private titleService = inject(Title);
|
||||
|
||||
public title = 'Ad Astra';
|
||||
public appClass = 'grayscale';
|
||||
|
||||
constructor(
|
||||
private userService: UserService,
|
||||
private titleService: Title,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.userService.populate();
|
||||
this.titleService.setTitle(this.title);
|
||||
|
||||
@@ -47,6 +47,10 @@ import { AeronefByImat, AeronefByYear } from '@models';
|
||||
],
|
||||
})
|
||||
export class AeronefsComponent implements OnInit, OnDestroy {
|
||||
private route = inject(ActivatedRoute);
|
||||
private _utilitiesService = inject(UtilitiesService);
|
||||
menuItems = inject(MenuItems);
|
||||
|
||||
private _data: Subscription = new Subscription();
|
||||
private _aeronefsByImat!: Array<AeronefByImat>;
|
||||
private _aeronefsByYear!: Array<AeronefByYear>;
|
||||
@@ -68,12 +72,6 @@ export class AeronefsComponent implements OnInit, OnDestroy {
|
||||
};
|
||||
public seriesColorClass: string[] = this._utilitiesService.getChartColors();
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private _utilitiesService: UtilitiesService,
|
||||
public menuItems: MenuItems,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
const data$: Observable<{ aeronefsPageData: AeronefsPageData }> = this.route.data as Observable<{
|
||||
aeronefsPageData: AeronefsPageData;
|
||||
|
||||
@@ -39,6 +39,12 @@ import { ListErrorsComponent, ShowAuthedDirective } from '@components/shared';
|
||||
styleUrl: './auth.component.scss',
|
||||
})
|
||||
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 _user: Subscription = new Subscription();
|
||||
authType = '';
|
||||
@@ -49,13 +55,7 @@ export class AuthComponent implements OnInit, OnDestroy {
|
||||
authForm!: UntypedFormGroup;
|
||||
destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private titleService: Title,
|
||||
private userService: UserService,
|
||||
private fb: UntypedFormBuilder,
|
||||
) {
|
||||
constructor() {
|
||||
this._resetErrors();
|
||||
// use FormBuilder to create a form group
|
||||
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 { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
@@ -63,6 +63,12 @@ import { CalculatorService, JumpsService, UserService, UtilitiesService } from '
|
||||
],
|
||||
})
|
||||
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 _currentUser!: Subscription; // = new Subscription();
|
||||
private _subscriptions: Array<Subscription> = [];
|
||||
@@ -100,14 +106,6 @@ export class CalculatorComponent implements OnInit, OnDestroy {
|
||||
@ViewChild(MatSort) sort!: MatSort;
|
||||
@ViewChild(MatPaginator) paginator!: MatPaginator;
|
||||
|
||||
constructor(
|
||||
private _calculatorService: CalculatorService,
|
||||
private _jumpsService: JumpsService,
|
||||
private _userService: UserService,
|
||||
private _utilitiesService: UtilitiesService,
|
||||
public menuItems: MenuItems,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
const currentUser$: Observable<User> = this._userService.currentUser;
|
||||
const lastjump$: Observable<Jump> = this._jumpsService.getLastJump();
|
||||
|
||||
@@ -45,6 +45,10 @@ import { CanopyBySize, CanopyByYear, CanopyModelBySize, CanopyModelByYear } from
|
||||
],
|
||||
})
|
||||
export class CanopiesComponent implements OnInit, OnDestroy {
|
||||
private route = inject(ActivatedRoute);
|
||||
private _utilitiesService = inject(UtilitiesService);
|
||||
menuItems = inject(MenuItems);
|
||||
|
||||
private _data: Subscription = new Subscription();
|
||||
private _canopiesModelBySize!: Array<CanopyModelBySize>;
|
||||
private _canopiesModelByYear!: Array<CanopyModelByYear>;
|
||||
@@ -72,12 +76,6 @@ export class CanopiesComponent implements OnInit, OnDestroy {
|
||||
};
|
||||
public seriesColorClass: string[] = this._utilitiesService.getChartColors();
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private _utilitiesService: UtilitiesService,
|
||||
public menuItems: MenuItems,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
const data$: Observable<{ canopiesPageData: CanopiesPageData }> = this.route.data as Observable<{
|
||||
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 { Title } from '@angular/platform-browser';
|
||||
import { MatDividerModule } from '@angular/material/divider';
|
||||
@@ -49,6 +49,12 @@ import {
|
||||
styleUrl: './dashboard.component.scss',
|
||||
})
|
||||
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 _data: Subscription = new Subscription();
|
||||
private _lastjump: Subscription = new Subscription();
|
||||
@@ -73,18 +79,7 @@ export class DashboardComponent implements OnInit, OnDestroy {
|
||||
public dropzonesCount = 0;
|
||||
public lastJump: Jump = {} as Jump;
|
||||
|
||||
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
|
||||
*/
|
||||
) {
|
||||
constructor() {
|
||||
this._resetErrors();
|
||||
}
|
||||
|
||||
|
||||
@@ -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 { Title } from '@angular/platform-browser';
|
||||
import { RouterLink } from '@angular/router';
|
||||
@@ -34,6 +34,9 @@ import { ListErrorsComponent } from '@components/shared';
|
||||
styleUrl: './demo.component.scss',
|
||||
})
|
||||
export class DemoComponent implements OnInit, OnDestroy {
|
||||
private titleService = inject(Title);
|
||||
private userService = inject(UserService);
|
||||
|
||||
private _user: Subscription = new Subscription();
|
||||
private _colors: string[] = [
|
||||
'primary',
|
||||
@@ -104,11 +107,6 @@ export class DemoComponent implements OnInit, OnDestroy {
|
||||
errors: Errors = { errors: {} };
|
||||
btnSettingsTitle = 'Paramètres';
|
||||
|
||||
constructor(
|
||||
private titleService: Title,
|
||||
private userService: UserService,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.titleService.setTitle(`Ad Astra - ${this.title}`);
|
||||
Object.assign(this.user, this.userService.getCurrentUser());
|
||||
|
||||
@@ -50,6 +50,10 @@ import { UtilitiesService } from '@services';
|
||||
],
|
||||
})
|
||||
export class DropzonesComponent implements OnInit, OnDestroy {
|
||||
private route = inject(ActivatedRoute);
|
||||
private _utilitiesService = inject(UtilitiesService);
|
||||
menuItems = inject(MenuItems);
|
||||
|
||||
private _data: Subscription = new Subscription();
|
||||
private _lastjump: Subscription = new Subscription();
|
||||
private _dropzonesByOaci!: Array<DropZoneByOaci>;
|
||||
@@ -86,22 +90,6 @@ export class DropzonesComponent implements OnInit, OnDestroy {
|
||||
maxZoom: 20,
|
||||
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() {
|
||||
const data$: Observable<{ dropZonesPageData: DropZonesPageData }> = this.route.data as Observable<{
|
||||
|
||||
@@ -52,6 +52,8 @@ export class GuildRaidStepperIntl extends MatStepperIntl {
|
||||
],
|
||||
})
|
||||
export class HerowarsGuildraidComponent implements OnInit {
|
||||
private _titleService = inject(Title);
|
||||
|
||||
public title = 'Guild Raids';
|
||||
public subtitle = 'Log';
|
||||
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 },
|
||||
];
|
||||
|
||||
constructor(private _titleService: Title) {}
|
||||
|
||||
ngOnInit() {
|
||||
this._titleService.setTitle(this.title);
|
||||
this._guildMembers.map((data) => {
|
||||
|
||||
@@ -54,6 +54,11 @@ import guildStatistics from '@data/hw-guild-statistics.json'; // page Overview -
|
||||
],
|
||||
})
|
||||
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 title = 'Guild War';
|
||||
public subtitle = 'Log';
|
||||
@@ -71,13 +76,6 @@ export class HerowarsGuildwarComponent implements OnInit {
|
||||
private _guildMembers: HWMember[] = [];
|
||||
private _guildInfo: HWActivityStat = {} as HWActivityStat;
|
||||
|
||||
constructor(
|
||||
private _titleService: Title,
|
||||
private _utilitiesService: UtilitiesService,
|
||||
private _clanService: HWClanService,
|
||||
private _memberService: HWMemberService,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
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 {
|
||||
private _titleService = inject(Title);
|
||||
|
||||
public title = 'HeroWars GM Tools';
|
||||
public description = 'Tools in working progress.';
|
||||
public errors: Errors = { errors: {} };
|
||||
@@ -59,8 +61,6 @@ export class HerowarsComponent implements OnInit {
|
||||
public now = new Date();
|
||||
private _guildMembers: HWMember[] = [];
|
||||
|
||||
constructor(private _titleService: Title) {}
|
||||
|
||||
ngOnInit() {
|
||||
try {
|
||||
this._titleService.setTitle(this.title);
|
||||
|
||||
@@ -24,18 +24,14 @@ import { Errors } from '@models';
|
||||
],
|
||||
})
|
||||
export class HomeComponent implements OnInit {
|
||||
private _titleService = inject(Title);
|
||||
|
||||
public title = 'Shop bientôt disponible!';
|
||||
public description = "Encore un peu de patience, notre shop sera mis en ligne d'ici peu.";
|
||||
public errors: Errors = { errors: {} };
|
||||
public destroyRef = inject(DestroyRef);
|
||||
public now = new Date();
|
||||
|
||||
constructor(
|
||||
private _titleService: Title,
|
||||
//private _utilitiesService: UtilitiesService
|
||||
//private _userService: UserService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this._titleService.setTitle(this.title);
|
||||
/*
|
||||
|
||||
@@ -29,6 +29,9 @@ import { Errors, Jump, JumpPageData } from '@models';
|
||||
styleUrl: './jump.component.scss',
|
||||
})
|
||||
export class JumpComponent implements OnInit, OnDestroy {
|
||||
private route = inject(ActivatedRoute);
|
||||
menuItems = inject(MenuItems);
|
||||
|
||||
private _data: Subscription = new Subscription();
|
||||
public title: string = '';
|
||||
public errors: Errors = { errors: {} };
|
||||
@@ -37,11 +40,6 @@ export class JumpComponent implements OnInit, OnDestroy {
|
||||
public prevSlug: string = '';
|
||||
public nextSlug: string = '';
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
public menuItems: MenuItems,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
const data$: Observable<{ pageData: JumpPageData }> = this.route.data as Observable<{ pageData: JumpPageData }>;
|
||||
this._data = data$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: { pageData: JumpPageData }) => {
|
||||
|
||||
@@ -48,6 +48,10 @@ import { Jump, JumpByCategorie, JumpByDate, JumpByDateByModule, JumpByModule, Ju
|
||||
],
|
||||
})
|
||||
export class JumpsComponent implements OnInit, OnDestroy {
|
||||
private route = inject(ActivatedRoute);
|
||||
private _utilitiesService = inject(UtilitiesService);
|
||||
menuItems = inject(MenuItems);
|
||||
|
||||
private _data: Subscription = new Subscription();
|
||||
private _jumpsByCategorie: Array<JumpByCategorie> = [];
|
||||
private _jumpsByModule: Array<JumpByModule> = [];
|
||||
@@ -91,12 +95,6 @@ export class JumpsComponent implements OnInit, OnDestroy {
|
||||
public seriesColTotalClosed: number[] = [];
|
||||
public seriesColTotalLastYears: number[] = [];
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private _utilitiesService: UtilitiesService,
|
||||
public menuItems: MenuItems,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
const data$: Observable<{ pageData: JumpsPageData }> = this.route.data as Observable<{
|
||||
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 { FormBuilder, FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||
@@ -48,6 +48,17 @@ import { AeronefsService, CanopiesService, DropZonesService, JumpsService } from
|
||||
],
|
||||
})
|
||||
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 _subscriptions: Array<Subscription> = [];
|
||||
private _aeronefByImat: Subscription = new Subscription();
|
||||
@@ -101,15 +112,9 @@ export class JumpAddDialogComponent implements OnDestroy {
|
||||
modules: Observable<Array<JumpByModule>>;
|
||||
};
|
||||
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<JumpAddDialogComponent>,
|
||||
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 },
|
||||
) {
|
||||
constructor() {
|
||||
const data = this.data;
|
||||
|
||||
this.inputOptions = { aeronefs: [], canopies: [], dropzones: [], categories: [] };
|
||||
//this.filteredOptions.aeronefs = this._aeronefsService.getAllByImat();
|
||||
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 { MatButtonModule } from '@angular/material/button';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
|
||||
@@ -12,10 +12,8 @@ import { Jump } from '@models';
|
||||
imports: [DatePipe, MatDialogModule, MatButtonModule, MatIconModule],
|
||||
})
|
||||
export class JumpDeleteDialogComponent {
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<JumpDeleteDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public jump: Jump,
|
||||
) {}
|
||||
dialogRef = inject<MatDialogRef<JumpDeleteDialogComponent>>(MatDialogRef);
|
||||
jump = inject<Jump>(MAT_DIALOG_DATA);
|
||||
|
||||
closeDialog(): void {
|
||||
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 { FormBuilder, FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||
@@ -38,6 +38,14 @@ import { AeronefsService, CanopiesService, DropZonesService, JumpsService } from
|
||||
],
|
||||
})
|
||||
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 _canopyModelBySize: Subscription = new Subscription();
|
||||
private _dropZoneByOaci: Subscription = new Subscription();
|
||||
@@ -61,15 +69,7 @@ export class JumpEditDialogComponent implements OnDestroy {
|
||||
modules: Observable<Array<JumpByModule>>;
|
||||
};
|
||||
|
||||
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,
|
||||
) {
|
||||
constructor() {
|
||||
this.inputOptions = { aeronefs: [], canopies: [], dropzones: [], categories: [] };
|
||||
const controlsConfig = {
|
||||
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 { MatButtonModule } from '@angular/material/button';
|
||||
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],
|
||||
})
|
||||
export class JumpViewDialogComponent {
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<JumpViewDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public jump: Jump,
|
||||
) {}
|
||||
dialogRef = inject<MatDialogRef<JumpViewDialogComponent>>(MatDialogRef);
|
||||
jump = inject<Jump>(MAT_DIALOG_DATA);
|
||||
|
||||
closeDialog(): void {
|
||||
// close the dialog without result
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
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 { ActivatedRoute, Router, RouterModule } from '@angular/router';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
@@ -58,6 +58,15 @@ import data from 'src/jumps.json';
|
||||
],
|
||||
})
|
||||
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 _subscriptions: Array<Subscription> = [];
|
||||
private _data: Subscription = new Subscription();
|
||||
@@ -92,17 +101,6 @@ export class LogbookComponent implements OnInit, OnDestroy, AfterContentChecked
|
||||
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() {
|
||||
//this.importJumps();
|
||||
const data$: Observable<{ isAuthenticated: boolean; lastjump: Jump }> = this.route.data as Observable<{
|
||||
|
||||
@@ -26,6 +26,9 @@ import { Errors, Article, ArticlePageData } from '@models';
|
||||
],
|
||||
})
|
||||
export class PageComponent implements OnInit, OnDestroy {
|
||||
private route = inject(ActivatedRoute);
|
||||
private titleService = inject(Title);
|
||||
|
||||
private _data: Subscription = new Subscription();
|
||||
public title = 'Shop bientôt disponible!';
|
||||
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 article: Article = {} as Article;
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private titleService: Title,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
const data$: Observable<{ pageData: ArticlePageData }> = this.route.data as Observable<{
|
||||
pageData: ArticlePageData;
|
||||
|
||||
@@ -26,6 +26,9 @@ import { Errors, Product, ProductPageData } from '@models';
|
||||
],
|
||||
})
|
||||
export class ProductComponent implements OnInit, OnDestroy {
|
||||
private route = inject(ActivatedRoute);
|
||||
private titleService = inject(Title);
|
||||
|
||||
private _data: Subscription = new Subscription();
|
||||
public title = 'Ad Astra - Produit';
|
||||
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 product: Product = {} as Product;
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private titleService: Title,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
const data$: Observable<{ pageData: ProductPageData }> = this.route.data as Observable<{
|
||||
pageData: ProductPageData;
|
||||
|
||||
@@ -36,6 +36,9 @@ import { Errors, Product, ProductsPageData } from '@models';
|
||||
],
|
||||
})
|
||||
export class ProductsComponent implements OnInit, OnDestroy {
|
||||
private route = inject(ActivatedRoute);
|
||||
private titleService = inject(Title);
|
||||
|
||||
private _data: Subscription = new Subscription();
|
||||
public title = 'Ad Astra - Produit';
|
||||
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 productsCount = 0;
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private titleService: Title,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
const data$: Observable<{ pageData: ProductsPageData }> = this.route.data as Observable<{
|
||||
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 { RouterLink } from '@angular/router';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
@@ -19,6 +19,9 @@ import { ListErrorsComponent } from '@components/shared';
|
||||
styleUrl: './profile.component.scss',
|
||||
})
|
||||
export class ProfileComponent implements OnInit, OnDestroy {
|
||||
private titleService = inject(Title);
|
||||
private userService = inject(UserService);
|
||||
|
||||
private _user: Subscription = new Subscription();
|
||||
title = 'Mon compte';
|
||||
bannerTitle = '';
|
||||
@@ -26,11 +29,6 @@ export class ProfileComponent implements OnInit, OnDestroy {
|
||||
errors: Errors = { errors: {} };
|
||||
btnSettingsTitle = 'Paramètres';
|
||||
|
||||
constructor(
|
||||
private titleService: Title,
|
||||
private userService: UserService,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.titleService.setTitle(`Ad Astra - ${this.title}`);
|
||||
Object.assign(this.user, this.userService.getCurrentUser());
|
||||
|
||||
@@ -40,6 +40,12 @@ import data from 'src/qcm-bpa.json';
|
||||
styleUrl: './qcm.component.scss',
|
||||
})
|
||||
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 _data: Subscription = new Subscription();
|
||||
private _timer: Subscription = new Subscription();
|
||||
@@ -61,13 +67,7 @@ export class QcmComponent implements OnInit, OnDestroy {
|
||||
public timeProgressColor = 'primary';
|
||||
public timeMax = 60 * 45;
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private fb: FormBuilder,
|
||||
private _qcmService: QcmService,
|
||||
private _userService: UserService,
|
||||
public menuItems: MenuItems,
|
||||
) {
|
||||
constructor() {
|
||||
this.qcmForm = this.fb.group({
|
||||
questions: this.fb.array([]),
|
||||
});
|
||||
|
||||
@@ -41,6 +41,11 @@ import { ListErrorsComponent } from '@components/shared';
|
||||
styleUrl: './credentials.component.scss',
|
||||
})
|
||||
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();
|
||||
title = 'Modifier le mot de passe';
|
||||
bannerTitle = '';
|
||||
@@ -52,12 +57,7 @@ export class CredentialsComponent implements OnInit, OnDestroy {
|
||||
isSubmitting = false;
|
||||
destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
private titleService: Title,
|
||||
private userService: UserService,
|
||||
private fb: UntypedFormBuilder,
|
||||
) {
|
||||
constructor() {
|
||||
this.credentialsForm = this.fb.group(
|
||||
{
|
||||
password: ['', Validators.required],
|
||||
|
||||
@@ -34,6 +34,11 @@ import { ListErrorsComponent } from '@components/shared';
|
||||
templateUrl: './settings.component.html',
|
||||
})
|
||||
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();
|
||||
title = 'Vos paramètres';
|
||||
bannerTitle = '';
|
||||
@@ -66,12 +71,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
|
||||
`${this.imgPath}animal_016${this.imgExt}`,
|
||||
];
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
private titleService: Title,
|
||||
private userService: UserService,
|
||||
private fb: UntypedFormBuilder,
|
||||
) {
|
||||
constructor() {
|
||||
// create form group using the form builder
|
||||
this.settingsForm = this.fb.group({
|
||||
username: ['', Validators.required],
|
||||
|
||||
@@ -1,55 +1,57 @@
|
||||
import { Directive, AfterContentChecked } from '@angular/core';
|
||||
import { Router, NavigationEnd } from '@angular/router';
|
||||
|
||||
import { AccordionLinkDirective } from './accordionlink.directive';
|
||||
import { filter } from 'rxjs/operators';
|
||||
|
||||
@Directive({
|
||||
selector: '[appAccordion]',
|
||||
standalone: true
|
||||
})
|
||||
export class AccordionDirective implements AfterContentChecked {
|
||||
protected navlinks: Array<AccordionLinkDirective> = [];
|
||||
|
||||
closeOtherLinks(selectedLink: AccordionLinkDirective): void {
|
||||
this.navlinks.forEach((link: AccordionLinkDirective) => {
|
||||
if (link !== selectedLink) {
|
||||
link.selected = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
addLink(link: AccordionLinkDirective): void {
|
||||
this.navlinks.push(link);
|
||||
}
|
||||
|
||||
removeGroup(link: AccordionLinkDirective): void {
|
||||
const index = this.navlinks.indexOf(link);
|
||||
if (index !== -1) {
|
||||
this.navlinks.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
checkOpenLinks() {
|
||||
this.navlinks.forEach((link: AccordionLinkDirective) => {
|
||||
if (link.group) {
|
||||
const routeUrl = this.router.url;
|
||||
const currentUrl = routeUrl.split('/');
|
||||
if (currentUrl.indexOf(link.group) > 0) {
|
||||
link.selected = true;
|
||||
this.closeOtherLinks(link);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngAfterContentChecked(): void {
|
||||
this.router.events
|
||||
.pipe(filter(event => event instanceof NavigationEnd))
|
||||
.subscribe(() => this.checkOpenLinks());
|
||||
}
|
||||
|
||||
constructor(private router: Router) {
|
||||
setTimeout(() => this.checkOpenLinks());
|
||||
}
|
||||
}
|
||||
import { Directive, AfterContentChecked, inject } from '@angular/core';
|
||||
import { Router, NavigationEnd } from '@angular/router';
|
||||
|
||||
import { AccordionLinkDirective } from './accordionlink.directive';
|
||||
import { filter } from 'rxjs/operators';
|
||||
|
||||
@Directive({
|
||||
selector: '[appAccordion]',
|
||||
standalone: true,
|
||||
})
|
||||
export class AccordionDirective implements AfterContentChecked {
|
||||
private router = inject(Router);
|
||||
|
||||
protected navlinks: Array<AccordionLinkDirective> = [];
|
||||
|
||||
closeOtherLinks(selectedLink: AccordionLinkDirective): void {
|
||||
this.navlinks.forEach((link: AccordionLinkDirective) => {
|
||||
if (link !== selectedLink) {
|
||||
link.selected = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
addLink(link: AccordionLinkDirective): void {
|
||||
this.navlinks.push(link);
|
||||
}
|
||||
|
||||
removeGroup(link: AccordionLinkDirective): void {
|
||||
const index = this.navlinks.indexOf(link);
|
||||
if (index !== -1) {
|
||||
this.navlinks.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
checkOpenLinks() {
|
||||
this.navlinks.forEach((link: AccordionLinkDirective) => {
|
||||
if (link.group) {
|
||||
const routeUrl = this.router.url;
|
||||
const currentUrl = routeUrl.split('/');
|
||||
if (currentUrl.indexOf(link.group) > 0) {
|
||||
link.selected = true;
|
||||
this.closeOtherLinks(link);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngAfterContentChecked(): void {
|
||||
this.router.events
|
||||
.pipe(filter((event) => event instanceof NavigationEnd))
|
||||
.subscribe(() => this.checkOpenLinks());
|
||||
}
|
||||
|
||||
constructor() {
|
||||
setTimeout(() => this.checkOpenLinks());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
import { Directive, HostListener, Inject } from '@angular/core';
|
||||
|
||||
import { AccordionLinkDirective } from './accordionlink.directive';
|
||||
|
||||
@Directive({
|
||||
selector: '[appAccordionToggle]',
|
||||
standalone: true
|
||||
})
|
||||
export class AccordionAnchorDirective {
|
||||
protected navlink: AccordionLinkDirective;
|
||||
|
||||
constructor(@Inject(AccordionLinkDirective) navlink: AccordionLinkDirective) {
|
||||
this.navlink = navlink;
|
||||
}
|
||||
|
||||
@HostListener('click', ['$event'])
|
||||
onClick() {
|
||||
this.navlink.toggle();
|
||||
}
|
||||
}
|
||||
import { Directive, HostListener, inject } from '@angular/core';
|
||||
|
||||
import { AccordionLinkDirective } from './accordionlink.directive';
|
||||
|
||||
@Directive({
|
||||
selector: '[appAccordionToggle]',
|
||||
standalone: true,
|
||||
})
|
||||
export class AccordionAnchorDirective {
|
||||
protected navlink: AccordionLinkDirective;
|
||||
|
||||
constructor() {
|
||||
const navlink = inject<AccordionLinkDirective>(AccordionLinkDirective);
|
||||
|
||||
this.navlink = navlink;
|
||||
}
|
||||
|
||||
@HostListener('click', ['$event'])
|
||||
onClick() {
|
||||
this.navlink.toggle();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,51 +1,46 @@
|
||||
import {
|
||||
Directive,
|
||||
HostBinding,
|
||||
Inject,
|
||||
Input,
|
||||
OnInit,
|
||||
OnDestroy
|
||||
} from '@angular/core';
|
||||
|
||||
import { AccordionDirective } from './accordion.directive';
|
||||
|
||||
@Directive({
|
||||
selector: '[appAccordionLink]',
|
||||
standalone: true
|
||||
})
|
||||
export class AccordionLinkDirective implements OnInit, OnDestroy {
|
||||
@Input()
|
||||
public group!: string;
|
||||
|
||||
@HostBinding('class.selected')
|
||||
@Input()
|
||||
get selected(): boolean {
|
||||
return this._selected;
|
||||
}
|
||||
|
||||
set selected(value: boolean) {
|
||||
this._selected = value;
|
||||
if (value) {
|
||||
this.nav.closeOtherLinks(this);
|
||||
}
|
||||
}
|
||||
|
||||
protected _selected: boolean = false;
|
||||
protected nav: AccordionDirective;
|
||||
|
||||
constructor(@Inject(AccordionDirective) nav: AccordionDirective) {
|
||||
this.nav = nav;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.nav.addLink(this);
|
||||
}
|
||||
|
||||
ngOnDestroy(){
|
||||
this.nav.removeGroup(this);
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.selected = !this.selected;
|
||||
}
|
||||
}
|
||||
import { Directive, HostBinding, Input, OnInit, OnDestroy, inject } from '@angular/core';
|
||||
|
||||
import { AccordionDirective } from './accordion.directive';
|
||||
|
||||
@Directive({
|
||||
selector: '[appAccordionLink]',
|
||||
standalone: true,
|
||||
})
|
||||
export class AccordionLinkDirective implements OnInit, OnDestroy {
|
||||
@Input()
|
||||
public group!: string;
|
||||
|
||||
@HostBinding('class.selected')
|
||||
@Input()
|
||||
get selected(): boolean {
|
||||
return this._selected;
|
||||
}
|
||||
|
||||
set selected(value: boolean) {
|
||||
this._selected = value;
|
||||
if (value) {
|
||||
this.nav.closeOtherLinks(this);
|
||||
}
|
||||
}
|
||||
|
||||
protected _selected: boolean = false;
|
||||
protected nav: AccordionDirective;
|
||||
|
||||
constructor() {
|
||||
const nav = inject<AccordionDirective>(AccordionDirective);
|
||||
|
||||
this.nav = nav;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.nav.addLink(this);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.nav.removeGroup(this);
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.selected = !this.selected;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-6
@@ -29,6 +29,10 @@ import { AeronefByImat, AeronefByYear } from '@models';
|
||||
templateUrl: './aeronefs-bar.component.html',
|
||||
})
|
||||
export class AeronefsBarComponent implements OnInit, OnDestroy {
|
||||
private _aeronefsService = inject(AeronefsService);
|
||||
private _utilitiesService = inject(UtilitiesService);
|
||||
menuItems = inject(MenuItems);
|
||||
|
||||
private _aeronefByImat: Subscription = new Subscription();
|
||||
private _aeronefByYear: Subscription = new Subscription();
|
||||
private _aeronefsByImat!: Array<AeronefByImat>;
|
||||
@@ -50,12 +54,6 @@ export class AeronefsBarComponent implements OnInit, OnDestroy {
|
||||
public displayCharts = false;
|
||||
public destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(
|
||||
private _aeronefsService: AeronefsService,
|
||||
private _utilitiesService: UtilitiesService,
|
||||
public menuItems: MenuItems,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this._loadAeronefByImat();
|
||||
}
|
||||
|
||||
+4
-6
@@ -31,6 +31,10 @@ import { AeronefByImat, AeronefByYear } from '@models';
|
||||
templateUrl: './aeronefs-pie.component.html',
|
||||
})
|
||||
export class AeronefsPieComponent implements OnInit, OnDestroy {
|
||||
private _aeronefsService = inject(AeronefsService);
|
||||
private _utilitiesService = inject(UtilitiesService);
|
||||
menuItems = inject(MenuItems);
|
||||
|
||||
private _aeronefByImat: Subscription = new Subscription();
|
||||
private _aeronefByYear: Subscription = new Subscription();
|
||||
private _aeronefsByImat!: Array<AeronefByImat>;
|
||||
@@ -51,12 +55,6 @@ export class AeronefsPieComponent implements OnInit, OnDestroy {
|
||||
public seriesColorClass: string[] = this._utilitiesService.getChartColors();
|
||||
public destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(
|
||||
private _aeronefsService: AeronefsService,
|
||||
private _utilitiesService: UtilitiesService,
|
||||
public menuItems: MenuItems,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this._loadAeronefByImat();
|
||||
}
|
||||
|
||||
+4
-6
@@ -29,6 +29,10 @@ import { CanopyModelBySize, CanopyModelByYear } from '@models';
|
||||
templateUrl: './canopies-models.component.html',
|
||||
})
|
||||
export class CanopiesModelsComponent implements OnInit, OnDestroy {
|
||||
private _canopiesService = inject(CanopiesService);
|
||||
private _utilitiesService = inject(UtilitiesService);
|
||||
menuItems = inject(MenuItems);
|
||||
|
||||
private _canopyBySize: Subscription = new Subscription();
|
||||
private _canopyByYear: Subscription = new Subscription();
|
||||
private _canopiesBySize!: Array<CanopyModelBySize>;
|
||||
@@ -49,12 +53,6 @@ export class CanopiesModelsComponent implements OnInit, OnDestroy {
|
||||
public seriesColorClass: string[] = this._utilitiesService.getChartColors();
|
||||
public destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(
|
||||
private _canopiesService: CanopiesService,
|
||||
private _utilitiesService: UtilitiesService,
|
||||
public menuItems: MenuItems,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this._loadCanopyModelBySize();
|
||||
}
|
||||
|
||||
+4
-6
@@ -30,6 +30,10 @@ import { CanopyBySize, CanopyByYear } from '@models';
|
||||
templateUrl: './canopies-sizes.component.html',
|
||||
})
|
||||
export class CanopiesSizesComponent implements OnInit, OnDestroy {
|
||||
private _canopiesService = inject(CanopiesService);
|
||||
private _utilitiesService = inject(UtilitiesService);
|
||||
menuItems = inject(MenuItems);
|
||||
|
||||
private _canopyBySize: Subscription = new Subscription();
|
||||
private _canopyByYear: Subscription = new Subscription();
|
||||
private _canopiesBySize!: Array<CanopyBySize>;
|
||||
@@ -50,12 +54,6 @@ export class CanopiesSizesComponent implements OnInit, OnDestroy {
|
||||
public seriesColorClass: string[] = this._utilitiesService.getChartColors();
|
||||
public destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(
|
||||
private _canopiesService: CanopiesService,
|
||||
private _utilitiesService: UtilitiesService,
|
||||
public menuItems: MenuItems,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this._loadCanopyBySize();
|
||||
}
|
||||
|
||||
+17
-8
@@ -8,19 +8,22 @@
|
||||
</button>
|
||||
<mat-menu #menuDropzoneBar="matMenu">
|
||||
@for (menuitem of menuItems.getMenuPanel(); track menuitem) {
|
||||
<button mat-menu-item>
|
||||
<mat-icon [fontIcon]="menuitem.icon"></mat-icon>
|
||||
<span>{{ menuitem.name }}</span>
|
||||
</button>
|
||||
<button mat-menu-item>
|
||||
<mat-icon [fontIcon]="menuitem.icon"></mat-icon>
|
||||
<span>{{ menuitem.name }}</span>
|
||||
</button>
|
||||
}
|
||||
</mat-menu>
|
||||
</mat-card-header>
|
||||
<mat-divider class="my-3"></mat-divider>
|
||||
<mat-card-content>
|
||||
@if (displayCharts) {
|
||||
<div class="barchart position-relative w-100 my-1">
|
||||
<x-chartist [configuration]="barChartDropZones"></x-chartist>
|
||||
</div>
|
||||
<app-bars-chart
|
||||
[names]="seriesName"
|
||||
[values]="seriesRow"
|
||||
[headers]="seriesHeader"
|
||||
[colors]="seriesColor"
|
||||
></app-bars-chart>
|
||||
}
|
||||
</mat-card-content>
|
||||
<mat-divider class="mt-3 mb-0"></mat-divider>
|
||||
@@ -29,7 +32,13 @@
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>Historique annuel</mat-panel-title>
|
||||
</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-accordion>
|
||||
</mat-card>
|
||||
|
||||
+6
-66
@@ -6,12 +6,10 @@ import { MatDividerModule } from '@angular/material/divider';
|
||||
import { MatExpansionModule } from '@angular/material/expansion';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
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 { MenuItems } from '@components/shared';
|
||||
import { BarsChartComponent } from '@components/shared/helpers-chart';
|
||||
import { HistoryTableComponent } from '@components/shared/helpers-jump';
|
||||
import { UtilitiesService, DropZonesService } from '@services';
|
||||
import { DropZoneByOaci, DropZoneByYear } from '@models';
|
||||
@@ -25,13 +23,16 @@ import { DropZoneByOaci, DropZoneByYear } from '@models';
|
||||
MatExpansionModule,
|
||||
MatIconModule,
|
||||
MatMenuModule,
|
||||
BaseChartDirective,
|
||||
ChartistModule,
|
||||
BarsChartComponent,
|
||||
HistoryTableComponent,
|
||||
],
|
||||
templateUrl: './dropzones-bar.component.html',
|
||||
})
|
||||
export class DropzonesBarComponent implements OnInit, OnDestroy {
|
||||
private _dropzonesService = inject(DropZonesService);
|
||||
private _utilitiesService = inject(UtilitiesService);
|
||||
menuItems = inject(MenuItems);
|
||||
|
||||
private _dropzoneByOaci: Subscription = new Subscription();
|
||||
private _dropzoneByYear: Subscription = new Subscription();
|
||||
private _dropzonesByOaci!: Array<DropZoneByOaci>;
|
||||
@@ -51,15 +52,8 @@ export class DropzonesBarComponent implements OnInit, OnDestroy {
|
||||
};
|
||||
public seriesColorClass: string[] = this._utilitiesService.getChartColors();
|
||||
public displayCharts = false;
|
||||
public barChartDropZones: Configuration = this._utilitiesService.getBarConfig();
|
||||
public destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(
|
||||
private _dropzonesService: DropZonesService,
|
||||
private _utilitiesService: UtilitiesService,
|
||||
public menuItems: MenuItems,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this._loadDropZoneByOaci();
|
||||
}
|
||||
@@ -101,60 +95,6 @@ export class DropzonesBarComponent implements OnInit, OnDestroy {
|
||||
row.count;
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
||||
+4
-6
@@ -30,6 +30,10 @@ import { DropZoneByOaci, DropZoneByYear } from '@models';
|
||||
templateUrl: './dropzones-pie.component.html',
|
||||
})
|
||||
export class DropzonesPieComponent implements OnInit, OnDestroy {
|
||||
private _dropzonesService = inject(DropZonesService);
|
||||
private _utilitiesService = inject(UtilitiesService);
|
||||
menuItems = inject(MenuItems);
|
||||
|
||||
private _dropzoneByOaci: Subscription = new Subscription();
|
||||
private _dropzoneByYear: Subscription = new Subscription();
|
||||
private _dropzonesByOaci!: Array<DropZoneByOaci>;
|
||||
@@ -50,12 +54,6 @@ export class DropzonesPieComponent implements OnInit, OnDestroy {
|
||||
public seriesColorClass: string[] = this._utilitiesService.getChartColors();
|
||||
public destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(
|
||||
private _dropzonesService: DropZonesService,
|
||||
private _utilitiesService: UtilitiesService,
|
||||
public menuItems: MenuItems,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this._loadDropZoneByOaci();
|
||||
}
|
||||
|
||||
+88
-86
@@ -1,86 +1,88 @@
|
||||
<mat-card>
|
||||
<mat-card-header>
|
||||
<mat-card-title>{{ title }}</mat-card-title>
|
||||
<mat-card-subtitle>{{ subtitle }} de {{min}} à {{max}}</mat-card-subtitle>
|
||||
<span class="flex-spacer"></span>
|
||||
<button mat-icon-button [matMenuTriggerFor]="menuJumpBar" aria-label="Menu Dropzone Bar">
|
||||
<mat-icon fontIcon="more_vert"></mat-icon>
|
||||
</button>
|
||||
<mat-menu #menuJumpBar="matMenu">
|
||||
<button mat-menu-item *ngFor="let menuitem of menuItems.getMenuPanel()">
|
||||
<mat-icon [fontIcon]="menuitem.icon"></mat-icon>
|
||||
<span>{{ menuitem.name }}</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</mat-card-header>
|
||||
<mat-divider class="my-3"></mat-divider>
|
||||
<mat-card-content>
|
||||
<!--
|
||||
<div class="text-center mb-3">
|
||||
<ul class="list-inline my-0">
|
||||
<li *ngFor='let name of seriesName; let i=index' class="list-inline-item me-lg-3 me-sm-2">
|
||||
<span class="{{seriesColor[i]}} fs-6 m-0">
|
||||
● {{name}}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
-->
|
||||
<div *ngIf="displayCharts" class="barchart position-relative w-100 my-1">
|
||||
<x-chartist [configuration]="barChartJumps"></x-chartist>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<mat-divider class="mt-3 mb-0"></mat-divider>
|
||||
<mat-accordion>
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>Historique annuel</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<table class="table table-striped table-dark table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th *ngFor='let name of seriesHeader; let i=index' class="text-end"> {{ name }} </th>
|
||||
<th class="text-end">Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor='let values of seriesRow; let i=index'>
|
||||
<th class="{{seriesColorClass[i]}} text-end"> ● {{ seriesName[i] }} </th>
|
||||
<td *ngFor='let value of values; let i=index' class="font-monospace text-end">
|
||||
<span *ngIf="value; else elseBlock" class="pr-1">{{ value }}</span>
|
||||
<ng-template #elseBlock><span class="text-empty pr-1">{{ value }}</span></ng-template>
|
||||
</td>
|
||||
<th class="{{seriesColorClass[i]}} font-monospace text-end">{{ seriesRowTotal[i] }}</th>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th class="text-end">Total</th>
|
||||
<th *ngFor='let value of seriesColTotal; let i=index' class="font-monospace text-end">
|
||||
<span *ngIf="value; else elseBlock" class="pr-1">{{ value }}</span>
|
||||
<ng-template #elseBlock><span class="text-empty pr-1">{{ value }}</span></ng-template>
|
||||
</th>
|
||||
<th class="font-monospace text-end">{{ grandTotal }}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="text-end">Moyenne</th>
|
||||
<th *ngFor='let value of seriesRowAvg; let i=index' class="font-monospace text-end">
|
||||
<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>
|
||||
</th>
|
||||
<th class="font-monospace text-end">{{ grandAvg | number : '1.0-1' }}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<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">
|
||||
<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>
|
||||
</th>
|
||||
<th class="font-monospace text-end">{{ grandAvgLastYears | number : '1.0-1' }}</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</mat-expansion-panel>
|
||||
</mat-accordion>
|
||||
</mat-card>
|
||||
<mat-card>
|
||||
<mat-card-header>
|
||||
<mat-card-title>{{ title }}</mat-card-title>
|
||||
<mat-card-subtitle>{{ subtitle }} de {{ min }} à {{ max }}</mat-card-subtitle>
|
||||
<span class="flex-spacer"></span>
|
||||
<button mat-icon-button [matMenuTriggerFor]="menuJumpBar" aria-label="Menu Dropzone Bar">
|
||||
<mat-icon fontIcon="more_vert"></mat-icon>
|
||||
</button>
|
||||
<mat-menu #menuJumpBar="matMenu">
|
||||
<button mat-menu-item *ngFor="let menuitem of menuItems.getMenuPanel()">
|
||||
<mat-icon [fontIcon]="menuitem.icon"></mat-icon>
|
||||
<span>{{ menuitem.name }}</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</mat-card-header>
|
||||
<mat-divider class="my-3"></mat-divider>
|
||||
<mat-card-content>
|
||||
@if (displayCharts) {
|
||||
<app-bars-chart
|
||||
[names]="seriesName"
|
||||
[values]="seriesRow"
|
||||
[headers]="seriesHeader"
|
||||
[colors]="seriesColor"
|
||||
></app-bars-chart>
|
||||
}
|
||||
</mat-card-content>
|
||||
<mat-divider class="mt-3 mb-0"></mat-divider>
|
||||
<mat-accordion>
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>Historique annuel</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<table class="table table-striped table-dark table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th *ngFor="let name of seriesHeader; let i = index" class="text-end">{{ name }}</th>
|
||||
<th class="text-end">Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let values of seriesRow; let i = index">
|
||||
<th class="{{ seriesColorClass[i] }} text-end">● {{ seriesName[i] }}</th>
|
||||
<td *ngFor="let value of values; let i = index" class="font-monospace text-end">
|
||||
<span *ngIf="value; else elseBlock" class="pr-1">{{ value }}</span>
|
||||
<ng-template #elseBlock
|
||||
><span class="text-empty pr-1">{{ value }}</span></ng-template
|
||||
>
|
||||
</td>
|
||||
<th class="{{ seriesColorClass[i] }} font-monospace text-end">{{ seriesRowTotal[i] }}</th>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th class="text-end">Total</th>
|
||||
<th *ngFor="let value of seriesColTotal; let i = index" class="font-monospace text-end">
|
||||
<span *ngIf="value; else elseBlock" class="pr-1">{{ value }}</span>
|
||||
<ng-template #elseBlock
|
||||
><span class="text-empty pr-1">{{ value }}</span></ng-template
|
||||
>
|
||||
</th>
|
||||
<th class="font-monospace text-end">{{ grandTotal }}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="text-end">Moyenne</th>
|
||||
<th *ngFor="let value of seriesRowAvg; let i = index" class="font-monospace text-end">
|
||||
<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
|
||||
>
|
||||
</th>
|
||||
<th class="font-monospace text-end">{{ grandAvg | number: "1.0-1" }}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<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">
|
||||
<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
|
||||
>
|
||||
</th>
|
||||
<th class="font-monospace text-end">{{ grandAvgLastYears | number: "1.0-1" }}</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</mat-expansion-panel>
|
||||
</mat-accordion>
|
||||
</mat-card>
|
||||
|
||||
+10
-66
@@ -1,36 +1,40 @@
|
||||
import { Component, DestroyRef, inject, OnInit, OnDestroy } from '@angular/core';
|
||||
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 { MatCardModule } from '@angular/material/card';
|
||||
import { MatDividerModule } from '@angular/material/divider';
|
||||
import { MatExpansionModule } from '@angular/material/expansion';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { ChartistModule, Configuration } from 'ng-chartist';
|
||||
import { AxisOptions, Label } from 'chartist';
|
||||
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
|
||||
import { MenuItems } from '@components/shared';
|
||||
import { BarsChartComponent } from '@components/shared/helpers-chart';
|
||||
import { UtilitiesService, JumpsService } from '@services';
|
||||
import { JumpByDate } from '@models';
|
||||
|
||||
@Component({
|
||||
selector: 'app-jumps-by-month',
|
||||
imports: [
|
||||
CommonModule,
|
||||
NgFor,
|
||||
NgIf,
|
||||
DecimalPipe,
|
||||
MatButtonModule,
|
||||
MatCardModule,
|
||||
MatDividerModule,
|
||||
MatExpansionModule,
|
||||
MatIconModule,
|
||||
MatMenuModule,
|
||||
ChartistModule,
|
||||
BarsChartComponent,
|
||||
],
|
||||
templateUrl: './jumps-by-month.component.html',
|
||||
})
|
||||
export class JumpsByMonthComponent implements OnInit, OnDestroy {
|
||||
private _jumpsService = inject(JumpsService);
|
||||
private _utilitiesService = inject(UtilitiesService);
|
||||
menuItems = inject(MenuItems);
|
||||
|
||||
private _jumpByDate: Subscription = new Subscription();
|
||||
private _jumpsByDate!: Array<JumpByDate>;
|
||||
private _jumpsByDateCount = 0;
|
||||
@@ -59,15 +63,8 @@ export class JumpsByMonthComponent implements OnInit, OnDestroy {
|
||||
public seriesColTotalClosed: number[] = [];
|
||||
public seriesColTotalLastYears: number[] = [];
|
||||
public displayCharts = false;
|
||||
public barChartJumps: Configuration = this._utilitiesService.getBarConfig();
|
||||
public destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(
|
||||
private _jumpsService: JumpsService,
|
||||
private _utilitiesService: UtilitiesService,
|
||||
public menuItems: MenuItems,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this._loadJumpByDate();
|
||||
}
|
||||
@@ -130,59 +127,6 @@ export class JumpsByMonthComponent implements OnInit, OnDestroy {
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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 { BaseChartDirective } from 'ng2-charts';
|
||||
|
||||
@@ -11,11 +11,11 @@ import { BarConfig } from '@models';
|
||||
templateUrl: './bar-chart.component.html',
|
||||
})
|
||||
export class BarChartComponent implements OnChanges {
|
||||
private _utilitiesService = inject(UtilitiesService);
|
||||
|
||||
public displayCharts = false;
|
||||
public chartConfig: BarConfig = this._utilitiesService.getBarChartConfig();
|
||||
|
||||
constructor(private _utilitiesService: UtilitiesService) {}
|
||||
|
||||
@Input() names: string[] = [];
|
||||
@Input() values: number[] = [];
|
||||
@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 { BaseChartDirective } from 'ng2-charts';
|
||||
|
||||
@@ -11,11 +11,11 @@ import { BarConfig } from '@models';
|
||||
templateUrl: './bar-horizontal-chart.component.html',
|
||||
})
|
||||
export class BarHorizontalChartComponent implements OnChanges {
|
||||
private _utilitiesService = inject(UtilitiesService);
|
||||
|
||||
public displayCharts = false;
|
||||
public chartConfig: BarConfig = this._utilitiesService.getHorizontalBarChartConfig();
|
||||
|
||||
constructor(private _utilitiesService: UtilitiesService) {}
|
||||
|
||||
@Input() names: string[] = [];
|
||||
@Input() values: number[] = [];
|
||||
@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 { BaseChartDirective } from 'ng2-charts';
|
||||
|
||||
@@ -11,11 +11,11 @@ import { BarConfig } from '@models';
|
||||
templateUrl: './bars-chart.component.html',
|
||||
})
|
||||
export class BarsChartComponent implements OnChanges, AfterContentChecked {
|
||||
private _utilitiesService = inject(UtilitiesService);
|
||||
|
||||
public displayCharts = false;
|
||||
public chartConfig: BarConfig = this._utilitiesService.getBarChartConfig();
|
||||
|
||||
constructor(private _utilitiesService: UtilitiesService) {}
|
||||
|
||||
@Input() names: string[] = [];
|
||||
@Input() values: Array<Array<number>> = [];
|
||||
@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 { BaseChartDirective } from 'ng2-charts';
|
||||
|
||||
@@ -11,11 +11,11 @@ import { CircleConfig } from '@models';
|
||||
templateUrl: './circle-chart.component.html',
|
||||
})
|
||||
export class CircleChartComponent implements OnChanges {
|
||||
private _utilitiesService = inject(UtilitiesService);
|
||||
|
||||
public displayCharts = false;
|
||||
public chartConfig: CircleConfig = this._utilitiesService.getCircleChartConfig();
|
||||
|
||||
constructor(private _utilitiesService: UtilitiesService) {}
|
||||
|
||||
@Input() names: string[] = [];
|
||||
@Input() values: number[] = [];
|
||||
@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 { BaseChartDirective } from 'ng2-charts';
|
||||
|
||||
@@ -11,11 +11,11 @@ import { LineConfig } from '@models';
|
||||
templateUrl: './line-chart.component.html',
|
||||
})
|
||||
export class LineChartComponent implements OnChanges {
|
||||
private _utilitiesService = inject(UtilitiesService);
|
||||
|
||||
public displayCharts = false;
|
||||
public chartConfig: LineConfig = this._utilitiesService.getLineChartConfig();
|
||||
|
||||
constructor(private _utilitiesService: UtilitiesService) {}
|
||||
|
||||
@Input() headers: string[] = [];
|
||||
@Input() names: string[] = [];
|
||||
@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 { BaseChartDirective } from 'ng2-charts';
|
||||
|
||||
@@ -11,11 +11,11 @@ import { LineConfig } from '@models';
|
||||
templateUrl: './linearea-chart.component.html',
|
||||
})
|
||||
export class LineAreaChartComponent implements OnChanges {
|
||||
private _utilitiesService = inject(UtilitiesService);
|
||||
|
||||
public displayCharts = false;
|
||||
public chartConfig: LineConfig = this._utilitiesService.getStackedLineAreaChartConfig();
|
||||
|
||||
constructor(private _utilitiesService: UtilitiesService) {}
|
||||
|
||||
@Input() headers: string[] = [];
|
||||
@Input() names: string[] = [];
|
||||
@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 { BaseChartDirective } from 'ng2-charts';
|
||||
|
||||
@@ -11,11 +11,11 @@ import { DoughnutConfig } from '@models';
|
||||
templateUrl: './pie-chart.component.html',
|
||||
})
|
||||
export class PieChartComponent implements OnChanges {
|
||||
private _utilitiesService = inject(UtilitiesService);
|
||||
|
||||
public displayCharts = false;
|
||||
public chartConfig: DoughnutConfig = this._utilitiesService.getDoughnutChartConfig();
|
||||
|
||||
constructor(private _utilitiesService: UtilitiesService) {}
|
||||
|
||||
@Input() names: string[] = [];
|
||||
@Input() values: number[] = [];
|
||||
@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 { RouterLink } from '@angular/router';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
@@ -24,6 +24,8 @@ import { JumpPreviewComponent } from './jump-preview.component';
|
||||
],
|
||||
})
|
||||
export class JumpListComponent implements OnInit, OnDestroy {
|
||||
private jumpsService = inject(JumpsService);
|
||||
|
||||
private _jumps: Subscription = new Subscription();
|
||||
errors: Errors = { errors: {} };
|
||||
query!: JumpListConfig;
|
||||
@@ -34,8 +36,6 @@ export class JumpListComponent implements OnInit, OnDestroy {
|
||||
pages: Array<number> = [1];
|
||||
lastUpdate: Date = new Date();
|
||||
|
||||
constructor(private jumpsService: JumpsService) {}
|
||||
|
||||
@Input() limit = 0;
|
||||
@Input() refresh = 30000;
|
||||
@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 { Router, RouterLink } from '@angular/router';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
@@ -17,17 +17,15 @@ import { JumpsService } from '@services';
|
||||
templateUrl: './jump-preview.component.html',
|
||||
})
|
||||
export class JumpPreviewComponent implements OnDestroy {
|
||||
private router = inject(Router);
|
||||
private jumpsService = inject(JumpsService);
|
||||
|
||||
@Input() jump!: Jump;
|
||||
@Input() isUser!: boolean;
|
||||
@Input() showMeta!: boolean;
|
||||
private _jump: Subscription = new Subscription();
|
||||
isDeleting = false;
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
private jumpsService: JumpsService,
|
||||
) {}
|
||||
|
||||
ngOnDestroy() {
|
||||
this._jump.unsubscribe();
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
OnChanges,
|
||||
OnDestroy,
|
||||
ViewChild,
|
||||
inject,
|
||||
} from '@angular/core';
|
||||
import { CommonModule, DecimalPipe, DatePipe } from '@angular/common';
|
||||
import { UntypedFormBuilder, UntypedFormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
@@ -88,6 +89,13 @@ import {
|
||||
providers: [{ provide: MatPaginatorIntl, useClass: FrenchPaginator }],
|
||||
})
|
||||
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 _subscriptions: Array<Subscription> = [];
|
||||
//private _jump: Subscription = new Subscription();
|
||||
@@ -131,14 +139,7 @@ export class JumpTableComponent implements OnChanges, OnDestroy, AfterContentChe
|
||||
@ViewChild(MatSort) sort!: MatSort;
|
||||
@ViewChild(MatPaginator) paginator!: MatPaginator;
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
private _jumpsService: JumpsService,
|
||||
private _jumpTableService: JumpTableService,
|
||||
private dialog: MatDialog,
|
||||
private fb: UntypedFormBuilder,
|
||||
private snackBar: MatSnackBar,
|
||||
) {
|
||||
constructor() {
|
||||
this._resetErrors();
|
||||
this.searchForm = this.fb.group({
|
||||
//numero: ['', Validators.required]
|
||||
|
||||
+8
-8
@@ -3,11 +3,11 @@
|
||||
display: inline-block;
|
||||
}
|
||||
.mat-mdc-standard-chip {
|
||||
--mdc-chip-container-height: 28px;
|
||||
--mdc-chip-container-shape-radius: 8px 8px 8px 8px;
|
||||
--mdc-chip-label-text-color: inherit;
|
||||
--mdc-chip-label-text-line-height: 20px;
|
||||
--mdc-chip-label-text-size: 13px;
|
||||
--mdc-chip-label-text-weight: 400;
|
||||
--mdc-chip-with-avatar-avatar-shape-radius: 6px 6px 6px 6px;
|
||||
}
|
||||
--mat-chip-container-height: 28px;
|
||||
--mat-chip-container-shape-radius: 8px 8px 8px 8px;
|
||||
--mat-chip-label-text-color: inherit;
|
||||
--mat-chip-label-text-line-height: 20px;
|
||||
--mat-chip-label-text-size: 13px;
|
||||
--mat-chip-label-text-weight: 400;
|
||||
--mat-chip-with-avatar-avatar-shape-radius: 6px 6px 6px 6px;
|
||||
}
|
||||
|
||||
+3
-1
@@ -48,6 +48,8 @@ export class StepperIntl extends MatStepperIntl {
|
||||
styleUrl: './guildraids-log.component.scss',
|
||||
})
|
||||
export class GuildraidsLogComponent implements OnInit {
|
||||
private fb = inject(FormBuilder);
|
||||
|
||||
public now: Date;
|
||||
public raidsForm: FormGroup;
|
||||
public guildMembers: HWMember[] = [];
|
||||
@@ -66,7 +68,7 @@ export class GuildraidsLogComponent implements OnInit {
|
||||
this.guildMembers = value;
|
||||
}
|
||||
|
||||
constructor(private fb: FormBuilder) {
|
||||
constructor() {
|
||||
this.now = new Date();
|
||||
const raidsDate = new Date();
|
||||
const startHour = 4;
|
||||
|
||||
+3
-3
@@ -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 { MatCardModule } from '@angular/material/card';
|
||||
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',
|
||||
})
|
||||
export class MembersStatisticsComponent implements OnInit {
|
||||
private _utilitiesService = inject(UtilitiesService);
|
||||
|
||||
public guildMembers: HWMember[] = [];
|
||||
public title = 'Members';
|
||||
public subtitle = 'statistics';
|
||||
@@ -82,8 +84,6 @@ export class MembersStatisticsComponent implements OnInit {
|
||||
this.guildMembers = value;
|
||||
}
|
||||
|
||||
constructor(private _utilitiesService: UtilitiesService) {}
|
||||
|
||||
ngOnInit() {
|
||||
const oneDayInSec = 24 * 60 * 60;
|
||||
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 { MediaMatcher } from '@angular/cdk/layout';
|
||||
import { MatBadgeModule } from '@angular/material/badge';
|
||||
@@ -51,6 +51,10 @@ import { FooterComponent } from '@components/shared/layout';
|
||||
styleUrls: [],
|
||||
})
|
||||
export class FullComponent implements OnInit, OnDestroy {
|
||||
private router = inject(Router);
|
||||
private userService = inject(UserService);
|
||||
menuItems = inject(MenuItems);
|
||||
|
||||
private _currentUser: Subscription = new Subscription();
|
||||
private _mobileQueryListener: () => void;
|
||||
mobileQuery: MediaQueryList;
|
||||
@@ -63,13 +67,10 @@ export class FullComponent implements OnInit, OnDestroy {
|
||||
//visibleMenu: string[] = ['products', 'page'];
|
||||
//visibleMenu: string[] = ['products'];
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
private userService: UserService,
|
||||
changeDetectorRef: ChangeDetectorRef,
|
||||
media: MediaMatcher,
|
||||
public menuItems: MenuItems,
|
||||
) {
|
||||
constructor() {
|
||||
const changeDetectorRef = inject(ChangeDetectorRef);
|
||||
const media = inject(MediaMatcher);
|
||||
|
||||
this.mobileQuery = media.matchMedia('(min-width: 768px)');
|
||||
this._mobileQueryListener = () => changeDetectorRef.detectChanges();
|
||||
this.mobileQuery.addListener(this._mobileQueryListener);
|
||||
|
||||
@@ -26,17 +26,15 @@ import { UserService } from '@services';
|
||||
],
|
||||
})
|
||||
export class HeaderComponent implements OnInit {
|
||||
private router = inject(Router);
|
||||
private userService = inject(UserService);
|
||||
|
||||
private _currentUser: Subscription = new Subscription();
|
||||
private _isAuthenticated: Subscription = new Subscription();
|
||||
private isAuthenticated = false;
|
||||
currentUser: User = {} as User;
|
||||
destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
private userService: UserService,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
const user$: Observable<User> = this.userService.currentUser.pipe(takeUntilDestroyed(this.destroyRef));
|
||||
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 { UserService } from '@services';
|
||||
|
||||
@Directive({
|
||||
selector: '[appShowAuthed]',
|
||||
standalone: true
|
||||
standalone: true,
|
||||
})
|
||||
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 templateRef: TemplateRef<any>,
|
||||
private templateRef: TemplateRef<never>,
|
||||
private userService: UserService,
|
||||
private viewContainer: ViewContainerRef
|
||||
) { }
|
||||
private _auth: Subscription = new Subscription();
|
||||
|
||||
@Input() set appShowAuthed(condition: boolean) {
|
||||
this.condition = condition;
|
||||
@@ -25,21 +22,17 @@ export class ShowAuthedDirective implements OnInit, OnDestroy {
|
||||
//condition: boolean;
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
const isAuthenticated$: Observable<boolean> = this.userService.isAuthenticated; // .pipe(take(1));
|
||||
this._auth = isAuthenticated$.subscribe(
|
||||
(isAuthenticated) => {
|
||||
if (isAuthenticated && this.condition || !isAuthenticated && !this.condition) {
|
||||
this.viewContainer.createEmbeddedView(this.templateRef);
|
||||
} else {
|
||||
this.viewContainer.clear();
|
||||
}
|
||||
this._auth = isAuthenticated$.subscribe((isAuthenticated) => {
|
||||
if ((isAuthenticated && this.condition) || (!isAuthenticated && !this.condition)) {
|
||||
this.viewContainer.createEmbeddedView(this.templateRef);
|
||||
} else {
|
||||
this.viewContainer.clear();
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
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 { DOCUMENT } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'app-spinner',
|
||||
@@ -10,15 +9,15 @@ import { DOCUMENT } from '@angular/common';
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
})
|
||||
export class SpinnerComponent implements OnDestroy {
|
||||
private router = inject(Router);
|
||||
private document = inject<Document>(DOCUMENT);
|
||||
|
||||
public isSpinnerVisible = true;
|
||||
|
||||
@Input()
|
||||
public backgroundColor = 'rgba(0, 115, 170, 0.69)';
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
@Inject(DOCUMENT) private document: Document,
|
||||
) {
|
||||
constructor() {
|
||||
this.router.events.subscribe(
|
||||
(event) => {
|
||||
if (event instanceof NavigationStart) {
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
/* 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 { Observable } from 'rxjs';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ApiService {
|
||||
constructor(
|
||||
private http: HttpClient
|
||||
) { }
|
||||
private http = inject(HttpClient);
|
||||
|
||||
/*private formatErrors(error: any) {
|
||||
return throwError(error.error);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { HttpParams } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@@ -8,10 +8,9 @@ import { map } from 'rxjs/operators';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ApplicationsService {
|
||||
private apiService = inject(ApiService);
|
||||
|
||||
private _apiDomain = '/skydive';
|
||||
constructor(
|
||||
private apiService: ApiService
|
||||
) { }
|
||||
|
||||
query(config: ApplicationListConfig): Observable<ApplicationList> {
|
||||
// Convert any filters over to Angular's URLSearchParams
|
||||
@@ -19,36 +18,37 @@ export class ApplicationsService {
|
||||
apikey: config.filters.apikey,
|
||||
author: config.filters.author,
|
||||
limit: config.filters.limit,
|
||||
offset: config.filters.offset
|
||||
offset: config.filters.offset,
|
||||
};
|
||||
return this.apiService
|
||||
.get(
|
||||
`${this._apiDomain}/applications` + ((config.type === 'feed') ? '/feed' : ''),
|
||||
new HttpParams({ fromObject: <{
|
||||
[param: string]: string | number | boolean | readonly (string | number | boolean)[];
|
||||
}>params })
|
||||
);
|
||||
return this.apiService.get(
|
||||
`${this._apiDomain}/applications` + (config.type === 'feed' ? '/feed' : ''),
|
||||
new HttpParams({ fromObject: <
|
||||
{
|
||||
[param: string]: string | number | boolean | readonly (string | number | boolean)[];
|
||||
}
|
||||
>params }),
|
||||
);
|
||||
}
|
||||
|
||||
get(slug: string): Observable<Application> {
|
||||
return this.apiService.get(`${this._apiDomain}/applications/${slug}`)
|
||||
.pipe(map(data => data.application));
|
||||
return this.apiService.get(`${this._apiDomain}/applications/${slug}`).pipe(map((data) => data.application));
|
||||
}
|
||||
|
||||
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> {
|
||||
if (application.slug) {
|
||||
// If we're updating an existing application
|
||||
return this.apiService.put(`${this._apiDomain}/applications/${application.slug}`, { application: application })
|
||||
.pipe(map(data => data.application));
|
||||
return this.apiService
|
||||
.put(`${this._apiDomain}/applications/${application.slug}`, { application: application })
|
||||
.pipe(map((data) => data.application));
|
||||
} else {
|
||||
// Otherwise, create a new application
|
||||
return this.apiService.post(`${this._apiDomain}/applications/`, { application: application })
|
||||
.pipe(map(data => data.application));
|
||||
return this.apiService
|
||||
.post(`${this._apiDomain}/applications/`, { application: application })
|
||||
.pipe(map((data) => data.application));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { HttpParams } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
@@ -8,22 +8,22 @@ import { Article, ArticleList, ArticleListConfig, ArticleListFilters, ArticlePag
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ArticlesService {
|
||||
private apiService = inject(ApiService);
|
||||
|
||||
private _apiDomain = '/cms';
|
||||
constructor(
|
||||
private apiService: ApiService
|
||||
) { }
|
||||
|
||||
query(config: ArticleListConfig): Observable<ArticleList> {
|
||||
// Convert any filters over to Angular's URLSearchParams
|
||||
const params: ArticleListFilters = {} as ArticleListFilters;
|
||||
Object.assign(params, config.filters);
|
||||
return this.apiService
|
||||
.get(
|
||||
`${this._apiDomain}/articles` + ((config.type === 'feed') ? '/feed' : ''),
|
||||
new HttpParams({ fromObject: <{
|
||||
[param: string]: string | number | boolean | readonly (string | number | boolean)[];
|
||||
}>params })
|
||||
);
|
||||
return this.apiService.get(
|
||||
`${this._apiDomain}/articles` + (config.type === 'feed' ? '/feed' : ''),
|
||||
new HttpParams({ fromObject: <
|
||||
{
|
||||
[param: string]: string | number | boolean | readonly (string | number | boolean)[];
|
||||
}
|
||||
>params }),
|
||||
);
|
||||
}
|
||||
|
||||
get(slug: string): Observable<ArticlePageData> {
|
||||
@@ -34,33 +34,39 @@ export class ArticlesService {
|
||||
}));*/
|
||||
return this.apiService.get(`${this._apiDomain}/articles/${slug}`);
|
||||
}
|
||||
|
||||
|
||||
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> {
|
||||
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> {
|
||||
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> {
|
||||
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> {
|
||||
// If we're updating an existing article
|
||||
if (article.slug) {
|
||||
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));
|
||||
|
||||
// Otherwise, create a new article
|
||||
} else {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,5 +77,4 @@ export class ArticlesService {
|
||||
unfavorite(slug: string): Observable<Article> {
|
||||
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 { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { ApiService } from '../api.service';
|
||||
import {
|
||||
HWActivityStat, HWClan, HWClanList, HWClanListConfig,
|
||||
HWClanListFilters, HWClanPageData, HWGuildClan,
|
||||
HWMember
|
||||
HWActivityStat,
|
||||
HWClan,
|
||||
HWClanList,
|
||||
HWClanListConfig,
|
||||
HWClanListFilters,
|
||||
HWClanPageData,
|
||||
HWGuildClan,
|
||||
HWMember,
|
||||
} from '@models';
|
||||
|
||||
import guildData from 'src/files-data/hw-guild-data.json'; // page Membres
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class HWClanService {
|
||||
private apiService = inject(ApiService);
|
||||
|
||||
private _apiDomain = '/herowars';
|
||||
constructor(
|
||||
private apiService: ApiService
|
||||
) { }
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -28,13 +43,14 @@ export class HWClanService {
|
||||
// Convert any filters over to Angular's URLSearchParams
|
||||
const params: HWClanListFilters = {} as HWClanListFilters;
|
||||
Object.assign(params, config.filters);
|
||||
return this.apiService
|
||||
.get(
|
||||
`${this._apiDomain}/clans`,
|
||||
new HttpParams({ fromObject: <{
|
||||
[param: string]: string | number | boolean | readonly (string | number | boolean)[];
|
||||
}>params })
|
||||
);
|
||||
return this.apiService.get(
|
||||
`${this._apiDomain}/clans`,
|
||||
new HttpParams({ fromObject: <
|
||||
{
|
||||
[param: string]: string | number | boolean | readonly (string | number | boolean)[];
|
||||
}
|
||||
>params }),
|
||||
);
|
||||
}
|
||||
|
||||
get(id: string): Observable<HWClanPageData> {
|
||||
@@ -42,31 +58,35 @@ export class HWClanService {
|
||||
}
|
||||
|
||||
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> {
|
||||
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> {
|
||||
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> {
|
||||
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> {
|
||||
// If we're updating an existing clan
|
||||
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
|
||||
} 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 {
|
||||
const guildClan: HWGuildClan = {} as HWGuildClan;
|
||||
Object.assign(guildClan, guildData.clan);
|
||||
@@ -77,7 +97,7 @@ export class HWClanService {
|
||||
|
||||
return guildClan;
|
||||
}
|
||||
|
||||
|
||||
loadClanStats(clan: HWGuildClan, members: HWMember[]): HWGuildClan {
|
||||
members.map((member: HWMember) => {
|
||||
clan.sumTotal.adventure += member.adventureSum;
|
||||
@@ -86,42 +106,42 @@ export class HWClanService {
|
||||
clan.todayTotal.activity += member.stat.todayActivity;
|
||||
clan.todayTotal.prestige += member.stat.todayPrestige;
|
||||
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.prestige += member.stat.prestigeSum;
|
||||
clan.sumTotal.titanite += member.stat.dungeonActivitySum;
|
||||
clan.sumTotal.score += member.score;
|
||||
clan.sumTotal.warGifts += member.warGifts;
|
||||
});
|
||||
clan.sumTotal.scoreGifts = (clan.giftsCount - Math.floor(clan.sumTotal.warGifts));
|
||||
clan.todayAverages.activity = (clan.todayTotal.activity / members.length);
|
||||
clan.todayAverages.prestige = (clan.todayTotal.prestige / members.length);
|
||||
clan.todayAverages.titanite = (clan.todayTotal.titanite / members.length);
|
||||
clan.todayAverages.score = (clan.todayTotal.score / members.length);
|
||||
clan.sumAverages.activity = (clan.sumTotal.activity / members.length);
|
||||
clan.sumAverages.prestige = (clan.sumTotal.prestige / members.length);
|
||||
clan.sumAverages.titanite = (clan.sumTotal.titanite / members.length);
|
||||
clan.sumTotal.scoreGifts = clan.giftsCount - Math.floor(clan.sumTotal.warGifts);
|
||||
clan.todayAverages.activity = clan.todayTotal.activity / members.length;
|
||||
clan.todayAverages.prestige = clan.todayTotal.prestige / members.length;
|
||||
clan.todayAverages.titanite = clan.todayTotal.titanite / members.length;
|
||||
clan.todayAverages.score = clan.todayTotal.score / members.length;
|
||||
clan.sumAverages.activity = clan.sumTotal.activity / members.length;
|
||||
clan.sumAverages.prestige = clan.sumTotal.prestige / members.length;
|
||||
clan.sumAverages.titanite = clan.sumTotal.titanite / members.length;
|
||||
if (clan.league === '3') {
|
||||
clan.sumAverages.war = (clan.sumTotal.war / 10);
|
||||
clan.sumAverages.war = clan.sumTotal.war / 10;
|
||||
} else if (clan.league === '2') {
|
||||
clan.sumAverages.war = (clan.sumTotal.war / 15);
|
||||
clan.sumAverages.war = clan.sumTotal.war / 15;
|
||||
} 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.gifts = (clan.sumTotal.gifts / members.length);
|
||||
clan.sumAverages.score = (clan.sumTotal.score / members.length);
|
||||
clan.sumAverages.scoreGifts = (clan.sumTotal.scoreGifts / members.length);
|
||||
clan.sumAverages.warGifts = (clan.sumTotal.warGifts / members.length);
|
||||
clan.sumAverages.adventure = clan.sumTotal.adventure / members.length;
|
||||
clan.sumAverages.gifts = clan.sumTotal.gifts / members.length;
|
||||
clan.sumAverages.score = clan.sumTotal.score / members.length;
|
||||
clan.sumAverages.scoreGifts = clan.sumTotal.scoreGifts / members.length;
|
||||
clan.sumAverages.warGifts = clan.sumTotal.warGifts / members.length;
|
||||
members.map((data) => {
|
||||
data.scoreGifts = ((data.score / clan.sumTotal.score) * clan.sumTotal.scoreGifts);
|
||||
data.rewards = Math.floor((data.scoreGifts + data.warGifts));
|
||||
data.scoreGifts = (data.score / clan.sumTotal.score) * clan.sumTotal.scoreGifts;
|
||||
data.rewards = Math.floor(data.scoreGifts + data.warGifts);
|
||||
clan.sumTotal.rewards += data.rewards;
|
||||
return data;
|
||||
});
|
||||
clan.sumAverages.rewards = (clan.sumTotal.rewards / members.length);
|
||||
clan.sumAverages.rewards = clan.sumTotal.rewards / members.length;
|
||||
|
||||
return clan;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,36 +1,41 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { HttpParams } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { ApiService, UtilitiesService } from '@services';
|
||||
import {
|
||||
HWGuildClan, HWWeekStat,
|
||||
HWMember, HWMemberList, HWMemberListConfig,
|
||||
HWMemberListFilters, HWMemberPageData, HWMemberStat
|
||||
HWGuildClan,
|
||||
HWWeekStat,
|
||||
HWMember,
|
||||
HWMemberList,
|
||||
HWMemberListConfig,
|
||||
HWMemberListFilters,
|
||||
HWMemberPageData,
|
||||
HWMemberStat,
|
||||
} from '@models';
|
||||
|
||||
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
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class HWMemberService {
|
||||
private _apiService = inject(ApiService);
|
||||
private _utilitiesService = inject(UtilitiesService);
|
||||
|
||||
private _apiDomain = '/herowars';
|
||||
constructor(
|
||||
private _apiService: ApiService,
|
||||
private _utilitiesService: UtilitiesService
|
||||
) { }
|
||||
|
||||
query(config: HWMemberListConfig): Observable<HWMemberList> {
|
||||
// Convert any filters over to Angular's URLSearchParams
|
||||
const params: HWMemberListFilters = {} as HWMemberListFilters;
|
||||
Object.assign(params, config.filters);
|
||||
return this._apiService
|
||||
.get(
|
||||
`${this._apiDomain}/members`,
|
||||
new HttpParams({ fromObject: <{
|
||||
[param: string]: string | number | boolean | readonly (string | number | boolean)[];
|
||||
}>params })
|
||||
);
|
||||
return this._apiService.get(
|
||||
`${this._apiDomain}/members`,
|
||||
new HttpParams({ fromObject: <
|
||||
{
|
||||
[param: string]: string | number | boolean | readonly (string | number | boolean)[];
|
||||
}
|
||||
>params }),
|
||||
);
|
||||
}
|
||||
|
||||
get(id: string): Observable<HWMemberPageData> {
|
||||
@@ -38,35 +43,43 @@ export class HWMemberService {
|
||||
}
|
||||
|
||||
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> {
|
||||
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> {
|
||||
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> {
|
||||
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> {
|
||||
// If we're updating an existing member
|
||||
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
|
||||
} 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[] {
|
||||
const guildMembers: HWMember[] = [];
|
||||
const now = new Date();
|
||||
const oneDayInSec = (24 * 60 * 60);
|
||||
const oneDayInSec = 24 * 60 * 60;
|
||||
const daysToKick = parseInt(guildData.clan.daysToKick);
|
||||
for (const data of Object.entries(guildData.clan.members)) {
|
||||
const member: HWMember = {} as HWMember;
|
||||
@@ -76,47 +89,56 @@ export class HWMemberService {
|
||||
} else {
|
||||
member.champion = false;
|
||||
}
|
||||
member.heroes = { power: 0, teams: []};
|
||||
member.titans = { power: 0, teams: []};
|
||||
member.heroes = { power: 0, teams: [] };
|
||||
member.titans = { power: 0, teams: [] };
|
||||
guildMembers.push(member);
|
||||
}
|
||||
guildMembers.map((data: HWMember) => {
|
||||
const last = new Date((parseInt(data.lastLoginTime) * 1000));
|
||||
const exp = new Date(last.getTime() + ((daysToKick * oneDayInSec) * 1000));
|
||||
const diff = Math.floor(((exp.getTime() - now.getTime()) / 1000));
|
||||
const daysLeft = Math.floor((diff / oneDayInSec));
|
||||
const last = new Date(parseInt(data.lastLoginTime) * 1000);
|
||||
const exp = new Date(last.getTime() + daysToKick * oneDayInSec * 1000);
|
||||
const diff = Math.floor((exp.getTime() - now.getTime()) / 1000);
|
||||
const daysLeft = Math.floor(diff / oneDayInSec);
|
||||
let timeLeft = diff;
|
||||
if (daysLeft >= 1) {
|
||||
timeLeft = (diff - (daysLeft * oneDayInSec));
|
||||
timeLeft = diff - daysLeft * oneDayInSec;
|
||||
}
|
||||
data.inactivity = {
|
||||
daysLeft: daysLeft,
|
||||
timeLeft: timeLeft,
|
||||
dropDelay: `${daysLeft}d, ${this._utilitiesService.secondsToDuration(timeLeft)}`,
|
||||
dropDate: Math.floor((exp.getTime() / 1000))
|
||||
dropDate: Math.floor(exp.getTime() / 1000),
|
||||
};
|
||||
data.raids = [];
|
||||
data.raidsInfo = {
|
||||
variationAvg: 0,
|
||||
variationSum: 0
|
||||
variationSum: 0,
|
||||
};
|
||||
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) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
|
||||
const { userId, ...memberStatWithoutUserId } = guildData.membersStat[index] as any;
|
||||
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) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
|
||||
const { id, ...weekStatSource } = guildStatistics.stat[index] as any;
|
||||
const stat: HWWeekStat = {} as HWWeekStat;
|
||||
Object.assign(stat, weekStatSource);
|
||||
data.weekStat = stat;
|
||||
data.adventureSum = guildStatistics.stat[index].adventureStat.reduce((accumulator, currentValue) => accumulator + currentValue, 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);
|
||||
data.adventureSum = guildStatistics.stat[index].adventureStat.reduce(
|
||||
(accumulator, currentValue) => accumulator + currentValue,
|
||||
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 {
|
||||
data.weekStat = {} as HWWeekStat;
|
||||
data.adventureSum = 0;
|
||||
@@ -124,8 +146,8 @@ export class HWMemberService {
|
||||
data.clanWarSum = 0;
|
||||
}
|
||||
|
||||
data.score = (data.stat.dungeonActivitySum + data.stat.activitySum + data.stat.prestigeSum);
|
||||
data.warGifts = (((clan.giftsCount / 2) * ((data.clanWarSum * 10) / 100)) / 20);
|
||||
data.score = data.stat.dungeonActivitySum + data.stat.activitySum + data.stat.prestigeSum;
|
||||
data.warGifts = ((clan.giftsCount / 2) * ((data.clanWarSum * 10) / 100)) / 20;
|
||||
data.scoreGifts = 0;
|
||||
data.rewards = 0;
|
||||
return data;
|
||||
@@ -133,5 +155,4 @@ export class HWMemberService {
|
||||
|
||||
return guildMembers;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { take } from 'rxjs/operators';
|
||||
|
||||
@@ -7,10 +7,9 @@ import { AeronefsPageData, CanopiesPageData, DropZonesPageData, JumpsPageData }
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class PagesService {
|
||||
private apiService = inject(ApiService);
|
||||
|
||||
private _apiDomain = '/skydive';
|
||||
constructor(
|
||||
private apiService: ApiService
|
||||
) { }
|
||||
|
||||
getAeronefsPage(): Observable<AeronefsPageData> {
|
||||
return this.apiService.get(`${this._apiDomain}/pages/aeronefs`).pipe(take(1));
|
||||
@@ -27,5 +26,4 @@ export class PagesService {
|
||||
getJumpsPage(): Observable<JumpsPageData> {
|
||||
return this.apiService.get(`${this._apiDomain}/pages/jumps`).pipe(take(1));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,29 +1,36 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { HttpParams } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
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' })
|
||||
export class ProductsService {
|
||||
private apiService = inject(ApiService);
|
||||
|
||||
private _apiDomain = '/ecommerce';
|
||||
constructor(
|
||||
private apiService: ApiService
|
||||
) { }
|
||||
|
||||
query(config: ProductListConfig): Observable<ProductList> {
|
||||
// Convert any filters over to Angular's URLSearchParams
|
||||
const params: ProductListFilters = {} as ProductListFilters;
|
||||
Object.assign(params, config.filters);
|
||||
return this.apiService
|
||||
.get(
|
||||
`${this._apiDomain}/products` + ((config.type === 'feed') ? '/feed' : ''),
|
||||
new HttpParams({ fromObject: <{
|
||||
[param: string]: string | number | boolean | readonly (string | number | boolean)[];
|
||||
}>params })
|
||||
);
|
||||
return this.apiService.get(
|
||||
`${this._apiDomain}/products` + (config.type === 'feed' ? '/feed' : ''),
|
||||
new HttpParams({ fromObject: <
|
||||
{
|
||||
[param: string]: string | number | boolean | readonly (string | number | boolean)[];
|
||||
}
|
||||
>params }),
|
||||
);
|
||||
}
|
||||
|
||||
get(slug: string): Observable<ProductsPageData> {
|
||||
@@ -35,7 +42,7 @@ export class ProductsService {
|
||||
}
|
||||
|
||||
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> {
|
||||
@@ -43,26 +50,33 @@ export class ProductsService {
|
||||
}
|
||||
|
||||
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> {
|
||||
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> {
|
||||
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> {
|
||||
// If we're updating an existing product
|
||||
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
|
||||
} 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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { ApiService } from '@services';
|
||||
@@ -7,13 +7,13 @@ import { map } from 'rxjs/operators';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ProfilesService {
|
||||
private apiService = inject(ApiService);
|
||||
|
||||
private _apiDomain = '/cms';
|
||||
constructor(
|
||||
private apiService: ApiService
|
||||
) { }
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -24,5 +24,4 @@ export class ProfilesService {
|
||||
unfollow(username: string): Observable<Profile> {
|
||||
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 { map } from 'rxjs/operators';
|
||||
|
||||
@@ -7,19 +7,15 @@ import { AeronefByImat, AeronefByYear } from '@models';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AeronefsService {
|
||||
private apiService = inject(ApiService);
|
||||
|
||||
private _apiDomain = '/skydive';
|
||||
constructor(
|
||||
private apiService: ApiService
|
||||
) { }
|
||||
|
||||
getAllByImat(): Observable<Array<AeronefByImat>> {
|
||||
return this.apiService.get(`${this._apiDomain}/aeronefs/allByImat`)
|
||||
.pipe(map(data => data.aeronefs));
|
||||
return this.apiService.get(`${this._apiDomain}/aeronefs/allByImat`).pipe(map((data) => data.aeronefs));
|
||||
}
|
||||
|
||||
getAllByImatByYear(): Observable<Array<AeronefByYear>> {
|
||||
return this.apiService.get(`${this._apiDomain}/aeronefs/allByImatByYear`)
|
||||
.pipe(map(data => data.aeronefs));
|
||||
return this.apiService.get(`${this._apiDomain}/aeronefs/allByImatByYear`).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 { UtilitiesService } from '@services';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class CalculatorService {
|
||||
private _utilitiesService = inject(UtilitiesService);
|
||||
|
||||
public coeffKgLbs: number = this._utilitiesService.getCoeffKgLbs();
|
||||
public coeffFtM: number = this._utilitiesService.getCoeffFtM();
|
||||
|
||||
constructor(
|
||||
private _utilitiesService: UtilitiesService
|
||||
) { }
|
||||
|
||||
private _getTableColumn(jumps: number): number {
|
||||
let column: number = 0;
|
||||
weightSizes[0].ranges.some((range: WeightSizeRange) => {
|
||||
if (jumps >= range.start && jumps <= range.end) {
|
||||
column = (range.num-1)
|
||||
column = range.num - 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -40,11 +38,11 @@ export class CalculatorService {
|
||||
}
|
||||
|
||||
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 {
|
||||
return Math.ceil(surface * (100 - percentOff) / 100);
|
||||
return Math.ceil((surface * (100 - percentOff)) / 100);
|
||||
}
|
||||
|
||||
public canopySizeCalc(weight: number, jumps: number): CalculatorResult {
|
||||
@@ -54,12 +52,12 @@ export class CalculatorService {
|
||||
const maxRange = 1600;
|
||||
const result: CalculatorResult = {
|
||||
min: 59,
|
||||
min11: 34
|
||||
min11: 34,
|
||||
};
|
||||
if (jumps > maxRange) {
|
||||
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.min11 = this._reduceLimit(result.min, 11);
|
||||
|
||||
@@ -67,7 +65,7 @@ export class CalculatorService {
|
||||
}
|
||||
|
||||
public convertFeet2Meters(size: number): number {
|
||||
return (size * this._utilitiesService.getCoeffFtM());
|
||||
return size * this._utilitiesService.getCoeffFtM();
|
||||
}
|
||||
|
||||
public getCanopySizes(weight: number, reduce = false): number[] {
|
||||
@@ -77,11 +75,11 @@ export class CalculatorService {
|
||||
if (weight > 110) {
|
||||
weight = 110;
|
||||
}
|
||||
const line = (weight - this._getTableLine(0));
|
||||
const line = weight - this._getTableLine(0);
|
||||
const data = weightSizes[line];
|
||||
if (reduce) {
|
||||
return data.ranges.map((range: WeightSizeRange): number => {
|
||||
return Math.ceil(range.value! * (100 - 11) / 100);
|
||||
return Math.ceil((range.value! * (100 - 11)) / 100);
|
||||
});
|
||||
} else {
|
||||
return data.ranges.map((range: WeightSizeRange): number => {
|
||||
@@ -91,7 +89,7 @@ export class CalculatorService {
|
||||
}
|
||||
|
||||
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 {
|
||||
@@ -125,5 +123,4 @@ export class CalculatorService {
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
@@ -7,29 +7,25 @@ import { CanopyBySize, CanopyByYear, CanopyModelBySize, CanopyModelByYear } from
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class CanopiesService {
|
||||
private apiService = inject(ApiService);
|
||||
|
||||
private _apiDomain = '/skydive';
|
||||
constructor(
|
||||
private apiService: ApiService
|
||||
) { }
|
||||
|
||||
getAllBySize(): Observable<Array<CanopyBySize>> {
|
||||
return this.apiService.get(`${this._apiDomain}/canopies/allBySize`)
|
||||
.pipe(map(data => data.canopies));
|
||||
return this.apiService.get(`${this._apiDomain}/canopies/allBySize`).pipe(map((data) => data.canopies));
|
||||
}
|
||||
|
||||
getAllBySizeByYear(): Observable<Array<CanopyByYear>> {
|
||||
return this.apiService.get(`${this._apiDomain}/canopies/allBySizeByYear`)
|
||||
.pipe(map(data => data.canopies));
|
||||
return this.apiService.get(`${this._apiDomain}/canopies/allBySizeByYear`).pipe(map((data) => data.canopies));
|
||||
}
|
||||
|
||||
getAllBySizeByModel(): Observable<Array<CanopyModelBySize>> {
|
||||
return this.apiService.get(`${this._apiDomain}/canopies/allBySizeByModel`)
|
||||
.pipe(map(data => data.canopies));
|
||||
return this.apiService.get(`${this._apiDomain}/canopies/allBySizeByModel`).pipe(map((data) => data.canopies));
|
||||
}
|
||||
|
||||
getAllBySizeByModelByYear(): Observable<Array<CanopyModelByYear>> {
|
||||
return this.apiService.get(`${this._apiDomain}/canopies/allBySizeByModelByYear`)
|
||||
.pipe(map(data => data.canopies));
|
||||
return this.apiService
|
||||
.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 { map } from 'rxjs/operators';
|
||||
|
||||
@@ -7,19 +7,15 @@ import { DropZoneByOaci, DropZoneByYear } from '@models';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class DropZonesService {
|
||||
private apiService = inject(ApiService);
|
||||
|
||||
private _apiDomain = '/skydive';
|
||||
constructor(
|
||||
private apiService: ApiService
|
||||
) { }
|
||||
|
||||
getAllByOaci(): Observable<Array<DropZoneByOaci>> {
|
||||
return this.apiService.get(`${this._apiDomain}/dropzones/allByOaci`)
|
||||
.pipe(map(data => data.dropzones));
|
||||
return this.apiService.get(`${this._apiDomain}/dropzones/allByOaci`).pipe(map((data) => data.dropzones));
|
||||
}
|
||||
|
||||
getAllByOaciByYear(): Observable<Array<DropZoneByYear>> {
|
||||
return this.apiService.get(`${this._apiDomain}/dropzones/allByOaciByYear`)
|
||||
.pipe(map(data => data.dropzones));
|
||||
return this.apiService.get(`${this._apiDomain}/dropzones/allByOaciByYear`).pipe(map((data) => data.dropzones));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,29 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { HttpParams } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { ApiService } from '../api.service';
|
||||
import {
|
||||
Jump, JumpByCategorie, JumpByDate, JumpByDay, JumpByModule, JumpFile,
|
||||
JumpList, JumpListConfig, JumpListFilters, JumpPageData,
|
||||
X2Data, SkydiverIdJumps
|
||||
Jump,
|
||||
JumpByCategorie,
|
||||
JumpByDate,
|
||||
JumpByDay,
|
||||
JumpByModule,
|
||||
JumpFile,
|
||||
JumpList,
|
||||
JumpListConfig,
|
||||
JumpListFilters,
|
||||
JumpPageData,
|
||||
X2Data,
|
||||
SkydiverIdJumps,
|
||||
} from '@models';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class JumpsService {
|
||||
private apiService = inject(ApiService);
|
||||
|
||||
private _apiDomain = '/skydive';
|
||||
constructor(
|
||||
private apiService: ApiService
|
||||
) { }
|
||||
|
||||
query(config: JumpListConfig): Observable<JumpList> {
|
||||
// Convert any filters over to Angular's URLSearchParams
|
||||
@@ -49,13 +57,14 @@ export class JumpsService {
|
||||
*/
|
||||
const params: JumpListFilters = {} as JumpListFilters;
|
||||
Object.assign(params, config.filters);
|
||||
return this.apiService
|
||||
.get(
|
||||
`${this._apiDomain}/jumps`,
|
||||
new HttpParams({ fromObject: <{
|
||||
[param: string]: string | number | boolean | readonly (string | number | boolean)[];
|
||||
}>params })
|
||||
);
|
||||
return this.apiService.get(
|
||||
`${this._apiDomain}/jumps`,
|
||||
new HttpParams({ fromObject: <
|
||||
{
|
||||
[param: string]: string | number | boolean | readonly (string | number | boolean)[];
|
||||
}
|
||||
>params }),
|
||||
);
|
||||
}
|
||||
|
||||
get(slug: string): Observable<JumpPageData> {
|
||||
@@ -67,79 +76,98 @@ export class JumpsService {
|
||||
}
|
||||
|
||||
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>> {
|
||||
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>> {
|
||||
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>> {
|
||||
const params: JumpListFilters = {} as JumpListFilters;
|
||||
Object.assign(params, config.filters);
|
||||
return this.apiService.get(`${this._apiDomain}/jumps/allByDay`, new HttpParams({ fromObject: <{
|
||||
[param: string]: string | number | boolean | readonly (string | number | boolean)[];
|
||||
}>params }))
|
||||
.pipe(map(data => data.days));
|
||||
return this.apiService
|
||||
.get(
|
||||
`${this._apiDomain}/jumps/allByDay`,
|
||||
new HttpParams({ fromObject: <
|
||||
{
|
||||
[param: string]: string | number | boolean | readonly (string | number | boolean)[];
|
||||
}
|
||||
>params }),
|
||||
)
|
||||
.pipe(map((data) => data.days));
|
||||
}
|
||||
|
||||
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> {
|
||||
const params: JumpListFilters = {} as JumpListFilters;
|
||||
Object.assign(params, config.filters);
|
||||
return this.apiService.get(`${this._apiDomain}/jumps/allFromSkydiverIdApi`, new HttpParams({ fromObject: <{
|
||||
[param: string]: string | number | boolean | readonly (string | number | boolean)[];
|
||||
}>params }))
|
||||
.pipe(map(data => data.jumps));
|
||||
return this.apiService
|
||||
.get(
|
||||
`${this._apiDomain}/jumps/allFromSkydiverIdApi`,
|
||||
new HttpParams({ fromObject: <
|
||||
{
|
||||
[param: string]: string | number | boolean | readonly (string | number | boolean)[];
|
||||
}
|
||||
>params }),
|
||||
)
|
||||
.pipe(map((data) => data.jumps));
|
||||
}
|
||||
|
||||
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> {
|
||||
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> {
|
||||
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> {
|
||||
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> {
|
||||
// If we're updating an existing jump
|
||||
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
|
||||
} 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> {
|
||||
return this.apiService.post(`${this._apiDomain}/jumps/data/${slug}`, { file: file, data: data })
|
||||
.pipe(map(data => data.jump));
|
||||
return this.apiService
|
||||
.post(`${this._apiDomain}/jumps/data/${slug}`, { file: file, data: data })
|
||||
.pipe(map((data) => data.jump));
|
||||
}
|
||||
|
||||
saveFile(slug: string, file: JumpFile): Observable<JumpFile> {
|
||||
return this.apiService.post(`${this._apiDomain}/jumps/file/${slug}`, { file: file })
|
||||
.pipe(map(data => data.file));
|
||||
return this.apiService
|
||||
.post(`${this._apiDomain}/jumps/file/${slug}`, { file: file })
|
||||
.pipe(map((data) => data.file));
|
||||
}
|
||||
|
||||
saveKml(slug: string, file: JumpFile): Observable<JumpFile> {
|
||||
return this.apiService.post(`${this._apiDomain}/jumps/kml/${slug}`, { file: file })
|
||||
.pipe(map(data => data.file));
|
||||
return this.apiService
|
||||
.post(`${this._apiDomain}/jumps/kml/${slug}`, { file: file })
|
||||
.pipe(map((data) => data.file));
|
||||
}
|
||||
|
||||
getAeronefs() {
|
||||
@@ -163,5 +191,4 @@ export class JumpsService {
|
||||
]
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
@@ -7,22 +7,23 @@ import { Qcm, QcmCategory, QcmQuestion } from '@models';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class QcmService {
|
||||
private apiService = inject(ApiService);
|
||||
|
||||
private _apiDomain = '/skydive';
|
||||
constructor(
|
||||
private apiService: ApiService
|
||||
) { }
|
||||
|
||||
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> {
|
||||
return this.apiService.post(`${this._apiDomain}/qcm/choices`, { question: question })
|
||||
.pipe(map(data => data.question));
|
||||
return this.apiService
|
||||
.post(`${this._apiDomain}/qcm/choices`, { question: question })
|
||||
.pipe(map((data) => data.question));
|
||||
}
|
||||
|
||||
saveQuestions(category: object): Observable<QcmCategory> {
|
||||
return this.apiService.post(`${this._apiDomain}/qcm/questions`, { category: category })
|
||||
.pipe(map(data => data.category));
|
||||
return this.apiService
|
||||
.post(`${this._apiDomain}/qcm/questions`, { category: category })
|
||||
.pipe(map((data) => data.category));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Injectable, OnDestroy } from '@angular/core';
|
||||
import { HttpClient } from "@angular/common/http";
|
||||
import { Injectable, OnDestroy, inject } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable, BehaviorSubject, ReplaySubject, Subscription } from 'rxjs';
|
||||
import { distinctUntilChanged, take, tap } from 'rxjs/operators';
|
||||
|
||||
@@ -8,6 +8,9 @@ import { JwtService } from '@services';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class UserService implements OnDestroy {
|
||||
private readonly http = inject(HttpClient);
|
||||
private readonly jwtService = inject(JwtService);
|
||||
|
||||
private _subcriptions: Array<Subscription> = new Array<Subscription>();
|
||||
private _user: Subscription = new Subscription();
|
||||
private currentUserSubject = new BehaviorSubject<User>({} as User);
|
||||
@@ -16,12 +19,7 @@ export class UserService implements OnDestroy {
|
||||
private isAuthenticatedSubject = new ReplaySubject<boolean>(1);
|
||||
public isAuthenticated = this.isAuthenticatedSubject.asObservable();
|
||||
|
||||
|
||||
private _apiDomain = '/cms';
|
||||
constructor(
|
||||
private readonly http: HttpClient,
|
||||
private readonly jwtService: JwtService
|
||||
) { }
|
||||
|
||||
ngOnDestroy() {
|
||||
this._subcriptions.forEach((subscription: Subscription) => subscription.unsubscribe());
|
||||
@@ -32,10 +30,12 @@ export class UserService implements OnDestroy {
|
||||
populate() {
|
||||
// If JWT detected, attempt to get & store user's info
|
||||
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({
|
||||
next: (data) => this.setAuth(data.user),
|
||||
error: () => this.purgeAuth()
|
||||
error: () => this.purgeAuth(),
|
||||
});
|
||||
this._subcriptions.push(this._user);
|
||||
} else {
|
||||
@@ -62,9 +62,11 @@ export class UserService implements OnDestroy {
|
||||
this.isAuthenticatedSubject.next(false);
|
||||
}
|
||||
|
||||
attemptAuth(type: string, credentials?: { email: string; password: string; }): Observable<{ user: User }> {
|
||||
const route = (type === 'login') ? '/login' : '';
|
||||
const user$: Observable<{ user: User }> = this.http.post<{ user: User }>(`${this._apiDomain}/user${route}`, { user: credentials });
|
||||
attemptAuth(type: string, credentials?: { email: string; password: string }): Observable<{ user: User }> {
|
||||
const route = type === 'login' ? '/login' : '';
|
||||
const user$: Observable<{ user: User }> = this.http.post<{ user: User }>(`${this._apiDomain}/user${route}`, {
|
||||
user: credentials,
|
||||
});
|
||||
/*return user$.pipe(map(
|
||||
(data: any) => {
|
||||
this.setAuth(data.user);
|
||||
@@ -79,7 +81,7 @@ export class UserService implements OnDestroy {
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -90,5 +92,4 @@ export class UserService implements OnDestroy {
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Chart } from 'chart.js';
|
||||
import { Configuration } from 'ng-chartist';
|
||||
|
||||
import { BarConfig, CircleConfig, DoughnutConfig, LineConfig } from '@models';
|
||||
|
||||
@@ -9,7 +8,7 @@ export class UtilitiesService {
|
||||
private _coeffKgLbs: number = 2.20462;
|
||||
private _coeffFtM: number = 0.092903;
|
||||
|
||||
constructor() { }
|
||||
constructor() {}
|
||||
|
||||
getCoeffKgLbs(): number {
|
||||
return this._coeffKgLbs;
|
||||
@@ -19,19 +18,6 @@ export class UtilitiesService {
|
||||
return this._coeffFtM;
|
||||
}
|
||||
|
||||
getBarConfig(): Configuration {
|
||||
const config: Configuration = {
|
||||
type: 'Bar',
|
||||
data: {
|
||||
'labels': [],
|
||||
'series': []
|
||||
},
|
||||
options: {},
|
||||
responsiveOptions: []
|
||||
};
|
||||
return config;
|
||||
}
|
||||
|
||||
getChartColors(): string[] {
|
||||
const colors: string[] = [
|
||||
'ct-color-a',
|
||||
@@ -59,22 +45,19 @@ export class UtilitiesService {
|
||||
'ct-color-w',
|
||||
'ct-color-x',
|
||||
'ct-color-y',
|
||||
'ct-color-z'
|
||||
'ct-color-z',
|
||||
];
|
||||
return colors;
|
||||
}
|
||||
|
||||
getCurrentDateFr(): string {
|
||||
return new Date().toLocaleDateString('fr');
|
||||
return new Date().toLocaleDateString('fr');
|
||||
}
|
||||
|
||||
|
||||
secondsToDuration(seconds: number, delimiter: string = ':'): string {
|
||||
return [
|
||||
Math.floor(seconds / 60 / 60),
|
||||
Math.floor(seconds / 60 % 60),
|
||||
Math.floor(seconds % 60)
|
||||
].join(delimiter)
|
||||
.replace(/\b(\d)\b/g, "0$1")//.replace(/^00\:/, '')
|
||||
return [Math.floor(seconds / 60 / 60), Math.floor((seconds / 60) % 60), 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[] {
|
||||
@@ -101,7 +84,7 @@ export class UtilitiesService {
|
||||
`rgba(143, 202, 202, ${opacity})`,
|
||||
`rgba(204, 226, 203, ${opacity})`,
|
||||
`rgba(182, 207, 182, ${opacity})`,
|
||||
`rgba(151, 193, 169, ${opacity})`
|
||||
`rgba(151, 193, 169, ${opacity})`,
|
||||
];
|
||||
break;
|
||||
case 'red':
|
||||
@@ -114,7 +97,7 @@ export class UtilitiesService {
|
||||
`rgba(228, 145, 122, ${opacity})`,
|
||||
`rgba(238, 168, 148, ${opacity})`,
|
||||
`rgba(247, 192, 175, ${opacity})`,
|
||||
`rgba(255, 215, 203, ${opacity})`
|
||||
`rgba(255, 215, 203, ${opacity})`,
|
||||
];
|
||||
break;
|
||||
case 'green':
|
||||
@@ -127,7 +110,7 @@ export class UtilitiesService {
|
||||
`rgba(134, 187, 142, ${opacity})`,
|
||||
`rgba(156, 203, 163, ${opacity})`,
|
||||
`rgba(179, 219, 184, ${opacity})`,
|
||||
`rgba(201, 235, 205, ${opacity})`
|
||||
`rgba(201, 235, 205, ${opacity})`,
|
||||
];
|
||||
break;
|
||||
case 'blue':
|
||||
@@ -140,7 +123,7 @@ export class UtilitiesService {
|
||||
`rgba(127, 170, 198, ${opacity})`,
|
||||
`rgba(148, 190, 217, ${opacity})`,
|
||||
`rgba(171, 210, 236, ${opacity})`,
|
||||
`rgba(193, 231, 255, ${opacity})`
|
||||
`rgba(193, 231, 255, ${opacity})`,
|
||||
];
|
||||
break;
|
||||
case 'all':
|
||||
@@ -197,7 +180,7 @@ export class UtilitiesService {
|
||||
`rgba(217, 202, 174, ${opacity})`,
|
||||
`rgba(151, 136, 199, ${opacity})`,
|
||||
`rgba(212, 206, 112, ${opacity})`,
|
||||
`rgba(255, 255, 255, ${opacity})`
|
||||
`rgba(255, 255, 255, ${opacity})`,
|
||||
];
|
||||
if (offset > 0 && offset < colors.length) {
|
||||
colors = colors.slice(offset);
|
||||
@@ -216,8 +199,8 @@ export class UtilitiesService {
|
||||
label: 'Nombre total de sauts',
|
||||
backgroundColor: this.getSeriesColors(0.8),
|
||||
borderColor: this.getSeriesColors(1), // 'rgba(255, 255, 255, 1)'
|
||||
borderWidth: 2
|
||||
}
|
||||
borderWidth: 2,
|
||||
},
|
||||
],
|
||||
circleChartOptions: {
|
||||
cutout: '90%',
|
||||
@@ -226,25 +209,27 @@ export class UtilitiesService {
|
||||
//spacing: -10,
|
||||
borderJoinStyle: 'round',
|
||||
borderRadius: 10,
|
||||
borderWidth: 0
|
||||
}
|
||||
borderWidth: 0,
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false,
|
||||
position: 'left'
|
||||
}
|
||||
position: 'left',
|
||||
},
|
||||
},
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
animation: {
|
||||
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 diff: number = parseInt(this.data.datasets[0].data[1]!.toString());
|
||||
const total: number = (count + diff);
|
||||
const percent: number = Math.round((count/total*100));
|
||||
const lineHeight = (height / 8);
|
||||
const total: number = count + diff;
|
||||
const percent: number = Math.round((count / total) * 100);
|
||||
const lineHeight = height / 8;
|
||||
ctx.restore();
|
||||
let fontSize = (height / 120).toFixed(2);
|
||||
ctx.font = `${fontSize}em sans-serif`;
|
||||
@@ -255,7 +240,7 @@ export class UtilitiesService {
|
||||
let text = this.data.datasets[0].label!;
|
||||
let textX = Math.round((width - ctx.measureText(text).width) / 2);
|
||||
let textY = height / 2;
|
||||
ctx.fillText(text, textX, (textY-lineHeight));
|
||||
ctx.fillText(text, textX, textY - lineHeight);
|
||||
text = `${percent}%`;
|
||||
textX = Math.round((width - ctx.measureText(text).width) / 2);
|
||||
textY = height / 2;
|
||||
@@ -269,17 +254,19 @@ export class UtilitiesService {
|
||||
text = `${count} / ${total}`;
|
||||
textX = Math.round((width - ctx.measureText(text).width) / 2);
|
||||
textY = height / 2;
|
||||
ctx.fillText(text, textX, (textY+lineHeight));
|
||||
ctx.fillText(text, textX, textY + lineHeight);
|
||||
ctx.save();
|
||||
//console.log(width, height, fontSize);
|
||||
},
|
||||
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 diff: number = parseInt(this.data.datasets[0].data[1]!.toString());
|
||||
const total: number = (count + diff);
|
||||
const percent: number = Math.round((count/total*100));
|
||||
const lineHeight = (height / 8);
|
||||
const total: number = count + diff;
|
||||
const percent: number = Math.round((count / total) * 100);
|
||||
const lineHeight = height / 8;
|
||||
ctx.restore();
|
||||
let fontSize = (height / 120).toFixed(2);
|
||||
ctx.font = `${fontSize}em sans-serif`;
|
||||
@@ -291,7 +278,7 @@ export class UtilitiesService {
|
||||
let text = this.data.datasets[0].label!;
|
||||
let textX = Math.round((width - ctx.measureText(text).width) / 2);
|
||||
let textY = height / 2;
|
||||
ctx.fillText(text, textX, (textY-lineHeight));
|
||||
ctx.fillText(text, textX, textY - lineHeight);
|
||||
text = `${percent}%`;
|
||||
textX = Math.round((width - ctx.measureText(text).width) / 2);
|
||||
textY = height / 2;
|
||||
@@ -305,7 +292,7 @@ export class UtilitiesService {
|
||||
text = `${count} / ${total}`;
|
||||
textX = Math.round((width - ctx.measureText(text).width) / 2);
|
||||
textY = height / 2;
|
||||
ctx.fillText(text, textX, (textY+lineHeight));
|
||||
ctx.fillText(text, textX, textY + lineHeight);
|
||||
ctx.save();
|
||||
//console.log(width, height, fontSize);
|
||||
},
|
||||
@@ -321,22 +308,26 @@ export class UtilitiesService {
|
||||
id: 'beforeinit'
|
||||
},*/
|
||||
{
|
||||
beforeDatasetDraw: (chart: Chart<"doughnut", number[], unknown>) => {
|
||||
const width = chart.width, height = chart.height, ctx = chart.ctx;
|
||||
beforeDatasetDraw: (chart: Chart<'doughnut', number[], unknown>) => {
|
||||
const width = chart.width,
|
||||
height = chart.height,
|
||||
ctx = chart.ctx;
|
||||
ctx.restore();
|
||||
const fontSize = (height / 150).toFixed(2);
|
||||
ctx.font = fontSize + "em sans-serif";
|
||||
ctx.fillStyle = "#ffffff";
|
||||
ctx.textBaseline = "middle";
|
||||
const text = chart.data.datasets[0].data[0] + "%", textX = Math.round((width - ctx.measureText(text).width) / 2), textY = height / 2;
|
||||
ctx.font = fontSize + 'em sans-serif';
|
||||
ctx.fillStyle = '#ffffff';
|
||||
ctx.textBaseline = 'middle';
|
||||
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.save();
|
||||
console.log(width, height, fontSize);
|
||||
},
|
||||
id: 'doughnutlabel'
|
||||
}
|
||||
id: 'doughnutlabel',
|
||||
},
|
||||
],
|
||||
circleChartLegend: false
|
||||
circleChartLegend: false,
|
||||
};
|
||||
return config;
|
||||
}
|
||||
@@ -350,25 +341,25 @@ export class UtilitiesService {
|
||||
label: 'Nombre total de sauts',
|
||||
backgroundColor: this.getSeriesColors(0.8),
|
||||
borderColor: this.getSeriesColors(1), // 'rgba(255, 255, 255, 1)'
|
||||
borderWidth: 2
|
||||
}
|
||||
borderWidth: 2,
|
||||
},
|
||||
],
|
||||
doughnutChartOptions: {
|
||||
elements: {
|
||||
arc: {
|
||||
borderWidth: 2,
|
||||
}
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
display: true,
|
||||
position: 'left'
|
||||
}
|
||||
position: 'left',
|
||||
},
|
||||
},
|
||||
responsive: true,
|
||||
maintainAspectRatio: false
|
||||
maintainAspectRatio: false,
|
||||
},
|
||||
doughnutChartLegend: false
|
||||
doughnutChartLegend: false,
|
||||
};
|
||||
return config;
|
||||
}
|
||||
@@ -377,19 +368,19 @@ export class UtilitiesService {
|
||||
const config: BarConfig = {
|
||||
barChartData: {
|
||||
labels: [''],
|
||||
datasets: []
|
||||
datasets: [],
|
||||
},
|
||||
barChartOptions: {
|
||||
plugins: {
|
||||
legend: {
|
||||
display: true,
|
||||
position: 'top'
|
||||
}
|
||||
position: 'top',
|
||||
},
|
||||
},
|
||||
elements: {
|
||||
bar: {
|
||||
borderWidth: 1,
|
||||
}
|
||||
},
|
||||
},
|
||||
/*interaction: {
|
||||
intersect: false,
|
||||
@@ -400,20 +391,30 @@ export class UtilitiesService {
|
||||
display: false,
|
||||
beginAtZero: true,
|
||||
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: {
|
||||
display: true,
|
||||
beginAtZero: true,
|
||||
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,
|
||||
maintainAspectRatio: false
|
||||
maintainAspectRatio: false,
|
||||
},
|
||||
barChartPlugins: [],
|
||||
barChartLegend: true
|
||||
barChartLegend: true,
|
||||
};
|
||||
return config;
|
||||
}
|
||||
@@ -422,24 +423,24 @@ export class UtilitiesService {
|
||||
const config: BarConfig = {
|
||||
barChartData: {
|
||||
labels: [''],
|
||||
datasets: []
|
||||
datasets: [],
|
||||
},
|
||||
barChartOptions: {
|
||||
indexAxis: 'y',
|
||||
elements: {
|
||||
bar: {
|
||||
borderWidth: 1,
|
||||
}
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
display: true,
|
||||
position: 'left'
|
||||
position: 'left',
|
||||
},
|
||||
title: {
|
||||
display: false,
|
||||
text: 'Nombre total de sauts'
|
||||
}
|
||||
text: 'Nombre total de sauts',
|
||||
},
|
||||
},
|
||||
responsive: true,
|
||||
aspectRatio: 3,
|
||||
@@ -447,17 +448,17 @@ export class UtilitiesService {
|
||||
x: {
|
||||
beginAtZero: true,
|
||||
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: {
|
||||
beginAtZero: true,
|
||||
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: [],
|
||||
barChartLegend: false
|
||||
barChartLegend: false,
|
||||
};
|
||||
return config;
|
||||
}
|
||||
@@ -466,14 +467,14 @@ export class UtilitiesService {
|
||||
const config: LineConfig = {
|
||||
lineChartData: {
|
||||
labels: [],
|
||||
datasets: []
|
||||
datasets: [],
|
||||
},
|
||||
lineChartOptions: {
|
||||
plugins: {
|
||||
legend: {
|
||||
display: true,
|
||||
position: 'top'
|
||||
}
|
||||
position: 'top',
|
||||
},
|
||||
},
|
||||
/*interaction: {
|
||||
intersect: false,
|
||||
@@ -484,64 +485,87 @@ export class UtilitiesService {
|
||||
display: true,
|
||||
beginAtZero: true,
|
||||
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: {
|
||||
display: true,
|
||||
beginAtZero: true,
|
||||
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,
|
||||
maintainAspectRatio: false
|
||||
maintainAspectRatio: false,
|
||||
},
|
||||
lineChartLegend: true
|
||||
lineChartLegend: true,
|
||||
};
|
||||
return config;
|
||||
}
|
||||
|
||||
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 {
|
||||
const config: LineConfig = {
|
||||
lineChartData: {
|
||||
labels: [],
|
||||
datasets: []
|
||||
datasets: [],
|
||||
},
|
||||
lineChartOptions: {
|
||||
plugins: {
|
||||
legend: {
|
||||
display: true,
|
||||
position: 'top'
|
||||
}
|
||||
position: 'top',
|
||||
},
|
||||
},
|
||||
interaction: {
|
||||
mode: 'nearest',
|
||||
axis: 'x',
|
||||
intersect: false
|
||||
intersect: false,
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
display: true,
|
||||
beginAtZero: true,
|
||||
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: {
|
||||
display: true,
|
||||
beginAtZero: true,
|
||||
stacked: true,
|
||||
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,
|
||||
maintainAspectRatio: false
|
||||
maintainAspectRatio: false,
|
||||
},
|
||||
lineChartLegend: true
|
||||
lineChartLegend: true,
|
||||
};
|
||||
return config;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user