mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-09-09 18:03:21 +00:00
Migrate to @angular-eslint/prefer-inject and @typescript-eslint/prefer-readonly (#11665)
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ChangeDetectionStrategy, Component, Input, ViewEncapsulation } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, Input, ViewEncapsulation, inject } from '@angular/core';
|
||||
import { LicenseData } from '../interfaces';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { TranslatePipe, TranslateService } from '@ngx-translate/core';
|
||||
@@ -30,6 +30,8 @@ import { MatTableModule } from '@angular/material/table';
|
||||
imports: [CommonModule, TranslatePipe, MatTableModule]
|
||||
})
|
||||
export class AboutLicenseListComponent {
|
||||
private readonly translateService = inject(TranslateService);
|
||||
|
||||
columns = [
|
||||
{
|
||||
columnDef: 'property',
|
||||
@@ -64,6 +66,4 @@ export class AboutLicenseListComponent {
|
||||
|
||||
@Input({ required: true })
|
||||
data: LicenseData[] = [];
|
||||
|
||||
constructor(private readonly translateService: TranslateService) {}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { Component, OnInit, ViewEncapsulation, inject } from '@angular/core';
|
||||
import { AppConfigService, AppConfigValues } from '../../app-config/app-config.service';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
@@ -29,11 +29,11 @@ import { MatCardModule } from '@angular/material/card';
|
||||
imports: [CommonModule, TranslatePipe, MatCardModule]
|
||||
})
|
||||
export class AboutServerSettingsComponent implements OnInit {
|
||||
private readonly appConfig = inject(AppConfigService);
|
||||
|
||||
ecmHost = '';
|
||||
bpmHost = '';
|
||||
|
||||
constructor(private appConfig: AppConfigService) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.ecmHost = this.appConfig.get(AppConfigValues.ECMHOST);
|
||||
this.bpmHost = this.appConfig.get(AppConfigValues.BPMHOST);
|
||||
|
||||
@@ -30,7 +30,7 @@ import { BehaviorSubject, Observable } from 'rxjs';
|
||||
})
|
||||
export class AppExtensionServiceMock {
|
||||
references$: Observable<ExtensionRef[]>;
|
||||
private _references = new BehaviorSubject<ExtensionRef[]>([]);
|
||||
private readonly _references = new BehaviorSubject<ExtensionRef[]>([]);
|
||||
|
||||
constructor() {
|
||||
this.references$ = this._references.asObservable();
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
*/
|
||||
|
||||
import { of } from 'rxjs';
|
||||
import { StoragePrefixFactory, StoragePrefixFactoryService } from './app-config-storage-prefix.factory';
|
||||
import { StoragePrefixFactory, StoragePrefixFactoryService, STORAGE_PREFIX_FACTORY_SERVICE } from './app-config-storage-prefix.factory';
|
||||
import { AppConfigService } from './app-config.service';
|
||||
import { Injector, runInInjectionContext } from '@angular/core';
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
type TestAppConfigService = Pick<AppConfigService, 'select'>;
|
||||
|
||||
@@ -31,7 +33,12 @@ describe('StoragePrefixFactory', () => {
|
||||
}
|
||||
};
|
||||
|
||||
const prefixFactory = new StoragePrefixFactory(appConfigService as AppConfigService);
|
||||
const injector = Injector.create({
|
||||
providers: [{ provide: AppConfigService, useValue: appConfigService }],
|
||||
parent: TestBed.inject(Injector)
|
||||
});
|
||||
|
||||
const prefixFactory = runInInjectionContext(injector, () => new StoragePrefixFactory());
|
||||
|
||||
prefixFactory.getPrefix().subscribe((prefix) => {
|
||||
expect(prefix).toBe(appConfigPrefix);
|
||||
@@ -47,7 +54,12 @@ describe('StoragePrefixFactory', () => {
|
||||
}
|
||||
};
|
||||
|
||||
const prefixFactory = new StoragePrefixFactory(appConfigService as AppConfigService);
|
||||
const injector = Injector.create({
|
||||
providers: [{ provide: AppConfigService, useValue: appConfigService }],
|
||||
parent: TestBed.inject(Injector)
|
||||
});
|
||||
|
||||
const prefixFactory = runInInjectionContext(injector, () => new StoragePrefixFactory());
|
||||
|
||||
prefixFactory.getPrefix().subscribe((prefix) => {
|
||||
expect(prefix).toBe(appConfigPrefix);
|
||||
@@ -69,7 +81,15 @@ describe('StoragePrefixFactory', () => {
|
||||
}
|
||||
};
|
||||
|
||||
const prefixFactory = new StoragePrefixFactory(appConfigService as AppConfigService, externalPrefixFactory);
|
||||
const injector = Injector.create({
|
||||
providers: [
|
||||
{ provide: AppConfigService, useValue: appConfigService },
|
||||
{ provide: STORAGE_PREFIX_FACTORY_SERVICE, useValue: externalPrefixFactory }
|
||||
],
|
||||
parent: TestBed.inject(Injector)
|
||||
});
|
||||
|
||||
const prefixFactory = runInInjectionContext(injector, () => new StoragePrefixFactory());
|
||||
|
||||
prefixFactory.getPrefix().subscribe((prefix) => {
|
||||
expect(prefix).toBe('prefix-from-factory');
|
||||
@@ -92,7 +112,15 @@ describe('StoragePrefixFactory', () => {
|
||||
}
|
||||
};
|
||||
|
||||
const prefixFactory = new StoragePrefixFactory(appConfigService as AppConfigService, externalPrefixFactory);
|
||||
const injector = Injector.create({
|
||||
providers: [
|
||||
{ provide: AppConfigService, useValue: appConfigService },
|
||||
{ provide: STORAGE_PREFIX_FACTORY_SERVICE, useValue: externalPrefixFactory }
|
||||
],
|
||||
parent: TestBed.inject(Injector)
|
||||
});
|
||||
|
||||
const prefixFactory = runInInjectionContext(injector, () => new StoragePrefixFactory());
|
||||
|
||||
prefixFactory.getPrefix().subscribe((prefix) => {
|
||||
expect(prefix).toBe(appConfigPrefix);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Inject, Injectable, InjectionToken, Optional } from '@angular/core';
|
||||
import { Injectable, InjectionToken, inject } from '@angular/core';
|
||||
import { AppConfigService, AppConfigValues } from './app-config.service';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { switchMap } from 'rxjs/operators';
|
||||
@@ -30,12 +30,8 @@ export const STORAGE_PREFIX_FACTORY_SERVICE = new InjectionToken<StoragePrefixFa
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class StoragePrefixFactory {
|
||||
constructor(
|
||||
private appConfigService: AppConfigService,
|
||||
@Optional()
|
||||
@Inject(STORAGE_PREFIX_FACTORY_SERVICE)
|
||||
private storagePrefixFactory?: StoragePrefixFactoryService
|
||||
) {}
|
||||
private readonly appConfigService = inject(AppConfigService);
|
||||
private readonly storagePrefixFactory = inject<StoragePrefixFactoryService>(STORAGE_PREFIX_FACTORY_SERVICE, { optional: true });
|
||||
|
||||
getPrefix(): Observable<string | undefined> {
|
||||
return this.appConfigService.select(AppConfigValues.STORAGE_PREFIX).pipe(
|
||||
|
||||
@@ -15,14 +15,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import { Pipe, PipeTransform, inject } from '@angular/core';
|
||||
import { AppConfigService } from './app-config.service';
|
||||
|
||||
@Pipe({
|
||||
name: 'adfAppConfig'
|
||||
})
|
||||
export class AppConfigPipe implements PipeTransform {
|
||||
constructor(private config: AppConfigService) {}
|
||||
private readonly config = inject(AppConfigService);
|
||||
|
||||
transform(value: string, fallback?: any): any {
|
||||
return this.config.get(value, fallback);
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import { throwError as observableThrowError, Observable } from 'rxjs';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import {
|
||||
HttpHandler,
|
||||
HttpInterceptor,
|
||||
@@ -33,12 +33,12 @@ import { AuthenticationService } from '../services/authentication.service';
|
||||
|
||||
@Injectable()
|
||||
export class AuthBearerInterceptor implements HttpInterceptor {
|
||||
private _bearerExcludedUrls: readonly string[] = ['resources/', 'assets/', 'auth/realms', 'idp/'];
|
||||
private readonly authenticationService = inject(AuthenticationService);
|
||||
|
||||
private readonly _bearerExcludedUrls: readonly string[] = ['resources/', 'assets/', 'auth/realms', 'idp/'];
|
||||
|
||||
private excludedUrlsRegex: RegExp[];
|
||||
|
||||
constructor(private authenticationService: AuthenticationService) {}
|
||||
|
||||
private loadExcludedUrlsRegex() {
|
||||
const excludedUrls = this.bearerExcludedUrls;
|
||||
this.excludedUrlsRegex = excludedUrls.map((urlPattern) => new RegExp(`^https?://[^/]+/${urlPattern}`, 'i')) || [];
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { AppConfigService, AppConfigValues } from '../../app-config/app-config.service';
|
||||
import { Authentication } from '../interfaces/authentication.interface';
|
||||
import { CookieService } from '../../common/services/cookie.service';
|
||||
@@ -34,6 +34,9 @@ const REMEMBER_ME_UNTIL = 1000 * 60 * 60 * 24 * 30;
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class BasicAlfrescoAuthService extends BaseAuthenticationService {
|
||||
private readonly contentAuth = inject(ContentAuth);
|
||||
private readonly processAuth = inject(ProcessAuth);
|
||||
|
||||
protected redirectUrl: RedirectionModel = null;
|
||||
|
||||
authentications: Authentication = {
|
||||
@@ -43,12 +46,10 @@ export class BasicAlfrescoAuthService extends BaseAuthenticationService {
|
||||
type: 'basic'
|
||||
};
|
||||
|
||||
constructor(
|
||||
appConfig: AppConfigService,
|
||||
cookie: CookieService,
|
||||
private readonly contentAuth: ContentAuth,
|
||||
private readonly processAuth: ProcessAuth
|
||||
) {
|
||||
constructor() {
|
||||
const appConfig = inject(AppConfigService);
|
||||
const cookie = inject(CookieService);
|
||||
|
||||
super(appConfig, cookie);
|
||||
|
||||
this.appConfig.onLoad.subscribe(() => {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { AdfHttpClient } from '@alfresco/adf-core/api';
|
||||
import { AppConfigService, AppConfigValues } from '../../app-config/app-config.service';
|
||||
import { StorageService } from '../../common/services/storage.service';
|
||||
@@ -38,6 +38,10 @@ export interface TicketEntry {
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ContentAuth {
|
||||
private readonly appConfigService = inject(AppConfigService);
|
||||
private readonly adfHttpClient = inject(AdfHttpClient);
|
||||
private readonly storageService = inject(StorageService);
|
||||
|
||||
onLogin = new ReplaySubject<any>(1);
|
||||
onLogout = new ReplaySubject<any>(1);
|
||||
onError = new Subject<any>();
|
||||
@@ -59,7 +63,7 @@ export class ContentAuth {
|
||||
return this.appConfigService.get<string>(AppConfigValues.ECMHOST) + '/' + contextRootEcm + '/api/-default-/public/authentication/versions/1';
|
||||
}
|
||||
|
||||
constructor(private appConfigService: AppConfigService, private adfHttpClient: AdfHttpClient, private storageService: StorageService) {
|
||||
constructor() {
|
||||
this.appConfigService.onLoad.subscribe(() => {
|
||||
this.setConfig();
|
||||
});
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { AdfHttpClient } from '@alfresco/adf-core/api';
|
||||
import { Authentication } from '../interfaces/authentication.interface';
|
||||
import { AppConfigService, AppConfigValues } from '../../app-config/app-config.service';
|
||||
@@ -26,6 +26,10 @@ import { ReplaySubject, Subject } from 'rxjs';
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ProcessAuth {
|
||||
private readonly appConfigService = inject(AppConfigService);
|
||||
private readonly adfHttpClient = inject(AdfHttpClient);
|
||||
private readonly storageService = inject(StorageService);
|
||||
|
||||
onLogin = new ReplaySubject<any>(1);
|
||||
onLogout = new ReplaySubject<any>(1);
|
||||
onError = new Subject<any>();
|
||||
@@ -45,7 +49,7 @@ export class ProcessAuth {
|
||||
return this.appConfigService.get<string>(AppConfigValues.BPMHOST) + '/' + contextRootBpm;
|
||||
}
|
||||
|
||||
constructor(private appConfigService: AppConfigService, private adfHttpClient: AdfHttpClient, private storageService: StorageService) {
|
||||
constructor() {
|
||||
this.appConfigService.onLoad.subscribe(() => {
|
||||
this.setConfig();
|
||||
});
|
||||
|
||||
@@ -23,21 +23,19 @@ import { MatDialog } from '@angular/material/dialog';
|
||||
import { StorageService } from '../../common/services/storage.service';
|
||||
import { BasicAlfrescoAuthService } from '../basic-auth/basic-alfresco-auth.service';
|
||||
import { OidcAuthenticationService } from '../oidc/oidc-authentication.service';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class AuthGuardService {
|
||||
constructor(
|
||||
private authenticationService: AuthenticationService,
|
||||
private basicAlfrescoAuthService: BasicAlfrescoAuthService,
|
||||
private oidcAuthenticationService: OidcAuthenticationService,
|
||||
private router: Router,
|
||||
private appConfigService: AppConfigService,
|
||||
private dialog: MatDialog,
|
||||
private storageService: StorageService
|
||||
) {}
|
||||
private readonly authenticationService = inject(AuthenticationService);
|
||||
private readonly basicAlfrescoAuthService = inject(BasicAlfrescoAuthService);
|
||||
private readonly oidcAuthenticationService = inject(OidcAuthenticationService);
|
||||
private readonly router = inject(Router);
|
||||
private readonly appConfigService = inject(AppConfigService);
|
||||
private readonly dialog = inject(MatDialog);
|
||||
private readonly storageService = inject(StorageService);
|
||||
|
||||
get withCredentials(): boolean {
|
||||
return this.appConfigService.get<boolean>('auth.withCredentials', false);
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { HttpClientTestingModule } from '@angular/common/http/testing';
|
||||
import { provideHttpClient } from '@angular/common/http';
|
||||
import { provideHttpClientTesting } from '@angular/common/http/testing';
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { of } from 'rxjs';
|
||||
import { AppConfigService } from '../../app-config/app-config.service';
|
||||
@@ -90,8 +91,7 @@ describe('AuthConfigService', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [HttpClientTestingModule],
|
||||
providers: [{ provide: AUTH_MODULE_CONFIG, useValue: { useHash: true } }]
|
||||
providers: [{ provide: AUTH_MODULE_CONFIG, useValue: { useHash: true } }, provideHttpClient(), provideHttpClientTesting()]
|
||||
});
|
||||
service = TestBed.inject(AuthConfigService);
|
||||
spyOn<any>(service, 'getLocationOrigin').and.returnValue('http://localhost:3000');
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { AuthConfig } from 'angular-oauth2-oidc';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { AppConfigService } from '../../app-config/app-config.service';
|
||||
@@ -37,12 +37,10 @@ export function authConfigFactory(authConfigService: AuthConfigService): Promise
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class AuthConfigService {
|
||||
constructor(
|
||||
private appConfigService: AppConfigService,
|
||||
@Inject(AUTH_MODULE_CONFIG) private readonly authModuleConfig: AuthModuleConfig
|
||||
) {}
|
||||
private readonly appConfigService = inject(AppConfigService);
|
||||
private readonly authModuleConfig = inject<AuthModuleConfig>(AUTH_MODULE_CONFIG);
|
||||
|
||||
private _authConfig!: AuthConfig;
|
||||
private readonly _authConfig!: AuthConfig;
|
||||
get authConfig(): AuthConfig {
|
||||
return this._authConfig;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,11 @@ import { HttpHeaders } from '@angular/common/http';
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class OidcAuthenticationService extends BaseAuthenticationService {
|
||||
private readonly jwtHelperService = inject(JwtHelperService);
|
||||
private readonly authStorage = inject(OAuthStorage);
|
||||
private readonly oauthService = inject(OAuthService);
|
||||
private readonly authConfig = inject(AuthConfigService);
|
||||
|
||||
private readonly auth = inject(AuthService);
|
||||
|
||||
/**
|
||||
@@ -46,14 +51,10 @@ export class OidcAuthenticationService extends BaseAuthenticationService {
|
||||
map(([authenticated, isDiscoveryDocumentLoaded]) => !authenticated && isDiscoveryDocumentLoaded)
|
||||
);
|
||||
|
||||
constructor(
|
||||
appConfig: AppConfigService,
|
||||
cookie: CookieService,
|
||||
private jwtHelperService: JwtHelperService,
|
||||
private authStorage: OAuthStorage,
|
||||
private oauthService: OAuthService,
|
||||
private readonly authConfig: AuthConfigService
|
||||
) {
|
||||
constructor() {
|
||||
const appConfig = inject(AppConfigService);
|
||||
const cookie = inject(CookieService);
|
||||
|
||||
super(appConfig, cookie);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Inject, Injectable, inject } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import {
|
||||
AuthConfig,
|
||||
AUTH_CONFIG,
|
||||
@@ -40,12 +40,15 @@ const isPromise = <T>(value: T | Promise<T>): value is Promise<T> => value && ty
|
||||
|
||||
@Injectable()
|
||||
export class RedirectAuthService extends AuthService {
|
||||
private readonly oauthService = inject(OAuthService);
|
||||
private readonly _oauthStorage = inject(OAuthStorage);
|
||||
|
||||
readonly authModuleConfig: AuthModuleConfig = inject(AUTH_MODULE_CONFIG);
|
||||
private readonly _retryLoginService: RetryLoginService = inject(RetryLoginService);
|
||||
private readonly _oauthLogger: OAuthLogger = inject(OAuthLogger);
|
||||
private readonly _timeSyncService: TimeSyncService = inject(TimeSyncService);
|
||||
|
||||
private _isDiscoveryDocumentLoadedSubject$ = new ReplaySubject<boolean>();
|
||||
private readonly _isDiscoveryDocumentLoadedSubject$ = new ReplaySubject<boolean>();
|
||||
public isDiscoveryDocumentLoaded$ = this._isDiscoveryDocumentLoadedSubject$.asObservable();
|
||||
|
||||
onLogin: Observable<any>;
|
||||
@@ -119,7 +122,7 @@ export class RedirectAuthService extends AuthService {
|
||||
return this.oauthService.hasValidIdToken() && this.oauthService.hasValidAccessToken();
|
||||
}
|
||||
|
||||
private authConfig!: AuthConfig | Promise<AuthConfig>;
|
||||
private readonly authConfig!: AuthConfig | Promise<AuthConfig>;
|
||||
|
||||
private readonly AUTH_STORAGE_ITEMS: string[] = [
|
||||
'access_token',
|
||||
@@ -136,8 +139,11 @@ export class RedirectAuthService extends AuthService {
|
||||
'session_state'
|
||||
];
|
||||
|
||||
constructor(private oauthService: OAuthService, private _oauthStorage: OAuthStorage, @Inject(AUTH_CONFIG) authConfig: AuthConfig) {
|
||||
constructor() {
|
||||
const authConfig = inject<AuthConfig>(AUTH_CONFIG);
|
||||
|
||||
super();
|
||||
const oauthService = this.oauthService;
|
||||
|
||||
this.authConfig = authConfig;
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import { LoginOptions, OAuthErrorEvent, OAuthService } from 'angular-oauth2-oidc
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class RetryLoginService {
|
||||
private oauthService = inject(OAuthService);
|
||||
private readonly oauthService = inject(OAuthService);
|
||||
|
||||
/**
|
||||
* Attempts to log in a specified number of times if the initial login attempt fails.
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { HTTP_INTERCEPTORS, HttpClient } from '@angular/common/http';
|
||||
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
|
||||
import { HTTP_INTERCEPTORS, HttpClient, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
|
||||
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { OAuthService, OAuthStorage } from 'angular-oauth2-oidc';
|
||||
import { TokenInterceptor } from './token.interceptor';
|
||||
@@ -38,7 +38,6 @@ describe('TokenInterceptor', () => {
|
||||
};
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
imports: [HttpClientTestingModule],
|
||||
providers: [
|
||||
{ provide: OAuthService, useValue: oauthServiceMock },
|
||||
{ provide: OAuthStorage, useValue: oauthStorageMock },
|
||||
@@ -46,7 +45,9 @@ describe('TokenInterceptor', () => {
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: TokenInterceptor,
|
||||
multi: true
|
||||
}
|
||||
},
|
||||
provideHttpClient(withInterceptorsFromDi()),
|
||||
provideHttpClientTesting()
|
||||
]
|
||||
});
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { AuthenticationService } from './authentication.service';
|
||||
import { CookieService } from '../../common/services/cookie.service';
|
||||
import { Injector, runInInjectionContext } from '@angular/core';
|
||||
import { AppConfigService } from '../../app-config/app-config.service';
|
||||
import { BasicAlfrescoAuthService } from '../basic-auth/basic-alfresco-auth.service';
|
||||
import { provideCoreAuth } from '../oidc/auth.module';
|
||||
@@ -28,7 +29,6 @@ import { OidcAuthenticationService } from '../oidc/oidc-authentication.service';
|
||||
import { OAuthEvent } from 'angular-oauth2-oidc';
|
||||
import { firstValueFrom, of, Subject, throwError } from 'rxjs';
|
||||
import { RedirectAuthService } from '../oidc/redirect-auth.service';
|
||||
import { Injector } from '@angular/core';
|
||||
import { ContentAuth, ProcessAuth } from '../public-api';
|
||||
|
||||
declare let jasmine: any;
|
||||
@@ -335,8 +335,15 @@ describe('AuthenticationService', () => {
|
||||
redirectAuthService = TestBed.inject(RedirectAuthService);
|
||||
redirectAuthService.onTokenReceived = onTokenReceived$;
|
||||
|
||||
const injector = TestBed.inject(Injector);
|
||||
authenticationService = new AuthenticationService(injector, redirectAuthService);
|
||||
const injector = Injector.create({
|
||||
providers: [
|
||||
{ provide: Injector, useValue: TestBed.inject(Injector) },
|
||||
{ provide: RedirectAuthService, useValue: redirectAuthService }
|
||||
],
|
||||
parent: TestBed.inject(Injector)
|
||||
});
|
||||
|
||||
authenticationService = runInInjectionContext(injector, () => new AuthenticationService());
|
||||
});
|
||||
|
||||
it('should emit event when RedirectAuthService onTokenReceived emits', () => {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { Injectable, Injector, inject } from '@angular/core';
|
||||
import { OidcAuthenticationService } from '../oidc/oidc-authentication.service';
|
||||
import { BasicAlfrescoAuthService } from '../basic-auth/basic-alfresco-auth.service';
|
||||
import { Observable, Subject, from } from 'rxjs';
|
||||
@@ -28,14 +28,14 @@ type EventEmitterInstance = InstanceType<typeof EventEmitter>;
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class AuthenticationService implements AuthenticationServiceInterface {
|
||||
private readonly injector = inject(Injector);
|
||||
private readonly redirectAuthService = inject(RedirectAuthService);
|
||||
|
||||
onLogin: Subject<any> = new Subject<any>();
|
||||
onLogout: Subject<any> = new Subject<any>();
|
||||
onTokenReceived: Subject<any> = new Subject<any>();
|
||||
|
||||
constructor(
|
||||
private readonly injector: Injector,
|
||||
private readonly redirectAuthService: RedirectAuthService
|
||||
) {
|
||||
constructor() {
|
||||
this.redirectAuthService.onLogin.subscribe((value) => this.onLogin.next(value));
|
||||
|
||||
this.redirectAuthService.onTokenReceived.subscribe((value) => this.onTokenReceived.next(value));
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { AppConfigService } from '../../app-config/app-config.service';
|
||||
@@ -32,7 +32,8 @@ import { OAuth2Service } from './oauth2.service';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class IdentityGroupService implements IdentityGroupServiceInterface {
|
||||
constructor(private oAuth2Service: OAuth2Service, private appConfigService: AppConfigService) {}
|
||||
private readonly oAuth2Service = inject(OAuth2Service);
|
||||
private readonly appConfigService = inject(AppConfigService);
|
||||
|
||||
private get identityHost(): string {
|
||||
return `${this.appConfigService.get('identityHost')}`;
|
||||
@@ -133,7 +134,7 @@ export class IdentityGroupService implements IdentityGroupServiceInterface {
|
||||
hasMoreItems: false,
|
||||
totalItems: totalCount.count
|
||||
}
|
||||
} as IdentityGroupQueryResponse)
|
||||
}) as IdentityGroupQueryResponse
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
@@ -32,10 +32,13 @@ export interface IdentityRoleResponseModel {
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class IdentityRoleService {
|
||||
protected http = inject(HttpClient);
|
||||
protected appConfig = inject(AppConfigService);
|
||||
|
||||
contextRoot = '';
|
||||
identityHost = '';
|
||||
|
||||
constructor(protected http: HttpClient, protected appConfig: AppConfigService) {
|
||||
constructor() {
|
||||
this.contextRoot = this.appConfig.get('apiHost', '');
|
||||
this.identityHost = this.appConfig.get('identityHost');
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { firstValueFrom, Observable, of } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { AppConfigService } from '../../app-config/app-config.service';
|
||||
@@ -36,11 +36,9 @@ import { OAuth2Service } from './oauth2.service';
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class IdentityUserService implements IdentityUserServiceInterface {
|
||||
constructor(
|
||||
private jwtHelperService: JwtHelperService,
|
||||
private oAuth2Service: OAuth2Service,
|
||||
private appConfigService: AppConfigService
|
||||
) {}
|
||||
private readonly jwtHelperService = inject(JwtHelperService);
|
||||
private readonly oAuth2Service = inject(OAuth2Service);
|
||||
private readonly appConfigService = inject(AppConfigService);
|
||||
|
||||
private get identityHost(): string {
|
||||
return `${this.appConfigService.get('identityHost')}`;
|
||||
|
||||
@@ -33,7 +33,7 @@ export class JwtHelperService {
|
||||
static USER_PREFERRED_USERNAME = 'preferred_username';
|
||||
static HXP_AUTHORIZATION = 'hxp_authorization';
|
||||
|
||||
private storageService: OAuthStorage = inject(OAuthStorage);
|
||||
private readonly storageService: OAuthStorage = inject(OAuthStorage);
|
||||
|
||||
/**
|
||||
* Decodes a JSON web token into a JS object.
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { Observable, from } from 'rxjs';
|
||||
import { AdfHttpClient } from '@alfresco/adf-core/api';
|
||||
|
||||
@@ -31,7 +31,7 @@ export interface OAuth2RequestParams {
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class OAuth2Service {
|
||||
constructor(private adfHttpClient: AdfHttpClient) {}
|
||||
private readonly adfHttpClient = inject(AdfHttpClient);
|
||||
|
||||
request<T>(opts: OAuth2RequestParams): Observable<T> {
|
||||
const { httpMethod, url, bodyParam, queryParams } = opts;
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
|
||||
import { provideHttpClient } from '@angular/common/http';
|
||||
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { AppConfigService } from '../../app-config/app-config.service';
|
||||
import { TimeSyncService } from './time-sync.service';
|
||||
@@ -30,8 +31,7 @@ describe('TimeSyncService', () => {
|
||||
appConfigSpy = jasmine.createSpyObj('AppConfigService', ['get']);
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
imports: [HttpClientTestingModule],
|
||||
providers: [TimeSyncService, { provide: AppConfigService, useValue: appConfigSpy }]
|
||||
providers: [TimeSyncService, { provide: AppConfigService, useValue: appConfigSpy }, provideHttpClient(), provideHttpClientTesting()]
|
||||
});
|
||||
|
||||
service = TestBed.inject(TimeSyncService);
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import { Injectable, Injector, inject } from '@angular/core';
|
||||
import { AppConfigService } from '../../app-config/app-config.service';
|
||||
import { from, Observable, throwError } from 'rxjs';
|
||||
import { catchError, map, timeout } from 'rxjs/operators';
|
||||
@@ -32,9 +32,12 @@ export interface TimeSync {
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class TimeSyncService {
|
||||
private readonly _injector = inject(Injector);
|
||||
private readonly _appConfigService = inject(AppConfigService);
|
||||
|
||||
private readonly _http: HttpClient;
|
||||
|
||||
constructor(private _injector: Injector, private _appConfigService: AppConfigService) {
|
||||
constructor() {
|
||||
this._http = this._injector.get(HttpClient);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,8 @@ import { TestBed } from '@angular/core/testing';
|
||||
import { UserAccessService } from './user-access.service';
|
||||
import { JwtHelperService } from './jwt-helper.service';
|
||||
import { AppConfigService } from '../../app-config';
|
||||
import { HttpClientTestingModule } from '@angular/common/http/testing';
|
||||
import { provideHttpClient } from '@angular/common/http';
|
||||
import { provideHttpClientTesting } from '@angular/common/http/testing';
|
||||
import { JWT_STORAGE_SERVICE, provideCoreAuth } from '../oidc/auth.module';
|
||||
import { StorageService } from '../../common/services/storage.service';
|
||||
|
||||
@@ -30,8 +31,12 @@ describe('UserAccessService', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [HttpClientTestingModule],
|
||||
providers: [provideCoreAuth({ useHash: true }), { provide: JWT_STORAGE_SERVICE, useClass: StorageService }]
|
||||
providers: [
|
||||
provideCoreAuth({ useHash: true }),
|
||||
{ provide: JWT_STORAGE_SERVICE, useClass: StorageService },
|
||||
provideHttpClient(),
|
||||
provideHttpClientTesting()
|
||||
]
|
||||
});
|
||||
userAccessService = TestBed.inject(UserAccessService);
|
||||
jwtHelperService = TestBed.inject(JwtHelperService);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { JwtHelperService } from './jwt-helper.service';
|
||||
import { ApplicationAccessModel } from '../models/application-access.model';
|
||||
import { AppConfigService } from '../../app-config/app-config.service';
|
||||
@@ -24,11 +24,12 @@ import { AppConfigService } from '../../app-config/app-config.service';
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class UserAccessService {
|
||||
private readonly jwtHelperService = inject(JwtHelperService);
|
||||
private readonly appConfigService = inject(AppConfigService);
|
||||
|
||||
private globalAccess: string[];
|
||||
private applicationAccess: ApplicationAccessModel[];
|
||||
|
||||
constructor(private jwtHelperService: JwtHelperService, private appConfigService: AppConfigService) {}
|
||||
|
||||
fetchUserAccess() {
|
||||
if (this.hasRolesInRealmAccess()) {
|
||||
this.fetchAccessFromRealmAccess();
|
||||
|
||||
+7
-7
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, effect, Input, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||
import { Component, effect, Input, OnInit, ViewChild, ViewEncapsulation, inject } from '@angular/core';
|
||||
import { DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core';
|
||||
import {
|
||||
DatetimeAdapter,
|
||||
@@ -69,6 +69,11 @@ import { IconModule } from '../../../icon/icon.module';
|
||||
host: { class: 'adf-card-view-dateitem' }
|
||||
})
|
||||
export class CardViewDateItemComponent extends BaseCardView<CardViewDateItemModel> implements OnInit {
|
||||
private readonly dateAdapter = inject<DateAdapter<Date>>(DateAdapter);
|
||||
private readonly userPreferencesService = inject(UserPreferencesService);
|
||||
private readonly clipboardService = inject(ClipboardService);
|
||||
private readonly translateService = inject(TranslationService);
|
||||
|
||||
@Input()
|
||||
displayEmpty = true;
|
||||
|
||||
@@ -82,12 +87,7 @@ export class CardViewDateItemComponent extends BaseCardView<CardViewDateItemMode
|
||||
|
||||
cardViewDateTimeControl: FormControl<Date> = new FormControl<Date>(null);
|
||||
|
||||
constructor(
|
||||
private dateAdapter: DateAdapter<Date>,
|
||||
private userPreferencesService: UserPreferencesService,
|
||||
private clipboardService: ClipboardService,
|
||||
private translateService: TranslationService
|
||||
) {
|
||||
constructor() {
|
||||
super();
|
||||
// Use effect to react to locale signal changes (must be in injection context)
|
||||
effect(() => {
|
||||
|
||||
+4
-2
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, Input, OnChanges, SimpleChange, SimpleChanges, ViewChild, ViewContainerRef } from '@angular/core';
|
||||
import { Component, Input, OnChanges, SimpleChange, SimpleChanges, ViewChild, ViewContainerRef, inject } from '@angular/core';
|
||||
import { CardViewItem } from '../../interfaces/card-view-item.interface';
|
||||
import { CardItemTypeService } from '../../services/card-item-types.service';
|
||||
import { DEFAULT_SEPARATOR } from '../card-view-textitem/card-view-textitem.component';
|
||||
@@ -25,6 +25,8 @@ import { DEFAULT_SEPARATOR } from '../card-view-textitem/card-view-textitem.comp
|
||||
template: '<ng-template #content />'
|
||||
})
|
||||
export class CardViewItemDispatcherComponent implements OnChanges {
|
||||
private readonly cardItemTypeService = inject(CardItemTypeService);
|
||||
|
||||
@Input()
|
||||
property: CardViewItem;
|
||||
|
||||
@@ -58,7 +60,7 @@ export class CardViewItemDispatcherComponent implements OnChanges {
|
||||
@ViewChild('content', { read: ViewContainerRef, static: true })
|
||||
content!: ViewContainerRef;
|
||||
|
||||
constructor(private cardItemTypeService: CardItemTypeService) {
|
||||
constructor() {
|
||||
const dynamicLifeCycleMethods = [
|
||||
'ngOnInit',
|
||||
'ngDoCheck',
|
||||
|
||||
+3
-3
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, DestroyRef, ElementRef, EventEmitter, Inject, inject, OnInit, Output, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||
import { Component, DestroyRef, ElementRef, EventEmitter, inject, OnInit, Output, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||
import { MatSelect } from '@angular/material/select';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
@@ -35,6 +35,8 @@ import { IconModule } from '../../../../icon/icon.module';
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class SelectFilterInputComponent implements OnInit {
|
||||
private readonly matSelect = inject<MatSelect>(MatSelect);
|
||||
|
||||
@ViewChild('selectFilterInput', { read: ElementRef, static: false }) selectFilterInput: ElementRef;
|
||||
@Output() change = new EventEmitter<string>();
|
||||
|
||||
@@ -43,8 +45,6 @@ export class SelectFilterInputComponent implements OnInit {
|
||||
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(@Inject(MatSelect) private matSelect: MatSelect) {}
|
||||
|
||||
onModelChange(value: string) {
|
||||
this.change.next(value);
|
||||
}
|
||||
|
||||
+4
-8
@@ -61,6 +61,10 @@ const templateTypes = {
|
||||
host: { class: 'adf-card-view-textitem' }
|
||||
})
|
||||
export class CardViewTextItemComponent extends BaseCardView<CardViewTextItemModel> implements OnChanges {
|
||||
private readonly clipboardService = inject(ClipboardService);
|
||||
private readonly translateService = inject(TranslationService);
|
||||
private readonly cd = inject(ChangeDetectorRef);
|
||||
|
||||
@Input()
|
||||
displayEmpty = true;
|
||||
|
||||
@@ -80,14 +84,6 @@ export class CardViewTextItemComponent extends BaseCardView<CardViewTextItemMode
|
||||
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(
|
||||
private clipboardService: ClipboardService,
|
||||
private translateService: TranslationService,
|
||||
private cd: ChangeDetectorRef
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
if (changes.property?.firstChange) {
|
||||
this.textInput.valueChanges
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Directive, EventEmitter, forwardRef, Input, Output } from '@angular/core';
|
||||
import { Directive, EventEmitter, forwardRef, Input, Output, inject } from '@angular/core';
|
||||
import { AbstractControl, NG_VALIDATORS, ValidationErrors } from '@angular/forms';
|
||||
import { CardViewBaseItemModel } from '../models/card-view-baseitem.model';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
@@ -31,14 +31,14 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
]
|
||||
})
|
||||
export class CardViewPropertyValidatorDirective {
|
||||
private readonly translateService = inject(TranslateService);
|
||||
|
||||
@Input()
|
||||
property: CardViewBaseItemModel;
|
||||
|
||||
@Output()
|
||||
validated = new EventEmitter<string[]>();
|
||||
|
||||
constructor(private readonly translateService: TranslateService) {}
|
||||
|
||||
validate(control: AbstractControl): ValidationErrors | null {
|
||||
const errors: ValidationErrors | null = this.property.isValid(control.value)
|
||||
? null
|
||||
|
||||
@@ -19,7 +19,7 @@ import { CardViewItem } from '../interfaces/card-view-item.interface';
|
||||
import { DynamicComponentModel } from '../../common/services/dynamic-component-mapper.service';
|
||||
import { CardViewBaseItemModel } from './card-view-baseitem.model';
|
||||
import { CardViewDateItemProperties } from '../interfaces/card-view.interfaces';
|
||||
import { LocalizedDatePipe } from '../../pipes/localized-date.pipe';
|
||||
import { DatePipe } from '@angular/common';
|
||||
import { DateFnsUtils } from '../../common/utils/date-fns-utils';
|
||||
|
||||
type DateItemType = Date | Date[] | null;
|
||||
@@ -29,8 +29,6 @@ export class CardViewDateItemModel extends CardViewBaseItemModel<DateItemType> i
|
||||
format: string;
|
||||
locale: string;
|
||||
|
||||
localizedDatePipe: LocalizedDatePipe;
|
||||
|
||||
constructor(cardViewDateItemProperties: CardViewDateItemProperties) {
|
||||
super(cardViewDateItemProperties);
|
||||
|
||||
@@ -56,8 +54,10 @@ export class CardViewDateItemModel extends CardViewBaseItemModel<DateItemType> i
|
||||
}
|
||||
|
||||
transformDate(value: Date | string | number): string {
|
||||
this.localizedDatePipe = new LocalizedDatePipe();
|
||||
return this.localizedDatePipe.transform(value, this.format, this.locale);
|
||||
const actualFormat = this.format || 'mediumDate';
|
||||
const actualLocale = this.locale || 'en-US';
|
||||
const datePipe = new DatePipe(actualLocale);
|
||||
return datePipe.transform(value, actualFormat);
|
||||
}
|
||||
|
||||
private prepareDate(date: Date): Date {
|
||||
|
||||
@@ -25,7 +25,10 @@ export interface LengthValidatorParams {
|
||||
export class CardViewItemLengthValidator implements CardViewItemValidator {
|
||||
message = 'CORE.CARDVIEW.VALIDATORS.LENGTH_VALIDATION_ERROR';
|
||||
|
||||
constructor(private minLength: number, private maxLength: number) {}
|
||||
constructor(
|
||||
private readonly minLength: number,
|
||||
private readonly maxLength: number
|
||||
) {}
|
||||
|
||||
isValid(value: string | string[]): boolean {
|
||||
if (Array.isArray(value)) {
|
||||
|
||||
@@ -26,7 +26,11 @@ export interface MatchValidatorParams {
|
||||
export class CardViewItemMatchValidator implements CardViewItemValidator {
|
||||
message = 'CORE.CARDVIEW.VALIDATORS.MATCH_VALIDATION_ERROR';
|
||||
|
||||
constructor(private expression: string, private flags?: string, private requiresMatch?: boolean) {}
|
||||
constructor(
|
||||
private readonly expression: string,
|
||||
private readonly flags?: string,
|
||||
private readonly requiresMatch?: boolean
|
||||
) {}
|
||||
|
||||
isValid(value: string | string[]): boolean {
|
||||
const regex = new RegExp(this.expression, this?.flags);
|
||||
|
||||
@@ -25,9 +25,12 @@ export interface MinMaxValidatorParams {
|
||||
|
||||
export class CardViewItemMinMaxValidator implements CardViewItemValidator {
|
||||
message = 'CORE.CARDVIEW.VALIDATORS.MINMAX_VALIDATION_ERROR';
|
||||
private intValidator: CardViewItemIntValidator;
|
||||
private readonly intValidator: CardViewItemIntValidator;
|
||||
|
||||
constructor(private minValue: number, private maxValue: number) {
|
||||
constructor(
|
||||
private readonly minValue: number,
|
||||
private readonly maxValue: number
|
||||
) {
|
||||
this.intValidator = new CardViewItemIntValidator();
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Directive, Input, HostListener, ViewContainerRef, Self, Optional } from '@angular/core';
|
||||
import { Directive, Input, HostListener, ViewContainerRef, inject } from '@angular/core';
|
||||
import { ClipboardService } from './clipboard.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { MatTooltip } from '@angular/material/tooltip';
|
||||
@@ -27,6 +27,11 @@ import { MatTooltip } from '@angular/material/tooltip';
|
||||
hostDirectives: [MatTooltip]
|
||||
})
|
||||
export class ClipboardDirective {
|
||||
private readonly clipboardService = inject(ClipboardService);
|
||||
viewContainerRef = inject(ViewContainerRef);
|
||||
private readonly matTooltip = inject(MatTooltip, { self: true });
|
||||
private readonly translate = inject(TranslateService, { optional: true });
|
||||
|
||||
/** Translation key or message for the tooltip. */
|
||||
// eslint-disable-next-line @angular-eslint/no-input-rename
|
||||
@Input('adf-clipboard')
|
||||
@@ -40,13 +45,6 @@ export class ClipboardDirective {
|
||||
// eslint-disable-next-line @angular-eslint/no-input-rename
|
||||
@Input('clipboard-notification') message: string;
|
||||
|
||||
constructor(
|
||||
private readonly clipboardService: ClipboardService,
|
||||
public viewContainerRef: ViewContainerRef,
|
||||
@Self() private readonly matTooltip: MatTooltip,
|
||||
@Optional() private readonly translate: TranslateService
|
||||
) {}
|
||||
|
||||
@HostListener('mouseenter')
|
||||
showTooltip() {
|
||||
const messageKey = this.placeholder || 'CLIPBOARD.CLICK_TO_COPY';
|
||||
|
||||
@@ -15,13 +15,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Injectable, Inject } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
import { NotificationService } from '../notifications/services/notification.service';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ClipboardService {
|
||||
constructor(@Inject(DOCUMENT) private document: any, private notificationService: NotificationService) {}
|
||||
private readonly document = inject(DOCUMENT);
|
||||
private readonly notificationService = inject(NotificationService);
|
||||
|
||||
/**
|
||||
* Checks if the target element can have its text copied.
|
||||
|
||||
@@ -41,7 +41,7 @@ export class CommentListComponent {
|
||||
@Output()
|
||||
clickRow = new EventEmitter<CommentModel>();
|
||||
|
||||
private commentsService = inject<CommentsService>(ADF_COMMENTS_SERVICE);
|
||||
private readonly commentsService = inject<CommentsService>(ADF_COMMENTS_SERVICE);
|
||||
|
||||
selectComment(comment: CommentModel): void {
|
||||
this.clickRow.emit(comment);
|
||||
|
||||
@@ -16,17 +16,7 @@
|
||||
*/
|
||||
|
||||
import { CommentModel } from '../models/comment.model';
|
||||
import {
|
||||
Component, ElementRef,
|
||||
EventEmitter,
|
||||
inject,
|
||||
Input,
|
||||
OnChanges,
|
||||
Output,
|
||||
SimpleChanges,
|
||||
ViewChild,
|
||||
ViewEncapsulation
|
||||
} from '@angular/core';
|
||||
import { Component, ElementRef, EventEmitter, inject, Input, OnChanges, Output, SimpleChanges, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||
import { ADF_COMMENTS_SERVICE } from './interfaces/comments.token';
|
||||
import { CommentsService } from './interfaces/comments-service.interface';
|
||||
import { CommonModule } from '@angular/common';
|
||||
@@ -75,7 +65,7 @@ export class CommentsComponent implements OnChanges {
|
||||
comments: CommentModel[] = [];
|
||||
beingAdded: boolean = false;
|
||||
|
||||
private commentsService = inject<CommentsService>(ADF_COMMENTS_SERVICE);
|
||||
private readonly commentsService = inject<CommentsService>(ADF_COMMENTS_SERVICE);
|
||||
|
||||
private readonly _commentControl = new FormControl('', [this.validateEmptyComment]);
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
/* eslint-disable no-console */
|
||||
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, inject as inject_1 } from '@angular/core';
|
||||
import { ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing';
|
||||
import { AppConfigService } from '../../app-config/app-config.service';
|
||||
import { LogService } from './log.service';
|
||||
@@ -28,7 +28,7 @@ import { LogService } from './log.service';
|
||||
providers: [LogService]
|
||||
})
|
||||
class ProvidesLogComponent {
|
||||
constructor(public logService: LogService) {}
|
||||
logService = inject_1(LogService);
|
||||
|
||||
error() {
|
||||
this.logService.error('Test message');
|
||||
|
||||
@@ -17,18 +17,17 @@
|
||||
|
||||
/* eslint-disable no-console */
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { AppConfigService, AppConfigValues } from '../../app-config/app-config.service';
|
||||
import { logLevels, LogLevelsEnum } from '../models/log-levels.model';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
/**
|
||||
* @deprecated This service is deprecated and will be removed in future versions.
|
||||
*/
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class LogService {
|
||||
private readonly appConfig = inject(AppConfigService);
|
||||
|
||||
get currentLogLevel(): number {
|
||||
const configLevel: string = this.appConfig.get<string>(AppConfigValues.LOG_LEVEL);
|
||||
|
||||
@@ -41,7 +40,7 @@ export class LogService {
|
||||
|
||||
onMessage: Subject<any>;
|
||||
|
||||
constructor(private appConfig: AppConfigService) {
|
||||
constructor() {
|
||||
this.onMessage = new Subject();
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { Title } from '@angular/platform-browser';
|
||||
import { AppConfigService } from '../../app-config/app-config.service';
|
||||
import { TranslationService } from '../../translation/translation.service';
|
||||
@@ -24,10 +24,16 @@ import { TranslationService } from '../../translation/translation.service';
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class PageTitleService {
|
||||
private readonly titleService = inject(Title);
|
||||
private readonly appConfig = inject(AppConfigService);
|
||||
private readonly translationService = inject(TranslationService);
|
||||
|
||||
private originalTitle: string = '';
|
||||
private translatedTitle: string = '';
|
||||
|
||||
constructor(private titleService: Title, private appConfig: AppConfigService, private translationService: TranslationService) {
|
||||
constructor() {
|
||||
const translationService = this.translationService;
|
||||
|
||||
translationService.translate.onLangChange.subscribe(() => this.onLanguageChanged());
|
||||
translationService.translate.onTranslationChange.subscribe(() => this.onLanguageChanged());
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
/* spellchecker: disable */
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { MatIconRegistry } from '@angular/material/icon';
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
|
||||
@@ -161,7 +161,10 @@ export class ThumbnailService {
|
||||
'multipart/related': './assets/images/ft_ic_website.svg'
|
||||
};
|
||||
|
||||
constructor(matIconRegistry: MatIconRegistry, sanitizer: DomSanitizer) {
|
||||
constructor() {
|
||||
const matIconRegistry = inject(MatIconRegistry);
|
||||
const sanitizer = inject(DomSanitizer);
|
||||
|
||||
Object.keys(this.mimeTypeIcons).forEach((key) => {
|
||||
const url = sanitizer.bypassSecurityTrustResourceUrl(this.mimeTypeIcons[key]);
|
||||
|
||||
|
||||
@@ -15,14 +15,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class UrlService {
|
||||
constructor(private sanitizer: DomSanitizer) {}
|
||||
private readonly sanitizer = inject(DomSanitizer);
|
||||
|
||||
/**
|
||||
* Creates a trusted object URL from the Blob.
|
||||
|
||||
@@ -40,9 +40,13 @@ export type UserPreferenceValues = (typeof UserPreferenceValues)[keyof typeof Us
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class UserPreferencesService {
|
||||
private document = inject(DOCUMENT);
|
||||
private rendererFactory = inject(RendererFactory2);
|
||||
private directionality = inject(Directionality);
|
||||
translate = inject(TranslateService);
|
||||
private readonly appConfig = inject(AppConfigService);
|
||||
private readonly storage = inject(StorageService);
|
||||
|
||||
private readonly document = inject(DOCUMENT);
|
||||
private readonly rendererFactory = inject(RendererFactory2);
|
||||
private readonly directionality = inject(Directionality);
|
||||
|
||||
defaults = {
|
||||
paginationSize: 25,
|
||||
@@ -52,7 +56,7 @@ export class UserPreferencesService {
|
||||
};
|
||||
|
||||
private userPreferenceStatus: any = { ...this.defaults };
|
||||
private onChangeSubject: BehaviorSubject<any>;
|
||||
private readonly onChangeSubject: BehaviorSubject<any>;
|
||||
onChange: Observable<any>;
|
||||
|
||||
/**
|
||||
@@ -107,11 +111,7 @@ export class UserPreferencesService {
|
||||
*/
|
||||
readonly supportedPageSizesSignal: Signal<number[]>;
|
||||
|
||||
constructor(
|
||||
public translate: TranslateService,
|
||||
private appConfig: AppConfigService,
|
||||
private storage: StorageService
|
||||
) {
|
||||
constructor() {
|
||||
this.onChangeSubject = new BehaviorSubject(this.userPreferenceStatus);
|
||||
this.onChange = this.onChangeSubject.asObservable();
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
import { DateFnsAdapter } from '@angular/material-date-fns-adapter';
|
||||
import { DateFnsUtils } from './date-fns-utils';
|
||||
import { effect, Inject, Injectable, Optional } from '@angular/core';
|
||||
import { effect, Injectable, inject } from '@angular/core';
|
||||
import { MAT_DATE_FORMATS, MAT_DATE_LOCALE, MatDateFormats } from '@angular/material/core';
|
||||
import { UserPreferencesService } from '../services/user-preferences.service';
|
||||
import { isValid, Locale, parse } from 'date-fns';
|
||||
@@ -68,6 +68,8 @@ export const ADF_DATE_FORMATS: MatDateFormats = {
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AdfDateFnsAdapter extends DateFnsAdapter {
|
||||
private readonly formats = inject<MatDateFormats>(MAT_DATE_FORMATS, { optional: true });
|
||||
|
||||
private _displayFormat?: string = null;
|
||||
|
||||
get displayFormat(): string | null {
|
||||
@@ -78,11 +80,10 @@ export class AdfDateFnsAdapter extends DateFnsAdapter {
|
||||
this._displayFormat = value ? DateFnsUtils.convertMomentToDateFnsFormat(value) : null;
|
||||
}
|
||||
|
||||
constructor(
|
||||
@Optional() @Inject(MAT_DATE_LOCALE) matDateLocale: Locale,
|
||||
@Optional() @Inject(MAT_DATE_FORMATS) private formats: MatDateFormats,
|
||||
preferences: UserPreferencesService
|
||||
) {
|
||||
constructor() {
|
||||
const matDateLocale = inject<Locale>(MAT_DATE_LOCALE, { optional: true });
|
||||
const preferences = inject(UserPreferencesService);
|
||||
|
||||
// Ensure we have a valid locale for the base class
|
||||
// If matDateLocale is not provided, use enUS as default
|
||||
super(matDateLocale || enUS);
|
||||
|
||||
@@ -89,7 +89,7 @@ export class DateFnsUtils {
|
||||
return dateFnsLocale;
|
||||
}
|
||||
|
||||
private static momentToDateFnsMap = {
|
||||
private static readonly momentToDateFnsMap = {
|
||||
D: 'd',
|
||||
Y: 'y',
|
||||
AZ: 'aa',
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Inject, Injectable, Optional } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { DateFnsUtils } from './date-fns-utils';
|
||||
import { DatetimeAdapter, MAT_DATETIME_FORMATS, MatDatetimeFormats } from '@mat-datetimepicker/core';
|
||||
import { DateAdapter, MAT_DATE_LOCALE } from '@angular/material/core';
|
||||
@@ -60,6 +60,8 @@ function range<T>(length: number, valueFunction: (index: number) => T): T[] {
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class AdfDateTimeFnsAdapter extends DatetimeAdapter<Date> {
|
||||
private readonly formats = inject<MatDatetimeFormats>(MAT_DATETIME_FORMATS, { optional: true });
|
||||
|
||||
private _displayFormat?: string = null;
|
||||
|
||||
get displayFormat(): string | null {
|
||||
@@ -70,11 +72,10 @@ export class AdfDateTimeFnsAdapter extends DatetimeAdapter<Date> {
|
||||
this._displayFormat = value ? DateFnsUtils.convertMomentToDateFnsFormat(value) : null;
|
||||
}
|
||||
|
||||
constructor(
|
||||
@Optional() @Inject(MAT_DATE_LOCALE) matDateLocale: Locale,
|
||||
@Optional() @Inject(MAT_DATETIME_FORMATS) private formats: MatDatetimeFormats,
|
||||
dateAdapter: DateAdapter<Date, Locale>
|
||||
) {
|
||||
constructor() {
|
||||
const matDateLocale = inject<Locale>(MAT_DATE_LOCALE, { optional: true });
|
||||
const dateAdapter = inject<DateAdapter<Date, Locale>>(DateAdapter);
|
||||
|
||||
super(dateAdapter);
|
||||
this.setLocale(matDateLocale);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { effect, Injectable } from '@angular/core';
|
||||
import { effect, Injectable, inject } from '@angular/core';
|
||||
import { DateAdapter } from '@angular/material/core';
|
||||
import { UserPreferencesService } from '../services/user-preferences.service';
|
||||
|
||||
@@ -34,7 +34,9 @@ export class MomentDateAdapter extends DateAdapter<Moment> {
|
||||
|
||||
overrideDisplayFormat: string;
|
||||
|
||||
constructor(preferences: UserPreferencesService) {
|
||||
constructor() {
|
||||
const preferences = inject(UserPreferencesService);
|
||||
|
||||
super();
|
||||
|
||||
// Use effect to reactively update locale when signal changes
|
||||
|
||||
@@ -21,7 +21,7 @@ import { MatMenuItem, MatMenuModule } from '@angular/material/menu';
|
||||
import { ContextMenuOverlayRef } from './context-menu-overlay';
|
||||
import { contextMenuAnimation } from './animations';
|
||||
import { CONTEXT_MENU_DATA } from './context-menu.tokens';
|
||||
import { AfterViewInit, Component, HostListener, Inject, Optional, QueryList, ViewChildren, ViewEncapsulation } from '@angular/core';
|
||||
import { AfterViewInit, Component, HostListener, QueryList, ViewChildren, ViewEncapsulation, inject } from '@angular/core';
|
||||
import { NgForOf, NgIf } from '@angular/common';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
import { DOWN_ARROW, UP_ARROW } from '@angular/cdk/keycodes';
|
||||
@@ -41,6 +41,9 @@ import { ContextMenuItem } from './interfaces';
|
||||
animations: [trigger('panelAnimation', contextMenuAnimation)]
|
||||
})
|
||||
export class ContextMenuListComponent implements AfterViewInit {
|
||||
private readonly contextMenuOverlayRef = inject<ContextMenuOverlayRef>(ContextMenuOverlayRef);
|
||||
private readonly data = inject(CONTEXT_MENU_DATA, { optional: true });
|
||||
|
||||
private keyManager: FocusKeyManager<MatMenuItem>;
|
||||
@ViewChildren(MatMenuItem) items: QueryList<MatMenuItem>;
|
||||
links: ContextMenuItem[];
|
||||
@@ -62,10 +65,7 @@ export class ContextMenuListComponent implements AfterViewInit {
|
||||
}
|
||||
}
|
||||
|
||||
constructor(
|
||||
@Inject(ContextMenuOverlayRef) private contextMenuOverlayRef: ContextMenuOverlayRef,
|
||||
@Optional() @Inject(CONTEXT_MENU_DATA) private data: ContextMenuItem[]
|
||||
) {
|
||||
constructor() {
|
||||
this.links = this.data;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
import { Overlay } from '@angular/cdk/overlay';
|
||||
import { ContextMenuOverlayService } from './context-menu-overlay.service';
|
||||
import { Injector } from '@angular/core';
|
||||
import { Injector, runInInjectionContext } from '@angular/core';
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
describe('ContextMenuOverlayService', () => {
|
||||
@@ -43,7 +43,15 @@ describe('ContextMenuOverlayService', () => {
|
||||
|
||||
describe('Overlay', () => {
|
||||
beforeEach(() => {
|
||||
contextMenuOverlayService = new ContextMenuOverlayService(injector, overlay);
|
||||
const testInjector = Injector.create({
|
||||
providers: [
|
||||
{ provide: Injector, useValue: injector },
|
||||
{ provide: Overlay, useValue: overlay }
|
||||
],
|
||||
parent: TestBed.inject(Injector)
|
||||
});
|
||||
|
||||
contextMenuOverlayService = runInInjectionContext(testInjector, () => new ContextMenuOverlayService());
|
||||
});
|
||||
|
||||
it('should create a custom overlay', () => {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Injectable, Injector, ElementRef, ComponentRef } from '@angular/core';
|
||||
import { Injectable, Injector, ElementRef, ComponentRef, inject } from '@angular/core';
|
||||
import { Overlay, OverlayConfig, OverlayRef } from '@angular/cdk/overlay';
|
||||
import { ComponentPortal } from '@angular/cdk/portal';
|
||||
import { ContextMenuOverlayRef } from './context-menu-overlay';
|
||||
@@ -33,10 +33,8 @@ const DEFAULT_CONFIG: ContextMenuOverlayConfig = {
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ContextMenuOverlayService {
|
||||
constructor(
|
||||
private injector: Injector,
|
||||
private overlay: Overlay
|
||||
) {}
|
||||
private readonly injector = inject(Injector);
|
||||
private readonly overlay = inject(Overlay);
|
||||
|
||||
open(config: ContextMenuOverlayConfig): ContextMenuOverlayRef {
|
||||
const overlayConfig = { ...DEFAULT_CONFIG, ...config };
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
import { OverlayRef } from '@angular/cdk/overlay';
|
||||
|
||||
export class ContextMenuOverlayRef {
|
||||
constructor(private overlayRef: OverlayRef) {}
|
||||
constructor(private readonly overlayRef: OverlayRef) {}
|
||||
|
||||
close(): void {
|
||||
this.overlayRef.dispose();
|
||||
|
||||
@@ -17,13 +17,15 @@
|
||||
|
||||
/* eslint-disable @angular-eslint/no-input-rename */
|
||||
|
||||
import { Directive, HostListener, Input } from '@angular/core';
|
||||
import { Directive, HostListener, Input, inject } from '@angular/core';
|
||||
import { ContextMenuOverlayService } from './context-menu-overlay.service';
|
||||
|
||||
@Directive({
|
||||
selector: '[adf-context-menu]'
|
||||
})
|
||||
export class ContextMenuDirective {
|
||||
private readonly contextMenuService = inject(ContextMenuOverlayService);
|
||||
|
||||
/** Items for the menu. */
|
||||
@Input('adf-context-menu')
|
||||
links: any[] | (() => any[]);
|
||||
@@ -32,8 +34,6 @@ export class ContextMenuDirective {
|
||||
@Input('adf-context-menu-enabled')
|
||||
enabled: boolean = false;
|
||||
|
||||
constructor(private contextMenuService: ContextMenuOverlayService) {}
|
||||
|
||||
@HostListener('contextmenu', ['$event'])
|
||||
onShowContextMenu(event?: MouseEvent) {
|
||||
if (this.enabled) {
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ import { TranslationService } from '../../../translation';
|
||||
name: 'columnsSearchFilter'
|
||||
})
|
||||
export class ColumnsSearchFilterPipe implements PipeTransform {
|
||||
private translationService = inject(TranslationService);
|
||||
private readonly translationService = inject(TranslationService);
|
||||
|
||||
transform(columns: DataColumn[], searchByName: string): DataColumn[] {
|
||||
const result = [];
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, ElementRef, EventEmitter, HostBinding, HostListener, Input, Output, ViewEncapsulation } from '@angular/core';
|
||||
import { Component, ElementRef, EventEmitter, HostBinding, HostListener, Input, Output, ViewEncapsulation, inject } from '@angular/core';
|
||||
import { FocusableOption } from '@angular/cdk/a11y';
|
||||
import { DataRow } from '../../data/data-row.model';
|
||||
|
||||
@@ -29,6 +29,8 @@ import { DataRow } from '../../data/data-row.model';
|
||||
}
|
||||
})
|
||||
export class DataTableRowComponent implements FocusableOption {
|
||||
private readonly element = inject(ElementRef);
|
||||
|
||||
@Input() row: DataRow;
|
||||
|
||||
@Input() disabled = true;
|
||||
@@ -74,8 +76,6 @@ export class DataTableRowComponent implements FocusableOption {
|
||||
}
|
||||
}
|
||||
|
||||
constructor(private element: ElementRef) {}
|
||||
|
||||
focus() {
|
||||
this.element.nativeElement.focus();
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, DebugElement, NO_ERRORS_SCHEMA, QueryList, SimpleChange, TemplateRef, ViewChild } from '@angular/core';
|
||||
import { Component, DebugElement, QueryList, SimpleChange, TemplateRef, ViewChild } from '@angular/core';
|
||||
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
||||
import { MatCheckboxChange } from '@angular/material/checkbox';
|
||||
import { DataColumn } from '../../data/data-column.model';
|
||||
@@ -1631,8 +1631,7 @@ describe('Accessibility', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [CustomColumnTemplateComponent],
|
||||
providers: [{ provide: ConfigurableFocusTrapFactory, useValue: focusTrapFactory }],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
providers: [{ provide: ConfigurableFocusTrapFactory, useValue: focusTrapFactory }]
|
||||
});
|
||||
columnCustomTemplate = TestBed.createComponent(CustomColumnTemplateComponent).componentInstance.templateRef;
|
||||
fixture = TestBed.createComponent(DataTableComponent);
|
||||
@@ -2020,8 +2019,7 @@ describe('Drag&Drop column header', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [CustomColumnTemplateComponent],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
imports: [CustomColumnTemplateComponent]
|
||||
});
|
||||
fixture = TestBed.createComponent(DataTableComponent);
|
||||
testingUtils = new UnitTestingUtils(fixture.debugElement);
|
||||
@@ -2114,8 +2112,7 @@ describe('Show/hide columns', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [CustomColumnTemplateComponent],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
imports: [CustomColumnTemplateComponent]
|
||||
});
|
||||
fixture = TestBed.createComponent(DataTableComponent);
|
||||
dataTable = fixture.componentInstance;
|
||||
@@ -2222,8 +2219,7 @@ describe('Column Resizing', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [CustomColumnTemplateComponent],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
imports: [CustomColumnTemplateComponent]
|
||||
});
|
||||
fixture = TestBed.createComponent(DataTableComponent);
|
||||
dataTable = fixture.componentInstance;
|
||||
|
||||
@@ -130,7 +130,12 @@ export type ShowHeaderMode = (typeof ShowHeaderMode)[keyof typeof ShowHeaderMode
|
||||
host: { class: 'adf-datatable' }
|
||||
})
|
||||
export class DataTableComponent implements OnInit, AfterContentInit, OnChanges, DoCheck, OnDestroy, AfterViewInit {
|
||||
private static MINIMUM_COLUMN_SIZE = 100;
|
||||
private readonly elementRef = inject(ElementRef);
|
||||
private readonly matIconRegistry = inject(MatIconRegistry);
|
||||
private readonly sanitizer = inject(DomSanitizer);
|
||||
private readonly focusTrapFactory = inject(ConfigurableFocusTrapFactory);
|
||||
|
||||
private static readonly MINIMUM_COLUMN_SIZE = 100;
|
||||
|
||||
@ViewChildren(DataTableRowComponent)
|
||||
rowsList: QueryList<DataTableRowComponent>;
|
||||
@@ -333,9 +338,9 @@ export class DataTableComponent implements OnInit, AfterContentInit, OnChanges,
|
||||
|
||||
private keyManager: FocusKeyManager<DataTableRowComponent>;
|
||||
private clickObserver: Observer<DataRowEvent>;
|
||||
private click$: Observable<DataRowEvent>;
|
||||
private readonly click$: Observable<DataRowEvent>;
|
||||
|
||||
private differ: any;
|
||||
private readonly differ: any;
|
||||
private rowMenuCache: any = {};
|
||||
|
||||
private singleClickStreamSub: Subscription;
|
||||
@@ -376,13 +381,9 @@ export class DataTableComponent implements OnInit, AfterContentInit, OnChanges,
|
||||
}
|
||||
}
|
||||
|
||||
constructor(
|
||||
private readonly elementRef: ElementRef,
|
||||
differs: IterableDiffers,
|
||||
private readonly matIconRegistry: MatIconRegistry,
|
||||
private readonly sanitizer: DomSanitizer,
|
||||
private readonly focusTrapFactory: ConfigurableFocusTrapFactory
|
||||
) {
|
||||
constructor() {
|
||||
const differs = inject(IterableDiffers);
|
||||
|
||||
if (differs) {
|
||||
this.differ = differs.find([]).create(null);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ChangeDetectionStrategy, Component, ViewEncapsulation, Input, computed } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, ViewEncapsulation, Input, computed, inject } from '@angular/core';
|
||||
import { DataTableCellComponent } from '../datatable-cell/datatable-cell.component';
|
||||
import { MatDialog, MatDialogModule } from '@angular/material/dialog';
|
||||
import { EditJsonDialogComponent, EditJsonDialogSettings } from '../../../dialogs/edit-json/edit-json.dialog';
|
||||
@@ -36,6 +36,8 @@ import { toSignal } from '@angular/core/rxjs-interop';
|
||||
host: { class: 'adf-datatable-content-cell' }
|
||||
})
|
||||
export class JsonCellComponent extends DataTableCellComponent {
|
||||
private readonly dialog = inject(MatDialog);
|
||||
|
||||
/** Editable JSON. */
|
||||
@Input()
|
||||
editable: boolean = false;
|
||||
@@ -47,10 +49,6 @@ export class JsonCellComponent extends DataTableCellComponent {
|
||||
return !!value || this.editable;
|
||||
});
|
||||
|
||||
constructor(private dialog: MatDialog) {
|
||||
super();
|
||||
}
|
||||
|
||||
view() {
|
||||
const rawValue = this.data.getValue(this.row, this.column, this.resolverFn);
|
||||
const value = typeof rawValue === 'object' ? JSON.stringify(rawValue || {}, null, 2) : String(rawValue ?? '');
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
/* eslint-disable @angular-eslint/component-selector, @angular-eslint/no-input-rename */
|
||||
|
||||
import { AfterContentInit, Component, ContentChild, TemplateRef } from '@angular/core';
|
||||
import { AfterContentInit, Component, ContentChild, TemplateRef, inject } from '@angular/core';
|
||||
import { DataColumnComponent } from './data-column.component';
|
||||
|
||||
@Component({
|
||||
@@ -25,11 +25,11 @@ import { DataColumnComponent } from './data-column.component';
|
||||
template: ''
|
||||
})
|
||||
export class DateColumnHeaderComponent implements AfterContentInit {
|
||||
private readonly columnComponent = inject(DataColumnComponent);
|
||||
|
||||
@ContentChild(TemplateRef)
|
||||
public header: TemplateRef<any>;
|
||||
|
||||
constructor(private columnComponent: DataColumnComponent) {}
|
||||
|
||||
ngAfterContentInit() {
|
||||
if (this.columnComponent) {
|
||||
this.columnComponent.header = this.header;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ContentChild, Input, Directive } from '@angular/core';
|
||||
import { ContentChild, Input, Directive, inject } from '@angular/core';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { AppConfigService } from '../../app-config/app-config.service';
|
||||
import { DataColumnListComponent } from '../data-column/data-column-list.component';
|
||||
@@ -45,11 +45,15 @@ export abstract class DataTableSchema<T = unknown> {
|
||||
protected columnsSchemaSubject$ = new BehaviorSubject<boolean>(false);
|
||||
isColumnSchemaCreated$ = this.columnsSchemaSubject$.asObservable();
|
||||
|
||||
constructor(
|
||||
private appConfigService: AppConfigService,
|
||||
protected presetKey: string,
|
||||
protected presetsModel: any
|
||||
) {}
|
||||
protected presetKey: string;
|
||||
protected presetsModel: any;
|
||||
|
||||
protected readonly appConfigService = inject(AppConfigService);
|
||||
|
||||
constructor(presetKey: string, presetsModel: any) {
|
||||
this.presetKey = presetKey;
|
||||
this.presetsModel = presetsModel;
|
||||
}
|
||||
|
||||
public createDatatableSchema(): void {
|
||||
this.loadLayoutPresets();
|
||||
|
||||
@@ -20,7 +20,11 @@ import { DataRow } from './data-row.model';
|
||||
|
||||
// Simple implementation of the DataRow interface.
|
||||
export class ObjectDataRow implements DataRow {
|
||||
constructor(private obj: any, public isSelected: boolean = false, public isSelectable: boolean = true) {
|
||||
constructor(
|
||||
private readonly obj: any,
|
||||
public isSelected: boolean = false,
|
||||
public isSelectable: boolean = true
|
||||
) {
|
||||
if (!obj) {
|
||||
throw new Error('Object source not found');
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Directive, Input, ElementRef, NgZone, OnInit, OnDestroy } from '@angular/core';
|
||||
import { Directive, Input, ElementRef, NgZone, OnInit, OnDestroy, inject } from '@angular/core';
|
||||
import { DataRow } from '../data/data-row.model';
|
||||
import { DataColumn } from '../data/data-column.model';
|
||||
|
||||
@@ -23,7 +23,9 @@ import { DataColumn } from '../data/data-column.model';
|
||||
selector: '[adf-drop-zone]'
|
||||
})
|
||||
export class DropZoneDirective implements OnInit, OnDestroy {
|
||||
private element: HTMLElement;
|
||||
private readonly ngZone = inject(NgZone);
|
||||
|
||||
private readonly element: HTMLElement;
|
||||
|
||||
@Input()
|
||||
dropTarget: 'header' | 'cell' = 'cell';
|
||||
@@ -34,7 +36,9 @@ export class DropZoneDirective implements OnInit, OnDestroy {
|
||||
@Input()
|
||||
dropColumn: DataColumn;
|
||||
|
||||
constructor(elementRef: ElementRef, private ngZone: NgZone) {
|
||||
constructor() {
|
||||
const elementRef = inject(ElementRef);
|
||||
|
||||
this.element = elementRef.nativeElement;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
import { TestBed, ComponentFixture } from '@angular/core/testing';
|
||||
import { DataTableComponent } from '../components/datatable/datatable.component';
|
||||
import { HeaderFilterTemplateDirective } from './header-filter-template.directive';
|
||||
import { Injector, runInInjectionContext } from '@angular/core';
|
||||
|
||||
describe('HeaderFilterTemplateDirective', () => {
|
||||
let fixture: ComponentFixture<DataTableComponent>;
|
||||
@@ -30,7 +31,13 @@ describe('HeaderFilterTemplateDirective', () => {
|
||||
});
|
||||
fixture = TestBed.createComponent(DataTableComponent);
|
||||
dataTable = fixture.componentInstance;
|
||||
directive = new HeaderFilterTemplateDirective(dataTable);
|
||||
|
||||
const injector = Injector.create({
|
||||
providers: [{ provide: DataTableComponent, useValue: dataTable }],
|
||||
parent: TestBed.inject(Injector)
|
||||
});
|
||||
|
||||
directive = runInInjectionContext(injector, () => new HeaderFilterTemplateDirective());
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
@@ -15,18 +15,18 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AfterContentInit, ContentChild, Directive, TemplateRef } from '@angular/core';
|
||||
import { AfterContentInit, ContentChild, Directive, TemplateRef, inject } from '@angular/core';
|
||||
import { DataTableComponent } from '../components/datatable/datatable.component';
|
||||
|
||||
@Directive({
|
||||
selector: 'adf-header-filter-template'
|
||||
})
|
||||
export class HeaderFilterTemplateDirective implements AfterContentInit {
|
||||
private readonly dataTable = inject(DataTableComponent, { optional: true });
|
||||
|
||||
@ContentChild(TemplateRef)
|
||||
template: any;
|
||||
|
||||
constructor(private dataTable: DataTableComponent) {}
|
||||
|
||||
ngAfterContentInit() {
|
||||
if (this.dataTable) {
|
||||
this.dataTable.headerFilterTemplate = this.template;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
import { TestBed, ComponentFixture } from '@angular/core/testing';
|
||||
import { DataTableComponent } from '../components/datatable/datatable.component';
|
||||
import { LoadingContentTemplateDirective } from './loading-template.directive';
|
||||
import { Injector, runInInjectionContext } from '@angular/core';
|
||||
|
||||
describe('LoadingContentTemplateDirective', () => {
|
||||
let fixture: ComponentFixture<DataTableComponent>;
|
||||
@@ -30,7 +31,13 @@ describe('LoadingContentTemplateDirective', () => {
|
||||
});
|
||||
fixture = TestBed.createComponent(DataTableComponent);
|
||||
dataTable = fixture.componentInstance;
|
||||
directive = new LoadingContentTemplateDirective(dataTable);
|
||||
|
||||
const injector = Injector.create({
|
||||
providers: [{ provide: DataTableComponent, useValue: dataTable }],
|
||||
parent: TestBed.inject(Injector)
|
||||
});
|
||||
|
||||
directive = runInInjectionContext(injector, () => new LoadingContentTemplateDirective());
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AfterContentInit, ContentChild, Directive, TemplateRef } from '@angular/core';
|
||||
import { AfterContentInit, ContentChild, Directive, TemplateRef, inject } from '@angular/core';
|
||||
import { DataTableComponent } from '../components/datatable/datatable.component';
|
||||
|
||||
/**
|
||||
@@ -25,11 +25,11 @@ import { DataTableComponent } from '../components/datatable/datatable.component'
|
||||
selector: 'adf-loading-content-template, loading-content-template'
|
||||
})
|
||||
export class LoadingContentTemplateDirective implements AfterContentInit {
|
||||
private readonly dataTable = inject(DataTableComponent);
|
||||
|
||||
@ContentChild(TemplateRef)
|
||||
template: any;
|
||||
|
||||
constructor(private dataTable: DataTableComponent) {}
|
||||
|
||||
ngAfterContentInit() {
|
||||
if (this.dataTable) {
|
||||
this.dataTable.loadingTemplate = this.template;
|
||||
|
||||
+8
-2
@@ -18,9 +18,9 @@
|
||||
import { TestBed, ComponentFixture } from '@angular/core/testing';
|
||||
import { DataTableComponent } from '../components/datatable/datatable.component';
|
||||
import { MainMenuDataTableTemplateDirective } from './main-data-table-action-template.directive';
|
||||
import { Injector, runInInjectionContext } from '@angular/core';
|
||||
|
||||
describe('MainMenuDataTableTemplateDirective', () => {
|
||||
|
||||
let fixture: ComponentFixture<DataTableComponent>;
|
||||
let dataTable: DataTableComponent;
|
||||
let directive: MainMenuDataTableTemplateDirective;
|
||||
@@ -28,7 +28,13 @@ describe('MainMenuDataTableTemplateDirective', () => {
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DataTableComponent);
|
||||
dataTable = fixture.componentInstance;
|
||||
directive = new MainMenuDataTableTemplateDirective(dataTable);
|
||||
|
||||
const injector = Injector.create({
|
||||
providers: [{ provide: DataTableComponent, useValue: dataTable }],
|
||||
parent: TestBed.inject(Injector)
|
||||
});
|
||||
|
||||
directive = runInInjectionContext(injector, () => new MainMenuDataTableTemplateDirective());
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
@@ -15,18 +15,18 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AfterContentInit, ContentChild, Directive, TemplateRef } from '@angular/core';
|
||||
import { AfterContentInit, ContentChild, Directive, TemplateRef, inject } from '@angular/core';
|
||||
import { DataTableComponent } from '../components/datatable/datatable.component';
|
||||
|
||||
@Directive({
|
||||
selector: 'adf-main-menu-datatable-template'
|
||||
})
|
||||
export class MainMenuDataTableTemplateDirective implements AfterContentInit {
|
||||
private readonly dataTable = inject(DataTableComponent);
|
||||
|
||||
@ContentChild(TemplateRef)
|
||||
template: any;
|
||||
|
||||
constructor(private dataTable: DataTableComponent) {}
|
||||
|
||||
ngAfterContentInit() {
|
||||
if (this.dataTable) {
|
||||
this.dataTable.mainActionTemplate = this.template;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
import { TestBed, ComponentFixture } from '@angular/core/testing';
|
||||
import { DataTableComponent } from '../components/datatable/datatable.component';
|
||||
import { NoContentTemplateDirective } from './no-content-template.directive';
|
||||
import { Injector, runInInjectionContext } from '@angular/core';
|
||||
|
||||
describe('NoContentTemplateDirective', () => {
|
||||
let fixture: ComponentFixture<DataTableComponent>;
|
||||
@@ -30,7 +31,13 @@ describe('NoContentTemplateDirective', () => {
|
||||
});
|
||||
fixture = TestBed.createComponent(DataTableComponent);
|
||||
dataTable = fixture.componentInstance;
|
||||
directive = new NoContentTemplateDirective(dataTable);
|
||||
|
||||
const injector = Injector.create({
|
||||
providers: [{ provide: DataTableComponent, useValue: dataTable }],
|
||||
parent: TestBed.inject(Injector)
|
||||
});
|
||||
|
||||
directive = runInInjectionContext(injector, () => new NoContentTemplateDirective());
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AfterContentInit, ContentChild, Directive, TemplateRef } from '@angular/core';
|
||||
import { AfterContentInit, ContentChild, Directive, TemplateRef, inject } from '@angular/core';
|
||||
import { DataTableComponent } from '../components/datatable/datatable.component';
|
||||
|
||||
/**
|
||||
@@ -25,11 +25,11 @@ import { DataTableComponent } from '../components/datatable/datatable.component'
|
||||
selector: 'adf-no-content-template, no-content-template'
|
||||
})
|
||||
export class NoContentTemplateDirective implements AfterContentInit {
|
||||
private readonly dataTable = inject(DataTableComponent);
|
||||
|
||||
@ContentChild(TemplateRef)
|
||||
template: any;
|
||||
|
||||
constructor(private dataTable: DataTableComponent) {}
|
||||
|
||||
ngAfterContentInit() {
|
||||
if (this.dataTable) {
|
||||
this.dataTable.noContentTemplate = this.template;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
import { TestBed, ComponentFixture } from '@angular/core/testing';
|
||||
import { DataTableComponent } from '../components/datatable/datatable.component';
|
||||
import { NoPermissionTemplateDirective } from './no-permission-template.directive';
|
||||
import { Injector, runInInjectionContext } from '@angular/core';
|
||||
|
||||
describe('NoPermissionTemplateDirective', () => {
|
||||
let fixture: ComponentFixture<DataTableComponent>;
|
||||
@@ -30,7 +31,13 @@ describe('NoPermissionTemplateDirective', () => {
|
||||
});
|
||||
fixture = TestBed.createComponent(DataTableComponent);
|
||||
dataTable = fixture.componentInstance;
|
||||
directive = new NoPermissionTemplateDirective(dataTable);
|
||||
|
||||
const injector = Injector.create({
|
||||
providers: [{ provide: DataTableComponent, useValue: dataTable }],
|
||||
parent: TestBed.inject(Injector)
|
||||
});
|
||||
|
||||
directive = runInInjectionContext(injector, () => new NoPermissionTemplateDirective());
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AfterContentInit, ContentChild, Directive, TemplateRef } from '@angular/core';
|
||||
import { AfterContentInit, ContentChild, Directive, TemplateRef, inject } from '@angular/core';
|
||||
import { DataTableComponent } from '../components/datatable/datatable.component';
|
||||
|
||||
/**
|
||||
@@ -25,11 +25,11 @@ import { DataTableComponent } from '../components/datatable/datatable.component'
|
||||
selector: 'adf-no-permission-template, no-permission-template'
|
||||
})
|
||||
export class NoPermissionTemplateDirective implements AfterContentInit {
|
||||
private readonly dataTable = inject(DataTableComponent);
|
||||
|
||||
@ContentChild(TemplateRef)
|
||||
template: any;
|
||||
|
||||
constructor(private dataTable: DataTableComponent) {}
|
||||
|
||||
ngAfterContentInit() {
|
||||
if (this.dataTable) {
|
||||
this.dataTable.noPermissionTemplate = this.template;
|
||||
|
||||
@@ -67,10 +67,18 @@ describe('ResizableDirective', () => {
|
||||
const injector = TestBed.inject(Injector);
|
||||
spyOn(ngZone, 'runOutsideAngular').and.callFake((fn) => fn());
|
||||
spyOn(ngZone, 'run').and.callFake((fn) => fn());
|
||||
runInInjectionContext(injector, () => {
|
||||
directive = new ResizableDirective(renderer, element, ngZone);
|
||||
|
||||
const testInjector = Injector.create({
|
||||
providers: [
|
||||
{ provide: Renderer2, useValue: renderer },
|
||||
{ provide: ElementRef, useValue: element },
|
||||
{ provide: NgZone, useValue: ngZone }
|
||||
],
|
||||
parent: injector
|
||||
});
|
||||
|
||||
directive = runInInjectionContext(testInjector, () => new ResizableDirective());
|
||||
|
||||
directive.ngOnInit();
|
||||
});
|
||||
|
||||
|
||||
@@ -26,6 +26,10 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
exportAs: 'adf-resizable'
|
||||
})
|
||||
export class ResizableDirective implements OnInit, OnDestroy {
|
||||
private readonly renderer = inject(Renderer2);
|
||||
private readonly element = inject<ElementRef<HTMLElement>>(ElementRef);
|
||||
private readonly zone = inject(NgZone);
|
||||
|
||||
/**
|
||||
* Emitted when the mouse is pressed and a resize event is about to begin.
|
||||
*/
|
||||
@@ -71,7 +75,10 @@ export class ResizableDirective implements OnInit, OnDestroy {
|
||||
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(private readonly renderer: Renderer2, private readonly element: ElementRef<HTMLElement>, private readonly zone: NgZone) {
|
||||
constructor() {
|
||||
const renderer = this.renderer;
|
||||
const zone = this.zone;
|
||||
|
||||
this.pointerDown = new Observable((observer: Observer<IResizeMouseEvent>) => {
|
||||
zone.runOutsideAngular(() => {
|
||||
this.unsubscribeMouseDown = renderer.listen('document', 'mousedown', (event: MouseEvent) => {
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ElementRef, NgZone, Renderer2 } from '@angular/core';
|
||||
import { ElementRef, NgZone, Renderer2, Injector, runInInjectionContext } from '@angular/core';
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { ResizeHandleDirective } from './resize-handle.directive';
|
||||
import { ResizableDirective } from './resizable.directive';
|
||||
import { Subject } from 'rxjs';
|
||||
@@ -38,7 +39,16 @@ describe('ResizeHandleDirective', () => {
|
||||
mousemove: new Subject()
|
||||
});
|
||||
|
||||
directive = new ResizeHandleDirective(renderer, element, ngZone);
|
||||
const injector = Injector.create({
|
||||
providers: [
|
||||
{ provide: Renderer2, useValue: renderer },
|
||||
{ provide: ElementRef, useValue: element },
|
||||
{ provide: NgZone, useValue: ngZone }
|
||||
],
|
||||
parent: TestBed.inject(Injector)
|
||||
});
|
||||
|
||||
directive = runInInjectionContext(injector, () => new ResizeHandleDirective());
|
||||
directive.resizableContainer = resizableContainer;
|
||||
});
|
||||
|
||||
|
||||
@@ -16,12 +16,16 @@
|
||||
*/
|
||||
|
||||
import { ResizableDirective } from './resizable.directive';
|
||||
import { Directive, ElementRef, HostListener, Input, NgZone, OnDestroy, OnInit, Renderer2 } from '@angular/core';
|
||||
import { Directive, ElementRef, HostListener, Input, NgZone, OnDestroy, OnInit, Renderer2, inject } from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[adf-resize-handle]'
|
||||
})
|
||||
export class ResizeHandleDirective implements OnInit, OnDestroy {
|
||||
private readonly renderer = inject(Renderer2);
|
||||
private readonly element = inject(ElementRef);
|
||||
private readonly zone = inject(NgZone);
|
||||
|
||||
/**
|
||||
* Reference to ResizableDirective
|
||||
*/
|
||||
@@ -30,7 +34,6 @@ export class ResizeHandleDirective implements OnInit, OnDestroy {
|
||||
private unlistenMouseDown?: () => void;
|
||||
private unlistenMouseMove?: () => void;
|
||||
private unlistenMouseUp?: () => void;
|
||||
constructor(private readonly renderer: Renderer2, private readonly element: ElementRef, private readonly zone: NgZone) {}
|
||||
|
||||
@HostListener('keydown', ['$event'])
|
||||
onKeydown(event: KeyboardEvent): void {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, Inject, SecurityContext, ViewEncapsulation } from '@angular/core';
|
||||
import { Component, SecurityContext, ViewEncapsulation, inject } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
@@ -41,6 +41,9 @@ export interface ConfirmDialogComponentProps {
|
||||
imports: [TranslatePipe, MatDialogModule, NgIf, MatButtonModule]
|
||||
})
|
||||
export class ConfirmDialogComponent {
|
||||
private readonly sanitizer = inject(DomSanitizer);
|
||||
private readonly data = inject<ConfirmDialogComponentProps>(MAT_DIALOG_DATA) ?? {};
|
||||
|
||||
title: string;
|
||||
message: string;
|
||||
yesLabel: string;
|
||||
@@ -48,14 +51,13 @@ export class ConfirmDialogComponent {
|
||||
thirdOptionLabel: string;
|
||||
htmlContent: string;
|
||||
|
||||
constructor(@Inject(MAT_DIALOG_DATA) data: ConfirmDialogComponentProps, private sanitizer: DomSanitizer) {
|
||||
data = data || {};
|
||||
this.title = data.title || 'ADF_CONFIRM_DIALOG.TITLE';
|
||||
this.message = data.message || 'ADF_CONFIRM_DIALOG.MESSAGE';
|
||||
this.yesLabel = data.yesLabel || 'ADF_CONFIRM_DIALOG.YES_LABEL';
|
||||
this.thirdOptionLabel = data.thirdOptionLabel;
|
||||
this.noLabel = data.noLabel || 'ADF_CONFIRM_DIALOG.NO_LABEL';
|
||||
this.htmlContent = data.htmlContent;
|
||||
constructor() {
|
||||
this.title = this.data.title || 'ADF_CONFIRM_DIALOG.TITLE';
|
||||
this.message = this.data.message || 'ADF_CONFIRM_DIALOG.MESSAGE';
|
||||
this.yesLabel = this.data.yesLabel || 'ADF_CONFIRM_DIALOG.YES_LABEL';
|
||||
this.thirdOptionLabel = this.data.thirdOptionLabel;
|
||||
this.noLabel = this.data.noLabel || 'ADF_CONFIRM_DIALOG.NO_LABEL';
|
||||
this.htmlContent = this.data.htmlContent;
|
||||
}
|
||||
|
||||
sanitizedHtmlContent(): string {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, Inject, InjectionToken, Injector, ViewEncapsulation } from '@angular/core';
|
||||
import { Component, InjectionToken, Injector, ViewEncapsulation, inject } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
|
||||
import { AdditionalDialogActionButton, DialogData } from './dialog-data.interface';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
@@ -36,6 +36,9 @@ export const DIALOG_COMPONENT_DATA = new InjectionToken<any>('dialog component d
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class DialogComponent {
|
||||
data = inject<DialogData>(MAT_DIALOG_DATA);
|
||||
dialogRef = inject<MatDialogRef<DialogComponent>>(MatDialogRef);
|
||||
|
||||
isConfirmButtonDisabled$ = new BehaviorSubject<boolean>(false);
|
||||
isCloseButtonHidden: boolean;
|
||||
isCancelButtonHidden: boolean;
|
||||
@@ -47,11 +50,9 @@ export class DialogComponent {
|
||||
|
||||
dataInjector: Injector;
|
||||
|
||||
constructor(
|
||||
@Inject(MAT_DIALOG_DATA)
|
||||
public data: DialogData,
|
||||
public dialogRef: MatDialogRef<DialogComponent>
|
||||
) {
|
||||
constructor() {
|
||||
const data = this.data;
|
||||
|
||||
if (data) {
|
||||
this.isCancelButtonHidden = data.isCancelButtonHidden || false;
|
||||
this.isCloseButtonHidden = data.isCloseButtonHidden || false;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, Inject, OnInit, Input, ViewEncapsulation } from '@angular/core';
|
||||
import { Component, OnInit, Input, ViewEncapsulation, inject } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
@@ -36,14 +36,14 @@ export interface EditJsonDialogSettings {
|
||||
host: { class: 'adf-edit-json-dialog' }
|
||||
})
|
||||
export class EditJsonDialogComponent implements OnInit {
|
||||
private readonly settings = inject<EditJsonDialogSettings>(MAT_DIALOG_DATA);
|
||||
|
||||
editable: boolean = false;
|
||||
title: string = 'JSON';
|
||||
|
||||
@Input()
|
||||
value: string = '';
|
||||
|
||||
constructor(@Inject(MAT_DIALOG_DATA) private settings: EditJsonDialogSettings) {}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.settings) {
|
||||
this.editable = this.settings.editable;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, Inject, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { Component, OnInit, ViewEncapsulation, inject } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
|
||||
import { UnsavedChangesDialogData } from './unsaved-changes-dialog.model';
|
||||
import { MatCheckboxChange, MatCheckboxModule } from '@angular/material/checkbox';
|
||||
@@ -44,12 +44,10 @@ import { IconModule } from '../../icon/icon.module';
|
||||
imports: [MatDialogModule, TranslatePipe, MatButtonModule, IconModule, CommonModule, MatCheckboxModule, ReactiveFormsModule]
|
||||
})
|
||||
export class UnsavedChangesDialogComponent implements OnInit {
|
||||
dialogData: UnsavedChangesDialogData;
|
||||
data = inject<UnsavedChangesDialogData>(MAT_DIALOG_DATA);
|
||||
private readonly userPreferencesService = inject(UserPreferencesService);
|
||||
|
||||
constructor(
|
||||
@Inject(MAT_DIALOG_DATA) public data: UnsavedChangesDialogData,
|
||||
private userPreferencesService: UserPreferencesService
|
||||
) {}
|
||||
dialogData: UnsavedChangesDialogData;
|
||||
|
||||
ngOnInit() {
|
||||
this.dialogData = {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { CanDeactivate } from '@angular/router';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
@@ -31,11 +31,13 @@ import { AuthenticationService, AuthGuardService } from '../../auth';
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class UnsavedChangesGuard implements CanDeactivate<any> {
|
||||
private readonly dialog = inject(MatDialog);
|
||||
private readonly authenticationService = inject(AuthenticationService);
|
||||
private readonly authGuardBaseService = inject(AuthGuardService);
|
||||
|
||||
unsaved = false;
|
||||
data: UnsavedChangesDialogData;
|
||||
|
||||
constructor(private dialog: MatDialog, private authenticationService: AuthenticationService, private authGuardBaseService: AuthGuardService) {}
|
||||
|
||||
/**
|
||||
* Allows to deactivate route when there is no unsaved changes, otherwise displays dialog to confirm discarding changes.
|
||||
*
|
||||
|
||||
@@ -17,13 +17,17 @@
|
||||
|
||||
/* eslint-disable @angular-eslint/no-input-rename */
|
||||
|
||||
import { Directive, ElementRef, Input, Renderer2, AfterViewChecked } from '@angular/core';
|
||||
import { Directive, ElementRef, Input, Renderer2, AfterViewChecked, inject } from '@angular/core';
|
||||
import { HighlightTransformService, HighlightTransformResult } from '../common/services/highlight-transform.service';
|
||||
|
||||
@Directive({
|
||||
selector: '[adf-highlight]'
|
||||
})
|
||||
export class HighlightDirective implements AfterViewChecked {
|
||||
private readonly el = inject(ElementRef);
|
||||
private readonly renderer = inject(Renderer2);
|
||||
private readonly highlightTransformService = inject(HighlightTransformService);
|
||||
|
||||
/** Class selector for highlightable elements. */
|
||||
@Input('adf-highlight-selector')
|
||||
selector: string = '';
|
||||
@@ -36,8 +40,6 @@ export class HighlightDirective implements AfterViewChecked {
|
||||
@Input('adf-highlight-class')
|
||||
classToApply: string = 'adf-highlight';
|
||||
|
||||
constructor(private el: ElementRef, private renderer: Renderer2, private highlightTransformService: HighlightTransformService) {}
|
||||
|
||||
ngAfterViewChecked() {
|
||||
this.highlight();
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AfterViewInit, DestroyRef, Directive, EventEmitter, inject, Inject, Output } from '@angular/core';
|
||||
import { AfterViewInit, DestroyRef, Directive, EventEmitter, inject, Output } from '@angular/core';
|
||||
import { MatSelect } from '@angular/material/select';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
@@ -25,6 +25,8 @@ const SELECT_ITEM_HEIGHT_EM = 3;
|
||||
selector: '[adf-infinite-select-scroll]'
|
||||
})
|
||||
export class InfiniteSelectScrollDirective implements AfterViewInit {
|
||||
private readonly matSelect = inject<MatSelect>(MatSelect);
|
||||
|
||||
static readonly MAX_ITEMS = 50;
|
||||
|
||||
/** Emitted when scroll reaches the last item. */
|
||||
@@ -33,8 +35,6 @@ export class InfiniteSelectScrollDirective implements AfterViewInit {
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
private itemHeightToWaitBeforeLoadNext = 0;
|
||||
|
||||
constructor(@Inject(MatSelect) private matSelect: MatSelect) {}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.matSelect.openedChange.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((opened: boolean) => {
|
||||
if (opened) {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Input, Directive, ElementRef, OnInit, Renderer2 } from '@angular/core';
|
||||
import { Input, Directive, ElementRef, OnInit, Renderer2, inject } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { AppConfigService } from '../app-config/app-config.service';
|
||||
import { AuthenticationService } from '../auth/services/authentication.service';
|
||||
@@ -24,6 +24,12 @@ import { AuthenticationService } from '../auth/services/authentication.service';
|
||||
selector: '[adf-logout]'
|
||||
})
|
||||
export class LogoutDirective implements OnInit {
|
||||
private readonly elementRef = inject(ElementRef);
|
||||
private readonly renderer = inject(Renderer2);
|
||||
private readonly router = inject(Router);
|
||||
private readonly appConfig = inject(AppConfigService);
|
||||
private readonly authenticationService = inject(AuthenticationService);
|
||||
|
||||
/** URI to redirect to after logging out. */
|
||||
@Input()
|
||||
redirectUri: string;
|
||||
@@ -32,14 +38,6 @@ export class LogoutDirective implements OnInit {
|
||||
@Input()
|
||||
enableRedirect: boolean = true;
|
||||
|
||||
constructor(
|
||||
private elementRef: ElementRef,
|
||||
private renderer: Renderer2,
|
||||
private router: Router,
|
||||
private appConfig: AppConfigService,
|
||||
private authenticationService: AuthenticationService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.elementRef.nativeElement) {
|
||||
this.renderer.listen(this.elementRef.nativeElement, 'click', (evt) => {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, Input, SecurityContext } from '@angular/core';
|
||||
import { Component, Input, SecurityContext, inject } from '@angular/core';
|
||||
import { animate, style, transition, trigger } from '@angular/animations';
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
import { CommonModule } from '@angular/common';
|
||||
@@ -33,13 +33,13 @@ import { CommonModule } from '@angular/common';
|
||||
]
|
||||
})
|
||||
export class TooltipCardComponent {
|
||||
private readonly sanitizer = inject(DomSanitizer);
|
||||
|
||||
@Input() image = '';
|
||||
@Input() text = '';
|
||||
@Input() htmlContent = '';
|
||||
@Input() width = '300';
|
||||
|
||||
constructor(private sanitizer: DomSanitizer) {}
|
||||
|
||||
sanitizedHtmlContent(): string {
|
||||
return this.sanitizer.sanitize(SecurityContext.HTML, this.htmlContent);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ComponentRef, Directive, ElementRef, HostListener, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import { ComponentRef, Directive, ElementRef, HostListener, Input, OnDestroy, OnInit, inject } from '@angular/core';
|
||||
import { Overlay, OverlayPositionBuilder, OverlayRef } from '@angular/cdk/overlay';
|
||||
import { ComponentPortal } from '@angular/cdk/portal';
|
||||
import { TooltipCardComponent } from './tooltip-card.component';
|
||||
@@ -24,6 +24,10 @@ import { TooltipCardComponent } from './tooltip-card.component';
|
||||
selector: '[adf-tooltip-card]'
|
||||
})
|
||||
export class TooltipCardDirective implements OnInit, OnDestroy {
|
||||
private readonly overlay = inject(Overlay);
|
||||
private readonly overlayPositionBuilder = inject(OverlayPositionBuilder);
|
||||
private readonly elementRef = inject(ElementRef);
|
||||
|
||||
@Input('adf-tooltip-card') text = '';
|
||||
@Input() image = '';
|
||||
@Input() width = '300';
|
||||
@@ -37,12 +41,6 @@ export class TooltipCardDirective implements OnInit, OnDestroy {
|
||||
|
||||
private overlayRef: OverlayRef;
|
||||
|
||||
constructor(
|
||||
private overlay: Overlay,
|
||||
private overlayPositionBuilder: OverlayPositionBuilder,
|
||||
private elementRef: ElementRef
|
||||
) {}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (this.overlayRef) {
|
||||
this.hide();
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ElementRef } from '@angular/core';
|
||||
import { fakeAsync, tick } from '@angular/core/testing';
|
||||
import { ElementRef, Renderer2, NgZone, Injector, runInInjectionContext } from '@angular/core';
|
||||
import { fakeAsync, tick, TestBed } from '@angular/core/testing';
|
||||
import { UploadDirective } from './upload.directive';
|
||||
|
||||
describe('UploadDirective', () => {
|
||||
@@ -26,9 +26,26 @@ describe('UploadDirective', () => {
|
||||
beforeEach(() => {
|
||||
nativeElement = {
|
||||
classList: jasmine.createSpyObj('classList', ['add', 'remove']),
|
||||
dispatchEvent: () => {}
|
||||
dispatchEvent: () => {},
|
||||
parentElement: {
|
||||
appendChild: jasmine.createSpy('appendChild')
|
||||
}
|
||||
};
|
||||
directive = new UploadDirective(new ElementRef(nativeElement), null, null);
|
||||
|
||||
const mockRenderer = jasmine.createSpyObj('Renderer2', ['createElement']);
|
||||
const mockNgZone = jasmine.createSpyObj('NgZone', ['runOutsideAngular']);
|
||||
mockNgZone.runOutsideAngular.and.callFake((fn: () => void) => fn());
|
||||
|
||||
const injector = Injector.create({
|
||||
providers: [
|
||||
{ provide: ElementRef, useValue: new ElementRef(nativeElement) },
|
||||
{ provide: Renderer2, useValue: mockRenderer },
|
||||
{ provide: NgZone, useValue: mockNgZone }
|
||||
],
|
||||
parent: TestBed.inject(Injector)
|
||||
});
|
||||
|
||||
directive = runInInjectionContext(injector, () => new UploadDirective());
|
||||
});
|
||||
|
||||
it('should be enabled by default', () => {
|
||||
|
||||
@@ -17,13 +17,17 @@
|
||||
|
||||
/* eslint-disable @angular-eslint/no-input-rename */
|
||||
|
||||
import { Directive, ElementRef, HostListener, Input, NgZone, OnDestroy, OnInit, Renderer2 } from '@angular/core';
|
||||
import { Directive, ElementRef, HostListener, Input, NgZone, OnDestroy, OnInit, Renderer2, inject } from '@angular/core';
|
||||
import { FileInfo, FileUtils } from '../common/utils/file-utils';
|
||||
|
||||
@Directive({
|
||||
selector: '[adf-upload]'
|
||||
})
|
||||
export class UploadDirective implements OnInit, OnDestroy {
|
||||
private readonly el = inject(ElementRef);
|
||||
private readonly renderer = inject(Renderer2);
|
||||
private readonly ngZone = inject(NgZone);
|
||||
|
||||
/** Enables/disables uploading. */
|
||||
@Input('adf-upload')
|
||||
enabled: boolean = true;
|
||||
@@ -53,11 +57,13 @@ export class UploadDirective implements OnInit, OnDestroy {
|
||||
|
||||
isDragging: boolean = false;
|
||||
|
||||
private cssClassName: string = 'adf-upload__dragging';
|
||||
private readonly cssClassName: string = 'adf-upload__dragging';
|
||||
private upload: HTMLInputElement;
|
||||
private element: HTMLElement;
|
||||
private readonly element: HTMLElement;
|
||||
|
||||
constructor() {
|
||||
const el = this.el;
|
||||
|
||||
constructor(private el: ElementRef, private renderer: Renderer2, private ngZone: NgZone) {
|
||||
this.element = el.nativeElement;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,8 @@ import {
|
||||
SimpleChanges,
|
||||
ViewChild,
|
||||
ViewChildren,
|
||||
ViewEncapsulation
|
||||
ViewEncapsulation,
|
||||
inject
|
||||
} from '@angular/core';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatChip, MatChipsModule } from '@angular/material/chips';
|
||||
@@ -51,6 +52,8 @@ import { IconModule } from '../icon/icon.module';
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class DynamicChipListComponent implements OnChanges, OnInit, AfterViewInit, OnDestroy {
|
||||
private readonly changeDetectorRef = inject(ChangeDetectorRef);
|
||||
|
||||
/* eslint no-underscore-dangle: ["error", { "allow": ["_elementRef"] }]*/
|
||||
/** Provide if you want to use paginated chips. */
|
||||
@Input()
|
||||
@@ -103,15 +106,13 @@ export class DynamicChipListComponent implements OnChanges, OnInit, AfterViewIni
|
||||
private initialLimitChipsDisplayed: boolean;
|
||||
private viewMoreButtonLeftOffsetBeforeFlexDirection: number;
|
||||
private requestedDisplayingAllChips = false;
|
||||
private resizeObserver = new ResizeObserver(() => {
|
||||
private readonly resizeObserver = new ResizeObserver(() => {
|
||||
if (this.initialLimitChipsDisplayed && this.chipsToDisplay.length) {
|
||||
this.calculateChipsToDisplay();
|
||||
this.changeDetectorRef.detectChanges();
|
||||
}
|
||||
});
|
||||
|
||||
constructor(private changeDetectorRef: ChangeDetectorRef) {}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
if (changes.pagination) {
|
||||
this.limitChipsDisplayed = this.pagination?.hasMoreItems;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import { NgClass, NgForOf, NgIf, NgStyle, NgTemplateOutlet } from '@angular/common';
|
||||
import { ChangeDetectorRef, Component, Inject, inject, Injector, Input, OnDestroy, OnInit, Optional, ViewEncapsulation } from '@angular/core';
|
||||
import { ChangeDetectorRef, Component, inject, Injector, Input, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatTabsModule } from '@angular/material/tabs';
|
||||
@@ -70,10 +70,12 @@ import { IconModule } from '../../icon/icon.module';
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class FormRendererComponent<T> implements OnInit, OnDestroy {
|
||||
private readonly middlewareServices = inject<FormFieldModelRenderMiddleware[]>(FORM_FIELD_MODEL_RENDER_MIDDLEWARE, { optional: true }) ?? [];
|
||||
|
||||
public readonly formService = inject(FormService);
|
||||
private readonly formRulesManager = inject(FormRulesManager<T>);
|
||||
private readonly dialog = inject(MatDialog);
|
||||
private cdr = inject(ChangeDetectorRef);
|
||||
private readonly cdr = inject(ChangeDetectorRef);
|
||||
|
||||
@Input({ required: true })
|
||||
formDefinition: FormModel;
|
||||
@@ -85,12 +87,6 @@ export class FormRendererComponent<T> implements OnInit, OnDestroy {
|
||||
|
||||
fields: FormFieldModel[];
|
||||
|
||||
constructor(
|
||||
@Optional()
|
||||
@Inject(FORM_FIELD_MODEL_RENDER_MIDDLEWARE)
|
||||
private middlewareServices?: FormFieldModelRenderMiddleware[]
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.runMiddlewareServices();
|
||||
if (!this.readOnly) {
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
/* eslint-disable @angular-eslint/component-selector */
|
||||
|
||||
import { CurrencyPipe, NgIf } from '@angular/common';
|
||||
import { Component, OnInit, ViewEncapsulation, InjectionToken, Inject, Optional, inject, DestroyRef } from '@angular/core';
|
||||
import { Component, OnInit, ViewEncapsulation, InjectionToken, inject, DestroyRef } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
@@ -57,6 +57,9 @@ export const ADF_AMOUNT_SETTINGS = new InjectionToken<Observable<AmountWidgetSet
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class AmountWidgetComponent extends WidgetComponent implements OnInit {
|
||||
private readonly currencyPipe = inject(CurrencyPipe);
|
||||
private readonly translationService = inject(TranslationService);
|
||||
|
||||
static DEFAULT_CURRENCY: string = '$';
|
||||
private showPlaceholder = true;
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
@@ -85,11 +88,9 @@ export class AmountWidgetComponent extends WidgetComponent implements OnInit {
|
||||
return this.currencyPipe.transform(this.field.placeholder, this.currency, this.currencyDisplay, this.decimalProperty, this.locale);
|
||||
}
|
||||
|
||||
constructor(
|
||||
@Optional() @Inject(ADF_AMOUNT_SETTINGS) settings: Observable<AmountWidgetSettings> | AmountWidgetSettings,
|
||||
private currencyPipe: CurrencyPipe,
|
||||
private translationService: TranslationService
|
||||
) {
|
||||
constructor() {
|
||||
const settings = inject<Observable<AmountWidgetSettings> | AmountWidgetSettings>(ADF_AMOUNT_SETTINGS, { optional: true });
|
||||
|
||||
super();
|
||||
if (isObservable(settings)) {
|
||||
settings.pipe(takeUntilDestroyed()).subscribe((data: AmountWidgetSettings) => {
|
||||
|
||||
+9
-5
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ChangeDetectorRef, Component, inject, AfterViewInit, DestroyRef, InjectionToken, Optional, Inject } from '@angular/core';
|
||||
import { ChangeDetectorRef, Component, inject, AfterViewInit, DestroyRef, InjectionToken } from '@angular/core';
|
||||
import { debounceTime, filter, isObservable, Observable } from 'rxjs';
|
||||
import { FormRulesEvent } from '../../../events';
|
||||
import { FormExpressionService } from '../../../services/form-expression.service';
|
||||
@@ -39,14 +39,18 @@ export abstract class BaseDisplayTextWidgetComponent extends WidgetComponent imp
|
||||
private enableExpressionEvaluation: boolean = false;
|
||||
protected originalFieldValue?: string;
|
||||
|
||||
constructor(@Optional() @Inject(ADF_DISPLAY_TEXT_SETTINGS) settings: Observable<DisplayTextWidgetSettings> | DisplayTextWidgetSettings) {
|
||||
private readonly settings = inject<Observable<DisplayTextWidgetSettings> | DisplayTextWidgetSettings>(ADF_DISPLAY_TEXT_SETTINGS, {
|
||||
optional: true
|
||||
});
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
if (isObservable(settings)) {
|
||||
settings.pipe(takeUntilDestroyed()).subscribe((data: DisplayTextWidgetSettings) => {
|
||||
if (isObservable(this.settings)) {
|
||||
this.settings.pipe(takeUntilDestroyed()).subscribe((data: DisplayTextWidgetSettings) => {
|
||||
this.updateSettingsBasedProperties(data);
|
||||
});
|
||||
} else {
|
||||
this.updateSettingsBasedProperties(settings);
|
||||
this.updateSettingsBasedProperties(this.settings);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ export interface FormFieldValidator {
|
||||
}
|
||||
|
||||
export class RequiredFieldValidator implements FormFieldValidator {
|
||||
private supportedTypes = [
|
||||
private readonly supportedTypes = [
|
||||
FormFieldTypes.TEXT,
|
||||
FormFieldTypes.MULTILINE_TEXT,
|
||||
FormFieldTypes.NUMBER,
|
||||
@@ -78,7 +78,7 @@ export class RequiredFieldValidator implements FormFieldValidator {
|
||||
}
|
||||
|
||||
export class NumberFieldValidator implements FormFieldValidator {
|
||||
private supportedTypes = [FormFieldTypes.NUMBER, FormFieldTypes.AMOUNT];
|
||||
private readonly supportedTypes = [FormFieldTypes.NUMBER, FormFieldTypes.AMOUNT];
|
||||
|
||||
static isNumber(value: any): boolean {
|
||||
return isNumberValue(value);
|
||||
@@ -109,7 +109,7 @@ export class NumberFieldValidator implements FormFieldValidator {
|
||||
}
|
||||
|
||||
export class MinLengthFieldValidator implements FormFieldValidator {
|
||||
private supportedTypes = [FormFieldTypes.TEXT, FormFieldTypes.MULTILINE_TEXT];
|
||||
private readonly supportedTypes = [FormFieldTypes.TEXT, FormFieldTypes.MULTILINE_TEXT];
|
||||
|
||||
isSupported(field: FormFieldModel): boolean {
|
||||
return field && this.supportedTypes.indexOf(field.type) > -1 && field.minLength > 0;
|
||||
@@ -130,8 +130,8 @@ export class MinLengthFieldValidator implements FormFieldValidator {
|
||||
|
||||
export class MaxLengthFieldValidator implements FormFieldValidator {
|
||||
constructor(
|
||||
private supportedTypes: FormFieldTypes[] = [FormFieldTypes.TEXT, FormFieldTypes.MULTILINE_TEXT],
|
||||
private maxLength?: number
|
||||
private readonly supportedTypes: FormFieldTypes[] = [FormFieldTypes.TEXT, FormFieldTypes.MULTILINE_TEXT],
|
||||
private readonly maxLength?: number
|
||||
) {}
|
||||
|
||||
isSupported(field: FormFieldModel): boolean {
|
||||
@@ -159,7 +159,7 @@ export class MaxLengthFieldValidator implements FormFieldValidator {
|
||||
}
|
||||
|
||||
export class MinValueFieldValidator implements FormFieldValidator {
|
||||
private supportedTypes = [FormFieldTypes.NUMBER, FormFieldTypes.DECIMAL, FormFieldTypes.AMOUNT];
|
||||
private readonly supportedTypes = [FormFieldTypes.NUMBER, FormFieldTypes.DECIMAL, FormFieldTypes.AMOUNT];
|
||||
|
||||
isSupported(field: FormFieldModel): boolean {
|
||||
return field && this.supportedTypes.indexOf(field.type) > -1 && NumberFieldValidator.isNumber(field.minValue);
|
||||
@@ -183,7 +183,7 @@ export class MinValueFieldValidator implements FormFieldValidator {
|
||||
}
|
||||
|
||||
export class MaxValueFieldValidator implements FormFieldValidator {
|
||||
private supportedTypes = [FormFieldTypes.NUMBER, FormFieldTypes.DECIMAL, FormFieldTypes.AMOUNT];
|
||||
private readonly supportedTypes = [FormFieldTypes.NUMBER, FormFieldTypes.DECIMAL, FormFieldTypes.AMOUNT];
|
||||
|
||||
isSupported(field: FormFieldModel): boolean {
|
||||
return field && this.supportedTypes.indexOf(field.type) > -1 && NumberFieldValidator.isNumber(field.maxValue);
|
||||
@@ -207,7 +207,7 @@ export class MaxValueFieldValidator implements FormFieldValidator {
|
||||
}
|
||||
|
||||
export class RegExFieldValidator implements FormFieldValidator {
|
||||
private supportedTypes = [FormFieldTypes.TEXT, FormFieldTypes.MULTILINE_TEXT];
|
||||
private readonly supportedTypes = [FormFieldTypes.TEXT, FormFieldTypes.MULTILINE_TEXT];
|
||||
|
||||
isSupported(field: FormFieldModel): boolean {
|
||||
return field && this.supportedTypes.indexOf(field.type) > -1 && !!field.regexPattern;
|
||||
@@ -226,7 +226,7 @@ export class RegExFieldValidator implements FormFieldValidator {
|
||||
}
|
||||
|
||||
export class FixedValueFieldValidator implements FormFieldValidator {
|
||||
private supportedTypes = [FormFieldTypes.TYPEAHEAD];
|
||||
private readonly supportedTypes = [FormFieldTypes.TYPEAHEAD];
|
||||
|
||||
isSupported(field: FormFieldModel): boolean {
|
||||
return field && this.supportedTypes.indexOf(field.type) > -1;
|
||||
@@ -264,7 +264,7 @@ export class FixedValueFieldValidator implements FormFieldValidator {
|
||||
}
|
||||
|
||||
export class DecimalFieldValidator implements FormFieldValidator {
|
||||
private supportedTypes = [FormFieldTypes.DECIMAL];
|
||||
private readonly supportedTypes = [FormFieldTypes.DECIMAL];
|
||||
|
||||
isSupported(field: FormFieldModel): boolean {
|
||||
return field && this.supportedTypes.indexOf(field.type) > -1 && !!field.value;
|
||||
|
||||
@@ -25,12 +25,16 @@ import { FormOutcomeModel } from './form-outcome.model';
|
||||
import { FormModel } from './form.model';
|
||||
import { TabModel } from './tab.model';
|
||||
import { fakeMetadataForm, mockDisplayExternalPropertyForm, mockFormWithSections, fakeValidatorMock } from '../../mock/form.mock';
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
describe('FormModel', () => {
|
||||
let formService: FormService;
|
||||
|
||||
beforeEach(() => {
|
||||
formService = new FormService();
|
||||
TestBed.configureTestingModule({
|
||||
providers: [FormService]
|
||||
});
|
||||
formService = TestBed.inject(FormService);
|
||||
});
|
||||
|
||||
it('should store original json', () => {
|
||||
|
||||
@@ -41,7 +41,7 @@ import { TranslatePipe } from '@ngx-translate/core';
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class JsonWidgetComponent extends WidgetComponent {
|
||||
private dialog = inject(MatDialog);
|
||||
private readonly dialog = inject(MatDialog);
|
||||
|
||||
view() {
|
||||
const rawValue = this.field.value;
|
||||
|
||||
@@ -49,7 +49,7 @@ import { WidgetComponent } from '../widget.component';
|
||||
export class NumberWidgetComponent extends WidgetComponent implements OnInit {
|
||||
displayValue: number;
|
||||
|
||||
private decimalNumberPipe = inject(DecimalNumberPipe);
|
||||
private readonly decimalNumberPipe = inject(DecimalNumberPipe);
|
||||
|
||||
ngOnInit() {
|
||||
if (this.field.readOnly) {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
/* eslint-disable @angular-eslint/component-selector, @typescript-eslint/no-use-before-define, @angular-eslint/no-input-rename */
|
||||
|
||||
import { Directive, ElementRef, forwardRef, HostListener, Input, OnChanges, Renderer2, SimpleChanges } from '@angular/core';
|
||||
import { Directive, ElementRef, forwardRef, HostListener, Input, OnChanges, Renderer2, SimpleChanges, inject } from '@angular/core';
|
||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
|
||||
export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
|
||||
@@ -34,13 +34,16 @@ export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
|
||||
providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR]
|
||||
})
|
||||
export class InputMaskDirective implements OnChanges, ControlValueAccessor {
|
||||
private readonly el = inject(ElementRef);
|
||||
private readonly render = inject(Renderer2);
|
||||
|
||||
/** Object defining mask and "reversed" status. */
|
||||
@Input('textMask') inputMask: {
|
||||
mask: string;
|
||||
isReversed: boolean;
|
||||
};
|
||||
|
||||
private translationMask = {
|
||||
private readonly translationMask = {
|
||||
'0': { pattern: /\d/ },
|
||||
'9': { pattern: /\d/, optional: true },
|
||||
'#': { pattern: /\d/, recursive: true },
|
||||
@@ -48,11 +51,9 @@ export class InputMaskDirective implements OnChanges, ControlValueAccessor {
|
||||
S: { pattern: /[a-zA-Z]/ }
|
||||
};
|
||||
|
||||
private byPassKeys = [9, 16, 17, 18, 36, 37, 38, 39, 40, 91];
|
||||
private readonly byPassKeys = [9, 16, 17, 18, 36, 37, 38, 39, 40, 91];
|
||||
private value;
|
||||
private invalidCharacters = [];
|
||||
|
||||
constructor(private el: ElementRef, private render: Renderer2) {}
|
||||
private readonly invalidCharacters = [];
|
||||
|
||||
_onChange = (_: any) => {};
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user