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
@@ -14,6 +14,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 { Observable, from, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { AppConfigService } from '@alfresco/adf-core';
@@ -26,12 +26,12 @@ import { RequestOptions } from '@alfresco/js-api';
@Injectable({ providedIn: 'root' })
export class AppsProcessCloudService {
private readonly adfHttpClient = inject(AdfHttpClient);
private readonly appConfigService = inject(AppConfigService);
deployedApps: ApplicationInstanceModel[];
constructor(
private readonly adfHttpClient: AdfHttpClient,
private readonly appConfigService: AppConfigService
) {
constructor() {
this.loadApps();
}
@@ -21,13 +21,11 @@ import {
DestroyRef,
EventEmitter,
HostListener,
Inject,
inject,
InjectionToken,
Input,
OnChanges,
OnInit,
Optional,
Output,
SimpleChanges
} from '@angular/core';
@@ -190,7 +188,9 @@ export class FormCloudComponent extends FormBaseComponent implements OnChanges,
private readonly destroyRef = inject(DestroyRef);
constructor(@Optional() @Inject(FORM_CLOUD_FIELD_VALIDATORS_TOKEN) injectedFieldValidators?: FormFieldValidator[]) {
constructor() {
const injectedFieldValidators = inject(FORM_CLOUD_FIELD_VALIDATORS_TOKEN, { optional: true });
super();
this.loadInjectedFieldValidators(injectedFieldValidators);
this.spinnerService.initSpinnerHandling(this.destroyRef);
@@ -58,11 +58,11 @@ const VALID_ALIAS = [ALIAS_ROOT_FOLDER, ALIAS_USER_FOLDER, '-shared-'];
encapsulation: ViewEncapsulation.None
})
export class AttachFileCloudWidgetComponent extends UploadCloudWidgetComponent implements OnInit, OnDestroy {
private contentNodeSelectorService = inject(ContentCloudNodeSelectorService);
private appConfigService = inject(AppConfigService);
private apiService = inject(AlfrescoApiService);
private contentNodeSelectorPanelService = inject(ContentNodeSelectorPanelService);
private newVersionUploaderService = inject(NewVersionUploaderService);
private readonly contentNodeSelectorService = inject(ContentCloudNodeSelectorService);
private readonly appConfigService = inject(AppConfigService);
private readonly apiService = inject(AlfrescoApiService);
private readonly contentNodeSelectorPanelService = inject(ContentNodeSelectorPanelService);
private readonly newVersionUploaderService = inject(NewVersionUploaderService);
typeId = 'AttachFileCloudWidgetComponent';
rootNodeId = ALIAS_USER_FOLDER;
@@ -39,8 +39,8 @@ const RETRIEVE_METADATA_OPTION = 'retrieveMetadata';
styleUrls: ['./file-properties-table-cloud.component.scss']
})
export class FilePropertiesTableCloudComponent {
private localizedDatePipe = inject(LocalizedDatePipe);
private thumbnailService = inject(ThumbnailService);
private readonly localizedDatePipe = inject(LocalizedDatePipe);
private readonly thumbnailService = inject(ThumbnailService);
@Input()
uploadedFiles;
@@ -20,9 +20,9 @@ import { DataTablePathParserHelper } from './helpers/data-table-path-parser.help
import { Subject } from 'rxjs';
export class WidgetDataTableAdapter implements DataTableAdapter {
private adapter: ObjectDataTableAdapter;
private columnKeys: string[] = [];
private helper = new DataTablePathParserHelper();
private readonly adapter: ObjectDataTableAdapter;
private readonly columnKeys: string[] = [];
private readonly helper = new DataTablePathParserHelper();
get selectedRow(): DataRow {
return this.adapter.selectedRow;
@@ -61,9 +61,9 @@ export class DataTableWidgetComponent extends WidgetComponent implements OnInit
private rowsData: DataRow[];
private columnsSchema: DataColumn[];
private variableName: string;
private defaultResponseProperty = 'data';
private pathParserHelper = new DataTablePathParserHelper();
private formCloudService = inject(FormCloudService);
private readonly defaultResponseProperty = 'data';
private readonly pathParserHelper = new DataTablePathParserHelper();
private readonly formCloudService = inject(FormCloudService);
ngOnInit(): void {
this.init();
@@ -76,7 +76,7 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
private readonly formCloudService = inject(FormCloudService);
private readonly appConfig = inject(AppConfigService);
private readonly formUtilsService = inject(FormUtilsService);
private destroyRef = inject(DestroyRef);
private readonly destroyRef = inject(DestroyRef);
typeId = 'DropdownCloudWidgetComponent';
showInputFilter = false;
@@ -93,7 +93,7 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
private readonly defaultVariableOptionLabel = 'name';
private readonly defaultVariableOptionPath = 'data';
private debounceSetValue = new Subject<void>();
private readonly debounceSetValue = new Subject<void>();
get showRequiredMessage(): boolean {
return this.dropdownControl.touched && this.dropdownControl.errors?.required && !this.isRestApiFailed && !this.variableOptionsFailed;
@@ -48,7 +48,7 @@ import { MatFormFieldModule } from '@angular/material/form-field';
encapsulation: ViewEncapsulation.None
})
export class PeopleCloudWidgetComponent extends WidgetComponent implements OnInit {
private identityUserService = inject(IdentityUserService);
private readonly identityUserService = inject(IdentityUserService);
typeId = 'PeopleCloudWidgetComponent';
appName: string;
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewEncapsulation } from '@angular/core';
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewEncapsulation, inject } from '@angular/core';
import { PresetConfig, NodesApiService, ContentMetadataComponent } from '@alfresco/adf-content-services';
import { Node } from '@alfresco/js-api';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
@@ -30,6 +30,8 @@ import { CommonModule } from '@angular/common';
encapsulation: ViewEncapsulation.None
})
export class PropertiesViewerWrapperComponent implements OnInit, OnChanges {
private readonly nodesApiService = inject(NodesApiService);
node: Node;
loading = true;
@@ -78,8 +80,6 @@ export class PropertiesViewerWrapperComponent implements OnInit, OnChanges {
@Output()
nodeContentLoaded = new EventEmitter<Node>();
constructor(private nodesApiService: NodesApiService) {}
ngOnChanges(changes: SimpleChanges): void {
if (changes?.['nodeId']?.currentValue && !changes['nodeId'].isFirstChange()) {
this.getNode(changes['nodeId'].currentValue);
@@ -46,9 +46,9 @@ import { FormsModule } from '@angular/forms';
encapsulation: ViewEncapsulation.None
})
export class RadioButtonsCloudWidgetComponent extends WidgetComponent implements OnInit {
private formCloudService = inject(FormCloudService);
private translateService = inject(TranslateService);
private formUtilsService = inject(FormUtilsService);
private readonly formCloudService = inject(FormCloudService);
private readonly translateService = inject(TranslateService);
private readonly formUtilsService = inject(FormUtilsService);
typeId = 'RadioButtonsCloudWidgetComponent';
restApiError: ErrorMessageModel;
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { NotificationService } from '@alfresco/adf-core';
import { MatDialog } from '@angular/material/dialog';
import { ContentNodeSelectorComponent, ContentNodeSelectorComponentData, NodeAction, AlfrescoApiService } from '@alfresco/adf-content-services';
@@ -28,6 +28,10 @@ import { DestinationFolderPathModel } from '../models/form-cloud-representation.
providedIn: 'root'
})
export class ContentCloudNodeSelectorService {
private readonly apiService = inject(AlfrescoApiService);
private readonly notificationService = inject(NotificationService);
private readonly dialog = inject(MatDialog);
private _nodesApi: NodesApi;
get nodesApi(): NodesApi {
this._nodesApi = this._nodesApi ?? new NodesApi(this.apiService.getInstance());
@@ -36,12 +40,6 @@ export class ContentCloudNodeSelectorService {
sourceNodeNotFound = false;
constructor(
private apiService: AlfrescoApiService,
private notificationService: NotificationService,
private dialog: MatDialog
) {}
openUploadFileDialog(
currentFolderId?: string,
selectionMode?: string,
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { inject, Inject, Injectable, InjectionToken, Optional } from '@angular/core';
import { inject, Injectable, InjectionToken } from '@angular/core';
import { FormValues, FormModel, FormFieldOption, FormFieldValidator, FormService } from '@alfresco/adf-core';
import { Observable, from, EMPTY } from 'rxjs';
import { expand, map, reduce, switchMap } from 'rxjs/operators';
@@ -25,7 +25,6 @@ import { TaskVariableCloud } from '../models/task-variable-cloud.model';
import { BaseCloudService } from '../../services/base-cloud.service';
import { FormContent } from '../../services/form-fields.interfaces';
import { FormCloudServiceInterface } from './form-cloud.service.interface';
import { AdfHttpClient } from '@alfresco/adf-core/api';
export const FORM_CLOUD_SERVICE_FIELD_VALIDATORS_TOKEN = new InjectionToken<FormFieldValidator[]>('FORM_CLOUD_SERVICE_FIELD_VALIDATORS_TOKEN');
@@ -34,21 +33,13 @@ export const FORM_CLOUD_SERVICE_FIELD_VALIDATORS_TOKEN = new InjectionToken<Form
})
export class FormCloudService extends BaseCloudService implements FormCloudServiceInterface {
private _uploadApi: UploadApi;
private fieldValidators: FormFieldValidator[];
private formService = inject(FormService);
private readonly fieldValidators: FormFieldValidator[] = inject(FORM_CLOUD_SERVICE_FIELD_VALIDATORS_TOKEN, { optional: true }) ?? [];
private readonly formService = inject(FormService);
get uploadApi(): UploadApi {
this._uploadApi = this._uploadApi ?? new UploadApi(this.apiService.getInstance());
return this._uploadApi;
}
constructor(
adfHttpClient: AdfHttpClient,
@Optional() @Inject(FORM_CLOUD_SERVICE_FIELD_VALIDATORS_TOKEN) injectedFieldValidators?: FormFieldValidator[]
) {
super(adfHttpClient);
this.fieldValidators = injectedFieldValidators || [];
}
/**
* Gets the form definition of a task.
*
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { Observable, from } from 'rxjs';
import { map } from 'rxjs/operators';
import { DownloadService } from '@alfresco/adf-core';
@@ -26,6 +26,11 @@ import { AuthenticationApi, Node, UploadApi } from '@alfresco/js-api';
providedIn: 'root'
})
export class ProcessCloudContentService {
private readonly apiService = inject(AlfrescoApiService);
private readonly nodesApiService = inject(NodesApiService);
private readonly contentService = inject(ContentService);
private readonly downloadService = inject(DownloadService);
private _uploadApi: UploadApi;
get uploadApi(): UploadApi {
this._uploadApi = this._uploadApi ?? new UploadApi(this.apiService.getInstance());
@@ -38,13 +43,6 @@ export class ProcessCloudContentService {
return this._authenticationApi;
}
constructor(
private apiService: AlfrescoApiService,
private nodesApiService: NodesApiService,
private contentService: ContentService,
private downloadService: DownloadService
) {}
createTemporaryRawRelatedContent(file: File, nodeId: string): Observable<Node> {
return from(this.uploadApi.uploadFile(file, '', nodeId, null, { overwrite: true })).pipe(
map((res: any) => ({
@@ -24,8 +24,8 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Injectable()
export class FormCloudSpinnerService {
private formService = inject(FormService);
private overlay = inject(Overlay);
private readonly formService = inject(FormService);
private readonly overlay = inject(Overlay);
private overlayRef?: OverlayRef = null;
@@ -74,6 +74,8 @@ import { IconModule } from '@alfresco/adf-core';
encapsulation: ViewEncapsulation.None
})
export class GroupCloudComponent implements OnInit, OnChanges {
private readonly identityGroupService = inject(IdentityGroupService);
/** Label for the user selection component. */
@Input()
label: string;
@@ -143,7 +145,7 @@ export class GroupCloudComponent implements OnInit, OnChanges {
warning = new EventEmitter<any>();
@ViewChild('groupInput')
private groupInput: ElementRef<HTMLInputElement>;
private readonly groupInput: ElementRef<HTMLInputElement>;
private searchGroups: IdentityGroupModel[] = [];
@@ -165,8 +167,6 @@ export class GroupCloudComponent implements OnInit, OnChanges {
private readonly destroyRef = inject(DestroyRef);
constructor(private identityGroupService: IdentityGroupService) {}
ngOnInit(): void {
this.initSearch();
}
@@ -20,8 +20,8 @@ import { TranslateModule } from '@ngx-translate/core';
import { IdentityGroupService } from './identity-group.service';
import { mockFoodGroups } from '../mock/group-cloud.mock';
import { AdfHttpClient } from '@alfresco/adf-core/api';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { HttpErrorResponse } from '@angular/common/http';
import { provideHttpClient, HttpErrorResponse } from '@angular/common/http';
import { provideHttpClientTesting } from '@angular/common/http/testing';
const mockHttpErrorResponse = new HttpErrorResponse({
error: 'Mock Error',
@@ -36,8 +36,8 @@ describe('IdentityGroupService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), HttpClientTestingModule],
providers: [IdentityGroupService]
imports: [TranslateModule.forRoot()],
providers: [IdentityGroupService, provideHttpClient(), provideHttpClientTesting()]
});
service = TestBed.inject(IdentityGroupService);
adfHttpClient = TestBed.inject(AdfHttpClient);
@@ -64,18 +64,18 @@ describe('IdentityGroupService', () => {
const searchSpy = spyOn(service, 'search').and.callThrough();
service.search('fake').subscribe(
() => {
service.search('fake').subscribe({
next: () => {
fail('expected an error, not groups');
},
(error) => {
error: (error) => {
expect(searchSpy).toHaveBeenCalled();
expect(error.status).toEqual(404);
expect(error.statusText).toEqual('Not Found');
expect(error.error).toEqual('Mock Error');
done();
}
);
});
});
it('should fetch groups by roles', (done) => {
@@ -107,11 +107,11 @@ describe('IdentityGroupService', () => {
roles: ['fake-role-1', 'fake-role-2'],
withinApplication: ''
})
.subscribe(
() => {
.subscribe({
next: () => {
fail('expected an error, not groups');
},
(error) => {
error: (error) => {
expect(searchSpy).toHaveBeenCalled();
expect(service.queryParams).toEqual({
search: 'fake',
@@ -122,7 +122,7 @@ describe('IdentityGroupService', () => {
expect(error.error).toEqual('Mock Error');
done();
}
);
});
});
it('should fetch groups within app', (done) => {
@@ -171,11 +171,11 @@ describe('IdentityGroupService', () => {
roles: [],
withinApplication: 'fake-app-name'
})
.subscribe(
() => {
.subscribe({
next: () => {
fail('expected an error, not groups');
},
(error) => {
error: (error) => {
expect(searchSpy).toHaveBeenCalled();
expect(service.queryParams).toEqual({
search: 'fake',
@@ -186,7 +186,7 @@ describe('IdentityGroupService', () => {
expect(error.error).toEqual('Mock Error');
done();
}
);
});
});
});
});
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { AppConfigService, OAuth2Service } from '@alfresco/adf-core';
import { EMPTY, Observable } from 'rxjs';
import { IdentityGroupModel } from '../models/identity-group.model';
@@ -29,9 +29,10 @@ export interface IdentityGroupFilterInterface {
@Injectable({ providedIn: 'root' })
export class IdentityGroupService {
queryParams: { search: string; application?: string; roles?: string[] };
private readonly oAuth2Service = inject(OAuth2Service);
private readonly appConfigService = inject(AppConfigService);
constructor(private oAuth2Service: OAuth2Service, private appConfigService: AppConfigService) {}
queryParams: { search: string; application?: string; roles?: string[] };
public search(name: string, filters?: IdentityGroupFilterInterface): Observable<IdentityGroupModel[]> {
if (name.trim() === '') {
@@ -78,6 +78,8 @@ import { MatTooltipModule } from '@angular/material/tooltip';
encapsulation: ViewEncapsulation.None
})
export class PeopleCloudComponent implements OnInit, OnChanges, AfterViewInit {
private readonly identityUserService = inject(IdentityUserService);
/** Label for the user selection component. */
@Input()
label: string;
@@ -205,7 +207,7 @@ export class PeopleCloudComponent implements OnInit, OnChanges, AfterViewInit {
warning = new EventEmitter<any>();
@ViewChild('userInput')
private userInput: ElementRef<HTMLInputElement>;
private readonly userInput: ElementRef<HTMLInputElement>;
private searchUsers: IdentityUserModel[] = [];
@@ -227,8 +229,6 @@ export class PeopleCloudComponent implements OnInit, OnChanges, AfterViewInit {
private readonly destroyRef = inject(DestroyRef);
constructor(private identityUserService: IdentityUserService) {}
ngOnInit(): void {
this.initSearch();
}
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { AppConfigService, JwtHelperService, OAuth2Service } from '@alfresco/adf-core';
import { EMPTY, Observable } from 'rxjs';
import { IdentityUserModel } from '../models/identity-user.model';
@@ -32,9 +32,11 @@ export interface IdentityUserFilterInterface {
providedIn: 'root'
})
export class IdentityUserService {
queryParams: { search: string; application?: string; roles?: string[]; groups?: string[] };
private readonly jwtHelperService = inject(JwtHelperService);
private readonly oAuth2Service = inject(OAuth2Service);
private readonly appConfigService = inject(AppConfigService);
constructor(private jwtHelperService: JwtHelperService, private oAuth2Service: OAuth2Service, private appConfigService: AppConfigService) {}
queryParams: { search: string; application?: string; roles?: string[]; groups?: string[] };
/**
* Gets the name and other basic details of the current user.
@@ -100,6 +100,15 @@ interface ProcessFilterFormProps {
encapsulation: ViewEncapsulation.None
})
export class EditProcessFilterCloudComponent implements OnChanges {
private readonly formBuilder = inject(FormBuilder);
dialog = inject(MatDialog);
private readonly dateAdapter = inject<DateAdapter<Date>>(DateAdapter);
private readonly userPreferencesService = inject(UserPreferencesService);
private readonly translateService = inject(TranslationService);
private readonly processFilterCloudService = inject(ProcessFilterCloudService);
private readonly appsProcessCloudService = inject(AppsProcessCloudService);
private readonly processCloudService = inject(ProcessCloudService);
/** The name of the application. */
@Input()
appName: string = '';
@@ -217,16 +226,7 @@ export class EditProcessFilterCloudComponent implements OnChanges {
private readonly destroyRef = inject(DestroyRef);
constructor(
private formBuilder: FormBuilder,
public dialog: MatDialog,
private dateAdapter: DateAdapter<Date>,
private userPreferencesService: UserPreferencesService,
private translateService: TranslationService,
private processFilterCloudService: ProcessFilterCloudService,
private appsProcessCloudService: AppsProcessCloudService,
private processCloudService: ProcessCloudService
) {
constructor() {
// Use effect to react to locale signal changes (must be in injection context)
effect(() => {
const locale = this.userPreferencesService.localeSignal();
@@ -64,7 +64,7 @@ export class ProcessFilterCloudModel {
processVariableFilters?: ProcessVariableFilterModel[];
private dateRangeFilterService = new DateRangeFilterService();
private readonly dateRangeFilterService = new DateRangeFilterService();
private _completedFrom: string | null;
private _completedTo: string | null;
private _startFrom: string | null;
@@ -45,9 +45,9 @@ const PROCESS_EVENT_SUBSCRIPTION_QUERY = `
providedIn: 'root'
})
export class ProcessFilterCloudService {
private filtersSubject: BehaviorSubject<ProcessFilterCloudModel[]>;
private readonly filtersSubject: BehaviorSubject<ProcessFilterCloudModel[]>;
filters$: Observable<ProcessFilterCloudModel[]>;
private filterKeyToBeRefreshedSource = new Subject<string>();
private readonly filterKeyToBeRefreshedSource = new Subject<string>();
filterKeyToBeRefreshed$: Observable<string> = this.filterKeyToBeRefreshedSource.asObservable();
protected readonly preferenceService = inject<PreferenceCloudServiceInterface>(PROCESS_FILTERS_SERVICE_TOKEN);
@@ -40,6 +40,10 @@ import { NgIf } from '@angular/common';
host: { class: 'adf-cloud-process-header' }
})
export class ProcessHeaderCloudComponent implements OnChanges, OnInit {
private readonly processCloudService = inject(ProcessCloudService);
private readonly translationService = inject(TranslationService);
private readonly appConfig = inject(AppConfigService);
/** (Required) The name of the application. */
@Input({ required: true })
appName: string = '';
@@ -59,12 +63,6 @@ export class ProcessHeaderCloudComponent implements OnChanges, OnInit {
private readonly destroyRef = inject(DestroyRef);
constructor(
private processCloudService: ProcessCloudService,
private translationService: TranslationService,
private appConfig: AppConfigService
) {}
ngOnInit() {
this.dateFormat = this.appConfig.get('adf-cloud-process-header.defaultDateFormat');
this.dateLocale = this.appConfig.get('dateValues.defaultDateLocale');
@@ -20,17 +20,16 @@ import {
Component,
ContentChild,
EventEmitter,
Inject,
input,
Input,
OnChanges,
Output,
SimpleChanges,
ViewChild,
ViewEncapsulation
ViewEncapsulation,
inject
} from '@angular/core';
import {
AppConfigService,
ColumnsSelectorComponent,
CustomEmptyContentTemplateDirective,
CustomLoadingContentTemplateDirective,
@@ -95,6 +94,11 @@ export class ProcessListCloudComponent
extends DataTableSchema<ProcessListDataColumnCustomData>
implements OnChanges, AfterContentInit, PaginatedComponent
{
private readonly processListCloudService = inject(ProcessListCloudService);
private readonly userPreferences = inject(UserPreferencesService);
private readonly cloudPreferenceService = inject<PreferenceCloudServiceInterface>(PROCESS_LISTS_PREFERENCES_SERVICE_TOKEN);
private readonly variableMapperService = inject(VariableMapperService);
@ViewChild(DataTableComponent) dataTable: DataTableComponent;
@ContentChild(CustomEmptyContentTemplateDirective)
@@ -354,7 +358,7 @@ export class ProcessListCloudComponent
processListRequestNode: ProcessListRequestModel;
dataAdapter: ProcessListDatatableAdapter;
private defaultSorting = { key: 'startDate', direction: 'desc' };
private readonly defaultSorting = { key: 'startDate', direction: 'desc' };
protected isLoadingPreferences$ = new BehaviorSubject<boolean>(true);
private readonly isReloadingSubject$ = new BehaviorSubject<boolean>(false);
@@ -363,20 +367,19 @@ export class ProcessListCloudComponent
map(([isLoadingPreferences, isReloading]) => isLoadingPreferences || isReloading)
);
private fetchProcessesTrigger$ = new Subject<void>();
private readonly fetchProcessesTrigger$ = new Subject<void>();
constructor() {
super(PRESET_KEY, processCloudPresetsDefaultModel);
const userPreferences = this.userPreferences;
constructor(
private processListCloudService: ProcessListCloudService,
appConfigService: AppConfigService,
private userPreferences: UserPreferencesService,
@Inject(PROCESS_LISTS_PREFERENCES_SERVICE_TOKEN) private cloudPreferenceService: PreferenceCloudServiceInterface,
private variableMapperService: VariableMapperService
) {
super(appConfigService, PRESET_KEY, processCloudPresetsDefaultModel);
this.size = userPreferences.paginationSize;
this.userPreferences.select(UserPreferenceValues.PaginationSize).subscribe((pageSize) => {
this.size = pageSize;
});
this.userPreferences
.select(UserPreferenceValues.PaginationSize)
.pipe(takeUntilDestroyed())
.subscribe((pageSize) => {
this.size = pageSize;
});
this.pagination = new BehaviorSubject<PaginationModel>({
maxItems: this.size,
skipCount: 0,
@@ -96,6 +96,8 @@ const PROCESS_DEFINITION_IDENTIFIER_REG_EXP = /%{processdefinition}/i;
encapsulation: ViewEncapsulation.None
})
export class StartProcessCloudComponent implements OnChanges, OnInit {
private readonly translateService = inject(TranslationService);
@ViewChild(MatAutocompleteTrigger)
inputAutocomplete: MatAutocompleteTrigger;
@@ -263,7 +265,7 @@ export class StartProcessCloudComponent implements OnChanges, OnInit {
return this.translateService.instant('ADF_CLOUD_PROCESS_LIST.ADF_CLOUD_START_PROCESS.FORM.ACTION.CANCEL').toUpperCase();
}
constructor(private readonly translateService: TranslationService) {
constructor() {
this.startProcessButtonLabel = this.defaultStartProcessButtonLabel;
this.cancelButtonLabel = this.defaultCancelProcessButtonLabel;
}
@@ -49,7 +49,7 @@ import { APP_CUSTOM_SCREEN_TOKEN, CustomScreen } from './provide-screen';
providedIn: 'root'
})
export class ScreenRenderingService extends DynamicComponentMapper {
private customScreens = inject<CustomScreen[]>(APP_CUSTOM_SCREEN_TOKEN, { optional: true }) || [];
private readonly customScreens = inject<CustomScreen[]>(APP_CUSTOM_SCREEN_TOKEN, { optional: true }) || [];
constructor() {
super();
@@ -24,6 +24,8 @@ import { RequestOptions } from '@alfresco/js-api';
@Injectable()
export class BaseCloudService {
protected adfHttpClient = inject(AdfHttpClient);
protected apiService = inject(AlfrescoApiService);
protected appConfigService = inject(AppConfigService);
@@ -34,8 +36,6 @@ export class BaseCloudService {
accepts: ['application/json']
};
constructor(protected adfHttpClient: AdfHttpClient) {}
getBasePath(appName: string): string {
return appName ? `${this.contextRoot}/${appName}` : this.contextRoot;
}
@@ -15,14 +15,14 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { PreferenceCloudServiceInterface } from './preference-cloud.interface';
import { StorageService } from '@alfresco/adf-core';
import { Observable, of } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class LocalPreferenceCloudService implements PreferenceCloudServiceInterface {
constructor(private storage: StorageService) {}
private readonly storage = inject(StorageService);
/**
* Gets local preferences
@@ -19,7 +19,8 @@ import { TestBed } from '@angular/core/testing';
import { NotificationCloudService } from './notification-cloud.service';
import { WebSocketService } from './web-socket.service';
import { Apollo } from 'apollo-angular';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { provideHttpClient } from '@angular/common/http';
import { provideHttpClientTesting } from '@angular/common/http/testing';
import { AuthenticationService } from '@alfresco/adf-core';
import { of, Subject } from 'rxjs';
@@ -42,7 +43,6 @@ describe('NotificationCloudService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [
WebSocketService,
{
@@ -55,7 +55,9 @@ describe('NotificationCloudService', () => {
getToken: () => 'testToken',
onLogout: onLogoutSubject.asObservable()
}
}
},
provideHttpClient(),
provideHttpClientTesting()
]
});
service = TestBed.inject(NotificationCloudService);
@@ -16,13 +16,13 @@
*/
import { gql } from '@apollo/client/core';
import { Injectable } from '@angular/core';
import { Injectable, inject } from '@angular/core';
import { WebSocketService } from './web-socket.service';
@Injectable({
providedIn: 'root'
})
export class NotificationCloudService {
constructor(private readonly webSocketService: WebSocketService) {}
private readonly webSocketService = inject(WebSocketService);
makeGQLQuery(appName: string, gqlQuery: string) {
return this.webSocketService.getSubscription({
@@ -51,17 +51,15 @@ interface serviceOptions {
providedIn: 'root'
})
export class WebSocketService {
private appConfigService = inject(AppConfigService);
private subscriptionProtocol = 'graphql-ws';
private readonly apollo = inject(Apollo);
private readonly httpLink = inject(HttpLink);
private readonly authService = inject(AuthenticationService);
private readonly appConfigService = inject(AppConfigService);
private readonly subscriptionProtocol: 'graphql-ws' | 'transport-ws' = 'graphql-ws';
private wsLink: GraphQLWsLink | WebSocketLink;
private httpLinkHandler: HttpLinkHandler;
constructor(
private readonly apollo: Apollo,
private readonly httpLink: HttpLink,
private readonly authService: AuthenticationService
) {}
public getSubscription<T>(options: serviceOptions): Observable<FetchResult<T>> {
const { apolloClientName, subscriptionOptions } = options;
this.authService.onLogout.pipe(take(1)).subscribe(() => {
@@ -20,17 +20,12 @@ import { Observable, of, Subject } from 'rxjs';
import { TaskDetailsCloudModel, TASK_ASSIGNED_STATE, TASK_CREATED_STATE } from '../models/task-details-cloud.model';
import { taskDetailsContainer } from '../task-header/mocks/task-details-cloud.mock';
import { TaskCloudService } from '../services/task-cloud.service';
import { AdfHttpClient } from '@alfresco/adf-core/api';
@Injectable()
export class TaskCloudServiceMock extends TaskCloudService {
currentUserMock = 'AssignedTaskUser';
dataChangesDetected$ = new Subject();
constructor(adfHttpClient: AdfHttpClient) {
super(adfHttpClient);
}
getTaskById(_appName: string, taskId: string): Observable<TaskDetailsCloudModel> {
return of(taskDetailsContainer[taskId]);
}
@@ -32,21 +32,16 @@ import { StartTaskCloudRequestModel } from '../models/start-task-cloud-request.m
import { ProcessDefinitionCloud } from '../../models/process-definition-cloud.model';
import { DEFAULT_TASK_PRIORITIES, TaskPriorityOption } from '../models/task.model';
import { IdentityUserService } from '../../people/services/identity-user.service';
import { AdfHttpClient } from '@alfresco/adf-core/api';
@Injectable({
providedIn: 'root'
})
export class TaskCloudService extends BaseCloudService {
private translateService = inject(TranslationService);
private identityUserService = inject(IdentityUserService);
private readonly translateService = inject(TranslationService);
private readonly identityUserService = inject(IdentityUserService);
dataChangesDetected$ = new Subject();
constructor(adfHttpClient: AdfHttpClient) {
super(adfHttpClient);
}
/**
* Complete a task.
*
@@ -61,7 +61,7 @@ import { TaskAssignmentFilterCloudComponent } from '../../task-assignment-filter
encapsulation: ViewEncapsulation.None
})
export class EditServiceTaskFilterCloudComponent extends BaseEditTaskFilterCloudComponent<ServiceTaskFilterCloudModel> {
private serviceTaskFilterCloudService = inject(ServiceTaskFilterCloudService);
private readonly serviceTaskFilterCloudService = inject(ServiceTaskFilterCloudService);
constructor() {
super();
@@ -64,7 +64,7 @@ import { TaskAssignmentFilterCloudComponent } from '../../task-assignment-filter
encapsulation: ViewEncapsulation.None
})
export class EditTaskFilterCloudComponent extends BaseEditTaskFilterCloudComponent<TaskFilterCloudModel> {
private taskFilterCloudService = inject(TaskFilterCloudService);
private readonly taskFilterCloudService = inject(TaskFilterCloudService);
constructor() {
super();
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Component, Input, Output, EventEmitter, OnInit, OnChanges, SimpleChanges } from '@angular/core';
import { Component, Input, Output, EventEmitter, OnInit, OnChanges, SimpleChanges, inject } from '@angular/core';
import { MatSelectChange, MatSelectModule } from '@angular/material/select';
import { AssignmentType, TaskFilterProperties, TaskStatusFilter } from '../../models/filter-cloud.model';
import { IdentityUserModel } from '../../../../people/models/identity-user.model';
@@ -35,6 +35,8 @@ import { PeopleCloudComponent } from '../../../../people/components/people-cloud
styleUrls: ['./task-assignment-filter.component.scss']
})
export class TaskAssignmentFilterCloudComponent implements OnInit, OnChanges {
private readonly identityUserService = inject(IdentityUserService);
@Input() appName: string;
@Input() taskFilterProperty: TaskFilterProperties;
@@ -53,8 +55,6 @@ export class TaskAssignmentFilterCloudComponent implements OnInit, OnChanges {
groupForm = new FormControl('');
assignmentTypeOptions: DropdownOption[];
constructor(private identityUserService: IdentityUserService) {}
ngOnChanges(changes: SimpleChanges): void {
if (changes?.status?.currentValue !== changes?.status?.previousValue) {
this.changeAssignmentTypeByStatus(changes?.status?.currentValue);
@@ -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 { AbstractControl, ReactiveFormsModule, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { CommonModule } from '@angular/common';
@@ -32,18 +32,16 @@ import { MatButtonModule } from '@angular/material/button';
encapsulation: ViewEncapsulation.None
})
export class TaskFilterDialogCloudComponent implements OnInit {
private readonly fb = inject(UntypedFormBuilder);
dialogRef = inject<MatDialogRef<TaskFilterDialogCloudComponent>>(MatDialogRef);
data = inject(MAT_DIALOG_DATA);
// eslint-disable-next-line @typescript-eslint/naming-convention
public static ACTION_SAVE = 'SAVE';
defaultIcon = 'inbox';
filterForm: UntypedFormGroup;
constructor(
private fb: UntypedFormBuilder,
public dialogRef: MatDialogRef<TaskFilterDialogCloudComponent>,
@Inject(MAT_DIALOG_DATA) public data
) {}
ngOnInit() {
this.filterForm = this.fb.group({
name: [this.data.name, Validators.required]
@@ -78,7 +78,7 @@ export class TaskFilterCloudModel {
private _dueDateTo: string;
private _createdFrom: string;
private _createdTo: string;
private dateRangeFilterService = new DateRangeFilterService();
private readonly dateRangeFilterService = new DateRangeFilterService();
processVariableFilters?: ProcessVariableFilterModel[];
@@ -26,7 +26,6 @@ import { TaskCloudNodePaging } from '../../../models/task-cloud.model';
import { NotificationCloudService } from '../../../services/notification-cloud.service';
import { TaskCloudEngineEvent } from '../../../models/engine-event-cloud.model';
import { IdentityUserService } from '../../../people/services/identity-user.service';
import { AdfHttpClient } from '@alfresco/adf-core/api';
const TASK_EVENT_SUBSCRIPTION_QUERY = `
subscription {
@@ -48,22 +47,17 @@ const TASK_EVENT_SUBSCRIPTION_QUERY = `
providedIn: 'root'
})
export class TaskFilterCloudService extends BaseCloudService {
private readonly notificationCloudService = inject(NotificationCloudService);
public preferenceService = inject<PreferenceCloudServiceInterface>(TASK_FILTERS_SERVICE_TOKEN);
protected identityUserService = inject(IdentityUserService);
private filtersSubject = new BehaviorSubject<TaskFilterCloudModel[]>([]);
private readonly filtersSubject = new BehaviorSubject<TaskFilterCloudModel[]>([]);
filters$ = this.filtersSubject.asObservable();
private filterKeyToBeRefreshedSource = new Subject<string>();
private readonly filterKeyToBeRefreshedSource = new Subject<string>();
filterKeyToBeRefreshed$ = this.filterKeyToBeRefreshedSource.asObservable();
constructor(
private notificationCloudService: NotificationCloudService,
adfHttpClient: AdfHttpClient
) {
super(adfHttpClient);
}
/**
* Creates and returns the default task filters for an app.
*
@@ -16,7 +16,7 @@
*/
import { ContentLinkModel, FormModel, FormOutcomeEvent, FormRenderingService } from '@alfresco/adf-core';
import { Component, EventEmitter, Input, Output, ViewChild, ViewEncapsulation } from '@angular/core';
import { Component, EventEmitter, Input, Output, ViewChild, ViewEncapsulation, inject } from '@angular/core';
import { FormCloudComponent } from '../../../../form/components/form-cloud.component';
import { AttachFileCloudWidgetComponent } from '../../../../form/components/widgets/attach-file/attach-file-cloud-widget.component';
import { DateCloudWidgetComponent } from '../../../../form/components/widgets/date/date-cloud.widget';
@@ -36,6 +36,9 @@ import { FormCustomOutcomesComponent } from '../../../../form/components/form-cl
encapsulation: ViewEncapsulation.None
})
export class TaskFormCloudComponent {
private readonly taskCloudService = inject(TaskCloudService);
private readonly formRenderingService = inject(FormRenderingService);
/** App id to fetch corresponding form and values. */
@Input()
appName: string = '';
@@ -174,10 +177,7 @@ export class TaskFormCloudComponent {
loading: boolean = false;
constructor(
private taskCloudService: TaskCloudService,
private formRenderingService: FormRenderingService
) {
constructor() {
this.formRenderingService.setComponentTypeResolver('upload', () => AttachFileCloudWidgetComponent, true);
this.formRenderingService.setComponentTypeResolver('dropdown', () => DropdownCloudWidgetComponent, true);
this.formRenderingService.setComponentTypeResolver('date', () => DateCloudWidgetComponent, true);
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Directive, Input, HostListener, Output, EventEmitter, OnInit, ElementRef, Renderer2 } from '@angular/core';
import { Directive, Input, HostListener, Output, EventEmitter, OnInit, ElementRef, Renderer2, inject } from '@angular/core';
import { IdentityUserService } from '../../../../../people/services/identity-user.service';
import { TaskCloudService } from '../../../../services/task-cloud.service';
import { firstValueFrom } from 'rxjs';
@@ -25,6 +25,11 @@ import { firstValueFrom } from 'rxjs';
selector: '[adf-cloud-claim-task]'
})
export class ClaimTaskCloudDirective implements OnInit {
private readonly el = inject(ElementRef);
private readonly renderer = inject(Renderer2);
private readonly taskListService = inject(TaskCloudService);
private readonly identityUserService = inject(IdentityUserService);
/** (Required) The id of the task. */
@Input()
taskId: string;
@@ -43,13 +48,6 @@ export class ClaimTaskCloudDirective implements OnInit {
invalidParams: string[] = [];
constructor(
private readonly el: ElementRef,
private readonly renderer: Renderer2,
private taskListService: TaskCloudService,
private identityUserService: IdentityUserService
) {}
ngOnInit() {
this.validateInputs();
}
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Directive, Input, HostListener, Output, EventEmitter, OnInit, ElementRef, Renderer2 } from '@angular/core';
import { Directive, Input, HostListener, Output, EventEmitter, OnInit, ElementRef, Renderer2, inject } from '@angular/core';
import { TaskCloudService } from '../../../../services/task-cloud.service';
import { firstValueFrom } from 'rxjs';
@@ -24,6 +24,10 @@ import { firstValueFrom } from 'rxjs';
selector: '[adf-cloud-unclaim-task]'
})
export class UnClaimTaskCloudDirective implements OnInit {
private readonly el = inject(ElementRef);
private readonly renderer = inject(Renderer2);
private readonly taskListService = inject(TaskCloudService);
/** (Required) The id of the task. */
@Input()
taskId: string;
@@ -42,12 +46,6 @@ export class UnClaimTaskCloudDirective implements OnInit {
invalidParams: string[] = [];
constructor(
private readonly el: ElementRef,
private readonly renderer: Renderer2,
private taskListService: TaskCloudService
) {}
ngOnInit() {
this.validateInputs();
}
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Directive, Input, HostListener, Output, EventEmitter, OnInit, ElementRef, Renderer2 } from '@angular/core';
import { Directive, Input, HostListener, Output, EventEmitter, OnInit, ElementRef, Renderer2, inject } from '@angular/core';
import { TaskCloudService } from '../../../../services/task-cloud.service';
import { firstValueFrom } from 'rxjs';
@@ -24,6 +24,10 @@ import { firstValueFrom } from 'rxjs';
selector: '[adf-cloud-complete-task]'
})
export class CompleteTaskDirective implements OnInit {
private readonly el = inject(ElementRef);
private readonly renderer = inject(Renderer2);
private readonly taskListService = inject(TaskCloudService);
/** (Required) The id of the task. */
@Input()
taskId: string;
@@ -42,12 +46,6 @@ export class CompleteTaskDirective implements OnInit {
invalidParams: string[] = [];
constructor(
private readonly el: ElementRef,
private readonly renderer: Renderer2,
private readonly taskListService: TaskCloudService
) {}
ngOnInit() {
this.validateInputs();
}
@@ -188,7 +188,7 @@ export class UserTaskCloudComponent implements OnInit, OnChanges {
taskTypeEnum = UserTaskContentType;
screenId: string;
private taskCloudService: TaskCloudService = inject(TaskCloudService);
private readonly taskCloudService: TaskCloudService = inject(TaskCloudService);
private readonly taskTypeResolverService = inject(TaskTypeResolverService);
private readonly destroyRef = inject(DestroyRef);
@@ -48,6 +48,11 @@ import { MatCardModule } from '@angular/material/card';
encapsulation: ViewEncapsulation.None
})
export class TaskHeaderCloudComponent implements OnInit, OnChanges {
private readonly taskCloudService = inject(TaskCloudService);
private readonly translationService = inject(TranslationService);
private readonly appConfig = inject(AppConfigService);
private readonly cardViewUpdateService = inject(CardViewUpdateService);
/** (Required) The name of the application. */
@Input({ required: true })
appName: string = '';
@@ -86,12 +91,7 @@ export class TaskHeaderCloudComponent implements OnInit, OnChanges {
private readonly destroyRef = inject(DestroyRef);
constructor(
private taskCloudService: TaskCloudService,
private translationService: TranslationService,
private appConfig: AppConfigService,
private cardViewUpdateService: CardViewUpdateService
) {
constructor() {
this.dateFormat = this.appConfig.get('adf-cloud-task-header.defaultDateFormat');
this.dateLocale = this.appConfig.get('dateValues.defaultDateLocale');
}
@@ -194,16 +194,16 @@ export abstract class BaseTaskListCloudComponent<T = unknown>
protected isLoadingPreferences$ = new BehaviorSubject<boolean>(true);
protected readonly destroyRef = inject(DestroyRef);
protected readonly appConfigService = inject(AppConfigService);
protected readonly taskCloudService = inject(TaskCloudService);
protected readonly userPreferences = inject(UserPreferencesService);
private readonly cloudPreferenceService: PreferenceCloudServiceInterface;
constructor(
appConfigService: AppConfigService,
private taskCloudService: TaskCloudService,
private userPreferences: UserPreferencesService,
presetKey: string,
private cloudPreferenceService: PreferenceCloudServiceInterface
) {
super(appConfigService, presetKey, taskPresetsCloudDefaultModel);
this.size = userPreferences.paginationSize;
// eslint-disable-next-line @angular-eslint/prefer-inject
constructor(presetKey: string, cloudPreferenceService: PreferenceCloudServiceInterface) {
super(presetKey, taskPresetsCloudDefaultModel);
this.cloudPreferenceService = cloudPreferenceService;
this.size = this.userPreferences.paginationSize;
this.pagination = new BehaviorSubject<PaginationModel>({
maxItems: this.size,
@@ -15,21 +15,18 @@
* limitations under the License.
*/
import { Component, Inject, Input, ViewEncapsulation } from '@angular/core';
import { Component, Input, ViewEncapsulation, inject } from '@angular/core';
import {
AppConfigService,
ColumnsSelectorComponent,
DataTableComponent,
EmptyContentComponent,
LoadingContentTemplateDirective,
MainMenuDataTableTemplateDirective,
NoContentTemplateDirective,
UserPreferencesService
NoContentTemplateDirective
} from '@alfresco/adf-core';
import { ServiceTaskQueryCloudRequestModel } from '../../models/service-task-cloud.model';
import { BaseTaskListCloudComponent } from '../base-task-list-cloud.component';
import { ServiceTaskListCloudService } from '../../services/service-task-list-cloud.service';
import { TaskCloudService } from '../../../services/task-cloud.service';
import { BehaviorSubject, combineLatest } from 'rxjs';
import { PreferenceCloudServiceInterface, TASK_LIST_PREFERENCES_SERVICE_TOKEN } from '../../../../services/public-api';
import { map } from 'rxjs/operators';
@@ -58,22 +55,20 @@ const PRESET_KEY = 'adf-cloud-service-task-list.presets';
encapsulation: ViewEncapsulation.None
})
export class ServiceTaskListCloudComponent extends BaseTaskListCloudComponent {
private readonly serviceTaskListCloudService = inject(ServiceTaskListCloudService);
@Input()
queryParams: { [key: string]: any } = {};
private isReloadingSubject$ = new BehaviorSubject<boolean>(false);
private readonly isReloadingSubject$ = new BehaviorSubject<boolean>(false);
isLoading$ = combineLatest([this.isLoadingPreferences$, this.isReloadingSubject$]).pipe(
map(([isLoadingPreferences, isReloading]) => isLoadingPreferences || isReloading)
);
constructor(
private serviceTaskListCloudService: ServiceTaskListCloudService,
appConfigService: AppConfigService,
taskCloudService: TaskCloudService,
userPreferences: UserPreferencesService,
@Inject(TASK_LIST_PREFERENCES_SERVICE_TOKEN) cloudPreferenceService: PreferenceCloudServiceInterface
) {
super(appConfigService, taskCloudService, userPreferences, PRESET_KEY, cloudPreferenceService);
constructor() {
const cloudPreferenceService = inject<PreferenceCloudServiceInterface>(TASK_LIST_PREFERENCES_SERVICE_TOKEN);
super(PRESET_KEY, cloudPreferenceService);
}
reload() {
@@ -15,22 +15,19 @@
* limitations under the License.
*/
import { Component, Inject, Input, ViewEncapsulation } from '@angular/core';
import { Component, Input, ViewEncapsulation, inject } from '@angular/core';
import {
AdfDateFnsAdapter,
AppConfigService,
ColumnsSelectorComponent,
DataTableComponent,
EmptyContentComponent,
LoadingContentTemplateDirective,
MainMenuDataTableTemplateDirective,
MOMENT_DATE_FORMATS,
NoContentTemplateDirective,
UserPreferencesService
NoContentTemplateDirective
} from '@alfresco/adf-core';
import { TaskListRequestModel, TaskQueryCloudRequestModel } from '../../../../models/filter-cloud-model';
import { BaseTaskListCloudComponent } from '../base-task-list-cloud.component';
import { TaskCloudService } from '../../../services/task-cloud.service';
import { TASK_LIST_CLOUD_TOKEN, TASK_LIST_PREFERENCES_SERVICE_TOKEN } from '../../../../services/cloud-token.service';
import { PreferenceCloudServiceInterface } from '../../../../services/preference-cloud.interface';
import { TaskListCloudServiceInterface } from '../../../../services/task-list-cloud.service.interface';
@@ -74,6 +71,9 @@ const PRESET_KEY = 'adf-cloud-task-list.presets';
encapsulation: ViewEncapsulation.None
})
export class TaskListCloudComponent extends BaseTaskListCloudComponent<ProcessListDataColumnCustomData> {
taskListCloudService = inject<TaskListCloudServiceInterface>(TASK_LIST_CLOUD_TOKEN);
private readonly viewModelCreator = inject(VariableMapperService);
/**
* The assignee of the process. Possible values are: "assignee" (the current user is the assignee),
* "candidate" (the current user is a task candidate", "group_x" (the task is assigned to a group
@@ -262,22 +262,16 @@ export class TaskListCloudComponent extends BaseTaskListCloudComponent<ProcessLi
rows: TaskInstanceCloudListViewModel[] = [];
declare dataAdapter: TasksListDatatableAdapter | undefined;
private isReloadingSubject$ = new BehaviorSubject<boolean>(false);
private readonly isReloadingSubject$ = new BehaviorSubject<boolean>(false);
isLoading$ = combineLatest([this.isLoadingPreferences$, this.isReloadingSubject$]).pipe(
map(([isLoadingPreferences, isReloading]) => isLoadingPreferences || isReloading)
);
private fetchProcessesTrigger$ = new Subject<void>();
private readonly fetchProcessesTrigger$ = new Subject<void>();
constructor(
@Inject(TASK_LIST_CLOUD_TOKEN) public taskListCloudService: TaskListCloudServiceInterface,
appConfigService: AppConfigService,
taskCloudService: TaskCloudService,
userPreferences: UserPreferencesService,
@Inject(TASK_LIST_PREFERENCES_SERVICE_TOKEN) cloudPreferenceService: PreferenceCloudServiceInterface,
private viewModelCreator: VariableMapperService
) {
super(appConfigService, taskCloudService, userPreferences, PRESET_KEY, cloudPreferenceService);
constructor() {
const cloudPreferenceService = inject<PreferenceCloudServiceInterface>(TASK_LIST_PREFERENCES_SERVICE_TOKEN);
super(PRESET_KEY, cloudPreferenceService);
combineLatest([this.isLoadingPreferences$, this.isColumnSchemaCreated$, this.fetchProcessesTrigger$])
.pipe(