[ACS-11417] lint enable angular eslint prefer inject rule default in ng20 for alfresco apps (#5111)

* [ACS-11417] Enable inject prefer eslint rule

* [ACS-11417] Added eslint rule for prefer readonly

* [ACS-11417] Fixed unit tests

* [ACS-11417] Addressed copilot comments
This commit is contained in:
AleksanderSklorz
2026-03-25 08:45:32 +01:00
committed by GitHub
parent 65c814d75b
commit 89a42b3de5
186 changed files with 929 additions and 938 deletions
@@ -91,8 +91,8 @@ export abstract class PageComponent implements OnInit, OnDestroy, OnChanges {
protected readonly destroyRef = inject(DestroyRef);
private autoDownloadService = inject(AutoDownloadService, { optional: true });
private navigationHistoryService = inject(NavigationHistoryService);
private readonly autoDownloadService = inject(AutoDownloadService, { optional: true });
private readonly navigationHistoryService = inject(NavigationHistoryService);
protected subscriptions: Subscription[] = [];
@@ -54,6 +54,12 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
encapsulation: ViewEncapsulation.None
})
export class InfoDrawerComponent implements OnChanges, OnInit, OnDestroy {
private readonly store = inject<Store<any>>(Store);
private readonly contentApi = inject(ContentApiService);
private readonly extensions = inject(AppExtensionService);
private readonly nodesService = inject(NodesApiService);
private readonly contentService = inject(ContentService);
@Input()
nodeId: string;
@@ -75,14 +81,6 @@ export class InfoDrawerComponent implements OnChanges, OnInit, OnDestroy {
private readonly destroyRef = inject(DestroyRef);
constructor(
private store: Store<any>,
private contentApi: ContentApiService,
private extensions: AppExtensionService,
private nodesService: NodesApiService,
private contentService: ContentService
) {}
ngOnInit() {
this.tabs = this.extensions.getSidebarTabs();
this.extensions
@@ -22,7 +22,7 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, Inject, ViewEncapsulation } from '@angular/core';
import { Component, ViewEncapsulation, inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { CommonModule } from '@angular/common';
import { TranslatePipe } from '@ngx-translate/core';
@@ -42,15 +42,16 @@ export interface OpenInAppDialogOptions {
encapsulation: ViewEncapsulation.None
})
export class OpenInAppComponent {
private redirectUrl: string;
data = inject<OpenInAppDialogOptions>(MAT_DIALOG_DATA);
private readonly dialog = inject<MatDialogRef<OpenInAppComponent>>(MatDialogRef);
private readonly redirectUrl: string;
public appStoreUrl: string;
public window: Window & typeof globalThis = window;
constructor(
@Inject(MAT_DIALOG_DATA)
public data: OpenInAppDialogOptions,
private dialog: MatDialogRef<OpenInAppComponent>
) {
constructor() {
const data = this.data;
if (data) {
this.redirectUrl = data.redirectUrl;
this.appStoreUrl = data.appStoreUrl;
@@ -22,7 +22,7 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, Input, ViewEncapsulation } from '@angular/core';
import { Component, Input, ViewEncapsulation, inject } from '@angular/core';
import { Observable } from 'rxjs';
import { AppService } from '../../services/app.service';
import { CommonModule } from '@angular/common';
@@ -40,12 +40,16 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
host: { class: 'aca-page-layout' }
})
export class PageLayoutComponent {
private readonly appService = inject(AppService);
@Input()
hasError = false;
appNavNarMode$: Observable<'collapsed' | 'expanded'>;
constructor(private appService: AppService) {
constructor() {
const appService = this.appService;
this.appNavNarMode$ = appService.appNavNarMode$.pipe(takeUntilDestroyed());
}
@@ -25,25 +25,30 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ToolbarActionComponent } from './toolbar-action.component';
import { ToolbarButtonType } from '../toolbar-button/toolbar-button.component';
import { ChangeDetectorRef } from '@angular/core';
import { ContentActionType } from '@alfresco/adf-extensions';
import { LibTestingModule } from '@alfresco/aca-shared';
import { ChangeDetectorRef } from '@angular/core';
describe('ToolbarActionComponent', () => {
let fixture: ComponentFixture<ToolbarActionComponent>;
let component: ToolbarActionComponent;
let changeDetectorRef: ChangeDetectorRef;
let mockChangeDetectorRef: jasmine.SpyObj<ChangeDetectorRef>;
beforeEach(() => {
mockChangeDetectorRef = jasmine.createSpyObj('ChangeDetectorRef', ['markForCheck', 'detectChanges']);
TestBed.configureTestingModule({
imports: [LibTestingModule, ToolbarActionComponent],
providers: [{ provide: ChangeDetectorRef, useValue: { markForCheck() {} } }]
imports: [LibTestingModule, ToolbarActionComponent]
});
fixture = TestBed.createComponent(ToolbarActionComponent);
component = fixture.componentInstance;
changeDetectorRef = TestBed.inject(ChangeDetectorRef);
Object.defineProperty(component, 'cd', {
value: mockChangeDetectorRef,
writable: false,
configurable: true
});
});
it('should be icon button by default', () => {
@@ -51,9 +56,6 @@ describe('ToolbarActionComponent', () => {
});
it('should force update UI on check for the viewer', () => {
component = new ToolbarActionComponent(changeDetectorRef);
const markForCheck = spyOn(changeDetectorRef, 'markForCheck');
component.actionRef = {
id: '-app.viewer',
type: ContentActionType.button,
@@ -63,6 +65,6 @@ describe('ToolbarActionComponent', () => {
};
component.ngDoCheck();
expect(markForCheck).toHaveBeenCalled();
expect(mockChangeDetectorRef.markForCheck).toHaveBeenCalled();
});
});
@@ -22,7 +22,7 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, ViewEncapsulation, ChangeDetectionStrategy, Input, DoCheck, ChangeDetectorRef } from '@angular/core';
import { Component, ViewEncapsulation, ChangeDetectionStrategy, Input, DoCheck, ChangeDetectorRef, inject } from '@angular/core';
import { ContentActionRef, DynamicExtensionComponent } from '@alfresco/adf-extensions';
import { ToolbarButtonComponent, ToolbarButtonType } from '../toolbar-button/toolbar-button.component';
import { ThemePalette } from '@angular/material/core';
@@ -39,6 +39,8 @@ import { ToolbarMenuComponent } from '../toolbar-menu/toolbar-menu.component';
host: { class: 'aca-toolbar-action' }
})
export class ToolbarActionComponent implements DoCheck {
private readonly cd = inject(ChangeDetectorRef);
@Input()
data: {
buttonType?: ToolbarButtonType;
@@ -54,8 +56,6 @@ export class ToolbarActionComponent implements DoCheck {
@Input()
actionRef: ContentActionRef;
constructor(private cd: ChangeDetectorRef) {}
// todo: review after ADF 2.6
// preview component : change detection workaround for children without input
ngDoCheck() {
@@ -22,7 +22,7 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Component, Input, ViewEncapsulation } from '@angular/core';
import { Component, Input, ViewEncapsulation, inject } from '@angular/core';
import { ContentActionRef } from '@alfresco/adf-extensions';
import { AppExtensionService } from '../../../services/app.extension.service';
import { ThemePalette } from '@angular/material/core';
@@ -47,6 +47,8 @@ export enum ToolbarButtonType {
host: { class: 'app-toolbar-button' }
})
export class ToolbarButtonComponent {
private readonly extensions = inject(AppExtensionService);
@Input()
data: {
buttonType?: ToolbarButtonType;
@@ -62,8 +64,6 @@ export class ToolbarButtonComponent {
@Input()
actionRef: ContentActionRef;
constructor(private extensions: AppExtensionService) {}
runAction() {
if (this.hasClickAction(this.actionRef)) {
this.extensions.runActionById(this.actionRef.actions.click, {
@@ -22,7 +22,7 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { AfterViewInit, Component, Input, ViewChild, ViewEncapsulation } from '@angular/core';
import { AfterViewInit, Component, Input, ViewChild, ViewEncapsulation, inject } from '@angular/core';
import { ContentActionRef, DynamicExtensionComponent } from '@alfresco/adf-extensions';
import { AppExtensionService } from '../../../services/app.extension.service';
import { MatMenuItem, MatMenuModule } from '@angular/material/menu';
@@ -40,6 +40,8 @@ import { IconComponent } from '@alfresco/adf-core';
host: { class: 'app-toolbar-menu-item' }
})
export class ToolbarMenuItemComponent implements AfterViewInit {
private readonly extensions = inject(AppExtensionService);
@Input()
actionRef: ContentActionRef;
@Input()
@@ -51,8 +53,6 @@ export class ToolbarMenuItemComponent implements AfterViewInit {
@ViewChild(DynamicExtensionComponent)
dynamicComponent: DynamicExtensionComponent;
constructor(private extensions: AppExtensionService) {}
runAction() {
if (this.hasClickAction(this.actionRef)) {
this.extensions.runActionById(
@@ -27,7 +27,6 @@ import { ContextMenu, CustomContextMenu } from '@alfresco/aca-shared/store';
import { ContentActionRef, ContentActionType } from '@alfresco/adf-extensions';
import { fakeAsync, TestBed, tick } from '@angular/core/testing';
import { Store } from '@ngrx/store';
import { Injector, runInInjectionContext } from '@angular/core';
const customActionsMock: ContentActionRef[] = [
{
@@ -50,11 +49,9 @@ describe('ContextActionsDirective', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ContextActionsDirective],
providers: [{ provide: Store, useValue: storeMock }]
});
runInInjectionContext(TestBed.inject(Injector), () => {
directive = new ContextActionsDirective(storeMock);
providers: [ContextActionsDirective, { provide: Store, useValue: storeMock }]
});
directive = TestBed.inject(ContextActionsDirective);
});
it('should not render context menu when `enabled` property is false', () => {
@@ -36,6 +36,8 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
exportAs: 'acaContextActions'
})
export class ContextActionsDirective implements OnInit {
private readonly store = inject<Store<AppStore>>(Store);
// eslint-disable-next-line
@Input('acaContextEnable')
enabled = true;
@@ -57,12 +59,10 @@ export class ContextActionsDirective implements OnInit {
}
}
private execute$: Subject<any> = new Subject();
private readonly execute$: Subject<any> = new Subject();
private readonly destroyRef = inject(DestroyRef);
constructor(private store: Store<AppStore>) {}
ngOnInit() {
this.execute$.pipe(debounceTime(300), takeUntilDestroyed(this.destroyRef)).subscribe((event: MouseEvent) => {
if (this.customActions?.length) {
@@ -23,50 +23,50 @@
*/
import { PaginationDirective } from './pagination.directive';
import { Component, ViewChild } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AppConfigService, PaginationComponent, PaginationModel, UserPreferencesService } from '@alfresco/adf-core';
import { initialState, LibTestingModule } from '../testing/lib-testing-module';
import { provideMockStore } from '@ngrx/store/testing';
import { Injector, runInInjectionContext } from '@angular/core';
@Component({
template: '<adf-pagination acaPagination></adf-pagination>',
imports: [PaginationComponent, PaginationDirective]
})
class TestComponent {
@ViewChild(PaginationComponent) pagination: PaginationComponent;
}
describe('PaginationDirective', () => {
let preferences: UserPreferencesService;
let config: AppConfigService;
let pagination: PaginationComponent;
let fixture: ComponentFixture<PaginationComponent>;
let directive: PaginationDirective;
let fixture: ComponentFixture<TestComponent>;
let component: TestComponent;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [LibTestingModule, PaginationDirective],
imports: [LibTestingModule, TestComponent],
providers: [provideMockStore({ initialState })]
});
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
preferences = TestBed.inject(UserPreferencesService);
config = TestBed.inject(AppConfigService);
fixture = TestBed.createComponent(PaginationComponent);
pagination = fixture.componentInstance;
runInInjectionContext(TestBed.inject(Injector), () => {
directive = new PaginationDirective(pagination, preferences, config);
});
});
afterEach(() => {
fixture.destroy();
});
it('should setup supported page sizes from app config', () => {
spyOn(config, 'get').and.returnValue([21, 31, 41]);
directive.ngOnInit();
fixture.detectChanges();
expect(pagination.supportedPageSizes).toEqual([21, 31, 41]);
expect(component.pagination.supportedPageSizes).toEqual([21, 31, 41]);
});
it('should update preferences on page size change', () => {
directive.ngOnInit();
fixture.detectChanges();
pagination.changePageSize.emit(
component.pagination.changePageSize.emit(
new PaginationModel({
maxItems: 100
})
@@ -31,13 +31,11 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
selector: '[acaPagination]'
})
export class PaginationDirective implements OnInit {
private readonly destroyRef = inject(DestroyRef);
private readonly pagination = inject(PaginationComponent);
private readonly preferences = inject(UserPreferencesService);
private readonly config = inject(AppConfigService);
constructor(
private readonly pagination: PaginationComponent,
private readonly preferences: UserPreferencesService,
private readonly config: AppConfigService
) {}
private readonly destroyRef = inject(DestroyRef);
ngOnInit() {
this.pagination.supportedPageSizes = this.config.get('pagination.supportedPageSizes');
@@ -33,8 +33,8 @@ import { OpenInAppComponent } from '../components/open-in-app/open-in-app.compon
export class AcaMobileAppSwitcherService {
public redirectUrl: string;
private dialogRef: MatDialogRef<OpenInAppComponent>;
private config = inject(AppConfigService);
private dialog = inject(MatDialog);
private readonly config = inject(AppConfigService);
private readonly dialog = inject(MatDialog);
get appStoreUrl(): string {
const defaultValue = 'https://apps.apple.com/us/app/alfresco-mobile-workspace/id1514434480';
@@ -28,7 +28,7 @@ import { AlfrescoMimeType, DefaultMimeTypes } from '../constants/mime-types';
@Injectable({ providedIn: 'root' })
export class AppSettingsService {
private appConfig = inject(AppConfigService);
private readonly appConfig = inject(AppConfigService);
/**
* Get the application copyright text from the app settings.
@@ -71,7 +71,17 @@ export function provideContentAppExtensions(): EnvironmentProviders[] {
providedIn: 'root'
})
export class AppExtensionService implements RuleContext {
private _references = new BehaviorSubject<ExtensionRef[]>([]);
readonly auth = inject(AuthenticationService);
protected readonly store = inject<Store<AppStore>>(Store);
protected readonly loader = inject(ExtensionLoaderService);
protected readonly extensions = inject(ExtensionService);
readonly permissions = inject(NodePermissionService);
readonly appConfig = inject(AppConfigService);
protected readonly matIconRegistry = inject(MatIconRegistry);
protected readonly sanitizer = inject(DomSanitizer);
protected readonly logger = inject(LogService);
private readonly _references = new BehaviorSubject<ExtensionRef[]>([]);
bulkActionExecuted$ = new Subject<void>();
navbar: Array<NavBarGroupRef> = [];
@@ -80,18 +90,18 @@ export class AppExtensionService implements RuleContext {
search: any;
viewerRules: ViewerRules = {};
private _headerActions = new BehaviorSubject<Array<ContentActionRef>>([]);
private _toolbarActions = new BehaviorSubject<Array<ContentActionRef>>([]);
private _viewerToolbarActions = new BehaviorSubject<Array<ContentActionRef>>([]);
private _sharedLinkViewerToolbarActions = new BehaviorSubject<Array<ContentActionRef>>([]);
private _contextMenuActions = new BehaviorSubject<Array<ContentActionRef>>([]);
private _openWithActions = new BehaviorSubject<Array<ContentActionRef>>([]);
private _createActions = new BehaviorSubject<Array<ContentActionRef>>([]);
private _sidebarActions = new BehaviorSubject<Array<ContentActionRef>>([]);
private _badges = new BehaviorSubject<Array<Badge>>([]);
private _filesDocumentListPreset = new BehaviorSubject<Array<DocumentListPresetRef>>([]);
private _customMetadataPanels = new BehaviorSubject<Array<ContentActionRef>>([]);
private _bulkActions = new BehaviorSubject<Array<ContentActionRef>>([]);
private readonly _headerActions = new BehaviorSubject<Array<ContentActionRef>>([]);
private readonly _toolbarActions = new BehaviorSubject<Array<ContentActionRef>>([]);
private readonly _viewerToolbarActions = new BehaviorSubject<Array<ContentActionRef>>([]);
private readonly _sharedLinkViewerToolbarActions = new BehaviorSubject<Array<ContentActionRef>>([]);
private readonly _contextMenuActions = new BehaviorSubject<Array<ContentActionRef>>([]);
private readonly _openWithActions = new BehaviorSubject<Array<ContentActionRef>>([]);
private readonly _createActions = new BehaviorSubject<Array<ContentActionRef>>([]);
private readonly _sidebarActions = new BehaviorSubject<Array<ContentActionRef>>([]);
private readonly _badges = new BehaviorSubject<Array<Badge>>([]);
private readonly _filesDocumentListPreset = new BehaviorSubject<Array<DocumentListPresetRef>>([]);
private readonly _customMetadataPanels = new BehaviorSubject<Array<ContentActionRef>>([]);
private readonly _bulkActions = new BehaviorSubject<Array<ContentActionRef>>([]);
private readonly _userProfileSections = new BehaviorSubject<Array<UserProfileSection>>([]);
documentListPresets: {
@@ -125,17 +135,7 @@ export class AppExtensionService implements RuleContext {
config: ExtensionConfig;
constructor(
public auth: AuthenticationService,
protected store: Store<AppStore>,
protected loader: ExtensionLoaderService,
protected extensions: ExtensionService,
public permissions: NodePermissionService,
public appConfig: AppConfigService,
protected matIconRegistry: MatIconRegistry,
protected sanitizer: DomSanitizer,
protected logger: LogService
) {
constructor() {
this.references$ = this._references.asObservable();
this.store.select(getRuleContext).subscribe((result) => {
@@ -58,13 +58,31 @@ import { MatDialog } from '@angular/material/dialog';
})
// After moving shell to ADF to core, AppService will implement ShellAppService
export class AppService implements ShellAppService {
private notificationService = inject(NotificationService);
private matDialog = inject(MatDialog);
private ready: BehaviorSubject<boolean>;
preferencesService = inject(UserPreferencesService);
private readonly authenticationService = inject(AuthenticationService);
private readonly store = inject<Store<AppStore>>(Store);
private readonly router = inject(Router);
private readonly activatedRoute = inject(ActivatedRoute);
private readonly config = inject(AppConfigService);
private readonly pageTitle = inject(PageTitleService);
private readonly alfrescoApiService = inject(AlfrescoApiService);
private readonly uploadService = inject(UploadService);
private readonly routerExtensionService = inject(RouterExtensionService);
private readonly contentApi = inject(ContentApiService);
private readonly sharedLinksApiService = inject(SharedLinksApiService);
private readonly overlayContainer = inject(OverlayContainer);
private readonly acaMobileAppSwitcherService = inject(AcaMobileAppSwitcherService);
private readonly appSettingsService = inject(AppSettingsService);
private readonly userProfileService = inject(UserProfileService);
private readonly storage = inject(StorageService);
private readonly notificationService = inject(NotificationService);
private readonly matDialog = inject(MatDialog);
private readonly ready: BehaviorSubject<boolean>;
ready$: Observable<boolean>;
private pageHeading = new BehaviorSubject('');
private readonly pageHeading = new BehaviorSubject('');
/** @deprecated page title is updated automatically */
pageHeading$ = this.pageHeading.asObservable();
@@ -82,26 +100,10 @@ export class AppService implements ShellAppService {
return this.config.get<boolean>('auth.withCredentials', false);
}
constructor(
public preferencesService: UserPreferencesService,
private authenticationService: AuthenticationService,
private store: Store<AppStore>,
private router: Router,
private activatedRoute: ActivatedRoute,
private config: AppConfigService,
private pageTitle: PageTitleService,
private alfrescoApiService: AlfrescoApiService,
private uploadService: UploadService,
private routerExtensionService: RouterExtensionService,
private contentApi: ContentApiService,
private sharedLinksApiService: SharedLinksApiService,
private overlayContainer: OverlayContainer,
searchQueryBuilderService: SearchQueryBuilderService,
private acaMobileAppSwitcherService: AcaMobileAppSwitcherService,
private appSettingsService: AppSettingsService,
private readonly userProfileService: UserProfileService,
private readonly storage: StorageService
) {
constructor() {
const searchQueryBuilderService = inject(SearchQueryBuilderService);
const acaMobileAppSwitcherService = this.acaMobileAppSwitcherService;
this.ready = new BehaviorSubject(this.authenticationService.isLoggedIn() || this.withCredentials);
this.ready$ = this.ready.asObservable();
@@ -33,7 +33,7 @@ const BYTES_TO_MB_CONVERSION_VALUE = 1048576;
providedIn: 'root'
})
export class AutoDownloadService {
private dialog = inject(MatDialog);
private readonly dialog = inject(MatDialog);
private shouldDownload(node: NodeEntry, threshold: number): boolean {
const fileSizeInBytes = node?.entry?.content?.sizeInBytes || 0;
@@ -22,7 +22,7 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { UserPreferencesService } from '@alfresco/adf-core';
import { AlfrescoApiService } from '@alfresco/adf-content-services';
import { Observable, from } from 'rxjs';
@@ -61,6 +61,9 @@ import { map } from 'rxjs/operators';
providedIn: 'root'
})
export class ContentApiService {
private readonly api = inject(AlfrescoApiService);
private readonly preferences = inject(UserPreferencesService);
@LazyApi((self: ContentApiService) => new NodesApi(self.api.getInstance()))
declare nodesApi: NodesApi;
@@ -91,11 +94,6 @@ export class ContentApiService {
@LazyApi((self: ContentApiService) => new VersionsApi(self.api.getInstance()))
declare versionsApi: VersionsApi;
constructor(
private readonly api: AlfrescoApiService,
private readonly preferences: UserPreferencesService
) {}
/**
* Moves a node to the trashcan.
*
@@ -22,16 +22,16 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { filter, startWith } from 'rxjs/operators';
import { Observable } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class NavigationHistoryService {
history: string[] = [];
private readonly router = inject(Router);
constructor(private router: Router) {}
history: string[] = [];
listenToRouteChanges(): Observable<NavigationEnd> {
return this.router.events.pipe(
@@ -39,7 +39,7 @@ export interface PermissionOptions {
export class NodePermissionService implements NodePermissions {
static readonly DEFAULT_OPERATION = 'OR';
private defaultOptions: PermissionOptions = {
private readonly defaultOptions: PermissionOptions = {
operation: NodePermissionService.DEFAULT_OPERATION,
target: null
};
@@ -22,7 +22,7 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/
import { Injectable, Type } from '@angular/core';
import { Injectable, Type, inject } from '@angular/core';
import { ExtensionService } from '@alfresco/adf-extensions';
import { ExtensionRoute } from '../models/types';
import { Router } from '@angular/router';
@@ -31,16 +31,14 @@ import { Router } from '@angular/router';
providedIn: 'root'
})
export class RouterExtensionService {
private readonly router = inject(Router);
protected readonly extensions = inject(ExtensionService);
defaults = {
layout: 'app.layout.main',
auth: ['app.auth', 'app.extensions.dataLoaderGuard']
};
constructor(
private readonly router: Router,
protected readonly extensions: ExtensionService
) {}
mapExtensionRoutes() {
const routesWithoutParent = [];
this.getApplicationRoutes().forEach((extensionRoute: ExtensionRoute) => {
@@ -30,13 +30,13 @@ import { PeopleApi, LazyApi } from '@alfresco/js-api';
@Injectable({ providedIn: 'root' })
export class UserProfileService {
private api = inject(AlfrescoApiService);
private groupService = inject(GroupService);
private readonly api = inject(AlfrescoApiService);
private readonly groupService = inject(GroupService);
@LazyApi((self: UserProfileService) => new PeopleApi(self.api.getInstance()))
declare private peopleApi: PeopleApi;
declare private readonly peopleApi: PeopleApi;
private userProfile = new BehaviorSubject<ProfileState>(null);
private readonly userProfile = new BehaviorSubject<ProfileState>(null);
userProfile$ = this.userProfile.asObservable();
/**
@@ -34,10 +34,10 @@ import { NotificationService } from '@alfresco/adf-core';
@Injectable()
export class RouterEffects {
private notificationService = inject(NotificationService);
private actions$ = inject(Actions);
private router = inject(Router);
private location = inject(Location);
private readonly notificationService = inject(NotificationService);
private readonly actions$ = inject(Actions);
private readonly router = inject(Router);
private readonly location = inject(Location);
navigateUrl$ = createEffect(
() =>