mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-09-09 18:03:21 +00:00
[ADF-4745] memory leak fixes (#4931)
* fix app-layout component * fix card-view component * fix cloud-layout service * code fixes * code fixes * even more fixes * even more fixes * lint fixes * test fixes * fix code * remove useless pipes * fix code owners * enable spellcheck for cloud components * update test * update test
This commit is contained in:
committed by
Eugenio Romano
parent
e2311ab045
commit
1abb9bfc89
@@ -16,18 +16,18 @@
|
||||
*/
|
||||
|
||||
import { AppsProcessService, TranslationService, CustomEmptyContentTemplateDirective } from '@alfresco/adf-core';
|
||||
import { AfterContentInit, Component, EventEmitter, Input, OnInit, Output, ContentChild } from '@angular/core';
|
||||
import { Observable, Observer, of } from 'rxjs';
|
||||
import { AfterContentInit, Component, EventEmitter, Input, OnInit, Output, ContentChild, OnDestroy } from '@angular/core';
|
||||
import { Observable, Observer, of, Subject } from 'rxjs';
|
||||
import { AppDefinitionRepresentationModel } from '../task-list';
|
||||
import { IconModel } from './icon.model';
|
||||
import { share } from 'rxjs/operators';
|
||||
import { share, takeUntil } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-apps',
|
||||
templateUrl: 'apps-list.component.html',
|
||||
styleUrls: ['./apps-list.component.scss']
|
||||
})
|
||||
export class AppsListComponent implements OnInit, AfterContentInit {
|
||||
export class AppsListComponent implements OnInit, AfterContentInit, OnDestroy {
|
||||
|
||||
public static LAYOUT_LIST: string = 'LIST';
|
||||
public static LAYOUT_GRID: string = 'GRID';
|
||||
@@ -60,17 +60,16 @@ export class AppsListComponent implements OnInit, AfterContentInit {
|
||||
|
||||
private appsObserver: Observer<AppDefinitionRepresentationModel>;
|
||||
apps$: Observable<AppDefinitionRepresentationModel>;
|
||||
|
||||
currentApp: AppDefinitionRepresentationModel;
|
||||
|
||||
appList: AppDefinitionRepresentationModel [] = [];
|
||||
|
||||
private iconsMDL: IconModel;
|
||||
|
||||
loading: boolean = false;
|
||||
|
||||
hasEmptyCustomContentTemplate: boolean = false;
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
constructor(
|
||||
private appsProcessService: AppsProcessService,
|
||||
private translationService: TranslationService) {
|
||||
@@ -83,13 +82,19 @@ export class AppsListComponent implements OnInit, AfterContentInit {
|
||||
this.setDefaultLayoutType();
|
||||
}
|
||||
|
||||
this.apps$.subscribe((app: any) => {
|
||||
this.appList.push(app);
|
||||
});
|
||||
this.apps$
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe((app: any) => this.appList.push(app));
|
||||
|
||||
this.iconsMDL = new IconModel();
|
||||
this.load();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
|
||||
ngAfterContentInit() {
|
||||
if (this.emptyCustomContent) {
|
||||
this.hasEmptyCustomContentTemplate = true;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
/* tslint:disable:component-selector */
|
||||
|
||||
import { Component, ViewEncapsulation, OnInit } from '@angular/core';
|
||||
import { Component, ViewEncapsulation, OnInit, OnDestroy } from '@angular/core';
|
||||
import {
|
||||
UploadWidgetComponent,
|
||||
FormService,
|
||||
@@ -26,14 +26,13 @@ import {
|
||||
ProcessContentService,
|
||||
ActivitiContentService,
|
||||
ContentService,
|
||||
FormEvent,
|
||||
AppConfigValues,
|
||||
AppConfigService
|
||||
} from '@alfresco/adf-core';
|
||||
import { ContentNodeDialogService } from '@alfresco/adf-content-services';
|
||||
import { Node, RelatedContentRepresentation } from '@alfresco/js-api';
|
||||
import { from, zip, of } from 'rxjs';
|
||||
import { mergeMap } from 'rxjs/operators';
|
||||
import { from, zip, of, Subject } from 'rxjs';
|
||||
import { mergeMap, takeUntil } from 'rxjs/operators';
|
||||
import { AttachFileWidgetDialogService } from './attach-file-widget-dialog.service';
|
||||
|
||||
@Component({
|
||||
@@ -53,10 +52,11 @@ import { AttachFileWidgetDialogService } from './attach-file-widget-dialog.servi
|
||||
},
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class AttachFileWidgetComponent extends UploadWidgetComponent implements OnInit {
|
||||
export class AttachFileWidgetComponent extends UploadWidgetComponent implements OnInit, OnDestroy {
|
||||
|
||||
repositoryList = [];
|
||||
private tempFilesList = [];
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
constructor(public formService: FormService,
|
||||
private logger: LogService,
|
||||
@@ -82,11 +82,18 @@ export class AttachFileWidgetComponent extends UploadWidgetComponent implements
|
||||
this.repositoryList = repoList;
|
||||
});
|
||||
|
||||
this.formService.taskSaved.subscribe((formSaved: FormEvent) => {
|
||||
if (formSaved.form.id === this.field.form.id) {
|
||||
this.tempFilesList = [];
|
||||
}
|
||||
});
|
||||
this.formService.taskSaved
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe(formSaved => {
|
||||
if (formSaved.form.id === this.field.form.id) {
|
||||
this.tempFilesList = [];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
|
||||
isFileSourceConfigured(): boolean {
|
||||
|
||||
@@ -15,17 +15,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
Component, EventEmitter, Input, Output, ViewEncapsulation, SimpleChanges, OnInit, OnDestroy, OnChanges
|
||||
} from '@angular/core';
|
||||
import { Component, EventEmitter, Input, Output, ViewEncapsulation, SimpleChanges, OnInit, OnDestroy, OnChanges } from '@angular/core';
|
||||
import { AttachFileWidgetComponent, AttachFolderWidgetComponent } from '../content-widget';
|
||||
import { EcmModelService, NodeService, WidgetVisibilityService,
|
||||
FormService, FormRenderingService, FormBaseComponent, FormOutcomeModel,
|
||||
ValidateFormEvent, FormEvent, FormErrorEvent, FormFieldModel,
|
||||
FormEvent, FormErrorEvent, FormFieldModel,
|
||||
FormModel, FormOutcomeEvent, FormValues, ContentLinkModel } from '@alfresco/adf-core';
|
||||
|
||||
import { Observable, of, Subscription } from 'rxjs';
|
||||
import { switchMap } from 'rxjs/operators';
|
||||
import { Observable, of, Subject } from 'rxjs';
|
||||
import { switchMap, takeUntil } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-form',
|
||||
@@ -84,7 +81,7 @@ export class FormComponent extends FormBaseComponent implements OnInit, OnDestro
|
||||
|
||||
debugMode: boolean = false;
|
||||
|
||||
protected subscriptions: Subscription[] = [];
|
||||
protected onDestroy$ = new Subject<boolean>();
|
||||
|
||||
constructor(protected formService: FormService,
|
||||
protected visibilityService: WidgetVisibilityService,
|
||||
@@ -97,21 +94,22 @@ export class FormComponent extends FormBaseComponent implements OnInit, OnDestro
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.subscriptions.push(
|
||||
this.formService.formContentClicked.subscribe((content: ContentLinkModel) => {
|
||||
this.formContentClicked.emit(content);
|
||||
}),
|
||||
this.formService.validateForm.subscribe((validateFormEvent: ValidateFormEvent) => {
|
||||
this.formService.formContentClicked
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe(content => this.formContentClicked.emit(content));
|
||||
|
||||
this.formService.validateForm
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe(validateFormEvent => {
|
||||
if (validateFormEvent.errorsField.length > 0) {
|
||||
this.formError.next(validateFormEvent.errorsField);
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.subscriptions.forEach((subscription) => subscription.unsubscribe());
|
||||
this.subscriptions = [];
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
@@ -187,8 +185,8 @@ export class FormComponent extends FormBaseComponent implements OnInit, OnDestro
|
||||
}
|
||||
|
||||
getFormByTaskId(taskId: string): Promise<FormModel> {
|
||||
return new Promise<FormModel>((resolve, reject) => {
|
||||
this.findProcessVariablesByTaskId(taskId).subscribe((processVariables) => {
|
||||
return new Promise<FormModel>(resolve => {
|
||||
this.findProcessVariablesByTaskId(taskId).subscribe(() => {
|
||||
this.formService
|
||||
.getTaskForm(taskId)
|
||||
.subscribe(
|
||||
|
||||
@@ -29,7 +29,7 @@ import {
|
||||
OnDestroy
|
||||
} from '@angular/core';
|
||||
import { FormComponent } from './form.component';
|
||||
import { ContentLinkModel, FormService, WidgetVisibilityService, FormRenderingService, ValidateFormEvent, FormOutcomeModel } from '@alfresco/adf-core';
|
||||
import { ContentLinkModel, FormService, WidgetVisibilityService, FormRenderingService, FormOutcomeModel } from '@alfresco/adf-core';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-start-form',
|
||||
@@ -77,24 +77,6 @@ export class StartFormComponent extends FormComponent implements OnChanges, OnIn
|
||||
this.showTitle = false;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.subscriptions.push(
|
||||
this.formService.formContentClicked.subscribe((content) => {
|
||||
this.formContentClicked.emit(content);
|
||||
}),
|
||||
this.formService.validateForm.subscribe((validateFormEvent: ValidateFormEvent) => {
|
||||
if (validateFormEvent.errorsField.length > 0) {
|
||||
this.formError.next(validateFormEvent.errorsField);
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.subscriptions.forEach((subscription) => subscription.unsubscribe());
|
||||
this.subscriptions = [];
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
const processDefinitionId = changes['processDefinitionId'];
|
||||
if (processDefinitionId && processDefinitionId.currentValue) {
|
||||
|
||||
@@ -16,16 +16,16 @@
|
||||
*/
|
||||
|
||||
import { CommentModel, CommentProcessService } from '@alfresco/adf-core';
|
||||
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
|
||||
import { Observable, Observer } from 'rxjs';
|
||||
import { share } from 'rxjs/operators';
|
||||
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges, OnDestroy } from '@angular/core';
|
||||
import { Observable, Observer, Subject } from 'rxjs';
|
||||
import { share, takeUntil } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-process-instance-comments',
|
||||
templateUrl: './process-comments.component.html',
|
||||
styleUrls: ['./process-comments.component.scss']
|
||||
})
|
||||
export class ProcessCommentsComponent implements OnChanges {
|
||||
export class ProcessCommentsComponent implements OnChanges, OnDestroy {
|
||||
|
||||
/** (**required**) The numeric ID of the process instance to display comments for. */
|
||||
@Input()
|
||||
@@ -44,16 +44,22 @@ export class ProcessCommentsComponent implements OnChanges {
|
||||
private commentObserver: Observer<CommentModel>;
|
||||
comment$: Observable<CommentModel>;
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
message: string;
|
||||
|
||||
beingAdded: boolean = false;
|
||||
|
||||
constructor(private commentProcessService: CommentProcessService) {
|
||||
this.comment$ = new Observable<CommentModel>((observer) => this.commentObserver = observer)
|
||||
.pipe(share());
|
||||
this.comment$.subscribe((comment: CommentModel) => {
|
||||
this.comments.push(comment);
|
||||
});
|
||||
this.comment$ = new Observable<CommentModel>(observer => this.commentObserver = observer).pipe(share());
|
||||
this.comment$
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe(comment => this.comments.push(comment));
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
|
||||
@@ -17,20 +17,20 @@
|
||||
|
||||
import { LogService } from '@alfresco/adf-core';
|
||||
import { DatePipe } from '@angular/common';
|
||||
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild } from '@angular/core';
|
||||
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild, OnDestroy } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material';
|
||||
import { Observable, Observer } from 'rxjs';
|
||||
import { Observable, Observer, Subject } from 'rxjs';
|
||||
import { TaskDetailsEvent, TaskDetailsModel } from '../../task-list';
|
||||
import { ProcessInstance } from '../models/process-instance.model';
|
||||
import { ProcessService } from './../services/process.service';
|
||||
import { share } from 'rxjs/operators';
|
||||
import { share, takeUntil } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-process-instance-tasks',
|
||||
templateUrl: './process-instance-tasks.component.html',
|
||||
styleUrls: ['./process-instance-tasks.component.css']
|
||||
})
|
||||
export class ProcessInstanceTasksComponent implements OnInit, OnChanges {
|
||||
export class ProcessInstanceTasksComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
/** (**required**) The ID of the process instance to display tasks for. */
|
||||
@Input()
|
||||
@@ -51,10 +51,10 @@ export class ProcessInstanceTasksComponent implements OnInit, OnChanges {
|
||||
|
||||
private taskObserver: Observer<TaskDetailsModel>;
|
||||
private completedTaskObserver: Observer<TaskDetailsModel>;
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
task$: Observable<TaskDetailsModel>;
|
||||
completedTask$: Observable<TaskDetailsModel>;
|
||||
|
||||
message: string;
|
||||
processId: string;
|
||||
|
||||
@@ -78,12 +78,18 @@ export class ProcessInstanceTasksComponent implements OnInit, OnChanges {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.task$.subscribe((task: TaskDetailsModel) => {
|
||||
this.activeTasks.push(task);
|
||||
});
|
||||
this.completedTask$.subscribe((task: TaskDetailsModel) => {
|
||||
this.completedTasks.push(task);
|
||||
});
|
||||
this.task$
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.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();
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
import {
|
||||
Component, EventEmitter, Input, OnChanges, OnInit,
|
||||
Output, SimpleChanges, ViewChild, ViewEncapsulation
|
||||
Output, SimpleChanges, ViewChild, ViewEncapsulation, OnDestroy
|
||||
} from '@angular/core';
|
||||
import {
|
||||
ActivitiContentService, AppConfigService, AppConfigValues,
|
||||
@@ -28,8 +28,8 @@ import { ProcessDefinitionRepresentation } from './../models/process-definition.
|
||||
import { ProcessInstance } from './../models/process-instance.model';
|
||||
import { ProcessService } from './../services/process.service';
|
||||
import { FormControl, Validators, AbstractControl } from '@angular/forms';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { map, takeUntil } from 'rxjs/operators';
|
||||
import { MatAutocompleteTrigger } from '@angular/material';
|
||||
import { StartFormComponent } from '../../form';
|
||||
|
||||
@@ -39,7 +39,7 @@ import { StartFormComponent } from '../../form';
|
||||
styleUrls: ['./start-process.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class StartProcessInstanceComponent implements OnChanges, OnInit {
|
||||
export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestroy {
|
||||
|
||||
MAX_LENGTH: number = 255;
|
||||
|
||||
@@ -101,6 +101,8 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit {
|
||||
filteredProcesses: Observable<ProcessDefinitionRepresentation[]>;
|
||||
maxProcessNameLength: number = this.MAX_LENGTH;
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
constructor(private activitiProcess: ProcessService,
|
||||
private activitiContentService: ActivitiContentService,
|
||||
private appConfig: AppConfigService) {
|
||||
@@ -112,13 +114,22 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit {
|
||||
|
||||
this.loadStartProcess();
|
||||
|
||||
this.processNameInput.valueChanges.subscribe((name) => this.name = name);
|
||||
this.processNameInput.valueChanges
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe(name => this.name = name);
|
||||
|
||||
this.filteredProcesses = this.processDefinitionInput.valueChanges
|
||||
.pipe(
|
||||
map((value) => this._filter(value))
|
||||
map((value) => this._filter(value)),
|
||||
takeUntil(this.onDestroy$)
|
||||
);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if (changes['values'] && changes['values'].currentValue) {
|
||||
this.moveNodeFromCStoPS();
|
||||
|
||||
@@ -16,16 +16,16 @@
|
||||
*/
|
||||
|
||||
import { LogService, UserPreferencesService, UserPreferenceValues, UserProcessModel, FormFieldModel, FormModel } from '@alfresco/adf-core';
|
||||
import { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation } from '@angular/core';
|
||||
import { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation, OnDestroy } from '@angular/core';
|
||||
import { DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core';
|
||||
import { MOMENT_DATE_FORMATS, MomentDateAdapter } from '@alfresco/adf-core';
|
||||
import moment from 'moment-es6';
|
||||
import { Moment } from 'moment';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { Observable, of, Subject } from 'rxjs';
|
||||
import { Form } from '../models/form.model';
|
||||
import { TaskDetailsModel } from '../models/task-details.model';
|
||||
import { TaskListService } from './../services/tasklist.service';
|
||||
import { switchMap, defaultIfEmpty } from 'rxjs/operators';
|
||||
import { switchMap, defaultIfEmpty, takeUntil } from 'rxjs/operators';
|
||||
import { FormBuilder, AbstractControl, Validators, FormGroup, FormControl } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
@@ -37,7 +37,7 @@ import { FormBuilder, AbstractControl, Validators, FormGroup, FormControl } from
|
||||
{ provide: MAT_DATE_FORMATS, useValue: MOMENT_DATE_FORMATS }],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class StartTaskComponent implements OnInit {
|
||||
export class StartTaskComponent implements OnInit, OnDestroy {
|
||||
|
||||
public FORMAT_DATE: string = 'DD/MM/YYYY';
|
||||
MAX_LENGTH: number = 255;
|
||||
@@ -71,6 +71,8 @@ export class StartTaskComponent implements OnInit {
|
||||
maxTaskNameLength: number = this.MAX_LENGTH;
|
||||
loading = false;
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param auth
|
||||
@@ -92,14 +94,21 @@ export class StartTaskComponent implements OnInit {
|
||||
this.validateMaxTaskNameLength();
|
||||
|
||||
this.field = new FormFieldModel(new FormModel(), { id: this.assigneeId, value: this.assigneeId, placeholder: 'Assignee' });
|
||||
this.userPreferencesService.select(UserPreferenceValues.Locale).subscribe((locale) => {
|
||||
this.dateAdapter.setLocale(locale);
|
||||
});
|
||||
|
||||
this.userPreferencesService
|
||||
.select(UserPreferenceValues.Locale)
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe(locale => this.dateAdapter.setLocale(locale));
|
||||
|
||||
this.loadFormsTask();
|
||||
this.buildForm();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
|
||||
buildForm() {
|
||||
this.taskForm = this.formBuilder.group({
|
||||
name: new FormControl(this.taskDetailsModel.name, [Validators.required, Validators.maxLength(this.maxTaskNameLength), this.whitespaceValidator]),
|
||||
@@ -107,7 +116,9 @@ export class StartTaskComponent implements OnInit {
|
||||
formKey: new FormControl('')
|
||||
});
|
||||
|
||||
this.taskForm.valueChanges.subscribe((taskFormValues) => this.setTaskDetails(taskFormValues));
|
||||
this.taskForm.valueChanges
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe(taskFormValues => this.setTaskDetails(taskFormValues));
|
||||
}
|
||||
|
||||
public whitespaceValidator(control: FormControl) {
|
||||
|
||||
@@ -33,23 +33,24 @@ import {
|
||||
Output,
|
||||
SimpleChanges,
|
||||
TemplateRef,
|
||||
ViewChild
|
||||
ViewChild,
|
||||
OnDestroy
|
||||
} from '@angular/core';
|
||||
import { MatDialog, MatDialogRef } from '@angular/material';
|
||||
import { Observable, Observer } from 'rxjs';
|
||||
import { Observable, Observer, Subject } from 'rxjs';
|
||||
import { ContentLinkModel, FormFieldValidator, FormModel, FormOutcomeEvent } from '@alfresco/adf-core';
|
||||
import { TaskQueryRequestRepresentationModel } from '../models/filter.model';
|
||||
import { TaskDetailsModel } from '../models/task-details.model';
|
||||
import { TaskListService } from './../services/tasklist.service';
|
||||
import { UserRepresentation } from '@alfresco/js-api';
|
||||
import { share } from 'rxjs/operators';
|
||||
import { share, takeUntil } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-task-details',
|
||||
templateUrl: './task-details.component.html',
|
||||
styleUrls: ['./task-details.component.scss']
|
||||
})
|
||||
export class TaskDetailsComponent implements OnInit, OnChanges {
|
||||
export class TaskDetailsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
@ViewChild('activitiComments')
|
||||
activitiComments: CommentsComponent;
|
||||
@@ -166,17 +167,15 @@ export class TaskDetailsComponent implements OnInit, OnChanges {
|
||||
|
||||
taskDetails: TaskDetailsModel;
|
||||
taskFormName: string = null;
|
||||
|
||||
taskPeople: UserProcessModel[] = [];
|
||||
|
||||
noTaskDetailsTemplateComponent: TemplateRef<any>;
|
||||
|
||||
showAssignee: boolean = false;
|
||||
showAttachForm: boolean = false;
|
||||
internalReadOnlyForm: boolean = false;
|
||||
|
||||
private peopleSearchObserver: Observer<UserProcessModel[]>;
|
||||
public errorDialogRef: MatDialogRef<TemplateRef<any>>;
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
peopleSearch: Observable<UserProcessModel[]>;
|
||||
|
||||
@@ -189,21 +188,30 @@ export class TaskDetailsComponent implements OnInit, OnChanges {
|
||||
private logService: LogService,
|
||||
private cardViewUpdateService: CardViewUpdateService,
|
||||
private dialog: MatDialog) {
|
||||
|
||||
this.peopleSearch = new Observable<UserProcessModel[]>((observer) => this.peopleSearchObserver = observer)
|
||||
.pipe(share());
|
||||
this.authService.getBpmLoggedUser().subscribe((user: UserRepresentation) => {
|
||||
this.currentLoggedUser = user;
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.peopleSearch = new Observable<UserProcessModel[]>((observer) => this.peopleSearchObserver = observer).pipe(share());
|
||||
this.authService.getBpmLoggedUser().subscribe(user => {
|
||||
this.currentLoggedUser = user;
|
||||
});
|
||||
|
||||
if (this.taskId) {
|
||||
this.loadDetails(this.taskId);
|
||||
}
|
||||
|
||||
this.cardViewUpdateService.itemUpdated$.subscribe(this.updateTaskDetails.bind(this));
|
||||
this.cardViewUpdateService.itemClicked$.subscribe(this.clickTaskDetails.bind(this));
|
||||
this.cardViewUpdateService.itemUpdated$
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.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();
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
@@ -265,12 +273,9 @@ export class TaskDetailsComponent implements OnInit, OnChanges {
|
||||
* @param updateNotification
|
||||
*/
|
||||
private updateTaskDetails(updateNotification: UpdateNotification) {
|
||||
this.taskListService.updateTask(this.taskId, updateNotification.changed)
|
||||
.subscribe(
|
||||
() => {
|
||||
this.loadDetails(this.taskId);
|
||||
}
|
||||
);
|
||||
this.taskListService
|
||||
.updateTask(this.taskId, updateNotification.changed)
|
||||
.subscribe(() => this.loadDetails(this.taskId));
|
||||
}
|
||||
|
||||
private clickTaskDetails(clickNotification: ClickNotification) {
|
||||
@@ -386,9 +391,9 @@ export class TaskDetailsComponent implements OnInit, OnChanges {
|
||||
* Complete button clicked
|
||||
*/
|
||||
onComplete(): void {
|
||||
this.taskListService.completeTask(this.taskId).subscribe(
|
||||
(res) => this.onFormCompleted(null)
|
||||
);
|
||||
this.taskListService
|
||||
.completeTask(this.taskId)
|
||||
.subscribe(() => this.onFormCompleted(null));
|
||||
}
|
||||
|
||||
onShowAttachForm() {
|
||||
@@ -461,10 +466,13 @@ export class TaskDetailsComponent implements OnInit, OnChanges {
|
||||
|
||||
searchUser(searchedWord: string) {
|
||||
this.peopleProcessService.getWorkflowUsers(null, searchedWord)
|
||||
.subscribe((users) => {
|
||||
users = users.filter((user) => user.id !== this.taskDetails.assignee.id);
|
||||
this.peopleSearchObserver.next(users);
|
||||
}, (error) => this.logService.error('Could not load users'));
|
||||
.subscribe(
|
||||
users => {
|
||||
users = users.filter((user) => user.id !== this.taskDetails.assignee.id);
|
||||
this.peopleSearchObserver.next(users);
|
||||
},
|
||||
() => this.logService.error('Could not load users')
|
||||
);
|
||||
}
|
||||
|
||||
onCloseSearch() {
|
||||
@@ -472,8 +480,9 @@ export class TaskDetailsComponent implements OnInit, OnChanges {
|
||||
}
|
||||
|
||||
assignTaskToUser(selectedUser: UserProcessModel) {
|
||||
this.taskListService.assignTask(this.taskDetails.id, selectedUser).subscribe(
|
||||
(res: any) => {
|
||||
this.taskListService
|
||||
.assignTask(this.taskDetails.id, selectedUser)
|
||||
.subscribe(() => {
|
||||
this.logService.info('Task Assigned to ' + selectedUser.email);
|
||||
this.assignTask.emit();
|
||||
});
|
||||
|
||||
@@ -285,11 +285,10 @@ export class TaskHeaderComponent implements OnChanges, OnInit {
|
||||
* @param taskId
|
||||
*/
|
||||
claimTask(taskId: string) {
|
||||
this.activitiTaskService.claimTask(taskId).subscribe(
|
||||
(res: any) => {
|
||||
this.logService.info('Task claimed');
|
||||
this.claim.emit(taskId);
|
||||
});
|
||||
this.activitiTaskService.claimTask(taskId).subscribe(() => {
|
||||
this.logService.info('Task claimed');
|
||||
this.claim.emit(taskId);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -298,11 +297,10 @@ export class TaskHeaderComponent implements OnChanges, OnInit {
|
||||
* @param taskId
|
||||
*/
|
||||
unclaimTask(taskId: string) {
|
||||
this.activitiTaskService.unclaimTask(taskId).subscribe(
|
||||
(res: any) => {
|
||||
this.logService.info('Task unclaimed');
|
||||
this.unclaim.emit(taskId);
|
||||
});
|
||||
this.activitiTaskService.unclaimTask(taskId).subscribe(() => {
|
||||
this.logService.info('Task unclaimed');
|
||||
this.unclaim.emit(taskId);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,21 +21,22 @@ import {
|
||||
UserPreferencesService, UserPreferenceValues, PaginationModel } from '@alfresco/adf-core';
|
||||
import {
|
||||
AfterContentInit, Component, ContentChild, EventEmitter,
|
||||
Input, OnChanges, Output, SimpleChanges } from '@angular/core';
|
||||
Input, OnChanges, Output, SimpleChanges, OnDestroy, OnInit } from '@angular/core';
|
||||
|
||||
import { Observable, BehaviorSubject } from 'rxjs';
|
||||
import { Observable, BehaviorSubject, Subject } from 'rxjs';
|
||||
import { TaskQueryRequestRepresentationModel } from '../models/filter.model';
|
||||
import { TaskListModel } from '../models/task-list.model';
|
||||
import { taskPresetsDefaultModel } from '../models/task-preset.model';
|
||||
import { TaskListService } from './../services/tasklist.service';
|
||||
import moment from 'moment-es6';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-tasklist',
|
||||
templateUrl: './task-list.component.html',
|
||||
styleUrls: ['./task-list.component.css']
|
||||
})
|
||||
export class TaskListComponent extends DataTableSchema implements OnChanges, AfterContentInit, PaginatedComponent {
|
||||
export class TaskListComponent extends DataTableSchema implements OnChanges, AfterContentInit, PaginatedComponent, OnDestroy, OnInit {
|
||||
|
||||
static PRESET_KEY = 'adf-task-list.presets';
|
||||
|
||||
@@ -170,13 +171,12 @@ export class TaskListComponent extends DataTableSchema implements OnChanges, Aft
|
||||
*/
|
||||
hasCustomDataSource: boolean = false;
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
constructor(private taskListService: TaskListService,
|
||||
appConfigService: AppConfigService,
|
||||
private userPreferences: UserPreferencesService) {
|
||||
super(appConfigService, TaskListComponent.PRESET_KEY, taskPresetsDefaultModel);
|
||||
this.userPreferences.select(UserPreferenceValues.PaginationSize).subscribe((pageSize) => {
|
||||
this.size = pageSize;
|
||||
});
|
||||
|
||||
this.pagination = new BehaviorSubject<PaginationModel>(<PaginationModel> {
|
||||
maxItems: this.size,
|
||||
@@ -196,6 +196,18 @@ export class TaskListComponent extends DataTableSchema implements OnChanges, Aft
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.userPreferences
|
||||
.select(UserPreferenceValues.PaginationSize)
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe(pageSize => this.size = pageSize);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy$.next(true);
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
|
||||
setCustomDataSource(rows: any[]): void {
|
||||
if (rows) {
|
||||
this.rows = rows;
|
||||
|
||||
Reference in New Issue
Block a user