mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-10-08 14:51:32 +00:00
[ACS-5991] ESLint fixes and code quality improvements (#8893)
* prefer-optional-chain: core * prefer-optional-chain: content, fix typings * prefer-optional-chain: process, fix typings * prefer-optional-chain: process-cloud, fix typings, fix ts configs and eslint * [ci: force] sonar errors fixes, insights lib * [ci:force] fix security issues * [ci:force] fix metadata e2e bug, js assignment bugs * [ci:force] fix lint issue * [ci:force] fix tests
This commit is contained in:
@@ -24,7 +24,6 @@ import { ProcessContentService } from '../form/services/process-content.service'
|
||||
templateUrl: './create-process-attachment.component.html'
|
||||
})
|
||||
export class CreateProcessAttachmentComponent implements OnChanges {
|
||||
|
||||
/** (required) The ID of the process instance to display. */
|
||||
@Input()
|
||||
processInstanceId: string;
|
||||
@@ -41,11 +40,10 @@ export class CreateProcessAttachmentComponent implements OnChanges {
|
||||
@Output()
|
||||
success: EventEmitter<any> = new EventEmitter<any>();
|
||||
|
||||
constructor(private activitiContentService: ProcessContentService) {
|
||||
}
|
||||
constructor(private activitiContentService: ProcessContentService) {}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if (changes['processInstanceId'] && changes['processInstanceId'].currentValue) {
|
||||
if (changes['processInstanceId']?.currentValue) {
|
||||
this.processInstanceId = changes['processInstanceId'].currentValue;
|
||||
}
|
||||
}
|
||||
@@ -64,7 +62,8 @@ export class CreateProcessAttachmentComponent implements OnChanges {
|
||||
},
|
||||
(err) => {
|
||||
this.error.emit(err);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -24,7 +24,6 @@ import { ProcessContentService } from '../form/services/process-content.service'
|
||||
templateUrl: './create-task-attachment.component.html'
|
||||
})
|
||||
export class AttachmentComponent implements OnChanges {
|
||||
|
||||
/** (required) The numeric ID of the task to display. */
|
||||
@Input()
|
||||
taskId: string;
|
||||
@@ -39,13 +38,12 @@ export class AttachmentComponent implements OnChanges {
|
||||
* from within the component.
|
||||
*/
|
||||
@Output()
|
||||
success: EventEmitter<any> = new EventEmitter<any>();
|
||||
success = new EventEmitter<any>();
|
||||
|
||||
constructor(private activitiContentService: ProcessContentService) {
|
||||
}
|
||||
constructor(private activitiContentService: ProcessContentService) {}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if (changes['taskId'] && changes['taskId'].currentValue) {
|
||||
if (changes['taskId']?.currentValue) {
|
||||
this.taskId = changes['taskId'].currentValue;
|
||||
}
|
||||
}
|
||||
|
@@ -37,7 +37,6 @@ import { ProcessContentService } from '../form/services/process-content.service'
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class ProcessAttachmentListComponent implements OnChanges, AfterContentInit {
|
||||
|
||||
@ContentChild(EmptyListComponent)
|
||||
emptyTemplate: EmptyListComponent;
|
||||
|
||||
@@ -74,14 +73,15 @@ export class ProcessAttachmentListComponent implements OnChanges, AfterContentIn
|
||||
attachments: any[] = [];
|
||||
isLoading: boolean = false;
|
||||
|
||||
constructor(private activitiContentService: ProcessContentService,
|
||||
private downloadService: DownloadService,
|
||||
private thumbnailService: ThumbnailService,
|
||||
private ngZone: NgZone) {
|
||||
}
|
||||
constructor(
|
||||
private activitiContentService: ProcessContentService,
|
||||
private downloadService: DownloadService,
|
||||
private thumbnailService: ThumbnailService,
|
||||
private ngZone: NgZone
|
||||
) {}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if (changes['processInstanceId'] && changes['processInstanceId'].currentValue) {
|
||||
if (changes['processInstanceId']?.currentValue) {
|
||||
this.loadAttachmentsByProcessInstanceId(changes['processInstanceId'].currentValue);
|
||||
}
|
||||
}
|
||||
@@ -119,7 +119,7 @@ export class ProcessAttachmentListComponent implements OnChanges, AfterContentIn
|
||||
}
|
||||
|
||||
isEmpty(): boolean {
|
||||
return this.attachments && this.attachments.length === 0;
|
||||
return this.attachments?.length === 0;
|
||||
}
|
||||
|
||||
onShowRowActionsMenu(event: any) {
|
||||
@@ -138,10 +138,7 @@ export class ProcessAttachmentListComponent implements OnChanges, AfterContentIn
|
||||
name: 'download'
|
||||
};
|
||||
|
||||
event.value.actions = [
|
||||
viewAction,
|
||||
downloadAction
|
||||
];
|
||||
event.value.actions = [viewAction, downloadAction];
|
||||
|
||||
if (!this.disabled) {
|
||||
event.value.actions.splice(1, 0, removeAction);
|
||||
@@ -212,7 +209,8 @@ export class ProcessAttachmentListComponent implements OnChanges, AfterContentIn
|
||||
(err) => {
|
||||
this.error.emit(err);
|
||||
this.isLoading = false;
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,7 +222,8 @@ export class ProcessAttachmentListComponent implements OnChanges, AfterContentIn
|
||||
},
|
||||
(err) => {
|
||||
this.error.emit(err);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -37,7 +37,6 @@ import { ProcessContentService } from '../form/services/process-content.service'
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class TaskAttachmentListComponent implements OnChanges, AfterContentInit {
|
||||
|
||||
@ContentChild(EmptyListComponent)
|
||||
emptyTemplate: EmptyListComponent;
|
||||
|
||||
@@ -71,14 +70,15 @@ export class TaskAttachmentListComponent implements OnChanges, AfterContentInit
|
||||
attachments: any[] = [];
|
||||
isLoading: boolean = false;
|
||||
|
||||
constructor(private activitiContentService: ProcessContentService,
|
||||
private downloadService: DownloadService,
|
||||
private thumbnailService: ThumbnailService,
|
||||
private ngZone: NgZone) {
|
||||
}
|
||||
constructor(
|
||||
private activitiContentService: ProcessContentService,
|
||||
private downloadService: DownloadService,
|
||||
private thumbnailService: ThumbnailService,
|
||||
private ngZone: NgZone
|
||||
) {}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if (changes['taskId'] && changes['taskId'].currentValue) {
|
||||
if (changes['taskId']?.currentValue) {
|
||||
this.loadAttachmentsByTaskId(changes['taskId'].currentValue);
|
||||
}
|
||||
}
|
||||
@@ -123,7 +123,8 @@ export class TaskAttachmentListComponent implements OnChanges, AfterContentInit
|
||||
},
|
||||
(err) => {
|
||||
this.error.emit(err);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,10 +148,7 @@ export class TaskAttachmentListComponent implements OnChanges, AfterContentInit
|
||||
name: 'download'
|
||||
};
|
||||
|
||||
event.value.actions = [
|
||||
viewAction,
|
||||
downloadAction
|
||||
];
|
||||
event.value.actions = [viewAction, downloadAction];
|
||||
|
||||
if (!this.disabled) {
|
||||
event.value.actions.splice(1, 0, removeAction);
|
||||
@@ -223,7 +221,8 @@ export class TaskAttachmentListComponent implements OnChanges, AfterContentInit
|
||||
(err) => {
|
||||
this.error.emit(err);
|
||||
this.isLoading = false;
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -15,18 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
Output,
|
||||
ViewEncapsulation,
|
||||
SimpleChanges,
|
||||
OnInit,
|
||||
OnDestroy,
|
||||
OnChanges,
|
||||
inject
|
||||
} from '@angular/core';
|
||||
import { Component, EventEmitter, Input, Output, ViewEncapsulation, SimpleChanges, OnInit, OnDestroy, OnChanges, inject } from '@angular/core';
|
||||
import {
|
||||
WidgetVisibilityService,
|
||||
FormService,
|
||||
@@ -48,7 +37,6 @@ import { ModelService } from './services/model.service';
|
||||
import { EditorService } from './services/editor.service';
|
||||
import { TaskService } from './services/task.service';
|
||||
import { TaskFormService } from './services/task-form.service';
|
||||
import { TaskRepresentation } from '@alfresco/js-api';
|
||||
import { NodesApiService } from '@alfresco/adf-content-services';
|
||||
import { FormDefinitionModel } from './model/form-definition.model';
|
||||
|
||||
@@ -128,17 +116,13 @@ export class FormComponent extends FormBaseComponent implements OnInit, OnDestro
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.formService.formContentClicked
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe(content => this.formContentClicked.emit(content));
|
||||
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);
|
||||
}
|
||||
});
|
||||
this.formService.validateForm.pipe(takeUntil(this.onDestroy$)).subscribe((validateFormEvent) => {
|
||||
if (validateFormEvent.errorsField.length > 0) {
|
||||
this.formError.next(validateFormEvent.errorsField);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
@@ -148,31 +132,31 @@ export class FormComponent extends FormBaseComponent implements OnInit, OnDestro
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
const taskId = changes['taskId'];
|
||||
if (taskId && taskId.currentValue) {
|
||||
if (taskId?.currentValue) {
|
||||
this.getFormByTaskId(taskId.currentValue);
|
||||
return;
|
||||
}
|
||||
|
||||
const formId = changes['formId'];
|
||||
if (formId && formId.currentValue) {
|
||||
if (formId?.currentValue) {
|
||||
this.getFormDefinitionByFormId(formId.currentValue);
|
||||
return;
|
||||
}
|
||||
|
||||
const formName = changes['formName'];
|
||||
if (formName && formName.currentValue) {
|
||||
if (formName?.currentValue) {
|
||||
this.getFormDefinitionByFormName(formName.currentValue);
|
||||
return;
|
||||
}
|
||||
|
||||
const nodeId = changes['nodeId'];
|
||||
if (nodeId && nodeId.currentValue) {
|
||||
if (nodeId?.currentValue) {
|
||||
this.loadFormForEcmNode(nodeId.currentValue);
|
||||
return;
|
||||
}
|
||||
|
||||
const data = changes['data'];
|
||||
if (data && data.currentValue) {
|
||||
if (data?.currentValue) {
|
||||
this.refreshFormData();
|
||||
return;
|
||||
}
|
||||
@@ -204,7 +188,7 @@ export class FormComponent extends FormBaseComponent implements OnInit, OnDestro
|
||||
|
||||
findProcessVariablesByTaskId(taskId: string): Observable<TaskProcessVariableModel[]> {
|
||||
return this.taskService.getTask(taskId).pipe(
|
||||
switchMap((task: TaskRepresentation) => {
|
||||
switchMap((task) => {
|
||||
if (this.isAProcessTask(task)) {
|
||||
return this.taskFormService.getTaskProcessVariable(taskId);
|
||||
} else {
|
||||
@@ -219,93 +203,83 @@ export class FormComponent extends FormBaseComponent implements OnInit, OnDestro
|
||||
}
|
||||
|
||||
getFormByTaskId(taskId: string): Promise<FormModel> {
|
||||
return new Promise<FormModel>(resolve => {
|
||||
return new Promise<FormModel>((resolve) => {
|
||||
this.findProcessVariablesByTaskId(taskId).subscribe((taskProcessVariables) => {
|
||||
this.taskFormService
|
||||
.getTaskForm(taskId)
|
||||
.subscribe(
|
||||
(form) => {
|
||||
const parsedForm = this.parseForm(form);
|
||||
this.visibilityService.refreshVisibility(parsedForm, taskProcessVariables);
|
||||
parsedForm.validateForm();
|
||||
this.form = parsedForm;
|
||||
this.onFormLoaded(this.form);
|
||||
resolve(this.form);
|
||||
},
|
||||
(error) => {
|
||||
this.handleError(error);
|
||||
resolve(null);
|
||||
}
|
||||
);
|
||||
this.taskFormService.getTaskForm(taskId).subscribe(
|
||||
(form) => {
|
||||
const parsedForm = this.parseForm(form);
|
||||
this.visibilityService.refreshVisibility(parsedForm, taskProcessVariables);
|
||||
parsedForm.validateForm();
|
||||
this.form = parsedForm;
|
||||
this.onFormLoaded(this.form);
|
||||
resolve(this.form);
|
||||
},
|
||||
(error) => {
|
||||
this.handleError(error);
|
||||
resolve(null);
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getFormDefinitionByFormId(formId: number) {
|
||||
this.editorService
|
||||
.getFormDefinitionById(formId)
|
||||
.subscribe(
|
||||
(form) => {
|
||||
this.formName = form.name;
|
||||
this.form = this.parseForm(form);
|
||||
this.visibilityService.refreshVisibility(this.form);
|
||||
this.form.validateForm();
|
||||
this.onFormLoaded(this.form);
|
||||
},
|
||||
(error) => {
|
||||
this.handleError(error);
|
||||
}
|
||||
);
|
||||
this.editorService.getFormDefinitionById(formId).subscribe(
|
||||
(form) => {
|
||||
this.formName = form.name;
|
||||
this.form = this.parseForm(form);
|
||||
this.visibilityService.refreshVisibility(this.form);
|
||||
this.form.validateForm();
|
||||
this.onFormLoaded(this.form);
|
||||
},
|
||||
(error) => {
|
||||
this.handleError(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
getFormDefinitionByFormName(formName: string) {
|
||||
this.modelService
|
||||
.getFormDefinitionByName(formName)
|
||||
.subscribe(
|
||||
(id) => {
|
||||
this.editorService.getFormDefinitionById(id).subscribe(
|
||||
(form) => {
|
||||
this.form = this.parseForm(form);
|
||||
this.visibilityService.refreshVisibility(this.form);
|
||||
this.form.validateForm();
|
||||
this.onFormLoaded(this.form);
|
||||
},
|
||||
(error) => {
|
||||
this.handleError(error);
|
||||
}
|
||||
);
|
||||
},
|
||||
(error) => {
|
||||
this.handleError(error);
|
||||
}
|
||||
);
|
||||
this.modelService.getFormDefinitionByName(formName).subscribe(
|
||||
(id) => {
|
||||
this.editorService.getFormDefinitionById(id).subscribe(
|
||||
(form) => {
|
||||
this.form = this.parseForm(form);
|
||||
this.visibilityService.refreshVisibility(this.form);
|
||||
this.form.validateForm();
|
||||
this.onFormLoaded(this.form);
|
||||
},
|
||||
(error) => {
|
||||
this.handleError(error);
|
||||
}
|
||||
);
|
||||
},
|
||||
(error) => {
|
||||
this.handleError(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
saveTaskForm() {
|
||||
if (this.form && this.form.taskId) {
|
||||
this.taskFormService
|
||||
.saveTaskForm(this.form.taskId, this.form.values)
|
||||
.subscribe(
|
||||
() => {
|
||||
this.onTaskSaved(this.form);
|
||||
this.storeFormAsMetadata();
|
||||
},
|
||||
(error) => this.onTaskSavedError(this.form, error)
|
||||
);
|
||||
if (this.form?.taskId) {
|
||||
this.taskFormService.saveTaskForm(this.form.taskId, this.form.values).subscribe(
|
||||
() => {
|
||||
this.onTaskSaved(this.form);
|
||||
this.storeFormAsMetadata();
|
||||
},
|
||||
(error) => this.onTaskSavedError(this.form, error)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
completeTaskForm(outcome?: string) {
|
||||
if (this.form && this.form.taskId) {
|
||||
this.taskFormService
|
||||
.completeTaskForm(this.form.taskId, this.form.values, outcome)
|
||||
.subscribe(
|
||||
() => {
|
||||
this.onTaskCompleted(this.form);
|
||||
this.storeFormAsMetadata();
|
||||
},
|
||||
(error) => this.onTaskCompletedError(this.form, error)
|
||||
);
|
||||
if (this.form?.taskId) {
|
||||
this.taskFormService.completeTaskForm(this.form.taskId, this.form.values, outcome).subscribe(
|
||||
() => {
|
||||
this.onTaskCompleted(this.form);
|
||||
this.storeFormAsMetadata();
|
||||
},
|
||||
(error) => this.onTaskCompletedError(this.form, error)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -319,7 +293,7 @@ export class FormComponent extends FormBaseComponent implements OnInit, OnDestro
|
||||
if (!formRepresentationJSON.fields) {
|
||||
form.outcomes = this.getFormDefinitionOutcomes(form);
|
||||
}
|
||||
if (this.fieldValidators && this.fieldValidators.length > 0) {
|
||||
if (this.fieldValidators?.length > 0) {
|
||||
form.fieldValidators = this.fieldValidators;
|
||||
}
|
||||
return form;
|
||||
@@ -333,13 +307,11 @@ export class FormComponent extends FormBaseComponent implements OnInit, OnDestro
|
||||
* @param form Form definition model.
|
||||
*/
|
||||
getFormDefinitionOutcomes(form: FormModel): FormOutcomeModel[] {
|
||||
return [
|
||||
new FormOutcomeModel(form, {id: '$save', name: FormOutcomeModel.SAVE_ACTION, isSystem: true})
|
||||
];
|
||||
return [new FormOutcomeModel(form, { id: '$save', name: FormOutcomeModel.SAVE_ACTION, isSystem: true })];
|
||||
}
|
||||
|
||||
checkVisibility(field: FormFieldModel) {
|
||||
if (field && field.form) {
|
||||
if (field?.form) {
|
||||
this.visibilityService.refreshVisibility(field.form);
|
||||
}
|
||||
}
|
||||
@@ -361,7 +333,6 @@ export class FormComponent extends FormBaseComponent implements OnInit, OnDestro
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a Form with a field for each metadata property.
|
||||
*
|
||||
@@ -374,24 +345,40 @@ export class FormComponent extends FormBaseComponent implements OnInit, OnDestro
|
||||
(form) => {
|
||||
this.ecmModelService.searchEcmType(formName, EcmModelService.MODEL_NAME).subscribe(
|
||||
(customType) => {
|
||||
const formDefinitionModel = new FormDefinitionModel(form.id, form.name, form.lastUpdatedByFullName, form.lastUpdated, customType.entry.properties);
|
||||
from(
|
||||
this.editorService.saveForm(form.id, formDefinitionModel)
|
||||
).subscribe((formData) => {
|
||||
observer.next(formData);
|
||||
observer.complete();
|
||||
}, (err) => this.handleError(err));
|
||||
const formDefinitionModel = new FormDefinitionModel(
|
||||
form.id,
|
||||
form.name,
|
||||
form.lastUpdatedByFullName,
|
||||
form.lastUpdated,
|
||||
customType.entry.properties
|
||||
);
|
||||
from(this.editorService.saveForm(form.id, formDefinitionModel)).subscribe(
|
||||
(formData) => {
|
||||
observer.next(formData);
|
||||
observer.complete();
|
||||
},
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
},
|
||||
(err) => this.handleError(err));
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
},
|
||||
(err) => this.handleError(err));
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
protected storeFormAsMetadata() {
|
||||
if (this.saveMetadata) {
|
||||
this.ecmModelService.createEcmTypeForActivitiForm(this.formName, this.form).subscribe((type) => {
|
||||
this.nodeService.createNodeMetadata(type.nodeType || type.entry.prefixedName, EcmModelService.MODEL_NAMESPACE, this.form.values, this.path, this.nameNode);
|
||||
this.ecmModelService.createEcmTypeForActivitiForm(this.formName, this.form).subscribe(
|
||||
(type) => {
|
||||
this.nodeService.createNodeMetadata(
|
||||
type.nodeType || type.entry.prefixedName,
|
||||
EcmModelService.MODEL_NAMESPACE,
|
||||
this.form.values,
|
||||
this.path,
|
||||
this.nameNode
|
||||
);
|
||||
},
|
||||
(error) => {
|
||||
this.handleError(error);
|
||||
@@ -450,10 +437,9 @@ export class FormComponent extends FormBaseComponent implements OnInit, OnDestro
|
||||
|
||||
private loadFormForEcmNode(nodeId: string): void {
|
||||
this.nodeService.getNodeMetadata(nodeId).subscribe((data) => {
|
||||
this.data = data.metadata;
|
||||
this.loadFormFromActiviti(data.nodeType);
|
||||
},
|
||||
this.handleError);
|
||||
this.data = data.metadata;
|
||||
this.loadFormFromActiviti(data.nodeType);
|
||||
}, this.handleError);
|
||||
}
|
||||
|
||||
private loadFormFromFormId(formId: number) {
|
||||
|
@@ -25,7 +25,6 @@ import { CustomModelApi } from '@alfresco/js-api';
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class EcmModelService {
|
||||
|
||||
public static MODEL_NAMESPACE: string = 'activitiForms';
|
||||
public static MODEL_NAME: string = 'activitiFormsModel';
|
||||
public static TYPE_MODEL: string = 'cm:folder';
|
||||
@@ -36,9 +35,7 @@ export class EcmModelService {
|
||||
return this._customModelApi;
|
||||
}
|
||||
|
||||
constructor(private apiService: AlfrescoApiService,
|
||||
private logService: LogService) {
|
||||
}
|
||||
constructor(private apiService: AlfrescoApiService, private logService: LogService) {}
|
||||
|
||||
public createEcmTypeForActivitiForm(formName: string, form: FormModel): Observable<any> {
|
||||
return new Observable((observer) => {
|
||||
@@ -59,11 +56,12 @@ export class EcmModelService {
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
searchActivitiEcmModel() {
|
||||
return this.getEcmModels().pipe(map((ecmModels: any) => ecmModels.list.entries.find((model) => model.entry.name === EcmModelService.MODEL_NAME)));
|
||||
return this.getEcmModels().pipe(
|
||||
map((ecmModels: any) => ecmModels.list.entries.find((model) => model.entry.name === EcmModelService.MODEL_NAME))
|
||||
);
|
||||
}
|
||||
|
||||
createActivitiEcmModel(formName: string, form: FormModel): Observable<any> {
|
||||
@@ -118,64 +116,62 @@ export class EcmModelService {
|
||||
observer.next(typeCreated);
|
||||
observer.complete();
|
||||
},
|
||||
(err) => this.handleError(err));
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
},
|
||||
(err) => this.handleError(err));
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public searchEcmType(typeName: string, modelName: string): Observable<any> {
|
||||
return this.getEcmType(modelName).pipe(map((customTypes: any) =>
|
||||
customTypes.list.entries.find((type) => type.entry.prefixedName === typeName || type.entry.title === typeName)));
|
||||
return this.getEcmType(modelName).pipe(
|
||||
map((customTypes: any) => customTypes.list.entries.find((type) => type.entry.prefixedName === typeName || type.entry.title === typeName))
|
||||
);
|
||||
}
|
||||
|
||||
public activeEcmModel(modelName: string): Observable<any> {
|
||||
return from(this.customModelApi.activateCustomModel(modelName))
|
||||
.pipe(
|
||||
map(this.toJson),
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
return from(this.customModelApi.activateCustomModel(modelName)).pipe(
|
||||
map(this.toJson),
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
}
|
||||
|
||||
public createEcmModel(modelName: string, nameSpace: string): Observable<any> {
|
||||
return from(this.customModelApi.createCustomModel('DRAFT', '', modelName, modelName, nameSpace))
|
||||
.pipe(
|
||||
map(this.toJson),
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
return from(this.customModelApi.createCustomModel('DRAFT', '', modelName, modelName, nameSpace)).pipe(
|
||||
map(this.toJson),
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
}
|
||||
|
||||
public getEcmModels(): Observable<any> {
|
||||
return from(this.customModelApi.getAllCustomModel())
|
||||
.pipe(
|
||||
map(this.toJson),
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
return from(this.customModelApi.getAllCustomModel()).pipe(
|
||||
map(this.toJson),
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
}
|
||||
|
||||
public getEcmType(modelName: string): Observable<any> {
|
||||
return from(this.customModelApi.getAllCustomType(modelName))
|
||||
.pipe(
|
||||
map(this.toJson),
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
return from(this.customModelApi.getAllCustomType(modelName)).pipe(
|
||||
map(this.toJson),
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
}
|
||||
|
||||
public createEcmType(typeName: string, modelName: string, parentType: string): Observable<any> {
|
||||
const name = this.cleanNameType(typeName);
|
||||
|
||||
return from(this.customModelApi.createCustomType(modelName, name, parentType, typeName, ''))
|
||||
.pipe(
|
||||
map(this.toJson),
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
return from(this.customModelApi.createCustomType(modelName, name, parentType, typeName, '')).pipe(
|
||||
map(this.toJson),
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
}
|
||||
|
||||
public addPropertyToAType(modelName: string, typeName: string, formFields: any) {
|
||||
const name = this.cleanNameType(typeName);
|
||||
|
||||
const properties = [];
|
||||
if (formFields && formFields.values) {
|
||||
if (formFields?.values) {
|
||||
for (const key in formFields.values) {
|
||||
if (key) {
|
||||
properties.push({
|
||||
@@ -191,12 +187,10 @@ export class EcmModelService {
|
||||
}
|
||||
}
|
||||
|
||||
return from(this.customModelApi.addPropertyToType(modelName, name, properties))
|
||||
.pipe(
|
||||
map(this.toJson),
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
|
||||
return from(this.customModelApi.addPropertyToType(modelName, name, properties)).pipe(
|
||||
map(this.toJson),
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
}
|
||||
|
||||
cleanNameType(name: string): string {
|
||||
@@ -208,10 +202,7 @@ export class EcmModelService {
|
||||
}
|
||||
|
||||
toJson(res: any) {
|
||||
if (res) {
|
||||
return res || {};
|
||||
}
|
||||
return {};
|
||||
return res || {};
|
||||
}
|
||||
|
||||
private handleError(err: any): any {
|
||||
|
@@ -25,7 +25,6 @@ import { catchError, map } from 'rxjs/operators';
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ModelService {
|
||||
|
||||
static UNKNOWN_ERROR_MESSAGE: string = 'Unknown error';
|
||||
static GENERIC_ERROR_MESSAGE: string = 'Server error';
|
||||
|
||||
@@ -35,8 +34,7 @@ export class ModelService {
|
||||
return this._modelsApi;
|
||||
}
|
||||
|
||||
constructor(private apiService: AlfrescoApiService, private logService: LogService) {
|
||||
}
|
||||
constructor(private apiService: AlfrescoApiService, private logService: LogService) {}
|
||||
|
||||
/**
|
||||
* Create a Form.
|
||||
@@ -52,9 +50,7 @@ export class ModelService {
|
||||
stencilSet: 0
|
||||
};
|
||||
|
||||
return from(
|
||||
this.modelsApi.createModel(dataModel)
|
||||
);
|
||||
return from(this.modelsApi.createModel(dataModel));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,11 +63,10 @@ export class ModelService {
|
||||
modelType: 2
|
||||
};
|
||||
|
||||
return from(this.modelsApi.getModels(opts))
|
||||
.pipe(
|
||||
map(this.toJsonArray),
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
return from(this.modelsApi.getModels(opts)).pipe(
|
||||
map(this.toJsonArray),
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,10 +76,7 @@ export class ModelService {
|
||||
* @returns JSON data
|
||||
*/
|
||||
toJsonArray(res: any) {
|
||||
if (res) {
|
||||
return res.data || [];
|
||||
}
|
||||
return [];
|
||||
return res?.data || [];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,16 +90,12 @@ export class ModelService {
|
||||
modelType: 2
|
||||
};
|
||||
|
||||
return from(
|
||||
this.modelsApi.getModels(opts)
|
||||
)
|
||||
.pipe(
|
||||
map((forms: any) => forms.data.find((formData) => formData.name === name)),
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
return from(this.modelsApi.getModels(opts)).pipe(
|
||||
map((forms) => forms.data.find((formData) => formData.name === name)),
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the form definition with a given name.
|
||||
*
|
||||
@@ -121,11 +109,10 @@ export class ModelService {
|
||||
modelType: 2
|
||||
};
|
||||
|
||||
return from(this.modelsApi.getModels(opts))
|
||||
.pipe(
|
||||
map(this.getFormId),
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
return from(this.modelsApi.getModels(opts)).pipe(
|
||||
map(this.getFormId),
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,7 +124,7 @@ export class ModelService {
|
||||
getFormId(form: any): string {
|
||||
let result = null;
|
||||
|
||||
if (form && form.data && form.data.length > 0) {
|
||||
if (form?.data?.length > 0) {
|
||||
result = form.data[0].id;
|
||||
}
|
||||
|
||||
@@ -152,11 +139,9 @@ export class ModelService {
|
||||
private handleError(error: any): Observable<any> {
|
||||
let errMsg = ModelService.UNKNOWN_ERROR_MESSAGE;
|
||||
if (error) {
|
||||
errMsg = (error.message) ? error.message :
|
||||
error.status ? `${error.status} - ${error.statusText}` : ModelService.GENERIC_ERROR_MESSAGE;
|
||||
errMsg = error.message ? error.message : error.status ? `${error.status} - ${error.statusText}` : ModelService.GENERIC_ERROR_MESSAGE;
|
||||
}
|
||||
this.logService.error(errMsg);
|
||||
return throwError(errMsg);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -15,17 +15,17 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AlfrescoApiService, LogService } from '@alfresco/adf-core';
|
||||
import { AlfrescoApiService, FormFieldOption, LogService } from '@alfresco/adf-core';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable, from, throwError } from 'rxjs';
|
||||
import { ProcessDefinitionsApi } from '@alfresco/js-api';
|
||||
import { catchError } from 'rxjs/operators';
|
||||
import { DynamicTableColumnOption } from '../widgets/dynamic-table/editors/models/dynamic-table-column-option.model';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ProcessDefinitionService {
|
||||
|
||||
static UNKNOWN_ERROR_MESSAGE: string = 'Unknown error';
|
||||
static GENERIC_ERROR_MESSAGE: string = 'Server error';
|
||||
|
||||
@@ -35,9 +35,7 @@ export class ProcessDefinitionService {
|
||||
return this._processDefinitionsApi;
|
||||
}
|
||||
|
||||
constructor(private apiService: AlfrescoApiService, private logService: LogService) {
|
||||
}
|
||||
|
||||
constructor(private apiService: AlfrescoApiService, private logService: LogService) {}
|
||||
|
||||
/**
|
||||
* Gets values of fields populated by a REST backend using a process ID.
|
||||
@@ -46,11 +44,8 @@ export class ProcessDefinitionService {
|
||||
* @param field Field identifier
|
||||
* @returns Field values
|
||||
*/
|
||||
getRestFieldValuesByProcessId(processDefinitionId: string, field: string): Observable<any> {
|
||||
return from(this.processDefinitionsApi.getRestFieldValues(processDefinitionId, field))
|
||||
.pipe(
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
getRestFieldValuesByProcessId(processDefinitionId: string, field: string): Observable<FormFieldOption[]> {
|
||||
return from(this.processDefinitionsApi.getRestFieldValues(processDefinitionId, field)).pipe(catchError((err) => this.handleError(err)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,11 +56,10 @@ export class ProcessDefinitionService {
|
||||
* @param column Column identifier
|
||||
* @returns Field values
|
||||
*/
|
||||
getRestFieldValuesColumnByProcessId(processDefinitionId: string, field: string, column?: string): Observable<any> {
|
||||
return from(this.processDefinitionsApi.getRestTableFieldValues(processDefinitionId, field, column))
|
||||
.pipe(
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
getRestFieldValuesColumnByProcessId(processDefinitionId: string, field: string, column?: string): Observable<DynamicTableColumnOption[]> {
|
||||
return from(this.processDefinitionsApi.getRestTableFieldValues(processDefinitionId, field, column)).pipe(
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,11 +84,13 @@ export class ProcessDefinitionService {
|
||||
private handleError(error: any): Observable<any> {
|
||||
let errMsg = ProcessDefinitionService.UNKNOWN_ERROR_MESSAGE;
|
||||
if (error) {
|
||||
errMsg = (error.message) ? error.message :
|
||||
error.status ? `${error.status} - ${error.statusText}` : ProcessDefinitionService.GENERIC_ERROR_MESSAGE;
|
||||
errMsg = error.message
|
||||
? error.message
|
||||
: error.status
|
||||
? `${error.status} - ${error.statusText}`
|
||||
: ProcessDefinitionService.GENERIC_ERROR_MESSAGE;
|
||||
}
|
||||
this.logService.error(errMsg);
|
||||
return throwError(errMsg);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -15,17 +15,17 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AlfrescoApiService, FormValues, LogService, TaskProcessVariableModel } from '@alfresco/adf-core';
|
||||
import { AlfrescoApiService, FormFieldOption, FormValues, LogService, TaskProcessVariableModel } from '@alfresco/adf-core';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { from, Observable, throwError } from 'rxjs';
|
||||
import { CompleteFormRepresentation, SaveFormRepresentation, TaskFormsApi } from '@alfresco/js-api';
|
||||
import { catchError, map } from 'rxjs/operators';
|
||||
import { DynamicTableColumnOption } from '../widgets/dynamic-table/editors/models/dynamic-table-column-option.model';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class TaskFormService {
|
||||
|
||||
static UNKNOWN_ERROR_MESSAGE: string = 'Unknown error';
|
||||
static GENERIC_ERROR_MESSAGE: string = 'Server error';
|
||||
|
||||
@@ -35,8 +35,7 @@ export class TaskFormService {
|
||||
return this._taskFormsApi;
|
||||
}
|
||||
|
||||
constructor(private apiService: AlfrescoApiService, private logService: LogService) {
|
||||
}
|
||||
constructor(private apiService: AlfrescoApiService, private logService: LogService) {}
|
||||
|
||||
/**
|
||||
* Saves a task form.
|
||||
@@ -48,10 +47,7 @@ export class TaskFormService {
|
||||
saveTaskForm(taskId: string, formValues: FormValues): Observable<any> {
|
||||
const saveFormRepresentation = { values: formValues } as SaveFormRepresentation;
|
||||
|
||||
return from(this.taskFormsApi.saveTaskForm(taskId, saveFormRepresentation))
|
||||
.pipe(
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
return from(this.taskFormsApi.saveTaskForm(taskId, saveFormRepresentation)).pipe(catchError((err) => this.handleError(err)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,10 +64,7 @@ export class TaskFormService {
|
||||
completeFormRepresentation.outcome = outcome;
|
||||
}
|
||||
|
||||
return from(this.taskFormsApi.completeTaskForm(taskId, completeFormRepresentation))
|
||||
.pipe(
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
return from(this.taskFormsApi.completeTaskForm(taskId, completeFormRepresentation)).pipe(catchError((err) => this.handleError(err)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,11 +74,10 @@ export class TaskFormService {
|
||||
* @returns Form definition
|
||||
*/
|
||||
getTaskForm(taskId: string): Observable<any> {
|
||||
return from(this.taskFormsApi.getTaskForm(taskId))
|
||||
.pipe(
|
||||
map(this.toJson),
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
return from(this.taskFormsApi.getTaskForm(taskId)).pipe(
|
||||
map(this.toJson),
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,11 +87,8 @@ export class TaskFormService {
|
||||
* @param field Field identifier
|
||||
* @returns Field values
|
||||
*/
|
||||
getRestFieldValues(taskId: string, field: string): Observable<any> {
|
||||
return from(this.taskFormsApi.getRestFieldValues(taskId, field))
|
||||
.pipe(
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
getRestFieldValues(taskId: string, field: string): Observable<FormFieldOption[]> {
|
||||
return from(this.taskFormsApi.getRestFieldValues(taskId, field)).pipe(catchError((err) => this.handleError(err)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,19 +99,15 @@ export class TaskFormService {
|
||||
* @param column Column identifier
|
||||
* @returns Field values
|
||||
*/
|
||||
getRestFieldValuesColumn(taskId: string, field: string, column?: string): Observable<any> {
|
||||
return from(this.taskFormsApi.getRestFieldColumnValues(taskId, field, column))
|
||||
.pipe(
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
getRestFieldValuesColumn(taskId: string, field: string, column?: string): Observable<DynamicTableColumnOption[]> {
|
||||
return from(this.taskFormsApi.getRestFieldColumnValues(taskId, field, column)).pipe(catchError((err) => this.handleError(err)));
|
||||
}
|
||||
|
||||
getTaskProcessVariable(taskId: string): Observable<TaskProcessVariableModel[]> {
|
||||
return from(this.taskFormsApi.getTaskFormVariables(taskId))
|
||||
.pipe(
|
||||
map((res) => this.toJson(res)),
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
return from(this.taskFormsApi.getTaskFormVariables(taskId)).pipe(
|
||||
map((res) => this.toJson(res)),
|
||||
catchError((err) => this.handleError(err))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -147,11 +132,9 @@ export class TaskFormService {
|
||||
private handleError(error: any): Observable<any> {
|
||||
let errMsg = TaskFormService.UNKNOWN_ERROR_MESSAGE;
|
||||
if (error) {
|
||||
errMsg = (error.message) ? error.message :
|
||||
error.status ? `${error.status} - ${error.statusText}` : TaskFormService.GENERIC_ERROR_MESSAGE;
|
||||
errMsg = error.message ? error.message : error.status ? `${error.status} - ${error.statusText}` : TaskFormService.GENERIC_ERROR_MESSAGE;
|
||||
}
|
||||
this.logService.error(errMsg);
|
||||
return throwError(errMsg);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -80,7 +80,7 @@ export class StartFormComponent extends FormComponent implements OnChanges, OnIn
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
const processDefinitionId = changes['processDefinitionId'];
|
||||
if (processDefinitionId && processDefinitionId.currentValue) {
|
||||
if (processDefinitionId?.currentValue) {
|
||||
this.processDefinitionId = processDefinitionId.currentValue;
|
||||
this.visibilityService.cleanProcessVariable();
|
||||
this.getStartFormDefinition(this.processDefinitionId);
|
||||
@@ -88,13 +88,13 @@ export class StartFormComponent extends FormComponent implements OnChanges, OnIn
|
||||
}
|
||||
|
||||
const data = changes['data'];
|
||||
if (data && data.currentValue) {
|
||||
if (data?.currentValue) {
|
||||
this.parseRefreshVisibilityValidateForm(this.form.json);
|
||||
return;
|
||||
}
|
||||
|
||||
const processId = changes['processId'];
|
||||
if (processId && processId.currentValue) {
|
||||
if (processId?.currentValue) {
|
||||
this.visibilityService.cleanProcessVariable();
|
||||
this.loadStartForm(processId.currentValue);
|
||||
return;
|
||||
@@ -102,33 +102,28 @@ export class StartFormComponent extends FormComponent implements OnChanges, OnIn
|
||||
}
|
||||
|
||||
loadStartForm(processId: string) {
|
||||
this.processService.getProcess(processId)
|
||||
.subscribe((instance: any) => {
|
||||
this.processService
|
||||
.getStartFormInstance(processId)
|
||||
.subscribe(
|
||||
(form) => {
|
||||
this.formName = form.name;
|
||||
if (instance.variables) {
|
||||
form.processVariables = instance.variables;
|
||||
}
|
||||
this.parseRefreshVisibilityValidateForm(form);
|
||||
},
|
||||
(error) => this.handleError(error)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
getStartFormDefinition(processId: string) {
|
||||
this.processService
|
||||
.getStartFormDefinition(processId)
|
||||
.subscribe(
|
||||
this.processService.getProcess(processId).subscribe((instance: any) => {
|
||||
this.processService.getStartFormInstance(processId).subscribe(
|
||||
(form) => {
|
||||
this.formName = form.processDefinitionName;
|
||||
this.formName = form.name;
|
||||
if (instance.variables) {
|
||||
form.processVariables = instance.variables;
|
||||
}
|
||||
this.parseRefreshVisibilityValidateForm(form);
|
||||
},
|
||||
(error) => this.handleError(error)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
getStartFormDefinition(processId: string) {
|
||||
this.processService.getStartFormDefinition(processId).subscribe(
|
||||
(form) => {
|
||||
this.formName = form.processDefinitionName;
|
||||
this.parseRefreshVisibilityValidateForm(form);
|
||||
},
|
||||
(error) => this.handleError(error)
|
||||
);
|
||||
}
|
||||
|
||||
parseRefreshVisibilityValidateForm(form) {
|
||||
@@ -141,10 +136,9 @@ export class StartFormComponent extends FormComponent implements OnChanges, OnIn
|
||||
|
||||
/** @override */
|
||||
isOutcomeButtonVisible(outcome: FormOutcomeModel, isFormReadOnly: boolean): boolean {
|
||||
if (outcome && outcome.isSystem && (outcome.name === FormOutcomeModel.SAVE_ACTION ||
|
||||
outcome.name === FormOutcomeModel.COMPLETE_ACTION)) {
|
||||
if (outcome?.isSystem && (outcome.name === FormOutcomeModel.SAVE_ACTION || outcome.name === FormOutcomeModel.COMPLETE_ACTION)) {
|
||||
return false;
|
||||
} else if (outcome && outcome.name === FormOutcomeModel.START_PROCESS_ACTION) {
|
||||
} else if (outcome?.name === FormOutcomeModel.START_PROCESS_ACTION) {
|
||||
return true;
|
||||
}
|
||||
return super.isOutcomeButtonVisible(outcome, isFormReadOnly);
|
||||
|
@@ -18,21 +18,9 @@
|
||||
/* eslint-disable @angular-eslint/component-selector */
|
||||
|
||||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import {
|
||||
AppConfigService,
|
||||
AppConfigValues,
|
||||
DownloadService,
|
||||
FormService,
|
||||
LogService,
|
||||
ThumbnailService
|
||||
} from '@alfresco/adf-core';
|
||||
import { AppConfigService, AppConfigValues, DownloadService, FormService, LogService, ThumbnailService } from '@alfresco/adf-core';
|
||||
import { ContentNodeDialogService, ContentService } from '@alfresco/adf-content-services';
|
||||
import {
|
||||
AlfrescoEndpointRepresentation,
|
||||
Node,
|
||||
NodeChildAssociation,
|
||||
RelatedContentRepresentation
|
||||
} from '@alfresco/js-api';
|
||||
import { AlfrescoEndpointRepresentation, Node, NodeChildAssociation, RelatedContentRepresentation } from '@alfresco/js-api';
|
||||
import { from, of, Subject, zip } from 'rxjs';
|
||||
import { mergeMap, takeUntil } from 'rxjs/operators';
|
||||
import { AttachFileWidgetDialogService } from './attach-file-widget-dialog.service';
|
||||
@@ -58,22 +46,23 @@ import { ActivitiContentService } from '../../services/activiti-alfresco.service
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class AttachFileWidgetComponent extends UploadWidgetComponent implements OnInit, OnDestroy {
|
||||
|
||||
typeId = 'AttachFileWidgetComponent';
|
||||
repositoryList: AlfrescoEndpointRepresentation[] = [];
|
||||
private tempFilesList = [];
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
constructor(public formService: FormService,
|
||||
private logger: LogService,
|
||||
public thumbnails: ThumbnailService,
|
||||
public processContentService: ProcessContentService,
|
||||
private activitiContentService: ActivitiContentService,
|
||||
private contentService: ContentService,
|
||||
private contentDialog: ContentNodeDialogService,
|
||||
private appConfigService: AppConfigService,
|
||||
private downloadService: DownloadService,
|
||||
private attachDialogService: AttachFileWidgetDialogService) {
|
||||
constructor(
|
||||
public formService: FormService,
|
||||
private logger: LogService,
|
||||
public thumbnails: ThumbnailService,
|
||||
public processContentService: ProcessContentService,
|
||||
private activitiContentService: ActivitiContentService,
|
||||
private contentService: ContentService,
|
||||
private contentDialog: ContentNodeDialogService,
|
||||
private appConfigService: AppConfigService,
|
||||
private downloadService: DownloadService,
|
||||
private attachDialogService: AttachFileWidgetDialogService
|
||||
) {
|
||||
super(formService, logger, thumbnails, processContentService);
|
||||
}
|
||||
|
||||
@@ -84,13 +73,11 @@ export class AttachFileWidgetComponent extends UploadWidgetComponent implements
|
||||
this.repositoryList = repoList;
|
||||
});
|
||||
|
||||
this.formService.taskSaved
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe(formSaved => {
|
||||
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() {
|
||||
@@ -99,7 +86,7 @@ export class AttachFileWidgetComponent extends UploadWidgetComponent implements
|
||||
}
|
||||
|
||||
isFileSourceConfigured(): boolean {
|
||||
return !!this.field.params && !!this.field.params.fileSource;
|
||||
return !!this.field.params?.fileSource;
|
||||
}
|
||||
|
||||
isMultipleSourceUpload(): boolean {
|
||||
@@ -107,22 +94,15 @@ export class AttachFileWidgetComponent extends UploadWidgetComponent implements
|
||||
}
|
||||
|
||||
isAllFileSourceSelected(): boolean {
|
||||
return this.field.params &&
|
||||
this.field.params.fileSource &&
|
||||
this.field.params.fileSource.serviceId === 'all-file-sources' &&
|
||||
!this.field.params.link;
|
||||
return this.field.params?.fileSource?.serviceId === 'all-file-sources' && !this.field.params.link;
|
||||
}
|
||||
|
||||
isOnlyLocalSourceSelected(): boolean {
|
||||
return this.field.params &&
|
||||
this.field.params.fileSource &&
|
||||
this.field.params.fileSource.serviceId === 'local-file';
|
||||
return this.field.params?.fileSource?.serviceId === 'local-file';
|
||||
}
|
||||
|
||||
isSimpleUploadButton(): boolean {
|
||||
return this.isUploadButtonVisible() &&
|
||||
!this.isFileSourceConfigured() ||
|
||||
this.isOnlyLocalSourceSelected();
|
||||
return (this.isUploadButtonVisible() && !this.isFileSourceConfigured()) || this.isOnlyLocalSourceSelected();
|
||||
}
|
||||
|
||||
isUploadButtonVisible(): boolean {
|
||||
@@ -133,11 +113,11 @@ export class AttachFileWidgetComponent extends UploadWidgetComponent implements
|
||||
return !!this.field.params?.fileSource?.selectedFolder;
|
||||
}
|
||||
|
||||
isTemporaryFile(file): boolean {
|
||||
isTemporaryFile(file: { name?: string }): boolean {
|
||||
return this.tempFilesList.findIndex((elem) => elem.name === file.name) >= 0;
|
||||
}
|
||||
|
||||
getNodeFromTempFile(file): NodeChildAssociation {
|
||||
getNodeFromTempFile(file: { name?: string }): NodeChildAssociation {
|
||||
return this.tempFilesList.find((elem) => elem.name === file.name);
|
||||
}
|
||||
|
||||
@@ -147,13 +127,14 @@ export class AttachFileWidgetComponent extends UploadWidgetComponent implements
|
||||
if (repository && this.isExternalHost(repository)) {
|
||||
this.uploadFileFromExternalCS(repository, params?.fileSource?.selectedFolder?.pathId);
|
||||
} else {
|
||||
this.contentDialog.openFileBrowseDialogByFolderId(params.fileSource.selectedFolder.pathId).subscribe(
|
||||
(selections: Node[]) => {
|
||||
this.tempFilesList.push(...selections);
|
||||
this.uploadFileFromCS(selections,
|
||||
this.field.params.fileSource.selectedFolder.accountId,
|
||||
this.field.params.fileSource.selectedFolder.siteId);
|
||||
});
|
||||
this.contentDialog.openFileBrowseDialogByFolderId(params.fileSource.selectedFolder.pathId).subscribe((selections: Node[]) => {
|
||||
this.tempFilesList.push(...selections);
|
||||
this.uploadFileFromCS(
|
||||
selections,
|
||||
this.field.params.fileSource.selectedFolder.accountId,
|
||||
this.field.params.fileSource.selectedFolder.siteId
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,11 +199,10 @@ export class AttachFileWidgetComponent extends UploadWidgetComponent implements
|
||||
if (this.isExternalHost(repository)) {
|
||||
this.uploadFileFromExternalCS(repository);
|
||||
} else {
|
||||
this.contentDialog.openFileBrowseDialogByDefaultLocation().subscribe(
|
||||
(selections: Node[]) => {
|
||||
this.tempFilesList.push(...selections);
|
||||
this.uploadFileFromCS(selections, `alfresco-${repository.id}-${repository.name}`);
|
||||
});
|
||||
this.contentDialog.openFileBrowseDialogByDefaultLocation().subscribe((selections: Node[]) => {
|
||||
this.tempFilesList.push(...selections);
|
||||
this.uploadFileFromCS(selections, `alfresco-${repository.id}-${repository.name}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,36 +217,33 @@ export class AttachFileWidgetComponent extends UploadWidgetComponent implements
|
||||
}
|
||||
|
||||
private findSource(sourceIdentifier: string): AlfrescoEndpointRepresentation {
|
||||
return this.repositoryList.find(repository => sourceIdentifier === `alfresco-${repository.id}-${repository.name}`);
|
||||
return this.repositoryList.find((repository) => sourceIdentifier === `alfresco-${repository.id}-${repository.name}`);
|
||||
}
|
||||
|
||||
private uploadFileFromExternalCS(repository: AlfrescoEndpointRepresentation, currentFolderId?: string) {
|
||||
const accountIdentifier = `alfresco-${repository.id}-${repository.name}`;
|
||||
this.attachDialogService.openLogin(repository, currentFolderId, accountIdentifier).subscribe(
|
||||
(selections: any[]) => {
|
||||
selections.forEach((node) => node.isExternal = true);
|
||||
this.tempFilesList.push(...selections);
|
||||
this.uploadFileFromCS(selections, accountIdentifier);
|
||||
});
|
||||
this.attachDialogService.openLogin(repository, currentFolderId, accountIdentifier).subscribe((selections: any[]) => {
|
||||
selections.forEach((node) => (node.isExternal = true));
|
||||
this.tempFilesList.push(...selections);
|
||||
this.uploadFileFromCS(selections, accountIdentifier);
|
||||
});
|
||||
}
|
||||
|
||||
private uploadFileFromCS(fileNodeList: any[], accountId: string, siteId?: string) {
|
||||
const filesSaved = [];
|
||||
|
||||
fileNodeList.forEach(node => {
|
||||
fileNodeList.forEach((node) => {
|
||||
node.isLink = this.field.params.link;
|
||||
});
|
||||
|
||||
from(fileNodeList).pipe(
|
||||
mergeMap((node) =>
|
||||
zip(
|
||||
of(node?.content?.mimeType),
|
||||
this.activitiContentService.applyAlfrescoNode(node, siteId, accountId),
|
||||
of(node.isExternal)
|
||||
from(fileNodeList)
|
||||
.pipe(
|
||||
mergeMap((node) =>
|
||||
zip(of(node?.content?.mimeType), this.activitiContentService.applyAlfrescoNode(node, siteId, accountId), of(node.isExternal))
|
||||
)
|
||||
)
|
||||
)
|
||||
.subscribe(([mimeType, res, isExternal]) => {
|
||||
.subscribe(
|
||||
([mimeType, res, isExternal]) => {
|
||||
res.mimeType = mimeType;
|
||||
res.isExternal = isExternal;
|
||||
filesSaved.push(res);
|
||||
@@ -279,12 +256,12 @@ export class AttachFileWidgetComponent extends UploadWidgetComponent implements
|
||||
this.field.value = [...previousFiles, ...filesSaved];
|
||||
this.field.json.value = [...previousFiles, ...filesSaved];
|
||||
this.hasFile = true;
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private getDomainHost(urlToCheck: string): string {
|
||||
const result = urlToCheck.match('^(?:https?:\/\/)?(?:[^@\/\n]+@)?(?:www\\.)?([^:\/?\n]+)');
|
||||
const result = urlToCheck.match('^(?:https?://)?(?:[^@/\n]+@)?(?:www\\.)?([^:/?\n]+)');
|
||||
return result[1];
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -18,10 +18,7 @@
|
||||
/* eslint-disable @angular-eslint/component-selector */
|
||||
|
||||
import { Component, ViewEncapsulation, OnInit } from '@angular/core';
|
||||
import {
|
||||
WidgetComponent,
|
||||
FormService
|
||||
} from '@alfresco/adf-core';
|
||||
import { WidgetComponent, FormService } from '@alfresco/adf-core';
|
||||
import { ContentNodeDialogService, NodesApiService } from '@alfresco/adf-content-services';
|
||||
import { Node } from '@alfresco/js-api';
|
||||
|
||||
@@ -43,20 +40,16 @@ import { Node } from '@alfresco/js-api';
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class AttachFolderWidgetComponent extends WidgetComponent implements OnInit {
|
||||
|
||||
typeId = 'AttachFolderWidgetComponent';
|
||||
hasFolder: boolean = false;
|
||||
selectedFolderName: string = '';
|
||||
|
||||
constructor(private contentDialog: ContentNodeDialogService,
|
||||
public formService: FormService,
|
||||
private nodeService: NodesApiService) {
|
||||
constructor(private contentDialog: ContentNodeDialogService, public formService: FormService, private nodeService: NodesApiService) {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.field &&
|
||||
this.field.value) {
|
||||
if (this.field?.value) {
|
||||
this.hasFolder = true;
|
||||
this.nodeService.getNode(this.field.value).subscribe((node: Node) => {
|
||||
this.selectedFolderName = node.name;
|
||||
@@ -65,27 +58,23 @@ export class AttachFolderWidgetComponent extends WidgetComponent implements OnIn
|
||||
}
|
||||
|
||||
isDefinedSourceFolder(): boolean {
|
||||
return !!this.field.params &&
|
||||
!!this.field.params.folderSource &&
|
||||
!!this.field.params.folderSource.selectedFolder;
|
||||
return !!this.field.params?.folderSource?.selectedFolder;
|
||||
}
|
||||
|
||||
openSelectDialogFromFileSource() {
|
||||
const params = this.field.params;
|
||||
if (this.isDefinedSourceFolder()) {
|
||||
this.contentDialog.openFolderBrowseDialogByFolderId(params.folderSource.selectedFolder.pathId).subscribe(
|
||||
(selections: Node[]) => {
|
||||
this.selectedFolderName = selections[0].name;
|
||||
this.field.value = selections[0].id;
|
||||
this.hasFolder = true;
|
||||
});
|
||||
this.contentDialog.openFolderBrowseDialogByFolderId(params.folderSource.selectedFolder.pathId).subscribe((selections: Node[]) => {
|
||||
this.selectedFolderName = selections[0].name;
|
||||
this.field.value = selections[0].id;
|
||||
this.hasFolder = true;
|
||||
});
|
||||
} else {
|
||||
this.contentDialog.openFolderBrowseDialogBySite().subscribe(
|
||||
(selections: Node[]) => {
|
||||
this.selectedFolderName = selections[0].name;
|
||||
this.field.value = selections[0].id;
|
||||
this.hasFolder = true;
|
||||
});
|
||||
this.contentDialog.openFolderBrowseDialogBySite().subscribe((selections: Node[]) => {
|
||||
this.selectedFolderName = selections[0].name;
|
||||
this.field.value = selections[0].id;
|
||||
this.hasFolder = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,5 +83,4 @@ export class AttachFolderWidgetComponent extends WidgetComponent implements OnIn
|
||||
this.selectedFolderName = '';
|
||||
this.hasFolder = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -62,7 +62,7 @@ export class ContentWidgetComponent implements OnChanges {
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
const contentId = changes['id'];
|
||||
if (contentId && contentId.currentValue) {
|
||||
if (contentId?.currentValue) {
|
||||
this.loadContent(contentId.currentValue);
|
||||
}
|
||||
}
|
||||
|
@@ -18,12 +18,7 @@
|
||||
/* eslint-disable @angular-eslint/component-selector */
|
||||
|
||||
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import {
|
||||
FormService,
|
||||
FormFieldOption,
|
||||
WidgetComponent,
|
||||
LogService
|
||||
} from '@alfresco/adf-core';
|
||||
import { FormService, FormFieldOption, WidgetComponent, LogService } from '@alfresco/adf-core';
|
||||
import { ProcessDefinitionService } from '../../services/process-definition.service';
|
||||
import { TaskFormService } from '../../services/task-form.service';
|
||||
|
||||
@@ -45,16 +40,17 @@ import { TaskFormService } from '../../services/task-form.service';
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class DropdownWidgetComponent extends WidgetComponent implements OnInit {
|
||||
|
||||
constructor(public formService: FormService,
|
||||
public taskFormService: TaskFormService,
|
||||
public processDefinitionService: ProcessDefinitionService,
|
||||
private logService: LogService) {
|
||||
constructor(
|
||||
public formService: FormService,
|
||||
public taskFormService: TaskFormService,
|
||||
public processDefinitionService: ProcessDefinitionService,
|
||||
private logService: LogService
|
||||
) {
|
||||
super(formService);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.field && this.field.restUrl) {
|
||||
if (this.field?.restUrl) {
|
||||
if (this.field.form.taskId) {
|
||||
this.getValuesByTaskId();
|
||||
} else {
|
||||
@@ -64,41 +60,31 @@ export class DropdownWidgetComponent extends WidgetComponent implements OnInit {
|
||||
}
|
||||
|
||||
getValuesByTaskId() {
|
||||
this.taskFormService
|
||||
.getRestFieldValues(
|
||||
this.field.form.taskId,
|
||||
this.field.id
|
||||
)
|
||||
.subscribe(
|
||||
(formFieldOption: FormFieldOption[]) => {
|
||||
const options = [];
|
||||
if (this.field.emptyOption) {
|
||||
options.push(this.field.emptyOption);
|
||||
}
|
||||
this.field.options = options.concat((formFieldOption || []));
|
||||
this.field.updateForm();
|
||||
},
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
this.taskFormService.getRestFieldValues(this.field.form.taskId, this.field.id).subscribe(
|
||||
(formFieldOption) => {
|
||||
const options = [];
|
||||
if (this.field.emptyOption) {
|
||||
options.push(this.field.emptyOption);
|
||||
}
|
||||
this.field.options = options.concat(formFieldOption || []);
|
||||
this.field.updateForm();
|
||||
},
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
}
|
||||
|
||||
getValuesByProcessDefinitionId() {
|
||||
this.processDefinitionService
|
||||
.getRestFieldValuesByProcessId(
|
||||
this.field.form.processDefinitionId,
|
||||
this.field.id
|
||||
)
|
||||
.subscribe(
|
||||
(formFieldOption: FormFieldOption[]) => {
|
||||
const options = [];
|
||||
if (this.field.emptyOption) {
|
||||
options.push(this.field.emptyOption);
|
||||
}
|
||||
this.field.options = options.concat((formFieldOption || []));
|
||||
this.field.updateForm();
|
||||
},
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
this.processDefinitionService.getRestFieldValuesByProcessId(this.field.form.processDefinitionId, this.field.id).subscribe(
|
||||
(formFieldOption) => {
|
||||
const options = [];
|
||||
if (this.field.emptyOption) {
|
||||
options.push(this.field.emptyOption);
|
||||
}
|
||||
this.field.options = options.concat(formFieldOption || []);
|
||||
this.field.updateForm();
|
||||
},
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
}
|
||||
|
||||
getOptionValue(option: FormFieldOption, fieldValue: string): string {
|
||||
|
@@ -41,7 +41,6 @@ import { DynamicTableModel } from './editors/models/dynamic-table.widget.model';
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class DynamicTableWidgetComponent extends WidgetComponent implements OnInit {
|
||||
|
||||
ERROR_MODEL_NOT_FOUND = 'Table model not found';
|
||||
|
||||
content: DynamicTableModel;
|
||||
@@ -51,11 +50,13 @@ export class DynamicTableWidgetComponent extends WidgetComponent implements OnIn
|
||||
|
||||
private selectArrayCode = [32, 0, 13];
|
||||
|
||||
constructor(public formService: FormService,
|
||||
public elementRef: ElementRef,
|
||||
private visibilityService: WidgetVisibilityService,
|
||||
private logService: LogService,
|
||||
private cd: ChangeDetectorRef) {
|
||||
constructor(
|
||||
public formService: FormService,
|
||||
public elementRef: ElementRef,
|
||||
private visibilityService: WidgetVisibilityService,
|
||||
private logService: LogService,
|
||||
private cd: ChangeDetectorRef
|
||||
) {
|
||||
super(formService);
|
||||
}
|
||||
|
||||
@@ -69,21 +70,21 @@ export class DynamicTableWidgetComponent extends WidgetComponent implements OnIn
|
||||
forceFocusOnAddButton() {
|
||||
if (this.content) {
|
||||
this.cd.detectChanges();
|
||||
const buttonAddRow = this.elementRef.nativeElement.querySelector('#' + this.content.id + '-add-row');
|
||||
const buttonAddRow = this.elementRef.nativeElement.querySelector('#' + this.content.id + '-add-row') as HTMLButtonElement;
|
||||
if (this.isDynamicTableReady(buttonAddRow)) {
|
||||
buttonAddRow.focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private isDynamicTableReady(buttonAddRow) {
|
||||
private isDynamicTableReady(buttonAddRow: HTMLButtonElement) {
|
||||
return this.field && !this.editMode && buttonAddRow;
|
||||
}
|
||||
|
||||
isValid() {
|
||||
let valid = true;
|
||||
|
||||
if (this.content && this.content.field) {
|
||||
if (this.content?.field) {
|
||||
valid = this.content.field.isValid;
|
||||
}
|
||||
|
||||
@@ -107,7 +108,7 @@ export class DynamicTableWidgetComponent extends WidgetComponent implements OnIn
|
||||
}
|
||||
|
||||
hasSelection(): boolean {
|
||||
return !!(this.content && this.content.selectedRow);
|
||||
return !!this.content?.selectedRow;
|
||||
}
|
||||
|
||||
moveSelectionUp(): boolean {
|
||||
@@ -192,7 +193,7 @@ export class DynamicTableWidgetComponent extends WidgetComponent implements OnIn
|
||||
}
|
||||
|
||||
copyRow(row: DynamicTableRow): DynamicTableRow {
|
||||
return {value: this.copyObject(row.value)} as DynamicTableRow;
|
||||
return { value: this.copyObject(row.value) } as DynamicTableRow;
|
||||
}
|
||||
|
||||
private copyObject(obj: any): any {
|
||||
|
@@ -17,12 +17,7 @@
|
||||
|
||||
/* eslint-disable @angular-eslint/component-selector */
|
||||
|
||||
import {
|
||||
UserPreferencesService,
|
||||
UserPreferenceValues,
|
||||
MomentDateAdapter,
|
||||
MOMENT_DATE_FORMATS
|
||||
} from '@alfresco/adf-core';
|
||||
import { UserPreferencesService, UserPreferenceValues, MomentDateAdapter, MOMENT_DATE_FORMATS } from '@alfresco/adf-core';
|
||||
import { Component, Input, OnInit, OnDestroy } from '@angular/core';
|
||||
import { DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core';
|
||||
import { MatDatepickerInputEvent } from '@angular/material/datepicker';
|
||||
@@ -37,12 +32,12 @@ import { takeUntil } from 'rxjs/operators';
|
||||
selector: 'adf-date-editor',
|
||||
templateUrl: './date.editor.html',
|
||||
providers: [
|
||||
{provide: DateAdapter, useClass: MomentDateAdapter},
|
||||
{provide: MAT_DATE_FORMATS, useValue: MOMENT_DATE_FORMATS}],
|
||||
{ provide: DateAdapter, useClass: MomentDateAdapter },
|
||||
{ provide: MAT_DATE_FORMATS, useValue: MOMENT_DATE_FORMATS }
|
||||
],
|
||||
styleUrls: ['./date.editor.scss']
|
||||
})
|
||||
export class DateEditorComponent implements OnInit, OnDestroy {
|
||||
|
||||
DATE_FORMAT: string = 'DD-MM-YYYY';
|
||||
|
||||
value: any;
|
||||
@@ -61,15 +56,13 @@ export class DateEditorComponent implements OnInit, OnDestroy {
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
constructor(private dateAdapter: DateAdapter<Moment>,
|
||||
private userPreferencesService: UserPreferencesService) {
|
||||
}
|
||||
constructor(private dateAdapter: DateAdapter<Moment>, private userPreferencesService: UserPreferencesService) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.userPreferencesService
|
||||
.select(UserPreferenceValues.Locale)
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe(locale => this.dateAdapter.setLocale(locale));
|
||||
.subscribe((locale) => this.dateAdapter.setLocale(locale));
|
||||
|
||||
const momentDateAdapter = this.dateAdapter as MomentDateAdapter;
|
||||
momentDateAdapter.overrideDisplayFormat = this.DATE_FORMAT;
|
||||
@@ -83,7 +76,7 @@ export class DateEditorComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
onDateChanged(newDateValue: MatDatepickerInputEvent<any> | HTMLInputElement) {
|
||||
if (newDateValue && newDateValue.value) {
|
||||
if (newDateValue?.value) {
|
||||
/* validates the user inputs */
|
||||
const momentDate = moment(newDateValue.value, this.DATE_FORMAT, true);
|
||||
|
||||
@@ -98,5 +91,4 @@ export class DateEditorComponent implements OnInit, OnDestroy {
|
||||
this.row.value[this.column.id] = '';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -17,12 +17,7 @@
|
||||
|
||||
/* eslint-disable @angular-eslint/component-selector */
|
||||
|
||||
import {
|
||||
MOMENT_DATE_FORMATS,
|
||||
MomentDateAdapter,
|
||||
UserPreferencesService,
|
||||
UserPreferenceValues
|
||||
} from '@alfresco/adf-core';
|
||||
import { MOMENT_DATE_FORMATS, MomentDateAdapter, UserPreferencesService, UserPreferenceValues } from '@alfresco/adf-core';
|
||||
import { Component, Input, OnInit, OnDestroy } from '@angular/core';
|
||||
import { DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core';
|
||||
import moment, { Moment } from 'moment';
|
||||
@@ -38,15 +33,14 @@ import { takeUntil } from 'rxjs/operators';
|
||||
selector: 'adf-datetime-editor',
|
||||
templateUrl: './datetime.editor.html',
|
||||
providers: [
|
||||
{provide: DateAdapter, useClass: MomentDateAdapter},
|
||||
{provide: MAT_DATE_FORMATS, useValue: MOMENT_DATE_FORMATS},
|
||||
{provide: DatetimeAdapter, useClass: MomentDatetimeAdapter},
|
||||
{provide: MAT_DATETIME_FORMATS, useValue: MAT_MOMENT_DATETIME_FORMATS}
|
||||
{ provide: DateAdapter, useClass: MomentDateAdapter },
|
||||
{ provide: MAT_DATE_FORMATS, useValue: MOMENT_DATE_FORMATS },
|
||||
{ provide: DatetimeAdapter, useClass: MomentDatetimeAdapter },
|
||||
{ provide: MAT_DATETIME_FORMATS, useValue: MAT_MOMENT_DATETIME_FORMATS }
|
||||
],
|
||||
styleUrls: ['./datetime.editor.scss']
|
||||
})
|
||||
export class DateTimeEditorComponent implements OnInit, OnDestroy {
|
||||
|
||||
DATE_TIME_FORMAT: string = 'DD/MM/YYYY HH:mm';
|
||||
|
||||
value: any;
|
||||
@@ -65,15 +59,13 @@ export class DateTimeEditorComponent implements OnInit, OnDestroy {
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
constructor(private dateAdapter: DateAdapter<Moment>,
|
||||
private userPreferencesService: UserPreferencesService) {
|
||||
}
|
||||
constructor(private dateAdapter: DateAdapter<Moment>, private userPreferencesService: UserPreferencesService) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.userPreferencesService
|
||||
.select(UserPreferenceValues.Locale)
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe(locale => this.dateAdapter.setLocale(locale));
|
||||
.subscribe((locale) => this.dateAdapter.setLocale(locale));
|
||||
|
||||
const momentDateAdapter = this.dateAdapter as MomentDateAdapter;
|
||||
momentDateAdapter.overrideDisplayFormat = this.DATE_TIME_FORMAT;
|
||||
@@ -87,7 +79,7 @@ export class DateTimeEditorComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
onDateChanged(newDateValue) {
|
||||
if (newDateValue && newDateValue.value) {
|
||||
if (newDateValue?.value) {
|
||||
const newValue = moment(newDateValue.value, this.DATE_TIME_FORMAT);
|
||||
this.row.value[this.column.id] = newDateValue.value.format(this.DATE_TIME_FORMAT);
|
||||
this.value = newValue;
|
||||
@@ -101,5 +93,4 @@ export class DateTimeEditorComponent implements OnInit, OnDestroy {
|
||||
this.row.value[this.column.id] = '';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -17,14 +17,14 @@
|
||||
|
||||
/* eslint-disable @angular-eslint/component-selector */
|
||||
|
||||
import { LogService, FormService } from '@alfresco/adf-core';
|
||||
import { LogService, FormService, FormFieldModel } from '@alfresco/adf-core';
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { DynamicTableColumnOption } from '../models/dynamic-table-column-option.model';
|
||||
import { DynamicTableColumn } from '../models/dynamic-table-column.model';
|
||||
import { DynamicTableRow } from '../models/dynamic-table-row.model';
|
||||
import { DynamicTableModel } from '../models/dynamic-table.widget.model';
|
||||
import { ProcessDefinitionService } from '../../../../services/process-definition.service';
|
||||
import { TaskFormService } from '../../../../services/task-form.service';
|
||||
import { TaskFormService } from '../../../../services/task-form.service';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-dropdown-editor',
|
||||
@@ -32,7 +32,6 @@ import { TaskFormService } from '../../../../services/task-form.service';
|
||||
styleUrls: ['./dropdown.editor.scss']
|
||||
})
|
||||
export class DropdownEditorComponent implements OnInit {
|
||||
|
||||
value: any = null;
|
||||
options: DynamicTableColumnOption[] = [];
|
||||
|
||||
@@ -45,17 +44,18 @@ export class DropdownEditorComponent implements OnInit {
|
||||
@Input()
|
||||
column: DynamicTableColumn;
|
||||
|
||||
constructor(public formService: FormService,
|
||||
private taskFormService: TaskFormService,
|
||||
private processDefinitionService: ProcessDefinitionService,
|
||||
private logService: LogService) {
|
||||
}
|
||||
constructor(
|
||||
public formService: FormService,
|
||||
private taskFormService: TaskFormService,
|
||||
private processDefinitionService: ProcessDefinitionService,
|
||||
private logService: LogService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
const field = this.table.field;
|
||||
if (field) {
|
||||
if (this.column.optionType === 'rest') {
|
||||
if (this.table.form && this.table.form.taskId) {
|
||||
if (this.table.form?.taskId) {
|
||||
this.getValuesByTaskId(field);
|
||||
} else {
|
||||
this.getValuesByProcessDefinitionId(field);
|
||||
@@ -67,38 +67,26 @@ export class DropdownEditorComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
getValuesByTaskId(field) {
|
||||
this.taskFormService
|
||||
.getRestFieldValuesColumn(
|
||||
field.form.taskId,
|
||||
field.id,
|
||||
this.column.id
|
||||
)
|
||||
.subscribe(
|
||||
(dynamicTableColumnOption: DynamicTableColumnOption[]) => {
|
||||
this.column.options = dynamicTableColumnOption || [];
|
||||
this.options = this.column.options;
|
||||
this.value = this.table.getCellValue(this.row, this.column);
|
||||
},
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
getValuesByTaskId(field: FormFieldModel) {
|
||||
this.taskFormService.getRestFieldValuesColumn(field.form.taskId, field.id, this.column.id).subscribe(
|
||||
(dynamicTableColumnOption) => {
|
||||
this.column.options = dynamicTableColumnOption || [];
|
||||
this.options = this.column.options;
|
||||
this.value = this.table.getCellValue(this.row, this.column);
|
||||
},
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
}
|
||||
|
||||
getValuesByProcessDefinitionId(field) {
|
||||
this.processDefinitionService
|
||||
.getRestFieldValuesColumnByProcessId(
|
||||
field.form.processDefinitionId,
|
||||
field.id,
|
||||
this.column.id
|
||||
)
|
||||
.subscribe(
|
||||
(dynamicTableColumnOption: DynamicTableColumnOption[]) => {
|
||||
this.column.options = dynamicTableColumnOption || [];
|
||||
this.options = this.column.options;
|
||||
this.value = this.table.getCellValue(this.row, this.column);
|
||||
},
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
getValuesByProcessDefinitionId(field: FormFieldModel) {
|
||||
this.processDefinitionService.getRestFieldValuesColumnByProcessId(field.form.processDefinitionId, field.id, this.column.id).subscribe(
|
||||
(dynamicTableColumnOption) => {
|
||||
this.column.options = dynamicTableColumnOption || [];
|
||||
this.options = this.column.options;
|
||||
this.value = this.table.getCellValue(this.row, this.column);
|
||||
},
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
}
|
||||
|
||||
onValueChanged(row: DynamicTableRow, column: DynamicTableColumn, event: any) {
|
||||
|
@@ -24,17 +24,13 @@ import { DynamicTableColumn } from './dynamic-table-column.model';
|
||||
import { DynamicTableRow } from './dynamic-table-row.model';
|
||||
|
||||
export class DateCellValidator implements CellValidator {
|
||||
|
||||
private supportedTypes: string[] = [
|
||||
'Date'
|
||||
];
|
||||
private supportedTypes: string[] = ['Date'];
|
||||
|
||||
isSupported(column: DynamicTableColumn): boolean {
|
||||
return column && column.editable && this.supportedTypes.indexOf(column.type) > -1;
|
||||
return column?.editable && this.supportedTypes.indexOf(column.type) > -1;
|
||||
}
|
||||
|
||||
validate(row: DynamicTableRow, column: DynamicTableColumn, summary?: DynamicRowValidationSummary): boolean {
|
||||
|
||||
if (this.isSupported(column)) {
|
||||
const value = row.value[column.id];
|
||||
|
||||
|
@@ -29,7 +29,6 @@ import { NumberCellValidator } from './number-cell-validator.model';
|
||||
import { RequiredCellValidator } from './required-cell-validator.model';
|
||||
|
||||
export class DynamicTableModel extends FormWidgetModel {
|
||||
|
||||
field: FormFieldModel;
|
||||
columns: DynamicTableColumn[] = [];
|
||||
visibleColumns: DynamicTableColumn[] = [];
|
||||
@@ -49,7 +48,7 @@ export class DynamicTableModel extends FormWidgetModel {
|
||||
return;
|
||||
}
|
||||
|
||||
this.rows.forEach((row) => row.selected = false);
|
||||
this.rows.forEach((row) => (row.selected = false));
|
||||
|
||||
this._selectedRow = value;
|
||||
|
||||
@@ -70,19 +69,15 @@ export class DynamicTableModel extends FormWidgetModel {
|
||||
}
|
||||
|
||||
if (field.json.value) {
|
||||
this.rows = field.json.value.map((obj) => ({selected: false, value: obj} as DynamicTableRow));
|
||||
this.rows = field.json.value.map((obj) => ({ selected: false, value: obj } as DynamicTableRow));
|
||||
}
|
||||
}
|
||||
|
||||
this._validators = [
|
||||
new RequiredCellValidator(),
|
||||
new DateCellValidator(),
|
||||
new NumberCellValidator()
|
||||
];
|
||||
this._validators = [new RequiredCellValidator(), new DateCellValidator(), new NumberCellValidator()];
|
||||
}
|
||||
|
||||
private getColumns(field: FormFieldModel): DynamicTableColumn[] {
|
||||
if (field && field.json) {
|
||||
if (field?.json) {
|
||||
let definitions = field.json.columnDefinitions;
|
||||
if (!definitions && field.json.params && field.json.params.field) {
|
||||
definitions = field.json.params.field.columnDefinitions;
|
||||
@@ -105,7 +100,7 @@ export class DynamicTableModel extends FormWidgetModel {
|
||||
moveRow(row: DynamicTableRow, offset: number) {
|
||||
const oldIndex = this.rows.indexOf(row);
|
||||
if (oldIndex > -1) {
|
||||
let newIndex = (oldIndex + offset);
|
||||
let newIndex = oldIndex + offset;
|
||||
|
||||
if (newIndex < 0) {
|
||||
newIndex = 0;
|
||||
|
@@ -23,14 +23,10 @@ import { DynamicTableColumn } from './dynamic-table-column.model';
|
||||
import { DynamicTableRow } from './dynamic-table-row.model';
|
||||
|
||||
export class NumberCellValidator implements CellValidator {
|
||||
|
||||
private supportedTypes: string[] = [
|
||||
'Number',
|
||||
'Amount'
|
||||
];
|
||||
private supportedTypes: string[] = ['Number', 'Amount'];
|
||||
|
||||
isSupported(column: DynamicTableColumn): boolean {
|
||||
return column && column.required && this.supportedTypes.indexOf(column.type) > -1;
|
||||
return column?.required && this.supportedTypes.indexOf(column.type) > -1;
|
||||
}
|
||||
|
||||
isNumber(value: any): boolean {
|
||||
@@ -42,13 +38,9 @@ export class NumberCellValidator implements CellValidator {
|
||||
}
|
||||
|
||||
validate(row: DynamicTableRow, column: DynamicTableColumn, summary?: DynamicRowValidationSummary): boolean {
|
||||
|
||||
if (this.isSupported(column)) {
|
||||
const value = row.value[column.id];
|
||||
if (value === null ||
|
||||
value === undefined ||
|
||||
value === '' ||
|
||||
this.isNumber(value)) {
|
||||
if (value === null || value === undefined || value === '' || this.isNumber(value)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -23,17 +23,10 @@ import { DynamicTableColumn } from './dynamic-table-column.model';
|
||||
import { DynamicTableRow } from './dynamic-table-row.model';
|
||||
|
||||
export class RequiredCellValidator implements CellValidator {
|
||||
|
||||
private supportedTypes: string[] = [
|
||||
'String',
|
||||
'Number',
|
||||
'Amount',
|
||||
'Date',
|
||||
'Dropdown'
|
||||
];
|
||||
private supportedTypes: string[] = ['String', 'Number', 'Amount', 'Date', 'Dropdown'];
|
||||
|
||||
isSupported(column: DynamicTableColumn): boolean {
|
||||
return column && column.required && this.supportedTypes.indexOf(column.type) > -1;
|
||||
return column?.required && this.supportedTypes.indexOf(column.type) > -1;
|
||||
}
|
||||
|
||||
validate(row: DynamicTableRow, column: DynamicTableColumn, summary?: DynamicRowValidationSummary): boolean {
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* eslint-disable @angular-eslint/component-selector */
|
||||
/* eslint-disable @angular-eslint/component-selector */
|
||||
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { DynamicRowValidationSummary } from '../models/dynamic-row-validation-summary.model';
|
||||
@@ -29,7 +29,6 @@ import { DynamicTableModel } from '../models/dynamic-table.widget.model';
|
||||
styleUrls: ['./row.editor.css']
|
||||
})
|
||||
export class RowEditorComponent {
|
||||
|
||||
@Input()
|
||||
table: DynamicTableModel;
|
||||
|
||||
@@ -71,11 +70,10 @@ export class RowEditorComponent {
|
||||
}
|
||||
|
||||
private isValid(): boolean {
|
||||
return this.validationSummary && this.validationSummary.isValid;
|
||||
return this.validationSummary?.isValid;
|
||||
}
|
||||
|
||||
private validate() {
|
||||
this.validationSummary = this.table.validateRow(this.row);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -42,7 +42,6 @@ import { PeopleProcessService } from '../../../common/services/people-process.se
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class FunctionalGroupWidgetComponent extends WidgetComponent implements OnInit {
|
||||
|
||||
minTermLength: number = 1;
|
||||
groupId: string;
|
||||
searchTerm = new UntypedFormControl();
|
||||
@@ -50,30 +49,26 @@ export class FunctionalGroupWidgetComponent extends WidgetComponent implements O
|
||||
tap((search: GroupModel | string) => {
|
||||
const isValid = typeof search !== 'string';
|
||||
const empty = search === '';
|
||||
this.updateOption(isValid ? search as GroupModel : null);
|
||||
this.updateOption(isValid ? (search as GroupModel) : null);
|
||||
this.validateGroup(isValid, empty);
|
||||
}),
|
||||
filter((group: string | GroupModel) => typeof group === 'string' && group.length >= this.minTermLength),
|
||||
debounceTime(300),
|
||||
switchMap((searchTerm: string) => this.peopleProcessService.getWorkflowGroups(searchTerm, this.groupId)
|
||||
.pipe(catchError(() => of([]))))
|
||||
switchMap((searchTerm: string) => this.peopleProcessService.getWorkflowGroups(searchTerm, this.groupId).pipe(catchError(() => of([]))))
|
||||
);
|
||||
|
||||
constructor(public peopleProcessService: PeopleProcessService,
|
||||
public formService: FormService,
|
||||
public elementRef: ElementRef) {
|
||||
constructor(public peopleProcessService: PeopleProcessService, public formService: FormService, public elementRef: ElementRef) {
|
||||
super(formService);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.field) {
|
||||
|
||||
if (this.field.readOnly) {
|
||||
this.searchTerm.disable();
|
||||
}
|
||||
|
||||
const params = this.field.params;
|
||||
if (params && params.restrictWithGroup) {
|
||||
if (params?.restrictWithGroup) {
|
||||
const restrictWithGroup = params.restrictWithGroup;
|
||||
this.groupId = restrictWithGroup.id;
|
||||
}
|
||||
|
@@ -21,13 +21,7 @@ import { FormService, WidgetComponent } from '@alfresco/adf-core';
|
||||
import { Component, ElementRef, EventEmitter, OnInit, Output, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||
import { UntypedFormControl } from '@angular/forms';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import {
|
||||
catchError,
|
||||
distinctUntilChanged,
|
||||
map,
|
||||
switchMap,
|
||||
tap
|
||||
} from 'rxjs/operators';
|
||||
import { catchError, distinctUntilChanged, map, switchMap, tap } from 'rxjs/operators';
|
||||
import { UserProcessModel } from '../../../common/models/user-process.model';
|
||||
import { PeopleProcessService } from '../../../common/services/people-process.service';
|
||||
|
||||
@@ -49,7 +43,6 @@ import { PeopleProcessService } from '../../../common/services/people-process.se
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class PeopleWidgetComponent extends WidgetComponent implements OnInit {
|
||||
|
||||
@ViewChild('inputValue', { static: true })
|
||||
input: ElementRef;
|
||||
|
||||
@@ -71,8 +64,7 @@ export class PeopleWidgetComponent extends WidgetComponent implements OnInit {
|
||||
distinctUntilChanged(),
|
||||
switchMap((searchTerm) => {
|
||||
const value = searchTerm.email ? this.getDisplayName(searchTerm) : searchTerm;
|
||||
return this.peopleProcessService.getWorkflowUsers(undefined, value, this.groupId)
|
||||
.pipe(catchError(() => of([])));
|
||||
return this.peopleProcessService.getWorkflowUsers(undefined, value, this.groupId).pipe(catchError(() => of([])));
|
||||
}),
|
||||
map((list: UserProcessModel[]) => {
|
||||
const value = this.searchTerm.value.email ? this.getDisplayName(this.searchTerm.value) : this.searchTerm.value;
|
||||
@@ -94,7 +86,7 @@ export class PeopleWidgetComponent extends WidgetComponent implements OnInit {
|
||||
this.searchTerm.disable();
|
||||
}
|
||||
const params = this.field.params;
|
||||
if (params && params.restrictWithGroup) {
|
||||
if (params?.restrictWithGroup) {
|
||||
const restrictWithGroup = params.restrictWithGroup;
|
||||
this.groupId = restrictWithGroup.id;
|
||||
}
|
||||
@@ -119,7 +111,7 @@ export class PeopleWidgetComponent extends WidgetComponent implements OnInit {
|
||||
return !!users.find((user) => {
|
||||
const selectedUser = this.getDisplayName(user).toLocaleLowerCase() === name.toLocaleLowerCase();
|
||||
if (selectedUser) {
|
||||
this.peopleSelected.emit(user && user.id || undefined);
|
||||
this.peopleSelected.emit(user?.id || undefined);
|
||||
}
|
||||
return selectedUser;
|
||||
});
|
||||
|
@@ -17,7 +17,7 @@
|
||||
|
||||
/* eslint-disable @angular-eslint/component-selector */
|
||||
|
||||
import { LogService, FormService, FormFieldOption, WidgetComponent } from '@alfresco/adf-core';
|
||||
import { LogService, FormService, WidgetComponent } from '@alfresco/adf-core';
|
||||
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { TaskFormService } from '../../services/task-form.service';
|
||||
import { ProcessDefinitionService } from '../../services/process-definition.service';
|
||||
@@ -40,16 +40,17 @@ import { ProcessDefinitionService } from '../../services/process-definition.serv
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class RadioButtonsWidgetComponent extends WidgetComponent implements OnInit {
|
||||
|
||||
constructor(public formService: FormService,
|
||||
private taskFormService: TaskFormService,
|
||||
private processDefinitionService: ProcessDefinitionService,
|
||||
private logService: LogService) {
|
||||
constructor(
|
||||
public formService: FormService,
|
||||
private taskFormService: TaskFormService,
|
||||
private processDefinitionService: ProcessDefinitionService,
|
||||
private logService: LogService
|
||||
) {
|
||||
super(formService);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.field && this.field.restUrl) {
|
||||
if (this.field?.restUrl) {
|
||||
if (this.field.form.taskId) {
|
||||
this.getOptionsByTaskId();
|
||||
} else {
|
||||
@@ -59,33 +60,23 @@ export class RadioButtonsWidgetComponent extends WidgetComponent implements OnIn
|
||||
}
|
||||
|
||||
getOptionsByTaskId() {
|
||||
this.taskFormService
|
||||
.getRestFieldValues(
|
||||
this.field.form.taskId,
|
||||
this.field.id
|
||||
)
|
||||
.subscribe(
|
||||
(formFieldOption: FormFieldOption[]) => {
|
||||
this.field.options = formFieldOption || [];
|
||||
this.field.updateForm();
|
||||
},
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
this.taskFormService.getRestFieldValues(this.field.form.taskId, this.field.id).subscribe(
|
||||
(formFieldOption) => {
|
||||
this.field.options = formFieldOption || [];
|
||||
this.field.updateForm();
|
||||
},
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
}
|
||||
|
||||
getOptionsByProcessDefinitionId() {
|
||||
this.processDefinitionService
|
||||
.getRestFieldValuesByProcessId(
|
||||
this.field.form.processDefinitionId,
|
||||
this.field.id
|
||||
)
|
||||
.subscribe(
|
||||
(formFieldOption: FormFieldOption[]) => {
|
||||
this.field.options = formFieldOption || [];
|
||||
this.field.updateForm();
|
||||
},
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
this.processDefinitionService.getRestFieldValuesByProcessId(this.field.form.processDefinitionId, this.field.id).subscribe(
|
||||
(formFieldOption) => {
|
||||
this.field.options = formFieldOption || [];
|
||||
this.field.updateForm();
|
||||
},
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
}
|
||||
|
||||
onOptionClick(optionSelected: any) {
|
||||
@@ -96,5 +87,4 @@ export class RadioButtonsWidgetComponent extends WidgetComponent implements OnIn
|
||||
handleError(error: any) {
|
||||
this.logService.error(error);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -41,16 +41,17 @@ import { ProcessDefinitionService } from '../../services/process-definition.serv
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class TypeaheadWidgetComponent extends WidgetComponent implements OnInit {
|
||||
|
||||
minTermLength: number = 1;
|
||||
value: string;
|
||||
oldValue: string;
|
||||
options: FormFieldOption[] = [];
|
||||
|
||||
constructor(public formService: FormService,
|
||||
private taskFormService: TaskFormService,
|
||||
private processDefinitionService: ProcessDefinitionService,
|
||||
private logService: LogService) {
|
||||
constructor(
|
||||
public formService: FormService,
|
||||
private taskFormService: TaskFormService,
|
||||
private processDefinitionService: ProcessDefinitionService,
|
||||
private logService: LogService
|
||||
) {
|
||||
super(formService);
|
||||
}
|
||||
|
||||
@@ -66,53 +67,45 @@ export class TypeaheadWidgetComponent extends WidgetComponent implements OnInit
|
||||
}
|
||||
|
||||
getValuesByTaskId() {
|
||||
this.taskFormService
|
||||
.getRestFieldValues(
|
||||
this.field.form.taskId,
|
||||
this.field.id
|
||||
)
|
||||
.subscribe(
|
||||
(formFieldOption: FormFieldOption[]) => {
|
||||
const options = formFieldOption || [];
|
||||
this.field.options = options;
|
||||
this.taskFormService.getRestFieldValues(this.field.form.taskId, this.field.id).subscribe(
|
||||
(formFieldOption) => {
|
||||
const options = formFieldOption || [];
|
||||
this.field.options = options;
|
||||
|
||||
const fieldValue = this.field.value;
|
||||
if (fieldValue) {
|
||||
const toSelect = options.find((item) => item.id === fieldValue || item.name.toLocaleLowerCase() === fieldValue.toLocaleLowerCase());
|
||||
if (toSelect) {
|
||||
this.value = toSelect.name;
|
||||
}
|
||||
const fieldValue = this.field.value;
|
||||
if (fieldValue) {
|
||||
const toSelect = options.find(
|
||||
(item) => item.id === fieldValue || item.name.toLocaleLowerCase() === fieldValue.toLocaleLowerCase()
|
||||
);
|
||||
if (toSelect) {
|
||||
this.value = toSelect.name;
|
||||
}
|
||||
this.onFieldChanged(this.field);
|
||||
this.field.updateForm();
|
||||
},
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
}
|
||||
this.onFieldChanged(this.field);
|
||||
this.field.updateForm();
|
||||
},
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
}
|
||||
|
||||
getValuesByProcessDefinitionId() {
|
||||
this.processDefinitionService
|
||||
.getRestFieldValuesByProcessId(
|
||||
this.field.form.processDefinitionId,
|
||||
this.field.id
|
||||
)
|
||||
.subscribe(
|
||||
(formFieldOption: FormFieldOption[]) => {
|
||||
const options = formFieldOption || [];
|
||||
this.field.options = options;
|
||||
this.processDefinitionService.getRestFieldValuesByProcessId(this.field.form.processDefinitionId, this.field.id).subscribe(
|
||||
(formFieldOption) => {
|
||||
const options = formFieldOption || [];
|
||||
this.field.options = options;
|
||||
|
||||
const fieldValue = this.field.value;
|
||||
if (fieldValue) {
|
||||
const toSelect = options.find((item) => item.id === fieldValue);
|
||||
if (toSelect) {
|
||||
this.value = toSelect.name;
|
||||
}
|
||||
const fieldValue = this.field.value;
|
||||
if (fieldValue) {
|
||||
const toSelect = options.find((item) => item.id === fieldValue);
|
||||
if (toSelect) {
|
||||
this.value = toSelect.name;
|
||||
}
|
||||
this.onFieldChanged(this.field);
|
||||
this.field.updateForm();
|
||||
},
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
}
|
||||
this.onFieldChanged(this.field);
|
||||
this.field.updateForm();
|
||||
},
|
||||
(err) => this.handleError(err)
|
||||
);
|
||||
}
|
||||
|
||||
getOptions(): FormFieldOption[] {
|
||||
@@ -169,5 +162,4 @@ export class TypeaheadWidgetComponent extends WidgetComponent implements OnInit
|
||||
isReadOnlyType(): boolean {
|
||||
return this.field.type === 'readonly';
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -41,7 +41,6 @@ import { mergeMap, map } from 'rxjs/operators';
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class UploadWidgetComponent extends WidgetComponent implements OnInit {
|
||||
|
||||
hasFile: boolean;
|
||||
displayText: string;
|
||||
multipleOption: string = '';
|
||||
@@ -50,17 +49,17 @@ export class UploadWidgetComponent extends WidgetComponent implements OnInit {
|
||||
@ViewChild('uploadFiles')
|
||||
fileInput: ElementRef;
|
||||
|
||||
constructor(public formService: FormService,
|
||||
private logService: LogService,
|
||||
private thumbnailService: ThumbnailService,
|
||||
public processContentService: ProcessContentService) {
|
||||
constructor(
|
||||
public formService: FormService,
|
||||
private logService: LogService,
|
||||
private thumbnailService: ThumbnailService,
|
||||
public processContentService: ProcessContentService
|
||||
) {
|
||||
super(formService);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.field &&
|
||||
this.field.value &&
|
||||
this.field.value.length > 0) {
|
||||
if (this.field?.value?.length > 0) {
|
||||
this.hasFile = true;
|
||||
}
|
||||
this.getMultipleFileParam();
|
||||
@@ -96,20 +95,17 @@ export class UploadWidgetComponent extends WidgetComponent implements OnInit {
|
||||
}
|
||||
|
||||
private uploadRawContent(file): Observable<any> {
|
||||
return this.processContentService.createTemporaryRawRelatedContent(file)
|
||||
.pipe(
|
||||
map((response: any) => {
|
||||
this.logService.info(response);
|
||||
response.contentBlob = file;
|
||||
return response;
|
||||
})
|
||||
);
|
||||
return this.processContentService.createTemporaryRawRelatedContent(file).pipe(
|
||||
map((response: any) => {
|
||||
this.logService.info(response);
|
||||
response.contentBlob = file;
|
||||
return response;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
getMultipleFileParam() {
|
||||
if (this.field &&
|
||||
this.field.params &&
|
||||
this.field.params.multiple) {
|
||||
if (this.field?.params?.multiple) {
|
||||
this.multipleOption = this.field.params.multiple ? 'multiple' : '';
|
||||
}
|
||||
}
|
||||
|
@@ -39,15 +39,19 @@ export const fakeProcessFilters = [
|
||||
];
|
||||
|
||||
export const fakeProcessFiltersResponse = {
|
||||
size: 1, total: 1, start: 0,
|
||||
data: [new FilterProcessRepresentationModel({
|
||||
name: 'Running',
|
||||
appId: '22',
|
||||
id: 333,
|
||||
recent: true,
|
||||
icon: 'glyphicon-random',
|
||||
filter: { sort: 'created-desc', name: '', state: 'running' }
|
||||
})]
|
||||
size: 1,
|
||||
total: 1,
|
||||
start: 0,
|
||||
data: [
|
||||
new FilterProcessRepresentationModel({
|
||||
name: 'Running',
|
||||
appId: '22',
|
||||
id: 333,
|
||||
recent: true,
|
||||
icon: 'glyphicon-random',
|
||||
filter: { sort: 'created-desc', name: '', state: 'running' }
|
||||
})
|
||||
]
|
||||
};
|
||||
|
||||
export const dummyRunningFilter = {
|
||||
@@ -58,9 +62,7 @@ export const dummyRunningFilter = {
|
||||
id: 18,
|
||||
index: 10,
|
||||
recent: false,
|
||||
hasFilter: () => {
|
||||
return true;
|
||||
}
|
||||
hasFilter: () => true
|
||||
};
|
||||
|
||||
export const dummyCompletedFilter = {
|
||||
@@ -71,9 +73,7 @@ export const dummyCompletedFilter = {
|
||||
id: 19,
|
||||
index: 11,
|
||||
recent: false,
|
||||
hasFilter: () => {
|
||||
return true;
|
||||
}
|
||||
hasFilter: () => true
|
||||
};
|
||||
|
||||
export const dummyAllFilter = {
|
||||
@@ -84,9 +84,7 @@ export const dummyAllFilter = {
|
||||
id: 20,
|
||||
index: 12,
|
||||
recent: false,
|
||||
hasFilter: () => {
|
||||
return true;
|
||||
}
|
||||
hasFilter: () => true
|
||||
};
|
||||
|
||||
export const dummyDuplicateRunningFilter = {
|
||||
@@ -97,7 +95,5 @@ export const dummyDuplicateRunningFilter = {
|
||||
id: 21,
|
||||
index: 13,
|
||||
recent: false,
|
||||
hasFilter: () => {
|
||||
return true;
|
||||
}
|
||||
hasFilter: () => true
|
||||
};
|
||||
|
@@ -18,14 +18,22 @@
|
||||
import { FilterRepresentationModel, TaskQueryRequestRepresentationModel } from '../../task-list/models/filter.model';
|
||||
|
||||
export const fakeFiltersResponse: any = {
|
||||
size: 2, total: 2, start: 0,
|
||||
size: 2,
|
||||
total: 2,
|
||||
start: 0,
|
||||
data: [
|
||||
{
|
||||
id: 1, name: 'FakeInvolvedTasks', recent: false, icon: 'glyphicon-align-left',
|
||||
id: 1,
|
||||
name: 'FakeInvolvedTasks',
|
||||
recent: false,
|
||||
icon: 'glyphicon-align-left',
|
||||
filter: { sort: 'created-desc', name: '', state: 'open', assignment: 'fake-involved' }
|
||||
},
|
||||
{
|
||||
id: 2, name: 'FakeMyTasks', recent: false, icon: 'glyphicon-align-left',
|
||||
id: 2,
|
||||
name: 'FakeMyTasks',
|
||||
recent: false,
|
||||
icon: 'glyphicon-align-left',
|
||||
filter: { sort: 'created-desc', name: '', state: 'open', assignment: 'fake-assignee' }
|
||||
}
|
||||
]
|
||||
@@ -53,10 +61,15 @@ export const fakeTaskFilters = [
|
||||
];
|
||||
|
||||
export const fakeAppFilter = {
|
||||
size: 1, total: 1, start: 0,
|
||||
size: 1,
|
||||
total: 1,
|
||||
start: 0,
|
||||
data: [
|
||||
{
|
||||
id: 1, name: 'FakeInvolvedTasks', recent: false, icon: 'glyphicon-align-left',
|
||||
id: 1,
|
||||
name: 'FakeInvolvedTasks',
|
||||
recent: false,
|
||||
icon: 'glyphicon-align-left',
|
||||
filter: { sort: 'created-desc', name: '', state: 'open', assignment: 'fake-involved' }
|
||||
}
|
||||
]
|
||||
@@ -111,9 +124,7 @@ export const dummyMyTasksFilter = {
|
||||
id: 81,
|
||||
index: 21,
|
||||
recent: false,
|
||||
hasFilter: () => {
|
||||
return true;
|
||||
}
|
||||
hasFilter: () => true
|
||||
};
|
||||
|
||||
export const dummyInvolvedTasksFilter = {
|
||||
@@ -124,9 +135,7 @@ export const dummyInvolvedTasksFilter = {
|
||||
id: 82,
|
||||
index: 22,
|
||||
recent: false,
|
||||
hasFilter: () => {
|
||||
return true;
|
||||
}
|
||||
hasFilter: () => true
|
||||
};
|
||||
|
||||
export const dummyQueuedTasksFilter = {
|
||||
@@ -137,9 +146,7 @@ export const dummyQueuedTasksFilter = {
|
||||
id: 83,
|
||||
index: 23,
|
||||
recent: false,
|
||||
hasFilter: () => {
|
||||
return true;
|
||||
}
|
||||
hasFilter: () => true
|
||||
};
|
||||
|
||||
export const dummyCompletedTasksFilter = {
|
||||
@@ -150,9 +157,7 @@ export const dummyCompletedTasksFilter = {
|
||||
id: 84,
|
||||
index: 24,
|
||||
recent: false,
|
||||
hasFilter: () => {
|
||||
return true;
|
||||
}
|
||||
hasFilter: () => true
|
||||
};
|
||||
|
||||
export const dummyDuplicateMyTasksFilter = {
|
||||
@@ -163,7 +168,5 @@ export const dummyDuplicateMyTasksFilter = {
|
||||
id: 85,
|
||||
index: 25,
|
||||
recent: false,
|
||||
hasFilter: () => {
|
||||
return true;
|
||||
}
|
||||
hasFilter: () => true
|
||||
};
|
||||
|
@@ -32,9 +32,7 @@ import { UserProcessModel } from '../../../common/models/user-process.model';
|
||||
host: { class: 'adf-people-search-field' },
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
|
||||
export class PeopleSearchFieldComponent {
|
||||
|
||||
@Input()
|
||||
performSearch: PerformSearchCallback;
|
||||
|
||||
@@ -49,19 +47,17 @@ export class PeopleSearchFieldComponent {
|
||||
|
||||
defaultPlaceholder = 'ADF_TASK_LIST.PEOPLE.SEARCH_USER';
|
||||
|
||||
constructor(public peopleProcessService: PeopleProcessService,
|
||||
private translationService: TranslationService) {
|
||||
this.users$ = this.searchUser.valueChanges
|
||||
.pipe(
|
||||
debounceTime(200),
|
||||
switchMap((searchWord: string) => {
|
||||
if (searchWord && searchWord.trim()) {
|
||||
return this.performSearch(searchWord);
|
||||
} else {
|
||||
return of([]);
|
||||
}
|
||||
})
|
||||
);
|
||||
constructor(public peopleProcessService: PeopleProcessService, private translationService: TranslationService) {
|
||||
this.users$ = this.searchUser.valueChanges.pipe(
|
||||
debounceTime(200),
|
||||
switchMap((searchWord: string) => {
|
||||
if (searchWord?.trim()) {
|
||||
return this.performSearch(searchWord);
|
||||
} else {
|
||||
return of([]);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
this.defaultPlaceholder = this.translationService.instant(this.defaultPlaceholder);
|
||||
}
|
||||
@@ -83,8 +79,8 @@ export class PeopleSearchFieldComponent {
|
||||
}
|
||||
|
||||
getInitialUserName(firstName: string, lastName: string): string {
|
||||
firstName = (firstName !== null && firstName !== '' ? firstName[0] : '');
|
||||
lastName = (lastName !== null && lastName !== '' ? lastName[0] : '');
|
||||
firstName = firstName !== null && firstName !== '' ? firstName[0] : '';
|
||||
lastName = lastName !== null && lastName !== '' ? lastName[0] : '';
|
||||
return this.getDisplayUser(firstName, lastName, '');
|
||||
}
|
||||
}
|
||||
|
@@ -34,9 +34,7 @@ const DEFAULT_ASSIGNEE_PLACEHOLDER = 'ADF_TASK_LIST.PEOPLE.ASSIGNEE';
|
||||
host: { class: 'adf-people-selector' },
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
|
||||
export class PeopleSelectorComponent {
|
||||
|
||||
@Input()
|
||||
peopleId: UserProcessModel;
|
||||
|
||||
@@ -51,21 +49,14 @@ export class PeopleSelectorComponent {
|
||||
selectedUser: UserProcessModel;
|
||||
defaultPlaceholder: string;
|
||||
|
||||
constructor(
|
||||
private peopleProcessService: PeopleProcessService,
|
||||
private logService: LogService,
|
||||
private translationService: TranslationService) {
|
||||
|
||||
constructor(private peopleProcessService: PeopleProcessService, private logService: LogService, private translationService: TranslationService) {
|
||||
this.peopleIdChange = new EventEmitter();
|
||||
this.performSearch = this.searchUser.bind(this);
|
||||
this.defaultPlaceholder = this.translationService.instant(DEFAULT_ASSIGNEE_PLACEHOLDER);
|
||||
}
|
||||
|
||||
searchUser(searchWord: string): Observable<any | UserProcessModel[]> {
|
||||
return this.peopleProcessService.getWorkflowUsers(undefined, searchWord)
|
||||
.pipe(
|
||||
catchError(this.onSearchUserError.bind(this))
|
||||
);
|
||||
return this.peopleProcessService.getWorkflowUsers(undefined, searchWord).pipe(catchError(this.onSearchUserError.bind(this)));
|
||||
}
|
||||
|
||||
userSelected(user: UserProcessModel): void {
|
||||
@@ -83,7 +74,7 @@ export class PeopleSelectorComponent {
|
||||
|
||||
private updateUserSelection(user: UserProcessModel): void {
|
||||
this.selectedUser = user;
|
||||
this.peopleIdChange.emit(user && user.id || undefined);
|
||||
this.peopleIdChange.emit(user?.id);
|
||||
this.searchFieldComponent.reset();
|
||||
}
|
||||
|
||||
|
@@ -29,7 +29,6 @@ import { share, takeUntil } from 'rxjs/operators';
|
||||
host: { class: 'adf-process-instance-comments' }
|
||||
})
|
||||
export class ProcessCommentsComponent implements OnChanges, OnDestroy {
|
||||
|
||||
/** (**required**) The numeric ID of the process instance to display comments for. */
|
||||
@Input()
|
||||
processInstanceId: string;
|
||||
@@ -42,7 +41,7 @@ export class ProcessCommentsComponent implements OnChanges, OnDestroy {
|
||||
@Output()
|
||||
error: EventEmitter<any> = new EventEmitter<any>();
|
||||
|
||||
comments: CommentModel [] = [];
|
||||
comments: CommentModel[] = [];
|
||||
comment$: Observable<CommentModel>;
|
||||
message: string;
|
||||
beingAdded: boolean = false;
|
||||
@@ -51,10 +50,8 @@ export class ProcessCommentsComponent implements OnChanges, OnDestroy {
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
constructor(private commentProcessService: CommentProcessService) {
|
||||
this.comment$ = new Observable<CommentModel>(observer => this.commentObserver = observer).pipe(share());
|
||||
this.comment$
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe(comment => 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() {
|
||||
@@ -74,21 +71,19 @@ export class ProcessCommentsComponent implements OnChanges, OnDestroy {
|
||||
}
|
||||
|
||||
add(): void {
|
||||
if (this.message && this.message.trim() && !this.beingAdded) {
|
||||
if (this.message?.trim() && !this.beingAdded) {
|
||||
this.beingAdded = true;
|
||||
this.commentProcessService.add(this.processInstanceId, this.message)
|
||||
.subscribe(
|
||||
(res: CommentModel) => {
|
||||
this.comments.unshift(res);
|
||||
this.message = '';
|
||||
this.beingAdded = false;
|
||||
|
||||
},
|
||||
(err) => {
|
||||
this.error.emit(err);
|
||||
this.beingAdded = false;
|
||||
}
|
||||
);
|
||||
this.commentProcessService.add(this.processInstanceId, this.message).subscribe(
|
||||
(res: CommentModel) => {
|
||||
this.comments.unshift(res);
|
||||
this.message = '';
|
||||
this.beingAdded = false;
|
||||
},
|
||||
(err) => {
|
||||
this.error.emit(err);
|
||||
this.beingAdded = false;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -33,7 +33,6 @@ import { Location } from '@angular/common';
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class ProcessFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
@@ -72,7 +71,7 @@ export class ProcessFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
currentFilter: ProcessInstanceFilterRepresentation;
|
||||
|
||||
filters: UserProcessInstanceFilterRepresentation [] = [];
|
||||
filters: UserProcessInstanceFilterRepresentation[] = [];
|
||||
active = false;
|
||||
isProcessRoute: boolean;
|
||||
isProcessActive: boolean;
|
||||
@@ -80,23 +79,24 @@ export class ProcessFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
private iconsMDL: IconModel;
|
||||
|
||||
constructor(private processFilterService: ProcessFilterService,
|
||||
private appsProcessService: AppsProcessService,
|
||||
private router: Router,
|
||||
private location: Location) {
|
||||
}
|
||||
constructor(
|
||||
private processFilterService: ProcessFilterService,
|
||||
private appsProcessService: AppsProcessService,
|
||||
private router: Router,
|
||||
private location: Location
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.iconsMDL = new IconModel();
|
||||
this.router.events
|
||||
.pipe(
|
||||
filter((event) => event instanceof NavigationStart),
|
||||
takeUntil(this.onDestroy$)
|
||||
)
|
||||
.subscribe((navigationStart: NavigationStart) => {
|
||||
const activeRoute = navigationStart.url;
|
||||
this.isProcessActive = activeRoute.includes('processes');
|
||||
});
|
||||
.pipe(
|
||||
filter((event) => event instanceof NavigationStart),
|
||||
takeUntil(this.onDestroy$)
|
||||
)
|
||||
.subscribe((navigationStart: NavigationStart) => {
|
||||
const activeRoute = navigationStart.url;
|
||||
this.isProcessActive = activeRoute.includes('processes');
|
||||
});
|
||||
const currentRoute = this.location.path();
|
||||
this.isProcessRoute = currentRoute.includes('processes');
|
||||
}
|
||||
@@ -108,7 +108,7 @@ export class ProcessFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
if (appId && (appId.currentValue || appId.currentValue === null)) {
|
||||
this.getFiltersByAppId(appId.currentValue);
|
||||
} else if (appName && appName.currentValue) {
|
||||
} else if (appName?.currentValue) {
|
||||
this.getFiltersByAppName(appName.currentValue);
|
||||
} else if (filterParam && filterParam.currentValue !== filterParam.previousValue) {
|
||||
this.selectProcessFilter(filterParam.currentValue);
|
||||
@@ -165,7 +165,8 @@ export class ProcessFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
},
|
||||
(err) => {
|
||||
this.error.emit(err);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -184,12 +185,12 @@ export class ProcessFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
*/
|
||||
selectProcessFilter(filterParam: FilterProcessRepresentationModel) {
|
||||
if (filterParam) {
|
||||
const newFilter = this.filters.find((processFilter, index) =>
|
||||
filterParam.index === index ||
|
||||
filterParam.id === processFilter.id ||
|
||||
(filterParam.name &&
|
||||
(filterParam.name.toLocaleLowerCase() === processFilter.name.toLocaleLowerCase())
|
||||
));
|
||||
const newFilter = this.filters.find(
|
||||
(processFilter, index) =>
|
||||
filterParam.index === index ||
|
||||
filterParam.id === processFilter.id ||
|
||||
(filterParam.name && filterParam.name.toLocaleLowerCase() === processFilter.name.toLocaleLowerCase())
|
||||
);
|
||||
this.currentFilter = newFilter;
|
||||
|
||||
if (newFilter) {
|
||||
|
@@ -31,7 +31,6 @@ import { ProcessInstanceTasksComponent } from './process-instance-tasks.componen
|
||||
styleUrls: ['./process-instance-details.component.css']
|
||||
})
|
||||
export class ProcessInstanceDetailsComponent implements OnChanges {
|
||||
|
||||
/** (required) The numeric ID of the process instance to display. */
|
||||
@Input()
|
||||
processInstanceId: string;
|
||||
@@ -71,12 +70,10 @@ export class ProcessInstanceDetailsComponent implements OnChanges {
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param translate Translation service
|
||||
* @param activitiProcess Process service
|
||||
* @param logService
|
||||
*/
|
||||
constructor(private activitiProcess: ProcessService,
|
||||
private logService: LogService) {
|
||||
}
|
||||
constructor(private activitiProcess: ProcessService, private logService: LogService) {}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
const processInstanceId = changes['processInstanceId'];
|
||||
@@ -84,7 +81,7 @@ export class ProcessInstanceDetailsComponent implements OnChanges {
|
||||
this.reset();
|
||||
return;
|
||||
}
|
||||
if (processInstanceId && processInstanceId.currentValue) {
|
||||
if (processInstanceId?.currentValue) {
|
||||
this.load(processInstanceId.currentValue);
|
||||
return;
|
||||
}
|
||||
@@ -99,11 +96,9 @@ export class ProcessInstanceDetailsComponent implements OnChanges {
|
||||
|
||||
load(processId: string) {
|
||||
if (processId) {
|
||||
this.activitiProcess.getProcess(processId).subscribe(
|
||||
(res: ProcessInstance) => {
|
||||
this.processInstanceDetails = res;
|
||||
}
|
||||
);
|
||||
this.activitiProcess.getProcess(processId).subscribe((res) => {
|
||||
this.processInstanceDetails = res;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,9 +110,11 @@ export class ProcessInstanceDetailsComponent implements OnChanges {
|
||||
this.activitiProcess.cancelProcess(this.processInstanceId).subscribe(
|
||||
(data) => {
|
||||
this.processCancelled.emit(data);
|
||||
}, (err) => {
|
||||
},
|
||||
(err) => {
|
||||
this.error.emit(err);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// bubbles (taskClick) event
|
||||
@@ -128,7 +125,8 @@ export class ProcessInstanceDetailsComponent implements OnChanges {
|
||||
getProcessNameOrDescription(dateFormat: string): string {
|
||||
let name = '';
|
||||
if (this.processInstanceDetails) {
|
||||
name = this.processInstanceDetails.name ||
|
||||
name =
|
||||
this.processInstanceDetails.name ||
|
||||
this.processInstanceDetails.processDefinitionName + ' - ' + this.getFormatDate(this.processInstanceDetails.started, dateFormat);
|
||||
}
|
||||
return name;
|
||||
@@ -144,7 +142,6 @@ export class ProcessInstanceDetailsComponent implements OnChanges {
|
||||
}
|
||||
|
||||
onShowProcessDiagram() {
|
||||
this.showProcessDiagram.emit({value: this.processInstanceId});
|
||||
this.showProcessDiagram.emit({ value: this.processInstanceId });
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -15,7 +15,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AppConfigService, CardViewDateItemModel, CardViewItem, CardViewBaseItemModel, CardViewTextItemModel, TranslationService } from '@alfresco/adf-core';
|
||||
import {
|
||||
AppConfigService,
|
||||
CardViewDateItemModel,
|
||||
CardViewItem,
|
||||
CardViewBaseItemModel,
|
||||
CardViewTextItemModel,
|
||||
TranslationService
|
||||
} from '@alfresco/adf-core';
|
||||
import { Component, Input, OnChanges } from '@angular/core';
|
||||
import { ProcessInstance } from '../models/process-instance.model';
|
||||
|
||||
@@ -25,17 +32,15 @@ import { ProcessInstance } from '../models/process-instance.model';
|
||||
styleUrls: ['./process-instance-header.component.css']
|
||||
})
|
||||
export class ProcessInstanceHeaderComponent implements OnChanges {
|
||||
|
||||
/** (**required**) Full details of the process instance to display information about. */
|
||||
@Input()
|
||||
processInstance: ProcessInstance;
|
||||
|
||||
properties: CardViewItem [];
|
||||
properties: CardViewItem[];
|
||||
dateFormat: string;
|
||||
dateLocale: string;
|
||||
|
||||
constructor(private translationService: TranslationService,
|
||||
private appConfig: AppConfigService) {
|
||||
constructor(private translationService: TranslationService, private appConfig: AppConfigService) {
|
||||
this.dateFormat = this.appConfig.get('dateValues.defaultDateFormat');
|
||||
this.dateLocale = this.appConfig.get('dateValues.defaultDateLocale');
|
||||
}
|
||||
@@ -61,7 +66,7 @@ export class ProcessInstanceHeaderComponent implements OnChanges {
|
||||
|
||||
getStartedByFullName(): string {
|
||||
let fullName = '';
|
||||
if (this.processInstance && this.processInstance.startedBy) {
|
||||
if (this.processInstance?.startedBy) {
|
||||
fullName += this.processInstance.startedBy.firstName || '';
|
||||
fullName += fullName ? ' ' : '';
|
||||
fullName += this.processInstance.startedBy.lastName || '';
|
||||
@@ -75,57 +80,47 @@ export class ProcessInstanceHeaderComponent implements OnChanges {
|
||||
|
||||
private initDefaultProperties(): any[] {
|
||||
return [
|
||||
new CardViewTextItemModel(
|
||||
{
|
||||
label: 'ADF_PROCESS_LIST.PROPERTIES.STATUS',
|
||||
value: this.getProcessStatus(),
|
||||
key: 'status'
|
||||
}),
|
||||
new CardViewDateItemModel(
|
||||
{
|
||||
label: 'ADF_PROCESS_LIST.PROPERTIES.END_DATE',
|
||||
value: this.processInstance.ended,
|
||||
format: this.dateFormat,
|
||||
locale: this.dateLocale,
|
||||
key: 'ended',
|
||||
default: this.translationService.instant('ADF_PROCESS_LIST.PROPERTIES.END_DATE_DEFAULT')
|
||||
}),
|
||||
new CardViewTextItemModel(
|
||||
{
|
||||
label: 'ADF_PROCESS_LIST.PROPERTIES.CATEGORY',
|
||||
value: this.processInstance.processDefinitionCategory,
|
||||
key: 'category',
|
||||
default: this.translationService.instant('ADF_PROCESS_LIST.PROPERTIES.CATEGORY_DEFAULT')
|
||||
}),
|
||||
new CardViewTextItemModel(
|
||||
{
|
||||
label: 'ADF_PROCESS_LIST.PROPERTIES.BUSINESS_KEY',
|
||||
value: this.processInstance.businessKey,
|
||||
key: 'businessKey',
|
||||
default: this.translationService.instant('ADF_PROCESS_LIST.PROPERTIES.BUSINESS_KEY_DEFAULT')
|
||||
}),
|
||||
new CardViewTextItemModel(
|
||||
{
|
||||
label: 'ADF_PROCESS_LIST.PROPERTIES.CREATED_BY',
|
||||
value: this.getStartedByFullName(),
|
||||
key: 'createdBy',
|
||||
default: this.translationService.instant('ADF_PROCESS_LIST.PROPERTIES.CREATED_BY_DEFAULT')
|
||||
}),
|
||||
new CardViewDateItemModel(
|
||||
{
|
||||
label: 'ADF_PROCESS_LIST.PROPERTIES.CREATED',
|
||||
value: this.processInstance.started,
|
||||
format: this.dateFormat,
|
||||
locale: this.dateLocale,
|
||||
key: 'created'
|
||||
}),
|
||||
new CardViewTextItemModel(
|
||||
{label: 'ADF_PROCESS_LIST.PROPERTIES.ID',
|
||||
value: this.processInstance.id,
|
||||
key: 'id'
|
||||
new CardViewTextItemModel({
|
||||
label: 'ADF_PROCESS_LIST.PROPERTIES.STATUS',
|
||||
value: this.getProcessStatus(),
|
||||
key: 'status'
|
||||
}),
|
||||
new CardViewTextItemModel(
|
||||
{label: 'ADF_PROCESS_LIST.PROPERTIES.DESCRIPTION',
|
||||
new CardViewDateItemModel({
|
||||
label: 'ADF_PROCESS_LIST.PROPERTIES.END_DATE',
|
||||
value: this.processInstance.ended,
|
||||
format: this.dateFormat,
|
||||
locale: this.dateLocale,
|
||||
key: 'ended',
|
||||
default: this.translationService.instant('ADF_PROCESS_LIST.PROPERTIES.END_DATE_DEFAULT')
|
||||
}),
|
||||
new CardViewTextItemModel({
|
||||
label: 'ADF_PROCESS_LIST.PROPERTIES.CATEGORY',
|
||||
value: this.processInstance.processDefinitionCategory,
|
||||
key: 'category',
|
||||
default: this.translationService.instant('ADF_PROCESS_LIST.PROPERTIES.CATEGORY_DEFAULT')
|
||||
}),
|
||||
new CardViewTextItemModel({
|
||||
label: 'ADF_PROCESS_LIST.PROPERTIES.BUSINESS_KEY',
|
||||
value: this.processInstance.businessKey,
|
||||
key: 'businessKey',
|
||||
default: this.translationService.instant('ADF_PROCESS_LIST.PROPERTIES.BUSINESS_KEY_DEFAULT')
|
||||
}),
|
||||
new CardViewTextItemModel({
|
||||
label: 'ADF_PROCESS_LIST.PROPERTIES.CREATED_BY',
|
||||
value: this.getStartedByFullName(),
|
||||
key: 'createdBy',
|
||||
default: this.translationService.instant('ADF_PROCESS_LIST.PROPERTIES.CREATED_BY_DEFAULT')
|
||||
}),
|
||||
new CardViewDateItemModel({
|
||||
label: 'ADF_PROCESS_LIST.PROPERTIES.CREATED',
|
||||
value: this.processInstance.started,
|
||||
format: this.dateFormat,
|
||||
locale: this.dateLocale,
|
||||
key: 'created'
|
||||
}),
|
||||
new CardViewTextItemModel({ label: 'ADF_PROCESS_LIST.PROPERTIES.ID', value: this.processInstance.id, key: 'id' }),
|
||||
new CardViewTextItemModel({
|
||||
label: 'ADF_PROCESS_LIST.PROPERTIES.DESCRIPTION',
|
||||
value: this.processInstance.processDefinitionDescription,
|
||||
key: 'description',
|
||||
default: this.translationService.instant('ADF_PROCESS_LIST.PROPERTIES.DESCRIPTION_DEFAULT')
|
||||
|
@@ -31,7 +31,6 @@ import { share, takeUntil } from 'rxjs/operators';
|
||||
styleUrls: ['./process-instance-tasks.component.css']
|
||||
})
|
||||
export class ProcessInstanceTasksComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
/** (**required**) The ID of the process instance to display tasks for. */
|
||||
@Input()
|
||||
processInstanceDetails: ProcessInstance;
|
||||
@@ -67,23 +66,15 @@ export class ProcessInstanceTasksComponent implements OnInit, OnChanges, OnDestr
|
||||
private completedTaskObserver: Observer<TaskDetailsModel>;
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
constructor(private activitiProcess: ProcessService,
|
||||
private logService: LogService,
|
||||
private dialog: MatDialog) {
|
||||
this.task$ = new Observable<TaskDetailsModel>((observer) => this.taskObserver = observer)
|
||||
.pipe(share());
|
||||
this.completedTask$ = new Observable<TaskDetailsModel>((observer) => this.completedTaskObserver = observer)
|
||||
.pipe(share());
|
||||
constructor(private activitiProcess: ProcessService, private logService: LogService, private dialog: MatDialog) {
|
||||
this.task$ = new Observable<TaskDetailsModel>((observer) => (this.taskObserver = observer)).pipe(share());
|
||||
this.completedTask$ = new Observable<TaskDetailsModel>((observer) => (this.completedTaskObserver = observer)).pipe(share());
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.task$
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe(task => this.activeTasks.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));
|
||||
this.completedTask$.pipe(takeUntil(this.onDestroy$)).subscribe((task) => this.completedTasks.push(task));
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
@@ -93,7 +84,7 @@ export class ProcessInstanceTasksComponent implements OnInit, OnChanges, OnDestr
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
const processInstanceDetails = changes['processInstanceDetails'];
|
||||
if (processInstanceDetails && processInstanceDetails.currentValue) {
|
||||
if (processInstanceDetails?.currentValue) {
|
||||
this.load(processInstanceDetails.currentValue.id);
|
||||
}
|
||||
}
|
||||
@@ -107,7 +98,7 @@ export class ProcessInstanceTasksComponent implements OnInit, OnChanges, OnDestr
|
||||
this.activeTasks = [];
|
||||
if (processInstanceId) {
|
||||
this.activitiProcess.getProcessTasks(processInstanceId, null).subscribe(
|
||||
(res: TaskDetailsModel[]) => {
|
||||
(res) => {
|
||||
res.forEach((task) => {
|
||||
this.taskObserver.next(task);
|
||||
});
|
||||
@@ -125,7 +116,7 @@ export class ProcessInstanceTasksComponent implements OnInit, OnChanges, OnDestr
|
||||
this.completedTasks = [];
|
||||
if (processInstanceId) {
|
||||
this.activitiProcess.getProcessTasks(processInstanceId, 'completed').subscribe(
|
||||
(res: TaskDetailsModel[]) => {
|
||||
(res) => {
|
||||
res.forEach((task) => {
|
||||
this.completedTaskObserver.next(task);
|
||||
});
|
||||
@@ -140,14 +131,12 @@ export class ProcessInstanceTasksComponent implements OnInit, OnChanges, OnDestr
|
||||
}
|
||||
|
||||
hasStartFormDefined(): boolean {
|
||||
return this.processInstanceDetails && this.processInstanceDetails.startFormDefined === true;
|
||||
return this.processInstanceDetails?.startFormDefined === true;
|
||||
}
|
||||
|
||||
getUserFullName(user: any): string {
|
||||
if (user) {
|
||||
return (user.firstName && user.firstName !== 'null'
|
||||
? user.firstName + ' ' : '') +
|
||||
user.lastName;
|
||||
return (user.firstName && user.firstName !== 'null' ? user.firstName + ' ' : '') + user.lastName;
|
||||
}
|
||||
return 'Nobody';
|
||||
}
|
||||
|
@@ -30,16 +30,7 @@ import {
|
||||
DataCellEvent,
|
||||
DEFAULT_PAGINATION
|
||||
} from '@alfresco/adf-core';
|
||||
import {
|
||||
AfterContentInit,
|
||||
Component,
|
||||
ContentChild,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnChanges,
|
||||
Output,
|
||||
SimpleChanges
|
||||
} from '@angular/core';
|
||||
import { AfterContentInit, Component, ContentChild, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
|
||||
import { ProcessFilterParamRepresentationModel } from '../models/filter-process.model';
|
||||
import { processPresetsDefaultModel } from '../models/process-preset.model';
|
||||
import { ProcessService } from '../services/process.service';
|
||||
@@ -55,7 +46,6 @@ const PRESET_KEY = 'adf-process-list.presets';
|
||||
templateUrl: './process-list.component.html'
|
||||
})
|
||||
export class ProcessInstanceListComponent extends DataTableSchema implements OnChanges, AfterContentInit, PaginatedComponent {
|
||||
|
||||
@ContentChild(CustomEmptyContentTemplateDirective)
|
||||
customEmptyContent: CustomEmptyContentTemplateDirective;
|
||||
|
||||
@@ -151,9 +141,7 @@ export class ProcessInstanceListComponent extends DataTableSchema implements OnC
|
||||
sorting: any[] = ['created', 'desc'];
|
||||
pagination: BehaviorSubject<PaginationModel>;
|
||||
|
||||
constructor(private processService: ProcessService,
|
||||
private userPreferences: UserPreferencesService,
|
||||
appConfig: AppConfigService) {
|
||||
constructor(private processService: ProcessService, private userPreferences: UserPreferencesService, appConfig: AppConfigService) {
|
||||
super(appConfig, PRESET_KEY, processPresetsDefaultModel);
|
||||
this.size = this.userPreferences.paginationSize;
|
||||
|
||||
@@ -167,7 +155,7 @@ export class ProcessInstanceListComponent extends DataTableSchema implements OnC
|
||||
ngAfterContentInit() {
|
||||
this.createDatatableSchema();
|
||||
|
||||
if (this.data && this.data.getColumns().length === 0) {
|
||||
if (this.data?.getColumns().length === 0) {
|
||||
this.data.setColumns(this.columns);
|
||||
}
|
||||
|
||||
@@ -266,7 +254,7 @@ export class ProcessInstanceListComponent extends DataTableSchema implements OnC
|
||||
}
|
||||
|
||||
currentPage(skipCount: number, maxItems: number): number {
|
||||
return (skipCount && maxItems) ? Math.floor(skipCount / maxItems) : 0;
|
||||
return skipCount && maxItems ? Math.floor(skipCount / maxItems) : 0;
|
||||
}
|
||||
|
||||
private createRequestNode(): ProcessFilterParamRepresentationModel {
|
||||
@@ -284,7 +272,7 @@ export class ProcessInstanceListComponent extends DataTableSchema implements OnC
|
||||
|
||||
private isSortChanged(changes: SimpleChanges): boolean {
|
||||
const actualSort = changes['sort'];
|
||||
return actualSort && actualSort.currentValue && actualSort.currentValue !== actualSort.previousValue;
|
||||
return actualSort?.currentValue && actualSort.currentValue !== actualSort.previousValue;
|
||||
}
|
||||
|
||||
private isPropertyChanged(changes: SimpleChanges): boolean {
|
||||
@@ -298,17 +286,17 @@ export class ProcessInstanceListComponent extends DataTableSchema implements OnC
|
||||
const page = changes['page'];
|
||||
const size = changes['size'];
|
||||
|
||||
if (appId && appId.currentValue) {
|
||||
if (appId?.currentValue) {
|
||||
changed = true;
|
||||
} else if (processDefinitionId) {
|
||||
changed = true;
|
||||
} else if (processInstanceId) {
|
||||
changed = true;
|
||||
} else if (state && state.currentValue) {
|
||||
} else if (state?.currentValue) {
|
||||
changed = true;
|
||||
} else if (sort && sort.currentValue) {
|
||||
} else if (sort?.currentValue) {
|
||||
changed = true;
|
||||
} else if (page && page.currentValue !== page.previousValue) {
|
||||
} else if (page && page?.currentValue !== page.previousValue) {
|
||||
changed = true;
|
||||
} else if (size && size.currentValue !== size.previousValue) {
|
||||
changed = true;
|
||||
@@ -318,10 +306,11 @@ export class ProcessInstanceListComponent extends DataTableSchema implements OnC
|
||||
|
||||
private load(requestNode: ProcessFilterParamRepresentationModel) {
|
||||
this.isLoading = true;
|
||||
this.processService.getProcesses(requestNode)
|
||||
.pipe(finalize(() => this.isLoading = false))
|
||||
this.processService
|
||||
.getProcesses(requestNode)
|
||||
.pipe(finalize(() => (this.isLoading = false)))
|
||||
.subscribe(
|
||||
response => {
|
||||
(response) => {
|
||||
this.rows = response.data;
|
||||
this.selectFirst();
|
||||
this.success.emit(response);
|
||||
@@ -332,7 +321,7 @@ export class ProcessInstanceListComponent extends DataTableSchema implements OnC
|
||||
totalItems: response.total
|
||||
});
|
||||
},
|
||||
error => {
|
||||
(error) => {
|
||||
this.error.emit(error);
|
||||
}
|
||||
);
|
||||
|
@@ -23,14 +23,7 @@ import { of, throwError } from 'rxjs';
|
||||
import { MatSelectChange } from '@angular/material/select';
|
||||
import { ProcessInstanceVariable } from '../models/process-instance-variable.model';
|
||||
import { ProcessService } from '../services/process.service';
|
||||
import {
|
||||
newProcess,
|
||||
taskFormMock,
|
||||
testProcessDef,
|
||||
testMultipleProcessDefs,
|
||||
testProcessDefWithForm,
|
||||
testProcessDefinitions
|
||||
} from '../../mock';
|
||||
import { newProcess, taskFormMock, testProcessDef, testMultipleProcessDefs, testProcessDefWithForm, testProcessDefinitions } from '../../mock';
|
||||
import { StartProcessInstanceComponent } from './start-process.component';
|
||||
import { ProcessTestingModule } from '../../testing/process.testing.module';
|
||||
import { By } from '@angular/platform-browser';
|
||||
@@ -41,7 +34,6 @@ import { ProcessInstance } from '../models/process-instance.model';
|
||||
import { ActivitiContentService } from '../../form/services/activiti-alfresco.service';
|
||||
|
||||
describe('StartProcessComponent', () => {
|
||||
|
||||
let appConfig: AppConfigService;
|
||||
let activitiContentService: ActivitiContentService;
|
||||
let component: StartProcessInstanceComponent;
|
||||
@@ -56,10 +48,7 @@ describe('StartProcessComponent', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
ProcessTestingModule
|
||||
]
|
||||
imports: [TranslateModule.forRoot(), ProcessTestingModule]
|
||||
});
|
||||
});
|
||||
|
||||
@@ -68,7 +57,7 @@ describe('StartProcessComponent', () => {
|
||||
selectElement.click();
|
||||
fixture.detectChanges();
|
||||
const options: any = fixture.debugElement.queryAll(By.css('.mat-option-text'));
|
||||
const currentOption = options.find( (option: DebugElement) => option.nativeElement.innerHTML.trim() === name );
|
||||
const currentOption = options.find((option: DebugElement) => option.nativeElement.innerHTML.trim() === name);
|
||||
|
||||
if (currentOption) {
|
||||
currentOption.nativeElement.click();
|
||||
@@ -93,7 +82,7 @@ describe('StartProcessComponent', () => {
|
||||
startProcessSpy = spyOn(processService, 'startProcess').and.returnValue(of(newProcess));
|
||||
getStartFormDefinitionSpy = spyOn(processService, 'getStartFormDefinition').and.returnValue(of(taskFormMock));
|
||||
applyAlfrescoNodeSpy = spyOn(activitiContentService, 'applyAlfrescoNode').and.returnValue(of({ id: 1234 }));
|
||||
spyOn(activitiContentService, 'getAlfrescoRepositories').and.returnValue(of([{ id: '1', name: 'fake-repo-name'}]));
|
||||
spyOn(activitiContentService, 'getAlfrescoRepositories').and.returnValue(of([{ id: '1', name: 'fake-repo-name' }]));
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -102,9 +91,7 @@ describe('StartProcessComponent', () => {
|
||||
});
|
||||
|
||||
describe('first step', () => {
|
||||
|
||||
describe('without start form', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
fixture.detectChanges();
|
||||
component.name = 'My new process';
|
||||
@@ -165,7 +152,6 @@ describe('StartProcessComponent', () => {
|
||||
});
|
||||
|
||||
describe('with start form', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
fixture.detectChanges();
|
||||
getDefinitionsSpy.and.returnValue(of(testProcessDefWithForm));
|
||||
@@ -199,7 +185,7 @@ describe('StartProcessComponent', () => {
|
||||
await fixture.whenStable();
|
||||
|
||||
const inputLabelsNodes = document.querySelectorAll('.adf-start-process .adf-process-input-container');
|
||||
inputLabelsNodes.forEach(labelNode => {
|
||||
inputLabelsNodes.forEach((labelNode) => {
|
||||
expect(labelNode.getAttribute('ng-reflect-float-label')).toBe('always');
|
||||
});
|
||||
});
|
||||
@@ -245,7 +231,6 @@ describe('StartProcessComponent', () => {
|
||||
});
|
||||
|
||||
describe('CS content connection', () => {
|
||||
|
||||
it('Should get the alfrescoRepositoryName from the config json', async () => {
|
||||
appConfig.config = Object.assign(appConfig.config, {
|
||||
alfrescoRepositoryName: 'alfresco-123'
|
||||
@@ -307,7 +292,6 @@ describe('StartProcessComponent', () => {
|
||||
});
|
||||
|
||||
describe('process definitions list', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
fixture.detectChanges();
|
||||
component.name = 'My new process';
|
||||
@@ -374,11 +358,10 @@ describe('StartProcessComponent', () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(component.selectedProcessDef.name).toBeNull();
|
||||
expect(component.selectedProcessDef.name).not.toBeDefined();
|
||||
});
|
||||
|
||||
describe('dropdown', () => {
|
||||
|
||||
it('should hide the process dropdown button if showSelectProcessDropdown is false', async () => {
|
||||
fixture.detectChanges();
|
||||
getDefinitionsSpy = getDefinitionsSpy.and.returnValue(of([testProcessDef]));
|
||||
@@ -427,7 +410,6 @@ describe('StartProcessComponent', () => {
|
||||
});
|
||||
|
||||
describe('input changes', () => {
|
||||
|
||||
beforeEach(async () => {
|
||||
component.appId = 123;
|
||||
fixture.detectChanges();
|
||||
@@ -449,7 +431,6 @@ describe('StartProcessComponent', () => {
|
||||
});
|
||||
|
||||
describe('start process', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
fixture.detectChanges();
|
||||
component.name = 'My new process';
|
||||
@@ -574,10 +555,9 @@ describe('StartProcessComponent', () => {
|
||||
fixture.detectChanges();
|
||||
expect(startSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Select applications', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
fixture.detectChanges();
|
||||
component.name = 'My new process';
|
||||
@@ -623,7 +603,7 @@ describe('StartProcessComponent', () => {
|
||||
expect(component.processDefinitions[0].name).toEqual('My Process 1');
|
||||
expect(component.processDefinitions[1].name).toEqual('My Process 2');
|
||||
|
||||
getDefinitionsSpy.and.returnValue(of([ { id: 'my:process 3', name: 'My Process 3', hasStartForm: true } ]));
|
||||
getDefinitionsSpy.and.returnValue(of([{ id: 'my:process 3', name: 'My Process 3', hasStartForm: true }]));
|
||||
fixture.detectChanges();
|
||||
|
||||
const newApplication = { value: deployedApps[1] } as MatSelectChange;
|
||||
@@ -811,9 +791,9 @@ describe('StartProcessComponent', () => {
|
||||
changeAppId(123);
|
||||
fixture.detectChanges();
|
||||
|
||||
const application1 = deployedApps[0];
|
||||
const application2 = deployedApps[1];
|
||||
const application3 = deployedApps[2];
|
||||
const application1 = deployedApps[0];
|
||||
const application2 = deployedApps[1];
|
||||
const application3 = deployedApps[2];
|
||||
|
||||
expect(component.applications.length).toBe(6);
|
||||
|
||||
@@ -857,10 +837,9 @@ describe('StartProcessComponent', () => {
|
||||
expect(component.selectedProcessDef.name).toEqual(processDefWithNoStartForm.name);
|
||||
expect(component.selectedProcessDef.hasStartForm).toEqual(processDefWithNoStartForm.hasStartForm);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Empty Template', () => {
|
||||
|
||||
it('[333510] Should be able to show empty template when no applications deployed', async () => {
|
||||
getDeployedApplicationsSpy = spyOn(appsProcessService, 'getDeployedApplications').and.returnValue(of([]));
|
||||
|
||||
@@ -939,7 +918,6 @@ describe('StartProcessComponent', () => {
|
||||
});
|
||||
|
||||
describe('Error event', () => {
|
||||
|
||||
const processDefError = { message: 'Failed to load Process definitions' };
|
||||
const applicationsError = { message: 'Failed to load applications' };
|
||||
const startProcessError = { message: 'Failed to start process' };
|
||||
|
@@ -146,7 +146,7 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
);
|
||||
|
||||
this.activitiContentService.getAlfrescoRepositories().subscribe((repoList) => {
|
||||
if (repoList && repoList[0]) {
|
||||
if (repoList?.[0]) {
|
||||
const alfrescoRepository = repoList[0];
|
||||
this.alfrescoRepositoryName = `alfresco-${alfrescoRepository.id}-${alfrescoRepository.name}`;
|
||||
}
|
||||
@@ -159,7 +159,7 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if (changes['values'] && changes['values'].currentValue) {
|
||||
if (changes['values']?.currentValue) {
|
||||
this.moveNodeFromCStoPS();
|
||||
}
|
||||
|
||||
@@ -281,7 +281,7 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
}
|
||||
|
||||
loadProcessDefinitionsBasedOnSelectedApp() {
|
||||
if (this.selectedApplication && this.selectedApplication.id) {
|
||||
if (this.selectedApplication?.id) {
|
||||
this.loadProcessDefinitions(this.selectedApplication ? this.selectedApplication.id : null);
|
||||
} else {
|
||||
this.isProcessDefinitionsLoading = false;
|
||||
@@ -298,15 +298,15 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
}
|
||||
|
||||
hasApplications(): boolean {
|
||||
return this.applications && this.applications.length > 0;
|
||||
return this.applications?.length > 0;
|
||||
}
|
||||
|
||||
hasProcessDefinitions(): boolean {
|
||||
return this.processDefinitions && this.processDefinitions.length > 0;
|
||||
return this.processDefinitions?.length > 0;
|
||||
}
|
||||
|
||||
isProcessDefinitionSelected(): boolean {
|
||||
return !!(this.selectedProcessDef && this.selectedProcessDef.id);
|
||||
return !!this.selectedProcessDef?.id;
|
||||
}
|
||||
|
||||
isProcessDefinitionsEmpty(): boolean {
|
||||
@@ -332,7 +332,7 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
if (this.values.hasOwnProperty(key)) {
|
||||
const currentValue = Array.isArray(this.values[key]) ? this.values[key] : [this.values[key]];
|
||||
const contents = currentValue
|
||||
.filter((value: any) => value && value.isFile)
|
||||
.filter((value: any) => !!value?.isFile)
|
||||
.map((content: Node) => this.activitiContentService.applyAlfrescoNode(content, null, accountIdentifier));
|
||||
forkJoin(contents).subscribe((res: RelatedContentRepresentation[]) => {
|
||||
this.movedNodeToPS = { [key]: [...res] };
|
||||
@@ -342,7 +342,7 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
}
|
||||
|
||||
startProcess(outcome?: string) {
|
||||
if (this.selectedProcessDef && this.selectedProcessDef.id && this.nameController.value) {
|
||||
if (this.selectedProcessDef?.id && this.nameController.value) {
|
||||
const formValues = this.startForm ? this.startForm.form.values : undefined;
|
||||
this.activitiProcess.startProcess(this.selectedProcessDef.id, this.nameController.value, outcome, formValues, this.variables).subscribe(
|
||||
(res) => {
|
||||
@@ -361,19 +361,19 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
}
|
||||
|
||||
hasStartForm(): boolean {
|
||||
return this.selectedProcessDef && this.selectedProcessDef.hasStartForm;
|
||||
return this.selectedProcessDef?.hasStartForm;
|
||||
}
|
||||
|
||||
isStartFormMissingOrValid(): boolean {
|
||||
if (this.startForm) {
|
||||
return this.startForm.form && this.startForm.form.isValid;
|
||||
return this.startForm.form?.isValid;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
validateForm(): boolean {
|
||||
return this.selectedProcessDef && this.selectedProcessDef.id && this.processNameInput.valid && this.isStartFormMissingOrValid();
|
||||
return this.selectedProcessDef?.id && this.processNameInput.valid && this.isStartFormMissingOrValid();
|
||||
}
|
||||
|
||||
onOutcomeClick(outcome: string) {
|
||||
@@ -436,7 +436,7 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
}
|
||||
|
||||
private isAppSelected(): boolean {
|
||||
return !!(this.selectedApplication && this.selectedApplication.id);
|
||||
return !!this.selectedApplication?.id;
|
||||
}
|
||||
|
||||
private removeDefaultApps(apps: AppDefinitionRepresentationModel[]): AppDefinitionRepresentationModel[] {
|
||||
@@ -466,13 +466,12 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
}
|
||||
|
||||
private isAppIdChanged(changes: SimpleChanges) {
|
||||
return changes['appId'] && changes['appId'].currentValue && changes['appId'].currentValue !== changes['appId'].previousValue;
|
||||
return changes['appId']?.currentValue && changes['appId'].currentValue !== changes['appId'].previousValue;
|
||||
}
|
||||
|
||||
private isProcessDefinitionChanged(changes: SimpleChanges) {
|
||||
return (
|
||||
changes['processDefinitionName'] &&
|
||||
changes['processDefinitionName'].currentValue &&
|
||||
changes['processDefinitionName']?.currentValue &&
|
||||
changes['processDefinitionName'].currentValue !== changes['processDefinitionName'].previousValue
|
||||
);
|
||||
}
|
||||
|
@@ -28,15 +28,15 @@ export class ProcessDefinitionRepresentation {
|
||||
hasStartForm: boolean;
|
||||
|
||||
constructor(obj?: any) {
|
||||
this.id = obj && obj.id || null;
|
||||
this.name = obj && obj.name || null;
|
||||
this.description = obj && obj.description || null;
|
||||
this.key = obj && obj.key || null;
|
||||
this.category = obj && obj.category || null;
|
||||
this.version = obj && obj.version || 0;
|
||||
this.deploymentId = obj && obj.deploymentId || null;
|
||||
this.tenantId = obj && obj.tenantId || null;
|
||||
this.metaDataValues = obj && obj.metaDataValues || [];
|
||||
this.hasStartForm = obj && obj.hasStartForm === true;
|
||||
this.id = obj?.id;
|
||||
this.name = obj?.name;
|
||||
this.description = obj?.description;
|
||||
this.key = obj?.key;
|
||||
this.category = obj?.category;
|
||||
this.version = obj?.version || 0;
|
||||
this.deploymentId = obj?.deploymentId;
|
||||
this.tenantId = obj?.tenantId;
|
||||
this.metaDataValues = obj?.metaDataValues || [];
|
||||
this.hasStartForm = obj?.hasStartForm === true;
|
||||
}
|
||||
}
|
||||
|
@@ -24,11 +24,11 @@ export class ProcessFilterRequestRepresentation {
|
||||
size: number;
|
||||
|
||||
constructor(obj?: any) {
|
||||
this.processDefinitionId = obj && obj.processDefinitionId || null;
|
||||
this.appDefinitionId = obj && obj.appDefinitionId || null;
|
||||
this.state = obj && obj.state || null;
|
||||
this.sort = obj && obj.sort || null;
|
||||
this.page = obj && obj.page || 0;
|
||||
this.size = obj && obj.size || 25;
|
||||
this.processDefinitionId = obj?.processDefinitionId;
|
||||
this.appDefinitionId = obj?.appDefinitionId;
|
||||
this.state = obj?.state;
|
||||
this.sort = obj?.sort;
|
||||
this.page = obj?.page || 0;
|
||||
this.size = obj?.size || 25;
|
||||
}
|
||||
}
|
||||
|
@@ -18,7 +18,6 @@
|
||||
import { RestVariable } from '@alfresco/js-api';
|
||||
|
||||
export class ProcessInstanceVariable implements RestVariable {
|
||||
|
||||
name?: string;
|
||||
scope?: string;
|
||||
type?: string;
|
||||
@@ -26,9 +25,9 @@ export class ProcessInstanceVariable implements RestVariable {
|
||||
valueUrl?: string;
|
||||
|
||||
constructor(obj?: any) {
|
||||
this.name = obj && obj.name !== undefined ? obj.name : null;
|
||||
this.scope = obj && obj.scope !== undefined ? obj.scope : null;
|
||||
this.value = obj && obj.value !== undefined ? obj.value : null;
|
||||
this.valueUrl = obj && obj.valueUrl !== undefined ? obj.valueUrl : null;
|
||||
this.name = obj?.name;
|
||||
this.scope = obj?.scope;
|
||||
this.value = obj?.value;
|
||||
this.valueUrl = obj?.valueUrl;
|
||||
}
|
||||
}
|
||||
|
@@ -18,7 +18,6 @@
|
||||
import { LightUserRepresentation, ProcessInstanceRepresentation, RestVariable } from '@alfresco/js-api';
|
||||
|
||||
export class ProcessInstance implements ProcessInstanceRepresentation {
|
||||
|
||||
businessKey?: string;
|
||||
ended?: Date;
|
||||
graphicalNotationDefined?: boolean;
|
||||
@@ -38,23 +37,22 @@ export class ProcessInstance implements ProcessInstanceRepresentation {
|
||||
variables?: RestVariable[];
|
||||
|
||||
constructor(data?: any) {
|
||||
this.businessKey = data && data.businessKey !== undefined ? data.businessKey : null;
|
||||
this.ended = data && data.ended !== undefined ? data.ended : null;
|
||||
this.graphicalNotationDefined = data && data.graphicalNotationDefined !== undefined ? data.graphicalNotationDefined : null;
|
||||
this.id = data && data.id !== undefined ? data.id : null;
|
||||
this.name = data && data.name !== undefined ? data.name : null;
|
||||
this.processDefinitionCategory = data && data.processDefinitionCategory !== undefined ? data.processDefinitionCategory : null;
|
||||
this.processDefinitionDeploymentId = data && data.processDefinitionDeploymentId !== undefined ? data.processDefinitionDeploymentId : null;
|
||||
this.processDefinitionDescription = data && data.processDefinitionDescription !== undefined ? data.processDefinitionDescription : null;
|
||||
this.processDefinitionId = data && data.processDefinitionId !== undefined ? data.processDefinitionId : null;
|
||||
this.processDefinitionKey = data && data.processDefinitionKey !== undefined ? data.processDefinitionKey : null;
|
||||
this.processDefinitionName = data && data.processDefinitionName !== undefined ? data.processDefinitionName : null;
|
||||
this.processDefinitionVersion = data && data.processDefinitionVersion !== undefined ? data.processDefinitionVersion : null;
|
||||
this.startFormDefined = data && data.startFormDefined !== undefined ? data.startFormDefined : null;
|
||||
this.started = data && data.started !== undefined ? data.started : null;
|
||||
this.startedBy = data && data.startedBy !== undefined ? data.startedBy : null;
|
||||
this.tenantId = data && data.tenantId !== undefined ? data.tenantId : null;
|
||||
this.variables = data && data.variables !== undefined ? data.variables : null;
|
||||
this.businessKey = data?.businessKey;
|
||||
this.ended = data?.ended;
|
||||
this.graphicalNotationDefined = data?.graphicalNotationDefined;
|
||||
this.id = data?.id;
|
||||
this.name = data?.name;
|
||||
this.processDefinitionCategory = data?.processDefinitionCategory;
|
||||
this.processDefinitionDeploymentId = data?.processDefinitionDeploymentId;
|
||||
this.processDefinitionDescription = data?.processDefinitionDescription;
|
||||
this.processDefinitionId = data?.processDefinitionId;
|
||||
this.processDefinitionKey = data?.processDefinitionKey;
|
||||
this.processDefinitionName = data?.processDefinitionName;
|
||||
this.processDefinitionVersion = data?.processDefinitionVersion;
|
||||
this.startFormDefined = data?.startFormDefined;
|
||||
this.started = data?.started;
|
||||
this.startedBy = data?.startedBy;
|
||||
this.tenantId = data?.tenantId;
|
||||
this.variables = data?.variables;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -16,7 +16,14 @@
|
||||
*/
|
||||
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { mockError, fakeProcessFiltersResponse, dummyRunningFilter, dummyAllFilter, dummyCompletedFilter, dummyDuplicateRunningFilter } from '../../mock';
|
||||
import {
|
||||
mockError,
|
||||
fakeProcessFiltersResponse,
|
||||
dummyRunningFilter,
|
||||
dummyAllFilter,
|
||||
dummyCompletedFilter,
|
||||
dummyDuplicateRunningFilter
|
||||
} from '../../mock';
|
||||
import { FilterProcessRepresentationModel } from '../models/filter-process.model';
|
||||
import { ProcessFilterService } from './process-filter.service';
|
||||
import { CoreTestingModule } from '@alfresco/adf-core';
|
||||
@@ -30,22 +37,19 @@ describe('Process filter', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
CoreTestingModule
|
||||
]
|
||||
imports: [CoreTestingModule]
|
||||
});
|
||||
service = TestBed.inject(ProcessFilterService);
|
||||
});
|
||||
|
||||
describe('filters', () => {
|
||||
|
||||
let getFilters: jasmine.Spy;
|
||||
let createFilter: jasmine.Spy;
|
||||
|
||||
beforeEach(() => {
|
||||
getFilters = spyOn(service['userFiltersApi'], 'getUserProcessInstanceFilters')
|
||||
.and
|
||||
.returnValue(Promise.resolve(fakeProcessFiltersResponse));
|
||||
getFilters = spyOn(service['userFiltersApi'], 'getUserProcessInstanceFilters').and.returnValue(
|
||||
Promise.resolve(fakeProcessFiltersResponse)
|
||||
);
|
||||
|
||||
jasmine.Ajax.install();
|
||||
});
|
||||
@@ -55,7 +59,6 @@ describe('Process filter', () => {
|
||||
});
|
||||
|
||||
describe('get filters', () => {
|
||||
|
||||
it('should call the API without an appId defined by default', () => {
|
||||
service.getProcessFilters(null);
|
||||
expect(getFilters).toHaveBeenCalled();
|
||||
@@ -67,33 +70,29 @@ describe('Process filter', () => {
|
||||
});
|
||||
|
||||
it('should return the task filter by id', (done) => {
|
||||
service.getProcessFilterById(333).subscribe(
|
||||
(processFilter: FilterProcessRepresentationModel) => {
|
||||
expect(processFilter).toBeDefined();
|
||||
expect(processFilter.id).toEqual(333);
|
||||
expect(processFilter.name).toEqual('Running');
|
||||
expect(processFilter.filter.sort).toEqual('created-desc');
|
||||
expect(processFilter.filter.state).toEqual('running');
|
||||
done();
|
||||
}
|
||||
);
|
||||
service.getProcessFilterById(333).subscribe((processFilter: FilterProcessRepresentationModel) => {
|
||||
expect(processFilter).toBeDefined();
|
||||
expect(processFilter.id).toEqual(333);
|
||||
expect(processFilter.name).toEqual('Running');
|
||||
expect(processFilter.filter.sort).toEqual('created-desc');
|
||||
expect(processFilter.filter.state).toEqual('running');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the task filter by name', (done) => {
|
||||
service.getProcessFilterByName('Running').subscribe(
|
||||
(res: FilterProcessRepresentationModel) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.id).toEqual(333);
|
||||
expect(res.name).toEqual('Running');
|
||||
expect(res.filter.sort).toEqual('created-desc');
|
||||
expect(res.filter.state).toEqual('running');
|
||||
done();
|
||||
}
|
||||
);
|
||||
service.getProcessFilterByName('Running').subscribe((res: FilterProcessRepresentationModel) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.id).toEqual(333);
|
||||
expect(res.name).toEqual('Running');
|
||||
expect(res.filter.sort).toEqual('created-desc');
|
||||
expect(res.filter.state).toEqual('running');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the default filters', (done) => {
|
||||
service.createDefaultFilters(1234).subscribe((res: FilterProcessRepresentationModel []) => {
|
||||
service.createDefaultFilters(1234).subscribe((res: FilterProcessRepresentationModel[]) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.length).toEqual(3);
|
||||
expect(res[0].name).toEqual('Running');
|
||||
@@ -109,7 +108,11 @@ describe('Process filter', () => {
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify({
|
||||
appId: 1001, id: 111, name: 'Running', icon: 'fake-icon', recent: false
|
||||
appId: 1001,
|
||||
id: 111,
|
||||
name: 'Running',
|
||||
icon: 'fake-icon',
|
||||
recent: false
|
||||
})
|
||||
});
|
||||
|
||||
@@ -117,7 +120,11 @@ describe('Process filter', () => {
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify({
|
||||
appId: 1001, id: 222, name: 'Completed', icon: 'fake-icon', recent: false
|
||||
appId: 1001,
|
||||
id: 222,
|
||||
name: 'Completed',
|
||||
icon: 'fake-icon',
|
||||
recent: false
|
||||
})
|
||||
});
|
||||
|
||||
@@ -125,13 +132,17 @@ describe('Process filter', () => {
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify({
|
||||
appId: 1001, id: 333, name: 'All', icon: 'fake-icon', recent: false
|
||||
appId: 1001,
|
||||
id: 333,
|
||||
name: 'All',
|
||||
icon: 'fake-icon',
|
||||
recent: false
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able create filters and add sorting information to the response', (done) => {
|
||||
service.createDefaultFilters(1234).subscribe((res: FilterProcessRepresentationModel []) => {
|
||||
service.createDefaultFilters(1234).subscribe((res: FilterProcessRepresentationModel[]) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.length).toEqual(3);
|
||||
expect(res[0].name).toEqual('Running');
|
||||
@@ -152,7 +163,11 @@ describe('Process filter', () => {
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify({
|
||||
appId: 1001, id: 111, name: 'Running', icon: 'fake-icon', recent: false
|
||||
appId: 1001,
|
||||
id: 111,
|
||||
name: 'Running',
|
||||
icon: 'fake-icon',
|
||||
recent: false
|
||||
})
|
||||
});
|
||||
|
||||
@@ -160,7 +175,11 @@ describe('Process filter', () => {
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify({
|
||||
appId: 1001, id: 222, name: 'Completed', icon: 'fake-icon', recent: false
|
||||
appId: 1001,
|
||||
id: 222,
|
||||
name: 'Completed',
|
||||
icon: 'fake-icon',
|
||||
recent: false
|
||||
})
|
||||
});
|
||||
|
||||
@@ -168,7 +187,11 @@ describe('Process filter', () => {
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify({
|
||||
appId: 1001, id: 333, name: 'All', icon: 'fake-icon', recent: false
|
||||
appId: 1001,
|
||||
id: 333,
|
||||
name: 'All',
|
||||
icon: 'fake-icon',
|
||||
recent: false
|
||||
})
|
||||
});
|
||||
});
|
||||
@@ -177,23 +200,20 @@ describe('Process filter', () => {
|
||||
getFilters = getFilters.and.returnValue(Promise.reject(mockError));
|
||||
|
||||
service.getProcessFilters(null).subscribe(
|
||||
() => {
|
||||
},
|
||||
() => {},
|
||||
(res) => {
|
||||
expect(res).toBe(mockError);
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('add filter', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
createFilter = spyOn(service['userFiltersApi'], 'createUserProcessInstanceFilter')
|
||||
.and
|
||||
.callFake((processfilter: FilterProcessRepresentationModel) => Promise.resolve(processfilter));
|
||||
createFilter = spyOn(service['userFiltersApi'], 'createUserProcessInstanceFilter').and.callFake(
|
||||
(processfilter: FilterProcessRepresentationModel) => Promise.resolve(processfilter)
|
||||
);
|
||||
});
|
||||
|
||||
const filter = fakeProcessFiltersResponse.data[0];
|
||||
@@ -214,8 +234,7 @@ describe('Process filter', () => {
|
||||
createFilter = createFilter.and.returnValue(Promise.reject(mockError));
|
||||
|
||||
service.addProcessFilter(filter).subscribe(
|
||||
() => {
|
||||
},
|
||||
() => {},
|
||||
(res) => {
|
||||
expect(res).toBe(mockError);
|
||||
done();
|
||||
@@ -226,15 +245,13 @@ describe('Process filter', () => {
|
||||
it('should return a default error if no data is returned by the API', (done) => {
|
||||
createFilter = createFilter.and.returnValue(Promise.reject(null));
|
||||
service.addProcessFilter(filter).subscribe(
|
||||
() => {
|
||||
},
|
||||
() => {},
|
||||
(res) => {
|
||||
expect(res).toBe('Server error');
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('isFilterAlreadyExisting', () => {
|
||||
@@ -251,16 +268,14 @@ describe('Process filter', () => {
|
||||
index: 0,
|
||||
name: 'Running',
|
||||
recent: false,
|
||||
hasFilter: () => {
|
||||
return true;
|
||||
}
|
||||
hasFilter: () => true
|
||||
}
|
||||
];
|
||||
|
||||
filterRepresentationData = {
|
||||
name : '',
|
||||
sort : 'created-desc',
|
||||
state : 'running'
|
||||
name: '',
|
||||
sort: 'created-desc',
|
||||
state: 'running'
|
||||
};
|
||||
});
|
||||
|
||||
@@ -278,7 +293,6 @@ describe('Process filter', () => {
|
||||
});
|
||||
|
||||
describe('createDefaultFilters', () => {
|
||||
|
||||
it('should return an array with unique process filters', (done) => {
|
||||
const appId = 123;
|
||||
|
||||
@@ -296,7 +310,12 @@ describe('Process filter', () => {
|
||||
spyOn<any>(service, 'getCompletedFilterInstance').and.returnValue(completedFilter);
|
||||
spyOn<any>(service, 'getAllFilterInstance').and.returnValue(allFilter);
|
||||
|
||||
spyOn(service, 'addProcessFilter').and.returnValues(runningObservable, completedObservable, allObservable, duplicateRunningObservable);
|
||||
spyOn(service, 'addProcessFilter').and.returnValues(
|
||||
runningObservable,
|
||||
completedObservable,
|
||||
allObservable,
|
||||
duplicateRunningObservable
|
||||
);
|
||||
|
||||
service.createDefaultFilters(appId).subscribe((result) => {
|
||||
expect(result).toEqual([
|
||||
@@ -307,7 +326,6 @@ describe('Process filter', () => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -26,7 +26,6 @@ import { TaskListService } from './../services/tasklist.service';
|
||||
styleUrls: ['./checklist.component.scss']
|
||||
})
|
||||
export class ChecklistComponent implements OnChanges {
|
||||
|
||||
/** (required) The id of the parent task to which subtasks are
|
||||
* attached.
|
||||
*/
|
||||
@@ -60,15 +59,13 @@ export class ChecklistComponent implements OnChanges {
|
||||
|
||||
taskName: string;
|
||||
|
||||
checklist: TaskDetailsModel [] = [];
|
||||
checklist: TaskDetailsModel[] = [];
|
||||
|
||||
constructor(private activitiTaskList: TaskListService,
|
||||
private dialog: MatDialog) {
|
||||
}
|
||||
constructor(private activitiTaskList: TaskListService, private dialog: MatDialog) {}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
const taskId = changes['taskId'];
|
||||
if (taskId && taskId.currentValue) {
|
||||
if (taskId?.currentValue) {
|
||||
this.getTaskChecklist();
|
||||
return;
|
||||
}
|
||||
@@ -78,7 +75,7 @@ export class ChecklistComponent implements OnChanges {
|
||||
this.checklist = [];
|
||||
if (this.taskId) {
|
||||
this.activitiTaskList.getTaskChecklist(this.taskId).subscribe(
|
||||
(taskDetailsModel: TaskDetailsModel[]) => {
|
||||
(taskDetailsModel) => {
|
||||
taskDetailsModel.forEach((task) => {
|
||||
this.checklist.push(task);
|
||||
});
|
||||
@@ -103,7 +100,7 @@ export class ChecklistComponent implements OnChanges {
|
||||
assignee: { id: this.assignee }
|
||||
});
|
||||
this.activitiTaskList.addTask(newTask).subscribe(
|
||||
(taskDetailsModel: TaskDetailsModel) => {
|
||||
(taskDetailsModel) => {
|
||||
this.checklist.push(taskDetailsModel);
|
||||
this.checklistTaskCreated.emit(taskDetailsModel);
|
||||
this.taskName = '';
|
||||
@@ -123,7 +120,8 @@ export class ChecklistComponent implements OnChanges {
|
||||
},
|
||||
(error) => {
|
||||
this.error.emit(error);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public cancel() {
|
||||
|
@@ -56,7 +56,6 @@ import { PeopleProcessService } from '../../common/services/people-process.servi
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class TaskDetailsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
@ViewChild('activitiComments')
|
||||
activitiComments: CommentsComponent;
|
||||
|
||||
@@ -149,7 +148,7 @@ export class TaskDetailsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
/** Emitted when a checklist task is deleted. */
|
||||
@Output()
|
||||
taskDeleted: EventEmitter<string> = new EventEmitter<string>();
|
||||
taskDeleted = new EventEmitter<string>();
|
||||
|
||||
/** Emitted when an error occurs. */
|
||||
@Output()
|
||||
@@ -163,7 +162,7 @@ export class TaskDetailsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
/** Emitted when a task is assigned. */
|
||||
@Output()
|
||||
assignTask: EventEmitter<void> = new EventEmitter<void>();
|
||||
assignTask = new EventEmitter<void>();
|
||||
|
||||
/** Emitted when a task is claimed. */
|
||||
@Output()
|
||||
@@ -187,27 +186,24 @@ export class TaskDetailsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
private peopleSearchObserver: Observer<UserProcessModel[]>;
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
constructor(private taskListService: TaskListService,
|
||||
private peopleProcessService: PeopleProcessService,
|
||||
private logService: LogService,
|
||||
private cardViewUpdateService: CardViewUpdateService,
|
||||
private dialog: MatDialog) {
|
||||
}
|
||||
constructor(
|
||||
private taskListService: TaskListService,
|
||||
private peopleProcessService: PeopleProcessService,
|
||||
private logService: LogService,
|
||||
private cardViewUpdateService: CardViewUpdateService,
|
||||
private dialog: MatDialog
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.peopleSearch = new Observable<UserProcessModel[]>((observer) => this.peopleSearchObserver = observer).pipe(share());
|
||||
this.peopleSearch = new Observable<UserProcessModel[]>((observer) => (this.peopleSearchObserver = observer)).pipe(share());
|
||||
|
||||
if (this.taskId) {
|
||||
this.loadDetails(this.taskId);
|
||||
}
|
||||
|
||||
this.cardViewUpdateService.itemUpdated$
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe(this.updateTaskDetails.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));
|
||||
this.cardViewUpdateService.itemClicked$.pipe(takeUntil(this.onDestroy$)).subscribe(this.clickTaskDetails.bind(this));
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
@@ -221,7 +217,7 @@ export class TaskDetailsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
if (taskId && !taskId.currentValue) {
|
||||
this.reset();
|
||||
} else if (taskId && taskId.currentValue) {
|
||||
} else if (taskId?.currentValue) {
|
||||
this.loadDetails(taskId.currentValue);
|
||||
}
|
||||
}
|
||||
@@ -276,7 +272,7 @@ export class TaskDetailsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
}
|
||||
|
||||
onFormLoaded(form: FormModel): void {
|
||||
this.taskFormName = (form && form.name ? form.name : null);
|
||||
this.taskFormName = form?.name;
|
||||
this.formLoaded.emit(form);
|
||||
}
|
||||
|
||||
@@ -312,14 +308,13 @@ export class TaskDetailsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
}
|
||||
|
||||
searchUser(searchedWord: string) {
|
||||
this.peopleProcessService.getWorkflowUsers(null, searchedWord)
|
||||
.subscribe(
|
||||
users => {
|
||||
users = users.filter((user) => user.id !== this.taskDetails.assignee.id);
|
||||
this.peopleSearchObserver.next(users);
|
||||
},
|
||||
() => this.logService.error('Could not load users')
|
||||
);
|
||||
this.peopleProcessService.getWorkflowUsers(null, searchedWord).subscribe(
|
||||
(users) => {
|
||||
users = users.filter((user) => user.id !== this.taskDetails.assignee.id);
|
||||
this.peopleSearchObserver.next(users);
|
||||
},
|
||||
() => this.logService.error('Could not load users')
|
||||
);
|
||||
}
|
||||
|
||||
onCloseSearch() {
|
||||
@@ -327,12 +322,10 @@ export class TaskDetailsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
}
|
||||
|
||||
assignTaskToUser(selectedUser: UserProcessModel) {
|
||||
this.taskListService
|
||||
.assignTask(this.taskDetails.id, selectedUser)
|
||||
.subscribe(() => {
|
||||
this.logService.info('Task Assigned to ' + selectedUser.email);
|
||||
this.assignTask.emit();
|
||||
});
|
||||
this.taskListService.assignTask(this.taskDetails.id, selectedUser).subscribe(() => {
|
||||
this.logService.info('Task Assigned to ' + selectedUser.email);
|
||||
this.assignTask.emit();
|
||||
});
|
||||
this.showAssignee = false;
|
||||
}
|
||||
|
||||
@@ -345,7 +338,7 @@ export class TaskDetailsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
}
|
||||
|
||||
isReadOnlyComment(): boolean {
|
||||
return (this.taskDetails && this.taskDetails.isCompleted()) && (this.taskPeople && this.taskPeople.length === 0);
|
||||
return this.taskDetails?.isCompleted() && this.taskPeople?.length === 0;
|
||||
}
|
||||
|
||||
private reset() {
|
||||
@@ -355,10 +348,12 @@ export class TaskDetailsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
private updateTaskDetails(updateNotification: UpdateNotification) {
|
||||
this.taskListService
|
||||
.updateTask(this.taskId, updateNotification.changed)
|
||||
.pipe(catchError(() => {
|
||||
this.cardViewUpdateService.updateElement(updateNotification.target);
|
||||
return of(null);
|
||||
}))
|
||||
.pipe(
|
||||
catchError(() => {
|
||||
this.cardViewUpdateService.updateElement(updateNotification.target);
|
||||
return of(null);
|
||||
})
|
||||
)
|
||||
.subscribe(() => this.loadDetails(this.taskId));
|
||||
}
|
||||
|
||||
@@ -375,38 +370,35 @@ export class TaskDetailsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
this.taskPeople = [];
|
||||
|
||||
if (taskId) {
|
||||
this.taskListService.getTaskDetails(taskId).subscribe(
|
||||
(res: TaskDetailsModel) => {
|
||||
this.showAttachForm = false;
|
||||
this.taskDetails = res;
|
||||
this.taskListService.getTaskDetails(taskId).subscribe((res) => {
|
||||
this.showAttachForm = false;
|
||||
this.taskDetails = res;
|
||||
|
||||
if (this.taskDetails.name === 'null') {
|
||||
this.taskDetails.name = 'No name';
|
||||
}
|
||||
if (this.taskDetails.name === 'null') {
|
||||
this.taskDetails.name = 'No name';
|
||||
}
|
||||
|
||||
const endDate: any = res.endDate;
|
||||
if (endDate && !isNaN(endDate.getTime())) {
|
||||
this.internalReadOnlyForm = true;
|
||||
} else {
|
||||
this.internalReadOnlyForm = this.readOnlyForm;
|
||||
}
|
||||
const endDate: any = res.endDate;
|
||||
if (endDate && !isNaN(endDate.getTime())) {
|
||||
this.internalReadOnlyForm = true;
|
||||
} else {
|
||||
this.internalReadOnlyForm = this.readOnlyForm;
|
||||
}
|
||||
|
||||
if (this.taskDetails && this.taskDetails.involvedPeople) {
|
||||
this.taskDetails.involvedPeople.forEach((user) => {
|
||||
this.taskPeople.push(new UserProcessModel(user));
|
||||
});
|
||||
}
|
||||
});
|
||||
if (this.taskDetails?.involvedPeople) {
|
||||
this.taskDetails.involvedPeople.forEach((user) => {
|
||||
this.taskPeople.push(new UserProcessModel(user));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private loadNextTask(processInstanceId: string, processDefinitionId: string): void {
|
||||
const requestNode = new TaskQueryRequestRepresentationModel(
|
||||
{
|
||||
processInstanceId,
|
||||
processDefinitionId
|
||||
}
|
||||
);
|
||||
const requestNode = new TaskQueryRequestRepresentationModel({
|
||||
processInstanceId,
|
||||
processDefinitionId
|
||||
});
|
||||
this.taskListService.getTasks(requestNode).subscribe(
|
||||
(response) => {
|
||||
if (response && response.length > 0) {
|
||||
@@ -414,8 +406,10 @@ export class TaskDetailsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
} else {
|
||||
this.reset();
|
||||
}
|
||||
}, (error) => {
|
||||
},
|
||||
(error) => {
|
||||
this.error.emit(error);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -32,7 +32,6 @@ import { filter, takeUntil } from 'rxjs/operators';
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class TaskFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
/** Parameters to use for the task filter. If there is no match then
|
||||
* the default filter (the first one the list) is selected.
|
||||
*/
|
||||
@@ -71,7 +70,7 @@ export class TaskFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
currentFilter: FilterRepresentationModel;
|
||||
|
||||
filters: FilterRepresentationModel [] = [];
|
||||
filters: FilterRepresentationModel[] = [];
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
isTaskRoute: boolean;
|
||||
@@ -79,12 +78,13 @@ export class TaskFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
private iconsMDL: IconModel;
|
||||
|
||||
constructor(private taskFilterService: TaskFilterService,
|
||||
private taskListService: TaskListService,
|
||||
private appsProcessService: AppsProcessService,
|
||||
private router: Router,
|
||||
private activatedRoute: ActivatedRoute) {
|
||||
}
|
||||
constructor(
|
||||
private taskFilterService: TaskFilterService,
|
||||
private taskListService: TaskListService,
|
||||
private appsProcessService: AppsProcessService,
|
||||
private router: Router,
|
||||
private activatedRoute: ActivatedRoute
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.iconsMDL = new IconModel();
|
||||
@@ -97,17 +97,17 @@ export class TaskFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
const activeRoute = navigationStart.url;
|
||||
this.isTaskActive = activeRoute.includes('tasks');
|
||||
});
|
||||
this.activatedRoute.url.subscribe((segments) => {
|
||||
const currentRoute = segments.join('/');
|
||||
this.isTaskRoute = currentRoute.includes('tasks');
|
||||
});
|
||||
this.activatedRoute.url.subscribe((segments) => {
|
||||
const currentRoute = segments.join('/');
|
||||
this.isTaskRoute = currentRoute.includes('tasks');
|
||||
});
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
const appName = changes['appName'];
|
||||
const appId = changes['appId'];
|
||||
const filterParam = changes['filterParam'];
|
||||
if (appName && appName.currentValue) {
|
||||
if (appName?.currentValue) {
|
||||
this.getFiltersByAppName(appName.currentValue);
|
||||
} else if (appId && appId.currentValue !== appId.previousValue) {
|
||||
this.getFiltersByAppId(appId.currentValue);
|
||||
@@ -169,7 +169,8 @@ export class TaskFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
},
|
||||
(err) => {
|
||||
this.error.emit(err);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,12 +199,12 @@ export class TaskFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
*/
|
||||
public selectFilter(newFilter: FilterParamsModel) {
|
||||
if (newFilter) {
|
||||
this.currentFilter = this.filters.find( (entry, index) =>
|
||||
newFilter.index === index ||
|
||||
newFilter.id === entry.id ||
|
||||
(newFilter.name &&
|
||||
(newFilter.name.toLocaleLowerCase() === entry.name.toLocaleLowerCase())
|
||||
));
|
||||
this.currentFilter = this.filters.find(
|
||||
(entry, index) =>
|
||||
newFilter.index === index ||
|
||||
newFilter.id === entry.id ||
|
||||
(newFilter.name && newFilter.name.toLocaleLowerCase() === entry.name.toLocaleLowerCase())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,7 +240,8 @@ export class TaskFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
this.selectFilter(filteredFilterList[0]);
|
||||
this.filterSelected.emit(this.currentFilter);
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -16,345 +16,336 @@
|
||||
*/
|
||||
|
||||
import { Component, OnInit, Input, Output, EventEmitter, SimpleChanges, ViewEncapsulation, OnChanges } from '@angular/core';
|
||||
import {
|
||||
FormModel,
|
||||
ContentLinkModel,
|
||||
FormFieldValidator,
|
||||
FormOutcomeEvent,
|
||||
TranslationService,
|
||||
FormFieldModel
|
||||
} from '@alfresco/adf-core';
|
||||
import { FormModel, ContentLinkModel, FormFieldValidator, FormOutcomeEvent, TranslationService, FormFieldModel } from '@alfresco/adf-core';
|
||||
import { TaskDetailsModel } from '../../models/task-details.model';
|
||||
import { TaskListService } from '../../services/tasklist.service';
|
||||
import { UserRepresentation, LightGroupRepresentation, LightUserRepresentation } from '@alfresco/js-api';
|
||||
import { UserRepresentation } from '@alfresco/js-api';
|
||||
import { Observable } from 'rxjs';
|
||||
import { PeopleProcessService } from '../../../common/services/people-process.service';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-task-form',
|
||||
templateUrl: './task-form.component.html',
|
||||
styleUrls: ['./task-form.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
selector: 'adf-task-form',
|
||||
templateUrl: './task-form.component.html',
|
||||
styleUrls: ['./task-form.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class TaskFormComponent implements OnInit, OnChanges {
|
||||
/** (**required**) The id of the task whose details we are asking for. */
|
||||
@Input()
|
||||
taskId: string;
|
||||
|
||||
/** (**required**) The id of the task whose details we are asking for. */
|
||||
@Input()
|
||||
taskId: string;
|
||||
/** Toggles rendering of the form title. */
|
||||
@Input()
|
||||
showFormTitle: boolean = false;
|
||||
|
||||
/** Toggles rendering of the form title. */
|
||||
@Input()
|
||||
showFormTitle: boolean = false;
|
||||
/** Toggles rendering of the `Complete` outcome button. */
|
||||
@Input()
|
||||
showFormCompleteButton: boolean = true;
|
||||
|
||||
/** Toggles rendering of the `Complete` outcome button. */
|
||||
@Input()
|
||||
showFormCompleteButton: boolean = true;
|
||||
/** Toggles rendering of the `Save` outcome button. */
|
||||
@Input()
|
||||
showFormSaveButton: boolean = true;
|
||||
|
||||
/** Toggles rendering of the `Save` outcome button. */
|
||||
@Input()
|
||||
showFormSaveButton: boolean = true;
|
||||
/** Toggle rendering of the `Cancel` button. */
|
||||
@Input()
|
||||
showCancelButton: boolean = true;
|
||||
|
||||
/** Toggle rendering of the `Cancel` button. */
|
||||
@Input()
|
||||
showCancelButton: boolean = true;
|
||||
/** Toggles read-only state of the form. All form widgets render as read-only
|
||||
* if enabled.
|
||||
*/
|
||||
@Input()
|
||||
readOnlyForm: boolean = false;
|
||||
|
||||
/** Toggles read-only state of the form. All form widgets render as read-only
|
||||
* if enabled.
|
||||
*/
|
||||
@Input()
|
||||
readOnlyForm: boolean = false;
|
||||
/** Toggles rendering of the `Refresh` button. */
|
||||
@Input()
|
||||
showFormRefreshButton: boolean = true;
|
||||
|
||||
/** Toggles rendering of the `Refresh` button. */
|
||||
@Input()
|
||||
showFormRefreshButton: boolean = true;
|
||||
/** Toggle rendering of the validation icon next to the form title. */
|
||||
@Input()
|
||||
showFormValidationIcon: boolean = true;
|
||||
|
||||
/** Toggle rendering of the validation icon next to the form title. */
|
||||
@Input()
|
||||
showFormValidationIcon: boolean = true;
|
||||
/** Field validators for use with the form. */
|
||||
@Input()
|
||||
fieldValidators: FormFieldValidator[] = [];
|
||||
|
||||
/** Field validators for use with the form. */
|
||||
@Input()
|
||||
fieldValidators: FormFieldValidator[] = [];
|
||||
/** Emitted when the form is submitted with the `Save` or custom outcomes. */
|
||||
@Output()
|
||||
formSaved = new EventEmitter<FormModel>();
|
||||
|
||||
/** Emitted when the form is submitted with the `Save` or custom outcomes. */
|
||||
@Output()
|
||||
formSaved = new EventEmitter<FormModel>();
|
||||
/** Emitted when the form is submitted with the `Complete` outcome. */
|
||||
@Output()
|
||||
formCompleted = new EventEmitter<FormModel>();
|
||||
|
||||
/** Emitted when the form is submitted with the `Complete` outcome. */
|
||||
@Output()
|
||||
formCompleted = new EventEmitter<FormModel>();
|
||||
/** Emitted when the form field content is clicked. */
|
||||
@Output()
|
||||
formContentClicked = new EventEmitter<ContentLinkModel>();
|
||||
|
||||
/** Emitted when the form field content is clicked. */
|
||||
@Output()
|
||||
formContentClicked = new EventEmitter<ContentLinkModel>();
|
||||
/** Emitted when the form is loaded or reloaded. */
|
||||
@Output()
|
||||
formLoaded = new EventEmitter<FormModel>();
|
||||
|
||||
/** Emitted when the form is loaded or reloaded. */
|
||||
@Output()
|
||||
formLoaded = new EventEmitter<FormModel>();
|
||||
/** Emitted when the form associated with the form task is attached. */
|
||||
@Output()
|
||||
showAttachForm = new EventEmitter<void>();
|
||||
|
||||
/** Emitted when the form associated with the form task is attached. */
|
||||
@Output()
|
||||
showAttachForm = new EventEmitter<void>();
|
||||
/** Emitted when any outcome is executed. Default behaviour can be prevented
|
||||
* via `event.preventDefault()`.
|
||||
*/
|
||||
@Output()
|
||||
executeOutcome = new EventEmitter<FormOutcomeEvent>();
|
||||
|
||||
/** Emitted when any outcome is executed. Default behaviour can be prevented
|
||||
* via `event.preventDefault()`.
|
||||
*/
|
||||
@Output()
|
||||
executeOutcome = new EventEmitter<FormOutcomeEvent>();
|
||||
/** Emitted when the form associated with the task is completed. */
|
||||
@Output()
|
||||
completed = new EventEmitter<void>();
|
||||
|
||||
/** Emitted when the form associated with the task is completed. */
|
||||
@Output()
|
||||
completed = new EventEmitter<void>();
|
||||
/** Emitted when the supplied form values have a validation error. */
|
||||
@Output()
|
||||
formError = new EventEmitter<FormFieldModel[]>();
|
||||
|
||||
/** Emitted when the supplied form values have a validation error. */
|
||||
@Output()
|
||||
formError = new EventEmitter<FormFieldModel[]>();
|
||||
/** Emitted when an error occurs. */
|
||||
@Output()
|
||||
error = new EventEmitter<any>();
|
||||
|
||||
/** Emitted when an error occurs. */
|
||||
@Output()
|
||||
error = new EventEmitter<any>();
|
||||
/** Emitted when the "Cancel" button is clicked. */
|
||||
@Output()
|
||||
cancel = new EventEmitter<void>();
|
||||
|
||||
/** Emitted when the "Cancel" button is clicked. */
|
||||
@Output()
|
||||
cancel = new EventEmitter<void>();
|
||||
/** Emitted when the task is claimed. */
|
||||
@Output()
|
||||
taskClaimed = new EventEmitter<string>();
|
||||
|
||||
/** Emitted when the task is claimed. */
|
||||
@Output()
|
||||
taskClaimed = new EventEmitter<string>();
|
||||
/** Emitted when the task is unclaimed (ie, requeued).. */
|
||||
@Output()
|
||||
taskUnclaimed = new EventEmitter<string>();
|
||||
|
||||
/** Emitted when the task is unclaimed (ie, requeued).. */
|
||||
@Output()
|
||||
taskUnclaimed = new EventEmitter<string>();
|
||||
taskDetails: TaskDetailsModel;
|
||||
currentLoggedUser: UserRepresentation;
|
||||
loading: boolean = false;
|
||||
completedTaskMessage: string;
|
||||
internalReadOnlyForm: boolean = false;
|
||||
|
||||
taskDetails: TaskDetailsModel;
|
||||
currentLoggedUser: UserRepresentation;
|
||||
loading: boolean = false;
|
||||
completedTaskMessage: string;
|
||||
internalReadOnlyForm: boolean = false;
|
||||
constructor(
|
||||
private taskListService: TaskListService,
|
||||
private peopleProcessService: PeopleProcessService,
|
||||
private translationService: TranslationService
|
||||
) {}
|
||||
|
||||
constructor(
|
||||
private taskListService: TaskListService,
|
||||
private peopleProcessService: PeopleProcessService,
|
||||
private translationService: TranslationService
|
||||
) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.peopleProcessService.getCurrentUserInfo().subscribe(user => {
|
||||
this.currentLoggedUser = user;
|
||||
});
|
||||
this.loadTask(this.taskId);
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
const taskId = changes['taskId'];
|
||||
if (taskId && taskId.currentValue) {
|
||||
this.loadTask(this.taskId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
loadTask(taskId: string) {
|
||||
this.loading = true;
|
||||
if (taskId) {
|
||||
this.taskListService.getTaskDetails(taskId).subscribe(
|
||||
(res: TaskDetailsModel) => {
|
||||
this.taskDetails = res;
|
||||
|
||||
if (!this.taskDetails.name) {
|
||||
this.taskDetails.name = 'No name';
|
||||
}
|
||||
|
||||
const endDate: any = res.endDate;
|
||||
if (endDate && !isNaN(endDate.getTime())) {
|
||||
this.internalReadOnlyForm = true;
|
||||
} else {
|
||||
this.internalReadOnlyForm = this.readOnlyForm;
|
||||
}
|
||||
this.loading = false;
|
||||
ngOnInit() {
|
||||
this.peopleProcessService.getCurrentUserInfo().subscribe((user) => {
|
||||
this.currentLoggedUser = user;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onFormSaved(savedForm: FormModel) {
|
||||
this.formSaved.emit(savedForm);
|
||||
}
|
||||
|
||||
onFormCompleted(form: FormModel) {
|
||||
this.formCompleted.emit(form);
|
||||
}
|
||||
|
||||
onFormLoaded(form: FormModel): void {
|
||||
this.formLoaded.emit(form);
|
||||
}
|
||||
|
||||
onFormContentClick(content: ContentLinkModel): void {
|
||||
this.formContentClicked.emit(content);
|
||||
}
|
||||
|
||||
onFormExecuteOutcome(outcome: FormOutcomeEvent) {
|
||||
this.executeOutcome.emit(outcome);
|
||||
}
|
||||
|
||||
onFormError(error: any) {
|
||||
this.formError.emit(error);
|
||||
}
|
||||
|
||||
onError(error: any) {
|
||||
this.error.emit(error);
|
||||
}
|
||||
|
||||
onCompleteTask() {
|
||||
this.taskListService.completeTask(this.taskDetails.id).subscribe(
|
||||
() => this.completed.emit(),
|
||||
(error) => this.error.emit(error));
|
||||
}
|
||||
|
||||
onCancel() {
|
||||
this.cancel.emit();
|
||||
}
|
||||
|
||||
onShowAttachForm() {
|
||||
this.showAttachForm.emit();
|
||||
}
|
||||
|
||||
hasFormKey(): boolean {
|
||||
return (this.taskDetails && (!!this.taskDetails.formKey));
|
||||
}
|
||||
|
||||
isStandaloneTask(): boolean {
|
||||
return !(this.taskDetails && (!!this.taskDetails.processDefinitionId));
|
||||
}
|
||||
|
||||
isTaskLoaded(): boolean {
|
||||
return !!this.taskDetails;
|
||||
}
|
||||
|
||||
isCompletedTask(): boolean {
|
||||
return this.taskDetails && this.taskDetails.endDate !== undefined && this.taskDetails.endDate !== null;
|
||||
}
|
||||
|
||||
isCompleteButtonVisible(): boolean {
|
||||
return !this.hasFormKey() && this.isTaskActive() && this.isCompleteButtonEnabled();
|
||||
}
|
||||
|
||||
isTaskActive() {
|
||||
return this.taskDetails && this.taskDetails.duration === null;
|
||||
}
|
||||
|
||||
isAssigned(): boolean {
|
||||
return !!this.taskDetails.assignee;
|
||||
}
|
||||
|
||||
isAssignedToMe(): boolean {
|
||||
return this.isAssigned() && this.hasEmailAddress() ?
|
||||
this.isEmailEqual() :
|
||||
this.isExternalIdEqual();
|
||||
}
|
||||
|
||||
isCompleteButtonEnabled(): boolean {
|
||||
return this.isAssignedToMe() || this.canInitiatorComplete();
|
||||
}
|
||||
|
||||
canInitiatorComplete(): boolean {
|
||||
return this.taskDetails.initiatorCanCompleteTask;
|
||||
}
|
||||
|
||||
isReadOnlyForm(): boolean {
|
||||
let readOnlyForm: boolean;
|
||||
if (this.isCandidateMember()) {
|
||||
readOnlyForm = this.internalReadOnlyForm || !this.isAssignedToMe();
|
||||
} else {
|
||||
readOnlyForm = this.internalReadOnlyForm || !(this.isAssignedToMe() || this.canCurrentUserAsInitiatorComplete() || this.isCurrentUserInvolved());
|
||||
this.loadTask(this.taskId);
|
||||
}
|
||||
|
||||
return readOnlyForm;
|
||||
}
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
const taskId = changes['taskId'];
|
||||
if (taskId?.currentValue) {
|
||||
this.loadTask(this.taskId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
isCurrentUserInvolved(): boolean {
|
||||
let isInvolved = false;
|
||||
if (this.taskDetails.involvedPeople && this.currentLoggedUser) {
|
||||
const userInvolved = this.taskDetails.involvedPeople.find(
|
||||
(involvedUser: LightUserRepresentation) =>
|
||||
involvedUser.email.toLocaleLowerCase() === this.currentLoggedUser.email.toLocaleLowerCase() ||
|
||||
involvedUser.id + '' === this.currentLoggedUser.externalId
|
||||
loadTask(taskId: string) {
|
||||
this.loading = true;
|
||||
if (taskId) {
|
||||
this.taskListService.getTaskDetails(taskId).subscribe((res) => {
|
||||
this.taskDetails = res;
|
||||
|
||||
if (!this.taskDetails.name) {
|
||||
this.taskDetails.name = 'No name';
|
||||
}
|
||||
|
||||
const endDate: any = res.endDate;
|
||||
if (endDate && !isNaN(endDate.getTime())) {
|
||||
this.internalReadOnlyForm = true;
|
||||
} else {
|
||||
this.internalReadOnlyForm = this.readOnlyForm;
|
||||
}
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onFormSaved(savedForm: FormModel) {
|
||||
this.formSaved.emit(savedForm);
|
||||
}
|
||||
|
||||
onFormCompleted(form: FormModel) {
|
||||
this.formCompleted.emit(form);
|
||||
}
|
||||
|
||||
onFormLoaded(form: FormModel): void {
|
||||
this.formLoaded.emit(form);
|
||||
}
|
||||
|
||||
onFormContentClick(content: ContentLinkModel): void {
|
||||
this.formContentClicked.emit(content);
|
||||
}
|
||||
|
||||
onFormExecuteOutcome(outcome: FormOutcomeEvent) {
|
||||
this.executeOutcome.emit(outcome);
|
||||
}
|
||||
|
||||
onFormError(error: any) {
|
||||
this.formError.emit(error);
|
||||
}
|
||||
|
||||
onError(error: any) {
|
||||
this.error.emit(error);
|
||||
}
|
||||
|
||||
onCompleteTask() {
|
||||
this.taskListService.completeTask(this.taskDetails.id).subscribe(
|
||||
() => this.completed.emit(),
|
||||
(error) => this.error.emit(error)
|
||||
);
|
||||
isInvolved = !!userInvolved;
|
||||
}
|
||||
|
||||
if (this.taskDetails.involvedGroups?.length && this.currentLoggedUser.groups?.length && !isInvolved) {
|
||||
const userGroup = this.taskDetails.involvedGroups.find(
|
||||
(involvedGroup: LightGroupRepresentation) =>
|
||||
this.currentLoggedUser.groups.find(
|
||||
group => group.name === involvedGroup.name.toLocaleLowerCase() || group.id === involvedGroup.id
|
||||
)
|
||||
onCancel() {
|
||||
this.cancel.emit();
|
||||
}
|
||||
|
||||
onShowAttachForm() {
|
||||
this.showAttachForm.emit();
|
||||
}
|
||||
|
||||
hasFormKey(): boolean {
|
||||
return !!this.taskDetails?.formKey;
|
||||
}
|
||||
|
||||
isStandaloneTask(): boolean {
|
||||
return !!!this.taskDetails?.processDefinitionId;
|
||||
}
|
||||
|
||||
isTaskLoaded(): boolean {
|
||||
return !!this.taskDetails;
|
||||
}
|
||||
|
||||
isCompletedTask(): boolean {
|
||||
return !!this.taskDetails?.endDate;
|
||||
}
|
||||
|
||||
isCompleteButtonVisible(): boolean {
|
||||
return !this.hasFormKey() && this.isTaskActive() && this.isCompleteButtonEnabled();
|
||||
}
|
||||
|
||||
isTaskActive() {
|
||||
return this.taskDetails?.duration === null;
|
||||
}
|
||||
|
||||
isAssigned(): boolean {
|
||||
return !!this.taskDetails.assignee;
|
||||
}
|
||||
|
||||
isAssignedToMe(): boolean {
|
||||
return this.isAssigned() && this.hasEmailAddress() ? this.isEmailEqual() : this.isExternalIdEqual();
|
||||
}
|
||||
|
||||
isCompleteButtonEnabled(): boolean {
|
||||
return this.isAssignedToMe() || this.canInitiatorComplete();
|
||||
}
|
||||
|
||||
canInitiatorComplete(): boolean {
|
||||
return !!this.taskDetails?.initiatorCanCompleteTask;
|
||||
}
|
||||
|
||||
isReadOnlyForm(): boolean {
|
||||
let readOnlyForm: boolean;
|
||||
if (this.isCandidateMember()) {
|
||||
readOnlyForm = this.internalReadOnlyForm || !this.isAssignedToMe();
|
||||
} else {
|
||||
readOnlyForm =
|
||||
this.internalReadOnlyForm || !(this.isAssignedToMe() || this.canCurrentUserAsInitiatorComplete() || this.isCurrentUserInvolved());
|
||||
}
|
||||
|
||||
return readOnlyForm;
|
||||
}
|
||||
|
||||
isCurrentUserInvolved(): boolean {
|
||||
let isInvolved = false;
|
||||
if (this.taskDetails.involvedPeople && this.currentLoggedUser) {
|
||||
const userInvolved = this.taskDetails.involvedPeople.find(
|
||||
(involvedUser) =>
|
||||
involvedUser.email.toLocaleLowerCase() === this.currentLoggedUser.email.toLocaleLowerCase() ||
|
||||
involvedUser.id + '' === this.currentLoggedUser.externalId
|
||||
);
|
||||
isInvolved = !!userInvolved;
|
||||
}
|
||||
|
||||
if (this.taskDetails.involvedGroups?.length && this.currentLoggedUser.groups?.length && !isInvolved) {
|
||||
const userGroup = this.taskDetails.involvedGroups.find((involvedGroup) =>
|
||||
this.currentLoggedUser.groups.find((group) => group.name === involvedGroup.name.toLocaleLowerCase() || group.id === involvedGroup.id)
|
||||
);
|
||||
isInvolved = !!userGroup;
|
||||
}
|
||||
return isInvolved;
|
||||
}
|
||||
|
||||
canCurrentUserAsInitiatorComplete(): boolean {
|
||||
return this.canInitiatorComplete() && this.isProcessInitiator();
|
||||
}
|
||||
|
||||
isProcessInitiator(): boolean {
|
||||
return this.currentLoggedUser && this.currentLoggedUser.id === +this.taskDetails.processInstanceStartUserId;
|
||||
}
|
||||
|
||||
isSaveButtonVisible(): boolean {
|
||||
return this.showFormSaveButton && (!this.canInitiatorComplete() || this.isAssignedToMe() || this.isCurrentUserInvolved());
|
||||
}
|
||||
|
||||
canCompleteNoFormTask(): boolean {
|
||||
return this.isReadOnlyForm();
|
||||
}
|
||||
|
||||
getCompletedTaskTranslatedMessage(): Observable<string> {
|
||||
return this.translationService.get('ADF_TASK_FORM.COMPLETED_TASK.TITLE', { taskName: this.taskDetails.name });
|
||||
}
|
||||
|
||||
isCandidateMember(): boolean {
|
||||
return this.taskDetails.managerOfCandidateGroup || this.taskDetails.memberOfCandidateGroup || this.taskDetails.memberOfCandidateUsers;
|
||||
}
|
||||
|
||||
isTaskClaimable(): boolean {
|
||||
return this.isCandidateMember() && !this.isAssigned();
|
||||
}
|
||||
|
||||
isTaskClaimedByCandidateMember(): boolean {
|
||||
return this.isCandidateMember() && this.isAssignedToMe() && !this.isCompletedTask();
|
||||
}
|
||||
|
||||
reloadTask() {
|
||||
this.loadTask(this.taskId);
|
||||
}
|
||||
|
||||
onClaimTask(taskId: string) {
|
||||
this.taskClaimed.emit(taskId);
|
||||
}
|
||||
|
||||
onClaimTaskError(error: any) {
|
||||
this.error.emit(error);
|
||||
}
|
||||
|
||||
onUnclaimTask(taskId: string) {
|
||||
this.taskUnclaimed.emit(taskId);
|
||||
}
|
||||
|
||||
onUnclaimTaskError(error: any) {
|
||||
this.error.emit(error);
|
||||
}
|
||||
|
||||
private hasEmailAddress(): boolean {
|
||||
return !!this.taskDetails.assignee.email;
|
||||
}
|
||||
|
||||
private isEmailEqual(): boolean {
|
||||
return (
|
||||
this.taskDetails.assignee &&
|
||||
this.currentLoggedUser &&
|
||||
this.taskDetails.assignee.email.toLocaleLowerCase() === this.currentLoggedUser.email.toLocaleLowerCase()
|
||||
);
|
||||
isInvolved = !!userGroup;
|
||||
}
|
||||
return isInvolved;
|
||||
}
|
||||
|
||||
canCurrentUserAsInitiatorComplete(): boolean {
|
||||
return this.canInitiatorComplete() && this.isProcessInitiator();
|
||||
}
|
||||
|
||||
isProcessInitiator(): boolean {
|
||||
return this.currentLoggedUser && ( this.currentLoggedUser.id === +this.taskDetails.processInstanceStartUserId);
|
||||
}
|
||||
|
||||
isSaveButtonVisible(): boolean {
|
||||
return this.showFormSaveButton && (!this.canInitiatorComplete() || this.isAssignedToMe() || this.isCurrentUserInvolved());
|
||||
}
|
||||
|
||||
canCompleteNoFormTask(): boolean {
|
||||
return this.isReadOnlyForm();
|
||||
}
|
||||
|
||||
getCompletedTaskTranslatedMessage(): Observable<string> {
|
||||
return this.translationService.get('ADF_TASK_FORM.COMPLETED_TASK.TITLE', { taskName: this.taskDetails.name });
|
||||
}
|
||||
|
||||
isCandidateMember(): boolean {
|
||||
return this.taskDetails.managerOfCandidateGroup || this.taskDetails.memberOfCandidateGroup || this.taskDetails.memberOfCandidateUsers;
|
||||
}
|
||||
|
||||
isTaskClaimable(): boolean {
|
||||
return this.isCandidateMember() && !this.isAssigned();
|
||||
}
|
||||
|
||||
isTaskClaimedByCandidateMember(): boolean {
|
||||
return this.isCandidateMember() && this.isAssignedToMe() && !this.isCompletedTask();
|
||||
}
|
||||
|
||||
reloadTask() {
|
||||
this.loadTask(this.taskId);
|
||||
}
|
||||
|
||||
onClaimTask(taskId: string) {
|
||||
this.taskClaimed.emit(taskId);
|
||||
}
|
||||
|
||||
onClaimTaskError(error: any) {
|
||||
this.error.emit(error);
|
||||
}
|
||||
|
||||
onUnclaimTask(taskId: string) {
|
||||
this.taskUnclaimed.emit(taskId);
|
||||
}
|
||||
|
||||
onUnclaimTaskError(error: any) {
|
||||
this.error.emit(error);
|
||||
}
|
||||
|
||||
private hasEmailAddress(): boolean {
|
||||
return this.taskDetails.assignee.email ? true : false;
|
||||
}
|
||||
|
||||
private isEmailEqual(): boolean {
|
||||
return (this.taskDetails.assignee && this.currentLoggedUser) && ( this.taskDetails.assignee.email.toLocaleLowerCase() === this.currentLoggedUser.email.toLocaleLowerCase());
|
||||
}
|
||||
|
||||
private isExternalIdEqual(): boolean {
|
||||
return (this.taskDetails.assignee && this.currentLoggedUser) && (this.taskDetails.assignee.externalId === this.currentLoggedUser.externalId);
|
||||
}
|
||||
private isExternalIdEqual(): boolean {
|
||||
return this.taskDetails.assignee && this.currentLoggedUser && this.taskDetails.assignee.externalId === this.currentLoggedUser.externalId;
|
||||
}
|
||||
}
|
||||
|
@@ -37,7 +37,6 @@ import { TaskDescriptionValidator } from '../validators/task-description.validat
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class TaskHeaderComponent implements OnChanges, OnInit {
|
||||
|
||||
/** The name of the form. */
|
||||
@Input()
|
||||
formName: string = null;
|
||||
@@ -58,7 +57,7 @@ export class TaskHeaderComponent implements OnChanges, OnInit {
|
||||
@Output()
|
||||
unclaim: EventEmitter<any> = new EventEmitter<any>();
|
||||
|
||||
properties: any [] = [];
|
||||
properties: any[] = [];
|
||||
inEdit: boolean = false;
|
||||
displayDateClearAction = false;
|
||||
dateFormat: string;
|
||||
@@ -66,9 +65,11 @@ export class TaskHeaderComponent implements OnChanges, OnInit {
|
||||
|
||||
private currentUserId: number;
|
||||
|
||||
constructor(private peopleProcessService: PeopleProcessService,
|
||||
private translationService: TranslationService,
|
||||
private appConfig: AppConfigService) {
|
||||
constructor(
|
||||
private peopleProcessService: PeopleProcessService,
|
||||
private translationService: TranslationService,
|
||||
private appConfig: AppConfigService
|
||||
) {
|
||||
this.dateFormat = this.appConfig.get('dateValues.defaultDateFormat');
|
||||
this.dateLocale = this.appConfig.get('dateValues.defaultDateLocale');
|
||||
}
|
||||
@@ -175,7 +176,7 @@ export class TaskHeaderComponent implements OnChanges, OnInit {
|
||||
* Returns task's status
|
||||
*/
|
||||
getTaskStatus(): string {
|
||||
return (this.taskDetails && this.taskDetails.isCompleted()) ? 'Completed' : 'Running';
|
||||
return this.taskDetails?.isCompleted() ? 'Completed' : 'Running';
|
||||
}
|
||||
|
||||
onClaimTask(taskId: string) {
|
||||
@@ -190,7 +191,7 @@ export class TaskHeaderComponent implements OnChanges, OnInit {
|
||||
* Returns true if the task is completed
|
||||
*/
|
||||
isCompleted(): boolean {
|
||||
return this.taskDetails && !!this.taskDetails.endDate;
|
||||
return !!this.taskDetails?.endDate;
|
||||
}
|
||||
|
||||
isFormClickable(): boolean {
|
||||
@@ -203,120 +204,94 @@ export class TaskHeaderComponent implements OnChanges, OnInit {
|
||||
|
||||
private initDefaultProperties(parentInfoMap): any[] {
|
||||
return [
|
||||
new CardViewTextItemModel(
|
||||
{
|
||||
label: 'ADF_TASK_LIST.PROPERTIES.ASSIGNEE',
|
||||
value: this.taskDetails.getFullName(),
|
||||
key: 'assignee',
|
||||
default: this.translationService.instant('ADF_TASK_LIST.PROPERTIES.ASSIGNEE_DEFAULT'),
|
||||
clickable: !this.isCompleted(),
|
||||
icon: 'create'
|
||||
}
|
||||
),
|
||||
new CardViewTextItemModel(
|
||||
{
|
||||
label: 'ADF_TASK_LIST.PROPERTIES.STATUS',
|
||||
value: this.getTaskStatus(),
|
||||
key: 'status'
|
||||
}
|
||||
),
|
||||
new CardViewIntItemModel(
|
||||
{
|
||||
label: 'ADF_TASK_LIST.PROPERTIES.PRIORITY',
|
||||
value: this.taskDetails.priority,
|
||||
key: 'priority',
|
||||
editable: true,
|
||||
validators: [new CardViewItemLengthValidator(1, 10)]
|
||||
}
|
||||
),
|
||||
new CardViewDateItemModel(
|
||||
{
|
||||
label: 'ADF_TASK_LIST.PROPERTIES.DUE_DATE',
|
||||
value: this.taskDetails.dueDate,
|
||||
key: 'dueDate',
|
||||
default: this.translationService.instant('ADF_TASK_LIST.PROPERTIES.DUE_DATE_DEFAULT'),
|
||||
editable: true,
|
||||
format: this.dateFormat,
|
||||
locale: this.dateLocale
|
||||
}
|
||||
),
|
||||
new CardViewTextItemModel(
|
||||
{
|
||||
label: 'ADF_TASK_LIST.PROPERTIES.CATEGORY',
|
||||
value: this.taskDetails.category,
|
||||
key: 'category',
|
||||
default: this.translationService.instant('ADF_TASK_LIST.PROPERTIES.CATEGORY_DEFAULT')
|
||||
}
|
||||
),
|
||||
new CardViewMapItemModel(
|
||||
{
|
||||
label: 'ADF_TASK_LIST.PROPERTIES.PARENT_NAME',
|
||||
value: parentInfoMap,
|
||||
key: 'parentName',
|
||||
default: this.translationService.instant('ADF_TASK_LIST.PROPERTIES.PARENT_NAME_DEFAULT'),
|
||||
clickable: true
|
||||
}
|
||||
),
|
||||
new CardViewDateItemModel(
|
||||
{
|
||||
label: 'ADF_TASK_LIST.PROPERTIES.CREATED',
|
||||
value: this.taskDetails.created,
|
||||
key: 'created',
|
||||
format: this.dateFormat,
|
||||
locale: this.dateLocale
|
||||
}
|
||||
),
|
||||
new CardViewTextItemModel(
|
||||
{
|
||||
label: 'ADF_TASK_LIST.PROPERTIES.DURATION',
|
||||
value: this.getTaskDuration(),
|
||||
key: 'duration'
|
||||
}
|
||||
),
|
||||
new CardViewTextItemModel(
|
||||
{
|
||||
label: 'ADF_TASK_LIST.PROPERTIES.PARENT_TASK_ID',
|
||||
value: this.taskDetails.parentTaskId,
|
||||
key: 'parentTaskId'
|
||||
}
|
||||
),
|
||||
new CardViewDateItemModel(
|
||||
{
|
||||
label: 'ADF_TASK_LIST.PROPERTIES.END_DATE',
|
||||
value: this.taskDetails.endDate,
|
||||
key: 'endDate',
|
||||
format: this.dateFormat,
|
||||
locale: this.dateLocale
|
||||
}
|
||||
),
|
||||
new CardViewTextItemModel(
|
||||
{
|
||||
label: 'ADF_TASK_LIST.PROPERTIES.ID',
|
||||
value: this.taskDetails.id,
|
||||
key: 'id'
|
||||
}
|
||||
),
|
||||
new CardViewTextItemModel(
|
||||
{
|
||||
label: 'ADF_TASK_LIST.PROPERTIES.DESCRIPTION',
|
||||
value: this.taskDetails.description,
|
||||
key: 'description',
|
||||
default: this.translationService.instant('ADF_TASK_LIST.PROPERTIES.DESCRIPTION_DEFAULT'),
|
||||
multiline: true,
|
||||
editable: true,
|
||||
validators: [new TaskDescriptionValidator()]
|
||||
}
|
||||
),
|
||||
new CardViewTextItemModel(
|
||||
{
|
||||
label: 'ADF_TASK_LIST.PROPERTIES.FORM_NAME',
|
||||
value: this.formName,
|
||||
key: 'formName',
|
||||
default: this.translationService.instant('ADF_TASK_LIST.PROPERTIES.FORM_NAME_DEFAULT'),
|
||||
clickable: this.isFormClickable(),
|
||||
icon: 'create'
|
||||
}
|
||||
)
|
||||
new CardViewTextItemModel({
|
||||
label: 'ADF_TASK_LIST.PROPERTIES.ASSIGNEE',
|
||||
value: this.taskDetails.getFullName(),
|
||||
key: 'assignee',
|
||||
default: this.translationService.instant('ADF_TASK_LIST.PROPERTIES.ASSIGNEE_DEFAULT'),
|
||||
clickable: !this.isCompleted(),
|
||||
icon: 'create'
|
||||
}),
|
||||
new CardViewTextItemModel({
|
||||
label: 'ADF_TASK_LIST.PROPERTIES.STATUS',
|
||||
value: this.getTaskStatus(),
|
||||
key: 'status'
|
||||
}),
|
||||
new CardViewIntItemModel({
|
||||
label: 'ADF_TASK_LIST.PROPERTIES.PRIORITY',
|
||||
value: this.taskDetails.priority,
|
||||
key: 'priority',
|
||||
editable: true,
|
||||
validators: [new CardViewItemLengthValidator(1, 10)]
|
||||
}),
|
||||
new CardViewDateItemModel({
|
||||
label: 'ADF_TASK_LIST.PROPERTIES.DUE_DATE',
|
||||
value: this.taskDetails.dueDate,
|
||||
key: 'dueDate',
|
||||
default: this.translationService.instant('ADF_TASK_LIST.PROPERTIES.DUE_DATE_DEFAULT'),
|
||||
editable: true,
|
||||
format: this.dateFormat,
|
||||
locale: this.dateLocale
|
||||
}),
|
||||
new CardViewTextItemModel({
|
||||
label: 'ADF_TASK_LIST.PROPERTIES.CATEGORY',
|
||||
value: this.taskDetails.category,
|
||||
key: 'category',
|
||||
default: this.translationService.instant('ADF_TASK_LIST.PROPERTIES.CATEGORY_DEFAULT')
|
||||
}),
|
||||
new CardViewMapItemModel({
|
||||
label: 'ADF_TASK_LIST.PROPERTIES.PARENT_NAME',
|
||||
value: parentInfoMap,
|
||||
key: 'parentName',
|
||||
default: this.translationService.instant('ADF_TASK_LIST.PROPERTIES.PARENT_NAME_DEFAULT'),
|
||||
clickable: true
|
||||
}),
|
||||
new CardViewDateItemModel({
|
||||
label: 'ADF_TASK_LIST.PROPERTIES.CREATED',
|
||||
value: this.taskDetails.created,
|
||||
key: 'created',
|
||||
format: this.dateFormat,
|
||||
locale: this.dateLocale
|
||||
}),
|
||||
new CardViewTextItemModel({
|
||||
label: 'ADF_TASK_LIST.PROPERTIES.DURATION',
|
||||
value: this.getTaskDuration(),
|
||||
key: 'duration'
|
||||
}),
|
||||
new CardViewTextItemModel({
|
||||
label: 'ADF_TASK_LIST.PROPERTIES.PARENT_TASK_ID',
|
||||
value: this.taskDetails.parentTaskId,
|
||||
key: 'parentTaskId'
|
||||
}),
|
||||
new CardViewDateItemModel({
|
||||
label: 'ADF_TASK_LIST.PROPERTIES.END_DATE',
|
||||
value: this.taskDetails.endDate,
|
||||
key: 'endDate',
|
||||
format: this.dateFormat,
|
||||
locale: this.dateLocale
|
||||
}),
|
||||
new CardViewTextItemModel({
|
||||
label: 'ADF_TASK_LIST.PROPERTIES.ID',
|
||||
value: this.taskDetails.id,
|
||||
key: 'id'
|
||||
}),
|
||||
new CardViewTextItemModel({
|
||||
label: 'ADF_TASK_LIST.PROPERTIES.DESCRIPTION',
|
||||
value: this.taskDetails.description,
|
||||
key: 'description',
|
||||
default: this.translationService.instant('ADF_TASK_LIST.PROPERTIES.DESCRIPTION_DEFAULT'),
|
||||
multiline: true,
|
||||
editable: true,
|
||||
validators: [new TaskDescriptionValidator()]
|
||||
}),
|
||||
new CardViewTextItemModel({
|
||||
label: 'ADF_TASK_LIST.PROPERTIES.FORM_NAME',
|
||||
value: this.formName,
|
||||
key: 'formName',
|
||||
default: this.translationService.instant('ADF_TASK_LIST.PROPERTIES.FORM_NAME_DEFAULT'),
|
||||
clickable: this.isFormClickable(),
|
||||
icon: 'create'
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
|
@@ -16,12 +16,20 @@
|
||||
*/
|
||||
|
||||
import {
|
||||
DataRowEvent, DataTableAdapter, DataTableSchema, CustomEmptyContentTemplateDirective, CustomLoadingContentTemplateDirective,
|
||||
AppConfigService, PaginatedComponent,
|
||||
UserPreferencesService, UserPreferenceValues, PaginationModel, DataCellEvent, DEFAULT_PAGINATION } from '@alfresco/adf-core';
|
||||
import {
|
||||
AfterContentInit, Component, ContentChild, EventEmitter,
|
||||
Input, OnChanges, Output, SimpleChanges, OnDestroy, OnInit } from '@angular/core';
|
||||
DataRowEvent,
|
||||
DataTableAdapter,
|
||||
DataTableSchema,
|
||||
CustomEmptyContentTemplateDirective,
|
||||
CustomLoadingContentTemplateDirective,
|
||||
AppConfigService,
|
||||
PaginatedComponent,
|
||||
UserPreferencesService,
|
||||
UserPreferenceValues,
|
||||
PaginationModel,
|
||||
DataCellEvent,
|
||||
DEFAULT_PAGINATION
|
||||
} from '@alfresco/adf-core';
|
||||
import { AfterContentInit, Component, ContentChild, EventEmitter, Input, OnChanges, Output, SimpleChanges, OnDestroy, OnInit } from '@angular/core';
|
||||
|
||||
import { Observable, BehaviorSubject, Subject } from 'rxjs';
|
||||
import { TaskQueryRequestRepresentationModel } from '../models/filter.model';
|
||||
@@ -39,7 +47,6 @@ export const PRESET_KEY = 'adf-task-list.presets';
|
||||
styleUrls: ['./task-list.component.css']
|
||||
})
|
||||
export class TaskListComponent extends DataTableSchema implements OnChanges, AfterContentInit, PaginatedComponent, OnDestroy, OnInit {
|
||||
|
||||
@ContentChild(CustomEmptyContentTemplateDirective)
|
||||
customEmptyContent: CustomEmptyContentTemplateDirective;
|
||||
|
||||
@@ -183,9 +190,7 @@ export class TaskListComponent extends DataTableSchema implements OnChanges, Aft
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
constructor(private taskListService: TaskListService,
|
||||
appConfigService: AppConfigService,
|
||||
private userPreferences: UserPreferencesService) {
|
||||
constructor(private taskListService: TaskListService, appConfigService: AppConfigService, private userPreferences: UserPreferencesService) {
|
||||
super(appConfigService, PRESET_KEY, taskPresetsDefaultModel);
|
||||
|
||||
this.pagination = new BehaviorSubject<PaginationModel>({
|
||||
@@ -210,7 +215,7 @@ export class TaskListComponent extends DataTableSchema implements OnChanges, Aft
|
||||
this.userPreferences
|
||||
.select(UserPreferenceValues.PaginationSize)
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe(pageSize => this.size = pageSize);
|
||||
.subscribe((pageSize) => (this.size = pageSize));
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
@@ -335,12 +340,12 @@ export class TaskListComponent extends DataTableSchema implements OnChanges, Aft
|
||||
}
|
||||
|
||||
currentPage(skipCount: number, maxItems: number): number {
|
||||
return (skipCount && maxItems) ? Math.floor(skipCount / maxItems) : 0;
|
||||
return skipCount && maxItems ? Math.floor(skipCount / maxItems) : 0;
|
||||
}
|
||||
|
||||
private isSortChanged(changes: SimpleChanges): boolean {
|
||||
const actualSort = changes['sort'];
|
||||
return actualSort && actualSort.currentValue && actualSort.currentValue !== actualSort.previousValue;
|
||||
return actualSort?.currentValue && actualSort.currentValue !== actualSort.previousValue;
|
||||
}
|
||||
|
||||
private isPropertyChanged(changes: SimpleChanges): boolean {
|
||||
@@ -349,7 +354,7 @@ export class TaskListComponent extends DataTableSchema implements OnChanges, Aft
|
||||
const landingTaskId = changes['landingTaskId'];
|
||||
const page = changes['page'];
|
||||
const size = changes['size'];
|
||||
if (landingTaskId && landingTaskId.currentValue && this.isEqualToCurrentId(landingTaskId.currentValue)) {
|
||||
if (landingTaskId?.currentValue && this.isEqualToCurrentId(landingTaskId.currentValue)) {
|
||||
changed = false;
|
||||
} else if (page && page.currentValue !== page.previousValue) {
|
||||
changed = true;
|
||||
@@ -364,9 +369,9 @@ export class TaskListComponent extends DataTableSchema implements OnChanges, Aft
|
||||
this.isLoading = true;
|
||||
|
||||
this.loadTasksByState()
|
||||
.pipe(finalize(() => this.isLoading = false))
|
||||
.pipe(finalize(() => (this.isLoading = false)))
|
||||
.subscribe(
|
||||
tasks => {
|
||||
(tasks) => {
|
||||
this.rows = this.optimizeTaskDetails(tasks.data);
|
||||
this.selectTask(this.landingTaskId);
|
||||
this.success.emit(tasks);
|
||||
@@ -377,9 +382,10 @@ export class TaskListComponent extends DataTableSchema implements OnChanges, Aft
|
||||
totalItems: tasks.total
|
||||
});
|
||||
},
|
||||
error => {
|
||||
(error) => {
|
||||
this.error.emit(error);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private loadTasksByState(): Observable<TaskListModel> {
|
||||
|
@@ -21,7 +21,6 @@
|
||||
import { UserProcessModel } from '../../common/models/user-process.model';
|
||||
|
||||
export class StartTaskModel {
|
||||
|
||||
name: string;
|
||||
description: string;
|
||||
assignee: UserProcessModel;
|
||||
@@ -30,11 +29,11 @@ export class StartTaskModel {
|
||||
category: string;
|
||||
|
||||
constructor(obj?: any) {
|
||||
this.name = obj && obj.name || null;
|
||||
this.description = obj && obj.description || null;
|
||||
this.assignee = obj && obj.assignee ? new UserProcessModel(obj.assignee) : null;
|
||||
this.dueDate = obj && obj.dueDate || null;
|
||||
this.formKey = obj && obj.formKey || null;
|
||||
this.category = obj && obj.category || null;
|
||||
this.name = obj?.name;
|
||||
this.description = obj?.description;
|
||||
this.assignee = obj?.assignee ? new UserProcessModel(obj.assignee) : null;
|
||||
this.dueDate = obj?.dueDate;
|
||||
this.formKey = obj?.formKey;
|
||||
this.category = obj?.category;
|
||||
}
|
||||
}
|
||||
|
@@ -17,7 +17,15 @@
|
||||
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { fakeAppPromise } from '../../mock';
|
||||
import { fakeFiltersResponse, fakeAppFilter, dummyMyTasksFilter, dummyInvolvedTasksFilter, dummyQueuedTasksFilter, dummyCompletedTasksFilter, dummyDuplicateMyTasksFilter } from '../../mock/task/task-filters.mock';
|
||||
import {
|
||||
fakeFiltersResponse,
|
||||
fakeAppFilter,
|
||||
dummyMyTasksFilter,
|
||||
dummyInvolvedTasksFilter,
|
||||
dummyQueuedTasksFilter,
|
||||
dummyCompletedTasksFilter,
|
||||
dummyDuplicateMyTasksFilter
|
||||
} from '../../mock/task/task-filters.mock';
|
||||
import { FilterRepresentationModel } from '../models/filter.model';
|
||||
import { TaskFilterService } from './task-filter.service';
|
||||
import { CoreModule } from '@alfresco/adf-core';
|
||||
@@ -28,15 +36,11 @@ import { of } from 'rxjs';
|
||||
declare let jasmine: any;
|
||||
|
||||
describe('Activiti Task filter Service', () => {
|
||||
|
||||
let service: TaskFilterService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
CoreModule.forRoot(),
|
||||
ProcessTestingModule
|
||||
]
|
||||
imports: [CoreModule.forRoot(), ProcessTestingModule]
|
||||
});
|
||||
service = TestBed.inject(TaskFilterService);
|
||||
jasmine.Ajax.install();
|
||||
@@ -47,7 +51,6 @@ describe('Activiti Task filter Service', () => {
|
||||
});
|
||||
|
||||
describe('Content tests', () => {
|
||||
|
||||
it('should return the task list filters', (done) => {
|
||||
service.getTaskListFilters().subscribe((res) => {
|
||||
expect(res).toBeDefined();
|
||||
@@ -84,15 +87,14 @@ describe('Activiti Task filter Service', () => {
|
||||
|
||||
it('should return the task filter by name', (done) => {
|
||||
service.getTaskFilterByName('FakeMyTasks').subscribe((res: FilterRepresentationModel) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.id).toEqual(2);
|
||||
expect(res.name).toEqual('FakeMyTasks');
|
||||
expect(res.filter.sort).toEqual('created-desc');
|
||||
expect(res.filter.state).toEqual('open');
|
||||
expect(res.filter.assignment).toEqual('fake-assignee');
|
||||
done();
|
||||
}
|
||||
);
|
||||
expect(res).toBeDefined();
|
||||
expect(res.id).toEqual(2);
|
||||
expect(res.name).toEqual('FakeMyTasks');
|
||||
expect(res.filter.sort).toEqual('created-desc');
|
||||
expect(res.filter.state).toEqual('open');
|
||||
expect(res.filter.assignment).toEqual('fake-assignee');
|
||||
done();
|
||||
});
|
||||
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
status: 200,
|
||||
@@ -102,7 +104,7 @@ describe('Activiti Task filter Service', () => {
|
||||
});
|
||||
|
||||
it('should call the api with the appId', (done) => {
|
||||
spyOn(service, 'callApiTaskFilters').and.returnValue((fakeAppPromise));
|
||||
spyOn(service, 'callApiTaskFilters').and.returnValue(fakeAppPromise);
|
||||
|
||||
const appId = 1;
|
||||
service.getTaskListFilters(appId).subscribe(() => {
|
||||
@@ -146,7 +148,11 @@ describe('Activiti Task filter Service', () => {
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify({
|
||||
appId: 1001, id: 111, name: 'My Tasks', icon: 'fake-icon', recent: false
|
||||
appId: 1001,
|
||||
id: 111,
|
||||
name: 'My Tasks',
|
||||
icon: 'fake-icon',
|
||||
recent: false
|
||||
})
|
||||
});
|
||||
|
||||
@@ -154,7 +160,11 @@ describe('Activiti Task filter Service', () => {
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify({
|
||||
appId: 1001, id: 222, name: 'Involved Tasks', icon: 'fake-icon', recent: false
|
||||
appId: 1001,
|
||||
id: 222,
|
||||
name: 'Involved Tasks',
|
||||
icon: 'fake-icon',
|
||||
recent: false
|
||||
})
|
||||
});
|
||||
|
||||
@@ -162,7 +172,11 @@ describe('Activiti Task filter Service', () => {
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify({
|
||||
appId: 1001, id: 333, name: 'Queued Tasks', icon: 'fake-icon', recent: false
|
||||
appId: 1001,
|
||||
id: 333,
|
||||
name: 'Queued Tasks',
|
||||
icon: 'fake-icon',
|
||||
recent: false
|
||||
})
|
||||
});
|
||||
|
||||
@@ -170,7 +184,11 @@ describe('Activiti Task filter Service', () => {
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify({
|
||||
appId: 1001, id: 444, name: 'Completed Tasks', icon: 'fake-icon', recent: false
|
||||
appId: 1001,
|
||||
id: 444,
|
||||
name: 'Completed Tasks',
|
||||
icon: 'fake-icon',
|
||||
recent: false
|
||||
})
|
||||
});
|
||||
});
|
||||
@@ -201,7 +219,11 @@ describe('Activiti Task filter Service', () => {
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify({
|
||||
appId: 1001, id: 111, name: 'My Tasks', icon: 'fake-icon', recent: false
|
||||
appId: 1001,
|
||||
id: 111,
|
||||
name: 'My Tasks',
|
||||
icon: 'fake-icon',
|
||||
recent: false
|
||||
})
|
||||
});
|
||||
|
||||
@@ -209,7 +231,11 @@ describe('Activiti Task filter Service', () => {
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify({
|
||||
appId: 1001, id: 222, name: 'Involved Tasks', icon: 'fake-icon', recent: false
|
||||
appId: 1001,
|
||||
id: 222,
|
||||
name: 'Involved Tasks',
|
||||
icon: 'fake-icon',
|
||||
recent: false
|
||||
})
|
||||
});
|
||||
|
||||
@@ -217,7 +243,11 @@ describe('Activiti Task filter Service', () => {
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify({
|
||||
appId: 1001, id: 333, name: 'Queued Tasks', icon: 'fake-icon', recent: false
|
||||
appId: 1001,
|
||||
id: 333,
|
||||
name: 'Queued Tasks',
|
||||
icon: 'fake-icon',
|
||||
recent: false
|
||||
})
|
||||
});
|
||||
|
||||
@@ -225,7 +255,11 @@ describe('Activiti Task filter Service', () => {
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify({
|
||||
appId: 1001, id: 444, name: 'Completed Tasks', icon: 'fake-icon', recent: false
|
||||
appId: 1001,
|
||||
id: 444,
|
||||
name: 'Completed Tasks',
|
||||
icon: 'fake-icon',
|
||||
recent: false
|
||||
})
|
||||
});
|
||||
});
|
||||
@@ -248,11 +282,13 @@ describe('Activiti Task filter Service', () => {
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify({
|
||||
id: '2233', name: 'FakeNameFilter', filter: { assignment: 'fake-assignment' }
|
||||
id: '2233',
|
||||
name: 'FakeNameFilter',
|
||||
filter: { assignment: 'fake-assignment' }
|
||||
})
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('isFilterAlreadyExisting', () => {
|
||||
let dummyTaskFilters: FilterRepresentationModel[];
|
||||
@@ -268,16 +304,14 @@ describe('Activiti Task filter Service', () => {
|
||||
index: 0,
|
||||
name: 'My Tasks',
|
||||
recent: false,
|
||||
hasFilter: () => {
|
||||
return true;
|
||||
}
|
||||
hasFilter: () => true
|
||||
}
|
||||
];
|
||||
|
||||
filterRepresentationData = {
|
||||
name : '',
|
||||
sort : 'created-desc',
|
||||
state : 'running'
|
||||
name: '',
|
||||
sort: 'created-desc',
|
||||
state: 'running'
|
||||
};
|
||||
});
|
||||
|
||||
@@ -295,7 +329,6 @@ describe('Activiti Task filter Service', () => {
|
||||
});
|
||||
|
||||
describe('createDefaultFilters', () => {
|
||||
|
||||
it('should return an array with unique task filters', (done) => {
|
||||
const appId = 101;
|
||||
|
||||
@@ -316,7 +349,13 @@ describe('Activiti Task filter Service', () => {
|
||||
spyOn(service, 'getQueuedTasksFilterInstance').and.returnValue(queuedTasksFilter);
|
||||
spyOn(service, 'getCompletedTasksFilterInstance').and.returnValue(completedTasksFilter);
|
||||
|
||||
spyOn(service, 'addFilter').and.returnValues(myTasksObservableObservable, involvedTasksObservable, queuedTasksObservable, completedTasksObservable, duplicateMyTasksObservableObservable);
|
||||
spyOn(service, 'addFilter').and.returnValues(
|
||||
myTasksObservableObservable,
|
||||
involvedTasksObservable,
|
||||
queuedTasksObservable,
|
||||
completedTasksObservable,
|
||||
duplicateMyTasksObservableObservable
|
||||
);
|
||||
|
||||
service.createDefaultFilters(appId).subscribe((result) => {
|
||||
expect(result).toEqual([
|
||||
@@ -328,6 +367,5 @@ describe('Activiti Task filter Service', () => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user