[ACS-8959] Introduce new takeUntilDestroyed operator where possible (#10388)

This commit is contained in:
dominikiwanekhyland
2024-11-19 11:54:00 +01:00
committed by GitHub
parent 3f6b60760f
commit 3078387325
128 changed files with 1452 additions and 1546 deletions

View File

@@ -17,8 +17,16 @@
import { CustomEmptyContentTemplateDirective, EmptyContentComponent } from '@alfresco/adf-core';
import { AppsProcessService } from '../services/apps-process.service';
import { AfterContentInit, Component, EventEmitter, Input, OnInit, Output, ContentChild, OnDestroy, ViewEncapsulation } from '@angular/core';
import { Subject } from 'rxjs';
import {
AfterContentInit,
Component,
ContentChild,
EventEmitter,
Input,
OnInit,
Output,
ViewEncapsulation
} from '@angular/core';
import { IconModel } from './icon.model';
import { finalize, map } from 'rxjs/operators';
import { AppDefinitionRepresentation } from '@alfresco/js-api';
@@ -55,7 +63,7 @@ export const APP_LIST_LAYOUT_GRID: string = 'GRID';
encapsulation: ViewEncapsulation.None,
host: { class: 'adf-apps' }
})
export class AppsListComponent implements OnInit, AfterContentInit, OnDestroy {
export class AppsListComponent implements OnInit, AfterContentInit {
@ContentChild(CustomEmptyContentTemplateDirective)
emptyCustomContent: CustomEmptyContentTemplateDirective;
@@ -88,8 +96,6 @@ export class AppsListComponent implements OnInit, AfterContentInit, OnDestroy {
hasEmptyCustomContentTemplate: boolean = false;
private iconsMDL: IconModel;
private onDestroy$ = new Subject<boolean>();
constructor(private appsProcessService: AppsProcessService) {}
ngOnInit() {
@@ -101,11 +107,6 @@ export class AppsListComponent implements OnInit, AfterContentInit, OnDestroy {
this.load();
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
ngAfterContentInit() {
if (this.emptyCustomContent) {
this.hasEmptyCustomContentTemplate = true;

View File

@@ -16,36 +16,36 @@
*/
import {
ChangeDetectorRef,
Component,
DestroyRef,
EventEmitter,
Input,
Output,
ViewEncapsulation,
SimpleChanges,
OnInit,
OnDestroy,
OnChanges,
inject,
ChangeDetectorRef
Input,
OnChanges,
OnInit,
Output,
SimpleChanges,
ViewEncapsulation
} from '@angular/core';
import {
WidgetVisibilityService,
FormService,
ContentLinkModel,
FormatSpacePipe,
FormBaseComponent,
FormOutcomeModel,
FormEvent,
FormErrorEvent,
FormEvent,
FormFieldModel,
FormModel,
FormOutcomeEvent,
FormValues,
ContentLinkModel,
TaskProcessVariableModel,
FormOutcomeModel,
FormRendererComponent,
FormatSpacePipe
FormService,
FormValues,
TaskProcessVariableModel,
WidgetVisibilityService
} from '@alfresco/adf-core';
import { from, Observable, of, Subject } from 'rxjs';
import { switchMap, takeUntil } from 'rxjs/operators';
import { from, Observable, of } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { EcmModelService } from './services/ecm-model.service';
import { ModelService } from './services/model.service';
import { EditorService } from './services/editor.service';
@@ -58,6 +58,7 @@ import { MatCardModule } from '@angular/material/card';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { TranslateModule } from '@ngx-translate/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
selector: 'adf-form',
@@ -67,7 +68,7 @@ import { TranslateModule } from '@ngx-translate/core';
styleUrls: ['./form.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class FormComponent extends FormBaseComponent implements OnInit, OnDestroy, OnChanges {
export class FormComponent extends FormBaseComponent implements OnInit, OnChanges {
protected formService = inject(FormService);
protected taskFormService = inject(TaskFormService);
protected taskService = inject(TaskService);
@@ -132,16 +133,16 @@ export class FormComponent extends FormBaseComponent implements OnInit, OnDestro
debugMode: boolean = false;
protected onDestroy$ = new Subject<boolean>();
private readonly destroyRef = inject(DestroyRef);
constructor() {
super();
}
ngOnInit() {
this.formService.formContentClicked.pipe(takeUntil(this.onDestroy$)).subscribe((content) => this.formContentClicked.emit(content));
this.formService.formContentClicked.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((content) => this.formContentClicked.emit(content));
this.formService.validateForm.pipe(takeUntil(this.onDestroy$)).subscribe((validateFormEvent) => {
this.formService.validateForm.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((validateFormEvent) => {
if (validateFormEvent.errorsField.length > 0) {
this.formError.next(validateFormEvent.errorsField);
this.cdRef.detectChanges();
@@ -149,11 +150,6 @@ export class FormComponent extends FormBaseComponent implements OnInit, OnDestro
});
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
ngOnChanges(changes: SimpleChanges) {
const taskId = changes['taskId'];
if (taskId?.currentValue) {

View File

@@ -19,15 +19,14 @@ import {
Component,
ElementRef,
EventEmitter,
inject,
Input,
OnChanges,
OnInit,
Output,
SimpleChanges,
ViewChild,
ViewEncapsulation,
OnDestroy,
inject
ViewEncapsulation
} from '@angular/core';
import { FormComponent } from '../form.component';
import { ContentLinkModel, FormOutcomeModel, FormRendererComponent } from '@alfresco/adf-core';
@@ -46,7 +45,7 @@ import { MatIconModule } from '@angular/material/icon';
styleUrls: ['./start-form.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class StartFormComponent extends FormComponent implements OnChanges, OnInit, OnDestroy {
export class StartFormComponent extends FormComponent implements OnChanges, OnInit {
public processService = inject(ProcessService);
/** Definition ID of the process to start, this parameter can not be use in combination with processId */

View File

@@ -15,24 +15,23 @@
* limitations under the License.
*/
import { Component, Inject, ViewEncapsulation, ViewChild, OnDestroy, OnInit } from '@angular/core';
import { Component, DestroyRef, inject, Inject, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { LoginDialogPanelComponent, TranslationService, AuthenticationService } from '@alfresco/adf-core';
import { AuthenticationService, LoginDialogPanelComponent, TranslationService } from '@alfresco/adf-core';
import { AttachFileWidgetDialogComponentData } from './attach-file-widget-dialog-component.interface';
import {
DocumentListService,
SitesService,
SearchService,
AlfrescoApiService,
ContentNodeSelectorPanelComponent,
AlfrescoApiService
DocumentListService,
SearchService,
SitesService
} from '@alfresco/adf-content-services';
import { ExternalAlfrescoApiService } from '../../services/external-alfresco-api.service';
import { Node } from '@alfresco/js-api';
import { CommonModule } from '@angular/common';
import { MatButtonModule } from '@angular/material/button';
import { TranslateModule } from '@ngx-translate/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
selector: 'adf-attach-file-widget-dialog',
@@ -49,7 +48,7 @@ import { takeUntil } from 'rxjs/operators';
{ provide: AlfrescoApiService, useClass: ExternalAlfrescoApiService }
]
})
export class AttachFileWidgetDialogComponent implements OnInit, OnDestroy {
export class AttachFileWidgetDialogComponent implements OnInit {
@ViewChild('adfLoginPanel')
loginPanel: LoginDialogPanelComponent;
@@ -58,7 +57,7 @@ export class AttachFileWidgetDialogComponent implements OnInit, OnDestroy {
buttonActionName: string;
chosenNode: Node[];
private onDestroy$ = new Subject<boolean>();
private readonly destroyRef = inject(DestroyRef);
constructor(
private translation: TranslationService,
@@ -74,18 +73,12 @@ export class AttachFileWidgetDialogComponent implements OnInit, OnDestroy {
}
ngOnInit() {
this.authenticationService.onLogin.pipe(takeUntil(this.onDestroy$)).subscribe(() => this.registerAndClose());
this.authenticationService.onLogin.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => this.registerAndClose());
if (this.isLoggedIn()) {
this.registerAndClose();
}
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
isLoggedIn(): boolean {
return !!this.externalApiService.getInstance()?.isLoggedIn();
}

View File

@@ -17,12 +17,24 @@
/* eslint-disable @angular-eslint/component-selector */
import { Component, isDevMode, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { AppConfigService, AppConfigValues, DownloadService, ErrorWidgetComponent, FormService, ThumbnailService } from '@alfresco/adf-core';
import { Component, DestroyRef, inject, isDevMode, OnInit, ViewEncapsulation } from '@angular/core';
import {
AppConfigService,
AppConfigValues,
DownloadService,
ErrorWidgetComponent,
FormService,
ThumbnailService
} from '@alfresco/adf-core';
import { AlfrescoIconComponent, ContentNodeDialogService, ContentService } from '@alfresco/adf-content-services';
import { AlfrescoEndpointRepresentation, Node, NodeChildAssociation, RelatedContentRepresentation } from '@alfresco/js-api';
import { from, of, Subject, zip } from 'rxjs';
import { mergeMap, takeUntil } from 'rxjs/operators';
import {
AlfrescoEndpointRepresentation,
Node,
NodeChildAssociation,
RelatedContentRepresentation
} from '@alfresco/js-api';
import { from, of, zip } from 'rxjs';
import { mergeMap } from 'rxjs/operators';
import { AttachFileWidgetDialogService } from './attach-file-widget-dialog.service';
import { UploadWidgetComponent } from '../upload/upload.widget';
import { ProcessContentService } from '../../services/process-content.service';
@@ -34,6 +46,7 @@ import { MatButtonModule } from '@angular/material/button';
import { MatMenuModule } from '@angular/material/menu';
import { MatListModule } from '@angular/material/list';
import { ActivatedRoute, Router } from '@angular/router';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
selector: 'attach-widget',
@@ -63,11 +76,12 @@ import { ActivatedRoute, Router } from '@angular/router';
},
encapsulation: ViewEncapsulation.None
})
export class AttachFileWidgetComponent extends UploadWidgetComponent implements OnInit, OnDestroy {
export class AttachFileWidgetComponent extends UploadWidgetComponent implements OnInit {
typeId = 'AttachFileWidgetComponent';
repositoryList: AlfrescoEndpointRepresentation[] = [];
private tempFilesList = [];
private onDestroy$ = new Subject<boolean>();
private readonly destroyRef = inject(DestroyRef);
constructor(
public formService: FormService,
@@ -96,18 +110,13 @@ export class AttachFileWidgetComponent extends UploadWidgetComponent implements
this.repositoryList = repoList;
});
this.formService.taskSaved.pipe(takeUntil(this.onDestroy$)).subscribe((formSaved) => {
this.formService.taskSaved.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((formSaved) => {
if (formSaved.form.id === this.field.form.id) {
this.tempFilesList = [];
}
});
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
isFileSourceConfigured(): boolean {
return !!this.field.params?.fileSource;
}

View File

@@ -17,17 +17,24 @@
/* eslint-disable @angular-eslint/component-selector */
import { Component, inject, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { FormService, FormFieldOption, WidgetComponent, ErrorWidgetComponent, ErrorMessageModel, FormFieldModel } from '@alfresco/adf-core';
import { Component, DestroyRef, inject, OnInit, ViewEncapsulation } from '@angular/core';
import {
ErrorMessageModel,
ErrorWidgetComponent,
FormFieldModel,
FormFieldOption,
FormService,
WidgetComponent
} from '@alfresco/adf-core';
import { ProcessDefinitionService } from '../../services/process-definition.service';
import { TaskFormService } from '../../services/task-form.service';
import { CommonModule } from '@angular/common';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatSelectModule } from '@angular/material/select';
import { AbstractControl, FormControl, ReactiveFormsModule, ValidationErrors, ValidatorFn } from '@angular/forms';
import { filter, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { filter } from 'rxjs/operators';
import { TranslateModule } from '@ngx-translate/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
selector: 'dropdown-widget',
@@ -48,14 +55,14 @@ import { TranslateModule } from '@ngx-translate/core';
},
encapsulation: ViewEncapsulation.None
})
export class DropdownWidgetComponent extends WidgetComponent implements OnInit, OnDestroy {
export class DropdownWidgetComponent extends WidgetComponent implements OnInit {
public formsService = inject(FormService);
public taskFormService = inject(TaskFormService);
public processDefinitionService = inject(ProcessDefinitionService);
dropdownControl = new FormControl<FormFieldOption | string>(undefined);
private readonly onDestroy$ = new Subject<void>();
private readonly destroyRef = inject(DestroyRef);
get isReadOnlyType(): boolean {
return this.field.type === 'readonly';
@@ -89,11 +96,6 @@ export class DropdownWidgetComponent extends WidgetComponent implements OnInit,
this.initFormControl();
}
ngOnDestroy(): void {
this.onDestroy$.next();
this.onDestroy$.complete();
}
getValuesByTaskId() {
this.taskFormService.getRestFieldValues(this.field.form.taskId, this.field.id).subscribe((formFieldOption) => {
const options = [];
@@ -134,7 +136,7 @@ export class DropdownWidgetComponent extends WidgetComponent implements OnInit,
this.dropdownControl.valueChanges
.pipe(
filter(() => !!this.field),
takeUntil(this.onDestroy$)
takeUntilDestroyed(this.destroyRef)
)
.subscribe((value) => {
this.setOptionValue(value, this.field);

View File

@@ -15,18 +15,18 @@
* limitations under the License.
*/
import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges, ViewEncapsulation } from '@angular/core';
import { Component, DestroyRef, EventEmitter, inject, Input, OnChanges, OnInit, Output, SimpleChanges, ViewEncapsulation } from '@angular/core';
import { ProcessInstanceFilterRepresentation, UserProcessInstanceFilterRepresentation } from '@alfresco/js-api';
import { Subject } from 'rxjs';
import { ProcessFilterService } from '../../services/process-filter.service';
import { AppsProcessService } from '../../../services/apps-process.service';
import { IconModel } from '../../../app-list/icon.model';
import { NavigationStart, Router } from '@angular/router';
import { filter, takeUntil } from 'rxjs/operators';
import { filter } from 'rxjs/operators';
import { CommonModule, Location } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { MatButtonModule } from '@angular/material/button';
import { IconComponent } from '@alfresco/adf-core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
selector: 'adf-process-instance-filters',
@@ -36,7 +36,7 @@ import { IconComponent } from '@alfresco/adf-core';
styleUrls: ['./process-filters.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class ProcessFiltersComponent implements OnInit, OnChanges, OnDestroy {
export class ProcessFiltersComponent implements OnInit, OnChanges {
/**
* The parameters to filter the task filter. If there is no match then the default one
* (ie, the first filter in the list) is selected.
@@ -78,10 +78,11 @@ export class ProcessFiltersComponent implements OnInit, OnChanges, OnDestroy {
active = false;
isProcessRoute: boolean;
isProcessActive: boolean;
private onDestroy$ = new Subject<boolean>();
private iconsMDL: IconModel;
private readonly destroyRef = inject(DestroyRef);
constructor(
private processFilterService: ProcessFilterService,
private appsProcessService: AppsProcessService,
@@ -94,7 +95,7 @@ export class ProcessFiltersComponent implements OnInit, OnChanges, OnDestroy {
this.router.events
.pipe(
filter((event) => event instanceof NavigationStart),
takeUntil(this.onDestroy$)
takeUntilDestroyed(this.destroyRef)
)
.subscribe((navigationStart: NavigationStart) => {
const activeRoute = navigationStart.url;
@@ -248,9 +249,4 @@ export class ProcessFiltersComponent implements OnInit, OnChanges, OnDestroy {
this.filters = [];
this.currentFilter = undefined;
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
}

View File

@@ -16,12 +16,12 @@
*/
import { CommonModule, DatePipe } from '@angular/common';
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild, OnDestroy } from '@angular/core';
import { Component, DestroyRef, EventEmitter, inject, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core';
import { MatDialog, MatDialogModule } from '@angular/material/dialog';
import { Observable, Observer, Subject } from 'rxjs';
import { Observable, Observer } from 'rxjs';
import { TaskDetailsEvent } from '../../../task-list';
import { ProcessService } from '../../services/process.service';
import { share, takeUntil } from 'rxjs/operators';
import { share } from 'rxjs/operators';
import { ProcessInstanceRepresentation, TaskRepresentation } from '@alfresco/js-api';
import { MatButtonModule } from '@angular/material/button';
import { TranslateModule } from '@ngx-translate/core';
@@ -29,6 +29,7 @@ import { MatChipsModule } from '@angular/material/chips';
import { MatListModule } from '@angular/material/list';
import { MatIconModule } from '@angular/material/icon';
import { StartFormComponent } from '../../../form';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
selector: 'adf-process-instance-tasks',
@@ -37,7 +38,7 @@ import { StartFormComponent } from '../../../form';
templateUrl: './process-instance-tasks.component.html',
styleUrls: ['./process-instance-tasks.component.css']
})
export class ProcessInstanceTasksComponent implements OnInit, OnChanges, OnDestroy {
export class ProcessInstanceTasksComponent implements OnInit, OnChanges {
/** The ID of the process instance to display tasks for. */
@Input()
processInstanceDetails: ProcessInstanceRepresentation;
@@ -72,7 +73,8 @@ export class ProcessInstanceTasksComponent implements OnInit, OnChanges, OnDestr
private taskObserver: Observer<TaskRepresentation>;
private completedTaskObserver: Observer<TaskRepresentation>;
private onDestroy$ = new Subject<boolean>();
private readonly destroyRef = inject(DestroyRef);
constructor(private processService: ProcessService, private dialog: MatDialog) {
this.task$ = new Observable<TaskRepresentation>((observer) => (this.taskObserver = observer)).pipe(share());
@@ -80,14 +82,9 @@ export class ProcessInstanceTasksComponent implements OnInit, OnChanges, OnDestr
}
ngOnInit() {
this.task$.pipe(takeUntil(this.onDestroy$)).subscribe((task) => this.activeTasks.push(task));
this.task$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((task) => this.activeTasks.push(task));
this.completedTask$.pipe(takeUntil(this.onDestroy$)).subscribe((task) => this.completedTasks.push(task));
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
this.completedTask$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((task) => this.completedTasks.push(task));
}
ngOnChanges(changes: SimpleChanges) {

View File

@@ -15,22 +15,40 @@
* limitations under the License.
*/
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild, ViewEncapsulation, OnDestroy } from '@angular/core';
import { AppConfigService, AppConfigValues, EmptyContentComponent, FormValues, LocalizedDatePipe } from '@alfresco/adf-core';
import {
Component,
DestroyRef,
EventEmitter,
inject,
Input,
OnChanges,
OnInit,
Output,
SimpleChanges,
ViewChild,
ViewEncapsulation
} from '@angular/core';
import {
AppConfigService,
AppConfigValues,
EmptyContentComponent,
FormValues,
LocalizedDatePipe
} from '@alfresco/adf-core';
import { AppsProcessService } from '../../../services/apps-process.service';
import { ProcessService } from '../../services/process.service';
import { UntypedFormControl, Validators, AbstractControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { Observable, Subject, forkJoin } from 'rxjs';
import { map, takeUntil } from 'rxjs/operators';
import { AbstractControl, FormsModule, ReactiveFormsModule, UntypedFormControl, Validators } from '@angular/forms';
import { forkJoin, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { MatAutocompleteModule, MatAutocompleteTrigger } from '@angular/material/autocomplete';
import { MatSelectChange, MatSelectModule } from '@angular/material/select';
import { StartFormComponent } from '../../../form';
import {
AppDefinitionRepresentation,
Node,
ProcessDefinitionRepresentation,
ProcessInstanceRepresentation,
RelatedContentRepresentation,
ProcessDefinitionRepresentation,
RestVariable
} from '@alfresco/js-api';
import { ActivitiContentService } from '../../../form/services/activiti-alfresco.service';
@@ -42,6 +60,7 @@ import { MatFormFieldModule } from '@angular/material/form-field';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
const MAX_LENGTH = 255;
const DATE_TIME_IDENTIFIER_REG_EXP = new RegExp('%{datetime}', 'i');
@@ -69,7 +88,7 @@ const PROCESS_DEFINITION_IDENTIFIER_REG_EXP = new RegExp('%{processdefinition}',
styleUrls: ['./start-process.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestroy {
export class StartProcessInstanceComponent implements OnChanges, OnInit {
/**
* Limit the list of processes that can be started to those
* contained in the specified app.
@@ -152,7 +171,7 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
isAppsLoading = true;
movedNodeToPS: FormValues;
private onDestroy$ = new Subject<boolean>();
private readonly destroyRef = inject(DestroyRef);
constructor(
private processService: ProcessService,
@@ -174,7 +193,7 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
this.filteredProcessesDefinitions$ = this.processDefinitionInput.valueChanges.pipe(
map((value) => this._filter(value)),
takeUntil(this.onDestroy$)
takeUntilDestroyed(this.destroyRef)
);
this.contentService.getAlfrescoRepositories().subscribe((repoList) => {
@@ -185,11 +204,6 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
});
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
ngOnChanges(changes: SimpleChanges) {
if (changes['values']?.currentValue) {
this.moveNodeFromCStoPS();

View File

@@ -23,7 +23,7 @@ describe('NoTaskDetailsTemplateDirective', () => {
let detailsComponent: TaskDetailsComponent;
beforeEach(() => {
detailsComponent = new TaskDetailsComponent(null, null, null, null);
detailsComponent = new TaskDetailsComponent(null, null, null, null, null);
component = new NoTaskDetailsTemplateDirective(detailsComponent);
});

View File

@@ -15,14 +15,21 @@
* limitations under the License.
*/
import { FormFieldModel, FormModel, DateFnsUtils, AdfDateFnsAdapter, ADF_DATE_FORMATS } from '@alfresco/adf-core';
import { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation, OnDestroy } from '@angular/core';
import { ADF_DATE_FORMATS, AdfDateFnsAdapter, DateFnsUtils, FormFieldModel, FormModel } from '@alfresco/adf-core';
import { Component, DestroyRef, EventEmitter, inject, Input, OnInit, Output, ViewEncapsulation } from '@angular/core';
import { DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core';
import { EMPTY, Observable, Subject } from 'rxjs';
import { EMPTY, Observable } from 'rxjs';
import { Form } from '../../models/form.model';
import { TaskListService } from '../../services/tasklist.service';
import { switchMap, defaultIfEmpty, takeUntil } from 'rxjs/operators';
import { UntypedFormBuilder, AbstractControl, Validators, UntypedFormGroup, UntypedFormControl, ReactiveFormsModule } from '@angular/forms';
import { defaultIfEmpty, switchMap } from 'rxjs/operators';
import {
AbstractControl,
ReactiveFormsModule,
UntypedFormBuilder,
UntypedFormControl,
UntypedFormGroup,
Validators
} from '@angular/forms';
import { isValid } from 'date-fns';
import { TaskRepresentation } from '@alfresco/js-api';
import { CommonModule } from '@angular/common';
@@ -35,6 +42,7 @@ import { MatIconModule } from '@angular/material/icon';
import { MatSelectModule } from '@angular/material/select';
import { MatButtonModule } from '@angular/material/button';
import { PeopleWidgetComponent } from '../../../form';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
const FORMAT_DATE = 'DD/MM/YYYY';
const MAX_LENGTH = 255;
@@ -63,7 +71,7 @@ const MAX_LENGTH = 255;
],
encapsulation: ViewEncapsulation.None
})
export class StartTaskComponent implements OnInit, OnDestroy {
export class StartTaskComponent implements OnInit {
/** (required) The id of the app. */
@Input()
appId: number;
@@ -93,7 +101,7 @@ export class StartTaskComponent implements OnInit, OnDestroy {
maxTaskNameLength: number = MAX_LENGTH;
loading = false;
private onDestroy$ = new Subject<boolean>();
private readonly destroyRef = inject(DestroyRef);
constructor(private taskService: TaskListService, private formBuilder: UntypedFormBuilder) {}
@@ -110,11 +118,6 @@ export class StartTaskComponent implements OnInit, OnDestroy {
this.buildForm();
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
buildForm(): void {
this.taskForm = this.formBuilder.group({
name: new UntypedFormControl(this.taskDetailsModel.name, [
@@ -126,7 +129,7 @@ export class StartTaskComponent implements OnInit, OnDestroy {
formKey: new UntypedFormControl('')
});
this.taskForm.valueChanges.pipe(takeUntil(this.onDestroy$)).subscribe((taskFormValues) => this.setTaskDetails(taskFormValues));
this.taskForm.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((taskFormValues) => this.setTaskDetails(taskFormValues));
}
private whitespaceValidator(control: UntypedFormControl): any {

View File

@@ -29,10 +29,10 @@ import {
} from '@alfresco/adf-core';
import {
Component,
DestroyRef,
EventEmitter,
Input,
OnChanges,
OnDestroy,
OnInit,
Output,
SimpleChanges,
@@ -41,9 +41,9 @@ import {
ViewEncapsulation
} from '@angular/core';
import { MatDialog, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { Observable, Observer, of, Subject } from 'rxjs';
import { Observable, Observer, of } from 'rxjs';
import { TaskListService } from '../../services/tasklist.service';
import { catchError, share, takeUntil } from 'rxjs/operators';
import { catchError, share } from 'rxjs/operators';
import { TaskFormComponent } from '../task-form/task-form.component';
import { PeopleProcessService } from '../../../services/people-process.service';
import { LightUserRepresentation, TaskQueryRepresentation, TaskRepresentation } from '@alfresco/js-api';
@@ -56,6 +56,7 @@ import { TaskCommentsComponent, TaskCommentsService } from '../../../task-commen
import { ChecklistComponent } from '../checklist/checklist.component';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
selector: 'adf-task-details',
@@ -86,7 +87,7 @@ import { MatCardModule } from '@angular/material/card';
styleUrls: ['./task-details.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class TaskDetailsComponent implements OnInit, OnChanges, OnDestroy {
export class TaskDetailsComponent implements OnInit, OnChanges {
@ViewChild('errorDialog')
errorDialog: TemplateRef<any>;
@@ -207,13 +208,13 @@ export class TaskDetailsComponent implements OnInit, OnChanges, OnDestroy {
data: any;
private peopleSearchObserver: Observer<LightUserRepresentation[]>;
private onDestroy$ = new Subject<boolean>();
constructor(
private taskListService: TaskListService,
private peopleProcessService: PeopleProcessService,
private cardViewUpdateService: CardViewUpdateService,
private dialog: MatDialog
private readonly taskListService: TaskListService,
private readonly peopleProcessService: PeopleProcessService,
private readonly cardViewUpdateService: CardViewUpdateService,
private readonly dialog: MatDialog,
private readonly destroyRef: DestroyRef
) {}
ngOnInit() {
@@ -223,14 +224,9 @@ export class TaskDetailsComponent implements OnInit, OnChanges, OnDestroy {
this.loadDetails(this.taskId);
}
this.cardViewUpdateService.itemUpdated$.pipe(takeUntil(this.onDestroy$)).subscribe(this.updateTaskDetails.bind(this));
this.cardViewUpdateService.itemUpdated$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(this.updateTaskDetails.bind(this));
this.cardViewUpdateService.itemClicked$.pipe(takeUntil(this.onDestroy$)).subscribe(this.clickTaskDetails.bind(this));
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
this.cardViewUpdateService.itemClicked$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(this.clickTaskDetails.bind(this));
}
ngOnChanges(changes: SimpleChanges): void {

View File

@@ -16,18 +16,18 @@
*/
import { AppsProcessService } from '../../../services/apps-process.service';
import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges, ViewEncapsulation } from '@angular/core';
import { Subject } from 'rxjs';
import { Component, DestroyRef, EventEmitter, inject, Input, OnChanges, OnInit, Output, SimpleChanges, ViewEncapsulation } from '@angular/core';
import { TaskFilterService } from '../../services/task-filter.service';
import { TaskListService } from '../../services/tasklist.service';
import { IconModel } from '../../../app-list/icon.model';
import { ActivatedRoute, NavigationStart, Router } from '@angular/router';
import { filter, takeUntil } from 'rxjs/operators';
import { filter } from 'rxjs/operators';
import { UserTaskFilterRepresentation } from '@alfresco/js-api';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { MatButtonModule } from '@angular/material/button';
import { IconComponent } from '@alfresco/adf-core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
@Component({
selector: 'adf-task-filters',
@@ -37,7 +37,7 @@ import { IconComponent } from '@alfresco/adf-core';
styleUrls: ['./task-filters.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class TaskFiltersComponent implements OnInit, OnChanges, OnDestroy {
export class TaskFiltersComponent implements OnInit, OnChanges {
/**
* Parameters to use for the task filter. If there is no match then
* the default filter (the first one the list) is selected.
@@ -76,12 +76,13 @@ export class TaskFiltersComponent implements OnInit, OnChanges, OnDestroy {
currentFilter: UserTaskFilterRepresentation;
filters: UserTaskFilterRepresentation[] = [];
private onDestroy$ = new Subject<boolean>();
isTaskRoute: boolean;
isTaskActive: boolean;
private iconsMDL: IconModel;
private readonly destroyRef = inject(DestroyRef);
constructor(
private taskFilterService: TaskFilterService,
private taskListService: TaskListService,
@@ -95,7 +96,7 @@ export class TaskFiltersComponent implements OnInit, OnChanges, OnDestroy {
this.router.events
.pipe(
filter((event) => event instanceof NavigationStart),
takeUntil(this.onDestroy$)
takeUntilDestroyed(this.destroyRef)
)
.subscribe((navigationStart: NavigationStart) => {
const activeRoute = navigationStart.url;
@@ -271,9 +272,4 @@ export class TaskFiltersComponent implements OnInit, OnChanges, OnDestroy {
this.filters = [];
this.currentFilter = undefined;
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
}

View File

@@ -90,10 +90,11 @@ export class TaskHeaderComponent implements OnChanges, OnInit {
dateLocale: string;
private currentUserId: number;
private readonly destroyRef = inject(DestroyRef);
private readonly usersSubject$ = new BehaviorSubject<CardViewSelectItemOption<number>[]>([]);
users$ = this.usersSubject$.asObservable();
private readonly destroyRef = inject(DestroyRef);
constructor(
private peopleProcessService: PeopleProcessService,
private translationService: TranslationService,

View File

@@ -16,32 +16,45 @@
*/
import {
DataRowEvent,
DataTableAdapter,
DataTableSchema,
AppConfigService,
CustomEmptyContentTemplateDirective,
CustomLoadingContentTemplateDirective,
AppConfigService,
PaginatedComponent,
UserPreferencesService,
UserPreferenceValues,
PaginationModel,
DataCellEvent,
DataRowEvent,
DataTableAdapter,
DataTableComponent,
DataTableSchema,
DEFAULT_PAGINATION,
EmptyContentComponent,
DataTableComponent,
LoadingContentTemplateDirective,
NoContentTemplateDirective
NoContentTemplateDirective,
PaginatedComponent,
PaginationModel,
UserPreferencesService,
UserPreferenceValues
} from '@alfresco/adf-core';
import { AfterContentInit, Component, ContentChild, EventEmitter, Input, OnChanges, Output, SimpleChanges, OnDestroy, OnInit } from '@angular/core';
import { BehaviorSubject, Subject } from 'rxjs';
import {
AfterContentInit,
Component,
ContentChild,
DestroyRef,
EventEmitter,
inject,
Input,
OnChanges,
OnInit,
Output,
SimpleChanges
} from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { taskPresetsDefaultModel } from '../../models/task-preset.model';
import { TaskListService } from '../../services/tasklist.service';
import { takeUntil, finalize } from 'rxjs/operators';
import { finalize } from 'rxjs/operators';
import { TaskQueryRepresentation, TaskRepresentation } from '@alfresco/js-api';
import { CommonModule } from '@angular/common';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { TranslateModule } from '@ngx-translate/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
export const PRESET_KEY = 'adf-task-list.presets';
@@ -60,7 +73,7 @@ export const PRESET_KEY = 'adf-task-list.presets';
templateUrl: './task-list.component.html',
styleUrls: ['./task-list.component.css']
})
export class TaskListComponent extends DataTableSchema implements OnChanges, AfterContentInit, PaginatedComponent, OnDestroy, OnInit {
export class TaskListComponent extends DataTableSchema implements OnChanges, AfterContentInit, PaginatedComponent, OnInit {
@ContentChild(CustomEmptyContentTemplateDirective)
customEmptyContent: CustomEmptyContentTemplateDirective;
@@ -212,7 +225,7 @@ export class TaskListComponent extends DataTableSchema implements OnChanges, Aft
*/
hasCustomDataSource: boolean = false;
private onDestroy$ = new Subject<boolean>();
private readonly destroyRef = inject(DestroyRef);
constructor(private taskListService: TaskListService, appConfigService: AppConfigService, private userPreferences: UserPreferencesService) {
super(appConfigService, PRESET_KEY, taskPresetsDefaultModel);
@@ -238,15 +251,10 @@ export class TaskListComponent extends DataTableSchema implements OnChanges, Aft
ngOnInit() {
this.userPreferences
.select(UserPreferenceValues.PaginationSize)
.pipe(takeUntil(this.onDestroy$))
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((pageSize) => (this.size = pageSize));
}
ngOnDestroy() {
this.onDestroy$.next(true);
this.onDestroy$.complete();
}
setCustomDataSource(rows: any[]): void {
if (rows) {
this.rows = rows;