Migrate to @angular-eslint/prefer-inject and @typescript-eslint/prefer-readonly (#11665)

This commit is contained in:
Denys Vuika
2026-02-18 15:38:01 +00:00
committed by GitHub
parent f8fa996b04
commit 3f542d99ba
470 changed files with 2638 additions and 2247 deletions
+3
View File
@@ -13,6 +13,9 @@ const config: StorybookConfig = {
framework: {
name: getAbsolutePath('@storybook/angular'),
options: {}
},
core: {
disableTelemetry: true
}
};
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { Agent, AgentsApi } from '@alfresco/js-api';
import { BehaviorSubject, from, Observable, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
@@ -25,8 +25,10 @@ import { AlfrescoApiService } from '../../services';
providedIn: 'root'
})
export class AgentService {
private readonly apiService = inject(AlfrescoApiService);
private _agentsApi: AgentsApi;
private agents = new BehaviorSubject<Agent[]>([]);
private readonly agents = new BehaviorSubject<Agent[]>([]);
get agentsApi(): AgentsApi {
this._agentsApi = this._agentsApi ?? new AgentsApi(this.apiService.getInstance());
@@ -35,8 +37,6 @@ export class AgentService {
agents$ = this.agents.asObservable();
constructor(private apiService: AlfrescoApiService) {}
/**
* Gets all agents from cache. If cache is empty, fetches agents from backend.
*
@@ -16,16 +16,13 @@
*/
import { AdfHttpClient } from '@alfresco/adf-core/api';
import { StorageService, AppConfigService } from '@alfresco/adf-core';
import { AlfrescoApi, AlfrescoApiConfig } from '@alfresco/js-api';
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { AlfrescoApiService } from '../services/alfresco-api.service';
@Injectable()
export class AlfrescoApiNoAuthService extends AlfrescoApiService {
constructor(storage: StorageService, appConfig: AppConfigService, private readonly adfHttpClient: AdfHttpClient) {
super(appConfig, storage);
}
private readonly adfHttpClient = inject(AdfHttpClient);
override createInstance(config: AlfrescoApiConfig) {
return new AlfrescoApi(
@@ -16,7 +16,7 @@
*/
import { AlfrescoApiConfig } from '@alfresco/js-api';
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { AppConfigService, AppConfigValues, StorageService } from '@alfresco/adf-core';
import { AlfrescoApiService } from '../services/alfresco-api.service';
import { SecurityOptionsLoaderService } from '../security-options-loader/security-options-loader.service';
@@ -35,12 +35,10 @@ export function createAlfrescoApiInstance(angularAlfrescoApiService: AlfrescoApi
providedIn: 'root'
})
export class AlfrescoApiLoaderService {
constructor(
private readonly appConfig: AppConfigService,
private readonly apiService: AlfrescoApiService,
private readonly securityOptionsLoaderService: SecurityOptionsLoaderService,
private storageService: StorageService
) {}
private readonly appConfig = inject(AppConfigService);
private readonly apiService = inject(AlfrescoApiService);
private readonly securityOptionsLoaderService = inject(SecurityOptionsLoaderService);
private readonly storageService = inject(StorageService);
async init(): Promise<any> {
await this.appConfig.load(this.securityOptionsLoaderService.load);
@@ -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, MatDialogRef } from '@angular/material/dialog';
import { AspectListDialogComponentData } from './aspect-list-dialog-data.interface';
import { TranslatePipe } from '@ngx-translate/core';
@@ -32,6 +32,9 @@ import { CommonModule } from '@angular/common';
encapsulation: ViewEncapsulation.None
})
export class AspectListDialogComponent implements OnInit {
private readonly dialog = inject<MatDialogRef<AspectListDialogComponent>>(MatDialogRef);
data = inject<AspectListDialogComponentData>(MAT_DIALOG_DATA);
title: string;
description: string;
currentNodeId: string;
@@ -40,7 +43,9 @@ export class AspectListDialogComponent implements OnInit {
currentAspectSelection: string[] = [];
constructor(private dialog: MatDialogRef<AspectListDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: AspectListDialogComponentData) {
constructor() {
const data = this.data;
this.title = data.title;
this.description = data.description;
this.overTableMessage = data.overTableMessage;
@@ -37,6 +37,9 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
encapsulation: ViewEncapsulation.None
})
export class AspectListComponent implements OnInit {
private readonly aspectListService = inject(AspectListService);
private readonly nodeApiService = inject(NodesApiService);
/** Node Id of the node that we want to update */
@Input({ required: true })
nodeId: string = '';
@@ -67,8 +70,6 @@ export class AspectListComponent implements OnInit {
private standardAspectsLoaded = 0;
private hasMoreAspects = false;
constructor(private aspectListService: AspectListService, private nodeApiService: NodesApiService) {}
ngOnInit(): void {
let aspects$: Observable<AspectEntry[]>;
if (this.nodeId) {
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { AlfrescoApiService } from '../../services/alfresco-api.service';
import { AppConfigService } from '@alfresco/adf-core';
import { from, Observable, of, zip } from 'rxjs';
@@ -30,14 +30,15 @@ export const CustomAspectsWhere = `(not namespaceUri matches('http://www.alfresc
providedIn: 'root'
})
export class AspectListService {
private readonly alfrescoApiService = inject(AlfrescoApiService);
private readonly appConfigService = inject(AppConfigService);
private _aspectsApi: AspectsApi;
get aspectsApi(): AspectsApi {
this._aspectsApi = this._aspectsApi ?? new AspectsApi(this.alfrescoApiService.getInstance());
return this._aspectsApi;
}
constructor(private alfrescoApiService: AlfrescoApiService, private appConfigService: AppConfigService) {}
getAllAspects(standardOpts?: ListAspectsOpts, customOpts?: ListAspectsOpts): Observable<CustomAspectPaging> {
const visibleAspectList = this.getVisibleAspects();
const standardAspects$ = this.getAspects(visibleAspectList, standardOpts);
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Observable, Subject } from 'rxjs';
import { AspectListDialogComponentData } from '../aspect-list-dialog-data.interface';
@@ -28,12 +28,10 @@ import { CategoryService } from '../../category';
providedIn: 'root'
})
export class DialogAspectListService {
constructor(
private dialog: MatDialog,
private overlayContainer: OverlayContainer,
private tagService: TagService,
private categoryService: CategoryService
) {}
private readonly dialog = inject(MatDialog);
private readonly overlayContainer = inject(OverlayContainer);
private readonly tagService = inject(TagService);
private readonly categoryService = inject(CategoryService);
openAspectListDialog(nodeId?: string, selectorAutoFocusedOnClose?: string): Observable<string[]> {
const select = new Subject<string[]>();
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { DialogAspectListService } from './dialog-aspect-list.service';
import { CardViewContentUpdateService } from '../../common/services/card-view-content-update.service';
import { NodesApiService } from '../../common/services/nodes-api.service';
@@ -25,12 +25,10 @@ import { TagService } from '../../tag/services/tag.service';
providedIn: 'root'
})
export class NodeAspectService {
constructor(
private nodesApiService: NodesApiService,
private dialogAspectListService: DialogAspectListService,
private cardViewContentUpdateService: CardViewContentUpdateService,
private tagService: TagService
) {}
private readonly nodesApiService = inject(NodesApiService);
private readonly dialogAspectListService = inject(DialogAspectListService);
private readonly cardViewContentUpdateService = inject(CardViewContentUpdateService);
private readonly tagService = inject(TagService);
updateNodeAspects(nodeId: string, selectorAutoFocusedOnClose?: string) {
this.dialogAspectListService.openAspectListDialog(nodeId, selectorAutoFocusedOnClose).subscribe((aspectList) => {
@@ -15,13 +15,14 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { AuthenticationService, BasicAlfrescoAuthService } from '@alfresco/adf-core';
import { take } from 'rxjs/operators';
@Injectable()
export class ContentAuthLoaderService {
constructor(private readonly basicAlfrescoAuthService: BasicAlfrescoAuthService, private readonly authService: AuthenticationService) {}
private readonly basicAlfrescoAuthService = inject(BasicAlfrescoAuthService);
private readonly authService = inject(AuthenticationService);
init(): void {
this.authService.onLogin.pipe(take(1)).subscribe({
@@ -73,6 +73,8 @@ interface CategoryNameControlErrors {
encapsulation: ViewEncapsulation.None
})
export class CategoriesManagementComponent implements OnInit, OnDestroy {
private readonly categoryService = inject(CategoryService);
readonly nameErrorMessagesByErrors = new Map<keyof CategoryNameControlErrors, string>([
['duplicatedExistingCategory', 'ALREADY_EXISTS'],
['duplicatedCategory', 'DUPLICATED_CATEGORY'],
@@ -82,9 +84,9 @@ export class CategoriesManagementComponent implements OnInit, OnDestroy {
['endsWithDot', 'ENDS_WITH_DOT']
]);
private existingCategoryLoaded$ = new Subject<void>();
private cancelExistingCategoriesLoading$ = new Subject<void>();
private _categoryNameControl = new FormControl<string>(
private readonly existingCategoryLoaded$ = new Subject<void>();
private readonly cancelExistingCategoriesLoading$ = new Subject<void>();
private readonly _categoryNameControl = new FormControl<string>(
'',
[
this.validateIfNotAlreadyAdded.bind(this),
@@ -168,12 +170,10 @@ export class CategoriesManagementComponent implements OnInit, OnDestroy {
categoryNameControlVisibleChange = new EventEmitter<boolean>();
@ViewChild('categoryNameInput')
private categoryNameInputElement: ElementRef;
private readonly categoryNameInputElement: ElementRef;
private readonly destroyRef = inject(DestroyRef);
constructor(private categoryService: CategoryService) {}
ngOnInit() {
this.categoryNameControl.valueChanges
.pipe(
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { TreeNodeType, TreeResponse, TreeService } from '../../tree';
import { CategoryNode } from '../models/category-node.interface';
import { CategoryService } from './category.service';
@@ -24,9 +24,7 @@ import { map, mergeMap, toArray } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class CategoryTreeDatasourceService extends TreeService<CategoryNode> {
constructor(private categoryService: CategoryService) {
super();
}
private readonly categoryService = inject(CategoryService);
public getSubNodes(parentNodeId: string, skipCount?: number, maxItems?: number, name?: string): Observable<TreeResponse<CategoryNode>> {
return !name
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { AppConfigService, UserPreferencesService } from '@alfresco/adf-core';
import {
CategoriesApi,
@@ -32,6 +32,10 @@ import { from, Observable } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class CategoryService {
private readonly apiService = inject(AlfrescoApiService);
private readonly userPreferencesService = inject(UserPreferencesService);
private readonly appConfigService = inject(AppConfigService);
private _categoriesApi: CategoriesApi;
private _searchApi: SearchApi;
@@ -45,12 +49,6 @@ export class CategoryService {
return this._searchApi;
}
constructor(
private apiService: AlfrescoApiService,
private userPreferencesService: UserPreferencesService,
private appConfigService: AppConfigService
) {}
/**
* Get subcategories of a given parent category
*
@@ -17,17 +17,19 @@
import { UpdateNotification, CardViewBaseItemModel, CardViewUpdateService } from '@alfresco/adf-core';
import { Node } from '@alfresco/js-api';
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class CardViewContentUpdateService {
private readonly cardViewUpdateService = inject(CardViewUpdateService);
itemUpdated$ = new Subject<UpdateNotification>();
updatedAspect$ = new Subject<Node>();
constructor(private cardViewUpdateService: CardViewUpdateService) {
constructor() {
this.linkVariables();
}
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { ContentApi, Node, NodeEntry } from '@alfresco/js-api';
import { Subject } from 'rxjs';
import { AuthenticationService, ThumbnailService } from '@alfresco/adf-core';
@@ -34,6 +34,10 @@ export interface FolderCreatedEvent {
providedIn: 'root'
})
export class ContentService {
authService = inject(AuthenticationService);
apiService = inject(AlfrescoApiService);
private readonly thumbnailService = inject(ThumbnailService);
folderCreated = new Subject<FolderCreatedEvent>();
folderCreate = new Subject<Node>();
folderEdit = new Subject<Node>();
@@ -44,8 +48,6 @@ export class ContentService {
return this._contentApi;
}
constructor(public authService: AuthenticationService, public apiService: AlfrescoApiService, private thumbnailService?: ThumbnailService) {}
/**
* Gets a content URL for the given node.
*
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { from, Observable, throwError, Subject } from 'rxjs';
import { catchError, map, switchMap, filter, take } from 'rxjs/operators';
import { RepositoryInfo, SystemPropertiesRepresentation, DiscoveryApi, AboutApi, SystemPropertiesApi } from '@alfresco/js-api';
@@ -27,6 +27,9 @@ import { BpmProductVersionModel, AuthenticationService } from '@alfresco/adf-cor
providedIn: 'root'
})
export class DiscoveryApiService {
private readonly authenticationService = inject(AuthenticationService);
private readonly alfrescoApiService = inject(AlfrescoApiService);
private _discoveryApi: DiscoveryApi;
get discoveryApi(): DiscoveryApi {
this._discoveryApi = this._discoveryApi ?? new DiscoveryApi(this.alfrescoApiService.getInstance());
@@ -38,10 +41,7 @@ export class DiscoveryApiService {
*/
ecmProductInfo$ = new Subject<RepositoryInfo>();
constructor(
private readonly authenticationService: AuthenticationService,
private readonly alfrescoApiService: AlfrescoApiService
) {
constructor() {
this.authenticationService.onLogin.subscribe(() => {
this.alfrescoApiService.alfrescoApiInitialized
.pipe(
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { FavoritesApi, NodePaging, FavoritePaging } from '@alfresco/js-api';
import { Observable, from, of } from 'rxjs';
import { AlfrescoApiService } from '../../services/alfresco-api.service';
@@ -26,6 +26,9 @@ import { catchError } from 'rxjs/operators';
providedIn: 'root'
})
export class FavoritesApiService {
private readonly apiService = inject(AlfrescoApiService);
private readonly preferences = inject(UserPreferencesService);
private _favoritesApi: FavoritesApi;
get favoritesApi(): FavoritesApi {
this._favoritesApi = this._favoritesApi ?? new FavoritesApi(this.apiService.getInstance());
@@ -41,8 +44,6 @@ export class FavoritesApiService {
return { entry };
}
constructor(private apiService: AlfrescoApiService, private preferences: UserPreferencesService) {}
remapFavoritesData(data: FavoritePaging = {}): NodePaging {
const pagination = data?.list?.pagination || {};
const entries: any[] = this.remapFavoriteEntries(data?.list?.entries || []);
@@ -29,7 +29,7 @@ import {
JobIdBodyEntry,
NodeAssociationPaging
} from '@alfresco/js-api';
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { from, Observable, Subject, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { NodeMetadata } from '../models/node-metadata.model';
@@ -39,6 +39,9 @@ import { AlfrescoApiService } from '../../services/alfresco-api.service';
providedIn: 'root'
})
export class NodesApiService {
private readonly apiService = inject(AlfrescoApiService);
private readonly preferences = inject(UserPreferencesService);
/**
* Publish/subscribe to events related to node updates.
*/
@@ -56,11 +59,6 @@ export class NodesApiService {
return this._nodesApi;
}
constructor(
private readonly apiService: AlfrescoApiService,
private readonly preferences: UserPreferencesService
) {}
private getEntryFromEntity(entity: NodeEntry): Node {
return entity.entry;
}
@@ -20,7 +20,8 @@ import { RedirectAuthService } from '@alfresco/adf-core';
import { PeopleContentQueryRequestModel, PeopleContentService } from './people-content.service';
import { TestBed } from '@angular/core/testing';
import { PersonPaging } from '@alfresco/js-api';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { provideHttpClient } from '@angular/common/http';
import { provideHttpClientTesting } from '@angular/common/http/testing';
import { EMPTY, firstValueFrom, of } from 'rxjs';
import { AlfrescoApiService } from '../../services';
import { AlfrescoApiServiceMock } from '../../mock';
@@ -70,11 +71,12 @@ describe('PeopleContentService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [
PeopleContentService,
{ provide: AlfrescoApiService, useClass: AlfrescoApiServiceMock },
{ provide: RedirectAuthService, useValue: { onLogin: EMPTY, onTokenReceived: of() } }
{ provide: RedirectAuthService, useValue: { onLogin: EMPTY, onTokenReceived: of() } },
provideHttpClient(),
provideHttpClientTesting()
]
});
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { from, Observable, of } from 'rxjs';
import { AuthenticationService } from '@alfresco/adf-core';
import { map, tap } from 'rxjs/operators';
@@ -44,6 +44,9 @@ export interface PeopleContentQueryRequestModel {
providedIn: 'root'
})
export class PeopleContentService {
private readonly apiService = inject(AlfrescoApiService);
private readonly contentService = inject(ContentService);
private currentUser: EcmUserModel;
private _peopleApi: PeopleApi;
@@ -52,7 +55,9 @@ export class PeopleContentService {
return this._peopleApi;
}
constructor(private apiService: AlfrescoApiService, authenticationService: AuthenticationService, private contentService: ContentService) {
constructor() {
const authenticationService = inject(AuthenticationService);
authenticationService.onLogout.subscribe(() => {
this.resetLocalCurrentUser();
});
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { ContentApi, RenditionEntry, RenditionPaging, RenditionsApi, VersionsApi } from '@alfresco/js-api';
import { Track, TranslationService, ViewUtilService } from '@alfresco/adf-core';
import { AlfrescoApiService } from '../../services/alfresco-api.service';
@@ -24,6 +24,10 @@ import { AlfrescoApiService } from '../../services/alfresco-api.service';
providedIn: 'root'
})
export class RenditionService {
private readonly apiService = inject(AlfrescoApiService);
private readonly translateService = inject(TranslationService);
private readonly viewUtilsService = inject(ViewUtilService);
static TARGET = '_new';
/**
@@ -51,7 +55,7 @@ export class RenditionService {
/**
* Timeout used for setInterval.
*/
private TRY_TIMEOUT: number = 10000;
private readonly TRY_TIMEOUT: number = 10000;
_renditionsApi: RenditionsApi;
get renditionsApi(): RenditionsApi {
@@ -66,19 +70,13 @@ export class RenditionService {
}
_versionsApi: VersionsApi;
private DEFAULT_RENDITION: string = 'imgpreview';
private readonly DEFAULT_RENDITION: string = 'imgpreview';
get versionsApi(): VersionsApi {
this._versionsApi = this._versionsApi ?? new VersionsApi(this.apiService.getInstance());
return this._versionsApi;
}
constructor(
private readonly apiService: AlfrescoApiService,
private readonly translateService: TranslationService,
private readonly viewUtilsService: ViewUtilService
) {}
getRenditionUrl(nodeId: string, type: string, renditionExists: boolean): string {
return renditionExists && type !== RenditionService.ContentGroup.IMAGE
? this.contentApi.getRenditionUrl(nodeId, RenditionService.ContentGroup.PDF)
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { inject, Injectable } from '@angular/core';
import { SavedSearchStrategy } from '../interfaces/saved-searches-strategy.interface';
import { AuthenticationService } from '@alfresco/adf-core';
import { ReplaySubject, Observable, catchError, switchMap, take, tap, throwError, map } from 'rxjs';
@@ -32,16 +32,14 @@ export abstract class SavedSearchesBaseService implements SavedSearchStrategy {
protected readonly _savedSearches$ = new ReplaySubject<SavedSearch[]>(1);
readonly savedSearches$: Observable<SavedSearch[]> = this._savedSearches$.asObservable();
protected readonly apiService = inject(AlfrescoApiService);
protected readonly authService = inject(AuthenticationService);
get nodesApi(): NodesApi {
this._nodesApi = this._nodesApi ?? new NodesApi(this.apiService.getInstance());
return this._nodesApi;
}
protected constructor(
protected readonly apiService: AlfrescoApiService,
protected readonly authService: AuthenticationService
) {}
protected abstract fetchAllSavedSearches(): Observable<SavedSearch[]>;
protected abstract updateSavedSearches(searches: SavedSearch[]): Observable<NodeEntry>;
@@ -19,9 +19,7 @@ import { NodeEntry } from '@alfresco/js-api';
import { Injectable } from '@angular/core';
import { Observable, of, from, throwError } from 'rxjs';
import { catchError, concatMap, first, map } from 'rxjs/operators';
import { AlfrescoApiService } from '../../services';
import { SavedSearch } from '../interfaces/saved-search.interface';
import { AuthenticationService } from '@alfresco/adf-core';
import { SavedSearchesBaseService } from './saved-searches-base.service';
@Injectable({
@@ -32,10 +30,6 @@ export class SavedSearchesLegacyService extends SavedSearchesBaseService {
private currentUserLocalStorageKey: string;
private createFileAttempt = false;
constructor(apiService: AlfrescoApiService, authService: AuthenticationService) {
super(apiService, authService);
}
protected fetchAllSavedSearches(): Observable<SavedSearch[]> {
return this.getSavedSearchesNodeId().pipe(
concatMap(() =>
@@ -16,12 +16,10 @@
*/
import { NodeEntry, PreferencesApi, ContentFieldsQuery, PreferenceEntry } from '@alfresco/js-api';
import { inject, Injectable, InjectionToken } from '@angular/core';
import { Injectable, InjectionToken, inject } from '@angular/core';
import { Observable, of, from, throwError } from 'rxjs';
import { catchError, concatMap, first, map, switchMap, take, tap } from 'rxjs/operators';
import { AlfrescoApiService } from '../../services/alfresco-api.service';
import { SavedSearch } from '../interfaces/saved-search.interface';
import { AuthenticationService } from '@alfresco/adf-core';
import { SavedSearchesBaseService } from './saved-searches-base.service';
export interface SavedSearchesPreferencesApiService {
@@ -37,7 +35,7 @@ export const SAVED_SEARCHES_SERVICE_PREFERENCES = new InjectionToken<SavedSearch
export class SavedSearchesService extends SavedSearchesBaseService {
private savedSearchFileNodeId: string;
private _preferencesApi: SavedSearchesPreferencesApiService;
private preferencesService = inject(SAVED_SEARCHES_SERVICE_PREFERENCES, { optional: true });
private readonly preferencesService = inject(SAVED_SEARCHES_SERVICE_PREFERENCES, { optional: true });
get preferencesApi(): SavedSearchesPreferencesApiService {
if (this.preferencesService) {
@@ -49,10 +47,6 @@ export class SavedSearchesService extends SavedSearchesBaseService {
return this._preferencesApi;
}
constructor(apiService: AlfrescoApiService, authService: AuthenticationService) {
super(apiService, authService);
}
protected fetchAllSavedSearches(): Observable<SavedSearch[]> {
const savedSearchesMigrated = localStorage.getItem(this.getLocalStorageKey()) ?? '';
if (savedSearchesMigrated === 'true') {
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { from, Observable } from 'rxjs';
import {
Node,
@@ -37,14 +37,14 @@ import { AlfrescoApiService } from '../../services/alfresco-api.service';
providedIn: 'root'
})
export class SitesService {
private readonly apiService = inject(AlfrescoApiService);
private _sitesApi: SitesApi;
get sitesApi(): SitesApi {
this._sitesApi = this._sitesApi ?? new SitesApi(this.apiService.getInstance());
return this._sitesApi;
}
constructor(private apiService: AlfrescoApiService) {}
/**
* Create a site
*
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Component, Input, OnChanges, SimpleChanges, ViewEncapsulation } from '@angular/core';
import { Component, Input, OnChanges, SimpleChanges, ViewEncapsulation, inject } from '@angular/core';
import { Node } from '@alfresco/js-api';
import { NodeAspectService } from '../../../aspect-list/services/node-aspect.service';
import { ContentMetadataCustomPanel, PresetConfig } from '../../interfaces/content-metadata.interfaces';
@@ -38,6 +38,10 @@ import { IconModule } from '@alfresco/adf-core';
host: { class: 'adf-content-metadata-card' }
})
export class ContentMetadataCardComponent implements OnChanges {
private readonly contentService = inject(ContentService);
private readonly nodeAspectService = inject(NodeAspectService);
private readonly versionCompatibilityService = inject(VersionCompatibilityService);
/** (required) The node entity to fetch metadata about */
@Input({ required: true })
node: Node;
@@ -110,11 +114,7 @@ export class ContentMetadataCardComponent implements OnChanges {
editAspectSupported = false;
constructor(
private contentService: ContentService,
private nodeAspectService: NodeAspectService,
private versionCompatibilityService: VersionCompatibilityService
) {
constructor() {
this.editAspectSupported = this.versionCompatibilityService.isVersionSupported('7');
}
@@ -86,6 +86,16 @@ export type DefaultPanels = (typeof DefaultPanels)[keyof typeof DefaultPanels];
encapsulation: ViewEncapsulation.None
})
export class ContentMetadataComponent implements OnChanges, OnInit {
private readonly contentMetadataService = inject(ContentMetadataService);
private readonly cardViewContentUpdateService = inject(CardViewContentUpdateService);
private readonly nodesApiService = inject(NodesApiService);
private readonly translationService = inject(TranslationService);
private readonly appConfig = inject(AppConfigService);
private readonly tagService = inject(TagService);
private readonly categoryService = inject(CategoryService);
private readonly contentService = inject(ContentService);
private readonly notificationService = inject(NotificationService);
/** (required) The node entity to fetch metadata about */
@Input({ required: true })
node: Node;
@@ -146,10 +156,10 @@ export class ContentMetadataComponent implements OnChanges, OnInit {
private _assignedTags: string[] = [];
private assignedTagsEntries: TagEntry[] = [];
private _tagsCreatorMode = TagsCreatorMode.CREATE_AND_ASSIGN;
private readonly _tagsCreatorMode = TagsCreatorMode.CREATE_AND_ASSIGN;
private _tags: string[] = [];
private targetProperty: CardViewBaseItemModel;
private classifiableChangedSubject = new Subject<void>();
private readonly classifiableChangedSubject = new Subject<void>();
private _saving = false;
DefaultPanels = DefaultPanels;
@@ -174,17 +184,7 @@ export class ContentMetadataComponent implements OnChanges, OnInit {
private readonly destroyRef = inject(DestroyRef);
constructor(
private contentMetadataService: ContentMetadataService,
private cardViewContentUpdateService: CardViewContentUpdateService,
private nodesApiService: NodesApiService,
private translationService: TranslationService,
private appConfig: AppConfigService,
private tagService: TagService,
private categoryService: CategoryService,
private contentService: ContentService,
private notificationService: NotificationService
) {
constructor() {
this.copyToClipboardAction = this.appConfig.get<boolean>('content-metadata.copy-to-clipboard-action');
this.multiValueSeparator = this.appConfig.get<string>('content-metadata.multi-value-pipe-separator') || DEFAULT_SEPARATOR;
this.useChipsForMultiValueProperty = this.appConfig.get<boolean>('content-metadata.multi-value-chips');
@@ -15,15 +15,15 @@
* limitations under the License.
*/
import { inject, Injectable } from '@angular/core';
import { inject, Injectable, Injector, runInInjectionContext } from '@angular/core';
import { Node } from '@alfresco/js-api';
import { CardViewDateItemModel, CardViewItemMatchValidator, CardViewTextItemModel, FileSizePipe, TranslationService } from '@alfresco/adf-core';
import { CardViewDateItemModel, CardViewItemMatchValidator, CardViewTextItemModel, FileSizePipe } from '@alfresco/adf-core';
@Injectable({
providedIn: 'root'
})
export class BasicPropertiesService {
private translationService = inject(TranslationService);
private readonly injector = inject(Injector);
getProperties(node: Node) {
const sizeInBytes = node.content ? node.content.sizeInBytes : '';
@@ -63,7 +63,7 @@ export class BasicPropertiesService {
label: 'CORE.METADATA.BASIC.SIZE',
value: sizeInBytes,
key: 'content.sizeInBytes',
pipes: [{ pipe: new FileSizePipe(this.translationService) }],
pipes: [{ pipe: runInInjectionContext(this.injector, () => new FileSizePipe()) }],
editable: false
}),
new CardViewTextItemModel({
@@ -19,7 +19,7 @@ import { ContentMetadataConfig, OrganisedPropertyGroup, PropertyGroupContainer,
import { getGroup, getProperty } from './property-group-reader';
export class AspectOrientedConfigService implements ContentMetadataConfig {
constructor(private config: any) {}
constructor(private readonly config: any) {}
public isGroupAllowed(groupName: string): boolean {
if (this.isIncludeAllEnabled()) {
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { AppConfigService, LogService } from '@alfresco/adf-core';
import { AspectOrientedConfigService } from './aspect-oriented-config.service';
import { IndifferentConfigService } from './indifferent-config.service';
@@ -29,7 +29,8 @@ const DEFAULT_PRESET_NAME = 'default';
providedIn: 'root'
})
export class ContentMetadataConfigFactory {
constructor(private appConfigService: AppConfigService, private logService: LogService) {}
private readonly appConfigService = inject(AppConfigService);
private readonly logService = inject(LogService);
public get(presetName: string = 'default'): ContentMetadataConfig {
let presetConfig: PresetConfig;
@@ -25,7 +25,7 @@ import {
import { getProperty } from './property-group-reader';
export class LayoutOrientedConfigService implements ContentMetadataConfig {
constructor(private config: any) {}
constructor(private readonly config: any) {}
public isGroupAllowed(groupName: string): boolean {
if (this.isIncludeAllEnabled()) {
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { Node } from '@alfresco/js-api';
import { BasicPropertiesService } from './basic-properties.service';
import { Observable, of, iif, Subject } from 'rxjs';
@@ -30,15 +30,13 @@ import { ContentTypePropertiesService } from './content-type-property.service';
providedIn: 'root'
})
export class ContentMetadataService {
error = new Subject<{ statusCode: number; message: string }>();
private readonly basicPropertiesService = inject(BasicPropertiesService);
private readonly contentMetadataConfigFactory = inject(ContentMetadataConfigFactory);
private readonly propertyGroupTranslatorService = inject(PropertyGroupTranslatorService);
private readonly propertyDescriptorsService = inject(PropertyDescriptorsService);
private readonly contentTypePropertyService = inject(ContentTypePropertiesService);
constructor(
private basicPropertiesService: BasicPropertiesService,
private contentMetadataConfigFactory: ContentMetadataConfigFactory,
private propertyGroupTranslatorService: PropertyGroupTranslatorService,
private propertyDescriptorsService: PropertyDescriptorsService,
private contentTypePropertyService: ContentTypePropertiesService
) {}
error = new Subject<{ statusCode: number; message: string }>();
getBasicProperties(node: Node): Observable<CardViewItem[]> {
return of(this.basicPropertiesService.getProperties(node));
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { CardViewItem, CardViewSelectItemModel, CardViewSelectItemOption, CardViewTextItemModel } from '@alfresco/adf-core';
import { Observable, of, Subject, zip } from 'rxjs';
@@ -31,12 +31,10 @@ import { VersionCompatibilityService } from '../../version-compatibility/version
providedIn: 'root'
})
export class ContentTypePropertiesService {
constructor(
private contentTypeService: ContentTypeService,
private dialog: MatDialog,
private versionCompatibilityService: VersionCompatibilityService,
private propertyGroupTranslatorService: PropertyGroupTranslatorService
) {}
private readonly contentTypeService = inject(ContentTypeService);
private readonly dialog = inject(MatDialog);
private readonly versionCompatibilityService = inject(VersionCompatibilityService);
private readonly propertyGroupTranslatorService = inject(PropertyGroupTranslatorService);
getContentTypeCardItem(node: Node): Observable<CardViewItem[]> {
if (this.versionCompatibilityService.isVersionSupported('7')) {
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { AlfrescoApiService } from '../../services/alfresco-api.service';
import { Observable, defer, forkJoin } from 'rxjs';
import { PropertyGroup, PropertyGroupContainer } from '../interfaces/content-metadata.interfaces';
@@ -26,14 +26,14 @@ import { ClassesApi } from '@alfresco/js-api';
providedIn: 'root'
})
export class PropertyDescriptorsService {
private readonly alfrescoApiService = inject(AlfrescoApiService);
private _classesApi: ClassesApi;
get classesApi(): ClassesApi {
this._classesApi = this._classesApi ?? new ClassesApi(this.alfrescoApiService.getInstance());
return this._classesApi;
}
constructor(private alfrescoApiService: AlfrescoApiService) {}
load(groupNames: string[]): Observable<PropertyGroupContainer> {
const groupFetchStreams = groupNames
.map((groupName) => groupName.replace(':', '_'))
@@ -29,8 +29,7 @@ import {
CardViewSelectItemModel,
CardViewTextItemModel,
DecimalNumberPipe,
LogService,
UserPreferencesService
LogService
} from '@alfresco/adf-core';
import { CardViewGroup, OrganisedPropertyGroup, Property } from '../interfaces/content-metadata.interfaces';
import { of } from 'rxjs';
@@ -53,9 +52,8 @@ export const RECOGNISED_ECM_TYPES = [D_TEXT, D_MLTEXT, D_DATE, D_DATETIME, D_INT
providedIn: 'root'
})
export class PropertyGroupTranslatorService {
private userPreferenceService = inject(UserPreferencesService);
private appConfig = inject(AppConfigService);
private logService = inject(LogService);
private readonly appConfig = inject(AppConfigService);
private readonly logService = inject(LogService);
valueSeparator: string;
@@ -221,7 +219,7 @@ export class PropertyGroupTranslatorService {
private getDecimalNumberPipe(): DecimalNumberPipe {
let decimalNumberPipe: DecimalNumberPipe;
runInInjectionContext(this.injector, () => {
decimalNumberPipe = new DecimalNumberPipe(this.userPreferenceService, this.appConfig);
decimalNumberPipe = new DecimalNumberPipe();
});
return decimalNumberPipe;
}
@@ -16,7 +16,7 @@
*/
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { EventEmitter, Injectable, Output } from '@angular/core';
import { EventEmitter, Injectable, Output, inject } from '@angular/core';
import { ThumbnailService, TranslationService } from '@alfresco/adf-core';
import { Subject, Observable, throwError } from 'rxjs';
import { ShareDataRow } from '../document-list/data/share-data-row.model';
@@ -36,21 +36,19 @@ import { SitesService } from '../common/services/sites.service';
})
// eslint-disable-next-line @angular-eslint/directive-class-suffix
export class ContentNodeDialogService {
private readonly dialog = inject(MatDialog);
private readonly contentService = inject(ContentService);
private readonly documentListService = inject(DocumentListService);
private readonly siteService = inject(SitesService);
private readonly translation = inject(TranslationService);
private readonly thumbnailService = inject(ThumbnailService);
static nonDocumentSiteContent = ['blog', 'calendar', 'dataLists', 'discussions', 'links', 'wiki'];
/** Emitted when an error occurs. */
@Output()
error: EventEmitter<any> = new EventEmitter<any>();
constructor(
private dialog: MatDialog,
private contentService: ContentService,
private documentListService: DocumentListService,
private siteService: SitesService,
private translation: TranslationService,
private thumbnailService: ThumbnailService
) {}
/**
* Opens a file browser at a chosen folder location.
* shows files and folders in the dialog search result.
@@ -90,6 +90,14 @@ export const defaultValidation = () => true;
providers: [SearchQueryBuilderService]
})
export class ContentNodeSelectorPanelComponent implements OnInit {
private readonly customResourcesService = inject(CustomResourcesService);
private readonly queryBuilderService = inject(SearchQueryBuilderService);
private readonly userPreferencesService = inject(UserPreferencesService);
private readonly nodesApiService = inject(NodesApiService);
private readonly uploadService = inject(UploadService);
private readonly sitesService = inject(SitesService);
private readonly contentNodeSelectorPanelService = inject(ContentNodeSelectorPanelService);
// eslint-disable-next-line @typescript-eslint/naming-convention
DEFAULT_PAGINATION: Pagination = new Pagination({
maxItems: 25,
@@ -304,16 +312,6 @@ export class ContentNodeSelectorPanelComponent implements OnInit {
private readonly destroyRef = inject(DestroyRef);
constructor(
private customResourcesService: CustomResourcesService,
private queryBuilderService: SearchQueryBuilderService,
private userPreferencesService: UserPreferencesService,
private nodesApiService: NodesApiService,
private uploadService: UploadService,
private sitesService: SitesService,
private contentNodeSelectorPanelService: ContentNodeSelectorPanelService
) {}
set chosenNode(value: Node[]) {
this._chosenNode = value;
this.select.next(value);
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Component, DestroyRef, inject, Inject, OnInit, ViewEncapsulation } from '@angular/core';
import { Component, DestroyRef, inject, OnInit, ViewEncapsulation } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { EmptyListComponent, IconModule, NotificationService, ToolbarComponent, ToolbarTitleComponent, TranslationService } from '@alfresco/adf-core';
import { Node } from '@alfresco/js-api';
@@ -62,6 +62,14 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
encapsulation: ViewEncapsulation.None
})
export class ContentNodeSelectorComponent implements OnInit {
private readonly translation = inject(TranslationService);
private readonly contentService = inject(ContentService);
private readonly notificationService = inject(NotificationService);
private readonly uploadService = inject(UploadService);
private readonly dialog = inject<MatDialogRef<ContentNodeSelectorComponent>>(MatDialogRef);
private readonly overlayContainer = inject(OverlayContainer);
data = inject<ContentNodeSelectorComponentData>(MAT_DIALOG_DATA);
title: string;
action: NodeAction;
buttonActionName: string;
@@ -78,15 +86,9 @@ export class ContentNodeSelectorComponent implements OnInit {
private readonly destroyRef = inject(DestroyRef);
constructor(
private translation: TranslationService,
private contentService: ContentService,
private notificationService: NotificationService,
private uploadService: UploadService,
private dialog: MatDialogRef<ContentNodeSelectorComponent>,
private overlayContainer: OverlayContainer,
@Inject(MAT_DIALOG_DATA) public data: ContentNodeSelectorComponentData
) {
constructor() {
const data = this.data;
this.action = data.actionName ?? NodeAction.CHOOSE;
this.buttonActionName = `NODE_SELECTOR.${this.action}`;
this.title = data.title;
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation } from '@angular/core';
import { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation, inject } from '@angular/core';
import { InfiniteSelectScrollDirective, AuthenticationService } from '@alfresco/adf-core';
import { SitePaging, SiteEntry, Site } from '@alfresco/js-api';
import { MatSelectChange, MatSelectModule } from '@angular/material/select';
@@ -43,6 +43,11 @@ export type Relations = (typeof Relations)[keyof typeof Relations];
host: { class: 'adf-sites-dropdown' }
})
export class DropdownSitesComponent implements OnInit {
private readonly authService = inject(AuthenticationService);
private readonly sitesService = inject(SitesService);
private readonly liveAnnouncer = inject(LiveAnnouncer);
private readonly translateService = inject(TranslateService);
/** Hide the "My Files" option. */
@Input()
hideMyFiles: boolean = false;
@@ -95,13 +100,6 @@ export class DropdownSitesComponent implements OnInit {
return this.loading;
}
constructor(
private authService: AuthenticationService,
private sitesService: SitesService,
private liveAnnouncer: LiveAnnouncer,
private translateService: TranslateService
) {}
ngOnInit() {
if (!this.siteList) {
this.loadSiteList();
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Component, Inject, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import { Component, OnInit, ViewChild, ViewEncapsulation, inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialog, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { MatSlideToggleChange, MatSlideToggleModule } from '@angular/material/slide-toggle';
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
@@ -59,7 +59,14 @@ interface SharedDialogFormProps {
encapsulation: ViewEncapsulation.None
})
export class ShareDialogComponent implements OnInit {
private minDateValidator = (control: FormControl<Date>): any =>
private readonly sharedLinksApiService = inject(SharedLinksApiService);
private readonly dialogRef = inject<MatDialogRef<ShareDialogComponent>>(MatDialogRef);
private readonly dialog = inject(MatDialog);
private readonly contentService = inject(ContentService);
private readonly renditionService = inject(RenditionService);
data = inject<ContentNodeShareSettings>(MAT_DIALOG_DATA);
private readonly minDateValidator = (control: FormControl<Date>): any =>
isBefore(endOfDay(new Date(control.value)), this.minDate) ? { invalidDate: true } : null;
minDate = add(new Date(), { days: 1 });
@@ -77,14 +84,6 @@ export class ShareDialogComponent implements OnInit {
@ViewChild('slideToggleExpirationDate', { static: true })
slideToggleExpirationDate;
constructor(
private sharedLinksApiService: SharedLinksApiService,
private dialogRef: MatDialogRef<ShareDialogComponent>,
private dialog: MatDialog,
private contentService: ContentService,
private renditionService: RenditionService,
@Inject(MAT_DIALOG_DATA) public data: ContentNodeShareSettings
) {}
ngOnInit() {
if (this.data.node?.entry) {
@@ -29,6 +29,10 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
exportAs: 'adfShare'
})
export class NodeSharedDirective implements OnChanges {
private readonly dialog = inject(MatDialog);
private readonly zone = inject(NgZone);
private readonly alfrescoApiService = inject(AlfrescoApiService);
isFile: boolean = false;
isShared: boolean = false;
@@ -48,8 +52,6 @@ export class NodeSharedDirective implements OnChanges {
}
private readonly destroyRef = inject(DestroyRef);
constructor(private dialog: MatDialog, private zone: NgZone, private alfrescoApiService: AlfrescoApiService) {}
shareNode(nodeEntry: NodeEntry) {
if (nodeEntry?.entry?.isFile) {
// shared and favorite
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { NodePaging, SharedLinkBodyCreate, SharedLinkEntry, SharedlinksApi } from '@alfresco/js-api';
import { Observable, from, of, Subject } from 'rxjs';
import { UserPreferencesService } from '@alfresco/adf-core';
@@ -26,6 +26,9 @@ import { AlfrescoApiService } from '../../services/alfresco-api.service';
providedIn: 'root'
})
export class SharedLinksApiService {
private readonly apiService = inject(AlfrescoApiService);
private readonly preferences = inject(UserPreferencesService);
error = new Subject<{ statusCode: number; message: string }>();
private _sharedLinksApi: SharedlinksApi;
@@ -34,8 +37,6 @@ export class SharedLinksApiService {
return this._sharedLinksApi;
}
constructor(private apiService: AlfrescoApiService, private preferences: UserPreferencesService) {}
/**
* Gets shared links available to the current user.
*
@@ -16,7 +16,7 @@
*/
import { TypeEntry } from '@alfresco/js-api';
import { Component, Inject, OnInit, ViewEncapsulation } from '@angular/core';
import { Component, OnInit, ViewEncapsulation, inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { ContentTypeDialogComponentData } from './content-type-metadata.interface';
import { ContentTypeService } from './content-type.service';
@@ -34,6 +34,10 @@ import { MatButtonModule } from '@angular/material/button';
encapsulation: ViewEncapsulation.None
})
export class ContentTypeDialogComponent implements OnInit {
private readonly dialog = inject<MatDialogRef<ContentTypeDialogComponent>>(MatDialogRef);
data = inject<ContentTypeDialogComponentData>(MAT_DIALOG_DATA);
private readonly contentTypeService = inject(ContentTypeService);
title: string;
description: string;
nodeType: string;
@@ -44,11 +48,9 @@ export class ContentTypeDialogComponent implements OnInit {
propertyColumns: string[] = ['name', 'title', 'dataType'];
constructor(
private dialog: MatDialogRef<ContentTypeDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: ContentTypeDialogComponentData,
private contentTypeService: ContentTypeService
) {
constructor() {
const data = this.data;
this.title = data.title;
this.description = data.description;
this.confirmMessage = data.confirmMessage;
@@ -16,7 +16,7 @@
*/
import { TypeEntry, TypePaging, TypesApi } from '@alfresco/js-api';
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { AlfrescoApiService } from '../services/alfresco-api.service';
import { from, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@@ -25,14 +25,14 @@ import { map } from 'rxjs/operators';
providedIn: 'root'
})
export class ContentTypeService {
private readonly alfrescoApiService = inject(AlfrescoApiService);
private _typesApi: TypesApi;
get typesApi(): TypesApi {
this._typesApi = this._typesApi ?? new TypesApi(this.alfrescoApiService.getInstance());
return this._typesApi;
}
constructor(private alfrescoApiService: AlfrescoApiService) {}
getContentTypeByPrefix(prefixedType: string): Observable<TypeEntry> {
return from(this.typesApi.getType(prefixedType));
}
@@ -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, MatDialogRef } from '@angular/material/dialog';
import { Subject } from 'rxjs';
import { Category } from '@alfresco/js-api';
@@ -37,15 +37,13 @@ export interface CategorySelectorDialogOptions {
encapsulation: ViewEncapsulation.None
})
export class CategorySelectorDialogComponent implements OnInit {
private readonly dialog = inject<MatDialogRef<CategorySelectorDialogComponent, boolean>>(MatDialogRef);
private readonly options = inject<CategorySelectorDialogOptions>(MAT_DIALOG_DATA);
categories: Category[] = [];
categoriesManagementMode = CategoriesManagementMode.ASSIGN;
multiSelect = true;
constructor(
private dialog: MatDialogRef<CategorySelectorDialogComponent, boolean>,
@Inject(MAT_DIALOG_DATA) private options: CategorySelectorDialogOptions
) {}
ngOnInit() {
this.multiSelect = this.options.multiSelect ?? true;
}
@@ -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, MatDialogRef, MatDialogModule } from '@angular/material/dialog';
import { NodesApiService } from '../../common/services/nodes-api.service';
import { DownloadZipService } from './services/download-zip.service';
@@ -35,20 +35,17 @@ import { MatButtonModule } from '@angular/material/button';
encapsulation: ViewEncapsulation.None
})
export class DownloadZipDialogComponent implements OnInit {
private readonly dialogRef = inject<MatDialogRef<DownloadZipDialogComponent>>(MatDialogRef);
data = inject(MAT_DIALOG_DATA);
private readonly downloadZipService = inject(DownloadZipService);
private readonly nodeService = inject(NodesApiService);
private readonly contentService = inject(ContentService);
// flag for async threads
cancelled = false;
downloadId: string;
percentageDone = 0;
constructor(
private dialogRef: MatDialogRef<DownloadZipDialogComponent>,
@Inject(MAT_DIALOG_DATA)
public data: any,
private downloadZipService: DownloadZipService,
private nodeService: NodesApiService,
private contentService: ContentService
) {}
ngOnInit() {
if (this.data?.nodeIds?.length > 0) {
if (!this.cancelled) {
@@ -16,7 +16,7 @@
*/
import { DownloadEntry, DownloadBodyCreate, DownloadsApi } from '@alfresco/js-api';
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { Observable, from } from 'rxjs';
import { AlfrescoApiService } from '../../../services/alfresco-api.service';
@@ -24,14 +24,14 @@ import { AlfrescoApiService } from '../../../services/alfresco-api.service';
providedIn: 'root'
})
export class DownloadZipService {
private readonly apiService = inject(AlfrescoApiService);
private _downloadsApi: DownloadsApi;
get downloadsApi(): DownloadsApi {
this._downloadsApi = this._downloadsApi ?? new DownloadsApi(this.apiService.getInstance());
return this._downloadsApi;
}
constructor(private apiService: AlfrescoApiService) {}
/**
* Creates a new download.
*
@@ -16,7 +16,7 @@
*/
import { Observable } from 'rxjs';
import { Component, DestroyRef, EventEmitter, inject, Inject, OnInit, Optional, Output, ViewEncapsulation } from '@angular/core';
import { Component, DestroyRef, EventEmitter, inject, OnInit, Output, ViewEncapsulation } from '@angular/core';
import { ReactiveFormsModule, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { Node } from '@alfresco/js-api';
@@ -49,6 +49,12 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
host: { class: 'adf-folder-dialog' }
})
export class FolderDialogComponent implements OnInit {
private readonly formBuilder = inject(UntypedFormBuilder);
private readonly dialog = inject<MatDialogRef<FolderDialogComponent>>(MatDialogRef);
private readonly nodesApi = inject(NodesApiService);
private readonly translation = inject(TranslationService);
data = inject(MAT_DIALOG_DATA, { optional: true });
/**
* Emitted when the edit/create folder give error for example a folder with same name already exist
*/
@@ -94,17 +100,11 @@ export class FolderDialogComponent implements OnInit {
}
private readonly destroyRef = inject(DestroyRef);
private readonly notificationService = inject(NotificationService)
private readonly notificationService = inject(NotificationService);
constructor() {
const data = this.data;
constructor(
private formBuilder: UntypedFormBuilder,
private dialog: MatDialogRef<FolderDialogComponent>,
private nodesApi: NodesApiService,
private translation: TranslationService,
@Optional()
@Inject(MAT_DIALOG_DATA)
public data: any
) {
if (data) {
this.editTitle = data.editTitle || this.editTitle;
this.createTitle = data.createTitle || this.createTitle;
@@ -68,6 +68,12 @@ interface VisibilityOption {
host: { class: 'adf-library-dialog' }
})
export class LibraryDialogComponent implements OnInit {
private readonly alfrescoApiService = inject(AlfrescoApiService);
private readonly sitesService = inject(SitesService);
private readonly formBuilder = inject(UntypedFormBuilder);
private readonly dialog = inject<MatDialogRef<LibraryDialogComponent>>(MatDialogRef);
private readonly notificationService = inject(NotificationService);
/** Emitted when an error occurs. */
@Output()
error = new EventEmitter<any>();
@@ -103,14 +109,6 @@ export class LibraryDialogComponent implements OnInit {
private readonly destroyRef = inject(DestroyRef);
constructor(
private alfrescoApiService: AlfrescoApiService,
private sitesService: SitesService,
private formBuilder: UntypedFormBuilder,
private dialog: MatDialogRef<LibraryDialogComponent>,
private notificationService: NotificationService
) {}
ngOnInit() {
const validators = {
id: [Validators.required, Validators.maxLength(72), this.forbidSpecialCharacters],
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Component, Inject, OnInit, Optional, ViewEncapsulation } from '@angular/core';
import { Component, OnInit, ViewEncapsulation, inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { ReactiveFormsModule, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { differenceInSeconds } from 'date-fns';
@@ -46,6 +46,11 @@ import { AlfrescoApiService } from '../../services/alfresco-api.service';
encapsulation: ViewEncapsulation.None
})
export class NodeLockDialogComponent implements OnInit {
private readonly formBuilder = inject(UntypedFormBuilder);
dialog = inject<MatDialogRef<NodeLockDialogComponent>>(MatDialogRef);
private readonly alfrescoApi = inject(AlfrescoApiService);
data = inject(MAT_DIALOG_DATA, { optional: true });
form: UntypedFormGroup;
node: Node = null;
nodeName: string;
@@ -56,15 +61,6 @@ export class NodeLockDialogComponent implements OnInit {
return this._nodesApi;
}
constructor(
private formBuilder: UntypedFormBuilder,
public dialog: MatDialogRef<NodeLockDialogComponent>,
private alfrescoApi: AlfrescoApiService,
@Optional()
@Inject(MAT_DIALOG_DATA)
public data: any
) {}
ngOnInit() {
const { node } = this.data;
this.nodeName = node.name;
@@ -15,14 +15,14 @@
* limitations under the License.
*/
import { AfterContentInit, Directive, ElementRef } from '@angular/core';
import { AfterContentInit, Directive, ElementRef, inject } from '@angular/core';
@Directive({
standalone: true,
selector: '[adf-auto-focus]'
})
export class AutoFocusDirective implements AfterContentInit {
public constructor(private el: ElementRef) {}
private readonly el = inject(ElementRef);
public ngAfterContentInit() {
setTimeout(() => {
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Directive, HostListener, Input, OnChanges, Output, EventEmitter, SimpleChanges } from '@angular/core';
import { Directive, HostListener, Input, OnChanges, Output, EventEmitter, SimpleChanges, inject } from '@angular/core';
import { FavoriteBodyCreate, FavoritesApi } from '@alfresco/js-api';
import { AlfrescoApiService } from '../services/alfresco-api.service';
import { LibraryEntity } from '../interfaces/library-entity.interface';
@@ -27,6 +27,9 @@ import { NotificationService } from '@alfresco/adf-core';
exportAs: 'favoriteLibrary'
})
export class LibraryFavoriteDirective implements OnChanges {
private readonly alfrescoApiService = inject(AlfrescoApiService);
private readonly notificationService = inject(NotificationService);
@Input('adf-favorite-library')
library: LibraryEntity = null;
@@ -59,8 +62,6 @@ export class LibraryFavoriteDirective implements OnChanges {
}
}
constructor(private readonly alfrescoApiService: AlfrescoApiService, private readonly notificationService: NotificationService) {}
ngOnChanges(changes: SimpleChanges) {
if (!changes.library.currentValue) {
this.targetLibrary = null;
@@ -18,28 +18,39 @@
import { fakeAsync, TestBed, tick } from '@angular/core/testing';
import { LibraryMembershipDirective } from './library-membership.directive';
import { SimpleChange } from '@angular/core';
import { of, throwError, Subject } from 'rxjs';
import { of, throwError } from 'rxjs';
import { SitesService } from '../common/services/sites.service';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { provideHttpClient } from '@angular/common/http';
import { provideHttpClientTesting } from '@angular/common/http/testing';
import { AlfrescoApiService } from '../services/alfresco-api.service';
import { AlfrescoApiServiceMock } from '../mock/alfresco-api.service.mock';
import { VersionCompatibilityService } from '../version-compatibility/version-compatibility.service';
describe('LibraryMembershipDirective', () => {
let alfrescoApiService: AlfrescoApiService;
let directive: LibraryMembershipDirective;
let sitesService: SitesService;
let versionCompatibilityService: jasmine.SpyObj<VersionCompatibilityService>;
let addMembershipSpy: jasmine.Spy;
let getMembershipSpy: jasmine.Spy;
let deleteMembershipSpy: jasmine.Spy;
let mockSupportedVersion = false;
let testSiteEntry: any;
let requestedMembershipResponse: any;
let testSiteEntry: Partial<{ id: string; guid: string; title: string; visibility: string }>;
let requestedMembershipResponse: Partial<{ id: string; createdAt: string; site: typeof testSiteEntry }>;
beforeEach(() => {
versionCompatibilityService = jasmine.createSpyObj('VersionCompatibilityService', ['isVersionSupported']);
versionCompatibilityService.isVersionSupported.and.callFake(() => mockSupportedVersion);
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [SitesService, { provide: AlfrescoApiService, useClass: AlfrescoApiServiceMock }]
providers: [
LibraryMembershipDirective,
SitesService,
{ provide: AlfrescoApiService, useClass: AlfrescoApiServiceMock },
{ provide: VersionCompatibilityService, useValue: versionCompatibilityService },
provideHttpClient(),
provideHttpClientTesting()
]
});
testSiteEntry = {
@@ -55,18 +66,14 @@ describe('LibraryMembershipDirective', () => {
site: testSiteEntry
};
alfrescoApiService = TestBed.inject(AlfrescoApiService);
sitesService = TestBed.inject(SitesService);
directive = new LibraryMembershipDirective(alfrescoApiService, sitesService, {
ecmProductInfo$: new Subject(),
isVersionSupported: () => mockSupportedVersion
} as any);
directive = TestBed.inject(LibraryMembershipDirective);
});
describe('markMembershipRequest', () => {
beforeEach(() => {
getMembershipSpy = spyOn(directive.sitesApi, 'getSiteMembershipRequestForPerson').and.returnValue(
Promise.resolve({ entry: requestedMembershipResponse })
Promise.resolve({ entry: requestedMembershipResponse } as never)
);
});
@@ -109,10 +116,10 @@ describe('LibraryMembershipDirective', () => {
beforeEach(() => {
mockSupportedVersion = false;
getMembershipSpy = spyOn(directive.sitesApi, 'getSiteMembershipRequestForPerson').and.returnValue(
Promise.resolve({ entry: requestedMembershipResponse })
Promise.resolve({ entry: requestedMembershipResponse } as never)
);
addMembershipSpy = spyOn(directive.sitesApi, 'createSiteMembershipRequestForPerson').and.returnValue(
Promise.resolve({ entry: requestedMembershipResponse })
Promise.resolve({ entry: requestedMembershipResponse } as never)
);
deleteMembershipSpy = spyOn(directive.sitesApi, 'deleteSiteMembershipRequestForPerson').and.returnValue(Promise.resolve());
});
@@ -162,7 +169,7 @@ describe('LibraryMembershipDirective', () => {
}));
it('should call API to add user to library if admin user', fakeAsync(() => {
const createSiteMembershipSpy = spyOn(sitesService, 'createSiteMembership').and.returnValue(of({} as any));
const createSiteMembershipSpy = spyOn(sitesService, 'createSiteMembership').and.returnValue(of({} as never));
const selection = { entry: { id: 'no-membership-requested' } };
const selectionChange = new SimpleChange(null, selection, true);
directive.isAdmin = true;
@@ -176,7 +183,7 @@ describe('LibraryMembershipDirective', () => {
it('should emit error when the request to join a library fails', fakeAsync(() => {
spyOn(directive.error, 'emit');
addMembershipSpy.and.returnValue(throwError('err'));
addMembershipSpy.and.returnValue(throwError(() => 'err'));
const selection = { entry: { id: 'no-membership-requested' } };
const change = new SimpleChange(null, selection, true);
@@ -206,7 +213,7 @@ describe('LibraryMembershipDirective', () => {
];
testData.forEach((data) => {
addMembershipSpy.and.returnValue(throwError({ message: data.fixture }));
addMembershipSpy.and.returnValue(throwError(() => ({ message: data.fixture })));
emitErrorSpy.calls.reset();
directive.toggleMembershipRequest();
tick();
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Directive, EventEmitter, HostListener, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
import { Directive, EventEmitter, HostListener, Input, OnChanges, Output, SimpleChanges, inject } from '@angular/core';
import { SiteEntry, SiteMembershipRequestBodyCreate, SiteMembershipRequestEntry, SitesApi } from '@alfresco/js-api';
import { BehaviorSubject, from, Observable } from 'rxjs';
import { AlfrescoApiService } from '../services/alfresco-api.service';
@@ -30,6 +30,10 @@ import { SitesService } from '../common/services/sites.service';
exportAs: 'libraryMembership'
})
export class LibraryMembershipDirective implements OnChanges {
private readonly alfrescoApiService = inject(AlfrescoApiService);
private readonly sitesService = inject(SitesService);
private readonly versionCompatibilityService = inject(VersionCompatibilityService);
targetSite: any = null;
isJoinRequested: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
@@ -60,12 +64,6 @@ export class LibraryMembershipDirective implements OnChanges {
this.toggleMembershipRequest();
}
constructor(
private alfrescoApiService: AlfrescoApiService,
private sitesService: SitesService,
private versionCompatibilityService: VersionCompatibilityService
) {}
ngOnChanges(changes: SimpleChanges) {
if (!changes.selection.currentValue?.entry) {
this.targetSite = null;
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Directive, Input, Component, OnInit, OnChanges, ViewContainerRef } from '@angular/core';
import { Directive, Input, Component, OnInit, OnChanges, ViewContainerRef, inject } from '@angular/core';
import { TranslatePipe } from '@ngx-translate/core';
@Directive({
@@ -23,14 +23,14 @@ import { TranslatePipe } from '@ngx-translate/core';
selector: '[adf-node-counter]'
})
export class NodeCounterDirective implements OnInit, OnChanges {
private readonly viewContainerRef = inject(ViewContainerRef);
/** Number to display in the counter badge */
@Input('adf-node-counter')
counter: number;
componentRef: NodeCounterComponent;
constructor(private viewContainerRef: ViewContainerRef) {}
ngOnInit() {
this.componentRef = this.viewContainerRef.createComponent(NodeCounterComponent).instance;
this.componentRef.counter = this.counter;
@@ -47,7 +47,7 @@ export class NodeCounterDirective implements OnInit, OnChanges {
standalone: true,
imports: [TranslatePipe],
selector: 'adf-node-counter',
template: ` <div>{{ 'NODE_COUNTER.SELECTED_COUNT' | translate : { count: counter } }}</div> `
template: ` <div>{{ 'NODE_COUNTER.SELECTED_COUNT' | translate: { count: counter } }}</div> `
})
export class NodeCounterComponent {
counter: number;
@@ -17,7 +17,7 @@
/* eslint-disable @angular-eslint/no-input-rename */
import { Directive, ElementRef, EventEmitter, HostListener, Input, OnChanges, Output } from '@angular/core';
import { Directive, ElementRef, EventEmitter, HostListener, Input, OnChanges, Output, inject } from '@angular/core';
import { NodeEntry, Node, DeletedNodeEntry, DeletedNode, TrashcanApi, NodesApi } from '@alfresco/js-api';
import { Observable, forkJoin, from, of } from 'rxjs';
import { TranslationService } from '@alfresco/adf-core';
@@ -51,6 +51,10 @@ interface ProcessStatus {
selector: '[adf-delete]'
})
export class NodeDeleteDirective implements OnChanges {
private readonly alfrescoApiService = inject(AlfrescoApiService);
private readonly translation = inject(TranslationService);
private readonly elementRef = inject(ElementRef);
/** Array of nodes to delete. */
@Input('adf-delete')
selection: NodeEntry[] | DeletedNodeEntry[];
@@ -80,8 +84,6 @@ export class NodeDeleteDirective implements OnChanges {
this.process(this.selection);
}
constructor(private alfrescoApiService: AlfrescoApiService, private translation: TranslationService, private elementRef: ElementRef) {}
ngOnChanges() {
if (!this.selection || (this.selection && this.selection.length === 0)) {
this.setDisableAttribute(true);
@@ -20,7 +20,8 @@ import { By } from '@angular/platform-browser';
import { MatDialog, MatDialogModule } from '@angular/material/dialog';
import { Component, DebugElement, ViewChild } from '@angular/core';
import { NodeDownloadDirective } from './node-download.directive';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { provideHttpClient } from '@angular/common/http';
import { provideHttpClientTesting } from '@angular/common/http/testing';
import { ContentApi } from '@alfresco/js-api';
import { AlfrescoApiService } from '../services/alfresco-api.service';
import { AlfrescoApiServiceMock } from '../mock/alfresco-api.service.mock';
@@ -56,8 +57,8 @@ describe('NodeDownloadDirective', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule, MatDialogModule, TestComponent],
providers: [{ provide: AlfrescoApiService, useClass: AlfrescoApiServiceMock }]
imports: [MatDialogModule, TestComponent],
providers: [{ provide: AlfrescoApiService, useClass: AlfrescoApiServiceMock }, provideHttpClient(), provideHttpClientTesting()]
});
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Directive, Input, HostListener } from '@angular/core';
import { Directive, Input, HostListener, inject } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { DownloadService } from '@alfresco/adf-core';
import { DownloadZipDialogComponent } from '../dialogs/download-zip/download-zip.dialog';
@@ -31,6 +31,10 @@ import { AlfrescoApiService } from '../services/alfresco-api.service';
selector: '[adfNodeDownload]'
})
export class NodeDownloadDirective {
private readonly apiService = inject(AlfrescoApiService);
private readonly downloadService = inject(DownloadService);
private readonly dialog = inject(MatDialog);
private _contentApi: ContentApi;
get contentApi(): ContentApi {
this._contentApi = this._contentApi ?? new ContentApi(this.apiService.getInstance());
@@ -50,8 +54,6 @@ export class NodeDownloadDirective {
this.downloadNodes(this.nodes);
}
constructor(private apiService: AlfrescoApiService, private downloadService: DownloadService, private dialog: MatDialog) {}
/**
* Downloads multiple selected nodes.
* Packs result into a .ZIP archive if there is more than one node selected.
@@ -19,22 +19,19 @@ import { SimpleChange } from '@angular/core';
import { fakeAsync, TestBed, tick } from '@angular/core/testing';
import { NodeFavoriteDirective } from './node-favorite.directive';
import { AppConfigService, AppConfigServiceMock, NotificationService } from '@alfresco/adf-core';
import { AlfrescoApiService } from '../services';
import { provideApiTesting } from '../testing/providers';
describe('NodeFavoriteDirective', () => {
let directive: NodeFavoriteDirective;
let alfrescoApiService: AlfrescoApiService;
let notificationService: NotificationService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [],
providers: [provideApiTesting(), { provide: AppConfigService, useClass: AppConfigServiceMock }]
providers: [NodeFavoriteDirective, provideApiTesting(), { provide: AppConfigService, useClass: AppConfigServiceMock }]
});
alfrescoApiService = TestBed.inject(AlfrescoApiService);
notificationService = TestBed.inject(NotificationService);
directive = new NodeFavoriteDirective(alfrescoApiService, notificationService);
directive = TestBed.inject(NodeFavoriteDirective);
});
describe('selection input change event', () => {
@@ -17,7 +17,7 @@
/* eslint-disable @angular-eslint/no-input-rename */
import { Directive, EventEmitter, HostListener, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
import { Directive, EventEmitter, HostListener, Input, OnChanges, Output, SimpleChanges, inject } from '@angular/core';
import { FavoriteBodyCreate, NodeEntry, SharedLinkEntry, Node, SharedLink, FavoritesApi } from '@alfresco/js-api';
import { Observable, from, forkJoin, of } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
@@ -30,6 +30,9 @@ import { NotificationService } from '@alfresco/adf-core';
exportAs: 'adfFavorite'
})
export class NodeFavoriteDirective implements OnChanges {
private readonly alfrescoApiService = inject(AlfrescoApiService);
private readonly notificationService = inject(NotificationService);
favorites: any[] = [];
private _favoritesApi: FavoritesApi;
@@ -53,8 +56,6 @@ export class NodeFavoriteDirective implements OnChanges {
this.toggleFavorite();
}
constructor(private readonly alfrescoApiService: AlfrescoApiService, private readonly notificationService: NotificationService) {}
ngOnChanges(changes: SimpleChanges) {
if (!changes.selection.currentValue.length) {
this.favorites = [];
@@ -17,7 +17,7 @@
/* eslint-disable @angular-eslint/no-input-rename */
import { Directive, ElementRef, Renderer2, HostListener, Input, AfterViewInit } from '@angular/core';
import { Directive, ElementRef, Renderer2, HostListener, Input, AfterViewInit, inject } from '@angular/core';
import { Node } from '@alfresco/js-api';
import { ContentService } from '../common/services/content.service';
import { AllowableOperationsEnum } from '../common/models/allowable-operations.enum';
@@ -28,6 +28,11 @@ import { ContentNodeDialogService } from '../content-node-selector/content-node-
selector: '[adf-node-lock]'
})
export class NodeLockDirective implements AfterViewInit {
element = inject(ElementRef);
private readonly renderer = inject(Renderer2);
private readonly contentService = inject(ContentService);
private readonly contentNodeDialogService = inject(ContentNodeDialogService);
/** Node to lock/unlock. */
@Input('adf-node-lock')
node: Node;
@@ -38,13 +43,6 @@ export class NodeLockDirective implements AfterViewInit {
this.contentNodeDialogService.openLockNodeDialog(this.node);
}
constructor(
public element: ElementRef,
private renderer: Renderer2,
private contentService: ContentService,
private contentNodeDialogService: ContentNodeDialogService
) {}
ngAfterViewInit() {
const hasAllowableOperations = this.contentService.hasAllowableOperations(this.node, AllowableOperationsEnum.LOCK);
this.renderer.setProperty(this.element.nativeElement, 'disabled', !hasAllowableOperations);
@@ -17,7 +17,7 @@
/* eslint-disable @angular-eslint/component-selector, @angular-eslint/no-input-rename */
import { Directive, EventEmitter, HostListener, Input, Output } from '@angular/core';
import { Directive, EventEmitter, HostListener, Input, Output, inject } from '@angular/core';
import { TrashcanApi, DeletedNodeEntry, DeletedNodesPaging } from '@alfresco/js-api';
import { Observable, forkJoin, from, of } from 'rxjs';
import { tap, mergeMap, map, catchError } from 'rxjs/operators';
@@ -30,6 +30,9 @@ import { AlfrescoApiService } from '../services/alfresco-api.service';
selector: '[adf-restore]'
})
export class NodeRestoreDirective {
private readonly alfrescoApiService = inject(AlfrescoApiService);
private readonly translation = inject(TranslationService);
private readonly restoreProcessStatus;
private _trashcanApi: TrashcanApi;
@@ -51,7 +54,7 @@ export class NodeRestoreDirective {
this.recover(this.selection);
}
constructor(private alfrescoApiService: AlfrescoApiService, private translation: TranslationService) {
constructor() {
this.restoreProcessStatus = this.processStatus();
}
@@ -29,11 +29,19 @@ describe('ContentColumnList', () => {
TestBed.configureTestingModule({
imports: [NoopAuthModule]
});
documentList = TestBed.createComponent(DocumentListComponent).componentInstance as DocumentListComponent;
actionList = new ContentActionListComponent(documentList);
const docListFixture = TestBed.createComponent(DocumentListComponent);
documentList = docListFixture.componentInstance;
});
it('should register action', () => {
TestBed.resetTestingModule();
TestBed.configureTestingModule({
imports: [NoopAuthModule],
providers: [{ provide: DocumentListComponent, useValue: documentList }, ContentActionListComponent]
});
actionList = TestBed.inject(ContentActionListComponent);
spyOn(documentList.actions, 'push').and.callThrough();
const action = new ContentActionModel();
@@ -44,12 +52,24 @@ describe('ContentColumnList', () => {
});
it('should require document list instance to register action', () => {
actionList = new ContentActionListComponent(null);
TestBed.resetTestingModule();
TestBed.configureTestingModule({
imports: [NoopAuthModule],
providers: [{ provide: DocumentListComponent, useValue: null }, ContentActionListComponent]
});
actionList = TestBed.inject(ContentActionListComponent);
const action = new ContentActionModel();
expect(actionList.registerAction(action)).toBeFalsy();
});
it('should require action instance to register', () => {
TestBed.resetTestingModule();
TestBed.configureTestingModule({
imports: [NoopAuthModule],
providers: [{ provide: DocumentListComponent, useValue: documentList }, ContentActionListComponent]
});
actionList = TestBed.inject(ContentActionListComponent);
spyOn(documentList.actions, 'push').and.callThrough();
const result = actionList.registerAction(null);
@@ -17,7 +17,7 @@
/* eslint-disable @angular-eslint/component-selector */
import { Component } from '@angular/core';
import { Component, inject } from '@angular/core';
import { ContentActionModel } from './../../models/content-action.model';
import { DocumentListComponent } from './../document-list.component';
@@ -26,7 +26,7 @@ import { DocumentListComponent } from './../document-list.component';
template: ''
})
export class ContentActionListComponent {
constructor(private documentList: DocumentListComponent) {}
private readonly documentList = inject(DocumentListComponent);
/**
* Registers action handler within the parent document list component.
@@ -21,46 +21,55 @@ import { FileNode } from '../../../mock';
import { ContentActionModel } from './../../models/content-action.model';
import { DocumentActionsService } from './../../services/document-actions.service';
import { FolderActionsService } from './../../services/folder-actions.service';
import { NodeActionsService } from './../../services/node-actions.service';
import { DocumentListComponent } from './../document-list.component';
import { ContentActionListComponent } from './content-action-list.component';
import { ContentActionComponent } from './content-action.component';
import { ContentService } from '../../../common/services/content.service';
import { NoopAuthModule } from '@alfresco/adf-core';
describe('ContentAction', () => {
let documentList: DocumentListComponent;
let actionList: ContentActionListComponent;
let documentActions: DocumentActionsService;
let folderActions: FolderActionsService;
let contentService: ContentService;
let nodeActionsService: NodeActionsService;
let documentActionsService: DocumentActionsService;
let folderActionsService: FolderActionsService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [NoopAuthModule]
});
contentService = TestBed.inject(ContentService);
nodeActionsService = new NodeActionsService(null, null, null);
documentActions = new DocumentActionsService(nodeActionsService, null, null, null);
folderActions = new FolderActionsService(nodeActionsService, null, contentService, null);
documentList = TestBed.createComponent(DocumentListComponent).componentInstance as DocumentListComponent;
actionList = new ContentActionListComponent(documentList);
const docListFixture = TestBed.createComponent(DocumentListComponent);
documentList = docListFixture.componentInstance;
TestBed.resetTestingModule();
TestBed.configureTestingModule({
imports: [NoopAuthModule],
providers: [
{ provide: DocumentListComponent, useValue: documentList },
ContentActionListComponent,
DocumentActionsService,
FolderActionsService
]
});
actionList = TestBed.inject(ContentActionListComponent);
documentActionsService = TestBed.inject(DocumentActionsService);
folderActionsService = TestBed.inject(FolderActionsService);
});
afterEach(() => {
documentList.actions = [];
});
it('should register within parent actions list', () => {
spyOn(actionList, 'registerAction').and.stub();
const action = new ContentActionComponent(actionList, null, null);
const action = TestBed.createComponent(ContentActionComponent).componentInstance as ContentActionComponent;
action.ngOnInit();
expect(actionList.registerAction).toHaveBeenCalled();
});
it('should setup and register model', () => {
const action = new ContentActionComponent(actionList, null, null);
const action = TestBed.createComponent(ContentActionComponent).componentInstance as ContentActionComponent;
action.target = 'document';
action.title = '<title>';
action.icon = '<icon>';
@@ -77,7 +86,7 @@ describe('ContentAction', () => {
});
it('should update visibility binding', () => {
const action = new ContentActionComponent(actionList, null, null);
const action = TestBed.createComponent(ContentActionComponent).componentInstance as ContentActionComponent;
action.target = 'document';
action.title = '<title>';
action.icon = '<icon>';
@@ -96,14 +105,15 @@ describe('ContentAction', () => {
it('should get action handler from document actions service', () => {
const handler = () => {};
spyOn(documentActions, 'getHandler').and.returnValue(handler);
spyOn(documentActionsService, 'getHandler').and.returnValue(handler);
const action = TestBed.createComponent(ContentActionComponent).componentInstance as ContentActionComponent;
const action = new ContentActionComponent(actionList, documentActions, null);
action.target = 'document';
action.handler = '<handler>';
action.ngOnInit();
expect(documentActions.getHandler).toHaveBeenCalledWith(action.handler);
expect(documentActionsService.getHandler).toHaveBeenCalledWith(action.handler);
expect(documentList.actions.length).toBe(1);
const model = documentList.actions[0];
@@ -112,14 +122,15 @@ describe('ContentAction', () => {
it('should get action handler from folder actions service', () => {
const handler = () => {};
spyOn(folderActions, 'getHandler').and.returnValue(handler);
spyOn(folderActionsService, 'getHandler').and.returnValue(handler);
const action = TestBed.createComponent(ContentActionComponent).componentInstance as ContentActionComponent;
const action = new ContentActionComponent(actionList, null, folderActions);
action.target = 'folder';
action.handler = '<handler>';
action.ngOnInit();
expect(folderActions.getHandler).toHaveBeenCalledWith(action.handler);
expect(folderActionsService.getHandler).toHaveBeenCalledWith(action.handler);
expect(documentList.actions.length).toBe(1);
const model = documentList.actions[0];
@@ -127,69 +138,75 @@ describe('ContentAction', () => {
});
it('should create document and folder action when there is no target', () => {
spyOn(folderActions, 'getHandler').and.stub();
spyOn(documentActions, 'getHandler').and.stub();
spyOn(folderActionsService, 'getHandler').and.stub();
spyOn(documentActionsService, 'getHandler').and.stub();
const action = TestBed.createComponent(ContentActionComponent).componentInstance as ContentActionComponent;
const action = new ContentActionComponent(actionList, documentActions, folderActions);
action.handler = '<handler>';
action.ngOnInit();
expect(documentList.actions.length).toBe(2);
expect(folderActions.getHandler).toHaveBeenCalled();
expect(documentActions.getHandler).toHaveBeenCalled();
expect(folderActionsService.getHandler).toHaveBeenCalled();
expect(documentActionsService.getHandler).toHaveBeenCalled();
});
it('should create document action when target is document', () => {
spyOn(folderActions, 'getHandler').and.stub();
spyOn(documentActions, 'getHandler').and.stub();
spyOn(folderActionsService, 'getHandler').and.stub();
spyOn(documentActionsService, 'getHandler').and.stub();
const action = TestBed.createComponent(ContentActionComponent).componentInstance as ContentActionComponent;
const action = new ContentActionComponent(actionList, documentActions, folderActions);
action.handler = '<handler>';
action.target = 'document';
action.ngOnInit();
expect(documentList.actions.length).toBe(1);
expect(folderActions.getHandler).not.toHaveBeenCalled();
expect(documentActions.getHandler).toHaveBeenCalled();
expect(folderActionsService.getHandler).not.toHaveBeenCalled();
expect(documentActionsService.getHandler).toHaveBeenCalled();
});
it('should create folder action when target is folder', () => {
spyOn(folderActions, 'getHandler').and.stub();
spyOn(documentActions, 'getHandler').and.stub();
spyOn(folderActionsService, 'getHandler').and.stub();
spyOn(documentActionsService, 'getHandler').and.stub();
const action = TestBed.createComponent(ContentActionComponent).componentInstance as ContentActionComponent;
const action = new ContentActionComponent(actionList, documentActions, folderActions);
action.handler = '<handler>';
action.target = 'folder';
action.ngOnInit();
expect(documentList.actions.length).toBe(1);
expect(folderActions.getHandler).toHaveBeenCalled();
expect(documentActions.getHandler).not.toHaveBeenCalled();
expect(folderActionsService.getHandler).toHaveBeenCalled();
expect(documentActionsService.getHandler).not.toHaveBeenCalled();
});
it('should be case insensitive for document target', () => {
spyOn(documentActions, 'getHandler').and.stub();
spyOn(documentActionsService, 'getHandler').and.stub();
const action = TestBed.createComponent(ContentActionComponent).componentInstance as ContentActionComponent;
const action = new ContentActionComponent(actionList, documentActions, null);
action.target = 'DoCuMeNt';
action.handler = '<handler>';
action.ngOnInit();
expect(documentActions.getHandler).toHaveBeenCalledWith(action.handler);
expect(documentActionsService.getHandler).toHaveBeenCalledWith(action.handler);
});
it('should be case insensitive for folder target', () => {
spyOn(folderActions, 'getHandler').and.stub();
spyOn(folderActionsService, 'getHandler').and.stub();
const action = TestBed.createComponent(ContentActionComponent).componentInstance as ContentActionComponent;
const action = new ContentActionComponent(actionList, null, folderActions);
action.target = 'FoLdEr';
action.handler = '<handler>';
action.ngOnInit();
expect(folderActions.getHandler).toHaveBeenCalledWith(action.handler);
expect(folderActionsService.getHandler).toHaveBeenCalledWith(action.handler);
});
it('should use custom "execute" emitter', (done) => {
const action = TestBed.createComponent(ContentActionComponent).componentInstance as ContentActionComponent;
const emitter = new EventEmitter();
emitter.subscribe((e) => {
@@ -197,7 +214,6 @@ describe('ContentAction', () => {
done();
});
const action = new ContentActionComponent(actionList, null, null);
action.target = 'document';
action.execute = emitter;
@@ -209,42 +225,44 @@ describe('ContentAction', () => {
});
it('should not find document action handler with missing service', () => {
const action = new ContentActionComponent(actionList, null, null);
const action = TestBed.createComponent(ContentActionComponent).componentInstance as ContentActionComponent;
expect(action.getSystemHandler('document', 'name')).toBeNull();
});
it('should not find folder action handler with missing service', () => {
const action = new ContentActionComponent(actionList, null, null);
const action = TestBed.createComponent(ContentActionComponent).componentInstance as ContentActionComponent;
expect(action.getSystemHandler('folder', 'name')).toBeNull();
});
it('should find document action handler via service', () => {
const handler = () => {};
const action = new ContentActionComponent(actionList, documentActions, null);
spyOn(documentActions, 'getHandler').and.returnValue(handler);
spyOn(documentActionsService, 'getHandler').and.returnValue(handler);
const action = TestBed.createComponent(ContentActionComponent).componentInstance as ContentActionComponent;
expect(action.getSystemHandler('document', 'name')).toBe(handler);
});
it('should find folder action handler via service', () => {
const handler = () => {};
const action = new ContentActionComponent(actionList, null, folderActions);
spyOn(folderActions, 'getHandler').and.returnValue(handler);
spyOn(folderActionsService, 'getHandler').and.returnValue(handler);
const action = TestBed.createComponent(ContentActionComponent).componentInstance as ContentActionComponent;
expect(action.getSystemHandler('folder', 'name')).toBe(handler);
});
it('should not find actions for unknown target type', () => {
spyOn(folderActions, 'getHandler').and.stub();
spyOn(documentActions, 'getHandler').and.stub();
spyOn(folderActionsService, 'getHandler').and.stub();
spyOn(documentActionsService, 'getHandler').and.stub();
const action = new ContentActionComponent(actionList, documentActions, folderActions);
const action = TestBed.createComponent(ContentActionComponent).componentInstance as ContentActionComponent;
expect(action.getSystemHandler('unknown', 'name')).toBeNull();
expect(folderActions.getHandler).not.toHaveBeenCalled();
expect(documentActions.getHandler).not.toHaveBeenCalled();
expect(folderActionsService.getHandler).not.toHaveBeenCalled();
expect(documentActionsService.getHandler).not.toHaveBeenCalled();
});
it('should wire model with custom event handler', (done) => {
const action = new ContentActionComponent(actionList, documentActions, folderActions);
const action = TestBed.createComponent(ContentActionComponent).componentInstance as ContentActionComponent;
const file = new FileNode();
const handler = new EventEmitter();
@@ -260,9 +278,10 @@ describe('ContentAction', () => {
});
it('should allow registering model without handler', () => {
const action = new ContentActionComponent(actionList, documentActions, folderActions);
spyOn(actionList, 'registerAction').and.callThrough();
const action = TestBed.createComponent(ContentActionComponent).componentInstance as ContentActionComponent;
action.execute = null;
action.handler = null;
action.target = 'document';
@@ -272,7 +291,7 @@ describe('ContentAction', () => {
});
it('should register on init', () => {
const action = new ContentActionComponent(actionList, null, null);
const action = TestBed.createComponent(ContentActionComponent).componentInstance as ContentActionComponent;
spyOn(action, 'register').and.callThrough();
action.ngOnInit();
@@ -281,10 +300,15 @@ describe('ContentAction', () => {
it('should require action list to register action with', () => {
const fakeModel = new ContentActionModel();
let action = new ContentActionComponent(actionList, null, null);
let action = TestBed.createComponent(ContentActionComponent).componentInstance as ContentActionComponent;
expect(action.register(fakeModel)).toBeTruthy();
action = new ContentActionComponent(null, null, null);
TestBed.resetTestingModule();
TestBed.configureTestingModule({
imports: [NoopAuthModule],
providers: [{ provide: ContentActionListComponent, useValue: null }]
});
action = TestBed.createComponent(ContentActionComponent).componentInstance as ContentActionComponent;
expect(action.register(fakeModel)).toBeFalsy();
});
});
@@ -17,7 +17,7 @@
/* eslint-disable @angular-eslint/component-selector */
import { Component, EventEmitter, Input, OnInit, Output, OnChanges, SimpleChanges, OnDestroy } from '@angular/core';
import { Component, EventEmitter, Input, OnInit, Output, OnChanges, SimpleChanges, OnDestroy, inject } from '@angular/core';
import { ContentActionHandler } from '../../models/content-action.model';
import { DocumentActionsService } from '../../services/document-actions.service';
@@ -28,10 +28,13 @@ import { Subscription } from 'rxjs';
@Component({
selector: 'content-action',
template: '',
providers: [DocumentActionsService, FolderActionsService]
template: ''
})
export class ContentActionComponent implements OnInit, OnChanges, OnDestroy {
private readonly list = inject(ContentActionListComponent);
private readonly documentActions = inject(DocumentActionsService);
private readonly folderActions = inject(FolderActionsService);
/** The title of the action as shown in the menu. */
@Input()
title: string = 'Action';
@@ -91,12 +94,6 @@ export class ContentActionComponent implements OnInit, OnChanges, OnDestroy {
private subscriptions: Subscription[] = [];
constructor(
private list: ContentActionListComponent,
private documentActions: DocumentActionsService,
private folderActions: FolderActionsService
) {}
ngOnInit() {
if (this.target === ContentActionTarget.All) {
this.folderActionModel = this.generateAction(ContentActionTarget.Folder);
@@ -51,7 +51,6 @@ import {
mockNodePagingWithPreselectedNodes,
mockPreselectedNodes
} from '../../mock';
import { domSanitizerMock } from '../../testing/dom-sanitizer-mock';
import { ImageResolver } from '../data/image-resolver.model';
import { RowFilter } from '../data/row-filter.model';
import { ShareDataRow } from '../data/share-data-row.model';
@@ -1179,7 +1178,7 @@ describe('DocumentList', () => {
it('should display [empty folder] template ', () => {
fixture.detectChanges();
runInInjectionContext(injector, () => {
documentList.dataTable = new DataTableComponent(null, null, matIconRegistryMock, domSanitizerMock, null);
documentList.dataTable = TestBed.createComponent(DataTableComponent).componentInstance as DataTableComponent;
});
expect(documentList.dataTable).toBeDefined();
expect(fixture.debugElement.query(By.css('adf-empty-list'))).not.toBeNull();
@@ -1200,7 +1199,7 @@ describe('DocumentList', () => {
it('should empty folder NOT show the pagination', () => {
runInInjectionContext(injector, () => {
documentList.dataTable = new DataTableComponent(null, null, matIconRegistryMock, domSanitizerMock, null);
documentList.dataTable = TestBed.createComponent(DataTableComponent).componentInstance as DataTableComponent;
});
expect(documentList.isEmpty()).toBeTruthy();
@@ -112,6 +112,18 @@ const BYTES_TO_MB_CONVERSION_VALUE = 1048576;
host: { class: 'adf-document-list' }
})
export class DocumentListComponent extends DataTableSchema implements OnInit, OnChanges, AfterContentInit, PaginatedComponent {
private readonly documentListService = inject(DocumentListService);
private readonly elementRef = inject(ElementRef);
private readonly appConfig: AppConfigService;
private readonly userPreferencesService = inject(UserPreferencesService);
private readonly contentService = inject(ContentService);
private readonly thumbnailService = inject(ThumbnailService);
private readonly alfrescoApiService = inject(AlfrescoApiService);
private readonly nodeService = inject(NodesApiService);
private readonly dataTableService = inject(DataTableService);
private readonly lockService = inject(LockService);
private readonly dialog = inject(MatDialog);
static SINGLE_CLICK_NAVIGATION: string = 'click';
static DOUBLE_CLICK_NAVIGATION: string = 'dblclick';
@@ -448,7 +460,7 @@ export class DocumentListComponent extends DataTableSchema implements OnInit, On
// @deprecated 3.0.0
folderNode: Node;
private _pagination: PaginationModel = this.DEFAULT_PAGINATION;
private readonly _pagination: PaginationModel = this.DEFAULT_PAGINATION;
pagination: BehaviorSubject<PaginationModel> = new BehaviorSubject<PaginationModel>(this.DEFAULT_PAGINATION);
sortingSubject: BehaviorSubject<DataSorting[]> = new BehaviorSubject<DataSorting[]>(this.DEFAULT_SORTING);
@@ -463,20 +475,12 @@ export class DocumentListComponent extends DataTableSchema implements OnInit, On
return this._nodesApi;
}
constructor(
private documentListService: DocumentListService,
private elementRef: ElementRef,
private appConfig: AppConfigService,
private userPreferencesService: UserPreferencesService,
private contentService: ContentService,
private thumbnailService: ThumbnailService,
private alfrescoApiService: AlfrescoApiService,
private nodeService: NodesApiService,
private dataTableService: DataTableService,
private lockService: LockService,
private dialog: MatDialog
) {
super(appConfig, 'default', presetsDefaultModel);
constructor() {
const appConfig = inject(AppConfigService);
super('default', presetsDefaultModel);
this.appConfig = appConfig;
this.nodeService.nodeUpdated.pipe(takeUntilDestroyed()).subscribe((node) => {
this.dataTableService.rowUpdate.next({ id: node.id, obj: { entry: node } });
});
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Component, Inject } from '@angular/core';
import { Component, inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
import { NodeEntry } from '@alfresco/js-api';
import { CommonModule } from '@angular/common';
@@ -29,5 +29,5 @@ import { NodeDownloadDirective } from '../../../directives/node-download.directi
templateUrl: './file-auto-download.component.html'
})
export class FileAutoDownloadComponent {
constructor(@Inject(MAT_DIALOG_DATA) public node: NodeEntry) {}
node = inject<NodeEntry>(MAT_DIALOG_DATA);
}
@@ -17,7 +17,7 @@
import { Subject } from 'rxjs';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { DataTableComponent, DataSorting, PaginationModel } from '@alfresco/adf-core';
import { DataSorting, PaginationModel } from '@alfresco/adf-core';
import { SearchService } from '../../../search/services/search.service';
import { SimpleChange } from '@angular/core';
import { SearchHeaderQueryBuilderService } from './../../../search/services/search-header-query-builder.service';
@@ -38,7 +38,7 @@ describe('FilterHeaderComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [FilterHeaderComponent],
providers: [provideRouter([]), { provide: SearchService, useValue: searchMock }, DataTableComponent]
providers: [provideRouter([]), { provide: SearchService, useValue: searchMock }]
});
fixture = TestBed.createComponent(FilterHeaderComponent);
component = fixture.componentInstance;
@@ -55,6 +55,9 @@ import { NodeTooltipUtils } from '../../utils/node-tooltip.utils';
}
})
export class LibraryNameColumnComponent implements OnInit {
private readonly element = inject(ElementRef);
private readonly nodesApiService = inject(NodesApiService);
@Input({ required: true })
context: any;
@@ -64,11 +67,6 @@ export class LibraryNameColumnComponent implements OnInit {
private readonly destroyRef = inject(DestroyRef);
constructor(
private element: ElementRef,
private nodesApiService: NodesApiService
) {}
ngOnInit() {
this.updateValue();
@@ -35,6 +35,8 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
host: { class: 'adf-library-role-column adf-datatable-content-cell' }
})
export class LibraryRoleColumnComponent implements OnInit {
private readonly nodesApiService = inject(NodesApiService);
@Input({ required: true })
context: any;
@@ -58,8 +60,6 @@ export class LibraryRoleColumnComponent implements OnInit {
private readonly destroyRef = inject(DestroyRef);
constructor(private nodesApiService: NodesApiService) {}
ngOnInit() {
this.updateValue();
@@ -35,6 +35,8 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
host: { class: 'adf-library-status-column adf-datatable-content-cell' }
})
export class LibraryStatusColumnComponent implements OnInit {
private readonly nodesApiService = inject(NodesApiService);
@Input({ required: true })
context: any;
@@ -42,8 +44,6 @@ export class LibraryStatusColumnComponent implements OnInit {
private readonly destroyRef = inject(DestroyRef);
constructor(private nodesApiService: NodesApiService) {}
ngOnInit() {
this.updateValue();
@@ -52,6 +52,9 @@ import { NodeTooltipUtils } from '../../utils/node-tooltip.utils';
host: { class: 'adf-datatable-content-cell adf-datatable-link adf-name-column' }
})
export class NameColumnComponent implements OnInit {
private readonly element = inject(ElementRef);
private readonly nodesApiService = inject(NodesApiService);
@Input({ required: true })
// eslint-disable-next-line @typescript-eslint/no-explicit-any
context: any;
@@ -66,11 +69,6 @@ export class NameColumnComponent implements OnInit {
private readonly destroyRef = inject(DestroyRef);
constructor(
private element: ElementRef,
private nodesApiService: NodesApiService
) {}
ngOnInit() {
this.updateValue();
@@ -41,10 +41,10 @@ export class ShareDataRow implements DataRow {
constructor(
private obj: NodeEntry,
private contentService: ContentService,
private permissionsStyle: PermissionStyleModel[],
private thumbnailService?: ThumbnailService,
private allowDropFiles?: boolean
private readonly contentService: ContentService,
private readonly permissionsStyle: PermissionStyleModel[],
private readonly thumbnailService?: ThumbnailService,
private readonly allowDropFiles?: boolean
) {
if (!obj) {
throw new Error(ERR_OBJECT_NOT_FOUND);
@@ -53,8 +53,8 @@ export class ShareDataTableAdapter implements DataTableAdapter {
}
constructor(
private thumbnailService: ThumbnailService,
private contentService: ContentService,
private readonly thumbnailService: ThumbnailService,
private readonly contentService: ContentService,
schema: DataColumn[] = [],
sorting?: DataSorting,
sortingMode: string = 'client',
@@ -35,7 +35,7 @@ import {
ResultSetPaging,
SEARCH_LANGUAGE
} from '@alfresco/js-api';
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { Observable, from, of } from 'rxjs';
import { map } from 'rxjs/operators';
@@ -43,6 +43,8 @@ const CREATE_PERMISSION: string = 'create';
@Injectable({ providedIn: 'root' })
export class CustomResourcesService {
private readonly apiService = inject(AlfrescoApiService);
private _peopleApi: PeopleApi;
get peopleApi(): PeopleApi {
this._peopleApi = this._peopleApi ?? new PeopleApi(this.apiService.getInstance());
@@ -85,8 +87,6 @@ export class CustomResourcesService {
return this._nodesApi;
}
constructor(private apiService: AlfrescoApiService) {}
/**
* Gets files recently accessed by a user.
*
@@ -69,7 +69,12 @@ describe('DocumentActionsService', () => {
const file = new FileNode();
expect(service.canExecuteAction(file)).toBeTruthy();
service = new DocumentActionsService(null, null, null);
TestBed.resetTestingModule();
TestBed.configureTestingModule({
imports: [NoopAuthModule],
providers: [{ provide: DocumentListService, useValue: null }]
});
service = TestBed.inject(DocumentActionsService);
expect(service.canExecuteAction(file)).toBeFalsy();
});
@@ -17,7 +17,7 @@
import { TranslationService } from '@alfresco/adf-core';
import { ContentService } from '../../common/services/content.service';
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { NodeEntry } from '@alfresco/js-api';
import { Observable, Subject, throwError, of } from 'rxjs';
import { ContentActionHandler } from '../models/content-action.model';
@@ -30,19 +30,19 @@ import { ContentNodeDialogService } from '../../content-node-selector/content-no
providedIn: 'root'
})
export class DocumentActionsService {
private readonly nodeActionsService = inject(NodeActionsService);
private readonly contentNodeDialogService = inject(ContentNodeDialogService);
private readonly translation = inject(TranslationService);
private readonly documentListService = inject(DocumentListService);
private readonly contentService = inject(ContentService);
permissionEvent = new Subject<PermissionModel>();
error = new Subject<Error>();
success = new Subject<string>();
private handlers: { [id: string]: ContentActionHandler } = {};
constructor(
private nodeActionsService: NodeActionsService,
private contentNodeDialogService: ContentNodeDialogService,
private translation: TranslationService,
private documentListService?: DocumentListService,
private contentService?: ContentService
) {
constructor() {
this.setupActionHandlers();
}
@@ -32,9 +32,9 @@ const ROOT_ID = '-root-';
providedIn: 'root'
})
export class DocumentListService implements DocumentListLoader {
private nodesApiService = inject(NodesApiService);
private apiService = inject(AlfrescoApiService);
private customResourcesService = inject(CustomResourcesService);
private readonly nodesApiService = inject(NodesApiService);
private readonly apiService = inject(AlfrescoApiService);
private readonly customResourcesService = inject(CustomResourcesService);
private _nodesApi: NodesApi;
get nodes(): NodesApi {
@@ -42,8 +42,8 @@ export class DocumentListService implements DocumentListLoader {
return this._nodesApi;
}
private _reload = new Subject<void>();
private _resetSelection = new Subject<void>();
private readonly _reload = new Subject<void>();
private readonly _resetSelection = new Subject<void>();
/** Gets an observable that emits when the document list should be reloaded. */
reload$ = this._reload.asObservable();
@@ -17,7 +17,7 @@
import { TranslationService } from '@alfresco/adf-core';
import { ContentService } from '../../common/services/content.service';
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { NodeEntry } from '@alfresco/js-api';
import { Observable, Subject, throwError, of } from 'rxjs';
import { ContentActionHandler } from '../models/content-action.model';
@@ -29,18 +29,18 @@ import { NodeActionsService } from './node-actions.service';
providedIn: 'root'
})
export class FolderActionsService {
private readonly nodeActionsService = inject(NodeActionsService);
private readonly documentListService = inject(DocumentListService);
private readonly contentService = inject(ContentService);
private readonly translation = inject(TranslationService);
permissionEvent = new Subject<PermissionModel>();
error = new Subject<Error>();
success = new Subject<string>();
private handlers: { [id: string]: ContentActionHandler } = {};
constructor(
private nodeActionsService: NodeActionsService,
private documentListService: DocumentListService,
private contentService: ContentService,
private translation: TranslationService
) {
constructor() {
this.setupActionHandlers();
}
@@ -20,7 +20,8 @@ import { LockService } from './lock.service';
import { AuthenticationService, RedirectAuthService } from '@alfresco/adf-core';
import { Node } from '@alfresco/js-api';
import { addDays, subDays } from 'date-fns';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { provideHttpClient } from '@angular/common/http';
import { provideHttpClientTesting } from '@angular/common/http/testing';
import { EMPTY, of } from 'rxjs';
describe('LockService', () => {
@@ -33,8 +34,11 @@ describe('LockService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [{ provide: RedirectAuthService, useValue: { onLogin: EMPTY, onTokenReceived: of() } }]
providers: [
{ provide: RedirectAuthService, useValue: { onLogin: EMPTY, onTokenReceived: of() } },
provideHttpClient(),
provideHttpClientTesting()
]
});
service = TestBed.inject(LockService);
authenticationService = TestBed.inject(AuthenticationService);
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { Node } from '@alfresco/js-api';
import { AuthenticationService } from '@alfresco/adf-core';
import { isAfter } from 'date-fns';
@@ -24,7 +24,7 @@ import { isAfter } from 'date-fns';
providedIn: 'root'
})
export class LockService {
constructor(private authService: AuthenticationService) {}
private readonly authService = inject(AuthenticationService);
isLocked(node: Node): boolean {
let isLocked = false;
@@ -15,15 +15,13 @@
* limitations under the License.
*/
import { Injectable, Output, EventEmitter } from '@angular/core';
import { Injectable, Output, EventEmitter, inject, Injector, runInInjectionContext } from '@angular/core';
import { Node, NodeEntry } from '@alfresco/js-api';
import { Observable } from 'rxjs';
import { switchMap, map } from 'rxjs/operators';
import { DownloadService } from '@alfresco/adf-core';
import { MatDialog } from '@angular/material/dialog';
import { ContentService } from '../../common/services/content.service';
import { NodeDownloadDirective } from '../../directives/node-download.directive';
import { AlfrescoApiService } from '../../services/alfresco-api.service';
import { DocumentListService } from './document-list.service';
import { ContentNodeDialogService } from '../../content-node-selector/content-node-dialog.service';
@@ -34,21 +32,19 @@ import { NodeAction } from '../models/node-action.enum';
})
// eslint-disable-next-line @angular-eslint/directive-class-suffix
export class NodeActionsService {
private readonly contentDialogService = inject(ContentNodeDialogService);
dialogRef = inject(MatDialog);
content = inject(ContentService);
private readonly documentListService = inject(DocumentListService);
private readonly injector = inject(Injector);
@Output()
error = new EventEmitter<any>();
constructor(
private contentDialogService: ContentNodeDialogService,
public dialogRef: MatDialog,
public content: ContentService,
private documentListService?: DocumentListService,
private apiService?: AlfrescoApiService,
private dialog?: MatDialog,
private downloadService?: DownloadService
) {}
downloadNode(node: NodeEntry) {
new NodeDownloadDirective(this.apiService, this.downloadService, this.dialog).downloadNode(node);
runInInjectionContext(this.injector, () => {
new NodeDownloadDirective().downloadNode(node);
});
}
/**
@@ -17,7 +17,7 @@
/* eslint-disable @angular-eslint/no-input-rename */
import { Directive, ElementRef, HostListener, Input, Output, EventEmitter } from '@angular/core';
import { Directive, ElementRef, HostListener, Input, Output, EventEmitter, inject } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Node } from '@alfresco/js-api';
import { FolderDialogComponent } from '../dialogs/folder/folder.dialog';
@@ -29,6 +29,10 @@ const DIALOG_WIDTH: number = 400;
selector: '[adf-edit-folder]'
})
export class FolderEditDirective {
dialogRef = inject(MatDialog);
elementRef = inject(ElementRef);
content = inject(ContentService);
/** Folder node to edit. */
@Input('adf-edit-folder')
folder: Node;
@@ -53,8 +57,6 @@ export class FolderEditDirective {
}
}
constructor(public dialogRef: MatDialog, public elementRef: ElementRef, public content: ContentService) {}
private get dialogConfig() {
const { folder } = this;
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { ContentIncludeQuery, Group, GroupEntry, GroupsApi } from '@alfresco/js-api';
import { AlfrescoApiService } from '../../services/alfresco-api.service';
import { from, Observable } from 'rxjs';
@@ -25,14 +25,14 @@ import { map } from 'rxjs/operators';
providedIn: 'root'
})
export class GroupService {
private readonly alfrescoApiService = inject(AlfrescoApiService);
private _groupsApi: GroupsApi;
get groupsApi(): GroupsApi {
this._groupsApi = this._groupsApi ?? new GroupsApi(this.alfrescoApiService.getInstance());
return this._groupsApi;
}
constructor(private alfrescoApiService: AlfrescoApiService) {}
async listAllGroupMembershipsForPerson(personId: string, opts?: any, accumulator = []): Promise<GroupEntry[]> {
const groupsPaginated = await this.groupsApi.listGroupMembershipsForPerson(personId, opts);
accumulator = [...accumulator, ...groupsPaginated.list.entries];
@@ -22,8 +22,8 @@ import { take, tap } from 'rxjs/operators';
export abstract class InfiniteScrollDatasource<T> extends DataSource<T> {
protected readonly dataStream = new BehaviorSubject<T[]>([]);
private isLoading$ = new Subject<boolean>();
private subscription = new Subscription();
private readonly isLoading$ = new Subject<boolean>();
private readonly subscription = new Subscription();
private batchesFetched = 0;
private _itemsCount = 0;
private _firstItem: T;
@@ -26,7 +26,7 @@ import {
LegalHoldApi,
RequestQuery
} from '@alfresco/js-api';
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { Observable, from } from 'rxjs';
import { map } from 'rxjs/operators';
import { AlfrescoApiService } from '../../services/alfresco-api.service';
@@ -35,14 +35,14 @@ import { AlfrescoApiService } from '../../services/alfresco-api.service';
providedIn: 'root'
})
export class LegalHoldService {
private readonly apiService = inject(AlfrescoApiService);
private _legalHoldApi: LegalHoldApi;
get legalHoldApi(): LegalHoldApi {
this._legalHoldApi = this._legalHoldApi ?? new LegalHoldApi(this.apiService.getInstance());
return this._legalHoldApi;
}
constructor(private readonly apiService: AlfrescoApiService) {}
/**
* Gets the list of holds available in the file plan.
*
@@ -17,12 +17,12 @@
import { Injectable } from '@angular/core';
import { AlfrescoApiService } from '../services/alfresco-api.service';
import { AppConfigService, StorageService } from '@alfresco/adf-core';
@Injectable()
export class AlfrescoApiServiceMock extends AlfrescoApiService {
constructor(protected appConfig: AppConfigService, protected storageService: StorageService) {
super(appConfig, storageService);
constructor() {
super();
if (!this.alfrescoApi) {
this.initAlfrescoApi();
}
@@ -17,8 +17,6 @@
import { NodeEntry } from '@alfresco/js-api';
import { of, Observable, ReplaySubject } from 'rxjs';
import { AlfrescoApiService } from '../services';
import { AuthenticationService } from '@alfresco/adf-core';
import { SavedSearch, SavedSearchesBaseService } from '../common';
import { Injectable } from '@angular/core';
@@ -28,10 +26,6 @@ export class MockSavedSearchesService extends SavedSearchesBaseService {
public updateSpy = jasmine.createSpy('updateSavedSearches').and.returnValue(of({} as NodeEntry));
constructor(apiService: AlfrescoApiService, authService: AuthenticationService) {
super(apiService, authService);
}
protected fetchAllSavedSearches(): Observable<SavedSearch[]> {
return this.fetchSubject.asObservable();
}
@@ -16,7 +16,7 @@
*/
import { Node } from '@alfresco/js-api';
import { Component, EventEmitter, Inject, OnInit, Output, ViewEncapsulation } from '@angular/core';
import { Component, EventEmitter, OnInit, Output, ViewEncapsulation, inject } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
import { NewVersionUploaderDialogData, NewVersionUploaderData, NewVersionUploaderDataAction } from './models';
import { CommonModule } from '@angular/common';
@@ -45,6 +45,9 @@ import { VersionListComponent } from '../version-manager/version-list.component'
}
})
export class NewVersionUploaderDialogComponent implements OnInit {
data = inject<NewVersionUploaderDialogData>(MAT_DIALOG_DATA);
private readonly dialogRef = inject<MatDialogRef<NewVersionUploaderDialogComponent>>(MatDialogRef);
/**
* Dialog title to show into the header.
* If data.title is not provided, a default title is set
@@ -59,11 +62,6 @@ export class NewVersionUploaderDialogComponent implements OnInit {
@Output()
uploadError = new EventEmitter<any>();
constructor(
@Inject(MAT_DIALOG_DATA) public data: NewVersionUploaderDialogData,
private dialogRef: MatDialogRef<NewVersionUploaderDialogComponent>
) {}
ngOnInit(): void {
this.setDialogTitle();
}
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { MatDialog, MatDialogConfig } from '@angular/material/dialog';
import { AlfrescoApiService } from '../services/alfresco-api.service';
@@ -30,14 +30,16 @@ import { take } from 'rxjs/operators';
providedIn: 'root'
})
export class NewVersionUploaderService {
private readonly apiService = inject(AlfrescoApiService);
private readonly dialog = inject(MatDialog);
private readonly overlayContainer = inject(OverlayContainer);
private _versionsApi: VersionsApi;
get versionsApi(): VersionsApi {
this._versionsApi = this._versionsApi ?? new VersionsApi(this.apiService.getInstance());
return this._versionsApi;
}
constructor(private apiService: AlfrescoApiService, private dialog: MatDialog, private overlayContainer: OverlayContainer) {}
/**
* Open a dialog NewVersionUploaderDialogComponent to display:
* - a side by side comparison between the current target node (type, name, icon) and the new file that should update it's version
@@ -19,7 +19,8 @@ import { TestBed } from '@angular/core/testing';
import { CommentModel, RedirectAuthService } from '@alfresco/adf-core';
import { fakeContentComment, fakeContentComments } from '../mocks/node-comments.mock';
import { NodeCommentsService } from './node-comments.service';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { provideHttpClient } from '@angular/common/http';
import { provideHttpClientTesting } from '@angular/common/http/testing';
import { EMPTY, of } from 'rxjs';
import { AlfrescoApiService } from '../../services';
import { AlfrescoApiServiceMock } from '../../mock';
@@ -31,10 +32,11 @@ describe('NodeCommentsService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [
{ provide: AlfrescoApiService, useClass: AlfrescoApiServiceMock },
{ provide: RedirectAuthService, useValue: { onLogin: EMPTY, onTokenReceived: of() } }
{ provide: RedirectAuthService, useValue: { onLogin: EMPTY, onTokenReceived: of() } },
provideHttpClient(),
provideHttpClientTesting()
]
});
service = TestBed.inject(NodeCommentsService);
@@ -17,7 +17,7 @@
import { CommentModel, CommentsService, User } from '@alfresco/adf-core';
import { CommentEntry, CommentsApi, Comment, PeopleApi } from '@alfresco/js-api';
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { Observable, from } from 'rxjs';
import { map } from 'rxjs/operators';
import { AlfrescoApiService } from '../../services/alfresco-api.service';
@@ -26,6 +26,8 @@ import { AlfrescoApiService } from '../../services/alfresco-api.service';
providedIn: 'root'
})
export class NodeCommentsService implements CommentsService {
private readonly apiService = inject(AlfrescoApiService);
private _commentsApi: CommentsApi;
get commentsApi(): CommentsApi {
this._commentsApi = this._commentsApi ?? new CommentsApi(this.apiService.getInstance());
@@ -38,8 +40,6 @@ export class NodeCommentsService implements CommentsService {
return this._peopleApi;
}
constructor(private readonly apiService: AlfrescoApiService) {}
/**
* Gets all comments that have been added to a task.
*
@@ -15,7 +15,7 @@
* limitations under the License.
*/
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 { NodeEntry, PermissionElement } from '@alfresco/js-api';
import { AddPermissionDialogData } from './add-permission-dialog-data.interface';
@@ -51,16 +51,16 @@ import { UserRoleColumnComponent } from '../user-role-column/user-role-column.co
encapsulation: ViewEncapsulation.None
})
export class AddPermissionDialogComponent {
data = inject<AddPermissionDialogData>(MAT_DIALOG_DATA);
private readonly dialogRef = inject<MatDialogRef<AddPermissionDialogComponent>>(MatDialogRef);
isSearchActive = true;
selectedMembers: MemberModel[] = [];
private existingMembers: PermissionElement[] = [];
private readonly existingMembers: PermissionElement[] = [];
currentSelection: NodeEntry[] = [];
constructor(
@Inject(MAT_DIALOG_DATA) public data: AddPermissionDialogData,
private dialogRef: MatDialogRef<AddPermissionDialogComponent>
) {
constructor() {
this.existingMembers = this.data.node.permissions.locallySet || [];
}
@@ -16,7 +16,7 @@
*/
import { Node, NodeEntry, PermissionElement } from '@alfresco/js-api';
import { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation } from '@angular/core';
import { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation, inject } from '@angular/core';
import { NodePermissionService } from '../../services/node-permission.service';
import { RoleModel } from '../../models/role.model';
import { ContentService } from '../../../common/services/content.service';
@@ -37,6 +37,9 @@ import { TranslatePipe } from '@ngx-translate/core';
* @deprecated in 4.4.0, use adf-add-permission-panel instead.
*/
export class AddPermissionComponent implements OnInit {
private readonly nodePermissionService = inject(NodePermissionService);
private readonly contentService = inject(ContentService);
/** ID of the target node. */
@Input({ required: true })
nodeId: string;
@@ -53,8 +56,6 @@ export class AddPermissionComponent implements OnInit {
currentNode: Node;
currentNodeRoles: RoleModel[];
constructor(private nodePermissionService: NodePermissionService, private contentService: ContentService) {}
ngOnInit(): void {
this.nodePermissionService.getNodeWithRoles(this.nodeId).subscribe(({ node, roles }) => {
this.currentNode = node;
@@ -16,7 +16,7 @@
*/
import { SearchRequest } from '@alfresco/js-api';
import { Injectable, Optional, Inject, InjectionToken } from '@angular/core';
import { Injectable, InjectionToken, inject } from '@angular/core';
import { SearchConfigurationInterface } from '../../../common/interfaces/search-configuration.interface';
export const SEARCH_QUERY_TOKEN = new InjectionToken<QueryProvider>('Alfresco Search Query Token');
@@ -26,11 +26,7 @@ export interface QueryProvider {
@Injectable()
export class SearchPermissionConfigurationService implements SearchConfigurationInterface {
constructor(
@Optional()
@Inject(SEARCH_QUERY_TOKEN)
private queryProvider: QueryProvider
) {}
private readonly queryProvider = inject<QueryProvider>(SEARCH_QUERY_TOKEN, { optional: true });
public generateQueryBody(searchTerm: string, maxResults: number, skipCount: number): SearchRequest {
return {
@@ -16,7 +16,7 @@
*/
/* eslint-disable @angular-eslint/no-input-rename */
import { Directive, Input, Output, EventEmitter } from '@angular/core';
import { Directive, Input, Output, EventEmitter, inject } from '@angular/core';
import { Node } from '@alfresco/js-api';
import { ContentService } from '../../common/services/content.service';
import { NodesApiService } from '../../common/services/nodes-api.service';
@@ -30,6 +30,9 @@ import { AllowableOperationsEnum } from '../../common/models/allowable-operation
}
})
export class InheritPermissionDirective {
private readonly nodeService = inject(NodesApiService);
private readonly contentService = inject(ContentService);
/** ID of the node to add/remove inherited permissions. */
@Input()
nodeId: string;
@@ -42,8 +45,6 @@ export class InheritPermissionDirective {
@Output()
error: EventEmitter<any> = new EventEmitter<any>();
constructor(private nodeService: NodesApiService, private contentService: ContentService) {}
onInheritPermissionClicked() {
this.nodeService.getNode(this.nodeId).subscribe((node: Node) => {
if (this.contentService.hasAllowableOperations(node, AllowableOperationsEnum.UPDATEPERMISSIONS)) {
@@ -49,6 +49,9 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
encapsulation: ViewEncapsulation.None
})
export class PermissionListComponent implements OnInit {
readonly permissionList = inject(PermissionListService);
private readonly contentService = inject(ContentService);
/** ID of the node whose permissions you want to show. */
@Input({ required: true })
nodeId: string;
@@ -71,10 +74,7 @@ export class PermissionListComponent implements OnInit {
return this._updatePermissionsAllowed;
}
constructor(
public readonly permissionList: PermissionListService,
private readonly contentService: ContentService
) {
constructor() {
this.error = this.permissionList.errored;
this.update = this.permissionList.updated;
}
@@ -17,7 +17,7 @@
import { NotificationService } from '@alfresco/adf-core';
import { Node, PermissionElement } from '@alfresco/js-api';
import { EventEmitter, Injectable } from '@angular/core';
import { EventEmitter, Injectable, inject } from '@angular/core';
import { MatSlideToggleChange } from '@angular/material/slide-toggle';
import { BehaviorSubject, forkJoin, Observable, of, Subject } from 'rxjs';
import { finalize, map, switchMap } from 'rxjs/operators';
@@ -36,6 +36,12 @@ const SITE_MANAGER_ROLE = 'SiteManager';
providedIn: 'root'
})
export class PermissionListService {
private readonly nodeService = inject(NodesApiService);
private readonly nodePermissionService = inject(NodePermissionService);
private readonly nodePermissionDialogService = inject(NodePermissionDialogService);
private readonly contentService = inject(ContentService);
private readonly notificationService = inject(NotificationService);
updated = new EventEmitter<PermissionDisplayModel>();
errored = new EventEmitter<PermissionDisplayModel>();
@@ -58,14 +64,6 @@ export class PermissionListService {
private node: Node;
private roles: RoleModel[];
constructor(
private nodeService: NodesApiService,
private nodePermissionService: NodePermissionService,
private nodePermissionDialogService: NodePermissionDialogService,
private contentService: ContentService,
private notificationService: NotificationService
) {}
fetchPermission(nodeId: string) {
this.loading$.next(true);
this.nodePermissionService

Some files were not shown because too many files have changed in this diff Show More