[ACS-7427] Process Services improvements and cleanup (#9664)

This commit is contained in:
Denys Vuika 2024-05-20 16:08:47 -04:00 committed by GitHub
parent 96e607b4de
commit e71e2a749a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
174 changed files with 1736 additions and 3933 deletions

View File

@ -16,24 +16,18 @@
*/
import { EcmUserModel, PeopleContentService } from '@alfresco/adf-content-services';
import { BpmUserModel, PeopleProcessService } from '@alfresco/adf-process-services';
import {
AuthenticationService,
BasicAlfrescoAuthService,
IdentityUserModel,
IdentityUserService,
UserInfoMode
} from '@alfresco/adf-core';
import { PeopleProcessService } from '@alfresco/adf-process-services';
import { AuthenticationService, BasicAlfrescoAuthService, IdentityUserModel, IdentityUserService, UserInfoMode } from '@alfresco/adf-core';
import { Component, OnInit, Input } from '@angular/core';
import { MenuPositionX, MenuPositionY } from '@angular/material/menu';
import { Observable, of } from 'rxjs';
import { UserRepresentation } from '@alfresco/js-api';
@Component({
selector: 'app-shell-user-info',
templateUrl: './user-info.component.html'
})
export class UserInfoComponent implements OnInit {
/** Custom choice for opening the menu at the bottom. Can be `before` or `after`. */
@Input()
menuPositionX: MenuPositionX = 'after';
@ -44,17 +38,17 @@ export class UserInfoComponent implements OnInit {
mode: UserInfoMode;
ecmUser$: Observable<EcmUserModel>;
bpmUser$: Observable<BpmUserModel>;
bpmUser$: Observable<UserRepresentation>;
identityUser$: Observable<IdentityUserModel>;
selectedIndex: number;
userInfoMode = UserInfoMode;
constructor(private peopleContentService: PeopleContentService,
private peopleProcessService: PeopleProcessService,
private identityUserService: IdentityUserService,
private basicAlfrescoAuthService: BasicAlfrescoAuthService,
private authService: AuthenticationService) {
}
constructor(
private peopleContentService: PeopleContentService,
private peopleProcessService: PeopleProcessService,
private identityUserService: IdentityUserService,
private basicAlfrescoAuthService: BasicAlfrescoAuthService,
private authService: AuthenticationService
) {}
ngOnInit() {
this.getUserInfo();
@ -69,7 +63,6 @@ export class UserInfoComponent implements OnInit {
this.mode = UserInfoMode.CONTENT_SSO;
this.loadEcmUserInfo();
}
} else if (this.isAllLoggedIn()) {
this.loadEcmUserInfo();
this.loadBpmUserInfo();
@ -103,7 +96,10 @@ export class UserInfoComponent implements OnInit {
}
private isAllLoggedIn() {
return (this.authService.isEcmLoggedIn() && this.authService.isBpmLoggedIn()) || (this.authService.isALLProvider() && this.basicAlfrescoAuthService.isKerberosEnabled());
return (
(this.authService.isEcmLoggedIn() && this.authService.isBpmLoggedIn()) ||
(this.authService.isALLProvider() && this.basicAlfrescoAuthService.isKerberosEnabled())
);
}
private isBpmLoggedIn() {
@ -114,4 +110,3 @@ export class UserInfoComponent implements OnInit {
return this.authService.isEcmLoggedIn() || (this.authService.isECMProvider() && this.basicAlfrescoAuthService.isKerberosEnabled());
}
}

View File

@ -20,6 +20,7 @@ import { UntypedFormGroup, UntypedFormBuilder, Validators, UntypedFormControl, A
import { ActivatedRoute, Params } from '@angular/router';
import { debounceTime, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { ProcessInstanceQueryRepresentationSort, ProcessInstanceQueryRepresentationState } from '@alfresco/js-api';
const DEFAULT_SIZE = 20;
@ -27,15 +28,14 @@ const DEFAULT_SIZE = 20;
templateUrl: './process-list-demo.component.html',
styleUrls: [`./process-list-demo.component.scss`]
})
export class ProcessListDemoComponent implements OnInit, OnDestroy {
minValue = 0;
processListForm: UntypedFormGroup;
appId: number;
processDefId: string;
processInsId: string;
state: string;
sort: string;
state: ProcessInstanceQueryRepresentationState;
sort: ProcessInstanceQueryRepresentationSort;
size: number = DEFAULT_SIZE;
page: number = 0;
@ -48,15 +48,13 @@ export class ProcessListDemoComponent implements OnInit, OnDestroy {
];
sortOptions = [
{value: 'created-asc', title: 'Created (asc)'},
{value: 'created-desc', title: 'Created (desc)'}
{ value: 'created-asc', title: 'Created (asc)' },
{ value: 'created-desc', title: 'Created (desc)' }
];
private onDestroy$ = new Subject<boolean>();
constructor(private route: ActivatedRoute,
private formBuilder: UntypedFormBuilder) {
}
constructor(private route: ActivatedRoute, private formBuilder: UntypedFormBuilder) {}
ngOnInit() {
this.resetQueryParameters();
@ -91,12 +89,11 @@ export class ProcessListDemoComponent implements OnInit, OnDestroy {
this.processListForm.valueChanges
.pipe(takeUntil(this.onDestroy$))
.pipe(debounceTime(500))
.subscribe(processFilter => {
.subscribe((processFilter) => {
if (this.isFormValid()) {
this.filterProcesses(processFilter);
}
});
}
filterProcesses(processFilter: any) {

View File

@ -17,19 +17,16 @@
import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { AppDefinitionRepresentationModel } from '@alfresco/adf-process-services';
import { AppDefinitionRepresentation } from '@alfresco/js-api';
@Component({
selector: 'app-process-list-view',
templateUrl: './apps-view.component.html'
})
export class AppsViewComponent {
constructor(private router: Router) {}
constructor(private router: Router) {
onAppClicked(app: AppDefinitionRepresentation) {
this.router.navigate(['/activiti/apps', app.id || 0, 'tasks']);
}
onAppClicked(app: AppDefinitionRepresentationModel) {
this.router.navigate(['/activiti/apps', app.id || 0, 'tasks']);
}
}

View File

@ -1,36 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { FormFieldModel, FormFieldTypes, FormFieldValidator } from '@alfresco/adf-core';
export class DemoFieldValidator implements FormFieldValidator {
isSupported(field: FormFieldModel): boolean {
return field && field.type === FormFieldTypes.TEXT;
}
validate(field: FormFieldModel): boolean {
if (this.isSupported(field)) {
if (field.value && field.value.toLowerCase() === 'admin') {
field.validationSummary.message = 'Sorry, the value cannot be "admin".';
return false;
}
}
return true;
}
}

View File

@ -16,29 +16,12 @@
*/
import { Component, Input, OnChanges, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import {
ProcessAttachmentListComponent,
ProcessInstance,
ProcessService,
ProcessUploadService
} from '@alfresco/adf-process-services';
import { AlfrescoApiService, AppConfigService } from '@alfresco/adf-core';
import { DiscoveryApiService, UploadService } from '@alfresco/adf-content-services';
import { ProcessAttachmentListComponent, ProcessService, ProcessUploadService } from '@alfresco/adf-process-services';
import { UploadService } from '@alfresco/adf-content-services';
import { PreviewService } from '../../services/preview.service';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
/**
* Provide a factory for process upload service
*
* @param api api client
* @param config config service
* @param discoveryApiService discovery service
* @returns factory function
*/
export function processUploadServiceFactory(api: AlfrescoApiService, config: AppConfigService, discoveryApiService: DiscoveryApiService) {
return new ProcessUploadService(api, config, discoveryApiService);
}
import { ProcessInstanceRepresentation } from '@alfresco/js-api';
@Component({
selector: 'app-process-attachments',
@ -47,41 +30,31 @@ export function processUploadServiceFactory(api: AlfrescoApiService, config: App
providers: [
{
provide: UploadService,
useFactory: (processUploadServiceFactory),
deps: [AlfrescoApiService, AppConfigService, DiscoveryApiService]
useClass: ProcessUploadService
}
],
encapsulation: ViewEncapsulation.None
})
export class ProcessAttachmentsComponent implements OnInit, OnChanges, OnDestroy {
@ViewChild('processAttachList')
processAttachList: ProcessAttachmentListComponent;
@Input()
processInstanceId: string;
processInstance: ProcessInstance;
processInstance: ProcessInstanceRepresentation;
private onDestroy$ = new Subject<boolean>();
constructor(
private uploadService: UploadService,
private processService: ProcessService,
private preview: PreviewService
) {}
constructor(private uploadService: UploadService, private processService: ProcessService, private preview: PreviewService) {}
ngOnInit() {
this.uploadService.fileUploadComplete
.pipe(takeUntil(this.onDestroy$))
.subscribe(value => this.onFileUploadComplete(value.data));
this.uploadService.fileUploadComplete.pipe(takeUntil(this.onDestroy$)).subscribe((value) => this.onFileUploadComplete(value.data));
}
ngOnChanges() {
if (this.processInstanceId) {
this.processService.getProcess(this.processInstanceId)
.subscribe((processInstance: ProcessInstance) => {
this.processService.getProcess(this.processInstanceId).subscribe((processInstance) => {
this.processInstance = processInstance;
});
}
@ -103,5 +76,4 @@ export class ProcessAttachmentsComponent implements OnInit, OnChanges, OnDestroy
isCompletedProcess(): boolean {
return this.processInstance?.ended != null;
}
}

View File

@ -162,7 +162,7 @@
[title]="'Start Process'"
[name]="defaultProcessName"
(formContentClicked)="onContentClick($event)"
(start)="onStartProcessInstance($event)"
(start)="onStartProcessInstance($event.id)"
(cancel)="onCancelProcessInstance()"
(error)="onStartProcessError($event)">
</adf-start-process>

View File

@ -18,7 +18,7 @@
// eslint-disable-next-line
import { AfterViewInit, Component, ElementRef, Input, OnDestroy, OnInit, ViewChild, ViewEncapsulation, EventEmitter, Output } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Pagination, UserProcessInstanceFilterRepresentation, ScriptFilesApi } from '@alfresco/js-api';
import { Pagination, UserProcessInstanceFilterRepresentation, ScriptFilesApi, UserTaskFilterRepresentation } from '@alfresco/js-api';
import {
FORM_FIELD_VALIDATORS,
FormRenderingService,
@ -32,10 +32,8 @@ import {
} from '@alfresco/adf-core';
import {
ProcessFiltersComponent,
ProcessInstance,
ProcessInstanceListComponent,
StartProcessInstanceComponent,
FilterRepresentationModel,
TaskDetailsEvent,
TaskFiltersComponent,
TaskListComponent,
@ -45,7 +43,6 @@ import {
DynamicTableRow
} from '@alfresco/adf-process-services';
import { Subject } from 'rxjs';
import { DemoFieldValidator } from './demo-field-validator';
import { PreviewService } from '../../services/preview.service';
import { Location } from '@angular/common';
import { takeUntil } from 'rxjs/operators';
@ -107,7 +104,7 @@ export class ProcessServiceComponent implements AfterViewInit, OnDestroy, OnInit
activeTab: number = this.tabs.tasks; // tasks|processes|reports
taskFilter: FilterRepresentationModel;
taskFilter: UserTaskFilterRepresentation;
processFilter: UserProcessInstanceFilterRepresentation;
blobFile: any;
flag = true;
@ -117,7 +114,7 @@ export class ProcessServiceComponent implements AfterViewInit, OnDestroy, OnInit
applicationId: number;
processDefinitionName: string;
fieldValidators = [...FORM_FIELD_VALIDATORS, new DemoFieldValidator()];
fieldValidators = [...FORM_FIELD_VALIDATORS];
private onDestroy$ = new Subject<boolean>();
private scriptFileApi: ScriptFilesApi;
@ -127,17 +124,17 @@ export class ProcessServiceComponent implements AfterViewInit, OnDestroy, OnInit
private route: ActivatedRoute,
private router: Router,
private apiService: AlfrescoApiService,
private appConfig: AppConfigService,
private preview: PreviewService,
private appConfigService: AppConfigService,
private previewService: PreviewService,
formService: FormService,
private location: Location,
private notificationService: NotificationService,
private preferenceService: UserPreferencesService
) {
this.scriptFileApi = new ScriptFilesApi(this.apiService.getInstance());
this.defaultProcessName = this.appConfig.get<string>('adf-start-process.name');
this.defaultProcessDefinitionName = this.appConfig.get<string>('adf-start-process.processDefinitionName');
this.defaultTaskName = this.appConfig.get<string>('adf-start-task.name');
this.defaultProcessName = this.appConfigService.get<string>('adf-start-process.name');
this.defaultProcessDefinitionName = this.appConfigService.get<string>('adf-start-process.processDefinitionName');
this.defaultTaskName = this.appConfigService.get<string>('adf-start-task.name');
this.processDefinitionName = this.defaultProcessDefinitionName;
this.preferenceService
@ -190,7 +187,7 @@ export class ProcessServiceComponent implements AfterViewInit, OnDestroy, OnInit
this.onDestroy$.complete();
}
onTaskFilterClick(filter: FilterRepresentationModel): void {
onTaskFilterClick(filter: UserTaskFilterRepresentation): void {
this.applyTaskFilter(filter);
this.taskPage = 0;
}
@ -218,7 +215,7 @@ export class ProcessServiceComponent implements AfterViewInit, OnDestroy, OnInit
this.applyTaskFilter(this.activitiFilter.getCurrentFilter());
}
applyTaskFilter(filter: FilterRepresentationModel) {
applyTaskFilter(filter: UserTaskFilterRepresentation) {
this.taskFilter = Object.assign({}, filter);
if (filter && this.taskList) {
@ -285,8 +282,8 @@ export class ProcessServiceComponent implements AfterViewInit, OnDestroy, OnInit
this.currentTaskId = currentTaskIdNew;
}
onStartProcessInstance(instance: ProcessInstance): void {
this.currentProcessInstanceId = instance.id;
onStartProcessInstance(instanceId: string): void {
this.currentProcessInstanceId = instanceId;
this.activitiStartProcess.reset();
this.activitiProcessFilter.selectRunningFilter();
}
@ -348,9 +345,9 @@ export class ProcessServiceComponent implements AfterViewInit, OnDestroy, OnInit
private showContentPreview(content: any) {
if (content.contentBlob) {
this.preview.showBlob(content.name, content.contentBlob);
this.previewService.showBlob(content.name, content.contentBlob);
} else {
this.preview.showResource(content.sourceId.split(';')[0]);
this.previewService.showResource(content.sourceId.split(';')[0]);
}
}

View File

@ -16,12 +16,7 @@
*/
import { Component, Input, OnChanges, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import {
TaskAttachmentListComponent,
TaskDetailsModel,
TaskListService,
TaskUploadService
} from '@alfresco/adf-process-services';
import { TaskAttachmentListComponent, TaskDetailsModel, TaskListService, TaskUploadService } from '@alfresco/adf-process-services';
import { AlfrescoApiService, AppConfigService } from '@alfresco/adf-core';
import { DiscoveryApiService, UploadService } from '@alfresco/adf-content-services';
import { PreviewService } from '../../services/preview.service';
@ -48,14 +43,12 @@ export function taskUploadServiceFactory(api: AlfrescoApiService, config: AppCon
providers: [
{
provide: UploadService,
useFactory: (taskUploadServiceFactory),
useFactory: taskUploadServiceFactory,
deps: [AlfrescoApiService, AppConfigService, DiscoveryApiService]
}
]
})
export class TaskAttachmentsComponent implements OnInit, OnChanges, OnDestroy {
@ViewChild('taskAttachList')
taskAttachList: TaskAttachmentListComponent;
@ -66,23 +59,15 @@ export class TaskAttachmentsComponent implements OnInit, OnChanges, OnDestroy {
private onDestroy$ = new Subject<boolean>();
constructor(
private uploadService: UploadService,
private activitiTaskList: TaskListService,
private preview: PreviewService) {
}
constructor(private uploadService: UploadService, private taskListService: TaskListService, private previewService: PreviewService) {}
ngOnInit() {
this.uploadService.fileUploadComplete
.pipe(takeUntil(this.onDestroy$))
.subscribe(event => this.onFileUploadComplete(event.data));
this.uploadService.fileUploadComplete.pipe(takeUntil(this.onDestroy$)).subscribe((event) => this.onFileUploadComplete(event.data));
}
ngOnChanges() {
if (this.taskId) {
this.activitiTaskList
.getTaskDetails(this.taskId)
.subscribe(taskDetails => this.taskDetails = taskDetails);
this.taskListService.getTaskDetails(this.taskId).subscribe((taskDetails) => (this.taskDetails = taskDetails));
}
}
@ -96,11 +81,10 @@ export class TaskAttachmentsComponent implements OnInit, OnChanges, OnDestroy {
}
onAttachmentClick(content: any): void {
this.preview.showBlob(content.name, content.contentBlob);
this.previewService.showBlob(content.name, content.contentBlob);
}
isCompletedTask(): boolean {
return this.taskDetails?.endDate != null;
}
}

View File

@ -163,29 +163,27 @@ for more information about installing and using the source code.
| Name | Description | Source link |
| ---- | ----------- | ----------- |
| [Bpm User model](core/models/bpm-user.model.md) | Contains information about a Process Services user. | [Source](../lib/process-services/src/lib/common/models/bpm-user.model.ts) |
| [Ecm User model](core/models/ecm-user.model.md) | Contains information about a Content Services user. | [Source](../lib/content-services/src/lib/common/models/ecm-user.model.ts) |
| [Form Field model](core/models/form-field.model.md) | Contains the value and metadata for a field of a Form component. | [Source](../lib/core/src/lib/form/components/widgets/core/form-field.model.ts) |
| [Product Version model](core/models/product-version.model.md) | Contains version and license information classes for Alfresco products. | [Source](../lib/core/src/lib/models/product-version.model.ts) |
| [User Process model](core/models/user-process.model.md) | Represents a Process Services user. | [Source](../lib/process-services/src/lib/common/models/user-process.model.ts) |
### Pipes
| Name | Description | Source link |
| ---- | ----------- | ----------- |
| [App Config Pipe](core/pipes/app-config.pipe.md) | Retrieves values from the application configuration file directly. | [Source](../lib/core/src/lib/app-config/app-config.pipe.ts) |
| [Decimal Number Pipe](core/pipes/decimal-number.pipe.md) | Transforms a number to have a certain amount of digits in its integer part and also in its decimal part. | [Source](../lib/core/src/lib/pipes/decimal-number.pipe.ts) |
| [File Size pipe](core/pipes/file-size.pipe.md) | Converts a number of bytes to the equivalent in KB, MB, etc. | [Source](../lib/core/src/lib/pipes/file-size.pipe.ts) |
| [Format Space pipe](core/pipes/format-space.pipe.md) | Replaces all the white space in a string with a supplied character. | [Source](../lib/core/src/lib/pipes/format-space.pipe.ts) |
| [Full name pipe](core/pipes/full-name.pipe.md) | Joins the first and last name properties from a UserProcessModel object into a single string. | [Source](../lib/core/src/lib/pipes/full-name.pipe.ts) |
| [Localized Date pipe](core/pipes/localized-date.pipe.md) | Converts a date to a given format and locale. | [Source](../lib/core/src/lib/pipes/localized-date.pipe.ts) |
| [Mime Type Icon pipe](core/pipes/mime-type-icon.pipe.md) | Retrieves an icon to represent a MIME type. | [Source](../lib/core/src/lib/pipes/mime-type-icon.pipe.ts) |
| Name | Description | Source link |
| ---- |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| ----------- |
| [App Config Pipe](core/pipes/app-config.pipe.md) | Retrieves values from the application configuration file directly. | [Source](../lib/core/src/lib/app-config/app-config.pipe.ts) |
| [Decimal Number Pipe](core/pipes/decimal-number.pipe.md) | Transforms a number to have a certain amount of digits in its integer part and also in its decimal part. | [Source](../lib/core/src/lib/pipes/decimal-number.pipe.ts) |
| [File Size pipe](core/pipes/file-size.pipe.md) | Converts a number of bytes to the equivalent in KB, MB, etc. | [Source](../lib/core/src/lib/pipes/file-size.pipe.ts) |
| [Format Space pipe](core/pipes/format-space.pipe.md) | Replaces all the white space in a string with a supplied character. | [Source](../lib/core/src/lib/pipes/format-space.pipe.ts) |
| [Full name pipe](core/pipes/full-name.pipe.md) | Joins the first and last name properties from a `UserLike` object into a single string. | [Source](../lib/core/src/lib/pipes/full-name.pipe.ts) |
| [Localized Date pipe](core/pipes/localized-date.pipe.md) | Converts a date to a given format and locale. | [Source](../lib/core/src/lib/pipes/localized-date.pipe.ts) |
| [Mime Type Icon pipe](core/pipes/mime-type-icon.pipe.md) | Retrieves an icon to represent a MIME type. | [Source](../lib/core/src/lib/pipes/mime-type-icon.pipe.ts) |
| [Multi Value Pipe](core/pipes/multi-value.pipe.md) | Takes an array of strings and turns it into one string where items are separated by a separator. The default separator applied to the list is the comma , however, you can set your own separator in the params of the pipe. | [Source](../lib/core/src/lib/pipes/multi-value.pipe.ts) |
| [Node Name Tooltip pipe](core/pipes/node-name-tooltip.pipe.md) | Formats the tooltip for a Node. | [Source](../lib/content-services/src/lib/pipes/node-name-tooltip.pipe.ts) |
| [Text Highlight pipe](core/pipes/text-highlight.pipe.md) | Adds highlighting to words or sections of text that match a search string. | [Source](../lib/core/src/lib/pipes/text-highlight.pipe.ts) |
| [Time Ago pipe](core/pipes/time-ago.pipe.md) | Converts a recent past date into a number of days ago. | [Source](../lib/core/src/lib/pipes/time-ago.pipe.ts) |
| [User Initial pipe](core/pipes/user-initial.pipe.md) | Takes the name fields of a UserProcessModel object and extracts and formats the initials. | [Source](../lib/core/src/lib/pipes/user-initial.pipe.ts) |
| [Date Time pipe](core/pipes/date-time.pipe.md) | Converts a given input value into a Date object and adjusts it according to the specified format and timezone offset. | [Source](../lib/core/src/lib/pipes/date-time.pipe.ts) |
| [Node Name Tooltip pipe](core/pipes/node-name-tooltip.pipe.md) | Formats the tooltip for a Node. | [Source](../lib/content-services/src/lib/pipes/node-name-tooltip.pipe.ts) |
| [Text Highlight pipe](core/pipes/text-highlight.pipe.md) | Adds highlighting to words or sections of text that match a search string. | [Source](../lib/core/src/lib/pipes/text-highlight.pipe.ts) |
| [Time Ago pipe](core/pipes/time-ago.pipe.md) | Converts a recent past date into a number of days ago. | [Source](../lib/core/src/lib/pipes/time-ago.pipe.ts) |
| [User Initial pipe](core/pipes/user-initial.pipe.md) | Takes the name fields of a `UserLike` object and extracts and formats the initials. | [Source](../lib/core/src/lib/pipes/user-initial.pipe.ts) |
| [Date Time pipe](core/pipes/date-time.pipe.md) | Converts a given input value into a Date object and adjusts it according to the specified format and timezone offset. | [Source](../lib/core/src/lib/pipes/date-time.pipe.ts) |
### Services

View File

@ -5,7 +5,7 @@ Status: Active
Last reviewed: 2019-02-08
---
# [Row Filter Model](../../../lib/content-services/document-list/data/row-filter.model.ts "Defined in row-filter.model.ts")
# Row Filter Model
Defines the Row Filter function used by the [Document List Component](../components/document-list.component.md).

View File

@ -2,22 +2,16 @@
Title: Content Comment List Service
Added: v6.0.0
Status: Active
Last reviewed: 2023-01-17
Last reviewed: 2024-05-14
---
# [Content Comment List service](../../../lib/content-services/src/lib/node-comments/services/content-comment-list.service.ts "Defined in content-comment-list.service.ts")
# Content Comment List Service
Gets user image for comments in Content Services.
## Class members
## API
### Methods
- **getUserImage**(user: `string`): `string`<br/>
- **getUserImage**(userId: `string`): `string`<br/>
Gets user image
- _user:_ `string` - The user id;
- **Returns** `string` - The user image path
## See also
- [Node comments component](../../../lib/content-services/src/lib/node-comments/node-comments.component.ts)

View File

@ -5,13 +5,11 @@ Status: Active
Last reviewed: 2022-12-19
---
# [Node Comments service](../../../lib/content-services/src/lib/node-comments/services/node-comments.service.ts "Defined in node-comments.service.ts")
# Node Comments Service
Adds and retrieves comments for nodes in Content Services.
## Class members
### Methods
## API
- **add**(id: `string`, message: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`CommentModel`](../../../lib/core/src/lib/models/comment.model.ts)`>`<br/>
Adds a comment to a task.
@ -23,10 +21,6 @@ Adds and retrieves comments for nodes in Content Services.
- _id:_ `string` - ID of the target task
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`CommentModel`](../../../lib/core/src/lib/models/comment.model.ts)`[]>` - Details for each comment
- **getUserImage**(avatarId: `string`): `string`<br/>
- _avatarId:_ `string` -
- **Returns** `string` -
## See also
- [Node comments component](../../../lib/content-services/src/lib/node-comments/node-comments.component.ts)
Gets the URL for the user's profile image.
- _avatarId:_ `string` - ID of the user
- **Returns** `string` - URL for the user's profile image

View File

@ -5,13 +5,11 @@ Status: Active
Last reviewed: 2022-12-19
---
# [Task Comments service](../../../lib/process-services/src/lib/task-comments/services/task-comments.service.ts "Defined in task-comments.service.ts")
# Task Comments Service
Adds and retrieves comments for task and process instances in Process Services.
## Class members
### Methods
## API
- **add**(id: `string`, message: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`CommentModel`](../../../lib/core/src/lib/models/comment.model.ts)`>`<br/>
Adds a comment to a task.
@ -22,11 +20,7 @@ Adds and retrieves comments for task and process instances in Process Services.
Gets all comments that have been added to a task.
- _id:_ `string` - ID of the target task
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`CommentModel`](../../../lib/core/src/lib/models/comment.model.ts)`[]>` - Details for each comment
- **getUserImage**(user: [`UserProcessModel`](../../core/models/user-process.model.md)): `string`<br/>
- _user:_ [`UserProcessModel`](../../core/models/user-process.model.md) -
- **Returns** `string` -
## See also
- [Task comments component](../../../lib/process-services/src/lib/task-comments/task-comments.component.ts)
- **getUserImage**(userId: `string`): `string`<br/>
Gets the URL for the user's profile image.
- _userId:_ `string` - ID of the user
- **Returns** `string` - URL for the user's profile image

View File

@ -1,27 +0,0 @@
---
Title: Bpm User model
Added: v2.0.0
Status: Active
---
# [Bpm User model](../../../lib/process-services/src/lib/common/models/bpm-user.model.ts "Defined in bpm-user.model.ts")
Contains information about a Process Services user.
## Details
Instances of this class are returned by the methods of the
[Bpm User service](../services/bpm-user.service.md). It implements the
[`UserRepresentation`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/activiti-rest-api/docs/UserRepresentation.md) interface, which is defined in the
[Alfresco JS API](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-activiti-rest-api/docs/UserRepresentation.md).
Note that the Typescript class for this model is in active development;
it is likely to change and so its properties are not listed here. For the
latest version of the class, see the
[source file](https://github.com/Alfresco/alfresco-ng2-components/blob/develop/lib/core/userinfo/models/bpm-user.model.ts).
## See also
- [Bpm user service](../services/bpm-user.service.md)
- [Ecm user model](ecm-user.model.md)
- [People process service](../services/people-process.service.md)

View File

@ -24,4 +24,3 @@ latest version of the class, see the
- [Ecm user service](../services/ecm-user.service.md)
- [People content service](../services/people-content.service.md)
- [Bpm user model](bpm-user.model.md)

View File

@ -1,24 +0,0 @@
---
Title: User Process model
Added: v2.0.0
Status: Active
---
# [User Process model](../../../lib/process-services/src/lib/common/models/user-process.model.ts "Defined in user-process.model.ts")
Represents a Process Services user.
## Details
This class contains basic information about a Process Services user and
is used throughout ADF to identify and list users (eg, to assign them to
a task or to list them in search results).
Note that the Typescript class for this model is in active development;
it is likely to change and so its properties are not listed here. For the
latest version of the class, see the
[source file](https://github.com/Alfresco/alfresco-ng2-components/blob/develop/lib/core/models/user-process.model.ts).
## See also
- [People process service](../services/people-process.service.md)

View File

@ -5,9 +5,9 @@ Status: Active
Last reviewed: 2018-11-12
---
# [Full name pipe](../../../lib/core/src/lib/pipes/full-name.pipe.ts "Defined in full-name.pipe.ts")
# Full Name Pipe
Joins the first and last name properties from a [`UserProcessModel`](../../core/models/user-process.model.md) object into a single string.
Joins the first and last name properties from the `UserLike` object into a single string.
## Basic Usage
@ -23,7 +23,7 @@ Joins the first and last name properties from a [`UserProcessModel`](../../core/
## Details
The pipe offers a convenient way to extract the name from a [User process model](../models/user-process.model.md) object.
The pipe offers a convenient way to extract the name from a `UserLike` object.
## See also

View File

@ -5,7 +5,7 @@ Status: Active
Last reviewed: 2018-11-19
---
# [Time Ago pipe](../../../lib/core/src/lib/pipes/time-ago.pipe.ts "Defined in time-ago.pipe.ts")
# Time Ago Pipe
Converts a recent past date into a number of days ago.
@ -21,14 +21,14 @@ Converts a recent past date into a number of days ago.
<!-- {% endraw %} -->
| Name | Type | Default value | Description |
| ---- | ---- | ------------- | ----------- |
| locale | string | 'en-US' | A locale id for the locale format rules to use. |
| Name | Type | Default value | Description |
|--------|--------|---------------|-------------------------------------------------|
| locale | string | 'en-US' | A locale id for the locale format rules to use. |
## Details
The pipe finds the difference between the input date and the current date. If it
is less than seven days then then the date will be formatted as "X days ago".
is less than seven days then the date will be formatted as "X days ago".
Otherwise, the usual full date format is used.
By default, it localizes the date to the language that is currently in use by the app. Furthermore, a different locale id can be passed to the pipe to overwrite the locale id to set a custom one.

View File

@ -5,9 +5,9 @@ Status: Active
Last reviewed: 2018-11-12
---
# [User Initial pipe](../../../lib/core/src/lib/pipes/user-initial.pipe.ts "Defined in user-initial.pipe.ts")
# User Initials Pipe
Takes the name fields of a [`UserProcessModel`](../../core/models/user-process.model.md) object and extracts and formats the initials.
Takes the name fields of a `UserLike` object and extracts and formats the initials.
## Basic Usage

View File

@ -13,10 +13,6 @@ Gets details of the Process Services apps that are deployed for the user.
### Methods
- **getApplicationDetailsById**(appId: `number`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`AppDefinitionRepresentation`](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-activiti-rest-api/docs/AppDefinitionRepresentation.md)`>`<br/>
Gets the details for a specific app ID number.
- _appId:_ `number` - ID of the target app
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`AppDefinitionRepresentation`](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-activiti-rest-api/docs/AppDefinitionRepresentation.md)`>` - Details of the app
- **getDeployedApplications**(): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`AppDefinitionRepresentation`](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-activiti-rest-api/docs/AppDefinitionRepresentation.md)`[]>`<br/>
Gets a list of deployed apps for this user.
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`AppDefinitionRepresentation`](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-activiti-rest-api/docs/AppDefinitionRepresentation.md)`[]>` - The list of deployed apps

View File

@ -13,18 +13,15 @@ Gets information about the current Process Services user.
### Methods
- **getCurrentUserInfo**(): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`BpmUserModel`](../../core/models/bpm-user.model.md)`>`<br/>
- **getCurrentUserInfo**(): `Observable<UserRepresentation>`<br/>
Gets information about the current user.
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`BpmUserModel`](../../core/models/bpm-user.model.md)`>` - User information object
- **Returns** [`Observable`<UserRepresentation>` - User information object
- **getCurrentUserProfileImage**(): `string`<br/>
Gets the current user's profile image as a URL.
- **Returns** `string` - URL string
## Details
The class returned by `getCurrentUserInfo` is detailed
in the [Bpm User model docs](../models/bpm-user.model.md).
See the
[getProfile](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-activiti-rest-api/docs/ProfileApi.md#getProfile)
and
@ -34,4 +31,3 @@ methods in the Alfresco JS API for more information about the REST calls used by
## See also
- [Ecm user service](../services/ecm-user.service.md)
- [Bpm user model](../models/bpm-user.model.md)

View File

@ -5,13 +5,11 @@ Status: Active
Last reviewed: 2018-11-14
---
# [Comment Process service](../../../lib/process-services/src/lib/process-comments/services/comment-process.service.ts "Defined in comment-process.service.ts")
# Comment Process Service
Adds and retrieves comments for task and process instances in Process Services.
## Class members
### Methods
## API
- **add**(id: `string`, message: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`CommentModel`](../../../lib/core/src/lib/models/comment.model.ts)`>`<br/>
Adds a comment to a process instance.
@ -22,13 +20,7 @@ Adds and retrieves comments for task and process instances in Process Services.
Gets all comments that have been added to a process instance.
- _id:_ `string` -
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`CommentModel`](../../../lib/core/src/lib/models/comment.model.ts)`[]>` - Details for each comment
- **getUserImage**(user: `any`): `string`<br/>
- _user:_ `any` -
- **Returns** `string` -
## Details
See the Comments API section of the
[Alfresco JS API docs](https://github.com/Alfresco/alfresco-js-api/tree/master/src/alfresco-activiti-rest-api)
for further details about the underlying REST API.
- **getUserImage**(userId: `string`): `string`<br/>
Gets the URL for the user image.
- _userId:_ `string` -
- **Returns** `string` - URL for the user image

View File

@ -4,7 +4,7 @@ Added: v2.0.0
Status: Active
---
# [Form service](../../../lib/core/src/lib/form/services/form.service.ts "Defined in form.service.ts")
# Form Service
Implements Process Services form methods
@ -13,11 +13,9 @@ Implements Process Services form methods
```ts
import { FormService, FormEvent, FormFieldEvent } from '@alfresco/adf-core';
@Component(...)
@Component()
class MyComponent {
constructor(formService: FormService) {
formService.formLoaded.subscribe(
(e: FormEvent) => {
console.log(`Form loaded: ${e.form.id}`);
@ -29,9 +27,7 @@ class MyComponent {
console.log(`Field value changed. Form: ${e.form.id}, Field: ${e.field.id}, Value: ${e.field.value}`);
}
);
}
}
```
@ -173,33 +169,25 @@ class MyComponent {
- `userId` - ID of the target user
- [`getWorkflowUsers(filter: string, groupId?: string): Observable<UserProcessModel[]>`](../../core/models/user-process.model.md)
- `getWorkflowUsers(filter: string, groupId?: string): Observable<LightUserRepresentation[]>`
Gets a list of workflow users.
- `filter` - Filter to select specific users
- `groupId` - (Optional) Group ID for the search
- [`getWorkflowGroups(filter: string, groupId?: string): Observable<GroupModel[]>`](../../../lib/core/src/lib/form/components/widgets/core/group.model.ts)
Gets a list of groups in a workflow.
- `getWorkflowGroups(filter: string, groupId?: string): Observable<GroupModel[]>`
Gets a list of groups in a workflow.
- `filter` - Filter to select specific groups
- `groupId` - (Optional) Group ID for the search
- `getFormId(res: any): string`
Gets the ID of a form.
Gets the ID of a form.
- `res` - Object representing a form
- `toJson(res: any): any`
Creates a JSON representation of form data.
Creates a JSON representation of form data.
- `res` - Object representing form data
- `toJsonArray(res: any): any`
Creates a JSON array representation of form data.
Creates a JSON array representation of form data.
- `res` - Object representing form data
- `handleError(error: any):`[`Observable`](http://reactivex.io/documentation/observable.html)`<any>`
Reports an error message.
- `error` - Data object with optional \`message\` and \`status\` fields for the error

View File

@ -2,69 +2,47 @@
Title: People Process service
Added: v2.0.0
Status: Active
Last reviewed: 2018-04-05
Last reviewed: 2024-05-14
---
# [People Process service](../../../lib/process-services/src/lib/common/services/people-process.service.ts "Defined in people-process.service.ts")
# People Process Service
Gets information about Process Services users.
## Class members
## API
### Methods
- **getCurrentUserInfo**(): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`BpmUserModel`](../../core/models/bpm-user.model.md)`>`<br/>
- **getCurrentUserInfo**(): `Observable<UserRepresentation>`<br/>
Gets information about the current user.
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`BpmUserModel`](../../core/models/bpm-user.model.md)`>` - User information object
- **Returns** `Observable<UserRepresentation>` - User information object
- **getCurrentUserProfileImage**(): `string`<br/>
Gets the current user's profile image as a URL.
- **Returns** `string` - URL string
- **getUserImage**(user: [`UserProcessModel`](../../core/models/user-process.model.md)): `string`<br/>
Gets the profile picture URL for the specified user.
- _user:_ [`UserProcessModel`](../../core/models/user-process.model.md) - The target user
- **Returns** `string` - Profile picture URL
- **getUserImage**(userId: string): `string`<br/>
Gets a user's profile image as a URL.
- _userId:_ `string` - User ID
- **Returns** `string` - URL string
- **getWorkflowGroups**(filter: `string`, groupId?: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`GroupModel`](../../../lib/core/src/lib/form/components/widgets/core/group.model.ts)`[]>`<br/>
Gets a list of groups in a workflow.
- _filter:_ `string` - Filter to select specific groups
- _groupId:_ `string` - (Optional) Group ID for the search
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`GroupModel`](../../../lib/core/src/lib/form/components/widgets/core/group.model.ts)`[]>` - Array of groups
- **getWorkflowUsers**(taskId?: `string`, searchWord?: `string`, groupId?: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`UserProcessModel`](../../core/models/user-process.model.md)`[]>`<br/>
- **getWorkflowUsers**(taskId?: `string`, searchWord?: `string`, groupId?: `string`): `Observable<LightUserRepresentation[]>`<br/>
Gets information about users across all tasks.
- _taskId:_ `string` - (Optional) ID of the task
- _searchWord:_ `string` - (Optional) Filter text to search for
- _groupId:_ `string` - (Optional)
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`UserProcessModel`](../../core/models/user-process.model.md)`[]>` - Array of user information objects
- **involveUserWithTask**(taskId: `string`, idToInvolve: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`UserProcessModel`](../../core/models/user-process.model.md)`[]>`<br/>
- **Returns** `Observable<LightUserRepresentation[]>` - Array of user information objects
- **involveUserWithTask**(taskId: `string`, idToInvolve: `string`): `Observable<LightUserRepresentation[]>`<br/>
Sets a user to be involved with a task.
- _taskId:_ `string` - ID of the target task
- _idToInvolve:_ `string` - ID of the user to involve
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`UserProcessModel`](../../core/models/user-process.model.md)`[]>` - Empty response when the update completes
- **removeInvolvedUser**(taskId: `string`, idToRemove: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`UserProcessModel`](../../core/models/user-process.model.md)`[]>`<br/>
- **Returns** `Observable<LightUserRepresentation>` - Empty response when the update completes
- **removeInvolvedUser**(taskId: `string`, idToRemove: `string`): `Observable<LightUserRepresentation[]>`<br/>
Removes a user who is currently involved with a task.
- _taskId:_ `string` - ID of the target task
- _idToRemove:_ `string` - ID of the user to remove
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`UserProcessModel`](../../core/models/user-process.model.md)`[]>` - Empty response when the update completes
## Details
Use `getWorkflowUsers` to find users across all tasks, optionally filtering by the `searchWord`
in the task name. The `taskId` parameter, if used, specifies a task to be _excluded_ from the
results. You would typically use this feature to find new users to assign to a task, in which
case you would want to exclude users already assigned to that task.
The [User Process model](../models/user-process.model.md) class used by the methods is seen throughout
ADF's Process Services features. Note that for `involveUserWithTask` and `removeInvolvedUser`,
null data is returned rather than usable details about users.
You can find more information about the REST API methods used by this service in the
[Task Actions API](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-activiti-rest-api/docs/TaskActionsApi.md#involveUser)
(for `involveUserWithTask` and `removeInvolvedUser`), the
[User Workflow API](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-activiti-rest-api/docs/UsersWorkflowApi.md#getUsers)
(for `getWorkflowUsers`) and the
[User API](https://github.com/Alfresco/alfresco-js-api/blob/master/src/alfresco-activiti-rest-api/docs/UserApi.md#getuserprofilepictureurl)(for `getUserImage`).
- **Returns** `Observable<LightUserRepresentation>` - Empty response when the update completes
## See also
- [User process model](../models/user-process.model.md)
- [Bpm user model](../models/bpm-user.model.md)
- [People content service](people-content.service.md)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 MiB

View File

@ -41,27 +41,27 @@ Edits task filter details.
### Properties
| Name | Type | Default value | Description |
| ---- | ---- | ------------- | ----------- |
| actions | `string[]` | | List of task filter actions. |
| appName | `string` | "" | (required) Name of the app. |
| environmentList | [`Environment`](../../../lib/process-services-cloud/src/lib/common/interface/environment.interface.ts)`[]` | \[] | List of environments. |
| filterProperties | `string[]` | \[] | List of task filter properties to display. |
| id | `string` | | (required) ID of the task filter. |
| processInstanceId | `string` | | processInstanceId of the task filter. |
| role | `string` | "" | user role. |
| showFilterActions | `boolean` | true | Toggles the filter actions. |
| showTaskFilterName | `boolean` | true | Toggles display of task filter name |
| showTitle | `boolean` | true | Toggles the title. |
| sortProperties | `string[]` | \[] | List of sort properties to display. |
| taskFilter | [`TaskFilterCloudModel`](../../../lib/process-services-cloud/src/lib/task/task-filters/models/filter-cloud.model.ts) | | Task Filter to use. |
| Name | Type | Default value | Description |
|--------------------|----------------------------------------------------------------------------------------------------------------------|---------------|--------------------------------------------|
| actions | `string[]` | | List of task filter actions. |
| appName | `string` | "" | (required) Name of the app. |
| environmentList | [`Environment`](../../../lib/process-services-cloud/src/lib/common/interface/environment.interface.ts)`[]` | \[] | List of environments. |
| filterProperties | `string[]` | \[] | List of task filter properties to display. |
| id | `string` | | (required) ID of the task filter. |
| processInstanceId | `string` | | processInstanceId of the task filter. |
| role | `string` | "" | user role. |
| showFilterActions | `boolean` | true | Toggles the filter actions. |
| showTaskFilterName | `boolean` | true | Toggles display of task filter name |
| showTitle | `boolean` | true | Toggles the title. |
| sortProperties | `string[]` | \[] | List of sort properties to display. |
| taskFilter | [`TaskFilterCloudModel`](../../../lib/process-services-cloud/src/lib/task/task-filters/models/filter-cloud.model.ts) | | Task Filter to use. |
### Events
| Name | Type | Description |
| ---- | ---- | ----------- |
| action | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`TaskFilterAction`](../../../lib/process-services-cloud/src/lib/task/task-filters/models/filter-cloud.model.ts)`>` | Emitted when a filter action occurs (i.e Save, Save As, Delete). |
| filterChange | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<>` | Emitted when a task filter property changes. |
| Name | Type | Description |
|--------------|----------------------------------|------------------------------------------------------------------|
| action | `EventEmitter<TaskFilterAction>` | Emitted when a filter action occurs (i.e Save, Save As, Delete). |
| filterChange | `EventEmitter<any>` | Emitted when a task filter property changes. |
## Details
@ -82,23 +82,23 @@ You can supply various _filter properties_ to edit that will determine
which tasks are found by a filter. The full set of properties is
given below:
| Name | Description |
| ---- | ----------- |
| **_appName_** | Name of the app |
| **_status_** | Execution state of the task. |
| **_assignee_** | [`User`](lib/core/src/lib/pipes/user-initial.pipe.ts) the task is assigned to |
| **_taskName_** | Name of the task |
| **_taskId_** | ID of the task |
| **_parentTaskId_** | ID of the task's parent task |
| **_priority_** | Task priority |
| **_createdDate_** | Date the task was created |
| **_standalone_** | Standalone status of the task |
| **_owner_** | [`User`](lib/core/src/lib/pipes/user-initial.pipe.ts) ID of the task's owner |
| **_processDefinitionId_** | Process definition ID |
| **_processInstanceId_** | Process instance ID |
| **_lastModified_** | Date the task was last modified. If lastModified defined the component will show the range **_lastModifiedFrom_**, **_lastModifiedTo_** |
| **_sort_** | Field on which the filter results will be sorted (doesn't participate in the filtering itself). Can be "id", "name", "createdDate", "priority", "processDefinitionId". |
| **_order_** | Sort ordering of the filter results it can be ASC or DESC (doesn't participate in the filtering itself). |
| Name | Description |
|---------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **_appName_** | Name of the app |
| **_status_** | Execution state of the task. |
| **_assignee_** | [`User`](lib/core/src/lib/pipes/user-initial.pipe.ts) the task is assigned to |
| **_taskName_** | Name of the task |
| **_taskId_** | ID of the task |
| **_parentTaskId_** | ID of the task's parent task |
| **_priority_** | Task priority |
| **_createdDate_** | Date the task was created |
| **_standalone_** | Standalone status of the task |
| **_owner_** | [`User`](lib/core/src/lib/pipes/user-initial.pipe.ts) ID of the task's owner |
| **_processDefinitionId_** | Process definition ID |
| **_processInstanceId_** | Process instance ID |
| **_lastModified_** | Date the task was last modified. If lastModified defined the component will show the range **_lastModifiedFrom_**, **_lastModifiedTo_** |
| **_sort_** | Field on which the filter results will be sorted (doesn't participate in the filtering itself). Can be "id", "name", "createdDate", "priority", "processDefinitionId". |
| **_order_** | Sort ordering of the filter results it can be ASC or DESC (doesn't participate in the filtering itself). |
By default, the **_status_**, **_assignee_**, **_sort_** and **_order_** properties
are displayed in the editor. However, you can also choose which properties
@ -107,8 +107,6 @@ the editor with the **_appName_**, **_processInstanceId_**, **_createdDate_** an
**_lastModified_** properties:
```ts
import { UserProcessModel } from '@alfresco/adf-core';
export class SomeComponent implements OnInit {
filterProperties: string[] = [
@ -124,6 +122,7 @@ export class SomeComponent implements OnInit {
onAction($event: TaskFilterAction) {
console.log('Clicked action: ', $event);
}
}
```
With this configuration, only the four listed properties will be shown.
@ -155,6 +154,7 @@ export class SomeComponent implements OnInit {
onAction($event: TaskFilterAction) {
console.log('Clicked action: ', $event);
}
}
```
```html
@ -171,11 +171,11 @@ With this configuration, only the three listed sort properties will be shown.
You can supply various _actions_ to apply on task filter.
| Name | Description |
| ---- | ----------- |
| **_save_** | Save task filter. |
| Name | Description |
|--------------|----------------------------|
| **_save_** | Save task filter. |
| **_saveAs_** | Creates a new task filter. |
| **_delete_** | Delete task filter. |
| **_delete_** | Delete task filter. |
By default, the **_save_**, **_saveAs_** and **_delete_** actions are
displayed in the editor. However, you can also choose which actions to
@ -194,6 +194,7 @@ export class SomeComponent implements OnInit {
onAction($event: TaskFilterAction) {
console.log('Clicked action: ', $event);
}
}
```
```html

View File

@ -25,7 +25,7 @@ Lists all available process filters and allows to select a filter.
| Name | Type | Default value | Description |
| ---- | ---- | ------------- | ----------- |
| appName | `string` | "" | (required) The application name |
| filterParam | [`FilterParamsModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts) | | (optional) The filter to be selected by default |
| filterParam | `UserTaskFilterRepresentation` | | (optional) The filter to be selected by default |
| showIcons | `boolean` | false | (optional) Toggles showing an icon by the side of each filter |
### Events

View File

@ -31,21 +31,21 @@ Shows all available filters.
### Properties
| Name | Type | Default value | Description |
| ---- | ---- | ------------- | ----------- |
| appName | `string` | "" | Display filters available to the current user for the application with the specified name. |
| filterParam | [`FilterParamsModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts) | | Parameters to use for the task filter cloud. If there is no match then the default filter (the first one in the list) is selected. |
| showIcons | `boolean` | false | Toggles display of the filter's icons. |
| Name | Type | Default value | Description |
|-------------|---------------------|---------------|------------------------------------------------------------------------------------------------------------------------------------|
| appName | `string` | "" | Display filters available to the current user for the application with the specified name. |
| filterParam | `FilterParamsModel` | | Parameters to use for the task filter cloud. If there is no match then the default filter (the first one in the list) is selected. |
| showIcons | `boolean` | false | Toggles display of the filter's icons. |
### Events
| Name | Type | Description |
| ---- | ---- | ----------- |
| error | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when an error occurs during loading. |
| filterClicked | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`TaskFilterCloudModel`](../../../lib/process-services-cloud/src/lib/task/task-filters/models/filter-cloud.model.ts)`>` | Emitted when a filter is being clicked from the UI. |
| filterCounterUpdated | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`TaskCloudEngineEvent`](../../../lib/process-services-cloud/src/lib/models/engine-event-cloud.model.ts)`[]>` | Emitted when filter counters are updated. |
| filterSelected | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`TaskFilterCloudModel`](../../../lib/process-services-cloud/src/lib/task/task-filters/models/filter-cloud.model.ts)`>` | Emitted when a filter is being selected based on the filterParam input. |
| success | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when the list is loaded. |
| Name | Type | Description |
|----------------------|---------------------------------------|-------------------------------------------------------------------------|
| error | `EventEmitter<any>` | Emitted when an error occurs during loading. |
| filterClicked | `EventEmitter<TaskFilterCloudModel>` | Emitted when a filter is being clicked from the UI. |
| filterCounterUpdated | `EventEmitter<TaskCloudEngineEvent>` | Emitted when filter counters are updated. |
| filterSelected | `EventEmitter`<TaskFilterCloudModel>` | Emitted when a filter is being selected based on the filterParam input. |
| success | `EventEmitter<any>` | Emitted when the list is loaded. |
## Details
@ -59,8 +59,7 @@ Use the `filterParam` property to restrict the range of filters that are shown:
</adf-cloud-task-filters>
```
You can use properties from [`FilterParamsModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)
as the value of `filterParam` as shown in the table below:
You can use properties from `FilterParamsModel` as the value of `filterParam` as shown in the table below:
| Name | Type | Description |
| ---- | ---- | ----------- |

View File

@ -37,17 +37,17 @@ You can show custom content when there are no apps available by supplying an
### Properties
| Name | Type | Default value | Description |
| ---- | ---- | ------------- | ----------- |
| filtersAppId | `any[]` | | Provides a way to filter the apps to show. |
| layoutType | `string` | | (**required**) Defines the layout of the apps. There are two possible values, "GRID" and "LIST". |
| Name | Type | Default value | Description |
|--------------|----------|---------------|--------------------------------------------------------------------------------------------------|
| filtersAppId | `any[]` | | Provides a way to filter the apps to show. |
| layoutType | `string` | | (**required**) Defines the layout of the apps. There are two possible values, "GRID" and "LIST". |
### Events
| Name | Type | Description |
| ---- | ---- | ----------- |
| appClick | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`AppDefinitionRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)`>` | Emitted when an app entry is clicked. |
| error | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when an error occurs. |
| Name | Type | Description |
|----------|---------------------------------------------|---------------------------------------|
| appClick | `EventEmitter<AppDefinitionRepresentation>` | Emitted when an app entry is clicked. |
| error | `EventEmitter<any>` | Emitted when an error occurs. |
## Details

View File

@ -5,7 +5,7 @@ Status: Active
Last reviewed: 2020-06-09
---
# [Form custom outcomes component](../../../lib/process-services/src/lib/form/form-custom-outcomes.component.ts "Defined in form-custom-outcomes.component.ts")
# Form Custom Outcomes Component
Supplies custom outcome buttons to be included in [Form component](form.component.md).

View File

@ -5,11 +5,9 @@ Status: Active
Last reviewed: 2019-01-16
---
# [Form component](../../../lib/process-services/src/lib/form/form.component.ts "Defined in form.component.ts")
# Form component
Shows a [`Form`](../../../lib/process-services/src/lib/task-list/models/form.model.ts) from APS
(See it live: [Form Quickstart](https://embed.plnkr.co/YSLXTqb3DtMhVJSqXKkE/))
Renders a Form from Alfresco Process Services.
## Contents

View File

@ -5,7 +5,7 @@ Status: Active
Last reviewed: 2019-01-14
---
# [People list component](../../../lib/process-services/src/lib/people/components/people-list/people-list.component.ts "Defined in people-list.component.ts")
# People List Component
Shows a list of users (people).
@ -16,32 +16,33 @@ Shows a list of users (people).
Populate the users in the component class:
```ts
import { UserProcessModel } from '@alfresco/adf-core';
import { LightUserRepresentation } from '@alfresco/js-api';
export class SomeComponent implements OnInit {
people: UserProcessModel[] = [
people: LightUserRepresentation[] = [
{
id: 1,
email: 'john.doe@alfresco.com',
firstName: 'John',
lastName: 'Doe'
id: 1,
email: 'john.doe@alfresco.com',
firstName: 'John',
lastName: 'Doe'
},
{
id: 2,
email: 'jane.doe@alfresco.com',
firstName: 'Jane',
lastName: 'Doe'
id: 2,
email: 'jane.doe@alfresco.com',
firstName: 'Jane',
lastName: 'Doe'
}
];
onClickPeopleRow(user: UserProcessModel) {
onClickPeopleRow(user: LightUserRepresentation) {
console.log('Clicked row: ', user);
}
onClickPeopleAction($event: Event) {
console.log('Clicked action: ', $event);
}
}
```
You can use column templates with the [people list component](people-list.component.md), since it is based on the
@ -76,14 +77,14 @@ You can use column templates with the [people list component](people-list.compon
### Properties
| Name | Type | Default value | Description |
| ---- | ---- | ------------- | ----------- |
| actions | `boolean` | false | Toggles whether or not actions should be visible, i.e. the 'Three-Dots' menu. |
| users | [`UserProcessModel`](../../core/models/user-process.model.md)`[]` | | The array of user data used to populate the people list. |
| Name | Type | Default value | Description |
|---------|-----------------------------|---------------|-------------------------------------------------------------------------------|
| actions | `boolean` | false | Toggles whether or not actions should be visible, i.e. the 'Three-Dots' menu. |
| users | `LightUserRepresentation[]` | | The array of user data used to populate the people list. |
### Events
| Name | Type | Description |
| ---- | ---- | ----------- |
| clickAction | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`UserEventModel`](../../../lib/process-services/src/lib/task-list/models/user-event.model.ts)`>` | Emitted when the user clicks in the 'Three Dots' drop down menu for a row. |
| clickRow | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`UserProcessModel`](../../core/models/user-process.model.md)`>` | Emitted when the user clicks a row in the people list. |
| Name | Type | Description |
|-------------|-----------------------------------------|----------------------------------------------------------------------------|
| clickAction | `EventEmitter<UserEventModel>` | Emitted when the user clicks in the 'Three Dots' drop down menu for a row. |
| clickRow | `EventEmitter<LightUserRepresentation>` | Emitted when the user clicks a row in the people list. |

View File

@ -5,7 +5,7 @@ Status: Active
Last reviewed: 2018-11-14
---
# [People Search component](../../../lib/process-services/src/lib/people/components/people-search/people-search.component.ts "Defined in people-search.component.ts")
# People Search Component
Searches users/people.
@ -18,10 +18,10 @@ Searches users/people.
### [Transclusions](../../user-guide/transclusion.md)
You can provide a title for the search header and a label for the action button using
special sub-components in the body of the `<adf-people-search>` element:
special subcomponents in the body of the `<adf-people-search>` element:
```html
<adf-people-search ...>
<adf-people-search>
<header-title>Custom title</header-title>
<action-button-label>Custom label</action-button-label>
</adf-people-search>
@ -31,24 +31,22 @@ special sub-components in the body of the `<adf-people-search>` element:
### Properties
| Name | Type | Default value | Description |
| ---- | ---- | ------------- | ----------- |
| results | [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`UserProcessModel`](../../core/models/user-process.model.md)`[]>` | | Parameters for displaying the list. |
| Name | Type | Default value | Description |
|---------|-----------------------------------------|---------------|-------------------------------------|
| results | `Observable<LightUserRepresentation[]>` | | Parameters for displaying the list. |
### Events
| Name | Type | Description |
| ---- | ---- | ----------- |
| closeSearch | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when the "close" button is clicked. |
| searchPeople | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when a search is performed with a new keyword. |
| success | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`UserProcessModel`](../../core/models/user-process.model.md)`>` | Emitted when a user is selected and the action button is clicked. |
| Name | Type | Description |
|--------------|-----------------------------------------|-------------------------------------------------------------------|
| closeSearch | `EventEmitter<any>` | Emitted when the "close" button is clicked. |
| searchPeople | `EventEmitter<any>` | Emitted when a search is performed with a new keyword. |
| success | `EventEmitter<LightUserRepresentation>` | Emitted when a user is selected and the action button is clicked. |
## Details
Usage example:
<!-- {% raw %} -->
```html
<adf-people-search
(searchPeople)="searchUser($event)"
@ -59,5 +57,3 @@ Usage example:
<action-button-label>{{ 'PEOPLE.ADD_USER' | translate }}</action-button-label>
</adf-people-search>
```
<!-- {% endraw %} -->

View File

@ -2,26 +2,14 @@
Title: People Component
Added: v2.0.0
Status: Active
Last reviewed: 2018-11-19
Last reviewed: 2024-05-16
---
# [People Component](../../../lib/process-services/src/lib/people/components/people/people.component.ts "Defined in people.component.ts")
# People Component
Displays users involved with a specified task
![activiti-people](../../docassets/images/activiti_people.png)
## Contents
- [Basic Usage](#basic-usage)
- [Class members](#class-members)
- [Properties](#properties)
- [Details](#details)
- [How to customize the people component behavior](#how-to-customize-the-people-component-behavior)
- [Involve People single click and close search](#involve-people-single-click-and-close-search)
- [Involve People single click without close search](#involve-people-single-click-without-close-search)
- [Involve People double click and close search](#involve-people-double-click-and-close-search)
- [Involve People double double without close search](#involve-people-double-double-without-close-search)
![people component](../../docassets/images/activiti_people.png)
## Basic Usage
@ -37,75 +25,12 @@ Displays users involved with a specified task
### Properties
| Name | Type | Default value | Description |
| ---- | ---- | ------------- | ----------- |
| people | [`UserProcessModel`](../../core/models/user-process.model.md)`[]` | \[] | The array of User objects to display. |
| readOnly | `boolean` | false | Should the data be read-only? |
| taskId | `string` | "" | The numeric ID of the task. |
| Name | Type | Default value | Description |
|----------|-----------------------------|---------------|---------------------------------------|
| people | `LightUserRepresentation[]` | \[] | The array of User objects to display. |
| readOnly | `boolean` | false | Should the data be read-only? |
| taskId | `string` | "" | The numeric ID of the task. |
### Events
- `error`: Emitted when an error occurs.
## Details
### How to customize the people component behavior
The [people component](people.component.md) provides two options to customize its behavior:
- _involveUserAndCloseSearch_: The selected user gets added and then the search section is closed
- _involveUserWithoutCloseSearch_: The selected user gets added without closing the search section
This makes it easy to customize the [people component](people.component.md) to involve the user via a single or double click event:
### Involve People single click and close search
```html
<adf-people #people
(row-click)="people.involveUserAndCloseSearch()"
[people]="YOUR_INVOLVED_PEOPLE_LIST"
[taskId]="YOUR_TASK_ID"
[readOnly]="YOUR_READ_ONLY_FLAG">
</adf-people>
```
![involve-people-single-click-and-close-search](../../docassets/images/involve-people-single-click-and-close-search.gif)
### Involve People single click without close search
```html
<adf-people #people
(row-click)="people.involveUserWithoutCloseSearch()"
[people]="YOUR_INVOLVED_PEOPLE_LIST"
[taskId]="YOUR_TASK_ID"
[readOnly]="YOUR_READ_ONLY_FLAG">
</adf-people>
```
![involve-people-single-click-without-close-search](../../docassets/images/involve-people-single-click-without-close-search.gif)
### Involve People double click and close search
```html
<adf-people #people
(row-dblclick)="people.involveUserAndCloseSearch()"
[people]="YOUR_INVOLVED_PEOPLE_LIST"
[taskId]="YOUR_TASK_ID"
[readOnly]="YOUR_READ_ONLY_FLAG">
</adf-people>
```
![involve-people-double-click-and-close-search](../../docassets/images/involve-people-double-click-and-close-search.gif)
### Involve People double double without close search
```html
<adf-people #people
(row-dblclick)="people.involveUserWithoutCloseSearch()"
[people]="YOUR_INVOLVED_PEOPLE_LIST"
[taskId]="YOUR_TASK_ID"
[readOnly]="YOUR_READ_ONLY_FLAG">
</adf-people>
```
![involve-people-double-click-without-close-search](../../docassets/images/involve-people-double-click-without-close-search.gif)

View File

@ -5,7 +5,7 @@ Status: Active
Last reviewed: 2018-09-14
---
# [Process Filters Component](../../../lib/process-services/src/lib/process-list/components/process-filters.component.ts "Defined in process-filters.component.ts")
# Process Filters Component
Collection of criteria used to filter process instances, which may be customized by users.
@ -17,14 +17,12 @@ Collection of criteria used to filter process instances, which may be customized
- [Events](#events)
- [Details](#details)
- [How filter the activiti process filters](#how-filter-the-activiti-process-filters)
- [FilterParamsModel](#filterparamsmodel)
- [See also](#see-also)
## Basic Usage
```html
<adf-process-instance-filters
appId="1001">
<adf-process-instance-filters appId="1001">
</adf-process-instance-filters>
```
@ -32,21 +30,21 @@ Collection of criteria used to filter process instances, which may be customized
### Properties
| Name | Type | Default value | Description |
| ---- | ---- | ------------- | ----------- |
| appId | `number` | | Display filters available to the current user for the application with the specified ID. |
| appName | `string` | | Display filters available to the current user for the application with the specified name. |
| filterParam | [`FilterProcessRepresentationModel`](../../../lib/process-services/src/lib/process-list/models/filter-process.model.ts) | | 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. |
| showIcon | `boolean` | true | Toggle to show or hide the filter's icon. |
| Name | Type | Default value | Description |
|-------------|-------------------------------------------------------------------------------------------------------------------------|---------------|-------------------------------------------------------------------------------------------------------------------------------------|
| appId | `number` | | Display filters available to the current user for the application with the specified ID. |
| appName | `string` | | Display filters available to the current user for the application with the specified name. |
| filterParam | [`FilterProcessRepresentationModel`](../../../lib/process-services/src/lib/process-list/models/filter-process.model.ts) | | 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. |
| showIcon | `boolean` | true | Toggle to show or hide the filter's icon. |
### Events
| Name | Type | Description |
| ---- | ---- | ----------- |
| error | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when an error occurs. |
| filterClicked | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`UserProcessInstanceFilterRepresentation`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/activiti-rest-api/docs/UserProcessInstanceFilterRepresentation.md)`>` | Emitted when a filter is being clicked from the UI. |
| filterSelected | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`UserProcessInstanceFilterRepresentation`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/activiti-rest-api/docs/UserProcessInstanceFilterRepresentation.md)`>` | Emitted when a filter is being selected based on the filterParam input. |
| success | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`ProcessInstanceFilterRepresentation`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/activiti-rest-api/docs/ProcessInstanceFilterRepresentation.md)`[]>` | Emitted when the list of filters has been successfully loaded from the server. |
| Name | Type | Description |
|----------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------|
| error | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when an error occurs. |
| filterClicked | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`UserProcessInstanceFilterRepresentation`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/activiti-rest-api/docs/UserProcessInstanceFilterRepresentation.md)`>` | Emitted when a filter is being clicked from the UI. |
| filterSelected | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`UserProcessInstanceFilterRepresentation`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/activiti-rest-api/docs/UserProcessInstanceFilterRepresentation.md)`>` | Emitted when a filter is being selected based on the filterParam input. |
| success | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`ProcessInstanceFilterRepresentation`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/activiti-rest-api/docs/ProcessInstanceFilterRepresentation.md)`[]>` | Emitted when the list of filters has been successfully loaded from the server. |
## Details
@ -58,7 +56,7 @@ process instances are displayed in the list.
If both `appId` and `appName` are specified then `appName` will take precedence and `appId` will be ignored.
### How filter the activiti process filters
### How filter the Activiti process filters
```html
<adf-process-instance-filters
@ -66,23 +64,13 @@ If both `appId` and `appName` are specified then `appName` will take precedence
</adf-process-instance-filters>
```
You can use inside the filterParam one of the properties defined by [`FilterParamsModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts) (see below).
You can use inside the filterParam one of the properties defined by `UserTaskFilterRepresentation`:
### FilterParamsModel
```json
{
"id": "number",
"name": "string",
"index": "number"
}
```
| Name | Type | Description |
| ---- | ---- | ----------- |
| id | string | The id of the task filter. |
| name | string | The name of the task filter, lowercase is checked. |
| index | number | Zero-based position of the filter in the array. |
| Name | Type | Description |
|-------|--------|----------------------------------------------------|
| id | string | The id of the task filter. |
| name | string | The name of the task filter, lowercase is checked. |
| index | number | Zero-based position of the filter in the array. |
## See also

View File

@ -22,7 +22,7 @@ Shows user information for `PROCESS` and `ALL` mode.
| Name | Type | Default value | Description |
| ---- | ---- | ------------- | ----------- |
| bpmBackgroundImage | `string` | | Custom path for the background banner image for APS users. |
| bpmUser | [`BpmUserModel`](../../core/models/bpm-user.model.md) | | BPM user info. |
| bpmUser | UserRepresentation | | BPM user info. |
| ecmBackgroundImage | `string` | | Custom path for the background banner image for ACS users. |
| ecmUser | [`EcmUserModel`](../../core/models/ecm-user.model.md) | | ECM user info. |
| isLoggedIn | `boolean` | | Determines if user is logged in. |

View File

@ -38,27 +38,27 @@ Starts a process.
### Properties
| Name | Type | Default value | Description |
| ---- | ---- | ------------- | ----------- |
| appId | `number` | | (optional) Limit the list of processes that can be started to those contained in the specified app. |
| name | `string` | "" | (optional) Name to assign to the current process. |
| processDefinitionName | `string` | | (optional) Definition name of the process to start. |
| processFilterSelector | `boolean` | true | (optional) Parameter to enable selection of process when filtering. |
| showSelectApplicationDropdown | `boolean` | false | (optional) Hide or show application selection dropdown. |
| showSelectProcessDropdown | `boolean` | true | Hide or show the process selection dropdown. |
| title | `string` | | (optional) Define the header of the component. |
| values | [`FormValues`](../../../lib/core/src/lib/form/components/widgets/core/form-values.ts) | | Parameter to pass form field values in the start form if one is associated. |
| variables | [`ProcessInstanceVariable`](../../../lib/process-services/src/lib/process-list/models/process-instance-variable.model.ts)`[]` | | Variables in the input to the process [`RestVariable`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/activiti-rest-api/docs/RestVariable.md). |
| Name | Type | Default value | Description |
|-------------------------------|------------------|---------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| appId | `number` | | (optional) Limit the list of processes that can be started to those contained in the specified app. |
| name | `string` | "" | (optional) Name to assign to the current process. |
| processDefinitionName | `string` | | (optional) Definition name of the process to start. |
| processFilterSelector | `boolean` | true | (optional) Parameter to enable selection of process when filtering. |
| showSelectApplicationDropdown | `boolean` | false | (optional) Hide or show application selection dropdown. |
| showSelectProcessDropdown | `boolean` | true | Hide or show the process selection dropdown. |
| title | `string` | | (optional) Define the header of the component. |
| values | `FormValues` | | Parameter to pass form field values in the start form if one is associated. |
| variables | `RestVariable[]` | | Variables in the input to the process [`RestVariable`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/activiti-rest-api/docs/RestVariable.md). |
### Events
| Name | Type | Description |
| ---- | ---- | ----------- |
| applicationSelection | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`AppDefinitionRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)`>` | Emitted when application selection changes. |
| cancel | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<void>` | Emitted when the process is canceled. |
| error | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when an error occurs. |
| processDefinitionSelection | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`ProcessDefinitionRepresentation`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/activiti-rest-api/docs/ProcessDefinitionRepresentation.md)`>` | Emitted when process definition selection changes. |
| start | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`ProcessInstance`](../../../lib/process-services/src/lib/process-list/models/process-instance.model.ts)`>` | Emitted when the process starts. |
| Name | Type | Description |
|----------------------------|-------------------------------------------------|----------------------------------------------------|
| applicationSelection | `EventEmitterAppDefinitionRepresentation>` | Emitted when application selection changes. |
| cancel | `EventEmitter<void>` | Emitted when the process is canceled. |
| error | `EventEmitter<any>` | Emitted when an error occurs. |
| processDefinitionSelection | `EventEmitter<ProcessDefinitionRepresentation>` | Emitted when process definition selection changes. |
| start | `EventEmitter<ProcessInstance>` | Emitted when the process starts. |
## Details
@ -123,8 +123,8 @@ to _alfresco-1002_ as follows:
"application": {
"name": "Alfresco ADF Application"
},
"ecmHost": "http://{hostname}{:port}/ecm",
"bpmHost": "http://{hostname}{:port}/bpm",
"ecmHost": "https://{hostname}{:port}/ecm",
"bpmHost": "https://{hostname}{:port}/bpm",
"logLevel": "silent",
"alfrescoRepositoryName": "alfresco-1002"
}
@ -135,10 +135,10 @@ You then need to pass the node as the input `values` object with the other prope
```ts
let node: Node = null;
this.nodesApiService.getNode(NODE_ID).subscribe((res) => this.node = res);
this.nodesApiService.getNode(NODE_ID).subscribe((res) => this.node = res);
const formValues: FormValues = {
'file' : node
'file' : node,
'field_one': 'example text'
};
```
@ -149,20 +149,19 @@ You could pass multiple nodes too:
const nodes: string[] = [NODE_ID_1, NODE_ID_2];
const values: FormValues = {
'files': []
};
'files': []
};
Observable.from(nodes)
.flatMap((nodeId) => this.nodesApiService.getNode(nodeId))
.subscribe(
(node) => {
values.files.push(node);
},
(error) => console.log(error) ,
() => {
this.formValues = values;
});
});
Observable.from(nodes)
.flatMap((nodeId) => this.nodesApiService.getNode(nodeId))
.subscribe(
(node) => {
values.files.push(node);
},
(error) => console.log(error),
() => {
this.formValues = values;
});
```
Note that in the object above, the key `file` is the name of the attach file field in the start form of the process. The value of the `file` property must be a
@ -211,9 +210,11 @@ When an error occurs, the component will emit an error event that can be used to
```
```ts
class StartProcessComponent {
onError(error) {
this.notificationService.showError(event.response.body.message);
}
}
```
## See also

View File

@ -23,17 +23,17 @@ Shows all available filters.
| ---- | ---- | ------------- | ----------- |
| appId | `number` | | Display filters available to the current user for the application with the specified ID. |
| appName | `string` | | Display filters available to the current user for the application with the specified name. |
| filterParam | [`FilterParamsModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts) | | Parameters to use for the task filter. If there is no match then the default filter (the first one the list) is selected. |
| filterParam | `UserTaskFilterRepresentation` | | Parameters to use for the task filter. If there is no match then the default filter (the first one the list) is selected. |
| showIcon | `boolean` | | Toggles display of the filter's icon. |
### Events
| Name | Type | Description |
| ---- | ---- | ----------- |
| error | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when an error occurs during loading. |
| filterClicked | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)`>` | Emitted when a filter is being clicked from the UI. |
| filterSelected | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<`[`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)`>` | Emitted when a filter is being selected based on the filterParam input. |
| success | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when the list is loaded. |
| Name | Type | Description |
| ---- |-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| ----------- |
| error | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when an error occurs during loading. |
| filterClicked | `EventEmitter<UserTaskFilterRepresentation>` | Emitted when a filter is being clicked from the UI. |
| filterSelected | `EventEmitter<UserTaskFilterRepresentation>` | Emitted when a filter is being selected based on the filterParam input. |
| success | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<any>` | Emitted when the list is loaded. |
## Details
@ -42,16 +42,14 @@ Shows all available filters.
Use the `filterParam` property to restrict the range of filters that are shown:
```html
<adf-task-filters
[filterParam]="{name:'My tasks'}">
<adf-task-filters [filterParam]="{name:'My tasks'}">
</adf-task-filters>
```
You can use properties from [`FilterParamsModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)
as the value of `filterParam` as shown in the table below:
You can use properties from `UserTaskFilterRepresentation` as the value of `filterParam` as shown in the table below:
| Name | Type | Description |
| ---- | ---- | ----------- |
| id | string | The id of the task filter |
| name | string | The name of the task filter, lowercase is checked |
| Name | Type | Description |
|-------|--------|-----------------------------------------------------|
| id | string | The id of the task filter |
| name | string | The name of the task filter, lowercase is checked |
| index | string | The zero-based position of the filter in the array. |

View File

@ -13,29 +13,29 @@ Manages process instances, process variables, and process audit Log.
### Methods
- **cancelProcess**(processInstanceId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<void>`<br/>
- **cancelProcess**(processInstanceId: `string`): `Observable<void>`<br/>
Cancels a process instance.
- _processInstanceId:_ `string` - ID of process to cancel
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<void>` - Null response notifying when the operation is complete
- **createOrUpdateProcessInstanceVariables**(processInstanceId: `string`, variables: [`RestVariable`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/activiti-rest-api/docs/RestVariable.md)`[]`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`ProcessInstanceVariable`](../../../lib/process-services/src/lib/process-list/models/process-instance-variable.model.ts)`[]>`<br/>
- **Returns** `Observable<void>` - Null response notifying when the operation is complete
- **createOrUpdateProcessInstanceVariables**(processInstanceId: `string`, variables: `RestVariable`[]`): `Observable<RestVariable[]>`<br/>
Creates or updates variables for a process instance.
- _processInstanceId:_ `string` - ID of the target process
- _variables:_ [`RestVariable`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/activiti-rest-api/docs/RestVariable.md)`[]` - Variables to update
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`ProcessInstanceVariable`](../../../lib/process-services/src/lib/process-list/models/process-instance-variable.model.ts)`[]>` - Array of instance variable info
- **deleteProcessInstanceVariable**(processInstanceId: `string`, variableName: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<void>`<br/>
- _variables:_ `RestVariable[]` - Variables to update
- **Returns** `Observable<ProcessInstanceVariable[]>` - Array of instance variable info
- **deleteProcessInstanceVariable**(processInstanceId: `string`, variableName: `string`): `Observable<void>`<br/>
Deletes a variable for a process instance.
- _processInstanceId:_ `string` - ID of the target process
- _variableName:_ `string` - Name of the variable to delete
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<void>` - Null response notifying when the operation is complete
- **fetchProcessAuditJsonById**(processId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<any>`<br/>
- **Returns** `Observable<void>` - Null response notifying when the operation is complete
- **fetchProcessAuditJsonById**(processId: `string`): `Observable<any>`<br/>
Fetches the Process Audit information in a JSON format.
- _processId:_ `string` - ID of the target process
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<any>` - JSON data
- **Returns** `Observable<any>` - JSON data
- **fetchProcessAuditPdfById**(processId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob)`>`<br/>
Fetches the Process Audit information as a PDF.
- _processId:_ `string` - ID of the target process
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob)`>` - Binary PDF data
- **getProcess**(processInstanceId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`ProcessInstance`](../../../lib/process-services/src/lib/process-list/models/process-instance.model.ts)`>`<br/>
- **Returns** `Observable<Blob>` - Binary PDF data
- **getProcess**(processInstanceId: `string`): `Observable<ProcessInstance>`<br/>
Gets Process Instance metadata.
- _processInstanceId:_ `string` - ID of the target process
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`ProcessInstance`](../../../lib/process-services/src/lib/process-list/models/process-instance.model.ts)`>` - Metadata for the instance
@ -43,10 +43,10 @@ Manages process instances, process variables, and process audit Log.
Gets process definitions associated with an app.
- _appId:_ `number` - (Optional) ID of a target app
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`ProcessDefinitionRepresentation`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/activiti-rest-api/docs/ProcessDefinitionRepresentation.md)`[]>` - Array of process definitions
- **getProcessInstanceVariables**(processInstanceId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`ProcessInstanceVariable`](../../../lib/process-services/src/lib/process-list/models/process-instance-variable.model.ts)`[]>`<br/>
- **getProcessInstanceVariables**(processInstanceId: `string`): `ObservableRestVariable[]>`<br/>
Gets the variables for a process instance.
- _processInstanceId:_ `string` - ID of the target process
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`ProcessInstanceVariable`](../../../lib/process-services/src/lib/process-list/models/process-instance-variable.model.ts)`[]>` - Array of instance variable info
- **Returns** `ObservableRestVariable[]>` - Array of instance variable info
- **getProcessInstances**(requestNode: [`ProcessFilterParamRepresentationModel`](../../../lib/process-services/src/lib/process-list/models/filter-process.model.ts), processDefinitionKey?: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`ProcessListModel`](../../../lib/process-services/src/lib/process-list/models/process-list.model.ts)`>`<br/>
Gets process instances for a filter and optionally a process definition.
- _requestNode:_ [`ProcessFilterParamRepresentationModel`](../../../lib/process-services/src/lib/process-list/models/filter-process.model.ts) - Filter for instances
@ -70,14 +70,14 @@ Manages process instances, process variables, and process audit Log.
Gets the start form instance for a given process.
- _processId:_ `string` - Process definition ID
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<any>` - Form definition
- **startProcess**(processDefinitionId: `string`, name: `string`, outcome?: `string`, startFormValues?: [`FormValues`](../../../lib/core/src/lib/form/components/widgets/core/form-values.ts), variables?: [`ProcessInstanceVariable`](../../../lib/process-services/src/lib/process-list/models/process-instance-variable.model.ts)`[]`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`ProcessInstance`](../../../lib/process-services/src/lib/process-list/models/process-instance.model.ts)`>`<br/>
- **startProcess**(processDefinitionId: `string`, name: `string`, outcome?: `string`, startFormValues?: `FormValues`, variables?: `RestVariable[]`): `Observable<ProcessInstance>`<br/>
Starts a process based on a process definition, name, form values or variables.
- _processDefinitionId:_ `string` - Process definition ID
- _name:_ `string` - Process name
- _outcome:_ `string` - (Optional) Process outcome
- _startFormValues:_ [`FormValues`](../../../lib/core/src/lib/form/components/widgets/core/form-values.ts) - (Optional) Values for the start form
- _variables:_ [`ProcessInstanceVariable`](../../../lib/process-services/src/lib/process-list/models/process-instance-variable.model.ts)`[]` - (Optional) Array of process instance variables
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`ProcessInstance`](../../../lib/process-services/src/lib/process-list/models/process-instance.model.ts)`>` - Details of the process instance just started
- _variables:_ `RestVariable[]` - (Optional) Array of process instance variables
- **Returns** `Observable<ProcessInstance>` - Details of the process instance just started
- **toJson**(res: `any`): `any`<br/>
Creates a JSON representation of form data.
- _res:_ `any` - Object representing form data

View File

@ -13,69 +13,74 @@ Manage Task Filters, which are pre-configured Task Instance queries.
### Methods
- **addFilter**(filter: [`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)`>`<br/>
- **addFilter**(filter: `UserTaskFilterRepresentation`): `Observable<UserTaskFilterRepresentation>`<br/>
Adds a new task filter
- _filter:_ [`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts) - The new filter to add
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)`>` - Details of task filter just added
- _filter:_ `UserTaskFilterRepresentation` - The new filter to add
- **Returns** `Observable<UserTaskFilterRepresentation>` - Details of task filter just added
- **callApiTaskFilters**(appId?: `number`): [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises)`<any>`<br/>
Calls `getUserTaskFilters` from the Alfresco JS API.
- _appId:_ `number` - (Optional) ID of the target app
- **Returns** [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises)`<any>` - List of task filters
- **createDefaultFilters**(appId: `number`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)`[]>`<br/>
- **createDefaultFilters**(appId: `number`): `Observable<UserTaskFilterRepresentation>[]>`<br/>
Creates and returns the default filters for a process app.
- _appId:_ `number` - ID of the target app
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)`[]>` - Array of default filters just created
- **getCompletedTasksFilterInstance**(appId: `number`, index?: `number`): [`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)<br/>
- **Returns** `Observable<UserTaskFilterRepresentation>[]>` - Array of default filters just created
- **getCompletedTasksFilterInstance**(appId: `number`, index?: `number`): `UserTaskFilterRepresentation`<br/>
Creates and returns a filter for "Completed" task instances.
- _appId:_ `number` - ID of the target app
- _index:_ `number` - (Optional) of the filter (optional)
- **Returns** [`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts) - The newly created filter
- **getInvolvedTasksFilterInstance**(appId: `number`, index?: `number`): [`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)<br/>
- **Returns** `UserTaskFilterRepresentation` - The newly created filter
- **getInvolvedTasksFilterInstance**(appId: `number`, index?: `number`): `UserTaskFilterRepresentation`<br/>
Creates and returns a filter for "Involved" task instances.
- _appId:_ `number` - ID of the target app
- _index:_ `number` - (Optional) of the filter (optional)
- **Returns** [`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts) - The newly created filter
- **getMyTasksFilterInstance**(appId: `number`, index?: `number`): [`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)<br/>
- **Returns** `UserTaskFilterRepresentation` - The newly created filter
- **getMyTasksFilterInstance**(appId: `number`, index?: `number`): `UserTaskFilterRepresentation`<br/>
Creates and returns a filter for "My Tasks" task instances.
- _appId:_ `number` - ID of the target app
- _index:_ `number` - (Optional) of the filter (optional)
- **Returns** [`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts) - The newly created filter
- **getQueuedTasksFilterInstance**(appId: `number`, index?: `number`): [`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)<br/>
- **Returns** `UserTaskFilterRepresentation` - The newly created filter
- **getQueuedTasksFilterInstance**(appId: `number`, index?: `number`): `UserTaskFilterRepresentation`<br/>
Creates and returns a filter for "Queued Tasks" task instances.
- _appId:_ `number` - ID of the target app
- _index:_ `number` - (Optional) of the filter (optional)
- **Returns** [`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts) - The newly created filter
- **getTaskFilterById**(filterId: `number`, appId?: `number`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)`>`<br/>
- **Returns** `UserTaskFilterRepresentation` - The newly created filter
- **getTaskFilterById**(filterId: `number`, appId?: `number`): `Observable<UserTaskFilterRepresentation>`<br/>
Gets a task filter by ID.
- _filterId:_ `number` - ID of the filter
- _appId:_ `number` - (Optional) ID of the app for the filter
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)`>` - Details of task filter
- **getTaskFilterByName**(taskName: `string`, appId?: `number`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)`>`<br/>
- **Returns** `Observable<UserTaskFilterRepresentation>` - Details of task filter
- **getTaskFilterByName**(taskName: `string`, appId?: `number`): `Observable<UserTaskFilterRepresentation>`<br/>
Gets a task filter by name.
- _taskName:_ `string` - Name of the filter
- _appId:_ `number` - (Optional) ID of the app for the filter
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)`>` - Details of task filter
- **getTaskListFilters**(appId?: `number`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)`[]>`<br/>
- **Returns** `ObservableUserTaskFilterRepresentation>` - Details of task filter
- **getTaskListFilters**(appId?: `number`): `UserTaskFilterRepresentation[]>`<br/>
Gets all task filters for a process app.
- _appId:_ `number` - (Optional) Optional ID for a specific app
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)`[]>` - Array of task filter details
- **Returns** `Observable<UserTaskFilterRepresentation[]>` - Array of task filter details
## Details
The methods of this service generally return an instance of [`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts) or
The methods of this service generally return an instance of `UserTaskFilterRepresentation` or
an array of instances. For example, you could use `getTaskListFilters` as follows:
```ts
const processAppId = 2;
this.taskFilterService.getTaskListFilters(processAppId).subscribe( (filters: FilterRepresentationModel[]) => {
console.log('Task filters: ', filters);
}, error => {
console.log('Error: ', error);
});
this.taskFilterService.getTaskListFilters(processAppId).subscribe(
(filters: UserTaskFilterRepresentation[]) => {
console.log('Task filters: ', filters);
},
(error) => {
console.log('Error: ', error);
}
);
```
The response is an array of [`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts) objects:
The response is an array of `UserTaskFilterRepresentation` objects:
```text
filters:
0: {id: 10, appId: 2, name: "Involved Tasks", recent: true, icon: "glyphicon-align-left", …}
1: {id: 9, appId: 2, name: "My Tasks", recent: false, icon: "glyphicon-inbox", …}
@ -85,6 +90,7 @@ The response is an array of [`FilterRepresentationModel`](../../../lib/process-s
5: {id: 4005, appId: 2, name: "My Tasks", recent: false, icon: "glyphicon-inbox", …}
6: {id: 4006, appId: 2, name: "Queued Tasks", recent: false, icon: "glyphicon-record", …}
7: {id: 4007, appId: 2, name: "Involved Tasks", recent: false, icon: "glyphicon-align-left", …}
```
These filters can now be used to get matching task instances for the process app with ID 2,
such as 'Involved Tasks', 'My Tasks', 'Queued Tasks', and 'Completed Tasks'.
@ -92,12 +98,12 @@ such as 'Involved Tasks', 'My Tasks', 'Queued Tasks', and 'Completed Tasks'.
### Importing
```ts
import { TaskFilterService, FilterRepresentationModel } from '@alfresco/adf-process-services';
import { TaskFilterService } from '@alfresco/adf-process-services';
export class SomePageComponent implements OnInit {
constructor(private taskFilterService: TaskFilterService) {
}
constructor(private taskFilterService: TaskFilterService) {
}
}
```
## See also

View File

@ -5,10 +5,14 @@ Status: Active
Last reviewed: 2018-11-14
---
# [Tasklist Service](../../../lib/process-services/src/lib/task-list/services/tasklist.service.ts "Defined in tasklist.service.ts")
# TaskList Service
Manages Task Instances.
```ts
import { TaskListService } from '@alfresco/adf-process-services';
```
## Class members
### Methods
@ -60,22 +64,17 @@ Manages Task Instances.
Fetches the Task Audit information in PDF format.
- _taskId:_ `string` - ID of the target task
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob)`>` - Binary PDF data
- **findAllTasksByState**(requestNode: [`TaskQueryRequestRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts), state?: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskListModel`](../../../lib/process-services/src/lib/task-list/models/task-list.model.ts)`>`<br/>
Gets all tasks matching a query and state value.
- _requestNode:_ [`TaskQueryRequestRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts) - Query to search for tasks.
- _state:_ `string` - (Optional) Task state. Can be "open" or "completed". State "all" applies to both "active" and "completed" tasks.
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskListModel`](../../../lib/process-services/src/lib/task-list/models/task-list.model.ts)`>` - List of tasks
- **findTasksByState**(requestNode: [`TaskQueryRequestRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts), state?: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskListModel`](../../../lib/process-services/src/lib/task-list/models/task-list.model.ts)`>`<br/>
- **findTasksByState**(requestNode: `TaskQueryRequestRepresentationModel`, state?: `string`): `Observable<ResultListDataRepresentationTaskRepresentation>`<br/>
Gets tasks matching a query and state value.
- _requestNode:_ [`TaskQueryRequestRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts) - Query to search for tasks
- _requestNode:_ `TaskQueryRequestRepresentationModel` - Query to search for tasks
- _state:_ `string` - (Optional) Task state. Can be "open" or "completed". State "all" applies to both "active" and "completed" tasks.
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskListModel`](../../../lib/process-services/src/lib/task-list/models/task-list.model.ts)`>` - List of tasks
- **getFilterForTaskById**(taskId: `string`, filterList: [`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)`[]`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)`>`<br/>
- **Returns** `Observable<ResultListDataRepresentationTaskRepresentation>` - List of tasks
- **getFilterForTaskById**(taskId: `string`, filterList: `UserTaskFilterRepresentation[]`): `Observable<UserTaskFilterRepresentation>`<br/>
Gets all the filters in the list that belong to a task.
- _taskId:_ `string` - ID of the target task
- _filterList:_ [`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)`[]` - List of filters to search through
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)`>` - Filters belonging to the task
- **getFormList**(): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`Form`](../../../lib/process-services/src/lib/task-list/models/form.model.ts)`[]>`<br/>
- _filterList:_ `UserTaskFilterRepresentation[]` - List of filters to search through
- **Returns** `Observable<UserTaskFilterRepresentation>` - Filters belonging to the task
- **getFormList**(): `Observable<Form[]>`<br/>
Gets all available reusable forms.
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`Form`](../../../lib/process-services/src/lib/task-list/models/form.model.ts)`[]>` - Array of form details
- **getTaskChecklist**(id: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsModel`](../../../lib/process-services/src/lib/task-list/models/task-details.model.ts)`[]>`<br/>
@ -85,21 +84,21 @@ Manages Task Instances.
- **getTaskDetails**(taskId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsModel`](../../../lib/process-services/src/lib/task-list/models/task-details.model.ts)`>`<br/>
Gets details for a task.
- _taskId:_ `string` - ID of the target task.
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsModel`](../../../lib/process-services/src/lib/task-list/models/task-details.model.ts)`>` - Task details
- **getTasks**(requestNode: [`TaskQueryRequestRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskListModel`](../../../lib/process-services/src/lib/task-list/models/task-list.model.ts)`>`<br/>
- **Returns** `Observable<TaskDetailsModel>` - Task details
- **getTasks**(requestNode: `TaskQueryRequestRepresentationModel`): `Observable<ResultListDataRepresentationTaskRepresentation>`<br/>
Gets all the tasks matching the supplied query.
- _requestNode:_ [`TaskQueryRequestRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts) - Query to search for tasks
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskListModel`](../../../lib/process-services/src/lib/task-list/models/task-list.model.ts)`>` - List of tasks
- **getTotalTasks**(requestNode: [`TaskQueryRequestRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)): [`Observable`](http://reactivex.io/documentation/observable.html)`<any>`<br/>
- _requestNode:_ `TaskQueryRequestRepresentationModel` - Query to search for tasks
- **Returns** `Observable<ResultListDataRepresentationTaskRepresentation>` - List of tasks
- **getTotalTasks**(requestNode: `TaskQueryRequestRepresentationModel`): [`Observable`](http://reactivex.io/documentation/observable.html)`<any>`<br/>
Gets the total number of the tasks found by a query.
- _requestNode:_ [`TaskQueryRequestRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts) - Query to search for tasks
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<any>` - Number of tasks
- **isTaskRelatedToFilter**(taskId: `string`, filterModel: [`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)`>`<br/>
- _requestNode:_ `TaskQueryRequestRepresentationModel` - Query to search for tasks
- **Returns** `Observable<any>` - Number of tasks
- **isTaskRelatedToFilter**(taskId: `string`, filterModel: `UserTaskFilterRepresentation`): `Observable<UserTaskFilterRepresentation`>`<br/>
Checks if a taskId is filtered with the given filter.
- _taskId:_ `string` - ID of the target task
- _filterModel:_ [`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts) - The filter you want to check
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`FilterRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts)`>` - The filter if it is related or null otherwise
- **unclaimTask**(taskId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsModel`](../../../lib/process-services/src/lib/task-list/models/task-details.model.ts)`>`<br/>
- _filterModel:_ `UserTaskFilterRepresentation` - The filter you want to check
- **Returns** `Observable<UserTaskFilterRepresentation>` - The filter if it is related or null otherwise
- **unclaimTask**(taskId: `string`): `Observable<TaskDetailsModel>`<br/>
Un-claims a task for the current user.
- _taskId:_ `string` - ID of the task to unclaim
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TaskDetailsModel`](../../../lib/process-services/src/lib/task-list/models/task-details.model.ts)`>` - Null response notifying when the operation is complete
@ -128,8 +127,9 @@ this.tasklistService.getTaskDetails(taskInstanceId).subscribe( (taskInstance: Ta
The resulting [`TaskDetailsModel`](../../../lib/process-services/src/lib/task-list/models/task-details.model.ts) object contains information like the following:
```text
adhocTaskCanBeReassigned: false
assignee: UserProcessModel {pictureId: null, id: 1, email: "admin@app.activiti.com", firstName: null, lastName: "Administrator"}
assignee: LightUserRepresentation {pictureId: null, id: 1, email: "admin@app.activiti.com", firstName: null, lastName: "Administrator"}
category: null
created: Wed Oct 11 2017 09:07:14 GMT+0100 (BST) {}
description: null
@ -159,10 +159,11 @@ The resulting [`TaskDetailsModel`](../../../lib/process-services/src/lib/task-li
processInstanceName: null
processInstanceStartUserId: "1"
taskDefinitionKey: "clarifyInvoice"
```
### Queries
Some of the methods run a search query contained in a [`TaskQueryRequestRepresentationModel`](../../../lib/process-services/src/lib/task-list/models/filter.model.ts) and
Some of the methods run a search query contained in a `TaskQueryRequestRepresentationModel` and
return the matched tasks. Below is an example of how you might run a query using `getTasks`:
```ts
@ -178,7 +179,8 @@ const taskQuery: TaskQueryRequestRepresentationModel = {
size: 5,
start: null
};
this.tasklistService.getTasks(taskQuery).subscribe( (taskListModel: TaskListModel) => {
this.tasklistService.getTasks(taskQuery).subscribe((taskListModel) => {
console.log('Task List Model: ', taskListModel);
}, error => {
console.log('Error: ', error);
@ -201,9 +203,9 @@ The `assignment` property filters tasks based on how they are assigned (or not a
Use `assignee` if you are interested in tasks that are assigned to a user. If you want to see
pooled tasks (i.e. tasks that needs to be claimed by a user), then use `candidate`.
A successful query returns a [`TaskListModel`](../../../lib/process-services/src/lib/task-list/models/task-list.model.ts) with the `data` property set to an array of
[`TaskDetailsModel`](../../../lib/process-services/src/lib/task-list/models/task-details.model.ts):
A successful query returns a `ResultListDataRepresentationTaskRepresentation` with the `data` property set to an array of `TaskRepresentation` objects. For example:
```text
data:
0: {id: "75010", name: "Approve Invoice - Invoice-10202.pdf", description: null, category: null, assignee: {…}, …}
1: {id: "74746", name: "Verify with the person that did the purchase", description: null, category: "2", assignee: {…}, …}
@ -214,18 +216,7 @@ A successful query returns a [`TaskListModel`](../../../lib/process-services/src
size: 5
start: 0
total: 10
```
The `total` property indicates that actual number of tasks that were found, but the `size` property
limited the found set to five items.
### Importing
```ts
import { TaskListService, TaskDetailsModel, TaskQueryRequestRepresentationModel, TaskListModel, Form } from '@alfresco/adf-process-services';
import { TaskUpdateRepresentation } from '@alfresco/js-api';
export class SomePageComponent implements OnInit {
constructor(private tasklistService: TaskListService) {
}
```

View File

@ -520,7 +520,6 @@ backend services have been tested with each released version of ADF.
- [Auth guard ecm service](core/services/auth-guard-ecm.service.md)
- [Auth guard service](core/services/auth-guard.service.md)
- [Authentication service](core/services/authentication.service.md)
- [Bpm user model](core/models/bpm-user.model.md)
- [Bpm user service](core/services/bpm-user.service.md)
- [Breadcrumb component](content-services/components/breadcrumb.component.md)
- [Card item types service](core/services/card-item-types.service.md)
@ -652,7 +651,6 @@ backend services have been tested with each released version of ADF.
- [Upload service](core/services/upload.service.md)
- [User initial pipe](core/pipes/user-initial.pipe.md)
- [User preferences service](core/services/user-preferences.service.md)
- [User process model](core/models/user-process.model.md)
- [Version list component](content-services/components/version-list.component.md)
- [Version manager component](content-services/components/version-manager.component.md)
- [Viewer component](core/components/viewer.component.md)

View File

@ -16,10 +16,9 @@
*/
import { BrowserActions, BrowserVisibility, DataTableComponentPage, DropdownPage, materialLocators } from '@alfresco/adf-testing';
import { $, by, element, protractor } from 'protractor';
import { $, by, element } from 'protractor';
export class ProcessListDemoPage {
appIdInput = $('input[data-automation-id="app-id"]');
resetButton = element(by.cssContainingText('button span', 'Reset'));
emptyProcessContent = $('.adf-empty-content');
@ -43,11 +42,8 @@ export class ProcessListDemoPage {
await this.stateDropdown.selectDropdownOption(stateOption);
}
async addAppId(appId: string | number): Promise<void> {
await BrowserActions.click(this.appIdInput);
await this.appIdInput.sendKeys(protractor.Key.ENTER);
await this.appIdInput.clear();
await this.appIdInput.sendKeys(appId);
async addAppId(appId: string): Promise<void> {
await BrowserActions.clearSendKeys(this.appIdInput, appId);
}
async clickResetButton(): Promise<void> {

View File

@ -20,22 +20,21 @@ import { $ } from 'protractor';
import { TasksListPage } from './tasks-list.page';
export class TaskListDemoPage {
taskListPage = new TasksListPage();
appId = $('input[data-automation-id=\'appId input\']');
itemsPerPage = $('input[data-automation-id=\'items per page\']');
itemsPerPageForm = $(`${materialLocators.Form.field.root}[data-automation-id=\'items per page\']`);
processDefinitionId = $('input[data-automation-id=\'process definition id\']');
processInstanceId = $('input[data-automation-id=\'process instance id\']');
page = $('input[data-automation-id=\'page\']');
pageForm = $(`${materialLocators.Form.field.root}[data-automation-id=\'page\']`);
taskName = $('input[data-automation-id=\'task name\']');
appId = $(`input[data-automation-id='appId input']`);
itemsPerPage = $(`input[data-automation-id='items per page']`);
itemsPerPageForm = $(`${materialLocators.Form.field.root}[data-automation-id='items per page']`);
processDefinitionId = $(`input[data-automation-id='process definition id']`);
processInstanceId = $(`input[data-automation-id='process instance id']`);
page = $(`input[data-automation-id='page']`);
pageForm = $(`${materialLocators.Form.field.root}[data-automation-id='page']`);
taskName = $(`input[data-automation-id='task name']`);
resetButton = $('.app-reset-button button');
dueBefore = $('input[data-automation-id=\'due before\']');
dueAfter = $('input[data-automation-id=\'due after\']');
taskId = $('input[data-automation-id=\'task id\']');
dueBefore = $(`input[data-automation-id='due before']`);
dueAfter = $(`input[data-automation-id='due after']`);
taskId = $(`input[data-automation-id='task id']`);
stateDropDownArrow = $(`${materialLocators.Form.field.root}[data-automation-id=\'state\']`);
stateDropDownArrow = $(`${materialLocators.Form.field.root}[data-automation-id='state']`);
stateDropdown = new DropdownPage(this.stateDropDownArrow);
taskList(): TasksListPage {
@ -131,5 +130,4 @@ export class TaskListDemoPage {
getAllProcessInstanceIds(): Promise<any> {
return this.taskList().getDataTable().getAllRowsColumnValues('Process Instance Id');
}
}

View File

@ -60,7 +60,7 @@ describe('Process List Test', () => {
insertAppId: 'Insert App ID'
};
let appWithDateFieldId: string | number;
let appWithDateFieldId: string;
let procWithDate: ProcessInstanceRepresentation;
let completedProcWithDate: ProcessInstanceRepresentation;
let completedProcWithUserWidget: ProcessInstanceRepresentation;
@ -83,7 +83,7 @@ describe('Process List Test', () => {
await processUtil.startProcessOfApp(appUserWidgetModel.name, processName.procWithUserWidget);
completedProcWithUserWidget = await processUtil.startProcessOfApp(appUserWidgetModel.name, processName.completedProcWithUserWidget);
appWithDateFieldId = await applicationsUtil.getAppDefinitionId(appDateModel.id);
appWithDateFieldId = (await applicationsUtil.getAppDefinitionId(appDateModel.id)).toString();
const procWithDateTaskId = await processUtil.getProcessTaskId(completedProcWithDate.id);

View File

@ -36,5 +36,12 @@
"C309878": "https://alfresco.atlassian.net/browse/AAE-21222",
"C601606": "https://alfresco.atlassian.net/browse/AAE-21222",
"C311295": "https://alfresco.atlassian.net/browse/AAE-21222",
"C315292": "https://alfresco.atlassian.net/browse/AAE-21222"
"C315292": "https://alfresco.atlassian.net/browse/AAE-21222",
"C280569": "https://hyland.atlassian.net/browse/ACS-7960",
"C282006": "https://hyland.atlassian.net/browse/ACS-7960",
"C282015": "https://hyland.atlassian.net/browse/ACS-7960",
"C282016": "https://hyland.atlassian.net/browse/ACS-7960",
"C282017": "https://hyland.atlassian.net/browse/ACS-7960",
"C282010": "https://hyland.atlassian.net/browse/ACS-7960",
"C261046": "https://hyland.atlassian.net/browse/ACS-7960"
}

View File

@ -6,7 +6,7 @@
<div *ngIf="!comment.hasAvatarPicture" class="adf-comment-user-icon">{{ comment.userInitials }}</div>
<img *ngIf="comment.hasAvatarPicture" class="adf-people-img"
[alt]="'COMMENTS.PROFILE_IMAGE' | translate"
[src]="getUserImage(comment.createdBy)" />
[src]="getUserImage(comment.createdBy.id.toString())" />
</div>
<div class="adf-comment-contents">
<div matLine class="adf-comment-user-name">{{ comment.userDisplayName }}</div>

View File

@ -17,7 +17,6 @@
import { Component, EventEmitter, Input, Output, ViewEncapsulation, inject } from '@angular/core';
import { CommentModel } from '../../models/comment.model';
import { User } from '../../models/general-user.model';
import { CommentsService } from '../interfaces/comments-service.interface';
import { ADF_COMMENTS_SERVICE } from '../interfaces/comments.token';
@ -28,7 +27,6 @@ import { ADF_COMMENTS_SERVICE } from '../interfaces/comments.token';
encapsulation: ViewEncapsulation.None
})
export class CommentListComponent {
/** The comments data used to populate the list. */
@Input()
comments: CommentModel[];
@ -43,7 +41,7 @@ export class CommentListComponent {
this.clickRow.emit(comment);
}
getUserImage(user: User): string {
return this.commentsService.getUserImage(user);
getUserImage(userId: string): string {
return this.commentsService.getUserImage(userId);
}
}

View File

@ -27,6 +27,7 @@ import { FormsModule } from '@angular/forms';
import { PipeModule } from '../../pipes/pipe.module';
import { CommentListComponent } from './comment-list.component';
import { TimeAgoPipe } from '../../pipes';
@NgModule({
imports: [
@ -38,14 +39,10 @@ import { CommentListComponent } from './comment-list.component';
MatFormFieldModule,
MatInputModule,
MatListModule,
MatLineModule
MatLineModule,
TimeAgoPipe
],
declarations: [
CommentListComponent
],
exports: [
CommentListComponent
]
declarations: [CommentListComponent],
exports: [CommentListComponent]
})
export class CommentListModule {
}
export class CommentListModule {}

View File

@ -18,7 +18,7 @@
import { CommentsService } from '../../interfaces/comments-service.interface';
export class CommentListServiceMock implements Partial<CommentsService> {
getUserImage(_user: any): string {
getUserImage(_userId: string): string {
return 'mock-user-image-path';
}
}

View File

@ -21,5 +21,5 @@ import { CommentModel } from '../../models/comment.model';
export interface CommentsService {
get(id: string): Observable<CommentModel[]>;
add(id: string, message: string): Observable<CommentModel>;
getUserImage(user: any): string;
getUserImage(userId: string): string;
}

View File

@ -51,12 +51,12 @@ export class CommentModel {
return result.toUpperCase();
}
constructor(obj?: Partial<CommentModel>) {
constructor(obj?: any) {
if (obj) {
this.id = obj.id;
this.message = obj.message;
this.created = obj.created;
this.createdBy = obj.createdBy;
this.createdBy = new User(obj.createdBy);
this.isSelected = obj.isSelected ? obj.isSelected : false;
}
}

View File

@ -34,4 +34,4 @@ export class User {
Object.assign(this, user);
}
}
};
}

View File

@ -21,6 +21,7 @@ import { FormJavascriptEventRepresentation } from './formJavascriptEventRepresen
import { FormOutcomeRepresentation } from './formOutcomeRepresentation';
import { FormTabRepresentation } from './formTabRepresentation';
import { FormVariableRepresentation } from './formVariableRepresentation';
import { RestVariable } from './restVariable';
export interface FormDefinitionRepresentation {
className?: string;
@ -45,4 +46,5 @@ export interface FormDefinitionRepresentation {
taskId?: string;
taskName?: string;
variables?: FormVariableRepresentation[];
processVariables?: RestVariable[];
}

View File

@ -22,4 +22,5 @@ export interface ProcessInstanceFilterRepresentation {
processDefinitionKey?: string;
sort?: string;
state?: string;
assignment?: string;
}

View File

@ -15,13 +15,18 @@
* limitations under the License.
*/
import { Union } from '../../../../types';
export interface ProcessInstanceQueryRepresentation {
appDefinitionId?: number;
page?: number;
processDefinitionId?: string;
processInstanceId?: string;
size?: number;
sort?: 'created-desc' | 'created-asc' | 'ended-desc' | 'ended-asc';
sort?: ProcessInstanceQueryRepresentationSort;
start?: number;
state?: 'running' | 'completed' | 'all';
state?: ProcessInstanceQueryRepresentationState;
}
export type ProcessInstanceQueryRepresentationSort = Union<string, 'created-desc' | 'created-asc' | 'ended-desc' | 'ended-asc'>;
export type ProcessInstanceQueryRepresentationState = Union<string, 'running' | 'completed' | 'all' | 'open'>;

View File

@ -15,8 +15,6 @@
* limitations under the License.
*/
export * from './process-comments.component';
export * from './services/comment-process.service';
export * from './process-comments.module';
// Creates a union type of string literals with strings, but retains intellisense for the literals.
// Union<string, 'foo' | 'bar'> => string | Omit<string, 'foo' | 'bar'>
export type Union<S = string, T extends string | number = string> = T | Omit<S, T>;

View File

@ -47,7 +47,7 @@ module.exports = function (config) {
}
},
jasmineHtmlReporter: {
suppressAll: true, // removes the duplicated traces
suppressAll: true // removes the duplicated traces
},
coverageReporter: {
@ -58,7 +58,7 @@ module.exports = function (config) {
global: {
statements: 75,
branches: 67,
functions: 70,
functions: 65,
lines: 75
}
}
@ -67,12 +67,7 @@ module.exports = function (config) {
customLaunchers: {
ChromeHeadless: {
base: 'Chrome',
flags: [
'--no-sandbox',
'--headless',
'--disable-gpu',
'--remote-debugging-port=9222'
]
flags: ['--no-sandbox', '--headless', '--disable-gpu', '--remote-debugging-port=9222']
}
},

View File

@ -23,10 +23,10 @@ import { of, throwError } from 'rxjs';
import { defaultApp, deployedApps, nonDeployedApps } from '../mock/apps-list.mock';
import { AppsListComponent, APP_LIST_LAYOUT_GRID, APP_LIST_LAYOUT_LIST } from './apps-list.component';
import { ProcessTestingModule } from '../testing/process.testing.module';
import { AppDefinitionRepresentationModel } from '../task-list';
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatProgressSpinnerHarness } from '@angular/material/progress-spinner/testing';
import { AppDefinitionRepresentation } from '@alfresco/js-api';
describe('AppsListComponent', () => {
let loader: HarnessLoader;
@ -61,6 +61,10 @@ describe('AppsListComponent', () => {
loader = TestbedHarnessEnvironment.documentRootLoader(fixture);
});
afterEach(() => {
fixture.destroy();
});
it('should define layoutType with the default value', () => {
component.layoutType = '';
fixture.detectChanges();
@ -88,16 +92,27 @@ describe('AppsListComponent', () => {
it('should show the apps filtered by defaultAppId', () => {
component.filtersAppId = [{ defaultAppId: 'fake-app-1' }];
fixture.detectChanges();
expect(component.isEmpty()).toBe(false);
expect(component.appList).toBeDefined();
expect(component.appList.length).toEqual(1);
});
it('should show the apps filtered by deploymentId', () => {
it('should filter apps by defaultAppId', async () => {
const filtered = component.filterApps(deployedApps, [{ defaultAppId: 'fake-app-1' }]);
expect(filtered.length).toEqual(1);
expect(filtered[0].defaultAppId).toEqual('fake-app-1');
});
it('should filter apps by deploymentId', async () => {
const filtered = component.filterApps(deployedApps, [{ deploymentId: '4' }]);
expect(filtered.length).toEqual(1);
expect(filtered[0].deploymentId).toEqual('4');
});
it('should show the apps filtered by deploymentId', async () => {
component.filtersAppId = [{ deploymentId: '4' }];
fixture.detectChanges();
expect(component.isEmpty()).toBe(false);
expect(component.appList).toBeDefined();
await fixture.whenStable();
expect(component.appList.length).toEqual(1);
expect(component.appList[0].deploymentId).toEqual('4');
});
@ -105,8 +120,6 @@ describe('AppsListComponent', () => {
it('should show the apps filtered by name', () => {
component.filtersAppId = [{ name: 'App5' }];
fixture.detectChanges();
expect(component.isEmpty()).toBe(false);
expect(component.appList).toBeDefined();
expect(component.appList.length).toEqual(1);
expect(component.appList[0].name).toEqual('App5');
});
@ -114,8 +127,6 @@ describe('AppsListComponent', () => {
it('should show the apps filtered by id', () => {
component.filtersAppId = [{ id: 6 }];
fixture.detectChanges();
expect(component.isEmpty()).toBe(false);
expect(component.appList).toBeDefined();
expect(component.appList.length).toEqual(1);
expect(component.appList[0].id).toEqual(6);
});
@ -123,8 +134,6 @@ describe('AppsListComponent', () => {
it('should show the apps filtered by modelId', () => {
component.filtersAppId = [{ modelId: 66 }];
fixture.detectChanges();
expect(component.isEmpty()).toBe(false);
expect(component.appList).toBeDefined();
expect(component.appList.length).toEqual(2);
expect(component.appList[0].modelId).toEqual(66);
});
@ -132,8 +141,6 @@ describe('AppsListComponent', () => {
it('should show the apps filtered by tenantId', () => {
component.filtersAppId = [{ tenantId: 9 }];
fixture.detectChanges();
expect(component.isEmpty()).toBe(false);
expect(component.appList).toBeDefined();
expect(component.appList.length).toEqual(2);
expect(component.appList[0].tenantId).toEqual(9);
});
@ -147,19 +154,19 @@ describe('AppsListComponent', () => {
describe('internationalization', () => {
it('should provide a translation for the default application name, when app name is not provided', () => {
const appDataMock = {
const appDataMock: AppDefinitionRepresentation = {
defaultAppId: 'tasks',
name: null
} as AppDefinitionRepresentationModel;
};
expect(component.getAppName(appDataMock)).toBe('ADF_TASK_LIST.APPS.TASK_APP_NAME');
});
it('should provide the application name, when it exists', () => {
const appDataMock = {
const appDataMock: AppDefinitionRepresentation = {
defaultAppId: 'uiu',
name: 'the-name'
} as AppDefinitionRepresentationModel;
};
expect(component.getAppName(appDataMock)).toBe(appDataMock.name);
});

View File

@ -18,10 +18,9 @@
import { CustomEmptyContentTemplateDirective, EmptyContentComponent } from '@alfresco/adf-core';
import { AppsProcessService } from './services/apps-process.service';
import { AfterContentInit, Component, EventEmitter, Input, OnInit, Output, ContentChild, OnDestroy, ViewEncapsulation } from '@angular/core';
import { Observable, Observer, Subject } from 'rxjs';
import { AppDefinitionRepresentationModel } from '../task-list';
import { Subject } from 'rxjs';
import { IconModel } from './icon.model';
import { share, takeUntil, finalize } from 'rxjs/operators';
import { finalize, map } from 'rxjs/operators';
import { AppDefinitionRepresentation } from '@alfresco/js-api';
import { CommonModule } from '@angular/common';
import { MatListModule } from '@angular/material/list';
@ -30,7 +29,6 @@ import { MatCardModule } from '@angular/material/card';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { TranslateModule } from '@ngx-translate/core';
const DEFAULT_TASKS_APP: string = 'tasks';
const DEFAULT_TASKS_APP_NAME: string = 'ADF_TASK_LIST.APPS.TASK_APP_NAME';
const DEFAULT_TASKS_APP_THEME: string = 'theme-2';
const DEFAULT_TASKS_APP_ICON: string = 'glyphicon-asterisk';
@ -58,39 +56,37 @@ export class AppsListComponent implements OnInit, AfterContentInit, OnDestroy {
@Input()
layoutType: string = APP_LIST_LAYOUT_GRID;
/** The default app to show when the component is loaded. */
@Input()
defaultAppId = 'tasks';
/** Provides a way to filter the apps to show. */
@Input()
filtersAppId: any[];
filtersAppId: AppDefinitionRepresentation[];
/** Emitted when an app entry is clicked. */
@Output()
appClick = new EventEmitter<AppDefinitionRepresentationModel>();
appClick = new EventEmitter<AppDefinitionRepresentation>();
/** Emitted when an error occurs. */
@Output()
error = new EventEmitter<any>();
apps$: Observable<AppDefinitionRepresentationModel>;
currentApp: AppDefinitionRepresentationModel;
appList: AppDefinitionRepresentationModel[] = [];
currentApp: AppDefinitionRepresentation;
appList: AppDefinitionRepresentation[] = [];
loading: boolean = false;
hasEmptyCustomContentTemplate: boolean = false;
private appsObserver: Observer<AppDefinitionRepresentation>;
private iconsMDL: IconModel;
private onDestroy$ = new Subject<boolean>();
constructor(private appsProcessService: AppsProcessService) {
this.apps$ = new Observable<AppDefinitionRepresentationModel>((observer) => (this.appsObserver = observer)).pipe(share());
}
constructor(private appsProcessService: AppsProcessService) {}
ngOnInit() {
if (!this.isValidType()) {
this.setDefaultLayoutType();
}
this.apps$.pipe(takeUntil(this.onDestroy$)).subscribe((app) => this.appList.push(app));
this.iconsMDL = new IconModel();
this.load();
}
@ -106,11 +102,11 @@ export class AppsListComponent implements OnInit, AfterContentInit, OnDestroy {
}
}
isDefaultApp(app: AppDefinitionRepresentation): boolean {
return app.defaultAppId === DEFAULT_TASKS_APP;
private isDefaultApp(app: AppDefinitionRepresentation): boolean {
return app.defaultAppId === this.defaultAppId;
}
getAppName(app: AppDefinitionRepresentationModel): string {
getAppName(app: AppDefinitionRepresentation): string {
return this.isDefaultApp(app) ? DEFAULT_TASKS_APP_NAME : app.name;
}
@ -119,7 +115,7 @@ export class AppsListComponent implements OnInit, AfterContentInit, OnDestroy {
*
* @param app application model
*/
selectApp(app: AppDefinitionRepresentationModel) {
selectApp(app: AppDefinitionRepresentation) {
this.currentApp = app;
this.appClick.emit(app);
}
@ -176,11 +172,11 @@ export class AppsListComponent implements OnInit, AfterContentInit, OnDestroy {
return this.loading;
}
getTheme(app: AppDefinitionRepresentationModel): string {
getTheme(app: AppDefinitionRepresentation): string {
return app.theme ? app.theme : '';
}
getBackgroundIcon(app: AppDefinitionRepresentationModel): string {
getBackgroundIcon(app: AppDefinitionRepresentation): string {
return this.iconsMDL.mapGlyphiconToMaterialDesignIcons(app.icon);
}
@ -188,18 +184,22 @@ export class AppsListComponent implements OnInit, AfterContentInit, OnDestroy {
this.loading = true;
this.appsProcessService
.getDeployedApplications()
.pipe(finalize(() => (this.loading = false)))
.pipe(
map((apps) => apps.filter((app) => app.deploymentId !== undefined || app.defaultAppId === this.defaultAppId)),
finalize(() => (this.loading = false))
)
.subscribe(
(res) => {
this.filterApps(res).forEach((app) => {
const apps = this.filterApps(res, this.filtersAppId).map((app) => {
if (this.isDefaultApp(app)) {
app.theme = DEFAULT_TASKS_APP_THEME;
app.icon = DEFAULT_TASKS_APP_ICON;
this.appsObserver.next(app);
} else if (app.deploymentId) {
this.appsObserver.next(app);
}
return app;
});
this.appList = [...apps];
},
(err) => {
this.error.emit(err);
@ -207,28 +207,19 @@ export class AppsListComponent implements OnInit, AfterContentInit, OnDestroy {
);
}
private filterApps(apps: AppDefinitionRepresentation[]): AppDefinitionRepresentation[] {
if (this.filtersAppId) {
const filteredApps: AppDefinitionRepresentation[] = [];
apps.forEach((app) => {
this.filtersAppId.forEach((filter) => {
if (
app.defaultAppId === filter.defaultAppId ||
app.deploymentId === filter.deploymentId ||
app.name === filter.name ||
app.id === filter.id ||
app.modelId === filter.modelId ||
app.tenantId === filter.tenantId
) {
filteredApps.push(app);
}
});
});
return filteredApps;
}
return apps;
filterApps(apps: AppDefinitionRepresentation[], filter: Partial<AppDefinitionRepresentation>[]): AppDefinitionRepresentation[] {
return filter && filter.length > 0
? apps.filter((app) =>
filter.some(
(f) =>
(f.defaultAppId && app.defaultAppId === f.defaultAppId) ||
(f.deploymentId && app.deploymentId === f.deploymentId) ||
(f.name && app.name === f.name) ||
(f.id !== undefined && app.id === f.id) ||
(f.modelId !== undefined && app.modelId === f.modelId) ||
(f.tenantId !== undefined && app.tenantId === f.tenantId)
)
)
: apps;
}
}

View File

@ -39,7 +39,7 @@ export class AppsProcessService {
* @returns The list of deployed apps
*/
getDeployedApplications(): Observable<AppDefinitionRepresentation[]> {
return from(this.appsApi.getAppDefinitions()).pipe(map((response) => response.data));
return from(this.appsApi.getAppDefinitions()).pipe(map((response) => response.data || []));
}
/**
@ -49,16 +49,6 @@ export class AppsProcessService {
* @returns The list of deployed apps
*/
getDeployedApplicationsByName(name: string): Observable<AppDefinitionRepresentation> {
return from(this.appsApi.getAppDefinitions()).pipe(map((response) => response.data.find((app) => app.name === name)));
}
/**
* Gets the details for a specific app ID number.
*
* @param appId ID of the target app
* @returns Details of the app
*/
getApplicationDetailsById(appId: number): Observable<AppDefinitionRepresentation> {
return from(this.appsApi.getAppDefinitions()).pipe(map((response) => response.data.find((app) => app.id === appId)));
return this.getDeployedApplications().pipe(map((response) => response.find((app) => app.name === name)));
}
}

View File

@ -34,7 +34,7 @@ export class CreateProcessAttachmentComponent implements OnChanges {
* from the user within the component.
*/
@Output()
error: EventEmitter<any> = new EventEmitter<any>();
error = new EventEmitter<any>();
/**
* Emitted when an attachment is successfully created or uploaded
@ -43,7 +43,7 @@ export class CreateProcessAttachmentComponent implements OnChanges {
@Output()
success = new EventEmitter<RelatedContentRepresentation>();
constructor(private activitiContentService: ProcessContentService) {}
constructor(private processContentService: ProcessContentService) {}
ngOnChanges(changes: SimpleChanges) {
if (changes['processInstanceId']?.currentValue) {
@ -59,7 +59,7 @@ export class CreateProcessAttachmentComponent implements OnChanges {
const opts = {
isRelatedContent: true
};
this.activitiContentService.createProcessRelatedContent(this.processInstanceId, file, opts).subscribe(
this.processContentService.createProcessRelatedContent(this.processInstanceId, file, opts).subscribe(
(res) => {
this.success.emit(res);
},

View File

@ -33,7 +33,7 @@ export class AttachmentComponent implements OnChanges {
* attachment from the user within the component.
*/
@Output()
error: EventEmitter<any> = new EventEmitter<any>();
error = new EventEmitter<any>();
/**
* Emitted when an attachment is created or uploaded successfully
@ -42,7 +42,7 @@ export class AttachmentComponent implements OnChanges {
@Output()
success = new EventEmitter<any>();
constructor(private activitiContentService: ProcessContentService) {}
constructor(private processContentService: ProcessContentService) {}
ngOnChanges(changes: SimpleChanges) {
if (changes['taskId']?.currentValue) {
@ -58,7 +58,7 @@ export class AttachmentComponent implements OnChanges {
const opts = {
isRelatedContent: true
};
this.activitiContentService.createTaskRelatedContent(this.taskId, file, opts).subscribe(
this.processContentService.createTaskRelatedContent(this.taskId, file, opts).subscribe(
(res) => {
this.success.emit(res);
},

View File

@ -7,8 +7,8 @@
<adf-no-content-template>
<ng-template>
<ng-content *ngIf="hasCustomTemplate; else defaulEmptyList" class="adf-custom-empty-template"></ng-content>
<ng-template #defaulEmptyList>
<ng-content *ngIf="hasCustomTemplate; else defaultEmptyList" class="adf-custom-empty-template"></ng-content>
<ng-template #defaultEmptyList>
<adf-empty-list>
<div adf-empty-list-header class="adf-empty-list-header">
{{'ADF_PROCESS_LIST.PROCESS-ATTACHMENT.EMPTY.HEADER' | translate}}
@ -19,7 +19,7 @@
</adf-no-content-template>
<data-columns>
<data-column key="icon" type="image" srTitle="ADF_PROCESS_LIST.PROPERTIES.THUMBNAIL" [sortable]="false"></data-column>
<data-column key="icon" type="image" [sr-title]="'ADF_PROCESS_LIST.PROPERTIES.THUMBNAIL'" [sortable]="false"></data-column>
<data-column key="name" type="text" title="{{'ADF_PROCESS_LIST.PROPERTIES.NAME' | translate}}" class="adf-full-width adf-ellipsis-cell" [sortable]="true"></data-column>
<data-column key="created" type="date" format="shortDate" title="{{'ADF_PROCESS_LIST.PROPERTIES.CREATED' | translate}}"></data-column>
</data-columns>

View File

@ -77,7 +77,7 @@ export class ProcessAttachmentListComponent implements OnChanges, AfterContentIn
isLoading: boolean = false;
constructor(
private activitiContentService: ProcessContentService,
private processContentService: ProcessContentService,
private downloadService: DownloadService,
private thumbnailService: ThumbnailService,
private ngZone: NgZone
@ -105,10 +105,6 @@ export class ProcessAttachmentListComponent implements OnChanges, AfterContentIn
});
}
hasCustomEmptyTemplate(): boolean {
return !!this.emptyTemplate;
}
add(content: any): void {
this.ngZone.run(() => {
this.attachments.push({
@ -121,10 +117,6 @@ export class ProcessAttachmentListComponent implements OnChanges, AfterContentIn
});
}
isEmpty(): boolean {
return this.attachments?.length === 0;
}
onShowRowActionsMenu(event: any) {
const viewAction = {
title: 'ADF_PROCESS_LIST.MENU_ACTIONS.VIEW_CONTENT',
@ -166,7 +158,7 @@ export class ProcessAttachmentListComponent implements OnChanges, AfterContentIn
}
emitDocumentContent(content: any) {
this.activitiContentService.getContentPreview(content.id).subscribe(
this.processContentService.getContentPreview(content.id).subscribe(
(blob: Blob) => {
content.contentBlob = blob;
this.attachmentClick.emit(content);
@ -178,7 +170,7 @@ export class ProcessAttachmentListComponent implements OnChanges, AfterContentIn
}
downloadContent(content: any): void {
this.activitiContentService.getFileRawContent(content.id).subscribe(
this.processContentService.getFileRawContent(content.id).subscribe(
(blob: Blob) => this.downloadService.downloadBlob(blob, content.name),
(err) => {
this.error.emit(err);
@ -186,17 +178,13 @@ export class ProcessAttachmentListComponent implements OnChanges, AfterContentIn
);
}
isDisabled(): boolean {
return this.disabled;
}
private loadAttachmentsByProcessInstanceId(processInstanceId: string) {
if (processInstanceId) {
this.reset();
this.isLoading = true;
const isRelatedContent = 'true';
this.activitiContentService.getProcessRelatedContent(processInstanceId, { isRelatedContent }).subscribe(
(res: any) => {
this.processContentService.getProcessRelatedContent(processInstanceId, { isRelatedContent }).subscribe(
(res) => {
res.data.forEach((content) => {
this.attachments.push({
id: content.id,
@ -219,7 +207,7 @@ export class ProcessAttachmentListComponent implements OnChanges, AfterContentIn
private deleteAttachmentById(contentId: number) {
if (contentId) {
this.activitiContentService.deleteRelatedContent(contentId).subscribe(
this.processContentService.deleteRelatedContent(contentId).subscribe(
() => {
this.attachments = this.attachments.filter((content) => content.id !== contentId);
},

View File

@ -6,8 +6,8 @@
(executeRowAction)="onExecuteRowAction($event)">
<adf-no-content-template>
<ng-template>
<ng-content *ngIf="hasCustomTemplate; else defaulEmptyList" class="adf-custom-empty-template"></ng-content>
<ng-template #defaulEmptyList>
<ng-content *ngIf="hasCustomTemplate; else defaultEmptyList" class="adf-custom-empty-template"></ng-content>
<ng-template #defaultEmptyList>
<adf-empty-list>
<div adf-empty-list-header class="adf-empty-list-header">
{{'ADF_TASK_LIST.ATTACHMENT.EMPTY.HEADER' | translate}}
@ -18,7 +18,7 @@
</adf-no-content-template>
<data-columns>
<data-column key="icon" type="image" srTitle="ADF_TASK_LIST.PROPERTIES.THUMBNAIL" [sortable]="false"></data-column>
<data-column key="icon" type="image" [sr-title]="'ADF_TASK_LIST.PROPERTIES.THUMBNAIL'" [sortable]="false"></data-column>
<data-column key="name" type="text" title="ADF_TASK_LIST.PROPERTIES.NAME" class="adf-full-width adf-ellipsis-cell" [sortable]="true"></data-column>
<data-column key="created" type="date" format="shortDate" title="ADF_TASK_LIST.PROPERTIES.CREATED"></data-column>
</data-columns>

View File

@ -95,10 +95,6 @@ export class TaskAttachmentListComponent implements OnChanges, AfterContentInit
this.attachments = [];
}
hasCustomEmptyTemplate() {
return !!this.emptyTemplate;
}
reload(): void {
this.ngZone.run(() => {
this.loadAttachmentsByTaskId(this.taskId);
@ -130,10 +126,6 @@ export class TaskAttachmentListComponent implements OnChanges, AfterContentInit
}
}
isEmpty(): boolean {
return this.attachments && this.attachments.length === 0;
}
onShowRowActionsMenu(event: any) {
const viewAction = {
title: 'ADF_TASK_LIST.MENU_ACTIONS.VIEW_CONTENT',
@ -195,10 +187,6 @@ export class TaskAttachmentListComponent implements OnChanges, AfterContentInit
);
}
isDisabled(): boolean {
return this.disabled;
}
private loadAttachmentsByTaskId(taskId: string) {
if (taskId) {
this.isLoading = true;

View File

@ -1,66 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { UserRepresentation } from '@alfresco/js-api';
export class BpmUserModel implements UserRepresentation {
apps: any;
capabilities: string[];
company: string;
created: Date;
email: string;
externalId: string;
firstName: string;
lastName: string;
fullname: string;
groups: any;
id: number;
lastUpdate: Date;
latestSyncTimeStamp: Date;
password: string;
pictureId: number;
status: string;
tenantId: number;
tenantName: string;
tenantPictureId: number;
type: string;
constructor(input?: any) {
if (input) {
this.apps = input.apps;
this.capabilities = input.capabilities;
this.company = input.company;
this.created = input.created;
this.email = input.email;
this.externalId = input.externalId;
this.firstName = input.firstName;
this.lastName = input.lastName;
this.fullname = input.fullname;
this.groups = input.groups;
this.id = input.id;
this.lastUpdate = input.lastUpdate;
this.latestSyncTimeStamp = input.latestSyncTimeStamp;
this.password = input.password;
this.pictureId = input.pictureId;
this.status = input.status;
this.tenantId = input.tenantId;
this.tenantName = input.tenantName;
this.tenantPictureId = input.tenantPictureId;
this.type = input.type;
}
}
}

View File

@ -1,45 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This object represent the process service user.*
*/
import { LightUserRepresentation } from '@alfresco/js-api';
export class UserProcessModel implements LightUserRepresentation {
id?: number;
email?: string;
firstName?: string;
lastName?: string;
pictureId?: number;
externalId?: string;
userImage?: string;
constructor(input?: any) {
if (input) {
this.id = input.id;
this.email = input.email || null;
this.firstName = input.firstName || null;
this.lastName = input.lastName || null;
this.pictureId = input.pictureId || null;
this.externalId = input.externalId || null;
this.userImage = input.userImage;
}
}
}

View File

@ -16,6 +16,3 @@
*/
export * from './services/people-process.service';
export * from './models/bpm-user.model';
export * from './models/user-process.model';

View File

@ -16,27 +16,27 @@
*/
import { fakeAsync, TestBed } from '@angular/core/testing';
import { UserProcessModel } from '../models/user-process.model';
import { PeopleProcessService } from './people-process.service';
import { CoreTestingModule } from '@alfresco/adf-core';
import { LightUserRepresentation } from '@alfresco/js-api';
declare let jasmine: any;
const firstInvolvedUser: UserProcessModel = new UserProcessModel({
const firstInvolvedUser: LightUserRepresentation = {
id: 1,
email: 'fake-user1@fake.com',
firstName: 'fakeName1',
lastName: 'fakeLast1'
});
};
const secondInvolvedUser: UserProcessModel = new UserProcessModel({
const secondInvolvedUser: LightUserRepresentation = {
id: 2,
email: 'fake-user2@fake.com',
firstName: 'fakeName2',
lastName: 'fakeLast2'
});
};
const fakeInvolveUserList: UserProcessModel[] = [firstInvolvedUser, secondInvolvedUser];
const fakeInvolveUserList: LightUserRepresentation[] = [firstInvolvedUser, secondInvolvedUser];
const errorResponse = { error: new Error('Unsuccessful HTTP response') };
@ -60,7 +60,7 @@ describe('PeopleProcessService', () => {
});
it('should be able to retrieve people to involve in the task', fakeAsync(() => {
service.getWorkflowUsers('fake-task-id', 'fake-filter').subscribe((users: UserProcessModel[]) => {
service.getWorkflowUsers('fake-task-id', 'fake-filter').subscribe((users) => {
expect(users).toBeDefined();
expect(users.length).toBe(2);
expect(users[0].id).toEqual(1);
@ -77,11 +77,11 @@ describe('PeopleProcessService', () => {
}));
it('should be able to get people images for people retrieved', fakeAsync(() => {
service.getWorkflowUsers('fake-task-id', 'fake-filter').subscribe((users: UserProcessModel[]) => {
service.getWorkflowUsers('fake-task-id', 'fake-filter').subscribe((users) => {
expect(users).toBeDefined();
expect(users.length).toBe(2);
expect(service.getUserImage(users[0])).toContain('/users/' + users[0].id + '/picture');
expect(service.getUserImage(users[1])).toContain('/users/' + users[1].id + '/picture');
expect(service.getUserImage(users[0].id.toString())).toContain('/users/' + users[0].id + '/picture');
expect(service.getUserImage(users[1].id.toString())).toContain('/users/' + users[1].id + '/picture');
});
jasmine.Ajax.requests.mostRecent().respondWith({
@ -92,13 +92,13 @@ describe('PeopleProcessService', () => {
}));
it('should return user image url', () => {
const url = service.getUserImage(firstInvolvedUser);
const url = service.getUserImage(firstInvolvedUser.id.toString());
expect(url).toContain('/users/' + firstInvolvedUser.id + '/picture');
});
it('should return empty list when there are no users to involve', fakeAsync(() => {
service.getWorkflowUsers('fake-task-id', 'fake-filter').subscribe((users: UserProcessModel[]) => {
service.getWorkflowUsers('fake-task-id', 'fake-filter').subscribe((users) => {
expect(users).toBeDefined();
expect(users.length).toBe(0);
});

View File

@ -16,12 +16,10 @@
*/
import { Injectable } from '@angular/core';
import { Observable, from, of } from 'rxjs';
import { Observable, from } from 'rxjs';
import { AlfrescoApiService, GroupModel } from '@alfresco/adf-core';
import { BpmUserModel } from '../models/bpm-user.model';
import { UserProcessModel } from '../models/user-process.model';
import { combineAll, defaultIfEmpty, map, switchMap } from 'rxjs/operators';
import { TaskActionsApi, UsersApi, ResultListDataRepresentationLightUserRepresentation, ActivitiGroupsApi, UserProfileApi } from '@alfresco/js-api';
import { map } from 'rxjs/operators';
import { TaskActionsApi, UsersApi, ActivitiGroupsApi, UserProfileApi, UserRepresentation, LightUserRepresentation } from '@alfresco/js-api';
@Injectable({
providedIn: 'root'
@ -58,8 +56,8 @@ export class PeopleProcessService {
*
* @returns User information object
*/
getCurrentUserInfo(): Observable<BpmUserModel> {
return from(this.profileApi.getProfile()).pipe(map((userRepresentation) => new BpmUserModel(userRepresentation)));
getCurrentUserInfo(): Observable<UserRepresentation> {
return from(this.profileApi.getProfile());
}
/**
@ -94,27 +92,19 @@ export class PeopleProcessService {
* @param groupId group id
* @returns Array of user information objects
*/
getWorkflowUsers(taskId?: string, searchWord?: string, groupId?: string): Observable<UserProcessModel[]> {
getWorkflowUsers(taskId?: string, searchWord?: string, groupId?: number): Observable<LightUserRepresentation[]> {
const option = { excludeTaskId: taskId, filter: searchWord, groupId };
return from(this.getWorkflowUserApi(option)).pipe(
switchMap((response) => (response.data as UserProcessModel[]) || []),
map((user) => {
user.userImage = this.getUserProfileImageApi(user.id.toString());
return of(user);
}),
combineAll(),
defaultIfEmpty([])
);
return from(this.userApi.getUsers(option)).pipe(map((response) => response.data || []));
}
/**
* Gets the profile picture URL for the specified user.
*
* @param user The target user
* @param userId The target user
* @returns Profile picture URL
*/
getUserImage(user: UserProcessModel): string {
return this.getUserProfileImageApi(user.id.toString());
getUserImage(userId: string): string {
return this.userApi.getUserProfilePictureUrl(userId);
}
/**
@ -124,8 +114,8 @@ export class PeopleProcessService {
* @param idToInvolve ID of the user to involve
* @returns Empty response when the update completes
*/
involveUserWithTask(taskId: string, idToInvolve: string): Observable<UserProcessModel[]> {
return from(this.involveUserToTaskApi(taskId, { userId: idToInvolve }));
involveUserWithTask(taskId: string, idToInvolve: string): Observable<LightUserRepresentation[]> {
return from(this.taskActionsApi.involveUser(taskId, { userId: idToInvolve }));
}
/**
@ -135,23 +125,7 @@ export class PeopleProcessService {
* @param idToRemove ID of the user to remove
* @returns Empty response when the update completes
*/
removeInvolvedUser(taskId: string, idToRemove: string): Observable<UserProcessModel[]> {
return from(this.removeInvolvedUserFromTaskApi(taskId, { userId: idToRemove }));
}
private getWorkflowUserApi(options: any): Promise<ResultListDataRepresentationLightUserRepresentation> {
return this.userApi.getUsers(options);
}
private involveUserToTaskApi(taskId: string, node: any) {
return this.taskActionsApi.involveUser(taskId, node);
}
private removeInvolvedUserFromTaskApi(taskId: string, node: any) {
return this.taskActionsApi.removeInvolvedUser(taskId, node);
}
private getUserProfileImageApi(userId: string): string {
return this.userApi.getUserProfilePictureUrl(userId);
removeInvolvedUser(taskId: string, idToRemove: string): Observable<LightUserRepresentation[]> {
return from(this.taskActionsApi.removeInvolvedUser(taskId, { userId: idToRemove }));
}
}

View File

@ -0,0 +1,48 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
AppDefinitionRepresentation,
LightUserRepresentation,
ProcessInstanceRepresentation,
RestVariable,
UserRepresentation,
UserTaskFilterRepresentation
} from '@alfresco/js-api';
/** @deprecated use js-api/ProcessInstanceRepresentation instead */
export type ProcessInstance = ProcessInstanceRepresentation;
/** @deprecated use js-api/UserTaskFilterRepresentation instead */
export type FilterRepresentationModel = UserTaskFilterRepresentation;
/** @deprecated use js-api/UserTaskFilterRepresentation instead */
export type FilterParamsModel = UserTaskFilterRepresentation;
/** @deprecated use js-api/UserRepresentation instead */
export type BpmUserModel = UserRepresentation;
/** @deprecated use js-api/AppDefinitionRepresentation instead */
export type AppDefinitionRepresentationModel = AppDefinitionRepresentation;
/** @deprecated use js-api/LightUserRepresentation instead */
export type UserProcessModel = LightUserRepresentation;
/** @deprecated use js-api/RestVariable instead */
export type ProcessInstanceVariable = RestVariable;
export { ProcessDefinitionRepresentation } from '@alfresco/js-api';

View File

@ -17,7 +17,7 @@
import { NgModule } from '@angular/core';
import { MaterialModule } from '../material.module';
import { CoreModule, FormatSpacePipe } from '@alfresco/adf-core';
import { CoreModule, FormatSpacePipe, InitialUsernamePipe } from '@alfresco/adf-core';
import { FormComponent } from './form.component';
import { StartFormComponent } from './start-form.component';
import { FormCustomOutcomesComponent } from './form-custom-outcomes.component';
@ -35,7 +35,7 @@ import { FileViewerWidgetComponent } from './widgets/file-viewer/file-viewer.wid
import { AlfrescoViewerModule } from '@alfresco/adf-content-services';
@NgModule({
imports: [DynamicTableModule, CoreModule, AlfrescoViewerModule, MaterialModule, FormatSpacePipe],
imports: [DynamicTableModule, CoreModule, AlfrescoViewerModule, MaterialModule, FormatSpacePipe, InitialUsernamePipe],
declarations: [
UploadWidgetComponent,
FormComponent,

View File

@ -102,7 +102,7 @@ export class StartFormComponent extends FormComponent implements OnChanges, OnIn
}
loadStartForm(processId: string) {
this.processService.getProcess(processId).subscribe((instance: any) => {
this.processService.getProcess(processId).subscribe((instance) => {
this.processService.getStartFormInstance(processId).subscribe(
(form) => {
this.formName = form.name;

View File

@ -26,7 +26,7 @@
<div [outerHTML]="user | usernameInitials:'adf-people-widget-pic'"></div>
<div *ngIf="user.pictureId" class="adf-people-widget-image-row">
<img id="adf-people-widget-pic-{{i}}" class="adf-people-widget-image"
[alt]="getDisplayName(user)" [src]="peopleProcessService.getUserImage(user)"/>
[alt]="getDisplayName(user)" [src]="peopleProcessService.getUserImage(user.id.toString())"/>
</div>
<span class="adf-people-label-name">{{getDisplayName(user)}}</span>
</div>

View File

@ -22,7 +22,7 @@ import { Observable, of } from 'rxjs';
import { PeopleWidgetComponent } from './people.widget';
import { TranslateService } from '@ngx-translate/core';
import { PeopleProcessService } from '../../../common/services/people-process.service';
import { UserProcessModel } from '../../../common/models/user-process.model';
import { LightUserRepresentation } from '@alfresco/js-api';
describe('PeopleWidgetComponent', () => {
let widget: PeopleWidgetComponent;
@ -53,29 +53,29 @@ describe('PeopleWidgetComponent', () => {
});
it('should return full name for a given model', () => {
const model = new UserProcessModel({
const model = {
firstName: 'John',
lastName: 'Doe'
});
};
expect(widget.getDisplayName(model)).toBe('John Doe');
});
it('should skip first name for display name', () => {
const model = new UserProcessModel({ firstName: null, lastName: 'Doe' });
const model = { firstName: null, lastName: 'Doe' };
expect(widget.getDisplayName(model)).toBe('Doe');
});
it('should skip last name for display name', () => {
const model = new UserProcessModel({ firstName: 'John', lastName: null });
const model = { firstName: 'John', lastName: null };
expect(widget.getDisplayName(model)).toBe('John');
});
it('should init value from the field', async () => {
widget.field.value = new UserProcessModel({
widget.field.value = {
id: 'people-id',
firstName: 'John',
lastName: 'Doe'
});
};
spyOn(peopleProcessService, 'getWorkflowUsers').and.returnValue(of(null));
@ -87,11 +87,11 @@ describe('PeopleWidgetComponent', () => {
});
it('should show the readonly value when the form is readonly', async () => {
widget.field.value = new UserProcessModel({
widget.field.value = {
id: 'people-id',
firstName: 'John',
lastName: 'Doe'
});
};
widget.field.readOnly = true;
widget.field.form.readOnly = true;
@ -131,12 +131,12 @@ describe('PeopleWidgetComponent', () => {
})
);
widget.field.value = new UserProcessModel({
widget.field.value = {
id: 'people-id',
firstName: 'John',
lastName: 'Doe',
email: 'john@test.com'
});
};
widget.ngOnInit();
const involvedUser = fixture.debugElement.nativeElement.querySelector('input[data-automation-id="adf-people-search-input"]');
@ -179,7 +179,7 @@ describe('PeopleWidgetComponent', () => {
});
describe('when template is ready', () => {
const fakeUserResult = [
const fakeUserResult: LightUserRepresentation[] = [
{ id: 1001, firstName: 'Test01', lastName: 'Test01', email: 'test' },
{ id: 1002, firstName: 'Test02', lastName: 'Test02', email: 'test2' }
];

View File

@ -22,8 +22,8 @@ import { Component, ElementRef, EventEmitter, OnInit, Output, ViewChild, ViewEnc
import { UntypedFormControl } from '@angular/forms';
import { Observable, of } from 'rxjs';
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';
import { LightUserRepresentation } from '@alfresco/js-api';
@Component({
selector: 'people-widget',
@ -50,7 +50,7 @@ export class PeopleWidgetComponent extends WidgetComponent implements OnInit {
@Output()
peopleSelected: EventEmitter<number> = new EventEmitter();
groupId: string;
groupId: number;
value: any;
searchTerm = new UntypedFormControl();
@ -67,7 +67,7 @@ export class PeopleWidgetComponent extends WidgetComponent implements OnInit {
const value = searchTerm.email ? this.getDisplayName(searchTerm) : searchTerm;
return this.peopleProcessService.getWorkflowUsers(undefined, value, this.groupId).pipe(catchError(() => of([])));
}),
map((list: UserProcessModel[]) => {
map((list) => {
const value = this.searchTerm.value.email ? this.getDisplayName(this.searchTerm.value) : this.searchTerm.value;
this.checkUserAndValidateForm(list, value);
return list;
@ -94,7 +94,7 @@ export class PeopleWidgetComponent extends WidgetComponent implements OnInit {
}
}
checkUserAndValidateForm(list: UserProcessModel[], value: string): void {
checkUserAndValidateForm(list: LightUserRepresentation[], value: string): void {
const isValidUser = this.isValidUser(list, value);
if (isValidUser || value === '') {
this.field.validationSummary.message = '';
@ -107,7 +107,7 @@ export class PeopleWidgetComponent extends WidgetComponent implements OnInit {
}
}
isValidUser(users: UserProcessModel[], name: string): boolean {
isValidUser(users: LightUserRepresentation[], name: string): boolean {
if (users) {
return !!users.find((user) => {
const selectedUser = this.getDisplayName(user).toLocaleLowerCase() === name.toLocaleLowerCase();
@ -120,7 +120,7 @@ export class PeopleWidgetComponent extends WidgetComponent implements OnInit {
return false;
}
getDisplayName(model: UserProcessModel) {
getDisplayName(model: LightUserRepresentation) {
if (model) {
const displayName = `${model.firstName || ''} ${model.lastName || ''}`;
return displayName.trim();
@ -128,7 +128,7 @@ export class PeopleWidgetComponent extends WidgetComponent implements OnInit {
return '';
}
onItemSelect(item?: UserProcessModel) {
onItemSelect(item?: LightUserRepresentation) {
if (item) {
this.field.value = item;
} else {

View File

@ -15,65 +15,80 @@
* limitations under the License.
*/
import { AppDefinitionRepresentationModel } from '../task-list';
import { AppDefinitionRepresentation } from '@alfresco/js-api';
export const nonDeployedApps = [new AppDefinitionRepresentationModel({
id: '1',
name: '1',
icon: 'icon1'
}), new AppDefinitionRepresentationModel({
id: '1',
name: '2',
icon: 'icon2'
}), new AppDefinitionRepresentationModel({
id: '1',
name: '3',
icon: 'icon3'
})];
export const deployedApps = [new AppDefinitionRepresentationModel({
id: 1,
name: 'App1',
icon: 'icon1',
deploymentId: '1',
defaultAppId: 'fake-app-1',
modelId: null,
tenantId: null
}), new AppDefinitionRepresentationModel({
id: 2,
name: 'App2',
icon: 'icon2',
deploymentId: '2',
modelId: null,
tenantId: null
}), new AppDefinitionRepresentationModel({
id: 3,
name: 'App3',
icon: 'icon3',
deploymentId: '3',
modelId: null,
tenantId: null
}), new AppDefinitionRepresentationModel({
id: 4,
name: 'App4',
icon: 'icon4',
deploymentId: '4',
modelId: 65,
tenantId: null
}), new AppDefinitionRepresentationModel({
id: 5,
name: 'App5',
icon: 'icon5',
deploymentId: '5',
modelId: 66,
tenantId: 9
}), new AppDefinitionRepresentationModel({
id: 6,
name: 'App6',
icon: 'icon6',
deploymentId: '6',
tenantId: 9,
modelId: 66
})];
export const defaultApp = [new AppDefinitionRepresentationModel({
defaultAppId: 'tasks'
})];
export const nonDeployedApps: AppDefinitionRepresentation[] = [
{
id: 1,
name: '1',
icon: 'icon1'
},
{
id: 1,
name: '2',
icon: 'icon2'
},
{
id: 1,
name: '3',
icon: 'icon3'
}
];
export const deployedApps: AppDefinitionRepresentation[] = [
{
id: 1,
name: 'App1',
icon: 'icon1',
deploymentId: '1',
defaultAppId: 'fake-app-1',
modelId: null,
tenantId: null
},
{
id: 2,
name: 'App2',
icon: 'icon2',
deploymentId: '2',
modelId: null,
tenantId: null
},
{
id: 3,
name: 'App3',
icon: 'icon3',
deploymentId: '3',
modelId: null,
tenantId: null
},
{
id: 4,
name: 'App4',
icon: 'icon4',
deploymentId: '4',
modelId: 65,
tenantId: null
},
{
id: 5,
name: 'App5',
icon: 'icon5',
deploymentId: '5',
modelId: 66,
tenantId: 9
},
{
id: 6,
name: 'App6',
icon: 'icon6',
deploymentId: '6',
tenantId: 9,
modelId: 66
}
];
export const defaultApp: AppDefinitionRepresentation[] = [
{
defaultAppId: 'tasks'
}
];

View File

@ -1,99 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { FilterProcessRepresentationModel } from '../../process-list/models/filter-process.model';
export const fakeProcessFilters = [
new FilterProcessRepresentationModel({
id: 10,
name: 'FakeCompleted',
icon: 'glyphicon-th',
filter: { state: 'open', assignment: 'fake-involved' }
}),
new FilterProcessRepresentationModel({
id: 20,
name: 'FakeAll',
icon: 'glyphicon-random',
filter: { state: 'open', assignment: 'fake-assignee' }
}),
new FilterProcessRepresentationModel({
id: 30,
name: 'Running',
icon: 'glyphicon-ok-sign',
filter: { state: 'open', assignment: 'fake-running' }
})
];
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' }
})
]
};
export const dummyRunningFilter = {
appId: 123,
name: 'Running',
filter: { sort: 'created-desc', name: '', state: 'running' },
icon: 'fa-random',
id: 18,
index: 10,
recent: false,
hasFilter: () => true
};
export const dummyCompletedFilter = {
appId: 123,
name: 'Completed',
filter: { sort: 'created-desc', name: '', state: 'completed' },
icon: 'fa-random',
id: 19,
index: 11,
recent: false,
hasFilter: () => true
};
export const dummyAllFilter = {
appId: 123,
name: 'All',
filter: { sort: 'created-desc', name: '', state: 'all' },
icon: 'fa-random',
id: 20,
index: 12,
recent: false,
hasFilter: () => true
};
export const dummyDuplicateRunningFilter = {
appId: 123,
name: 'Running',
filter: { sort: 'created-desc', name: '', state: 'running' },
icon: 'fa-random',
id: 21,
index: 13,
recent: false,
hasFilter: () => true
};

View File

@ -15,9 +15,9 @@
* limitations under the License.
*/
import { ProcessListModel } from '../../process-list/models/process-list.model';
import { ResultListDataRepresentationProcessInstanceRepresentation } from '@alfresco/js-api';
export const fakeProcessInstance = new ProcessListModel({
export const fakeProcessInstance: ResultListDataRepresentationProcessInstanceRepresentation = {
size: 2,
total: 2,
start: 0,
@ -28,7 +28,7 @@ export const fakeProcessInstance = new ProcessListModel({
businessKey: null,
processDefinitionId: 'fakeprocess:5:7507',
tenantId: 'tenant_1',
started: '2015-11-09T12:36:14.184+0000',
started: new Date('2015-11-09T12:36:14.184+0000'),
ended: null,
startedBy: {
id: 3,
@ -58,7 +58,7 @@ export const fakeProcessInstance = new ProcessListModel({
businessKey: null,
processDefinitionId: 'fakeprocess:5:7507',
tenantId: 'tenant_1',
started: '2018-01-10T17:02:22.597+0000',
started: new Date('2018-01-10T17:02:22.597+0000'),
ended: null,
startedBy: {
id: 3,
@ -83,7 +83,7 @@ export const fakeProcessInstance = new ProcessListModel({
]
}
]
});
};
export const fakeProcessInstancesWithNoName = {
size: 2,
@ -125,12 +125,12 @@ export const fakeProcessInstancesWithNoName = {
]
};
export const fakeProcessInstancesEmpty = new ProcessListModel({
export const fakeProcessInstancesEmpty: ResultListDataRepresentationProcessInstanceRepresentation = {
size: 0,
total: 0,
start: 0,
data: []
});
};
export const fakeProcessCustomSchema = [
{

View File

@ -16,37 +16,37 @@
*/
/* spell-checker: disable */
import { ProcessInstance } from '../../process-list/models/process-instance.model';
import { ProcessInstanceRepresentation } from '@alfresco/js-api';
export const exampleProcess = new ProcessInstance({
export const exampleProcess: ProcessInstanceRepresentation = {
id: '123',
name: 'Process 123',
started: '2016-11-10T03:37:30.010+0000',
started: new Date('2016-11-10T03:37:30.010+0000'),
startedBy: {
id: 1001,
firstName: 'Bob',
lastName: 'Jones',
email: 'bob@app.activiti.com'
}
});
};
export const processEnded = new ProcessInstance({
export const processEnded: ProcessInstanceRepresentation = {
id: '123',
name: 'Process 123',
started: '2016-11-10T03:37:30.010+0000',
started: new Date('2016-11-10T03:37:30.010+0000'),
startedBy: {
id: 1001,
firstName: 'Bob',
lastName: 'Jones',
email: 'bob@app.activiti.com'
},
ended: '2016-11-11T03:37:30.010+0000'
});
ended: new Date('2016-11-11T03:37:30.010+0000')
};
export const mockRunningProcess = new ProcessInstance({
export const mockRunningProcess: ProcessInstanceRepresentation = {
id: '123',
name: 'Process 123',
started: '2016-11-10T03:37:30.010+0000',
started: new Date('2016-11-10T03:37:30.010+0000'),
startedBy: {
id: 1001,
firstName: 'Bob',
@ -54,12 +54,12 @@ export const mockRunningProcess = new ProcessInstance({
email: 'bob@app.activiti.com'
},
ended: null
});
};
export const exampleProcessNoName = new ProcessInstance({
export const exampleProcessNoName: ProcessInstanceRepresentation = {
id: '123',
name: null,
started: '2016-11-10T03:37:30.010+0000',
started: new Date('2016-11-10T03:37:30.010+0000'),
startedBy: {
id: 1001,
firstName: 'Bob',
@ -67,4 +67,4 @@ export const exampleProcessNoName = new ProcessInstance({
email: 'bob@app.activiti.com'
},
processDefinitionName: 'My Process'
});
};

View File

@ -1,47 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { TaskDetailsModel } from '../../task-list';
import { ProcessDefinitionRepresentation } from '../../process-list/models/process-definition.model';
export const mockError = {
message: null,
messageKey: 'GENERAL.ERROR.FORBIDDEN'
};
export const fakeTasksList = {
data: [
new TaskDetailsModel({
id: 1,
name: 'Task 1',
processInstanceId: 1000,
created: '2016-11-10T03:37:30.010+0000'
}),
new TaskDetailsModel({
id: 2,
name: 'Task 2',
processInstanceId: 1000,
created: '2016-11-10T03:37:30.010+0000'
})
]
};
export const fakeProcessDef = new ProcessDefinitionRepresentation({
id: '32323',
key: 'blah',
name: 'Process 1'
});

View File

@ -15,38 +15,44 @@
* limitations under the License.
*/
import { ProcessDefinitionRepresentation } from '../../process-list/models/process-definition.model';
import { ProcessInstance } from '../../process-list/models/process-instance.model';
import { ProcessInstanceRepresentation, ProcessDefinitionRepresentation } from '@alfresco/js-api';
export const newProcess = new ProcessInstance({
export const newProcess: ProcessInstanceRepresentation = {
id: '32323',
name: 'Process'
});
};
export const testProcessDef = new ProcessDefinitionRepresentation({
export const testProcessDef: ProcessDefinitionRepresentation = {
id: 'my:process1',
name: 'My Process 1',
hasStartForm: false
});
};
export const testProcessDefinitions = [new ProcessDefinitionRepresentation({
id: 'my:process1',
name: 'My Process 1',
hasStartForm: false
})];
export const testProcessDefinitions: ProcessDefinitionRepresentation[] = [
{
id: 'my:process1',
name: 'My Process 1',
hasStartForm: false
}
];
export const testMultipleProcessDefs = [new ProcessDefinitionRepresentation({
id: 'my:process1',
name: 'My Process 1',
hasStartForm: false
}), new ProcessDefinitionRepresentation({
id: 'my:process2',
name: 'My Process 2',
hasStartForm: true
})];
export const testMultipleProcessDefs: ProcessDefinitionRepresentation[] = [
{
id: 'my:process1',
name: 'My Process 1',
hasStartForm: false
},
{
id: 'my:process2',
name: 'My Process 2',
hasStartForm: true
}
];
export const testProcessDefWithForm = [new ProcessDefinitionRepresentation({
id: 'my:process1',
name: 'My Process 1',
hasStartForm: true
})];
export const testProcessDefWithForm: ProcessDefinitionRepresentation[] = [
{
id: 'my:process1',
name: 'My Process 1',
hasStartForm: true
}
];

View File

@ -16,13 +16,9 @@
*/
export * from './process/process-instances-list.mock';
export * from './process/process.service.mock';
export * from './process/start-process.component.mock';
export * from './process/process.model.mock';
export * from './process/process-comments.mock';
export * from './task/task-details.mock';
export * from './task/task-list.mock';
export * from './task/tasklist-service.mock';
export * from './process/process-filters.mock';
export * from './task/task-filters.mock';

View File

@ -1,178 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { FilterRepresentationModel, TaskQueryRequestRepresentationModel } from '../../task-list/models/filter.model';
export const fakeFiltersResponse: any = {
size: 2,
total: 2,
start: 0,
data: [
{
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',
filter: { sort: 'created-desc', name: '', state: 'open', assignment: 'fake-assignee' }
}
]
};
export const fakeTaskFilters = [
new FilterRepresentationModel({
name: 'FakeInvolvedTasks',
icon: 'glyphicon-align-left',
id: 10,
filter: { state: 'open', assignment: 'fake-involved' }
}),
new FilterRepresentationModel({
name: 'FakeMyTasks1',
icon: 'glyphicon-ok-sign',
id: 11,
filter: { state: 'open', assignment: 'fake-assignee' }
}),
new FilterRepresentationModel({
name: 'FakeMyTasks2',
icon: 'glyphicon-inbox',
id: 12,
filter: { state: 'open', assignment: 'fake-assignee' }
})
];
export const fakeAppFilter = {
size: 1,
total: 1,
start: 0,
data: [
{
id: 1,
name: 'FakeInvolvedTasks',
recent: false,
icon: 'glyphicon-align-left',
filter: { sort: 'created-desc', name: '', state: 'open', assignment: 'fake-involved' }
}
]
};
export const fakeFilter: TaskQueryRequestRepresentationModel = {
sort: 'created-desc',
text: '',
state: 'open',
assignment: 'fake-assignee'
};
export const mockFilterNoState: TaskQueryRequestRepresentationModel = {
sort: 'created-desc',
text: '',
assignment: 'fake-assignee'
};
export const fakeRepresentationFilter1: FilterRepresentationModel = new FilterRepresentationModel({
appId: 1,
name: 'CONTAIN FILTER',
recent: true,
icon: 'glyphicon-align-left',
filter: {
processDefinitionId: null,
processDefinitionKey: null,
name: null,
state: 'open',
sort: 'created-desc',
assignment: 'involved',
dueAfter: null,
dueBefore: null
}
});
export const fakeRepresentationFilter2: FilterRepresentationModel = new FilterRepresentationModel({
appId: 2,
name: 'NO TASK FILTER',
recent: false,
icon: 'glyphicon-inbox',
filter: {
processDefinitionId: null,
processDefinitionKey: null,
name: null,
state: 'open',
sort: 'created-desc',
assignment: 'assignee',
dueAfter: null,
dueBefore: null
}
});
export const dummyMyTasksFilter = {
appId: 101,
name: 'My Tasks',
filter: { sort: 'created-desc', name: '', state: 'open', assignment: 'fake-mytasks' },
icon: 'fa-random',
id: 81,
index: 21,
recent: false,
hasFilter: () => true
};
export const dummyInvolvedTasksFilter = {
appId: 101,
name: 'Involved Tasks',
filter: { sort: 'created-desc', name: '', state: 'open', assignment: 'fake-involved' },
icon: 'fa-random',
id: 82,
index: 22,
recent: false,
hasFilter: () => true
};
export const dummyQueuedTasksFilter = {
appId: 101,
name: 'Queued Tasks',
filter: { sort: 'created-desc', name: '', state: 'open', assignment: 'fake-queued' },
icon: 'fa-random',
id: 83,
index: 23,
recent: false,
hasFilter: () => true
};
export const dummyCompletedTasksFilter = {
appId: 101,
name: 'Completed',
filter: { sort: 'created-desc', name: '', state: 'open', assignment: 'fake-completed' },
icon: 'fa-random',
id: 84,
index: 24,
recent: false,
hasFilter: () => true
};
export const dummyDuplicateMyTasksFilter = {
appId: 101,
name: 'My Tasks',
filter: { sort: 'created-desc', name: '', state: 'open', assignment: 'fake-mytasks' },
icon: 'fa-random',
id: 85,
index: 25,
recent: false,
hasFilter: () => true
};

View File

@ -15,9 +15,7 @@
* limitations under the License.
*/
import { TaskListModel } from '../../task-list/models/task-list.model';
export const fakeGlobalTask = new TaskListModel({
export const fakeGlobalTask: any = {
size: 2,
start: 0,
total: 2,
@ -76,7 +74,7 @@ export const fakeGlobalTask = new TaskListModel({
endDate: null
}
]
});
};
export const fakeCustomSchema = [
{
@ -126,164 +124,170 @@ export const fakeEmptyTask = {
data: []
};
export const paginatedTask = new TaskListModel({
export const paginatedTask: any = {
size: 5,
total: 9,
start: 0,
data: [{
id: '69211',
name: 'My Task Name',
description: '',
category: null,
assignee: {id: 1493, firstName: 'fake name', lastName: 'fake', email: 'abc@test.com'},
created: '2020-02-06T18:41:21.587+0000',
dueDate: null,
endDate: null,
duration: null,
priority: 50,
parentTaskId: null,
parentTaskName: null,
processInstanceId: null,
processInstanceName: null,
processDefinitionId: null,
processDefinitionName: null,
processDefinitionDescription: null,
processDefinitionKey: null,
processDefinitionCategory: null,
processDefinitionVersion: 0,
processDefinitionDeploymentId: null,
formKey: null,
processInstanceStartUserId: null,
initiatorCanCompleteTask: false,
adhocTaskCanBeReassigned: false,
taskDefinitionKey: null,
executionId: null,
memberOfCandidateGroup: false,
memberOfCandidateUsers: false,
managerOfCandidateGroup: false
}, {
id: '61054',
name: null,
description: null,
category: null,
assignee: {id: 19, firstName: 'Mm9ntWGB', lastName: 'jfQOzSDL', email: 'c4jly@activiti.test.com'},
created: '2020-02-06T15:26:32.488+0000',
dueDate: null,
endDate: null,
duration: null,
priority: 50,
parentTaskId: null,
parentTaskName: null,
processInstanceId: '61049',
processInstanceName: null,
processDefinitionId: 'upload:1:50118',
processDefinitionName: 'upload',
processDefinitionDescription: null,
processDefinitionKey: 'upload',
processDefinitionCategory: 'http://www.activiti.org/processdef',
processDefinitionVersion: 1,
processDefinitionDeploymentId: '50115',
formKey: '8474',
processInstanceStartUserId: null,
initiatorCanCompleteTask: false,
adhocTaskCanBeReassigned: false,
taskDefinitionKey: 'sid-7A12380E-28F8-4B15-9326-C5CFB8DD5BBC',
executionId: '61049',
memberOfCandidateGroup: false,
memberOfCandidateUsers: false,
managerOfCandidateGroup: false
}, {
id: '61048',
name: 'My Task Name',
description: null,
category: null,
assignee: {id: 1493, firstName: 'fake name', lastName: 'fake', email: 'abc@test.com'},
created: '2020-02-06T15:26:03.012+0000',
dueDate: null,
endDate: null,
duration: null,
priority: 50,
parentTaskId: null,
parentTaskName: null,
processInstanceId: null,
processInstanceName: null,
processDefinitionId: null,
processDefinitionName: null,
processDefinitionDescription: null,
processDefinitionKey: null,
processDefinitionCategory: null,
processDefinitionVersion: 0,
processDefinitionDeploymentId: null,
formKey: null,
processInstanceStartUserId: null,
initiatorCanCompleteTask: false,
adhocTaskCanBeReassigned: false,
taskDefinitionKey: null,
executionId: null,
memberOfCandidateGroup: false,
memberOfCandidateUsers: false,
managerOfCandidateGroup: false
}, {
id: '54705',
name: 'My Task Name',
description: '',
category: '1349',
assignee: {id: 1493, firstName: 'fake name', lastName: 'fake', email: 'abc@test.com'},
created: '2020-02-06T13:01:23.403+0000',
dueDate: null,
endDate: null,
duration: null,
priority: 50,
parentTaskId: null,
parentTaskName: null,
processInstanceId: null,
processInstanceName: null,
processDefinitionId: null,
processDefinitionName: null,
processDefinitionDescription: null,
processDefinitionKey: null,
processDefinitionCategory: null,
processDefinitionVersion: 0,
processDefinitionDeploymentId: null,
formKey: null,
processInstanceStartUserId: null,
initiatorCanCompleteTask: false,
adhocTaskCanBeReassigned: false,
taskDefinitionKey: null,
executionId: null,
memberOfCandidateGroup: false,
memberOfCandidateUsers: false,
managerOfCandidateGroup: false
}, {
id: '50158',
name: 'My Task Name',
description: '',
category: '1349',
assignee: {id: 1493, firstName: 'fake name', lastName: 'fake', email: 'abc@test.com'},
created: '2020-02-06T09:13:55.532+0000',
dueDate: '2019-01-09T11:53:00.000+0000',
endDate: null,
duration: null,
priority: 0,
parentTaskId: null,
parentTaskName: null,
processInstanceId: null,
processInstanceName: null,
processDefinitionId: null,
processDefinitionName: null,
processDefinitionDescription: null,
processDefinitionKey: null,
processDefinitionCategory: null,
processDefinitionVersion: 0,
processDefinitionDeploymentId: null,
formKey: '8484',
processInstanceStartUserId: null,
initiatorCanCompleteTask: false,
adhocTaskCanBeReassigned: false,
taskDefinitionKey: null,
executionId: null,
memberOfCandidateGroup: false,
memberOfCandidateUsers: false,
managerOfCandidateGroup: false
}]
});
data: [
{
id: '69211',
name: 'My Task Name',
description: '',
category: null,
assignee: { id: 1493, firstName: 'fake name', lastName: 'fake', email: 'abc@test.com' },
created: '2020-02-06T18:41:21.587+0000',
dueDate: null,
endDate: null,
duration: null,
priority: 50,
parentTaskId: null,
parentTaskName: null,
processInstanceId: null,
processInstanceName: null,
processDefinitionId: null,
processDefinitionName: null,
processDefinitionDescription: null,
processDefinitionKey: null,
processDefinitionCategory: null,
processDefinitionVersion: 0,
processDefinitionDeploymentId: null,
formKey: null,
processInstanceStartUserId: null,
initiatorCanCompleteTask: false,
adhocTaskCanBeReassigned: false,
taskDefinitionKey: null,
executionId: null,
memberOfCandidateGroup: false,
memberOfCandidateUsers: false,
managerOfCandidateGroup: false
},
{
id: '61054',
name: null,
description: null,
category: null,
assignee: { id: 19, firstName: 'Mm9ntWGB', lastName: 'jfQOzSDL', email: 'c4jly@activiti.test.com' },
created: '2020-02-06T15:26:32.488+0000',
dueDate: null,
endDate: null,
duration: null,
priority: 50,
parentTaskId: null,
parentTaskName: null,
processInstanceId: '61049',
processInstanceName: null,
processDefinitionId: 'upload:1:50118',
processDefinitionName: 'upload',
processDefinitionDescription: null,
processDefinitionKey: 'upload',
processDefinitionCategory: 'http://www.activiti.org/processdef',
processDefinitionVersion: 1,
processDefinitionDeploymentId: '50115',
formKey: '8474',
processInstanceStartUserId: null,
initiatorCanCompleteTask: false,
adhocTaskCanBeReassigned: false,
taskDefinitionKey: 'sid-7A12380E-28F8-4B15-9326-C5CFB8DD5BBC',
executionId: '61049',
memberOfCandidateGroup: false,
memberOfCandidateUsers: false,
managerOfCandidateGroup: false
},
{
id: '61048',
name: 'My Task Name',
description: null,
category: null,
assignee: { id: 1493, firstName: 'fake name', lastName: 'fake', email: 'abc@test.com' },
created: '2020-02-06T15:26:03.012+0000',
dueDate: null,
endDate: null,
duration: null,
priority: 50,
parentTaskId: null,
parentTaskName: null,
processInstanceId: null,
processInstanceName: null,
processDefinitionId: null,
processDefinitionName: null,
processDefinitionDescription: null,
processDefinitionKey: null,
processDefinitionCategory: null,
processDefinitionVersion: 0,
processDefinitionDeploymentId: null,
formKey: null,
processInstanceStartUserId: null,
initiatorCanCompleteTask: false,
adhocTaskCanBeReassigned: false,
taskDefinitionKey: null,
executionId: null,
memberOfCandidateGroup: false,
memberOfCandidateUsers: false,
managerOfCandidateGroup: false
},
{
id: '54705',
name: 'My Task Name',
description: '',
category: '1349',
assignee: { id: 1493, firstName: 'fake name', lastName: 'fake', email: 'abc@test.com' },
created: '2020-02-06T13:01:23.403+0000',
dueDate: null,
endDate: null,
duration: null,
priority: 50,
parentTaskId: null,
parentTaskName: null,
processInstanceId: null,
processInstanceName: null,
processDefinitionId: null,
processDefinitionName: null,
processDefinitionDescription: null,
processDefinitionKey: null,
processDefinitionCategory: null,
processDefinitionVersion: 0,
processDefinitionDeploymentId: null,
formKey: null,
processInstanceStartUserId: null,
initiatorCanCompleteTask: false,
adhocTaskCanBeReassigned: false,
taskDefinitionKey: null,
executionId: null,
memberOfCandidateGroup: false,
memberOfCandidateUsers: false,
managerOfCandidateGroup: false
},
{
id: '50158',
name: 'My Task Name',
description: '',
category: '1349',
assignee: { id: 1493, firstName: 'fake name', lastName: 'fake', email: 'abc@test.com' },
created: '2020-02-06T09:13:55.532+0000',
dueDate: '2019-01-09T11:53:00.000+0000',
endDate: null,
duration: null,
priority: 0,
parentTaskId: null,
parentTaskName: null,
processInstanceId: null,
processInstanceName: null,
processDefinitionId: null,
processDefinitionName: null,
processDefinitionDescription: null,
processDefinitionKey: null,
processDefinitionCategory: null,
processDefinitionVersion: 0,
processDefinitionDeploymentId: null,
formKey: '8484',
processInstanceStartUserId: null,
initiatorCanCompleteTask: false,
adhocTaskCanBeReassigned: false,
taskDefinitionKey: null,
executionId: null,
memberOfCandidateGroup: false,
memberOfCandidateUsers: false,
managerOfCandidateGroup: false
}
]
};

View File

@ -1,38 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { TaskListModel } from '../../task-list/models/task-list.model';
import { fakeAppFilter } from './task-filters.mock';
export const fakeUser1 = { id: 1, email: 'fake-email@dom.com', firstName: 'firstName', lastName: 'lastName' };
export const fakeTaskList = new TaskListModel({
size: 1,
total: 1,
start: 0,
data: [
{
id: '1',
name: 'FakeNameTask',
description: null,
category: null,
assignee: fakeUser1,
created: '2016-07-15T11:19:17.440+0000'
}
]
});
export const fakeAppPromise = Promise.resolve(fakeAppFilter);

View File

@ -20,14 +20,14 @@ import { DataRowActionEvent, DataRowEvent, ObjectDataRow } from '@alfresco/adf-c
import { UserEventModel } from '../../../task-list/models/user-event.model';
import { PeopleListComponent } from './people-list.component';
import { ProcessTestingModule } from '../../../testing/process.testing.module';
import { UserProcessModel } from '../../../common/models/user-process.model';
import { LightUserRepresentation } from '@alfresco/js-api';
const fakeUser: UserProcessModel = new UserProcessModel({
const fakeUser: LightUserRepresentation = {
id: 1,
firstName: 'fake-name',
lastName: 'fake-last',
email: 'fake@mail.com'
});
};
describe('PeopleListComponent', () => {
let peopleListComponent: PeopleListComponent;
@ -35,7 +35,7 @@ describe('PeopleListComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ProcessTestingModule]
imports: [ProcessTestingModule, PeopleListComponent]
});
fixture = TestBed.createComponent(PeopleListComponent);
peopleListComponent = fixture.componentInstance;

View File

@ -15,19 +15,20 @@
* limitations under the License.
*/
import { DataTableComponent, DataCellEvent, DataColumnListComponent, ShowHeaderMode } from '@alfresco/adf-core';
import { DataTableComponent, DataCellEvent, DataColumnListComponent, ShowHeaderMode, DataTableModule } from '@alfresco/adf-core';
import { AfterContentInit, Component, ContentChild, EventEmitter, Input, Output, ViewChild } from '@angular/core';
import { UserProcessModel } from '../../../common/models/user-process.model';
import { UserEventModel } from '../../../task-list/models/user-event.model';
import { LightUserRepresentation } from '@alfresco/js-api';
import { CommonModule } from '@angular/common';
@Component({
selector: 'adf-people-list',
standalone: true,
imports: [CommonModule, DataTableModule],
templateUrl: './people-list.component.html',
styleUrls: ['./people-list.component.scss']
})
export class PeopleListComponent implements AfterContentInit {
@ContentChild(DataColumnListComponent)
columnList: DataColumnListComponent;
@ -36,21 +37,21 @@ export class PeopleListComponent implements AfterContentInit {
/** The array of user data used to populate the people list. */
@Input()
users: UserProcessModel[];
users: LightUserRepresentation[];
/** Toggles whether or not actions should be visible, i.e. the 'Three-Dots' menu. */
/** Toggles if actions should be visible, i.e. the 'Three-Dots' menu. */
@Input()
actions: boolean = false;
/** Emitted when the user clicks a row in the people list. */
@Output()
clickRow = new EventEmitter<UserProcessModel>();
clickRow = new EventEmitter<LightUserRepresentation>();
/** Emitted when the user clicks in the 'Three Dots' drop down menu for a row. */
@Output()
clickAction = new EventEmitter<UserEventModel>();
user: UserProcessModel;
user: LightUserRepresentation;
showHeader = ShowHeaderMode.Never;
ngAfterContentInit() {
@ -67,20 +68,17 @@ export class PeopleListComponent implements AfterContentInit {
}
onShowRowActionsMenu(event: DataCellEvent) {
const removeAction = {
title: 'Remove',
name: 'remove'
};
event.value.actions = [
removeAction
];
event.value.actions = [removeAction];
}
onExecuteRowAction(event: any) {
const args = event.value;
const action = args.action;
this.clickAction.emit({type: action.name, value: args.row.obj});
this.clickAction.emit({ type: action.name, value: args.row.obj });
}
}

View File

@ -18,7 +18,7 @@
{{getInitialUserName(entry.row.obj.firstName, entry.row.obj.lastName)}}</div>
<div>
<img [alt]="getDisplayUser(entry.row.obj.firstName, entry.row.obj.lastName, ' ')" *ngIf="entry.row.obj.pictureId" class="adf-people-img"
[src]="peopleProcessService.getUserImage(entry.row.obj)"/>
[src]="peopleProcessService.getUserImage(entry.row.obj.id.toString())"/>
</div>
</ng-template>
</data-column>

View File

@ -15,18 +15,24 @@
* limitations under the License.
*/
import { TranslationService } from '@alfresco/adf-core';
import { DataTableModule, TranslationService } from '@alfresco/adf-core';
import { Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angular/core';
import { UntypedFormControl } from '@angular/forms';
import { ReactiveFormsModule, UntypedFormControl } from '@angular/forms';
import { debounceTime, switchMap } from 'rxjs/operators';
import { Observable, of } from 'rxjs';
import { PerformSearchCallback } from '../../interfaces/perform-search-callback.interface';
import { getDisplayUser } from '../../helpers/get-display-user';
import { PeopleProcessService } from '../../../common/services/people-process.service';
import { UserProcessModel } from '../../../common/models/user-process.model';
import { LightUserRepresentation } from '@alfresco/js-api';
import { CommonModule } from '@angular/common';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { PeopleListComponent } from '../people-list/people-list.component';
@Component({
selector: 'adf-people-search-field',
standalone: true,
imports: [CommonModule, MatFormFieldModule, MatInputModule, ReactiveFormsModule, DataTableModule, PeopleListComponent],
templateUrl: './people-search-field.component.html',
styleUrls: ['./people-search-field.component.scss'],
host: { class: 'adf-people-search-field' },
@ -40,9 +46,9 @@ export class PeopleSearchFieldComponent {
placeholder: string;
@Output()
rowClick = new EventEmitter<UserProcessModel>();
rowClick = new EventEmitter<LightUserRepresentation>();
users$: Observable<UserProcessModel[]>;
users$: Observable<LightUserRepresentation[]>;
searchUser: UntypedFormControl = new UntypedFormControl();
defaultPlaceholder = 'ADF_TASK_LIST.PEOPLE.SEARCH_USER';
@ -70,7 +76,7 @@ export class PeopleSearchFieldComponent {
return this.placeholder || this.defaultPlaceholder;
}
onRowClick(model: UserProcessModel) {
onRowClick(model: LightUserRepresentation) {
this.rowClick.emit(model);
}

View File

@ -1,5 +1,5 @@
<div class="adf-search-text-header">
<ng-content select="[adf-people-search-title], [people-search-title]"></ng-content>
<div class="adf-search-text-header" *ngIf="headerTitle">
{{headerTitle | translate}}
</div>
<adf-people-search-field [performSearch]="performSearch" (rowClick)="onRowClick($event)"></adf-people-search-field>
@ -9,6 +9,6 @@
{{'ADF_TASK_LIST.PEOPLE.DIALOG_CLOSE' | translate }}
</button>
<button mat-button type="button" id="add-people" (click)="involveUserAndClose()">
<ng-content select="[adf-people-search-action-label], [people-search-action-label]"></ng-content>
{{actionLabel | translate}}
</button>
</div>

View File

@ -19,21 +19,21 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { of } from 'rxjs';
import { PeopleSearchComponent } from './people-search.component';
import { ProcessTestingModule } from '../../../testing/process.testing.module';
import { UserProcessModel } from '../../../common/models/user-process.model';
import { LightUserRepresentation } from '@alfresco/js-api';
const fakeUser: UserProcessModel = new UserProcessModel({
id: '1',
const fakeUser: LightUserRepresentation = {
id: 1,
firstName: 'John',
lastName: 'Doe',
email: 'JohnDoe@fake.com'
});
};
const fakeSecondUser: UserProcessModel = new UserProcessModel({
id: '2',
const fakeSecondUser: LightUserRepresentation = {
id: 2,
firstName: 'Jane',
lastName: 'Jackson',
email: 'JaneJackson@fake.com'
});
};
describe('PeopleSearchComponent', () => {
let peopleSearchComponent: PeopleSearchComponent;
@ -44,7 +44,7 @@ describe('PeopleSearchComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ProcessTestingModule]
imports: [ProcessTestingModule, PeopleSearchComponent]
});
fixture = TestBed.createComponent(PeopleSearchComponent);
peopleSearchComponent = fixture.componentInstance;

View File

@ -15,14 +15,20 @@
* limitations under the License.
*/
import { UserProcessModel } from '../../../common/models/user-process.model';
import { Component, EventEmitter, OnInit, Input, Output, ViewEncapsulation } from '@angular/core';
import { Observable } from 'rxjs';
import { PerformSearchCallback } from '../../interfaces/perform-search-callback.interface';
import { map } from 'rxjs/operators';
import { LightUserRepresentation } from '@alfresco/js-api';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { PeopleSearchFieldComponent } from '../people-search-field/people-search-field.component';
import { MatButtonModule } from '@angular/material/button';
@Component({
selector: 'adf-people-search',
standalone: true,
imports: [CommonModule, TranslateModule, PeopleSearchFieldComponent, MatButtonModule],
templateUrl: './people-search.component.html',
styleUrls: ['./people-search.component.scss'],
host: {
@ -30,12 +36,16 @@ import { map } from 'rxjs/operators';
},
encapsulation: ViewEncapsulation.None
})
export class PeopleSearchComponent implements OnInit {
@Input()
headerTitle?: string;
@Input()
actionLabel?: string;
/** Parameters for displaying the list. */
@Input()
results: Observable<UserProcessModel[]>;
results: Observable<LightUserRepresentation[]>;
/** Emitted when a search is performed with a new keyword. */
@Output()
@ -43,25 +53,22 @@ export class PeopleSearchComponent implements OnInit {
/** Emitted when a user is selected and the action button is clicked. */
@Output()
success = new EventEmitter<UserProcessModel>();
success = new EventEmitter<LightUserRepresentation>();
/** Emitted when the "close" button is clicked. */
@Output()
closeSearch = new EventEmitter();
filteredResults$: Observable<UserProcessModel[]>;
selectedUser: UserProcessModel = {};
filteredResults$: Observable<LightUserRepresentation[]>;
selectedUser: LightUserRepresentation = {} as any;
performSearch: PerformSearchCallback;
ngOnInit() {
this.filteredResults$ = this.results
.pipe(
map((users) => users.filter((user) => user.id !== this.selectedUser.id))
);
this.filteredResults$ = this.results.pipe(map((users) => users.filter((user) => user.id !== this.selectedUser.id)));
this.performSearch = this.performSearchCallback.bind(this);
}
onRowClick(user: UserProcessModel) {
onRowClick(user: LightUserRepresentation) {
this.selectedUser = user;
}
@ -81,7 +88,7 @@ export class PeopleSearchComponent implements OnInit {
this.success.emit(this.selectedUser);
}
private performSearchCallback(event: any): Observable<UserProcessModel[]> {
private performSearchCallback(event: any): Observable<LightUserRepresentation[]> {
this.searchPeople.emit(event);
return this.filteredResults$;
}

View File

@ -23,12 +23,17 @@ import { getDisplayUser } from '../../helpers/get-display-user';
import { Observable, of } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { PeopleProcessService } from '../../../common/services/people-process.service';
import { UserProcessModel } from '../../../common/models/user-process.model';
import { LightUserRepresentation } from '@alfresco/js-api';
import { CommonModule } from '@angular/common';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
const DEFAULT_ASSIGNEE_PLACEHOLDER = 'ADF_TASK_LIST.PEOPLE.ASSIGNEE';
@Component({
selector: 'adf-people-selector',
standalone: true,
imports: [CommonModule, PeopleSearchFieldComponent, MatButtonModule, MatIconModule],
templateUrl: './people-selector.component.html',
styleUrls: ['./people-selector.component.scss'],
host: { class: 'adf-people-selector' },
@ -36,7 +41,7 @@ const DEFAULT_ASSIGNEE_PLACEHOLDER = 'ADF_TASK_LIST.PEOPLE.ASSIGNEE';
})
export class PeopleSelectorComponent {
@Input()
peopleId: UserProcessModel;
peopleId: LightUserRepresentation;
// Poorly documented Angular magic for [(peopleId)]
@Output()
@ -46,7 +51,7 @@ export class PeopleSelectorComponent {
searchFieldComponent: PeopleSearchFieldComponent;
performSearch: PerformSearchCallback;
selectedUser: UserProcessModel;
selectedUser: LightUserRepresentation;
defaultPlaceholder: string;
constructor(private peopleProcessService: PeopleProcessService, private translationService: TranslationService) {
@ -55,11 +60,11 @@ export class PeopleSelectorComponent {
this.defaultPlaceholder = this.translationService.instant(DEFAULT_ASSIGNEE_PLACEHOLDER);
}
searchUser(searchWord: string): Observable<any | UserProcessModel[]> {
searchUser(searchWord: string): Observable<any | LightUserRepresentation[]> {
return this.peopleProcessService.getWorkflowUsers(undefined, searchWord).pipe(catchError(() => of([])));
}
userSelected(user: UserProcessModel): void {
userSelected(user: LightUserRepresentation): void {
this.updateUserSelection(user);
}
@ -67,7 +72,7 @@ export class PeopleSelectorComponent {
this.updateUserSelection(undefined);
}
private updateUserSelection(user: UserProcessModel): void {
private updateUserSelection(user: LightUserRepresentation): void {
this.selectedUser = user;
this.peopleIdChange.emit(user?.id);
this.searchFieldComponent.reset();

View File

@ -14,13 +14,13 @@
<div class="adf-assignment-container" *ngIf="showAssignment">
<adf-people-search
#peopleSearch
[headerTitle]="'ADF_TASK_LIST.DETAILS.LABELS.ADD_PEOPLE'"
[actionLabel]="'ADF_TASK_LIST.PEOPLE.ADD_USER'"
(searchPeople)="searchUser($event)"
(success)="involveUser($event)"
(closeSearch)="onCloseSearch()"
[results]="peopleSearch$"
>
<ng-container adf-people-search-title>{{ 'ADF_TASK_LIST.DETAILS.LABELS.ADD_PEOPLE' | translate }}</ng-container>
<ng-container adf-people-search-action-label>{{ 'ADF_TASK_LIST.PEOPLE.ADD_USER' | translate }}</ng-container>
</adf-people-search>
</div>
<div class="adf-assignment-list-container" id="assignment-people-list" *ngIf="hasPeople()">
@ -36,7 +36,7 @@
[alt]="getDisplayUser(entry.row.obj.firstName, entry.row.obj.lastName, ' ')"
*ngIf="entry.row.obj.pictureId"
class="adf-people-img"
[src]="peopleProcessService.getUserImage(entry.row.obj)"
[src]="peopleProcessService.getUserImage(entry.row.obj.id.toString())"
/>
</div>
</ng-template>

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