diff --git a/client/app/admin/accounting-documents/accounting-documents.component.ts b/client/app/admin/accounting-documents/accounting-documents.component.ts index cd42992c8..0f44a463b 100644 --- a/client/app/admin/accounting-documents/accounting-documents.component.ts +++ b/client/app/admin/accounting-documents/accounting-documents.component.ts @@ -1,4 +1,4 @@ -import {Component, Input, OnInit} from '@angular/core'; +import {Component, Input, OnInit, inject} from '@angular/core'; import { AccountingDocumentInput, ExpenseClaim, @@ -21,6 +21,8 @@ import {MatButtonModule} from '@angular/material/button'; imports: [NaturalFileComponent, MatButtonModule, MatIconModule, NaturalIconDirective], }) export class AccountingDocumentsComponent implements OnInit { + public readonly accountingDocumentService = inject(AccountingDocumentService); + @Input({required: true}) public model!: | Transaction['transaction'] | ExpenseClaim['expenseClaim'] @@ -52,8 +54,6 @@ export class AccountingDocumentsComponent implements OnInit { private readonly removedFiles: WithId[] = []; private _disabled = false; - public constructor(public readonly accountingDocumentService: AccountingDocumentService) {} - public ngOnInit(): void { if ('accountingDocuments' in this.model) { this.files = [...this.model.accountingDocuments]; diff --git a/client/app/admin/accounts/account/account.component.ts b/client/app/admin/accounts/account/account.component.ts index 51ee334ff..8b2eb0d35 100644 --- a/client/app/admin/accounts/account/account.component.ts +++ b/client/app/admin/accounts/account/account.component.ts @@ -1,4 +1,4 @@ -import {Component, OnInit} from '@angular/core'; +import {Component, OnInit, inject} from '@angular/core'; import { NaturalAbstractDetail, NaturalDetailHeaderComponent, @@ -59,15 +59,18 @@ import {takeUntilDestroyed} from '@angular/core/rxjs-interop'; ], }) export class AccountComponent extends NaturalAbstractDetail implements OnInit { + public readonly accountService: AccountService; + public readonly userService = inject(UserService); + public nextCodeAvailable: number | null = null; public accountHierarchicConfig = groupAccountHierarchicConfiguration; public readonly AccountType = AccountType; - public constructor( - public readonly accountService: AccountService, - public readonly userService: UserService, - ) { + public constructor() { + const accountService = inject(AccountService); + super('account', accountService); + this.accountService = accountService; } public override ngOnInit(): void { diff --git a/client/app/admin/accounts/accounts/accounts.component.ts b/client/app/admin/accounts/accounts/accounts.component.ts index f7b37ef1f..7b9144b11 100644 --- a/client/app/admin/accounts/accounts/accounts.component.ts +++ b/client/app/admin/accounts/accounts/accounts.component.ts @@ -1,4 +1,4 @@ -import {Component, OnInit} from '@angular/core'; +import {Component, OnInit, inject} from '@angular/core'; import { AvailableColumn, Button, @@ -66,6 +66,12 @@ type AccountingExportDialogResult = { ], }) export class AccountsComponent extends NaturalAbstractNavigableList implements OnInit { + private readonly accountService: AccountService; + private readonly dialog = inject(MatDialog); + public readonly permissionsService = inject(PermissionsService); + public readonly transactionLineService = inject(TransactionLineService); + public readonly userService = inject(UserService); + public override availableColumns: AvailableColumn[] = [ {id: 'navigation', label: 'Navigation'}, {id: 'code', label: 'Code'}, @@ -107,15 +113,13 @@ export class AccountsComponent extends NaturalAbstractNavigableList { if (!(e instanceof NavigationEnd)) { diff --git a/client/app/admin/bookable-metadata/bookable-metadata.component.ts b/client/app/admin/bookable-metadata/bookable-metadata.component.ts index 905fff6b1..71a5e1afd 100644 --- a/client/app/admin/bookable-metadata/bookable-metadata.component.ts +++ b/client/app/admin/bookable-metadata/bookable-metadata.component.ts @@ -1,4 +1,4 @@ -import {Component, Input, OnInit} from '@angular/core'; +import {Component, Input, OnInit, inject} from '@angular/core'; import {BookableMetadataService} from './bookable-metadata.service'; import { NaturalAlertService, @@ -32,6 +32,9 @@ import {MatTableModule} from '@angular/material/table'; ], }) export class BookableMetadataComponent implements OnInit { + private readonly bookableMetaService = inject(BookableMetadataService); + private readonly alertService = inject(NaturalAlertService); + @Input({required: true}) public bookable!: Bookable['bookable']; @Input() public edit = false; public readonly deleting = new Map(); @@ -40,11 +43,6 @@ export class BookableMetadataComponent implements OnInit { public columns: string[] = []; - public constructor( - private readonly bookableMetaService: BookableMetadataService, - private readonly alertService: NaturalAlertService, - ) {} - public ngOnInit(): void { if (this.edit) { this.columns = ['name', 'value', 'delete']; diff --git a/client/app/admin/bookableTags/bookableTag/bookableTag.component.ts b/client/app/admin/bookableTags/bookableTag/bookableTag.component.ts index f7b1e9081..e17f7a86b 100644 --- a/client/app/admin/bookableTags/bookableTag/bookableTag.component.ts +++ b/client/app/admin/bookableTags/bookableTag/bookableTag.component.ts @@ -1,4 +1,4 @@ -import {Component} from '@angular/core'; +import {Component, inject} from '@angular/core'; import { NaturalAbstractDetail, NaturalDetailHeaderComponent, @@ -33,7 +33,9 @@ import {MatDividerModule} from '@angular/material/divider'; ], }) export class BookableTagComponent extends NaturalAbstractDetail { - public constructor(bookableTagService: BookableTagService) { + public constructor() { + const bookableTagService = inject(BookableTagService); + super('bookableTag', bookableTagService); } } diff --git a/client/app/admin/bookableTags/bookableTags/bookableTags.component.ts b/client/app/admin/bookableTags/bookableTags/bookableTags.component.ts index df3bb82c4..2f3bf6e87 100644 --- a/client/app/admin/bookableTags/bookableTags/bookableTags.component.ts +++ b/client/app/admin/bookableTags/bookableTags/bookableTags.component.ts @@ -1,4 +1,4 @@ -import {Component, OnInit} from '@angular/core'; +import {Component, OnInit, inject} from '@angular/core'; import { AvailableColumn, NaturalAbstractList, @@ -39,14 +39,15 @@ import {AsyncPipe} from '@angular/common'; ], }) export class BookableTagsComponent extends NaturalAbstractList implements OnInit { + public readonly permissionsService = inject(PermissionsService); + public override availableColumns: AvailableColumn[] = [ {id: 'color', label: 'Couleur'}, {id: 'name', label: 'Nom'}, ]; - public constructor( - bookableTagService: BookableTagService, - public readonly permissionsService: PermissionsService, - ) { + public constructor() { + const bookableTagService = inject(BookableTagService); + super(bookableTagService); } } diff --git a/client/app/admin/bookables/application-confirm/application-confirm.component.ts b/client/app/admin/bookables/application-confirm/application-confirm.component.ts index e2b813e6b..d70743228 100644 --- a/client/app/admin/bookables/application-confirm/application-confirm.component.ts +++ b/client/app/admin/bookables/application-confirm/application-confirm.component.ts @@ -1,5 +1,5 @@ -import {Component, Inject} from '@angular/core'; -import {MatDialogRef, MAT_DIALOG_DATA, MatDialogModule} from '@angular/material/dialog'; +import {Component, inject} from '@angular/core'; +import {MAT_DIALOG_DATA, MatDialogModule} from '@angular/material/dialog'; import {MatButton} from '@angular/material/button'; import {FormControl, ReactiveFormsModule, Validators} from '@angular/forms'; import {MatError, MatFormField, MatHint, MatLabel, MatSuffix} from '@angular/material/form-field'; @@ -7,7 +7,6 @@ import {MatDatepicker, MatDatepickerInput, MatDatepickerToggle} from '@angular/m import {MatInput} from '@angular/material/input'; import {ApplicationConfirmData} from '../bookables/parent.component'; import {UsersVariables} from '../../../shared/generated-types'; -import {ActivatedRoute} from '@angular/router'; import {UserService} from '../../users/services/user.service'; import {NaturalQueryVariablesManager} from '@ecodev/natural'; import {MatOption, MatSelect} from '@angular/material/select'; @@ -35,15 +34,15 @@ import {MatOption, MatSelect} from '@angular/material/select'; }) // This dialog is only displayed when the user submits an application for a COURSE export class ApplicationConfirmComponent { + private readonly userService = inject(UserService); + private readonly futureOwner = inject(MAT_DIALOG_DATA); + public readonly participant = new FormControl(null, [Validators.required]); public familyMembers: string[] = []; - public constructor( - private readonly route: ActivatedRoute, - private readonly userService: UserService, - public dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) private readonly futureOwner: ApplicationConfirmData, - ) { + public constructor() { + const futureOwner = this.futureOwner; + if (futureOwner) { // Populate the select menu with his/her family members const qvm = new NaturalQueryVariablesManager(); diff --git a/client/app/admin/bookables/bookable/bookable.component.ts b/client/app/admin/bookables/bookable/bookable.component.ts index 9fd18c0d1..9599fb4aa 100644 --- a/client/app/admin/bookables/bookable/bookable.component.ts +++ b/client/app/admin/bookables/bookable/bookable.component.ts @@ -1,4 +1,4 @@ -import {Component, OnInit} from '@angular/core'; +import {Component, OnInit, inject} from '@angular/core'; import { formatIsoDateTime, IEnum, @@ -84,6 +84,11 @@ import {takeUntilDestroyed} from '@angular/core/rxjs-interop'; ], }) export class BookableComponent extends NaturalAbstractDetail implements OnInit { + public readonly bookableTagService = inject(BookableTagService); + public readonly licenseService = inject(LicenseService); + private readonly imageService = inject(ImageService); + public readonly permissionsService = inject(PermissionsService); + public accountHierarchicConfig = accountHierarchicConfiguration; public bookingsVariables: BookingsVariables = {}; public viewer!: NonNullable; @@ -91,13 +96,9 @@ export class BookableComponent extends NaturalAbstractDetail implements OnInit { + public readonly permissionsService = inject(PermissionsService); + @Output() public readonly bookableClick = new EventEmitter(); - public constructor( - bookableService: BookableService, - naturalSearchFacetsService: NaturalSearchFacetsService, - public readonly permissionsService: PermissionsService, - dialog: MatDialog, - snackbar: MatSnackBar, - bookingService: BookingService, - ) { + public constructor() { + const bookableService = inject(BookableService); + const naturalSearchFacetsService = inject(NaturalSearchFacetsService); + const dialog = inject(MatDialog); + const snackbar = inject(MatSnackBar); + const bookingService = inject(BookingService); + super(bookableService, dialog, snackbar, bookingService); this.naturalSearchFacets = naturalSearchFacetsService.get( this.route.snapshot.data.isEquipment ? 'equipment' : 'bookables', diff --git a/client/app/admin/bookables/bookables/usage-bookables.component.ts b/client/app/admin/bookables/bookables/usage-bookables.component.ts index 6eb7d9883..90ec6b984 100644 --- a/client/app/admin/bookables/bookables/usage-bookables.component.ts +++ b/client/app/admin/bookables/bookables/usage-bookables.component.ts @@ -1,4 +1,4 @@ -import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; +import {Component, EventEmitter, Input, OnInit, Output, inject} from '@angular/core'; import {NaturalSearchFacetsService} from '../../../shared/natural-search/natural-search-facets.service'; import {PermissionsService} from '../../../shared/services/permissions.service'; import {UsageBookableService} from '../services/usage-bookable.service'; @@ -55,6 +55,9 @@ import {takeUntilDestroyed} from '@angular/core/rxjs-interop'; ], }) export class UsageBookablesComponent extends ParentComponent implements OnInit { + public readonly permissionsService = inject(PermissionsService); + private readonly userService = inject(UserService); + @Output() public readonly bookableClick = new EventEmitter(); @Input() @@ -68,15 +71,13 @@ export class UsageBookablesComponent extends ParentComponent { + private readonly bookingService = inject(BookingService); + public static readonly membershipServices: BookablesVariables = { filter: { groups: [ @@ -98,7 +100,7 @@ export class BookableService extends NaturalAbstractModelService< filter: {groups: [{conditions: [{bookingType: {in: {values: [BookingType.Application]}}}]}]}, }; - public constructor(private readonly bookingService: BookingService) { + public constructor() { super('bookable', bookableQuery, bookablesQuery, createBookable, updateBookable, deleteBookables); } diff --git a/client/app/admin/bookables/services/usage-bookable.service.ts b/client/app/admin/bookables/services/usage-bookable.service.ts index 103ac21f1..071ebe1c1 100644 --- a/client/app/admin/bookables/services/usage-bookable.service.ts +++ b/client/app/admin/bookables/services/usage-bookable.service.ts @@ -1,4 +1,4 @@ -import {Injectable} from '@angular/core'; +import {Injectable, inject} from '@angular/core'; import {bookableQuery, createBookable, deleteBookables, updateBookable, usageBookablesQuery} from './bookable.queries'; import { Bookable, @@ -33,7 +33,9 @@ export class UsageBookableService extends NaturalAbstractModelService< DeleteBookables, DeleteBookablesVariables > { - public constructor(protected readonly bookingService: BookingService) { + protected readonly bookingService = inject(BookingService); + + public constructor() { super('bookable', bookableQuery, usageBookablesQuery, createBookable, updateBookable, deleteBookables); } diff --git a/client/app/admin/bookings/booking/booking.component.ts b/client/app/admin/bookings/booking/booking.component.ts index a28739097..37aeaaa55 100644 --- a/client/app/admin/bookings/booking/booking.component.ts +++ b/client/app/admin/bookings/booking/booking.component.ts @@ -1,4 +1,4 @@ -import {Component, OnInit} from '@angular/core'; +import {Component, OnInit, inject} from '@angular/core'; import {BookingService} from '../services/booking.service'; import { BookableSortingField, @@ -75,6 +75,10 @@ import {FormsModule, ReactiveFormsModule} from '@angular/forms'; ], }) export class BookingComponent extends NaturalAbstractDetail implements OnInit { + public readonly bookingService: BookingService; + public readonly bookableService = inject(BookableService); + public readonly userService = inject(UserService); + public BookingStatus = BookingStatus; public suggestionVariables: BookablesVariables = {}; public suggestionSelection: NaturalSearchSelections = [[]]; @@ -117,12 +121,11 @@ export class BookingComponent extends NaturalAbstractDetail { + public readonly permissionsService = inject(PermissionsService); + private readonly copyContactDataButtonService = + inject>(CopyContactDataButtonService); + public override readonly buttons: Button[] = this.copyContactDataButtonService.getButtons( this.variablesManager, 'bookingsWithOwnerContact', ); - public constructor( - bookingWithOwnerService: BookingWithOwnerService, - naturalSearchFacetsService: NaturalSearchFacetsService, - public readonly permissionsService: PermissionsService, - private readonly copyContactDataButtonService: CopyContactDataButtonService, - ) { + public constructor() { + const bookingWithOwnerService = inject(BookingWithOwnerService); + const naturalSearchFacetsService = inject(NaturalSearchFacetsService); + super(bookingWithOwnerService); this.naturalSearchFacets = naturalSearchFacetsService.get('bookingsForBookable'); } diff --git a/client/app/admin/bookings/bookings/bookings.component.ts b/client/app/admin/bookings/bookings/bookings.component.ts index ea906765a..dfee416e1 100644 --- a/client/app/admin/bookings/bookings/bookings.component.ts +++ b/client/app/admin/bookings/bookings/bookings.component.ts @@ -1,4 +1,4 @@ -import {Component} from '@angular/core'; +import {Component, inject} from '@angular/core'; import {BookingService} from '../services/booking.service'; import {NaturalSearchFacetsService} from '../../../shared/natural-search/natural-search-facets.service'; import {PermissionsService} from '../../../shared/services/permissions.service'; @@ -56,11 +56,12 @@ import {CommonModule, DatePipe} from '@angular/common'; ], }) export class BookingsComponent extends AbstractBookings { - public constructor( - bookingService: BookingService, - naturalSearchFacetsService: NaturalSearchFacetsService, - public readonly permissionsService: PermissionsService, - ) { + public readonly permissionsService = inject(PermissionsService); + + public constructor() { + const bookingService = inject(BookingService); + const naturalSearchFacetsService = inject(NaturalSearchFacetsService); + super(bookingService); this.naturalSearchFacets = naturalSearchFacetsService.get( this.route.snapshot.data.advancedFacets ? 'bookingsAdvanced' : 'bookings', diff --git a/client/app/admin/bookings/services/booking-with-owner.service.ts b/client/app/admin/bookings/services/booking-with-owner.service.ts index 89298f3ce..6a2896c6a 100644 --- a/client/app/admin/bookings/services/booking-with-owner.service.ts +++ b/client/app/admin/bookings/services/booking-with-owner.service.ts @@ -1,4 +1,4 @@ -import {Injectable} from '@angular/core'; +import {Injectable, inject} from '@angular/core'; import { bookingQuery, bookingsWithOwnerBalanceQuery, @@ -37,7 +37,9 @@ export class BookingWithOwnerService extends NaturalAbstractModelService< DeleteBookings, DeleteBookingsVariables > { - public constructor(private readonly bookingService: BookingService) { + private readonly bookingService = inject(BookingService); + + public constructor() { super('booking', bookingQuery, bookingsWithOwnerBalanceQuery, createBooking, updateBooking, deleteBookings); } diff --git a/client/app/admin/configurations/services/configuration.service.ts b/client/app/admin/configurations/services/configuration.service.ts index 8f8277774..e15a7b25e 100644 --- a/client/app/admin/configurations/services/configuration.service.ts +++ b/client/app/admin/configurations/services/configuration.service.ts @@ -1,6 +1,6 @@ import {Apollo} from 'apollo-angular'; import {NetworkStatus} from '@apollo/client/core'; -import {Injectable} from '@angular/core'; +import {Injectable, inject} from '@angular/core'; import {Observable} from 'rxjs'; import {distinctUntilChanged, filter, map, takeWhile} from 'rxjs/operators'; import { @@ -15,7 +15,7 @@ import {configurationQuery, updateConfiguration} from './configuration.queries'; providedIn: 'root', }) export class ConfigurationService { - public constructor(private readonly apollo: Apollo) {} + private readonly apollo = inject(Apollo); public get(key: string): Observable { const queryRef = this.apollo.watchQuery({ diff --git a/client/app/admin/configurations/support/support.component.ts b/client/app/admin/configurations/support/support.component.ts index dd6472481..02ae0f09c 100644 --- a/client/app/admin/configurations/support/support.component.ts +++ b/client/app/admin/configurations/support/support.component.ts @@ -1,4 +1,4 @@ -import {Component, DestroyRef, Inject, inject, OnInit, Optional} from '@angular/core'; +import {Component, DestroyRef, inject, OnInit} from '@angular/core'; import {MAT_DIALOG_DATA, MatDialogModule} from '@angular/material/dialog'; import {ActivatedRoute} from '@angular/router'; import {PermissionsService} from '../../../shared/services/permissions.service'; @@ -35,6 +35,14 @@ export type SupportComponentData = { ], }) export class SupportComponent implements OnInit { + private readonly configurationService = inject(ConfigurationService); + public readonly permissionsService = inject(PermissionsService); + public readonly route = inject(ActivatedRoute); + private readonly alertService = inject(NaturalAlertService); + public readonly data? = inject>(MAT_DIALOG_DATA, { + optional: true, + }); + private readonly destroyRef = inject(DestroyRef); public text = ''; @@ -51,16 +59,6 @@ export class SupportComponent implements OnInit { public activable = false; public updating = false; - public constructor( - private readonly configurationService: ConfigurationService, - public readonly permissionsService: PermissionsService, - public readonly route: ActivatedRoute, - private readonly alertService: NaturalAlertService, - @Optional() - @Inject(MAT_DIALOG_DATA) - public readonly data?: NaturalDialogTriggerProvidedData, - ) {} - public ngOnInit(): void { this.readonly = this.route.snapshot.data.readonly || this.data?.data?.readonly; this.configurationService diff --git a/client/app/admin/expenseClaim/expenseClaim/expenseClaim.component.ts b/client/app/admin/expenseClaim/expenseClaim/expenseClaim.component.ts index 2b0b80a62..9688c650a 100644 --- a/client/app/admin/expenseClaim/expenseClaim/expenseClaim.component.ts +++ b/client/app/admin/expenseClaim/expenseClaim/expenseClaim.component.ts @@ -1,4 +1,4 @@ -import {Component, OnInit} from '@angular/core'; +import {Component, OnInit, inject} from '@angular/core'; import { NaturalAbstractDetail, NaturalDetailHeaderComponent, @@ -62,17 +62,20 @@ export class ExpenseClaimComponent extends NaturalAbstractDetail implements OnInit { + public readonly expenseClaimService: ExpenseClaimService; + public readonly userService = inject(UserService); + public readonly transactionLineService = inject(TransactionLineService); + public readonly permissionsService = inject(PermissionsService); + public ExpenseClaimType = ExpenseClaimType; public ExpenseClaimStatus = ExpenseClaimStatus; public viewer!: NonNullable; - public constructor( - public readonly expenseClaimService: ExpenseClaimService, - public readonly userService: UserService, - public readonly transactionLineService: TransactionLineService, - public readonly permissionsService: PermissionsService, - ) { + public constructor() { + const expenseClaimService = inject(ExpenseClaimService); + super('expenseClaim', expenseClaimService); + this.expenseClaimService = expenseClaimService; } public override ngOnInit(): void { diff --git a/client/app/admin/expenseClaim/expenseClaims/expenseClaims.component.ts b/client/app/admin/expenseClaim/expenseClaims/expenseClaims.component.ts index 956b5d118..b717fb57a 100644 --- a/client/app/admin/expenseClaim/expenseClaims/expenseClaims.component.ts +++ b/client/app/admin/expenseClaim/expenseClaims/expenseClaims.component.ts @@ -1,4 +1,4 @@ -import {Component, OnInit} from '@angular/core'; +import {Component, OnInit, inject} from '@angular/core'; import { AvailableColumn, NaturalAbstractList, @@ -51,6 +51,8 @@ import {MatTableModule} from '@angular/material/table'; ], }) export class ExpenseClaimsComponent extends NaturalAbstractList implements OnInit { + public readonly permissionsService = inject(PermissionsService); + public override availableColumns: AvailableColumn[] = [ {id: 'name', label: 'Nom'}, {id: 'owner', label: 'Membre'}, @@ -63,11 +65,10 @@ export class ExpenseClaimsComponent extends NaturalAbstractList { - public constructor( - licenseService: LicenseService, - public readonly userService: UserService, - public readonly bookableService: BookableService, - ) { + public readonly userService = inject(UserService); + public readonly bookableService = inject(BookableService); + + public constructor() { + const licenseService = inject(LicenseService); + super('license', licenseService); } } diff --git a/client/app/admin/licenses/licenses/licenses.component.ts b/client/app/admin/licenses/licenses/licenses.component.ts index 4785380fa..ade376a91 100644 --- a/client/app/admin/licenses/licenses/licenses.component.ts +++ b/client/app/admin/licenses/licenses/licenses.component.ts @@ -1,4 +1,4 @@ -import {Component, OnInit} from '@angular/core'; +import {Component, OnInit, inject} from '@angular/core'; import { AvailableColumn, NaturalAbstractList, @@ -37,12 +37,13 @@ import {AsyncPipe} from '@angular/common'; ], }) export class LicensesComponent extends NaturalAbstractList implements OnInit { + public readonly permissionsService = inject(PermissionsService); + public override availableColumns: AvailableColumn[] = [{id: 'name', label: 'Nom'}]; - public constructor( - licenseService: LicenseService, - public readonly permissionsService: PermissionsService, - ) { + public constructor() { + const licenseService = inject(LicenseService); + super(licenseService); } } diff --git a/client/app/admin/logs/logs/logs.component.ts b/client/app/admin/logs/logs/logs.component.ts index 1d47ddef2..b548f264f 100644 --- a/client/app/admin/logs/logs/logs.component.ts +++ b/client/app/admin/logs/logs/logs.component.ts @@ -1,11 +1,10 @@ -import {Component, OnInit} from '@angular/core'; -import {ActivatedRoute} from '@angular/router'; +import {Component, inject, OnInit} from '@angular/core'; import { NaturalAbstractList, - SortingOrder, NaturalColumnsPickerComponent, NaturalSearchComponent, NaturalTableButtonComponent, + SortingOrder, } from '@ecodev/natural'; import {CurrentUserForProfile, LogSortingField, UserRole} from '../../../shared/generated-types'; import {LogService} from '../services/log.service'; @@ -35,11 +34,10 @@ import {CommonModule} from '@angular/common'; ], }) export class LogsComponent extends NaturalAbstractList implements OnInit { - public constructor( - route: ActivatedRoute, - logService: LogService, - naturalSearchFacetsService: NaturalSearchFacetsService, - ) { + public constructor() { + const logService = inject(LogService); + const naturalSearchFacetsService = inject(NaturalSearchFacetsService); + super(logService); this.naturalSearchFacets = naturalSearchFacetsService.get('logs'); diff --git a/client/app/admin/transactionTags/transactionTag/transactionTag.component.ts b/client/app/admin/transactionTags/transactionTag/transactionTag.component.ts index c08ce6bf8..3fbda4cc4 100644 --- a/client/app/admin/transactionTags/transactionTag/transactionTag.component.ts +++ b/client/app/admin/transactionTags/transactionTag/transactionTag.component.ts @@ -1,4 +1,4 @@ -import {Component} from '@angular/core'; +import {Component, inject} from '@angular/core'; import { NaturalAbstractDetail, NaturalDetailHeaderComponent, @@ -33,7 +33,9 @@ import {MatDividerModule} from '@angular/material/divider'; ], }) export class TransactionTagComponent extends NaturalAbstractDetail { - public constructor(transactionTagService: TransactionTagService) { + public constructor() { + const transactionTagService = inject(TransactionTagService); + super('transactionTag', transactionTagService); } } diff --git a/client/app/admin/transactionTags/transactionTags/transactionTags.component.ts b/client/app/admin/transactionTags/transactionTags/transactionTags.component.ts index 2a6184d0c..eea8f3183 100644 --- a/client/app/admin/transactionTags/transactionTags/transactionTags.component.ts +++ b/client/app/admin/transactionTags/transactionTags/transactionTags.component.ts @@ -1,4 +1,4 @@ -import {Component, OnInit} from '@angular/core'; +import {Component, OnInit, inject} from '@angular/core'; import { AvailableColumn, NaturalAbstractList, @@ -42,16 +42,17 @@ import {AsyncPipe} from '@angular/common'; ], }) export class TransactionTagsComponent extends NaturalAbstractList implements OnInit { + public readonly permissionsService = inject(PermissionsService); + public readonly transactionLineService = inject(TransactionLineService); + public override availableColumns: AvailableColumn[] = [ {id: 'color', label: 'Couleur'}, {id: 'name', label: 'Nom'}, {id: 'transactions', label: 'Transactions'}, ]; - public constructor( - transactionTagService: TransactionTagService, - public readonly permissionsService: PermissionsService, - public readonly transactionLineService: TransactionLineService, - ) { + public constructor() { + const transactionTagService = inject(TransactionTagService); + super(transactionTagService); } } diff --git a/client/app/admin/transactions/editable-transaction-lines/editable-transaction-lines.component.ts b/client/app/admin/transactions/editable-transaction-lines/editable-transaction-lines.component.ts index 10a43f43a..1a4af241d 100644 --- a/client/app/admin/transactions/editable-transaction-lines/editable-transaction-lines.component.ts +++ b/client/app/admin/transactions/editable-transaction-lines/editable-transaction-lines.component.ts @@ -1,4 +1,4 @@ -import {Component, Input} from '@angular/core'; +import {Component, Input, inject} from '@angular/core'; import {TransactionLineService} from '../services/transactionLine.service'; import {BookableService} from '../../bookables/services/bookable.service'; import {TransactionLineInput, TransactionLines} from '../../../shared/generated-types'; @@ -52,6 +52,9 @@ export class EditableTransactionLinesComponent extends NaturalAbstractEditableLi TransactionLineService, TransactionLines['transactionLines']['items'][0] | TransactionLineInput > { + public readonly transactionTagService = inject(TransactionTagService); + public readonly bookableService = inject(BookableService); + @Input({required: true}) public set input(value: EditableTransactionLinesInput) { this.input$.next(value); @@ -72,11 +75,9 @@ export class EditableTransactionLinesComponent extends NaturalAbstractEditableLi 'remove', ]; - public constructor( - transactionLineService: TransactionLineService, - public readonly transactionTagService: TransactionTagService, - public readonly bookableService: BookableService, - ) { + public constructor() { + const transactionLineService = inject(TransactionLineService); + super(transactionLineService); this.input$ diff --git a/client/app/admin/transactions/services/transaction.service.ts b/client/app/admin/transactions/services/transaction.service.ts index 4ae9496ce..360484bd8 100644 --- a/client/app/admin/transactions/services/transaction.service.ts +++ b/client/app/admin/transactions/services/transaction.service.ts @@ -1,4 +1,4 @@ -import {Injectable} from '@angular/core'; +import {Injectable, inject} from '@angular/core'; import {Validators} from '@angular/forms'; import {formatIsoDateTime, FormValidators, Literal, NaturalAbstractModelService} from '@ecodev/natural'; import { @@ -42,12 +42,12 @@ export class TransactionService extends NaturalAbstractModelService< DeleteTransactions, DeleteTransactionsVariables > { + private readonly transactionLineService = inject(TransactionLineService); + private readonly accountService = inject(AccountService); + private bankAccount: Accounts['accounts']['items'][0] | null = null; - public constructor( - private readonly transactionLineService: TransactionLineService, - private accountService: AccountService, - ) { + public constructor() { super( 'transaction', transactionQuery, @@ -57,7 +57,7 @@ export class TransactionService extends NaturalAbstractModelService< deleteTransactions, ); - accountService.getAccountByCode(localConfig.accounting.bankAccountCode).subscribe(res => { + this.accountService.getAccountByCode(localConfig.accounting.bankAccountCode).subscribe(res => { if (res.length === 1) { this.bankAccount = res.items[0]; } diff --git a/client/app/admin/transactions/transaction/transaction.component.ts b/client/app/admin/transactions/transaction/transaction.component.ts index 3d246c25f..a7b855439 100644 --- a/client/app/admin/transactions/transaction/transaction.component.ts +++ b/client/app/admin/transactions/transaction/transaction.component.ts @@ -1,4 +1,4 @@ -import {Component, OnInit, ViewChild} from '@angular/core'; +import {Component, OnInit, ViewChild, inject} from '@angular/core'; import {NavigationEnd, RouterLink} from '@angular/router'; import { cancellableTimeout, @@ -91,6 +91,11 @@ export class TransactionComponent > implements OnInit { + private readonly transactionService: TransactionService; + public readonly bookableService = inject(BookableService); + public readonly transactionLineService = inject(TransactionLineService); + public readonly userService = inject(UserService); + @ViewChild(EditableTransactionLinesComponent) public transactionLinesComponent!: EditableTransactionLinesComponent; @ViewChild('transactionDocuments', {static: true}) private accountingDocuments!: AccountingDocumentsComponent; @@ -104,13 +109,11 @@ export class TransactionComponent public viewer!: NonNullable; public transactionLines: EditableTransactionLinesInput = {mode: 'empty'}; - public constructor( - private readonly transactionService: TransactionService, - public readonly bookableService: BookableService, - public readonly transactionLineService: TransactionLineService, - public readonly userService: UserService, - ) { + public constructor() { + const transactionService = inject(TransactionService); + super('transaction', transactionService); + this.transactionService = transactionService; } public override ngOnInit(): void { diff --git a/client/app/admin/transactions/transactionLines/transactionLines.component.ts b/client/app/admin/transactions/transactionLines/transactionLines.component.ts index 0ed50b343..88b178f4c 100644 --- a/client/app/admin/transactions/transactionLines/transactionLines.component.ts +++ b/client/app/admin/transactions/transactionLines/transactionLines.component.ts @@ -1,4 +1,4 @@ -import {Component, Input, OnInit} from '@angular/core'; +import {Component, Input, OnInit, inject} from '@angular/core'; import { AvailableColumn, Button, @@ -56,6 +56,9 @@ import {MatTableModule} from '@angular/material/table'; ], }) export class TransactionLinesComponent extends NaturalAbstractList implements OnInit { + private readonly transactionLineService: TransactionLineService; + public readonly permissionsService = inject(PermissionsService); + public override availableColumns: AvailableColumn[] = [ {id: 'transactionDate', label: 'Date'}, {id: 'name', label: 'Nom'}, @@ -79,12 +82,12 @@ export class TransactionLinesComponent extends NaturalAbstractList { - public constructor( - userTagService: UserTagService, - public readonly userService: UserService, - ) { + public readonly userService = inject(UserService); + + public constructor() { + const userTagService = inject(UserTagService); + super('userTag', userTagService); } } diff --git a/client/app/admin/userTags/userTags/userTags.component.ts b/client/app/admin/userTags/userTags/userTags.component.ts index 1e03e7272..c0f633718 100644 --- a/client/app/admin/userTags/userTags/userTags.component.ts +++ b/client/app/admin/userTags/userTags/userTags.component.ts @@ -1,4 +1,4 @@ -import {Component, OnInit} from '@angular/core'; +import {Component, OnInit, inject} from '@angular/core'; import { AvailableColumn, NaturalAbstractList, @@ -41,15 +41,16 @@ import {AsyncPipe} from '@angular/common'; ], }) export class UserTagsComponent extends NaturalAbstractList implements OnInit { + public readonly permissionsService = inject(PermissionsService); + public override availableColumns: AvailableColumn[] = [ {id: 'color', label: 'Couleur'}, {id: 'name', label: 'Nom'}, ]; - public constructor( - userTagService: UserTagService, - public readonly permissionsService: PermissionsService, - ) { + public constructor() { + const userTagService = inject(UserTagService); + super(userTagService); } } diff --git a/client/app/admin/users/services/user.service.ts b/client/app/admin/users/services/user.service.ts index 918186a53..16d145fa0 100644 --- a/client/app/admin/users/services/user.service.ts +++ b/client/app/admin/users/services/user.service.ts @@ -1,5 +1,5 @@ import {gql} from 'apollo-angular'; -import {Inject, Injectable, OnDestroy} from '@angular/core'; +import {Injectable, OnDestroy, inject} from '@angular/core'; import {FormControl, ValidationErrors, Validators} from '@angular/forms'; import {Router} from '@angular/router'; import { @@ -105,6 +105,12 @@ export class UserService > implements OnDestroy { + protected readonly router = inject(Router); + protected readonly bookingService = inject(BookingService); + private readonly permissionsService = inject(PermissionsService); + protected readonly pricedBookingService = inject(PricedBookingService); + private readonly storage = inject(LOCAL_STORAGE); + /** * Should be used only by getViewer and cacheViewer */ @@ -117,13 +123,7 @@ export class UserService private readonly storageKey = 'viewer'; private readonly onDestroy = new Subject(); - public constructor( - protected readonly router: Router, - protected readonly bookingService: BookingService, - private readonly permissionsService: PermissionsService, - protected readonly pricedBookingService: PricedBookingService, - @Inject(LOCAL_STORAGE) private readonly storage: NaturalStorage, - ) { + public constructor() { super('user', userQuery, usersQuery, createUser, updateUser, null); this.keepViewerSyncedAcrossBrowserTabs(); } diff --git a/client/app/admin/users/user/user.component.ts b/client/app/admin/users/user/user.component.ts index f50117668..8d29a6260 100644 --- a/client/app/admin/users/user/user.component.ts +++ b/client/app/admin/users/user/user.component.ts @@ -1,4 +1,4 @@ -import {Component, OnInit} from '@angular/core'; +import {Component, OnInit, inject} from '@angular/core'; import { IEnum, ifValid, @@ -98,6 +98,13 @@ import {MoneyComponent} from '../../../shared/components/money/money.component'; ], }) export class UserComponent extends NaturalAbstractDetail implements OnInit { + private readonly userService: UserService; + public readonly userTagService = inject(UserTagService); + public readonly licenseService = inject(LicenseService); + public readonly bookingService = inject(BookingService); + public readonly accountService = inject(AccountService); + public readonly permissionsService = inject(PermissionsService); + public showFamilyTab = false; public updating = false; public ibanLocked = true; @@ -114,15 +121,11 @@ export class UserComponent extends NaturalAbstractDetail implements OnInit { + private readonly userService: UserService; + public readonly permissionsService = inject(PermissionsService); + private readonly apollo = inject(Apollo); + private readonly dialog = inject(MatDialog); + private readonly copyContactDataButtonService = + inject>(CopyContactDataButtonService); + public override availableColumns: AvailableColumn[] = [ {id: 'balance', label: 'Solde'}, {id: 'name', label: 'Nom'}, @@ -80,16 +87,13 @@ export class UsersComponent extends NaturalAbstractList implements public readonly activating = new Map(); public readonly welcoming = new Map(); - public constructor( - route: ActivatedRoute, - private readonly userService: UserService, - naturalSearchFacetsService: NaturalSearchFacetsService, - public readonly permissionsService: PermissionsService, - private readonly apollo: Apollo, - private readonly dialog: MatDialog, - private readonly copyContactDataButtonService: CopyContactDataButtonService, - ) { + public constructor() { + const userService = inject(UserService); + const naturalSearchFacetsService = inject(NaturalSearchFacetsService); + super(userService); + this.userService = userService; + this.naturalSearchFacets = naturalSearchFacetsService.get('users'); } diff --git a/client/app/booking/bookable/bookable.component.ts b/client/app/booking/bookable/bookable.component.ts index a2c13de99..6133b52ed 100644 --- a/client/app/booking/bookable/bookable.component.ts +++ b/client/app/booking/bookable/bookable.component.ts @@ -1,4 +1,4 @@ -import {Component, OnInit} from '@angular/core'; +import {Component, OnInit, inject} from '@angular/core'; import {ActivatedRoute, RouterLink} from '@angular/router'; import {BookableService} from '../../admin/bookables/services/bookable.service'; import {BookingService} from '../../admin/bookings/services/booking.service'; @@ -18,6 +18,11 @@ import {NaturalFileComponent} from '@ecodev/natural'; imports: [NaturalFileComponent, MatDividerModule, MatIconModule, MatButtonModule, RouterLink, TimeagoModule], }) export class BookableComponent implements OnInit { + private readonly bookableService = inject(BookableService); + private readonly route = inject(ActivatedRoute); + private readonly permissionsService = inject(PermissionsService); + public readonly bookingService = inject(BookingService); + /** * If the user has a required licence to use the bookable */ @@ -43,13 +48,6 @@ export class BookableComponent implements OnInit { public bookable: Bookable['bookable'] | null = null; - public constructor( - private readonly bookableService: BookableService, - private readonly route: ActivatedRoute, - private readonly permissionsService: PermissionsService, - public readonly bookingService: BookingService, - ) {} - public ngOnInit(): void { this.route.data.subscribe(data => { this.bookable = data.model; diff --git a/client/app/booking/components/code-input/code-input.component.ts b/client/app/booking/components/code-input/code-input.component.ts index c17f86b48..5ec3312f8 100644 --- a/client/app/booking/components/code-input/code-input.component.ts +++ b/client/app/booking/components/code-input/code-input.component.ts @@ -1,4 +1,4 @@ -import {Component} from '@angular/core'; +import {Component, inject} from '@angular/core'; import {Router, RouterLink} from '@angular/router'; import {MatButtonModule} from '@angular/material/button'; import {FocusDirective} from '../../../shared/directives/focus'; @@ -12,9 +12,9 @@ import {FormsModule} from '@angular/forms'; imports: [FormsModule, FocusDirective, MatButtonModule, RouterLink], }) export class CodeInputComponent { - public code = ''; + private readonly router = inject(Router); - public constructor(private readonly router: Router) {} + public code = ''; public goToBookable(code: string): void { this.router.navigate(['/booking', code]); diff --git a/client/app/booking/components/scan/scan.component.ts b/client/app/booking/components/scan/scan.component.ts index 42180b199..7016322d8 100644 --- a/client/app/booking/components/scan/scan.component.ts +++ b/client/app/booking/components/scan/scan.component.ts @@ -11,16 +11,14 @@ import {takeUntilDestroyed} from '@angular/core/rxjs-interop'; standalone: true, }) export class ScanComponent implements OnInit, OnDestroy { + public readonly router = inject(Router); + private readonly route = inject(ActivatedRoute); + private readonly alertService = inject(NaturalAlertService); + private readonly qrService = inject(QrService); + private readonly destroyRef = inject(DestroyRef); @ViewChild('video', {static: true}) private videoRef!: ElementRef; - public constructor( - public readonly router: Router, - private readonly route: ActivatedRoute, - private readonly alertService: NaturalAlertService, - private readonly qrService: QrService, - ) {} - public ngOnInit(): void { this.qrService.qrCode.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({ next: code => { diff --git a/client/app/booking/components/self-approved-booking/self-approved-booking.component.ts b/client/app/booking/components/self-approved-booking/self-approved-booking.component.ts index 99142faa2..48d73f2fd 100644 --- a/client/app/booking/components/self-approved-booking/self-approved-booking.component.ts +++ b/client/app/booking/components/self-approved-booking/self-approved-booking.component.ts @@ -1,4 +1,4 @@ -import {Component, OnInit} from '@angular/core'; +import {Component, OnInit, inject} from '@angular/core'; import {ActivatedRoute, Router} from '@angular/router'; import {BookableService} from '../../../admin/bookables/services/bookable.service'; import {BookingService} from '../../../admin/bookings/services/booking.service'; @@ -31,16 +31,16 @@ import {first} from 'rxjs/operators'; ], }) export class SelfApprovedBookingComponent implements OnInit { + private readonly route = inject(ActivatedRoute); + private readonly router = inject(Router); + private readonly bookingService = inject(BookingService); + private readonly bookableService = inject(BookableService); + private readonly alertService = inject(NaturalAlertService); + public bookable: Bookable['bookable'] | null = null; public booking: Literal = {}; - public constructor( - private readonly route: ActivatedRoute, - private readonly router: Router, - private readonly bookingService: BookingService, - private readonly bookableService: BookableService, - private readonly alertService: NaturalAlertService, - ) { + public constructor() { this.route.data .pipe( takeUntilDestroyed(), diff --git a/client/app/dashboard/dashboard.component.ts b/client/app/dashboard/dashboard.component.ts index 7b7a6a1c2..1902830f6 100644 --- a/client/app/dashboard/dashboard.component.ts +++ b/client/app/dashboard/dashboard.component.ts @@ -1,4 +1,4 @@ -import {Component} from '@angular/core'; +import {Component, inject} from '@angular/core'; import {UserService} from '../admin/users/services/user.service'; import {BookingService} from '../admin/bookings/services/booking.service'; import {ActivatedRoute, RouterLink} from '@angular/router'; @@ -20,15 +20,15 @@ import {CommonModule} from '@angular/common'; imports: [CommonModule, NavigationsComponent, MatButtonModule, RouterLink, MatIconModule, NaturalIconDirective], }) export class DashboardComponent { + public readonly userService = inject(UserService); + public readonly bookingService = inject(BookingService); + public readonly route = inject(ActivatedRoute); + public readonly permissionsService = inject(PermissionsService); + public title = 'my-ichtus'; public readonly adminRoute: Observable; - public constructor( - public readonly userService: UserService, - public readonly bookingService: BookingService, - public readonly route: ActivatedRoute, - public readonly permissionsService: PermissionsService, - ) { + public constructor() { this.adminRoute = this.route.data.pipe( map(data => { switch (data.viewer.role) { diff --git a/client/app/door/door.component.ts b/client/app/door/door.component.ts index 84abc9f0e..b8d0b1433 100644 --- a/client/app/door/door.component.ts +++ b/client/app/door/door.component.ts @@ -1,4 +1,4 @@ -import {Component, OnInit} from '@angular/core'; +import {Component, OnInit, inject} from '@angular/core'; import {DoorService} from './services/door.service'; import {Literal, NaturalAlertService} from '@ecodev/natural'; import {UserService} from '../admin/users/services/user.service'; @@ -16,14 +16,12 @@ import {CardComponent} from '../shared/components/card/card.component'; imports: [CardComponent, MatButtonModule, MatIconModule], }) export class DoorComponent implements OnInit { - public viewer!: NonNullable; + public readonly doorService = inject(DoorService); + private readonly userService = inject(UserService); + private readonly alertService = inject(NaturalAlertService); + private readonly route = inject(ActivatedRoute); - public constructor( - public readonly doorService: DoorService, - private readonly userService: UserService, - private readonly alertService: NaturalAlertService, - private readonly route: ActivatedRoute, - ) {} + public viewer!: NonNullable; public open(door: Literal): void { this.doorService.open({door: door.id}).subscribe({ diff --git a/client/app/door/services/door.service.ts b/client/app/door/services/door.service.ts index c0884d5f2..6e31efe91 100644 --- a/client/app/door/services/door.service.ts +++ b/client/app/door/services/door.service.ts @@ -1,5 +1,5 @@ import {Apollo} from 'apollo-angular'; -import {Injectable} from '@angular/core'; +import {Injectable, inject} from '@angular/core'; import {Observable} from 'rxjs'; import {map} from 'rxjs/operators'; import {openDoorMutation} from './door.queries'; @@ -16,7 +16,7 @@ type DoorConfig = { providedIn: 'root', }) export class DoorService { - public constructor(private readonly apollo: Apollo) {} + private readonly apollo = inject(Apollo); public doors: DoorConfig[] = [ { diff --git a/client/app/home/home.component.ts b/client/app/home/home.component.ts index 2ba813635..28e9723bd 100644 --- a/client/app/home/home.component.ts +++ b/client/app/home/home.component.ts @@ -1,4 +1,4 @@ -import {Component, DestroyRef, Inject, inject, OnInit} from '@angular/core'; +import {Component, DestroyRef, inject, OnInit} from '@angular/core'; import {UserService} from '../admin/users/services/user.service'; import { LOCAL_STORAGE, @@ -34,6 +34,13 @@ import {takeUntilDestroyed} from '@angular/core/rxjs-interop'; ], }) export class HomeComponent implements OnInit { + private readonly userService = inject(UserService); + private readonly router = inject(Router); + private readonly storage = inject(LOCAL_STORAGE); + public readonly route = inject(ActivatedRoute); + private readonly configurationService = inject(ConfigurationService); + private readonly naturalSidenavStackService = inject(NaturalSidenavStackService); + private readonly destroyRef = inject(DestroyRef); public menu: NaturalSidenavContainerComponent | undefined; @@ -44,15 +51,6 @@ export class HomeComponent implements OnInit { public announcementActive = false; - public constructor( - private readonly userService: UserService, - private readonly router: Router, - @Inject(LOCAL_STORAGE) private readonly storage: NaturalStorage, - public readonly route: ActivatedRoute, - private readonly configurationService: ConfigurationService, - private readonly naturalSidenavStackService: NaturalSidenavStackService, - ) {} - public ngOnInit(): void { const announcementConfigKey = 'announcement-text'; this.configurationService diff --git a/client/app/login/login.component.ts b/client/app/login/login.component.ts index 9b36d125b..f61c0297d 100644 --- a/client/app/login/login.component.ts +++ b/client/app/login/login.component.ts @@ -1,4 +1,4 @@ -import {Component, OnInit} from '@angular/core'; +import {Component, OnInit, inject} from '@angular/core'; import {ActivatedRoute, Router, RouterLink} from '@angular/router'; import {MatSnackBar} from '@angular/material/snack-bar'; import {ifValid, NaturalIconDirective} from '@ecodev/natural'; @@ -29,6 +29,12 @@ import {MatFormFieldModule} from '@angular/material/form-field'; ], }) export class LoginComponent implements OnInit { + private readonly route = inject(ActivatedRoute); + private readonly router = inject(Router); + private readonly userService = inject(UserService); + private readonly snackBar = inject(MatSnackBar); + private readonly fb = inject(NonNullableFormBuilder); + /** * Stores the received redirect URL until we need to use it (when login is successfull) */ @@ -39,14 +45,6 @@ export class LoginComponent implements OnInit { }); public hidePassword = true; - public constructor( - private readonly route: ActivatedRoute, - private readonly router: Router, - private readonly userService: UserService, - private readonly snackBar: MatSnackBar, - private readonly fb: NonNullableFormBuilder, - ) {} - public ngOnInit(): void { this.returnUrl = this.route.snapshot.queryParams.returnUrl || '/'; const logout = this.route.snapshot.queryParams.logout || false; diff --git a/client/app/profile/components/booking-history/booking-history.component.ts b/client/app/profile/components/booking-history/booking-history.component.ts index 1eaaf361a..0a8677acd 100644 --- a/client/app/profile/components/booking-history/booking-history.component.ts +++ b/client/app/profile/components/booking-history/booking-history.component.ts @@ -1,4 +1,4 @@ -import {Component} from '@angular/core'; +import {Component, inject} from '@angular/core'; import {ActivatedRoute} from '@angular/router'; import {NavigationsComponent} from '../../../shared/components/navigations/navigations.component'; @@ -10,5 +10,5 @@ import {NavigationsComponent} from '../../../shared/components/navigations/navig imports: [NavigationsComponent], }) export class BookingHistoryComponent { - public constructor(public readonly route: ActivatedRoute) {} + public readonly route = inject(ActivatedRoute); } diff --git a/client/app/profile/components/bvr/bvr.component.ts b/client/app/profile/components/bvr/bvr.component.ts index b5a025904..44a68f0da 100644 --- a/client/app/profile/components/bvr/bvr.component.ts +++ b/client/app/profile/components/bvr/bvr.component.ts @@ -1,5 +1,5 @@ import {gql, Apollo} from 'apollo-angular'; -import {Component, Inject, Input} from '@angular/core'; +import {Component, Input, inject} from '@angular/core'; import {BankingInfosForExport, BankingInfos, BankingInfosVariables} from '../../../shared/generated-types'; import {DOCUMENT} from '@angular/common'; import {copyToClipboard, NaturalIconDirective} from '@ecodev/natural'; @@ -44,6 +44,9 @@ const queryForExport = gql` ], }) export class BvrComponent { + private readonly apollo = inject(Apollo); + private readonly document = inject(DOCUMENT); + @Input() public set bankingData(data: BankingInfosVariables) { this.variables = data; this.apollo @@ -58,11 +61,6 @@ export class BvrComponent { private variables!: BankingInfosVariables; public bankingInfos: BankingInfos['bankingInfos'] | null = null; - public constructor( - private readonly apollo: Apollo, - @Inject(DOCUMENT) private readonly document: Document, - ) {} - public copyToClipboard(text: string): void { copyToClipboard(this.document, text); } diff --git a/client/app/profile/components/create-expense-claim/create-expense-claim.component.html b/client/app/profile/components/create-expense-claim/create-expense-claim.component.html index d806196c5..1ace0789f 100644 --- a/client/app/profile/components/create-expense-claim/create-expense-claim.component.html +++ b/client/app/profile/components/create-expense-claim/create-expense-claim.component.html @@ -19,7 +19,7 @@

{{ data.seo.title }}

Secteur concerné - @for (option of expenseClaimService.getSectors(); track option) { + @for (option of service.getSectors(); track option) { {{ option }} diff --git a/client/app/profile/components/create-expense-claim/create-expense-claim.component.ts b/client/app/profile/components/create-expense-claim/create-expense-claim.component.ts index e52fb2aaf..8a2a60d7d 100644 --- a/client/app/profile/components/create-expense-claim/create-expense-claim.component.ts +++ b/client/app/profile/components/create-expense-claim/create-expense-claim.component.ts @@ -1,4 +1,4 @@ -import {Component, OnInit, ViewChild} from '@angular/core'; +import {Component, inject, OnInit, ViewChild} from '@angular/core'; import {ExpenseClaimService} from '../../../admin/expenseClaim/services/expenseClaim.service'; import {CreateExpenseClaim, ExpenseClaimStatus, ExpenseClaimType} from '../../../shared/generated-types'; import {UserService} from '../../../admin/users/services/user.service'; @@ -33,14 +33,15 @@ export class CreateExpenseClaimComponent extends NaturalAbstractDetail implements OnInit { + public readonly userService = inject(UserService); + @ViewChild(AccountingDocumentsComponent, {static: true}) private accountingDocuments!: AccountingDocumentsComponent; public ExpenseClaimType = ExpenseClaimType; - public constructor( - public expenseClaimService: ExpenseClaimService, - public readonly userService: UserService, - ) { + public constructor() { + const expenseClaimService = inject(ExpenseClaimService); + super('expenseClaim', expenseClaimService); } diff --git a/client/app/profile/components/create-refund/create-refund.component.ts b/client/app/profile/components/create-refund/create-refund.component.ts index 39faa7d55..f56e6ebe4 100644 --- a/client/app/profile/components/create-refund/create-refund.component.ts +++ b/client/app/profile/components/create-refund/create-refund.component.ts @@ -1,4 +1,4 @@ -import {Component} from '@angular/core'; +import {Component, inject} from '@angular/core'; import {MatDialogModule} from '@angular/material/dialog'; import {NonNullableFormBuilder, FormsModule, ReactiveFormsModule, Validators} from '@angular/forms'; import {money} from '@ecodev/natural'; @@ -23,6 +23,8 @@ import {MatFormFieldModule} from '@angular/material/form-field'; ], }) export class CreateRefundComponent { + private readonly fb = inject(NonNullableFormBuilder); + /** * Form for ExpenseClaimInput */ @@ -31,6 +33,4 @@ export class CreateRefundComponent { name: ['Demande de remboursement', [Validators.required, Validators.maxLength(50)]], description: ['', []], }); - - public constructor(private readonly fb: NonNullableFormBuilder) {} } diff --git a/client/app/profile/components/family-member/family-member.component.ts b/client/app/profile/components/family-member/family-member.component.ts index 0d7acd2a8..877ec527a 100644 --- a/client/app/profile/components/family-member/family-member.component.ts +++ b/client/app/profile/components/family-member/family-member.component.ts @@ -1,4 +1,4 @@ -import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; +import {Component, EventEmitter, Input, OnInit, Output, inject} from '@angular/core'; import {CreateUser, CurrentUserForProfile, UpdateUser, Users} from '../../../shared/generated-types'; import { NaturalAbstractDetail, @@ -49,7 +49,9 @@ export class FamilyMemberComponent extends NaturalAbstractDetail(); public loaded = false; - public constructor(userService: FamilyUserService) { + public constructor() { + const userService = inject(FamilyUserService); + super('user', userService); } diff --git a/client/app/profile/components/family-member/family-user.service.ts b/client/app/profile/components/family-member/family-user.service.ts index 147762a86..892ffa0bd 100644 --- a/client/app/profile/components/family-member/family-user.service.ts +++ b/client/app/profile/components/family-member/family-user.service.ts @@ -1,26 +1,12 @@ -import {Inject, Injectable} from '@angular/core'; +import {Injectable} from '@angular/core'; import {UserService} from '../../../admin/users/services/user.service'; -import {Router} from '@angular/router'; -import {BookingService} from '../../../admin/bookings/services/booking.service'; -import {PermissionsService} from '../../../shared/services/permissions.service'; import {Relationship, UserInput, UserRole} from '../../../shared/generated-types'; -import {FormValidators, LOCAL_STORAGE, NaturalStorage} from '@ecodev/natural'; -import {PricedBookingService} from '../../../admin/bookings/services/PricedBooking.service'; +import {FormValidators} from '@ecodev/natural'; @Injectable({ providedIn: 'root', }) export class FamilyUserService extends UserService { - public constructor( - router: Router, - bookingService: BookingService, - permissionsService: PermissionsService, - pricedBookingService: PricedBookingService, - @Inject(LOCAL_STORAGE) storage: NaturalStorage, - ) { - super(router, bookingService, permissionsService, pricedBookingService, storage); - } - public override getDefaultForServer(): UserInput { return { ...super.getDefaultForServer(), diff --git a/client/app/profile/components/family/family.component.ts b/client/app/profile/components/family/family.component.ts index 75d8985a4..82c64d52b 100644 --- a/client/app/profile/components/family/family.component.ts +++ b/client/app/profile/components/family/family.component.ts @@ -1,4 +1,4 @@ -import {ChangeDetectorRef, Component, OnInit, QueryList, ViewChildren} from '@angular/core'; +import {ChangeDetectorRef, Component, OnInit, QueryList, ViewChildren, inject} from '@angular/core'; import {CurrentUserForProfile, UpdateUser, Users, UsersVariables} from '../../../shared/generated-types'; import {UserService} from '../../../admin/users/services/user.service'; import {PermissionsService} from '../../../shared/services/permissions.service'; @@ -26,6 +26,12 @@ import {AsyncPipe} from '@angular/common'; ], }) export class FamilyComponent implements OnInit { + public readonly userService = inject(UserService); + private readonly route = inject(ActivatedRoute); + private readonly alertService = inject(NaturalAlertService); + public readonly permissionsService = inject(PermissionsService); + private readonly changeDetectorRef = inject(ChangeDetectorRef); + public viewer!: NonNullable; public familyMembers: Users['users']['items'][0][] = []; @@ -35,14 +41,6 @@ export class FamilyComponent implements OnInit { public activeMember: Users['users']['items'][0] | null = null; @ViewChildren(MatExpansionPanel) private readonly expansionPanels!: QueryList; - public constructor( - public readonly userService: UserService, - private readonly route: ActivatedRoute, - private readonly alertService: NaturalAlertService, - public readonly permissionsService: PermissionsService, - private readonly changeDetectorRef: ChangeDetectorRef, - ) {} - public ngOnInit(): void { this.viewer = this.route.snapshot.data.viewer; this.reload(); diff --git a/client/app/profile/components/finances/finances.component.ts b/client/app/profile/components/finances/finances.component.ts index bfe87e4b9..600f1c6fe 100644 --- a/client/app/profile/components/finances/finances.component.ts +++ b/client/app/profile/components/finances/finances.component.ts @@ -1,4 +1,4 @@ -import {Component, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core'; +import {Component, Input, OnChanges, OnInit, SimpleChanges, inject} from '@angular/core'; import {CurrentUserForProfile, ExpenseClaims, ExpenseClaimType} from '../../../shared/generated-types'; import {UserService} from '../../../admin/users/services/user.service'; import {ExpenseClaimService} from '../../../admin/expenseClaim/services/expenseClaim.service'; @@ -48,6 +48,11 @@ import {CommonModule} from '@angular/common'; ], }) export class FinancesComponent extends NaturalAbstractList implements OnInit, OnChanges { + private readonly userService = inject(UserService); + private readonly expenseClaimService: ExpenseClaimService; + private readonly transactionLineService = inject(TransactionLineService); + private readonly dialog = inject(MatDialog); + @Input({required: true}) public viewer!: NonNullable; public override selectedColumns = ['name', 'updateDate', 'status', 'type', 'remarks', 'amount', 'cancel']; @@ -61,13 +66,11 @@ export class FinancesComponent extends NaturalAbstractList public canCreateExpenseClaim = false; public override persistSearch = false; - public constructor( - private readonly userService: UserService, - private readonly expenseClaimService: ExpenseClaimService, - private readonly transactionLineService: TransactionLineService, - private readonly dialog: MatDialog, - ) { + public constructor() { + const expenseClaimService = inject(ExpenseClaimService); + super(expenseClaimService); + this.expenseClaimService = expenseClaimService; } public ngOnChanges(changes: SimpleChanges): void { diff --git a/client/app/profile/components/history/history.component.ts b/client/app/profile/components/history/history.component.ts index 0ca331e44..77a3d9395 100644 --- a/client/app/profile/components/history/history.component.ts +++ b/client/app/profile/components/history/history.component.ts @@ -18,19 +18,17 @@ import {takeUntilDestroyed} from '@angular/core/rxjs-interop'; imports: [CommonModule, MatTableModule, TransactionAmountComponent], }) export class HistoryComponent implements OnInit { + private readonly userService = inject(UserService); + private readonly route = inject(ActivatedRoute); + private readonly expenseClaimService = inject(ExpenseClaimService); + private readonly transactionLineService = inject(TransactionLineService); + private readonly destroyRef = inject(DestroyRef); @Input({required: true}) public viewer!: NonNullable; public transactionLinesDS!: NaturalDataSource; public transactionsColumns = ['name', 'bookable', 'transactionDate', 'remarks', 'amount']; - public constructor( - private readonly userService: UserService, - private readonly route: ActivatedRoute, - private readonly expenseClaimService: ExpenseClaimService, - private readonly transactionLineService: TransactionLineService, - ) {} - public ngOnInit(): void { this.viewer = this.route.snapshot.data.viewer; diff --git a/client/app/profile/components/profile/profile.component.ts b/client/app/profile/components/profile/profile.component.ts index 54fba9a64..1e2f38efc 100644 --- a/client/app/profile/components/profile/profile.component.ts +++ b/client/app/profile/components/profile/profile.component.ts @@ -55,24 +55,22 @@ import {takeUntilDestroyed} from '@angular/core/rxjs-interop'; ], }) export class ProfileComponent implements OnInit { + public readonly userService = inject(UserService); + public readonly permissionsService = inject(PermissionsService); + private readonly alertService = inject(NaturalAlertService); + private readonly route = inject(ActivatedRoute); + private readonly router = inject(Router); + public readonly bookableService = inject(BookableService); + private readonly apollo = inject(Apollo); + private readonly dialog = inject(MatDialog); + private readonly datatransService = inject(DatatransService); + private readonly licenseService = inject(LicenseService); + private readonly destroyRef = inject(DestroyRef); public viewer!: NonNullable; public config = localConfig; public licenses: Licenses['licenses']['items'][0][] = []; - public constructor( - public readonly userService: UserService, - public readonly permissionsService: PermissionsService, - private readonly alertService: NaturalAlertService, - private readonly route: ActivatedRoute, - private readonly router: Router, - public readonly bookableService: BookableService, - private readonly apollo: Apollo, - private readonly dialog: MatDialog, - private readonly datatransService: DatatransService, - private readonly licenseService: LicenseService, - ) {} - public ngOnInit(): void { this.viewer = this.route.snapshot.data.viewer; diff --git a/client/app/profile/components/provision/provision.component.ts b/client/app/profile/components/provision/provision.component.ts index 73e435ce7..025411968 100644 --- a/client/app/profile/components/provision/provision.component.ts +++ b/client/app/profile/components/provision/provision.component.ts @@ -1,4 +1,4 @@ -import {Component, Inject, ViewChild} from '@angular/core'; +import {Component, ViewChild, inject} from '@angular/core'; import {ShowOnDirtyErrorStateMatcher} from '@angular/material/core'; import {MAT_DIALOG_DATA, MatDialogModule} from '@angular/material/dialog'; import {FormControl, FormsModule, ReactiveFormsModule, Validators} from '@angular/forms'; @@ -32,6 +32,8 @@ export type ProvisionData = { ], }) export class ProvisionComponent { + public readonly data = inject(MAT_DIALOG_DATA); + /** * Minimum payment amount * Positive number at the payment is always positive @@ -46,7 +48,9 @@ export class ProvisionComponent { @ViewChild(BvrComponent) private bvr!: BvrComponent; - public constructor(@Inject(MAT_DIALOG_DATA) public readonly data: ProvisionData) { + public constructor() { + const data = this.data; + this.bvrData = { user: data.user.id, }; diff --git a/client/app/profile/components/services/services.component.ts b/client/app/profile/components/services/services.component.ts index 67055bc43..918b6bf15 100644 --- a/client/app/profile/components/services/services.component.ts +++ b/client/app/profile/components/services/services.component.ts @@ -39,6 +39,11 @@ import {takeUntilDestroyed} from '@angular/core/rxjs-interop'; ], }) export class ServicesComponent implements OnInit, OnChanges { + private readonly userService = inject(UserService); + public readonly route = inject(ActivatedRoute); + private readonly alertService = inject(NaturalAlertService); + private readonly bookingService = inject(BookingService); + private readonly destroyRef = inject(DestroyRef); @Input({required: true}) public user!: NonNullable; @@ -51,13 +56,6 @@ export class ServicesComponent implements OnInit, OnChanges { public applicationsColumns = ['name', 'startDate', 'remarks', 'initialPrice', 'periodicPrice', 'cancel']; public readonly deleting = new Map(); - public constructor( - private readonly userService: UserService, - public readonly route: ActivatedRoute, - private readonly alertService: NaturalAlertService, - private readonly bookingService: BookingService, - ) {} - public ngOnChanges(changes: SimpleChanges): void { const previousUser = changes.user?.previousValue; if (previousUser && previousUser.id !== this.user.id) { diff --git a/client/app/safety/safety.component.ts b/client/app/safety/safety.component.ts index 71b3d4248..285ece26a 100644 --- a/client/app/safety/safety.component.ts +++ b/client/app/safety/safety.component.ts @@ -1,4 +1,4 @@ -import {Component} from '@angular/core'; +import {Component, inject} from '@angular/core'; import {SafetyBookingService} from './safety-booking.service'; import {NaturalSearchFacetsService} from '../shared/natural-search/natural-search-facets.service'; import {PermissionsService} from '../shared/services/permissions.service'; @@ -55,11 +55,12 @@ import {CommonModule, DatePipe} from '@angular/common'; ], }) export class SafetyComponent extends AbstractBookings { - public constructor( - safetyBookingService: SafetyBookingService, - naturalSearchFacetsService: NaturalSearchFacetsService, - public readonly permissionsService: PermissionsService, - ) { + public readonly permissionsService = inject(PermissionsService); + + public constructor() { + const safetyBookingService = inject(SafetyBookingService); + const naturalSearchFacetsService = inject(NaturalSearchFacetsService); + super(safetyBookingService); this.naturalSearchFacets = naturalSearchFacetsService.get('bookings'); } diff --git a/client/app/shared/components/address/address.component.ts b/client/app/shared/components/address/address.component.ts index b1ac3871a..770c48336 100644 --- a/client/app/shared/components/address/address.component.ts +++ b/client/app/shared/components/address/address.component.ts @@ -1,4 +1,4 @@ -import {Component, EventEmitter, Input, Output} from '@angular/core'; +import {Component, EventEmitter, Input, Output, inject} from '@angular/core'; import {CountryService} from './country.service'; import {FormGroup, FormsModule, ReactiveFormsModule} from '@angular/forms'; import {NaturalSelectComponent} from '@ecodev/natural'; @@ -13,12 +13,12 @@ import {MatFormFieldModule} from '@angular/material/form-field'; imports: [FormsModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, NaturalSelectComponent], }) export class AddressComponent { + public readonly countryService = inject(CountryService); + @Input() public vertical = false; @Input({required: true}) public form!: FormGroup; @Output() public readonly addressChange = new EventEmitter(); - public constructor(public readonly countryService: CountryService) {} - public update(): void { this.addressChange.emit(); } diff --git a/client/app/shared/components/copy-contact-data/copy-contact-data-button.service.ts b/client/app/shared/components/copy-contact-data/copy-contact-data-button.service.ts index 694f95214..df5fedc24 100644 --- a/client/app/shared/components/copy-contact-data/copy-contact-data-button.service.ts +++ b/client/app/shared/components/copy-contact-data/copy-contact-data-button.service.ts @@ -1,4 +1,4 @@ -import {Inject, Injectable} from '@angular/core'; +import {Injectable, inject} from '@angular/core'; import {Button, copyToClipboard, NaturalQueryVariablesManager} from '@ecodev/natural'; import { BookingsWithOwnerContact, @@ -19,17 +19,15 @@ export type ContactType = 'bookingsWithOwnerContact' | 'emailAndPhoneUsers'; providedIn: 'root', }) export class CopyContactDataButtonService { + private readonly apollo = inject(Apollo); + private readonly document = inject(DOCUMENT); + private type!: ContactType; private variablesManager!: NaturalQueryVariablesManager; private usersEmail: string | null = null; private usersEmailAndName: string | null = null; private usersPhoneAndName: string | null = null; - public constructor( - private readonly apollo: Apollo, - @Inject(DOCUMENT) private readonly document: Document, - ) {} - public getButtons(variablesManager: NaturalQueryVariablesManager, type: ContactType): Button[] { this.variablesManager = variablesManager; this.type = type; diff --git a/client/app/shared/components/error/error.component.ts b/client/app/shared/components/error/error.component.ts index b1ef33772..585dfeb4e 100644 --- a/client/app/shared/components/error/error.component.ts +++ b/client/app/shared/components/error/error.component.ts @@ -1,4 +1,4 @@ -import {Component} from '@angular/core'; +import {Component, inject} from '@angular/core'; import {ErrorService} from './error.service'; import {ActivatedRoute, RouterLink} from '@angular/router'; import {MatButtonModule} from '@angular/material/button'; @@ -15,7 +15,10 @@ import {MatIconModule} from '@angular/material/icon'; export class ErrorComponent { public readonly error: Error | null = null; - public constructor(errorService: ErrorService, route: ActivatedRoute) { + public constructor() { + const errorService = inject(ErrorService); + const route = inject(ActivatedRoute); + this.error = errorService.getLastError(); if (route.snapshot.data.notFound) { diff --git a/client/app/shared/components/error/error.service.ts b/client/app/shared/components/error/error.service.ts index 96e5dbd08..d4620480e 100644 --- a/client/app/shared/components/error/error.service.ts +++ b/client/app/shared/components/error/error.service.ts @@ -1,4 +1,4 @@ -import {Injectable} from '@angular/core'; +import {Injectable, inject} from '@angular/core'; import {Router} from '@angular/router'; import {Observable, throwError} from 'rxjs'; import {catchError} from 'rxjs/operators'; @@ -10,9 +10,9 @@ import {catchError} from 'rxjs/operators'; providedIn: 'root', }) export class ErrorService { - private lastError: Error | null = null; + private readonly router = inject(Router); - public constructor(private readonly router: Router) {} + private lastError: Error | null = null; /** * Redirect to error page and display given error diff --git a/client/app/shared/components/navigations/comment.component.ts b/client/app/shared/components/navigations/comment.component.ts index 1385ef074..6209eebce 100644 --- a/client/app/shared/components/navigations/comment.component.ts +++ b/client/app/shared/components/navigations/comment.component.ts @@ -1,4 +1,4 @@ -import {Component, Inject} from '@angular/core'; +import {Component, inject} from '@angular/core'; import {MAT_DIALOG_DATA, MatDialogModule} from '@angular/material/dialog'; import {MatButtonModule} from '@angular/material/button'; import {TextFieldModule} from '@angular/cdk/text-field'; @@ -14,7 +14,7 @@ import {MatFormFieldModule} from '@angular/material/form-field'; imports: [MatDialogModule, MatFormFieldModule, MatInputModule, FormsModule, TextFieldModule, MatButtonModule], }) export class CommentComponent { - public comment = ''; + public readonly data = inject(MAT_DIALOG_DATA); - public constructor(@Inject(MAT_DIALOG_DATA) public readonly data: any) {} + public comment = ''; } diff --git a/client/app/shared/components/navigations/navigations.component.ts b/client/app/shared/components/navigations/navigations.component.ts index 4e3bdc305..5c8136ac3 100644 --- a/client/app/shared/components/navigations/navigations.component.ts +++ b/client/app/shared/components/navigations/navigations.component.ts @@ -1,4 +1,4 @@ -import {Component, Input, OnInit} from '@angular/core'; +import {Component, Input, OnInit, inject} from '@angular/core'; import {UserService} from '../../../admin/users/services/user.service'; import {BookingService} from '../../../admin/bookings/services/booking.service'; import {animate, style, transition, trigger} from '@angular/animations'; @@ -89,6 +89,12 @@ function bookingsToExtended(bookings: Bookings['bookings']): PaginatedExtendedBo ], }) export class NavigationsComponent implements OnInit { + public readonly userService = inject(UserService); + public readonly bookingService = inject(BookingService); + private readonly alertService = inject(NaturalAlertService); + private readonly dialog = inject(MatDialog); + private readonly snackbar = inject(MatSnackBar); + @Input({required: true}) public user!: NonNullable; @Input() public activeOnly = true; @Input() public showEmptyMessage = false; @@ -100,14 +106,6 @@ export class NavigationsComponent implements OnInit { private currentPage = 0; private family: (NonNullable | Users['users']['items'][0])[] = []; - public constructor( - public readonly userService: UserService, - public readonly bookingService: BookingService, - private readonly alertService: NaturalAlertService, - private readonly dialog: MatDialog, - private readonly snackbar: MatSnackBar, - ) {} - public ngOnInit(): void { const qvm = new NaturalQueryVariablesManager(); qvm.set('variables', { diff --git a/client/app/shared/components/particle-button/particle-effect.directive.ts b/client/app/shared/components/particle-button/particle-effect.directive.ts index 9443830f3..cb1e2655b 100644 --- a/client/app/shared/components/particle-button/particle-effect.directive.ts +++ b/client/app/shared/components/particle-button/particle-effect.directive.ts @@ -1,4 +1,4 @@ -import {AfterContentInit, Directive, ElementRef, EventEmitter, Input, Output, Renderer2} from '@angular/core'; +import {AfterContentInit, Directive, ElementRef, EventEmitter, Input, Output, Renderer2, inject} from '@angular/core'; import {rand} from './utils'; import {Direction, IOption, Particles} from './particles'; @@ -7,6 +7,9 @@ import {Direction, IOption, Particles} from './particles'; standalone: true, }) export class ParticleEffectDirective implements AfterContentInit { + private readonly renderer = inject(Renderer2); + private readonly el = inject(ElementRef); + private _particles: Particles | undefined; private _pHidden = false; @Input() public pColor = '#000'; @@ -39,11 +42,6 @@ export class ParticleEffectDirective implements AfterContentInit { return this._pHidden; } - public constructor( - private renderer: Renderer2, - private el: ElementRef, - ) {} - public ngAfterContentInit(): void { this._particles = new Particles(this.el.nativeElement, this.getOptions(), this.renderer); diff --git a/client/app/shared/components/particle-switch/particle-switch.component.ts b/client/app/shared/components/particle-switch/particle-switch.component.ts index d2d32f090..a12362590 100644 --- a/client/app/shared/components/particle-switch/particle-switch.component.ts +++ b/client/app/shared/components/particle-switch/particle-switch.component.ts @@ -1,4 +1,4 @@ -import {AfterViewInit, Component, ContentChild, ElementRef, Input, TemplateRef, ViewChild} from '@angular/core'; +import {AfterViewInit, Component, ContentChild, ElementRef, Input, TemplateRef, ViewChild, inject} from '@angular/core'; import {Direction} from '../particle-button/particles'; import {CommonModule} from '@angular/common'; import {ParticleEffectDirective} from '../particle-button/particle-effect.directive'; @@ -20,6 +20,8 @@ type ParticleSwitchOption = { imports: [ParticleEffectDirective, CommonModule], }) export class ParticleSwitchComponent implements AfterViewInit { + private readonly rootElement = inject>(ElementRef); + @ContentChild(TemplateRef, {static: true}) public template!: TemplateRef; @ViewChild('wrapper', {static: true}) private wrapper!: ElementRef; @@ -75,8 +77,6 @@ export class ParticleSwitchComponent implements AfterViewInit { this.firstDisplay = false; } - public constructor(private readonly rootElement: ElementRef) {} - public ngAfterViewInit(): void { this.updateSize(); } diff --git a/client/app/shared/components/transaction-amount/transaction-amount.component.ts b/client/app/shared/components/transaction-amount/transaction-amount.component.ts index c303115cf..53eb720ba 100644 --- a/client/app/shared/components/transaction-amount/transaction-amount.component.ts +++ b/client/app/shared/components/transaction-amount/transaction-amount.component.ts @@ -1,4 +1,4 @@ -import {Component, EventEmitter, Input, OnChanges, Output} from '@angular/core'; +import {Component, EventEmitter, Input, OnChanges, Output, inject} from '@angular/core'; import {AccountType, MinimalAccount, TransactionLine} from '../../generated-types'; import {TransactionLineService} from '../../../admin/transactions/services/transactionLine.service'; import {RouterLink} from '@angular/router'; @@ -13,6 +13,8 @@ import {CommonModule} from '@angular/common'; imports: [CommonModule, MatTooltipModule, RouterLink], }) export class TransactionAmountComponent implements OnChanges { + public readonly transactionLineService = inject(TransactionLineService); + @Input() public transactionLine: TransactionLine['transactionLine'] | null = null; /** @@ -24,8 +26,6 @@ export class TransactionAmountComponent implements OnChanges { public isIncome: boolean | null = null; - public constructor(public readonly transactionLineService: TransactionLineService) {} - public ngOnChanges(): void { const account = this.relativeToAccount; const transaction = this.transactionLine; diff --git a/client/app/shared/directives/focus.ts b/client/app/shared/directives/focus.ts index d2858f879..3e0e5c442 100644 --- a/client/app/shared/directives/focus.ts +++ b/client/app/shared/directives/focus.ts @@ -1,11 +1,11 @@ -import {AfterViewInit, Directive, ElementRef} from '@angular/core'; +import {AfterViewInit, Directive, ElementRef, inject} from '@angular/core'; @Directive({ selector: '[appFocus]', standalone: true, }) export class FocusDirective implements AfterViewInit { - public constructor(public readonly elementRef: ElementRef) {} + public readonly elementRef = inject>(ElementRef); public ngAfterViewInit(): void { setTimeout(() => this.elementRef.nativeElement.focus()); diff --git a/client/app/shared/natural-search/natural-search-facets.service.ts b/client/app/shared/natural-search/natural-search-facets.service.ts index f50554753..fe395b252 100644 --- a/client/app/shared/natural-search/natural-search-facets.service.ts +++ b/client/app/shared/natural-search/natural-search-facets.service.ts @@ -1,4 +1,4 @@ -import {Injectable} from '@angular/core'; +import {Injectable, inject} from '@angular/core'; import { DropdownFacet, FlagFacet, @@ -67,6 +67,17 @@ function prefixOperatorWithField(selection: NaturalSearchSelection): NaturalSear providedIn: 'root', }) export class NaturalSearchFacetsService { + private readonly enumService = inject(NaturalEnumService); + private readonly userTagService = inject(UserTagService); + private readonly transactionService = inject(TransactionService); + private readonly transactionTagService = inject(TransactionTagService); + private readonly bookableService = inject(BookableService); + private readonly bookableTagService = inject(BookableTagService); + private readonly accountService = inject(AccountService); + private readonly userService = inject(UserService); + private readonly licenceService = inject(LicenseService); + private readonly expenseClaimService = inject(ExpenseClaimService); + private readonly userTags: DropdownFacet> = { display: 'Tags', field: 'userTags', @@ -700,19 +711,6 @@ export class NaturalSearchFacetsService { logs: [this.creationDate, this.creator, this.message], }; - public constructor( - private readonly enumService: NaturalEnumService, - private readonly userTagService: UserTagService, - private readonly transactionService: TransactionService, - private readonly transactionTagService: TransactionTagService, - private readonly bookableService: BookableService, - private readonly bookableTagService: BookableTagService, - private readonly accountService: AccountService, - private readonly userService: UserService, - private readonly licenceService: LicenseService, - private readonly expenseClaimService: ExpenseClaimService, - ) {} - /** * Returns the natural search configuration for given, or null if non-existent */ diff --git a/client/app/shared/services/datatrans.service.ts b/client/app/shared/services/datatrans.service.ts index 23316e377..571c46a2a 100644 --- a/client/app/shared/services/datatrans.service.ts +++ b/client/app/shared/services/datatrans.service.ts @@ -1,4 +1,4 @@ -import {Inject, Injectable} from '@angular/core'; +import {Injectable, inject} from '@angular/core'; import {HmacSHA256} from 'crypto-es/lib/sha256'; import {Hex} from 'crypto-es/lib/core'; import {DOCUMENT} from '@angular/common'; @@ -40,6 +40,8 @@ function stringifyReplacer(key: string, value: unknown): unknown { providedIn: 'root', }) export class DatatransService { + private readonly document = inject(DOCUMENT); + private preservedStyles: {html: string; body: string} = {html: '', body: ''}; private paymentFrame: HTMLDivElement | null = null; private paymentForm: HTMLFormElement | null = null; @@ -59,7 +61,7 @@ export class DatatransService { }, }; - public constructor(@Inject(DOCUMENT) private readonly document: Document) { + public constructor() { const window = this.document.defaultView; if (!window) { throw new Error('Cannot use DatatransService without window'); diff --git a/client/app/shared/services/logger-extra.service.ts b/client/app/shared/services/logger-extra.service.ts index 19da0ff5b..e38dfda71 100644 --- a/client/app/shared/services/logger-extra.service.ts +++ b/client/app/shared/services/logger-extra.service.ts @@ -1,4 +1,4 @@ -import {Injectable} from '@angular/core'; +import {Injectable, inject} from '@angular/core'; import {NaturalLoggerExtra, NaturalLoggerType} from '@ecodev/natural'; import {Observable} from 'rxjs'; import {map} from 'rxjs/operators'; @@ -8,7 +8,7 @@ import {UserService} from '../../admin/users/services/user.service'; providedIn: 'root', }) export class LoggerExtraService implements NaturalLoggerExtra { - public constructor(private readonly userService: UserService) {} + private readonly userService = inject(UserService); public getExtras(): Observable> { return this.userService.getViewer().pipe( diff --git a/client/app/shared/services/network-activity.service.ts b/client/app/shared/services/network-activity.service.ts index 3cb84736e..a4662cb60 100644 --- a/client/app/shared/services/network-activity.service.ts +++ b/client/app/shared/services/network-activity.service.ts @@ -1,4 +1,4 @@ -import {Injectable} from '@angular/core'; +import {Injectable, inject} from '@angular/core'; import {BehaviorSubject, Subject} from 'rxjs'; import {NgProgress} from 'ngx-progressbar'; @@ -6,6 +6,8 @@ import {NgProgress} from 'ngx-progressbar'; providedIn: 'root', }) export class NetworkActivityService { + private readonly progressService = inject(NgProgress); + /** * Count pending requests */ @@ -17,8 +19,6 @@ export class NetworkActivityService { public readonly isPending = new BehaviorSubject(false); public readonly errors = new Subject(); - public constructor(private readonly progressService: NgProgress) {} - public increase(): void { if (this.pending === 0) { this.progressService.ref().start(); diff --git a/client/app/shared/services/permissions.service.ts b/client/app/shared/services/permissions.service.ts index 40131468d..98be496e4 100644 --- a/client/app/shared/services/permissions.service.ts +++ b/client/app/shared/services/permissions.service.ts @@ -1,5 +1,5 @@ import {Apollo} from 'apollo-angular'; -import {Injectable} from '@angular/core'; +import {Injectable, inject} from '@angular/core'; import {Literal} from '@ecodev/natural'; import {BehaviorSubject, Observable} from 'rxjs'; import {concatMap, debounceTime, distinctUntilChanged, filter, map, shareReplay} from 'rxjs/operators'; @@ -32,7 +32,9 @@ export class PermissionsService { user: null, }); - public constructor(apollo: Apollo) { + public constructor() { + const apollo = inject(Apollo); + // Query the API whenever our variables change const fetch = this.currentContexts.pipe( distinctUntilChanged(isEqual), diff --git a/client/app/shared/testing/MockApolloProvider.ts b/client/app/shared/testing/MockApolloProvider.ts index 10171b038..7f22552f0 100644 --- a/client/app/shared/testing/MockApolloProvider.ts +++ b/client/app/shared/testing/MockApolloProvider.ts @@ -1,7 +1,7 @@ import {Apollo} from 'apollo-angular'; import {ApolloClient, InMemoryCache} from '@apollo/client/core'; import {SchemaLink} from '@apollo/client/link/schema'; -import {Injectable, NgZone} from '@angular/core'; +import {Injectable, NgZone, inject} from '@angular/core'; import {buildClientSchema} from 'graphql'; import {addMocksToSchema} from '@graphql-tools/mock'; import {schema as introspectionResult} from './../../../../data/tmp/schema'; @@ -14,7 +14,9 @@ import {apolloDefaultOptions, cacheConfig} from '../config/apollo-options.provid providedIn: 'root', }) class MockApollo extends Apollo { - public constructor(ngZone: NgZone) { + public constructor() { + const ngZone = inject(NgZone); + super(ngZone); this.client = this.createMockClient(); } diff --git a/client/app/user/components/change-password/change-password.component.ts b/client/app/user/components/change-password/change-password.component.ts index 245d57ab9..373e7e0db 100644 --- a/client/app/user/components/change-password/change-password.component.ts +++ b/client/app/user/components/change-password/change-password.component.ts @@ -1,5 +1,5 @@ import {Apollo, gql} from 'apollo-angular'; -import {Component} from '@angular/core'; +import {Component, inject} from '@angular/core'; import {ActivatedRoute, Router} from '@angular/router'; import {ifValid, NaturalAlertService, NaturalIconDirective} from '@ecodev/natural'; import {FormsModule, NonNullableFormBuilder, ReactiveFormsModule} from '@angular/forms'; @@ -24,16 +24,17 @@ import {PasswordComponent} from '../password/password.component'; ], }) export class ChangePasswordComponent { + private readonly apollo = inject(Apollo); + private readonly alertService = inject(NaturalAlertService); + private readonly router = inject(Router); + private readonly fb = inject(NonNullableFormBuilder); + private readonly token: string; public readonly form = this.fb.group({password: ['']}); - public constructor( - route: ActivatedRoute, - private readonly apollo: Apollo, - private readonly alertService: NaturalAlertService, - private readonly router: Router, - private readonly fb: NonNullableFormBuilder, - ) { + public constructor() { + const route = inject(ActivatedRoute); + this.token = route.snapshot.params.token; } diff --git a/client/app/user/components/register/register-confirm.component.ts b/client/app/user/components/register/register-confirm.component.ts index e5b7e4bc5..5436b1bc5 100644 --- a/client/app/user/components/register/register-confirm.component.ts +++ b/client/app/user/components/register/register-confirm.component.ts @@ -1,14 +1,11 @@ -import {Apollo} from 'apollo-angular'; -import {Component, OnInit} from '@angular/core'; -import {available, deliverableEmail, NaturalAlertService, NaturalIconDirective, relationsToIds} from '@ecodev/natural'; +import {Component, inject, OnInit} from '@angular/core'; +import {available, deliverableEmail, NaturalIconDirective, relationsToIds} from '@ecodev/natural'; import {pick} from 'lodash-es'; import {RegisterComponent} from './register.component'; -import {FormsModule, NonNullableFormBuilder, ReactiveFormsModule, Validators} from '@angular/forms'; +import {FormsModule, ReactiveFormsModule, Validators} from '@angular/forms'; import {loginValidator, UserService} from '../../../admin/users/services/user.service'; -import {ActivatedRoute, Router} from '@angular/router'; import {UserByTokenResolve} from '../../../admin/users/user'; import {ConfirmRegistrationVariables, UserByToken} from '../../../shared/generated-types'; -import {BookableService} from '../../../admin/bookables/services/bookable.service'; import {MatButtonModule} from '@angular/material/button'; import {MatCheckboxModule} from '@angular/material/checkbox'; import {MatTableModule} from '@angular/material/table'; @@ -44,16 +41,10 @@ import {MatFormFieldModule} from '@angular/material/form-field'; ], }) export class RegisterConfirmComponent extends RegisterComponent implements OnInit { - public constructor( - apollo: Apollo, - route: ActivatedRoute, - fb: NonNullableFormBuilder, - router: Router, - alertService: NaturalAlertService, - bookableService: BookableService, - private readonly userService: UserService, - ) { - super(apollo, route, fb, router, alertService, bookableService); + private readonly userService = inject(UserService); + + public constructor() { + super(); this.step = 2; } diff --git a/client/app/user/components/register/register.component.ts b/client/app/user/components/register/register.component.ts index 378451db4..3dc6ba820 100644 --- a/client/app/user/components/register/register.component.ts +++ b/client/app/user/components/register/register.component.ts @@ -1,5 +1,5 @@ import {Apollo, gql} from 'apollo-angular'; -import {Component, OnInit} from '@angular/core'; +import {Component, OnInit, inject} from '@angular/core'; import { deliverableEmail, ifValid, @@ -47,21 +47,19 @@ import {MatFormFieldModule} from '@angular/material/form-field'; ], }) export class RegisterComponent implements OnInit { + protected readonly apollo = inject(Apollo); + protected readonly route = inject(ActivatedRoute); + protected readonly fb = inject(NonNullableFormBuilder); + protected readonly router = inject(Router); + protected readonly alertService = inject(NaturalAlertService); + protected readonly bookableService = inject(BookableService); + public mandatoryBookables: NaturalDataSource | null = null; public step: 1 | 2 = 1; public sending = false; public form!: FormGroup; - public constructor( - protected readonly apollo: Apollo, - protected readonly route: ActivatedRoute, - protected readonly fb: NonNullableFormBuilder, - protected readonly router: Router, - protected readonly alertService: NaturalAlertService, - protected readonly bookableService: BookableService, - ) {} - public ngOnInit(): void { this.fetchMandatoryBookables(); this.initForm(); diff --git a/client/app/user/components/request-password-reset/request-password-reset.component.ts b/client/app/user/components/request-password-reset/request-password-reset.component.ts index 80091e845..473e6cf82 100644 --- a/client/app/user/components/request-password-reset/request-password-reset.component.ts +++ b/client/app/user/components/request-password-reset/request-password-reset.component.ts @@ -1,5 +1,5 @@ import {Apollo} from 'apollo-angular'; -import {Component} from '@angular/core'; +import {Component, inject} from '@angular/core'; import {FormControl, FormGroup, Validators, FormsModule, ReactiveFormsModule} from '@angular/forms'; import {Router} from '@angular/router'; import {UserService} from '../../../admin/users/services/user.service'; @@ -25,15 +25,15 @@ import {MatFormFieldModule} from '@angular/material/form-field'; ], }) export class RequestPasswordResetComponent { + private readonly apollo = inject(Apollo); + private readonly alertService = inject(NaturalAlertService); + private readonly router = inject(Router); + private readonly userService = inject(UserService); + public readonly form: FormGroup; public sending = false; - public constructor( - private readonly apollo: Apollo, - private readonly alertService: NaturalAlertService, - private readonly router: Router, - private readonly userService: UserService, - ) { + public constructor() { this.form = new FormGroup({login: new FormControl('', [Validators.required])}); } diff --git a/package.json b/package.json index 212a63dbb..b817684fc 100644 --- a/package.json +++ b/package.json @@ -29,8 +29,8 @@ "@angular/router": "^18.2.3", "@apollo/client": "~3.10.8", "@ecodev/fab-speed-dial": "^17.0.0", - "@ecodev/natural": "^61.0.0", - "@ecodev/natural-editor": "^61.0.0", + "@ecodev/natural": "^61.0.1", + "@ecodev/natural-editor": "^61.0.1", "@ecodev/natural-layout": "^2.0.2", "@graphql-codegen/cli": "^5.0.2", "@graphql-codegen/typescript-apollo-angular": "^4.0.0", diff --git a/yarn.lock b/yarn.lock index 4759084d0..89af5e1f4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1639,10 +1639,10 @@ dependencies: tslib "^2.6" -"@ecodev/natural-editor@^61.0.0": - version "61.0.0" - resolved "https://registry.yarnpkg.com/@ecodev/natural-editor/-/natural-editor-61.0.0.tgz#a1db404dde0b4ab30255069e5b64a6f006f5f62c" - integrity sha512-YounDLzECmOMJCrgkBbkE2Ue/JpjnKHOug0r3BQZElLQQplrcMZBT2qox6D68agmvXNEO45mninPWyl1vRy9bw== +"@ecodev/natural-editor@^61.0.1": + version "61.0.1" + resolved "https://registry.yarnpkg.com/@ecodev/natural-editor/-/natural-editor-61.0.1.tgz#ae75cc3bbab025ba38e6854b94dcb03fa1bfdda6" + integrity sha512-mSclDuR6TPp5QZ1vJc2TAaDTI3cOJsPgBu7zv3ZkKTxzHqVKGD6/vTI5rbDrfORhCRRHAgrj4hjJY8PgBICwwQ== dependencies: prosemirror-commands "^1.5.2" prosemirror-dropcursor "^1.8.1" @@ -1664,10 +1664,10 @@ resolved "https://registry.yarnpkg.com/@ecodev/natural-layout/-/natural-layout-2.0.2.tgz#e2c64c2ddb3c60793a39236b52624fde323e610a" integrity sha512-BV75kFQmpfuSBNQ1jyKu+IdGkFTMESjPrtKrEyc3MqcmVhV5IiYU0LXTaghLZozuZgCT9HfMOnEsh05aS2j9uQ== -"@ecodev/natural@^61.0.0": - version "61.0.0" - resolved "https://registry.yarnpkg.com/@ecodev/natural/-/natural-61.0.0.tgz#6d428c8288c0f7c5372b978d3f6572c9b96f943f" - integrity sha512-hGwGFiIykME9KsjcR4u9pLw4nu98/MG4aa3yteOyLTZK553cFuhCK/5d/sZ+tE7ebTIfSU/bmHBhw9jJJ9AScg== +"@ecodev/natural@^61.0.1": + version "61.0.1" + resolved "https://registry.yarnpkg.com/@ecodev/natural/-/natural-61.0.1.tgz#a45308883e33c23cf7f384fc512bd18a8ae5ec8b" + integrity sha512-vDAMc69w8eUaIVZXa4TkL4u/LYkwytkFhaVLDbpAc3oy+i+/VJERYUCckh5Ly8xYTHtrSnymvdCPlboZr2zvfQ== dependencies: crypto-es "^2.0.3" extract-files "^13.0.0"