mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ACS-7427] Process Services improvements and cleanup (#9664)
This commit is contained in:
@@ -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);
|
||||
});
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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)));
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
},
|
||||
|
@@ -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);
|
||||
},
|
||||
|
@@ -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>
|
||||
|
@@ -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);
|
||||
},
|
||||
|
@@ -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>
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -16,6 +16,3 @@
|
||||
*/
|
||||
|
||||
export * from './services/people-process.service';
|
||||
|
||||
export * from './models/bpm-user.model';
|
||||
export * from './models/user-process.model';
|
||||
|
@@ -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);
|
||||
});
|
||||
|
@@ -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 }));
|
||||
}
|
||||
}
|
||||
|
48
lib/process-services/src/lib/compat/types.ts
Normal file
48
lib/process-services/src/lib/compat/types.ts
Normal 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';
|
@@ -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,
|
||||
|
@@ -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;
|
||||
|
@@ -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>
|
||||
|
@@ -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' }
|
||||
];
|
||||
|
@@ -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 {
|
||||
|
@@ -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'
|
||||
}
|
||||
];
|
||||
|
@@ -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
|
||||
};
|
@@ -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 = [
|
||||
{
|
||||
|
@@ -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'
|
||||
});
|
||||
};
|
||||
|
@@ -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'
|
||||
});
|
@@ -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
|
||||
}
|
||||
];
|
||||
|
@@ -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';
|
||||
|
@@ -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
|
||||
};
|
@@ -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
|
||||
}
|
||||
]
|
||||
};
|
||||
|
@@ -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);
|
@@ -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;
|
||||
|
@@ -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 });
|
||||
}
|
||||
}
|
||||
|
@@ -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>
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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>
|
||||
|
@@ -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;
|
||||
|
@@ -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$;
|
||||
}
|
||||
|
@@ -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();
|
||||
|
@@ -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>
|
||||
|
@@ -18,47 +18,47 @@
|
||||
import { ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing';
|
||||
import { PeopleComponent } from './people.component';
|
||||
import { ProcessTestingModule } from '../../../testing/process.testing.module';
|
||||
import { UserProcessModel } from '../../../common/models/user-process.model';
|
||||
import { LightUserRepresentation } from '@alfresco/js-api';
|
||||
|
||||
declare let jasmine: any;
|
||||
|
||||
const fakeUser = new UserProcessModel({
|
||||
id: 'fake-id',
|
||||
const fakeUser: LightUserRepresentation = {
|
||||
id: 0,
|
||||
firstName: 'fake-name',
|
||||
lastName: 'fake-last',
|
||||
email: 'fake@mail.com'
|
||||
});
|
||||
};
|
||||
|
||||
const fakeSecondUser = new UserProcessModel({
|
||||
id: 'fake-involve-id',
|
||||
const fakeSecondUser: LightUserRepresentation = {
|
||||
id: 1,
|
||||
firstName: 'fake-involve-name',
|
||||
lastName: 'fake-involve-last',
|
||||
email: 'fake-involve@mail.com'
|
||||
});
|
||||
};
|
||||
|
||||
describe('PeopleComponent', () => {
|
||||
let activitiPeopleComponent: PeopleComponent;
|
||||
let peopleComponent: PeopleComponent;
|
||||
let fixture: ComponentFixture<PeopleComponent>;
|
||||
let element: HTMLElement;
|
||||
const userArray = [fakeUser, fakeSecondUser];
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [ProcessTestingModule]
|
||||
imports: [ProcessTestingModule, PeopleComponent]
|
||||
});
|
||||
fixture = TestBed.createComponent(PeopleComponent);
|
||||
activitiPeopleComponent = fixture.componentInstance;
|
||||
peopleComponent = fixture.componentInstance;
|
||||
element = fixture.nativeElement;
|
||||
|
||||
activitiPeopleComponent.people = [];
|
||||
activitiPeopleComponent.readOnly = true;
|
||||
peopleComponent.people = [];
|
||||
peopleComponent.readOnly = true;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
afterEach(() => fixture.destroy());
|
||||
|
||||
it('should show people component title', async () => {
|
||||
activitiPeopleComponent.people = [...userArray];
|
||||
peopleComponent.people = [...userArray];
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
@@ -77,8 +77,8 @@ describe('PeopleComponent', () => {
|
||||
|
||||
describe('when there are involved people', () => {
|
||||
beforeEach(() => {
|
||||
activitiPeopleComponent.taskId = 'fake-task-id';
|
||||
activitiPeopleComponent.people.push(...userArray);
|
||||
peopleComponent.taskId = 'fake-task-id';
|
||||
peopleComponent.people.push(...userArray);
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
@@ -100,7 +100,7 @@ describe('PeopleComponent', () => {
|
||||
});
|
||||
|
||||
it('should remove people involved', fakeAsync(() => {
|
||||
activitiPeopleComponent.removeInvolvedUser(fakeUser);
|
||||
peopleComponent.removeInvolvedUser(fakeUser);
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
status: 200
|
||||
});
|
||||
@@ -113,7 +113,7 @@ describe('PeopleComponent', () => {
|
||||
}));
|
||||
|
||||
it('should involve people', fakeAsync(() => {
|
||||
activitiPeopleComponent.involveUser(fakeUser);
|
||||
peopleComponent.involveUser(fakeUser);
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
status: 200
|
||||
});
|
||||
@@ -126,7 +126,7 @@ describe('PeopleComponent', () => {
|
||||
}));
|
||||
|
||||
it('should return an observable with user search results', (done) => {
|
||||
activitiPeopleComponent.peopleSearch$.subscribe((users) => {
|
||||
peopleComponent.peopleSearch$.subscribe((users) => {
|
||||
expect(users.length).toBe(2);
|
||||
expect(users[0].firstName).toBe('fake-test-1');
|
||||
expect(users[0].lastName).toBe('fake-last-1');
|
||||
@@ -134,7 +134,7 @@ describe('PeopleComponent', () => {
|
||||
expect(users[0].id).toBe(1);
|
||||
done();
|
||||
});
|
||||
activitiPeopleComponent.searchUser('fake-search-word');
|
||||
peopleComponent.searchUser('fake-search-word');
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
status: 200,
|
||||
contentType: 'json',
|
||||
@@ -158,11 +158,11 @@ describe('PeopleComponent', () => {
|
||||
});
|
||||
|
||||
it('should return an empty list for not valid search', (done) => {
|
||||
activitiPeopleComponent.peopleSearch$.subscribe((users) => {
|
||||
peopleComponent.peopleSearch$.subscribe((users) => {
|
||||
expect(users.length).toBe(0);
|
||||
done();
|
||||
});
|
||||
activitiPeopleComponent.searchUser('fake-search-word');
|
||||
peopleComponent.searchUser('fake-search-word');
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
status: 200,
|
||||
contentType: 'json',
|
||||
@@ -174,7 +174,7 @@ describe('PeopleComponent', () => {
|
||||
describe('when there are errors on service call', () => {
|
||||
beforeEach(() => {
|
||||
jasmine.Ajax.install();
|
||||
activitiPeopleComponent.people.push(...userArray);
|
||||
peopleComponent.people.push(...userArray);
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
@@ -183,7 +183,7 @@ describe('PeopleComponent', () => {
|
||||
});
|
||||
|
||||
it('should not remove user if remove involved user fail', async () => {
|
||||
activitiPeopleComponent.removeInvolvedUser(fakeUser);
|
||||
peopleComponent.removeInvolvedUser(fakeUser);
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
status: 403
|
||||
});
|
||||
@@ -194,7 +194,7 @@ describe('PeopleComponent', () => {
|
||||
});
|
||||
|
||||
it('should not involve user if involve user fail', async () => {
|
||||
activitiPeopleComponent.involveUser(fakeUser);
|
||||
peopleComponent.involveUser(fakeUser);
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
status: 403
|
||||
});
|
||||
|
@@ -20,11 +20,19 @@ import { Observable, Observer } from 'rxjs';
|
||||
import { UserEventModel } from '../../../task-list/models/user-event.model';
|
||||
import { PeopleSearchComponent } from '../people-search/people-search.component';
|
||||
import { share } 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';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { DataTableModule } from '@alfresco/adf-core';
|
||||
import { PeopleListComponent } from '../people-list/people-list.component';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-people',
|
||||
standalone: true,
|
||||
imports: [CommonModule, MatCardModule, TranslateModule, MatIconModule, DataTableModule, PeopleSearchComponent, PeopleListComponent],
|
||||
templateUrl: './people.component.html',
|
||||
styleUrls: ['./people.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
@@ -32,7 +40,7 @@ import { PeopleProcessService } from '../../../common/services/people-process.se
|
||||
export class PeopleComponent {
|
||||
/** The array of User objects to display. */
|
||||
@Input()
|
||||
people: UserProcessModel[] = [];
|
||||
people: LightUserRepresentation[] = [];
|
||||
|
||||
/** The numeric ID of the task. */
|
||||
@Input()
|
||||
@@ -49,24 +57,12 @@ export class PeopleComponent {
|
||||
error = new EventEmitter<any>();
|
||||
|
||||
showAssignment: boolean = false;
|
||||
peopleSearch$: Observable<UserProcessModel[]>;
|
||||
peopleSearch$: Observable<LightUserRepresentation[]>;
|
||||
|
||||
private peopleSearchObserver: Observer<UserProcessModel[]>;
|
||||
private peopleSearchObserver: Observer<LightUserRepresentation[]>;
|
||||
|
||||
constructor(public peopleProcessService: PeopleProcessService) {
|
||||
this.peopleSearch$ = new Observable<UserProcessModel[]>((observer) => (this.peopleSearchObserver = observer)).pipe(share());
|
||||
}
|
||||
|
||||
involveUserAndCloseSearch() {
|
||||
if (this.peopleSearch) {
|
||||
this.peopleSearch.involveUserAndClose();
|
||||
}
|
||||
}
|
||||
|
||||
involveUserWithoutCloseSearch() {
|
||||
if (this.peopleSearch) {
|
||||
this.peopleSearch.involveUser();
|
||||
}
|
||||
this.peopleSearch$ = new Observable<LightUserRepresentation[]>((observer) => (this.peopleSearchObserver = observer)).pipe(share());
|
||||
}
|
||||
|
||||
searchUser(searchedWord: string) {
|
||||
@@ -78,8 +74,8 @@ export class PeopleComponent {
|
||||
);
|
||||
}
|
||||
|
||||
involveUser(user: UserProcessModel) {
|
||||
if (user?.id) {
|
||||
involveUser(user: LightUserRepresentation) {
|
||||
if (user?.id !== undefined) {
|
||||
this.peopleProcessService.involveUserWithTask(this.taskId, user.id.toString()).subscribe(
|
||||
() => (this.people = [...this.people, user]),
|
||||
() => this.error.emit('Impossible to involve user with task')
|
||||
@@ -87,7 +83,7 @@ export class PeopleComponent {
|
||||
}
|
||||
}
|
||||
|
||||
removeInvolvedUser(user: UserProcessModel) {
|
||||
removeInvolvedUser(user: LightUserRepresentation) {
|
||||
this.peopleProcessService.removeInvolvedUser(this.taskId, user.id.toString()).subscribe(
|
||||
() => {
|
||||
this.people = this.people.filter((involvedUser) => involvedUser.id !== user.id);
|
||||
|
@@ -1,25 +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 { Directive } from '@angular/core';
|
||||
|
||||
/**
|
||||
* Directive selectors without adf- prefix will be deprecated on 3.0.0
|
||||
*/
|
||||
// eslint-disable-next-line @angular-eslint/directive-selector
|
||||
@Directive({ selector: 'adf-people-search-action-label, people-search-action-label' })
|
||||
export class PeopleSearchActionLabelDirective { }
|
@@ -1,25 +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 { Directive } from '@angular/core';
|
||||
|
||||
/**
|
||||
* Directive selectors without adf- prefix will be deprecated on 3.0.0
|
||||
*/
|
||||
// eslint-disable-next-line @angular-eslint/directive-selector
|
||||
@Directive({ selector: '[adf-people-search-title]' })
|
||||
export class PeopleSearchTitleDirective { }
|
@@ -16,6 +16,6 @@
|
||||
*/
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import { UserProcessModel } from '../../common/models/user-process.model';
|
||||
import { LightUserRepresentation } from '@alfresco/js-api';
|
||||
|
||||
export type PerformSearchCallback = (searchWord: string) => Observable<UserProcessModel[]>;
|
||||
export type PerformSearchCallback = (searchWord: string) => Observable<LightUserRepresentation[]>;
|
||||
|
@@ -15,47 +15,15 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { MaterialModule } from '../material.module';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
|
||||
import { CoreModule } from '@alfresco/adf-core';
|
||||
import { PeopleComponent } from './components/people/people.component';
|
||||
import { PeopleListComponent } from './components/people-list/people-list.component';
|
||||
import { PeopleSearchComponent } from './components/people-search/people-search.component';
|
||||
import { PeopleSearchFieldComponent } from './components/people-search-field/people-search-field.component';
|
||||
import { PeopleSelectorComponent } from './components/people-selector/people-selector.component';
|
||||
|
||||
import { PeopleSearchActionLabelDirective } from './directives/people-search-action-label.directive';
|
||||
import { PeopleSearchTitleDirective } from './directives/people-search-title.directive';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
MaterialModule,
|
||||
CommonModule,
|
||||
CoreModule
|
||||
],
|
||||
declarations: [
|
||||
PeopleComponent,
|
||||
PeopleSearchComponent,
|
||||
PeopleSearchFieldComponent,
|
||||
PeopleSelectorComponent,
|
||||
PeopleSearchTitleDirective,
|
||||
PeopleSearchActionLabelDirective,
|
||||
PeopleListComponent
|
||||
],
|
||||
exports: [
|
||||
PeopleComponent,
|
||||
PeopleSearchComponent,
|
||||
PeopleSearchFieldComponent,
|
||||
PeopleSelectorComponent,
|
||||
PeopleSearchTitleDirective,
|
||||
PeopleSearchActionLabelDirective,
|
||||
PeopleListComponent
|
||||
]
|
||||
imports: [PeopleComponent, PeopleSearchComponent, PeopleSearchFieldComponent, PeopleSelectorComponent, PeopleListComponent],
|
||||
exports: [PeopleComponent, PeopleSearchComponent, PeopleSearchFieldComponent, PeopleSelectorComponent, PeopleListComponent]
|
||||
})
|
||||
export class PeopleModule {
|
||||
}
|
||||
export class PeopleModule {}
|
||||
|
@@ -23,7 +23,4 @@ export * from './components/people-selector/people-selector.component';
|
||||
|
||||
export * from './interfaces/perform-search-callback.interface';
|
||||
|
||||
export * from './directives/people-search-action-label.directive';
|
||||
export * from './directives/people-search-title.directive';
|
||||
|
||||
export * from './people.module';
|
||||
|
@@ -15,4 +15,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './public-api';
|
||||
export * from './process-comments.component';
|
||||
export * from './services/comment-process.service';
|
||||
export * from './process-comments.module';
|
||||
|
@@ -18,34 +18,38 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable, from, of } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { CommentModel, UserProcessModel, CommentsService } from '@alfresco/adf-core';
|
||||
import { fakeUser1 } from '../mock/comment-process.mock';
|
||||
import { CommentModel, CommentsService } from '@alfresco/adf-core';
|
||||
|
||||
export const fakeUser1 = { id: 1, email: 'fake-email@dom.com', firstName: 'firstName', lastName: 'lastName', avatarId: '0' };
|
||||
|
||||
@Injectable()
|
||||
export class CommentProcessServiceMock implements Partial<CommentsService> {
|
||||
private comments: CommentModel [] = [];
|
||||
private comments: CommentModel[] = [];
|
||||
|
||||
get(_id: string): Observable<CommentModel[]> {
|
||||
const user = new UserProcessModel(fakeUser1);
|
||||
|
||||
this.comments.push(new CommentModel({
|
||||
id: 46,
|
||||
message: 'Hello from Process Model',
|
||||
created: new Date('2022-08-02T03:37:30.010+0000'),
|
||||
createdBy: user
|
||||
}));
|
||||
this.comments.push(
|
||||
new CommentModel({
|
||||
id: 46,
|
||||
message: 'Hello from Process Model',
|
||||
created: new Date('2022-08-02T03:37:30.010+0000'),
|
||||
createdBy: fakeUser1
|
||||
})
|
||||
);
|
||||
|
||||
return of(this.comments);
|
||||
}
|
||||
|
||||
add(_id: string, _message: string): Observable<CommentModel> {
|
||||
return from(this.comments).pipe(
|
||||
map((response) => new CommentModel({
|
||||
id: response.id,
|
||||
message: response.message,
|
||||
created: response.created,
|
||||
createdBy: response.createdBy
|
||||
}))
|
||||
map(
|
||||
(response) =>
|
||||
new CommentModel({
|
||||
id: response.id,
|
||||
message: response.message,
|
||||
created: response.created,
|
||||
createdBy: response.createdBy
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,40 +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 { EcmUserModel } from '@alfresco/adf-core';
|
||||
|
||||
export const fakeUser1 = { id: 1, email: 'fake-email@dom.com', firstName: 'firstName', lastName: 'lastName' };
|
||||
|
||||
export const testUser: EcmUserModel = {
|
||||
id: '44',
|
||||
email: 'test.user@hyland.com',
|
||||
firstName: 'Test',
|
||||
lastName: 'User',
|
||||
company: {
|
||||
organization: '',
|
||||
address1: '',
|
||||
address2: '',
|
||||
address3: '',
|
||||
postcode: '',
|
||||
telephone: '',
|
||||
fax: '',
|
||||
email: ''
|
||||
},
|
||||
enabled: true,
|
||||
isAdmin: undefined,
|
||||
avatarId: '044'
|
||||
};
|
@@ -1,15 +1,21 @@
|
||||
<div class="adf-comments-container">
|
||||
<div id="comment-header" class="adf-comments-header">
|
||||
{{'ADF_PROCESS_LIST.DETAILS.COMMENTS.HEADER' | translate: { count: comments?.length} }}
|
||||
{{ 'ADF_PROCESS_LIST.DETAILS.COMMENTS.HEADER' | translate : { count: comments?.length } }}
|
||||
</div>
|
||||
<div class="adf-comments-input-container" *ngIf="!isReadOnly()">
|
||||
<mat-form-field class="adf-full-width">
|
||||
<input matInput id="comment-input" placeholder="{{'ADF_PROCESS_LIST.DETAILS.COMMENTS.ADD' | translate}}" [(ngModel)]="message" (keyup.enter)="add()" (keyup.esc)="clear()">
|
||||
<input
|
||||
matInput
|
||||
id="comment-input"
|
||||
placeholder="{{ 'ADF_PROCESS_LIST.DETAILS.COMMENTS.ADD' | translate }}"
|
||||
[(ngModel)]="message"
|
||||
(keyup.enter)="add()"
|
||||
(keyup.escape)="clear()"
|
||||
/>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div *ngIf="comments.length > 0">
|
||||
<adf-comment-list [comments]="comments">
|
||||
</adf-comment-list>
|
||||
<adf-comment-list [comments]="comments"> </adf-comment-list>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -31,7 +31,7 @@ describe('ProcessCommentsComponent', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [ProcessTestingModule]
|
||||
imports: [ProcessTestingModule, ProcessCommentsComponent]
|
||||
});
|
||||
fixture = TestBed.createComponent(ProcessCommentsComponent);
|
||||
component = fixture.componentInstance;
|
||||
|
@@ -15,14 +15,27 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { CommentModel } from '@alfresco/adf-core';
|
||||
import { ADF_COMMENTS_SERVICE, CommentListModule, CommentModel } from '@alfresco/adf-core';
|
||||
import { CommentProcessService } from './services/comment-process.service';
|
||||
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges, OnDestroy, ViewEncapsulation } from '@angular/core';
|
||||
import { Observable, Observer, Subject } from 'rxjs';
|
||||
import { share, takeUntil } from 'rxjs/operators';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-process-instance-comments',
|
||||
standalone: true,
|
||||
imports: [CommonModule, TranslateModule, MatFormFieldModule, MatInputModule, CommentListModule, FormsModule],
|
||||
providers: [
|
||||
{
|
||||
provide: ADF_COMMENTS_SERVICE,
|
||||
useClass: CommentProcessService
|
||||
}
|
||||
],
|
||||
templateUrl: './process-comments.component.html',
|
||||
styleUrls: ['./process-comments.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
|
@@ -15,35 +15,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { MaterialModule } from '../material.module';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { ADF_COMMENTS_SERVICE, CoreModule } from '@alfresco/adf-core';
|
||||
|
||||
import { ProcessCommentsComponent } from './process-comments.component';
|
||||
import { CommentProcessService } from './services/comment-process.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
MaterialModule,
|
||||
CommonModule,
|
||||
CoreModule
|
||||
],
|
||||
declarations: [
|
||||
ProcessCommentsComponent
|
||||
],
|
||||
exports: [
|
||||
ProcessCommentsComponent
|
||||
],
|
||||
providers: [
|
||||
{
|
||||
provide: ADF_COMMENTS_SERVICE,
|
||||
useClass: CommentProcessService
|
||||
}
|
||||
]
|
||||
imports: [ProcessCommentsComponent],
|
||||
exports: [ProcessCommentsComponent]
|
||||
})
|
||||
export class ProcessCommentsModule {
|
||||
}
|
||||
export class ProcessCommentsModule {}
|
||||
|
@@ -1,22 +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.
|
||||
*/
|
||||
|
||||
export * from './process-comments.component';
|
||||
|
||||
export * from './services/comment-process.service';
|
||||
|
||||
export * from './process-comments.module';
|
@@ -21,7 +21,6 @@ import { CommentModel, AlfrescoApiService, CommentsService, User } from '@alfres
|
||||
import { map } from 'rxjs/operators';
|
||||
import { ActivitiCommentsApi } from '@alfresco/js-api';
|
||||
import { PeopleProcessService } from '../../common/services/people-process.service';
|
||||
import { UserProcessModel } from '../../common/models/user-process.model';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@@ -44,19 +43,14 @@ export class CommentProcessService implements CommentsService {
|
||||
get(id: string): Observable<CommentModel[]> {
|
||||
return from(this.commentsApi.getProcessInstanceComments(id)).pipe(
|
||||
map((response) => {
|
||||
const comments: CommentModel[] = [];
|
||||
response.data.forEach((comment) => {
|
||||
const user = new UserProcessModel(comment.createdBy);
|
||||
comments.push(
|
||||
new CommentModel({
|
||||
id: comment.id,
|
||||
message: comment.message,
|
||||
created: comment.created,
|
||||
createdBy: new User(user)
|
||||
})
|
||||
);
|
||||
return response.data.map((comment) => {
|
||||
return new CommentModel({
|
||||
id: comment.id,
|
||||
message: comment.message,
|
||||
created: comment.created,
|
||||
createdBy: new User(comment.createdBy)
|
||||
});
|
||||
});
|
||||
return comments;
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -82,7 +76,7 @@ export class CommentProcessService implements CommentsService {
|
||||
);
|
||||
}
|
||||
|
||||
getUserImage(user: UserProcessModel): string {
|
||||
return this.peopleProcessService.getUserImage(user);
|
||||
getUserImage(userId: string): string {
|
||||
return this.peopleProcessService.getUserImage(userId);
|
||||
}
|
||||
}
|
||||
|
@@ -21,13 +21,14 @@ import { of, throwError } from 'rxjs';
|
||||
import { ProcessService } from './../services/process.service';
|
||||
import { DownloadService } from '@alfresco/adf-core';
|
||||
import { ProcessTestingModule } from '../../testing/process.testing.module';
|
||||
import { ProcessInstanceAuditInfoRepresentation } from '@alfresco/js-api';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-basic-button',
|
||||
template: ` <button
|
||||
id="auditButton"
|
||||
adf-process-audit
|
||||
[process-id]="1234"
|
||||
[process-id]="'1234'"
|
||||
[download]="download"
|
||||
[fileName]="fileName"
|
||||
[format]="format"
|
||||
@@ -42,8 +43,12 @@ class BasicButtonComponent {
|
||||
fileName: string;
|
||||
format: string;
|
||||
|
||||
onAuditClick() {}
|
||||
onAuditError() {}
|
||||
onAuditClick(_event: any) {
|
||||
/* do nothing */
|
||||
}
|
||||
onAuditError(_event: any) {
|
||||
/* do nothing */
|
||||
}
|
||||
}
|
||||
|
||||
describe('ProcessAuditDirective', () => {
|
||||
@@ -140,11 +145,11 @@ describe('ProcessAuditDirective', () => {
|
||||
component.fileName = 'FakeAuditName';
|
||||
component.format = 'json';
|
||||
component.download = true;
|
||||
const auditJson = {
|
||||
processInstanceId: 42516,
|
||||
const auditJson: ProcessInstanceAuditInfoRepresentation = {
|
||||
processInstanceId: '42516',
|
||||
processInstanceName: 'Fake Process - August 3rd 2017',
|
||||
processDefinitionName: 'Claim Approval Process',
|
||||
processDefinitionVersion: 1,
|
||||
processDefinitionVersion: '1',
|
||||
processInstanceStartTime: 'Thu Aug 03 15:32:47 UTC 2017',
|
||||
processInstanceEndTime: null,
|
||||
// eslint-disable-next-line @cspell/spellchecker
|
||||
|
@@ -17,18 +17,37 @@
|
||||
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, SimpleChange } from '@angular/core';
|
||||
import { from, of, throwError } from 'rxjs';
|
||||
import { FilterProcessRepresentationModel } from '../models/filter-process.model';
|
||||
import { AppsProcessService } from '../../app-list/services/apps-process.service';
|
||||
import { ProcessFilterService } from '../services/process-filter.service';
|
||||
import { ProcessFiltersComponent } from './process-filters.component';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { fakeProcessFilters } from '../../mock/process/process-filters.mock';
|
||||
import { ProcessTestingModule } from '../../testing/process.testing.module';
|
||||
import { NavigationStart, Router } from '@angular/router';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { ProcessInstanceFilterRepresentation, UserProcessInstanceFilterRepresentation } from '@alfresco/js-api';
|
||||
|
||||
const fakeProcessFilters: UserProcessInstanceFilterRepresentation[] = [
|
||||
{
|
||||
id: 10,
|
||||
name: 'FakeCompleted',
|
||||
icon: 'glyphicon-th',
|
||||
filter: { state: 'open', assignment: 'fake-involved' }
|
||||
},
|
||||
{
|
||||
id: 20,
|
||||
name: 'FakeAll',
|
||||
icon: 'glyphicon-random',
|
||||
filter: { state: 'open', assignment: 'fake-assignee' }
|
||||
},
|
||||
{
|
||||
id: 30,
|
||||
name: 'Running',
|
||||
icon: 'glyphicon-ok-sign',
|
||||
filter: { state: 'open', assignment: 'fake-running' }
|
||||
}
|
||||
];
|
||||
|
||||
describe('ProcessFiltersComponent', () => {
|
||||
let filterList: ProcessFiltersComponent;
|
||||
let fixture: ComponentFixture<ProcessFiltersComponent>;
|
||||
@@ -95,7 +114,7 @@ describe('ProcessFiltersComponent', () => {
|
||||
|
||||
it('should emit the selected filter based on the filterParam input', async () => {
|
||||
spyOn(processFilterService, 'getProcessFilters').and.returnValue(of(fakeProcessFilters));
|
||||
filterList.filterParam = new FilterProcessRepresentationModel({ id: 10 });
|
||||
filterList.filterParam = { id: 10 } as any;
|
||||
const appId = '1';
|
||||
const change = new SimpleChange(null, appId, true);
|
||||
|
||||
@@ -130,7 +149,7 @@ describe('ProcessFiltersComponent', () => {
|
||||
const change = new SimpleChange(null, appId, true);
|
||||
|
||||
filterList.currentFilter = nonExistingFilterParam;
|
||||
filterList.filterParam = new FilterProcessRepresentationModel(nonExistingFilterParam);
|
||||
filterList.filterParam = nonExistingFilterParam as any;
|
||||
|
||||
filterList.ngOnChanges({ appId: change });
|
||||
fixture.detectChanges();
|
||||
@@ -180,11 +199,11 @@ describe('ProcessFiltersComponent', () => {
|
||||
});
|
||||
|
||||
it('should emit an event when a filter is selected', async () => {
|
||||
const currentFilter = new FilterProcessRepresentationModel({
|
||||
const currentFilter: UserProcessInstanceFilterRepresentation = {
|
||||
id: 10,
|
||||
name: 'FakeCompleted',
|
||||
filter: { state: 'open', assignment: 'fake-involved' }
|
||||
});
|
||||
};
|
||||
|
||||
let lastValue: UserProcessInstanceFilterRepresentation;
|
||||
filterList.filterClicked.subscribe((filter) => (lastValue = filter));
|
||||
@@ -226,10 +245,10 @@ describe('ProcessFiltersComponent', () => {
|
||||
});
|
||||
|
||||
it('should return the current filter after one is selected', () => {
|
||||
const filter = new FilterProcessRepresentationModel({
|
||||
const filter: UserProcessInstanceFilterRepresentation = {
|
||||
name: 'FakeAll',
|
||||
filter: { state: 'open', assignment: 'fake-assignee' }
|
||||
});
|
||||
};
|
||||
expect(filterList.currentFilter).toBeUndefined();
|
||||
filterList.selectFilter(filter);
|
||||
expect(filterList.getCurrentFilter()).toBe(filter);
|
||||
@@ -238,7 +257,7 @@ describe('ProcessFiltersComponent', () => {
|
||||
it('should select the filter passed as input by id', async () => {
|
||||
spyOn(processFilterService, 'getProcessFilters').and.returnValue(of(fakeProcessFilters));
|
||||
|
||||
filterList.filterParam = new FilterProcessRepresentationModel({ id: 20 });
|
||||
filterList.filterParam = { id: 20 } as any;
|
||||
|
||||
const appId = 1;
|
||||
const change = new SimpleChange(null, appId, true);
|
||||
@@ -255,7 +274,7 @@ describe('ProcessFiltersComponent', () => {
|
||||
it('should select the filter passed as input by name', async () => {
|
||||
spyOn(processFilterService, 'getProcessFilters').and.returnValue(of(fakeProcessFilters));
|
||||
|
||||
filterList.filterParam = new FilterProcessRepresentationModel({ name: 'FakeAll' });
|
||||
filterList.filterParam = { name: 'FakeAll' } as any;
|
||||
|
||||
const appId = 1;
|
||||
const change = new SimpleChange(null, appId, true);
|
||||
|
@@ -17,8 +17,7 @@
|
||||
|
||||
import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges, ViewEncapsulation } from '@angular/core';
|
||||
import { ProcessInstanceFilterRepresentation, UserProcessInstanceFilterRepresentation } from '@alfresco/js-api';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { FilterProcessRepresentationModel } from '../models/filter-process.model';
|
||||
import { Subject } from 'rxjs';
|
||||
import { ProcessFilterService } from './../services/process-filter.service';
|
||||
import { AppsProcessService } from '../../app-list/services/apps-process.service';
|
||||
import { IconModel } from '../../app-list/icon.model';
|
||||
@@ -38,7 +37,7 @@ export class ProcessFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
* (ie, the first filter in the list) is selected.
|
||||
*/
|
||||
@Input()
|
||||
filterParam: FilterProcessRepresentationModel;
|
||||
filterParam: UserProcessInstanceFilterRepresentation;
|
||||
|
||||
/** Emitted when a filter is being clicked from the UI. */
|
||||
@Output()
|
||||
@@ -62,14 +61,12 @@ export class ProcessFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
/** Toggle to show or hide the filter's icon. */
|
||||
@Input()
|
||||
showIcon: boolean = true;
|
||||
showIcon = true;
|
||||
|
||||
/** Emitted when a filter is being selected based on the filterParam input. */
|
||||
@Output()
|
||||
filterSelected = new EventEmitter<UserProcessInstanceFilterRepresentation>();
|
||||
|
||||
filter$: Observable<ProcessInstanceFilterRepresentation>;
|
||||
|
||||
currentFilter: ProcessInstanceFilterRepresentation;
|
||||
|
||||
filters: UserProcessInstanceFilterRepresentation[] = [];
|
||||
@@ -186,7 +183,7 @@ export class ProcessFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
*
|
||||
* @param filterParam filter parameter
|
||||
*/
|
||||
selectProcessFilter(filterParam: FilterProcessRepresentationModel): void {
|
||||
selectProcessFilter(filterParam: UserProcessInstanceFilterRepresentation): void {
|
||||
if (filterParam) {
|
||||
const newFilter = this.filters.find(
|
||||
(processFilter, index) =>
|
||||
@@ -211,16 +208,6 @@ export class ProcessFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
this.selectProcessFilter(this.processFilterService.getRunningFilterInstance(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Select as default task filter the first in the list
|
||||
*/
|
||||
selectDefaultTaskFilter() {
|
||||
if (!this.isFilterListEmpty()) {
|
||||
this.currentFilter = this.filters[0];
|
||||
this.filterSelected.emit(this.filters[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current task
|
||||
*
|
||||
|
@@ -18,11 +18,10 @@
|
||||
import { DatePipe } from '@angular/common';
|
||||
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges, ViewChild } from '@angular/core';
|
||||
import { TaskDetailsEvent } from '../../task-list';
|
||||
|
||||
import { ProcessInstance } from '../models/process-instance.model';
|
||||
import { ProcessService } from './../services/process.service';
|
||||
import { ProcessInstanceHeaderComponent } from './process-instance-header.component';
|
||||
import { ProcessInstanceTasksComponent } from './process-instance-tasks.component';
|
||||
import { ProcessInstanceRepresentation } from '@alfresco/js-api';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-process-instance-details',
|
||||
@@ -64,9 +63,9 @@ export class ProcessInstanceDetailsComponent implements OnChanges {
|
||||
@Output()
|
||||
showProcessDiagram = new EventEmitter<any>();
|
||||
|
||||
processInstanceDetails: ProcessInstance;
|
||||
processInstanceDetails: ProcessInstanceRepresentation;
|
||||
|
||||
constructor(private activitiProcess: ProcessService) {}
|
||||
constructor(private processService: ProcessService) {}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
const processInstanceId = changes['processInstanceId'];
|
||||
@@ -89,7 +88,7 @@ export class ProcessInstanceDetailsComponent implements OnChanges {
|
||||
|
||||
load(processId: string) {
|
||||
if (processId) {
|
||||
this.activitiProcess.getProcess(processId).subscribe((res) => {
|
||||
this.processService.getProcess(processId).subscribe((res) => {
|
||||
this.processInstanceDetails = res;
|
||||
});
|
||||
}
|
||||
@@ -100,7 +99,7 @@ export class ProcessInstanceDetailsComponent implements OnChanges {
|
||||
}
|
||||
|
||||
cancelProcess() {
|
||||
this.activitiProcess.cancelProcess(this.processInstanceId).subscribe(
|
||||
this.processService.cancelProcess(this.processInstanceId).subscribe(
|
||||
(data) => {
|
||||
this.processCancelled.emit(data);
|
||||
},
|
||||
|
@@ -17,7 +17,6 @@
|
||||
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { AppConfigService } from '@alfresco/adf-core';
|
||||
import { ProcessInstance } from '../models/process-instance.model';
|
||||
import { exampleProcess } from '../../mock';
|
||||
import { ProcessInstanceHeaderComponent } from './process-instance-header.component';
|
||||
import { ProcessTestingModule } from '../../testing/process.testing.module';
|
||||
@@ -34,7 +33,7 @@ describe('ProcessInstanceHeaderComponent', () => {
|
||||
fixture = TestBed.createComponent(ProcessInstanceHeaderComponent);
|
||||
component = fixture.componentInstance;
|
||||
|
||||
component.processInstance = new ProcessInstance(exampleProcess);
|
||||
component.processInstance = exampleProcess;
|
||||
|
||||
appConfigService = TestBed.inject(AppConfigService);
|
||||
appConfigService.config['adf-process-instance-header'] = {};
|
||||
|
@@ -24,7 +24,7 @@ import {
|
||||
TranslationService
|
||||
} from '@alfresco/adf-core';
|
||||
import { Component, Input, OnChanges } from '@angular/core';
|
||||
import { ProcessInstance } from '../models/process-instance.model';
|
||||
import { ProcessInstanceRepresentation } from '@alfresco/js-api';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-process-instance-header',
|
||||
@@ -34,7 +34,7 @@ import { ProcessInstance } from '../models/process-instance.model';
|
||||
export class ProcessInstanceHeaderComponent implements OnChanges {
|
||||
/** (**required**) Full details of the process instance to display information about. */
|
||||
@Input()
|
||||
processInstance: ProcessInstance;
|
||||
processInstance: ProcessInstanceRepresentation;
|
||||
|
||||
properties: CardViewItem[];
|
||||
dateFormat: string;
|
||||
|
@@ -21,13 +21,13 @@ import { By } from '@angular/platform-browser';
|
||||
import { of } from 'rxjs';
|
||||
import { TaskDetailsModel } from '../../task-list';
|
||||
import { taskDetailsMock } from '../../mock';
|
||||
import { ProcessInstance } from './../models/process-instance.model';
|
||||
import { ProcessService } from './../services/process.service';
|
||||
import { ProcessInstanceTasksComponent } from './process-instance-tasks.component';
|
||||
import { ProcessTestingModule } from '../../testing/process.testing.module';
|
||||
import { HarnessLoader } from '@angular/cdk/testing';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { MatListItemHarness } from '@angular/material/list/testing';
|
||||
import { ProcessInstanceRepresentation } from '@alfresco/js-api';
|
||||
|
||||
describe('ProcessInstanceTasksComponent', () => {
|
||||
let component: ProcessInstanceTasksComponent;
|
||||
@@ -35,7 +35,7 @@ describe('ProcessInstanceTasksComponent', () => {
|
||||
let loader: HarnessLoader;
|
||||
let processService: ProcessService;
|
||||
|
||||
const exampleProcessInstance = new ProcessInstance({ id: '123' });
|
||||
const exampleProcessInstance: ProcessInstanceRepresentation = { id: '123' };
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
|
@@ -20,9 +20,9 @@ import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChange
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { Observable, Observer, Subject } from 'rxjs';
|
||||
import { TaskDetailsEvent, TaskDetailsModel } from '../../task-list';
|
||||
import { ProcessInstance } from '../models/process-instance.model';
|
||||
import { ProcessService } from './../services/process.service';
|
||||
import { share, takeUntil } from 'rxjs/operators';
|
||||
import { ProcessInstanceRepresentation } from '@alfresco/js-api';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-process-instance-tasks',
|
||||
@@ -32,7 +32,7 @@ import { share, takeUntil } from 'rxjs/operators';
|
||||
export class ProcessInstanceTasksComponent implements OnInit, OnChanges, OnDestroy {
|
||||
/** The ID of the process instance to display tasks for. */
|
||||
@Input()
|
||||
processInstanceDetails: ProcessInstance;
|
||||
processInstanceDetails: ProcessInstanceRepresentation;
|
||||
|
||||
/**
|
||||
* Toggles whether to show a refresh button next to the list of tasks to allow
|
||||
|
@@ -1,4 +1,4 @@
|
||||
<adf-datatable #dataTable
|
||||
<adf-datatable
|
||||
[data]="data"
|
||||
[rows]="rows"
|
||||
[columns]="columns"
|
||||
|
@@ -31,15 +31,36 @@ import {
|
||||
DEFAULT_PAGINATION
|
||||
} from '@alfresco/adf-core';
|
||||
import { AfterContentInit, Component, ContentChild, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
|
||||
import { ProcessFilterParamRepresentationModel } from '../models/filter-process.model';
|
||||
import { processPresetsDefaultModel } from '../models/process-preset.model';
|
||||
import { ProcessService } from '../services/process.service';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { ProcessListModel } from '../models/process-list.model';
|
||||
import { finalize } from 'rxjs/operators';
|
||||
import {
|
||||
ProcessInstanceQueryRepresentation,
|
||||
ProcessInstanceQueryRepresentationSort,
|
||||
ProcessInstanceQueryRepresentationState,
|
||||
ResultListDataRepresentationProcessInstanceRepresentation
|
||||
} from '@alfresco/js-api';
|
||||
|
||||
const PRESET_KEY = 'adf-process-list.presets';
|
||||
|
||||
export const processPresetsDefaultModel = {
|
||||
default: [
|
||||
{
|
||||
key: 'name',
|
||||
type: 'text',
|
||||
title: 'ADF_PROCESS_LIST.PROPERTIES.NAME',
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
key: 'created',
|
||||
type: 'text',
|
||||
title: 'ADF_PROCESS_LIST.PROPERTIES.CREATED',
|
||||
cssClass: 'hidden',
|
||||
sortable: true
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
@Component({
|
||||
selector: 'adf-process-instance-list',
|
||||
styleUrls: ['./process-list.component.css'],
|
||||
@@ -62,18 +83,17 @@ export class ProcessInstanceListComponent extends DataTableSchema implements OnC
|
||||
|
||||
/** The id of the process instance. */
|
||||
@Input()
|
||||
processInstanceId: number | string;
|
||||
processInstanceId: string;
|
||||
|
||||
/** Defines the state of the processes. Possible values are `running`, `completed` and `all` */
|
||||
/** Defines the state of the processes. */
|
||||
@Input()
|
||||
state: string;
|
||||
state: ProcessInstanceQueryRepresentationState;
|
||||
|
||||
/**
|
||||
* Defines the sort ordering of the list. Possible values are `created-desc`, `created-asc`,
|
||||
* `ended-desc`, `ended-asc`.
|
||||
* Defines the sort ordering of the list.
|
||||
*/
|
||||
@Input()
|
||||
sort: string;
|
||||
sort: ProcessInstanceQueryRepresentationSort;
|
||||
|
||||
/** The page number of the processes to fetch. */
|
||||
@Input()
|
||||
@@ -137,14 +157,14 @@ export class ProcessInstanceListComponent extends DataTableSchema implements OnC
|
||||
/** Emitted when the list of process instances has been loaded successfully from the server. */
|
||||
// eslint-disable-next-line @angular-eslint/no-output-native
|
||||
@Output()
|
||||
success = new EventEmitter<ProcessListModel>();
|
||||
success = new EventEmitter<ResultListDataRepresentationProcessInstanceRepresentation>();
|
||||
|
||||
/** Emitted when an error occurs while loading the list of process instances from the server. */
|
||||
// eslint-disable-next-line @angular-eslint/no-output-native
|
||||
@Output()
|
||||
error = new EventEmitter<any>();
|
||||
|
||||
requestNode: ProcessFilterParamRepresentationModel;
|
||||
requestNode: ProcessInstanceQueryRepresentation;
|
||||
currentInstanceId: string;
|
||||
isLoading: boolean = true;
|
||||
rows: any[] = [];
|
||||
@@ -271,8 +291,8 @@ export class ProcessInstanceListComponent extends DataTableSchema implements OnC
|
||||
return skipCount && maxItems ? Math.floor(skipCount / maxItems) : 0;
|
||||
}
|
||||
|
||||
private createRequestNode(): ProcessFilterParamRepresentationModel {
|
||||
return new ProcessFilterParamRepresentationModel({
|
||||
private createRequestNode(): ProcessInstanceQueryRepresentation {
|
||||
return {
|
||||
appDefinitionId: this.appId,
|
||||
processDefinitionId: this.processDefinitionId,
|
||||
processInstanceId: this.processInstanceId,
|
||||
@@ -281,7 +301,7 @@ export class ProcessInstanceListComponent extends DataTableSchema implements OnC
|
||||
page: this.page,
|
||||
size: this.size,
|
||||
start: 0
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
private isSortChanged(changes: SimpleChanges): boolean {
|
||||
@@ -318,7 +338,7 @@ export class ProcessInstanceListComponent extends DataTableSchema implements OnC
|
||||
return changed;
|
||||
}
|
||||
|
||||
private load(requestNode: ProcessFilterParamRepresentationModel) {
|
||||
private load(requestNode: ProcessInstanceQueryRepresentation) {
|
||||
this.isLoading = true;
|
||||
this.processService
|
||||
.getProcesses(requestNode)
|
||||
@@ -329,7 +349,7 @@ export class ProcessInstanceListComponent extends DataTableSchema implements OnC
|
||||
this.selectFirst();
|
||||
this.success.emit(response);
|
||||
this.pagination.next({
|
||||
count: response.data.length,
|
||||
count: (response.data || []).length,
|
||||
maxItems: this.size,
|
||||
skipCount: this.page * this.size,
|
||||
totalItems: response.total
|
||||
|
@@ -50,7 +50,7 @@
|
||||
*ngIf="showSelectProcessDropdown"
|
||||
mat-icon-button
|
||||
(click)="displayDropdown($event)"
|
||||
[disabled]="disableDropdownButton()"
|
||||
[disabled]="isDropdownDisabled()"
|
||||
[attr.aria-label]="'ADF_PROCESS_LIST.START_PROCESS.FORM.LABEL.TYPE' | translate | uppercase">
|
||||
<mat-icon>arrow_drop_down</mat-icon>
|
||||
</button>
|
||||
|
@@ -21,7 +21,6 @@ import { AppConfigService } from '@alfresco/adf-core';
|
||||
import { AppsProcessService } from '../../app-list/services/apps-process.service';
|
||||
import { of, throwError } from 'rxjs';
|
||||
import { MatSelectChange } from '@angular/material/select';
|
||||
import { ProcessInstanceVariable } from '../models/process-instance-variable.model';
|
||||
import { ProcessService } from '../services/process.service';
|
||||
import { newProcess, taskFormMock, testProcessDef, testMultipleProcessDefs, testProcessDefWithForm, testProcessDefinitions } from '../../mock';
|
||||
import { StartProcessInstanceComponent } from './start-process.component';
|
||||
@@ -32,6 +31,7 @@ import { HarnessLoader } from '@angular/cdk/testing';
|
||||
import { MatFormFieldHarness } from '@angular/material/form-field/testing';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { MatAutocompleteHarness } from '@angular/material/autocomplete/testing';
|
||||
import { RestVariable } from '@alfresco/js-api';
|
||||
|
||||
describe('StartProcessComponent', () => {
|
||||
let appConfig: AppConfigService;
|
||||
@@ -358,7 +358,7 @@ describe('StartProcessComponent', () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(component.selectedProcessDef.name).not.toBeDefined();
|
||||
expect(component.selectedProcessDef).toBeUndefined();
|
||||
});
|
||||
|
||||
describe('dropdown', () => {
|
||||
@@ -468,9 +468,9 @@ describe('StartProcessComponent', () => {
|
||||
});
|
||||
|
||||
it('should call service to start process with the variables setted', async () => {
|
||||
const inputProcessVariable: ProcessInstanceVariable[] = [];
|
||||
const inputProcessVariable: RestVariable[] = [];
|
||||
|
||||
const variable: ProcessInstanceVariable = {};
|
||||
const variable: RestVariable = {};
|
||||
variable.name = 'nodeId';
|
||||
variable.value = 'id';
|
||||
|
||||
|
@@ -18,9 +18,6 @@
|
||||
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild, ViewEncapsulation, OnDestroy } from '@angular/core';
|
||||
import { AppConfigService, AppConfigValues, FormValues, LocalizedDatePipe } from '@alfresco/adf-core';
|
||||
import { AppsProcessService } from '../../app-list/services/apps-process.service';
|
||||
import { ProcessInstanceVariable } from '../models/process-instance-variable.model';
|
||||
import { ProcessDefinitionRepresentation } from './../models/process-definition.model';
|
||||
import { ProcessInstance } from './../models/process-instance.model';
|
||||
import { ProcessService } from './../services/process.service';
|
||||
import { UntypedFormControl, Validators, AbstractControl } from '@angular/forms';
|
||||
import { Observable, Subject, forkJoin } from 'rxjs';
|
||||
@@ -28,8 +25,14 @@ import { map, takeUntil } from 'rxjs/operators';
|
||||
import { MatAutocompleteTrigger } from '@angular/material/autocomplete';
|
||||
import { MatSelectChange } from '@angular/material/select';
|
||||
import { StartFormComponent } from '../../form';
|
||||
import { Node, RelatedContentRepresentation } from '@alfresco/js-api';
|
||||
import { AppDefinitionRepresentationModel } from '../../task-list';
|
||||
import {
|
||||
AppDefinitionRepresentation,
|
||||
Node,
|
||||
ProcessInstanceRepresentation,
|
||||
RelatedContentRepresentation,
|
||||
ProcessDefinitionRepresentation,
|
||||
RestVariable
|
||||
} from '@alfresco/js-api';
|
||||
import { ActivitiContentService } from '../../form/services/activiti-alfresco.service';
|
||||
import { getTime } from 'date-fns';
|
||||
|
||||
@@ -64,7 +67,7 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
* [RestVariable](https://github.com/Alfresco/alfresco-js-api/tree/master/src/alfresco-activiti-rest-api/docs/RestVariable.md).
|
||||
*/
|
||||
@Input()
|
||||
variables: ProcessInstanceVariable[];
|
||||
variables: RestVariable[];
|
||||
|
||||
/** Parameter to pass form field values in the start form if one is associated. */
|
||||
@Input()
|
||||
@@ -76,23 +79,23 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
|
||||
/** Hide or show the process selection dropdown. */
|
||||
@Input()
|
||||
showSelectProcessDropdown: boolean = true;
|
||||
showSelectProcessDropdown = true;
|
||||
|
||||
/** Hide or show application selection dropdown. */
|
||||
@Input()
|
||||
showSelectApplicationDropdown?: boolean = false;
|
||||
showSelectApplicationDropdown? = false;
|
||||
|
||||
/** Parameter to enable selection of process when filtering. */
|
||||
@Input()
|
||||
processFilterSelector?: boolean = true;
|
||||
processFilterSelector? = true;
|
||||
|
||||
/** Emitted when the process starts. */
|
||||
@Output()
|
||||
start = new EventEmitter<ProcessInstance>();
|
||||
start = new EventEmitter<ProcessInstanceRepresentation>();
|
||||
|
||||
/** Emitted when the process is canceled. */
|
||||
@Output()
|
||||
cancel: EventEmitter<void> = new EventEmitter<void>();
|
||||
cancel = new EventEmitter<void>();
|
||||
|
||||
/** Emitted when an error occurs. */
|
||||
@Output()
|
||||
@@ -104,7 +107,7 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
|
||||
/** Emitted when application selection changes. */
|
||||
@Output()
|
||||
applicationSelection = new EventEmitter<AppDefinitionRepresentationModel>();
|
||||
applicationSelection = new EventEmitter<AppDefinitionRepresentation>();
|
||||
|
||||
@ViewChild('startForm')
|
||||
startForm: StartFormComponent;
|
||||
@@ -119,17 +122,18 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
filteredProcessesDefinitions$: Observable<ProcessDefinitionRepresentation[]>;
|
||||
maxProcessNameLength: number = MAX_LENGTH;
|
||||
alfrescoRepositoryName: string;
|
||||
applications: AppDefinitionRepresentationModel[] = [];
|
||||
selectedApplication: AppDefinitionRepresentationModel;
|
||||
applications: AppDefinitionRepresentation[] = [];
|
||||
selectedApplication: AppDefinitionRepresentation;
|
||||
|
||||
isProcessDefinitionsLoading = true;
|
||||
isAppsLoading = true;
|
||||
movedNodeToPS: FormValues;
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
constructor(
|
||||
private activitiProcess: ProcessService,
|
||||
private activitiContentService: ActivitiContentService,
|
||||
private processService: ProcessService,
|
||||
private contentService: ActivitiContentService,
|
||||
private appsProcessService: AppsProcessService,
|
||||
private appConfig: AppConfigService,
|
||||
private datePipe: LocalizedDatePipe
|
||||
@@ -150,7 +154,7 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
takeUntil(this.onDestroy$)
|
||||
);
|
||||
|
||||
this.activitiContentService.getAlfrescoRepositories().subscribe((repoList) => {
|
||||
this.contentService.getAlfrescoRepositories().subscribe((repoList) => {
|
||||
if (repoList?.[0]) {
|
||||
const alfrescoRepository = repoList[0];
|
||||
this.alfrescoRepositoryName = `alfresco-${alfrescoRepository.id}-${alfrescoRepository.name}`;
|
||||
@@ -168,42 +172,37 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
this.moveNodeFromCStoPS();
|
||||
}
|
||||
|
||||
if (this.isAppIdChanged(changes)) {
|
||||
this.appId = changes['appId'].currentValue;
|
||||
this.load();
|
||||
const appId = changes['appId'];
|
||||
if (appId?.currentValue) {
|
||||
this.load(appId.currentValue);
|
||||
}
|
||||
|
||||
if (this.isProcessDefinitionChanged(changes)) {
|
||||
this.processDefinitionName = changes['processDefinitionName'].currentValue;
|
||||
this.filterProcessDefinitionByName();
|
||||
const processDefinitionName = changes['processDefinitionName'];
|
||||
if (processDefinitionName?.currentValue) {
|
||||
this.filterProcessDefinitionByName(processDefinitionName.currentValue);
|
||||
}
|
||||
}
|
||||
|
||||
getSelectedProcess(selectedProcess: string): ProcessDefinitionRepresentation {
|
||||
let processSelected = this.processDefinitions.find((process) => process.name.toLowerCase() === selectedProcess);
|
||||
|
||||
if (!processSelected) {
|
||||
processSelected = new ProcessDefinitionRepresentation();
|
||||
}
|
||||
return processSelected;
|
||||
private getSelectedProcess(selectedProcess: string): ProcessDefinitionRepresentation {
|
||||
return this.processDefinitions.find((process) => process.name.toLowerCase() === selectedProcess);
|
||||
}
|
||||
|
||||
load() {
|
||||
private load(appId?: number) {
|
||||
if (this.showSelectApplicationDropdown) {
|
||||
this.loadApps();
|
||||
} else {
|
||||
this.loadProcessDefinitions(this.appId);
|
||||
this.loadProcessDefinitions(appId);
|
||||
}
|
||||
}
|
||||
|
||||
loadProcessDefinitions(appId: any): void {
|
||||
loadProcessDefinitions(appId: number): void {
|
||||
this.isProcessDefinitionsLoading = true;
|
||||
this.resetSelectedProcessDefinition();
|
||||
|
||||
this.activitiProcess
|
||||
this.processService
|
||||
.getProcessDefinitions(appId)
|
||||
.pipe(
|
||||
map((processDefinitionRepresentations: ProcessDefinitionRepresentation[]) => {
|
||||
map((processDefinitionRepresentations) => {
|
||||
let currentProcessDef: ProcessDefinitionRepresentation;
|
||||
|
||||
if (processDefinitionRepresentations.length === 1) {
|
||||
@@ -236,9 +235,9 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
);
|
||||
}
|
||||
|
||||
filterProcessDefinitionByName() {
|
||||
if (this.processDefinitionName) {
|
||||
const filteredProcessDef = this.processDefinitions.find((processDefinition) => processDefinition.name === this.processDefinitionName);
|
||||
private filterProcessDefinitionByName(definitionName: string) {
|
||||
if (definitionName) {
|
||||
const filteredProcessDef = this.processDefinitions.find((processDefinition) => processDefinition.name === definitionName);
|
||||
|
||||
if (filteredProcessDef) {
|
||||
this.processDefinitionSelectionChanged(filteredProcessDef);
|
||||
@@ -247,14 +246,15 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
}
|
||||
}
|
||||
|
||||
loadApps() {
|
||||
private loadApps() {
|
||||
this.isAppsLoading = true;
|
||||
this.appsProcessService
|
||||
.getDeployedApplications()
|
||||
.pipe(
|
||||
map((response: AppDefinitionRepresentationModel[]) => {
|
||||
const applications = this.removeDefaultApps(response);
|
||||
let currentApplication: AppDefinitionRepresentationModel;
|
||||
map((response) => {
|
||||
const applications = response.filter((app) => app.id);
|
||||
|
||||
let currentApplication: AppDefinitionRepresentation;
|
||||
|
||||
if (applications && applications.length === 1) {
|
||||
currentApplication = applications[0];
|
||||
@@ -285,7 +285,7 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
);
|
||||
}
|
||||
|
||||
loadProcessDefinitionsBasedOnSelectedApp() {
|
||||
private loadProcessDefinitionsBasedOnSelectedApp() {
|
||||
if (this.selectedApplication?.id) {
|
||||
this.loadProcessDefinitions(this.selectedApplication ? this.selectedApplication.id : null);
|
||||
} else {
|
||||
@@ -314,11 +314,7 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
return !!this.selectedProcessDef?.id;
|
||||
}
|
||||
|
||||
isProcessDefinitionsEmpty(): boolean {
|
||||
return this.processDefinitions.length === 0;
|
||||
}
|
||||
|
||||
disableDropdownButton(): boolean {
|
||||
isDropdownDisabled(): boolean {
|
||||
return this.showSelectApplicationDropdown && !this.isAppSelected();
|
||||
}
|
||||
|
||||
@@ -338,7 +334,7 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
const currentValue = Array.isArray(this.values[key]) ? this.values[key] : [this.values[key]];
|
||||
const contents = currentValue
|
||||
.filter((value: any) => !!value?.isFile)
|
||||
.map((content: Node) => this.activitiContentService.applyAlfrescoNode(content, null, accountIdentifier));
|
||||
.map((content: Node) => this.contentService.applyAlfrescoNode(content, null, accountIdentifier));
|
||||
forkJoin(contents).subscribe((res: RelatedContentRepresentation[]) => {
|
||||
this.movedNodeToPS = { [key]: [...res] };
|
||||
});
|
||||
@@ -349,7 +345,7 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
startProcess(outcome?: string) {
|
||||
if (this.selectedProcessDef?.id && this.nameController.value) {
|
||||
const formValues = this.startForm ? this.startForm.form.values : undefined;
|
||||
this.activitiProcess.startProcess(this.selectedProcessDef.id, this.nameController.value, outcome, formValues, this.variables).subscribe(
|
||||
this.processService.startProcess(this.selectedProcessDef.id, this.nameController.value, outcome, formValues, this.variables).subscribe(
|
||||
(res) => {
|
||||
this.name = '';
|
||||
this.start.emit(res);
|
||||
@@ -369,7 +365,7 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
return this.selectedProcessDef?.hasStartForm;
|
||||
}
|
||||
|
||||
isStartFormMissingOrValid(): boolean {
|
||||
private isStartFormMissingOrValid(): boolean {
|
||||
if (this.startForm) {
|
||||
return this.startForm.form?.isValid;
|
||||
} else {
|
||||
@@ -404,7 +400,7 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
return undefined;
|
||||
}
|
||||
|
||||
displayDropdown(event) {
|
||||
displayDropdown(event: Event) {
|
||||
event.stopPropagation();
|
||||
if (!this.inputAutocomplete.panelOpen) {
|
||||
this.processDefinitionInput.setValue('');
|
||||
@@ -424,7 +420,7 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
|
||||
processDefinitionSelectionChanged(processDefinition: ProcessDefinitionRepresentation) {
|
||||
if (processDefinition) {
|
||||
const processInstanceDetails = new ProcessInstance({ processDefinitionName: processDefinition.name });
|
||||
const processInstanceDetails: ProcessInstanceRepresentation = { processDefinitionName: processDefinition.name };
|
||||
const processName = this.formatProcessName(this.name, processInstanceDetails);
|
||||
this.processNameInput.setValue(processName);
|
||||
this.processNameInput.markAsDirty();
|
||||
@@ -444,10 +440,6 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
return !!this.selectedApplication?.id;
|
||||
}
|
||||
|
||||
private removeDefaultApps(apps: AppDefinitionRepresentationModel[]): AppDefinitionRepresentationModel[] {
|
||||
return apps.filter((app) => app.id);
|
||||
}
|
||||
|
||||
private resetSelectedProcessDefinition() {
|
||||
this.selectedProcessDef = undefined;
|
||||
if (this.processDefinitionInput) {
|
||||
@@ -470,17 +462,6 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
}
|
||||
}
|
||||
|
||||
private isAppIdChanged(changes: SimpleChanges) {
|
||||
return changes['appId']?.currentValue && changes['appId'].currentValue !== changes['appId'].previousValue;
|
||||
}
|
||||
|
||||
private isProcessDefinitionChanged(changes: SimpleChanges) {
|
||||
return (
|
||||
changes['processDefinitionName']?.currentValue &&
|
||||
changes['processDefinitionName'].currentValue !== changes['processDefinitionName'].previousValue
|
||||
);
|
||||
}
|
||||
|
||||
private _filter(value: string): ProcessDefinitionRepresentation[] {
|
||||
if (value !== null && value !== undefined) {
|
||||
const filterValue = value.toLowerCase();
|
||||
@@ -495,7 +476,7 @@ export class StartProcessInstanceComponent implements OnChanges, OnInit, OnDestr
|
||||
return [];
|
||||
}
|
||||
|
||||
private formatProcessName(processNameFormat: string, processInstance?: ProcessInstance): string {
|
||||
private formatProcessName(processNameFormat: string, processInstance?: ProcessInstanceRepresentation): string {
|
||||
let processName = processNameFormat;
|
||||
if (processName.match(DATE_TIME_IDENTIFIER_REG_EXP)) {
|
||||
const presentDateTime = getTime(new Date());
|
||||
|
@@ -1,72 +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 {
|
||||
ProcessInstanceQueryRepresentation,
|
||||
ProcessInstanceFilterRepresentation,
|
||||
UserProcessInstanceFilterRepresentation
|
||||
} from '@alfresco/js-api';
|
||||
|
||||
export class FilterProcessRepresentationModel implements UserProcessInstanceFilterRepresentation {
|
||||
appId: number;
|
||||
filter: ProcessInstanceFilterRepresentation;
|
||||
icon: string;
|
||||
id: number;
|
||||
index: number;
|
||||
name: string;
|
||||
recent: boolean;
|
||||
|
||||
constructor(obj: any) {
|
||||
if (obj) {
|
||||
this.id = obj.id || null;
|
||||
this.appId = obj.appId || null;
|
||||
this.name = obj.name || null;
|
||||
this.recent = !!obj.recent;
|
||||
this.icon = obj.icon || null;
|
||||
this.filter = obj.filter || null;
|
||||
this.index = obj.index;
|
||||
}
|
||||
}
|
||||
|
||||
hasFilter() {
|
||||
return !!this.filter;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This object represent the parameters of a process filter.
|
||||
*/
|
||||
export class ProcessFilterParamRepresentationModel implements ProcessInstanceQueryRepresentation {
|
||||
|
||||
processDefinitionId?: string;
|
||||
processInstanceId?: string;
|
||||
appDefinitionId?: number;
|
||||
state?: any;
|
||||
sort?: any;
|
||||
page?: number;
|
||||
size?: number;
|
||||
|
||||
constructor(obj?: any) {
|
||||
this.processDefinitionId = obj.processDefinitionId || null;
|
||||
this.appDefinitionId = obj.appDefinitionId || null;
|
||||
this.processInstanceId = obj.processInstanceId || null;
|
||||
this.state = obj.state || null;
|
||||
this.sort = obj.sort || null;
|
||||
this.page = obj.page || null;
|
||||
this.size = obj.size || null;
|
||||
}
|
||||
}
|
@@ -1,42 +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.
|
||||
*/
|
||||
|
||||
export class ProcessDefinitionRepresentation {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
key: string;
|
||||
category: string;
|
||||
version: number;
|
||||
deploymentId: string;
|
||||
tenantId: string;
|
||||
metaDataValues: any[];
|
||||
hasStartForm: boolean;
|
||||
|
||||
constructor(obj?: any) {
|
||||
this.id = obj?.id;
|
||||
this.name = obj?.name;
|
||||
this.description = obj?.description;
|
||||
this.key = obj?.key;
|
||||
this.category = obj?.category;
|
||||
this.version = obj?.version || 0;
|
||||
this.deploymentId = obj?.deploymentId;
|
||||
this.tenantId = obj?.tenantId;
|
||||
this.metaDataValues = obj?.metaDataValues || [];
|
||||
this.hasStartForm = obj?.hasStartForm === true;
|
||||
}
|
||||
}
|
@@ -1,34 +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.
|
||||
*/
|
||||
|
||||
export class ProcessFilterRequestRepresentation {
|
||||
processDefinitionId: string;
|
||||
appDefinitionId: string;
|
||||
state: string;
|
||||
sort: string;
|
||||
page: number;
|
||||
size: number;
|
||||
|
||||
constructor(obj?: any) {
|
||||
this.processDefinitionId = obj?.processDefinitionId;
|
||||
this.appDefinitionId = obj?.appDefinitionId;
|
||||
this.state = obj?.state;
|
||||
this.sort = obj?.sort;
|
||||
this.page = obj?.page || 0;
|
||||
this.size = obj?.size || 25;
|
||||
}
|
||||
}
|
@@ -1,33 +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 { RestVariable } from '@alfresco/js-api';
|
||||
|
||||
export class ProcessInstanceVariable implements RestVariable {
|
||||
name?: string;
|
||||
scope?: string;
|
||||
type?: string;
|
||||
value?: string;
|
||||
valueUrl?: string;
|
||||
|
||||
constructor(obj?: any) {
|
||||
this.name = obj?.name;
|
||||
this.scope = obj?.scope;
|
||||
this.value = obj?.value;
|
||||
this.valueUrl = obj?.valueUrl;
|
||||
}
|
||||
}
|
@@ -1,58 +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 { LightUserRepresentation, ProcessInstanceRepresentation, RestVariable } from '@alfresco/js-api';
|
||||
|
||||
export class ProcessInstance implements ProcessInstanceRepresentation {
|
||||
businessKey?: string;
|
||||
ended?: Date;
|
||||
graphicalNotationDefined?: boolean;
|
||||
id?: string;
|
||||
name?: string;
|
||||
processDefinitionCategory?: string;
|
||||
processDefinitionDeploymentId?: string;
|
||||
processDefinitionDescription?: string;
|
||||
processDefinitionId?: string;
|
||||
processDefinitionKey?: string;
|
||||
processDefinitionName?: string;
|
||||
processDefinitionVersion?: number;
|
||||
startFormDefined?: boolean;
|
||||
started?: Date;
|
||||
startedBy?: LightUserRepresentation;
|
||||
tenantId?: string;
|
||||
variables?: RestVariable[];
|
||||
|
||||
constructor(data?: any) {
|
||||
this.businessKey = data?.businessKey;
|
||||
this.ended = data?.ended;
|
||||
this.graphicalNotationDefined = data?.graphicalNotationDefined;
|
||||
this.id = data?.id;
|
||||
this.name = data?.name;
|
||||
this.processDefinitionCategory = data?.processDefinitionCategory;
|
||||
this.processDefinitionDeploymentId = data?.processDefinitionDeploymentId;
|
||||
this.processDefinitionDescription = data?.processDefinitionDescription;
|
||||
this.processDefinitionId = data?.processDefinitionId;
|
||||
this.processDefinitionKey = data?.processDefinitionKey;
|
||||
this.processDefinitionName = data?.processDefinitionName;
|
||||
this.processDefinitionVersion = data?.processDefinitionVersion;
|
||||
this.startFormDefined = data?.startFormDefined;
|
||||
this.started = data?.started;
|
||||
this.startedBy = data?.startedBy;
|
||||
this.tenantId = data?.tenantId;
|
||||
this.variables = data?.variables;
|
||||
}
|
||||
}
|
@@ -1,37 +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 { ProcessInstance } from './process-instance.model';
|
||||
|
||||
export class ProcessListModel {
|
||||
size: number;
|
||||
total: number;
|
||||
start: number;
|
||||
length: number;
|
||||
data: ProcessInstance [];
|
||||
|
||||
constructor(obj?: any) {
|
||||
if (obj) {
|
||||
this.size = obj.size || null;
|
||||
this.total = obj.total || null;
|
||||
this.start = obj.start || null;
|
||||
this.length = obj.length || null;
|
||||
this.data = obj.data || [];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,34 +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.
|
||||
*/
|
||||
|
||||
export const processPresetsDefaultModel = {
|
||||
default: [
|
||||
{
|
||||
key: 'name',
|
||||
type: 'text',
|
||||
title: 'ADF_PROCESS_LIST.PROPERTIES.NAME',
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
key: 'created',
|
||||
type: 'text',
|
||||
title: 'ADF_PROCESS_LIST.PROPERTIES.CREATED',
|
||||
cssClass: 'hidden',
|
||||
sortable: true
|
||||
}
|
||||
]
|
||||
};
|
@@ -28,11 +28,4 @@ export * from './components/start-process.component';
|
||||
export * from './services/process.service';
|
||||
export * from './services/process-filter.service';
|
||||
|
||||
// models
|
||||
export * from './models/filter-process.model';
|
||||
export * from './models/process-definition.model';
|
||||
export * from './models/process-instance.model';
|
||||
export * from './models/process-instance-filter.model';
|
||||
export * from './models/process-instance-variable.model';
|
||||
|
||||
export * from './process-list.module';
|
||||
|
@@ -16,22 +16,34 @@
|
||||
*/
|
||||
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import {
|
||||
mockError,
|
||||
fakeProcessFiltersResponse,
|
||||
dummyRunningFilter,
|
||||
dummyAllFilter,
|
||||
dummyCompletedFilter,
|
||||
dummyDuplicateRunningFilter
|
||||
} from '../../mock';
|
||||
import { FilterProcessRepresentationModel } from '../models/filter-process.model';
|
||||
import { ProcessFilterService } from './process-filter.service';
|
||||
import { CoreTestingModule } from '@alfresco/adf-core';
|
||||
import { ProcessInstanceFilterRepresentation } from '@alfresco/js-api';
|
||||
import { ProcessInstanceFilterRepresentation, UserProcessInstanceFilterRepresentation } from '@alfresco/js-api';
|
||||
import { of } from 'rxjs';
|
||||
|
||||
declare let jasmine: any;
|
||||
|
||||
const fakeProcessFiltersResponse: any = {
|
||||
size: 1,
|
||||
total: 1,
|
||||
start: 0,
|
||||
data: [
|
||||
{
|
||||
name: 'Running',
|
||||
appId: '22',
|
||||
id: 333,
|
||||
recent: true,
|
||||
icon: 'glyphicon-random',
|
||||
filter: { sort: 'created-desc', name: '', state: 'running' }
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const mockError = {
|
||||
message: null,
|
||||
messageKey: 'GENERAL.ERROR.FORBIDDEN'
|
||||
};
|
||||
|
||||
describe('Process filter', () => {
|
||||
let service: ProcessFilterService;
|
||||
|
||||
@@ -47,9 +59,7 @@ describe('Process filter', () => {
|
||||
let createFilter: jasmine.Spy;
|
||||
|
||||
beforeEach(() => {
|
||||
getFilters = spyOn(service.userFiltersApi, 'getUserProcessInstanceFilters').and.returnValue(
|
||||
Promise.resolve(fakeProcessFiltersResponse)
|
||||
);
|
||||
getFilters = spyOn(service.userFiltersApi, 'getUserProcessInstanceFilters').and.returnValue(Promise.resolve(fakeProcessFiltersResponse));
|
||||
|
||||
jasmine.Ajax.install();
|
||||
});
|
||||
@@ -92,7 +102,7 @@ describe('Process filter', () => {
|
||||
});
|
||||
|
||||
it('should return the default filters', (done) => {
|
||||
service.createDefaultFilters(1234).subscribe((res: FilterProcessRepresentationModel[]) => {
|
||||
service.createDefaultFilters(1234).subscribe((res) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.length).toEqual(3);
|
||||
expect(res[0].name).toEqual('Running');
|
||||
@@ -142,7 +152,7 @@ describe('Process filter', () => {
|
||||
});
|
||||
|
||||
it('should be able create filters and add sorting information to the response', (done) => {
|
||||
service.createDefaultFilters(1234).subscribe((res: FilterProcessRepresentationModel[]) => {
|
||||
service.createDefaultFilters(1234).subscribe((res) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.length).toEqual(3);
|
||||
expect(res[0].name).toEqual('Running');
|
||||
@@ -211,12 +221,12 @@ describe('Process filter', () => {
|
||||
|
||||
describe('add filter', () => {
|
||||
beforeEach(() => {
|
||||
createFilter = spyOn(service.userFiltersApi, 'createUserProcessInstanceFilter').and.callFake(
|
||||
(processFilter) => Promise.resolve(processFilter)
|
||||
createFilter = spyOn(service.userFiltersApi, 'createUserProcessInstanceFilter').and.callFake((processFilter) =>
|
||||
Promise.resolve(processFilter)
|
||||
);
|
||||
});
|
||||
|
||||
const filter = fakeProcessFiltersResponse.data[0];
|
||||
const filter: UserProcessInstanceFilterRepresentation = fakeProcessFiltersResponse.data[0];
|
||||
|
||||
it('should call the API to create the filter', () => {
|
||||
service.addProcessFilter(filter);
|
||||
@@ -255,7 +265,7 @@ describe('Process filter', () => {
|
||||
});
|
||||
|
||||
describe('isFilterAlreadyExisting', () => {
|
||||
let dummyProcessFilters: FilterProcessRepresentationModel[];
|
||||
let dummyProcessFilters: UserProcessInstanceFilterRepresentation[];
|
||||
let filterRepresentationData: ProcessInstanceFilterRepresentation;
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -267,8 +277,7 @@ describe('Process filter', () => {
|
||||
id: 8,
|
||||
index: 0,
|
||||
name: 'Running',
|
||||
recent: false,
|
||||
hasFilter: () => true
|
||||
recent: false
|
||||
}
|
||||
];
|
||||
|
||||
@@ -296,10 +305,42 @@ describe('Process filter', () => {
|
||||
it('should return an array with unique process filters', (done) => {
|
||||
const appId = 123;
|
||||
|
||||
const runningFilter = dummyRunningFilter;
|
||||
const completedFilter = dummyCompletedFilter;
|
||||
const allFilter = dummyAllFilter;
|
||||
const duplicateRunningFilter = dummyDuplicateRunningFilter;
|
||||
const runningFilter = {
|
||||
appId: 123,
|
||||
name: 'Running',
|
||||
filter: { sort: 'created-desc', name: '', state: 'running' },
|
||||
icon: 'fa-random',
|
||||
id: 18,
|
||||
index: 10,
|
||||
recent: false
|
||||
};
|
||||
const completedFilter = {
|
||||
appId: 123,
|
||||
name: 'Completed',
|
||||
filter: { sort: 'created-desc', name: '', state: 'completed' },
|
||||
icon: 'fa-random',
|
||||
id: 19,
|
||||
index: 11,
|
||||
recent: false
|
||||
};
|
||||
const allFilter = {
|
||||
appId: 123,
|
||||
name: 'All',
|
||||
filter: { sort: 'created-desc', name: '', state: 'all' },
|
||||
icon: 'fa-random',
|
||||
id: 20,
|
||||
index: 12,
|
||||
recent: false
|
||||
};
|
||||
const duplicateRunningFilter = {
|
||||
appId: 123,
|
||||
name: 'Running',
|
||||
filter: { sort: 'created-desc', name: '', state: 'running' },
|
||||
icon: 'fa-random',
|
||||
id: 21,
|
||||
index: 13,
|
||||
recent: false
|
||||
};
|
||||
|
||||
const runningObservable = of(runningFilter);
|
||||
const completedObservable = of(completedFilter);
|
||||
@@ -319,9 +360,9 @@ describe('Process filter', () => {
|
||||
|
||||
service.createDefaultFilters(appId).subscribe((result) => {
|
||||
expect(result).toEqual([
|
||||
new FilterProcessRepresentationModel({ ...runningFilter, filter: runningFilter.filter, appId }),
|
||||
new FilterProcessRepresentationModel({ ...completedFilter, filter: completedFilter.filter, appId }),
|
||||
new FilterProcessRepresentationModel({ ...allFilter, filter: allFilter.filter, appId })
|
||||
{ ...runningFilter, filter: runningFilter.filter, appId },
|
||||
{ ...completedFilter, filter: completedFilter.filter, appId },
|
||||
{ ...allFilter, filter: allFilter.filter, appId }
|
||||
]);
|
||||
done();
|
||||
});
|
||||
|
@@ -18,7 +18,6 @@
|
||||
import { AlfrescoApiService } from '@alfresco/adf-core';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable, from, forkJoin } from 'rxjs';
|
||||
import { FilterProcessRepresentationModel } from '../models/filter-process.model';
|
||||
import { map } from 'rxjs/operators';
|
||||
import {
|
||||
ResultListDataRepresentationUserProcessInstanceFilterRepresentation,
|
||||
@@ -30,15 +29,13 @@ import {
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ProcessFilterService {
|
||||
|
||||
private _userFiltersApi: UserFiltersApi;
|
||||
get userFiltersApi(): UserFiltersApi {
|
||||
this._userFiltersApi = this._userFiltersApi ?? new UserFiltersApi(this.alfrescoApiService.getInstance());
|
||||
return this._userFiltersApi;
|
||||
}
|
||||
|
||||
constructor(private alfrescoApiService: AlfrescoApiService) {
|
||||
}
|
||||
constructor(private alfrescoApiService: AlfrescoApiService) {}
|
||||
|
||||
/**
|
||||
* Gets all filters defined for a Process App.
|
||||
@@ -46,20 +43,18 @@ export class ProcessFilterService {
|
||||
* @param appId ID of the target app
|
||||
* @returns Array of filter details
|
||||
*/
|
||||
getProcessFilters(appId: number): Observable<FilterProcessRepresentationModel[]> {
|
||||
return from(this.callApiProcessFilters(appId))
|
||||
.pipe(
|
||||
map((response) => {
|
||||
const filters: FilterProcessRepresentationModel[] = [];
|
||||
response.data.forEach((filter) => {
|
||||
if (!this.isFilterAlreadyExisting(filters, filter.name)) {
|
||||
const filterModel = new FilterProcessRepresentationModel(filter);
|
||||
filters.push(filterModel);
|
||||
}
|
||||
});
|
||||
return filters;
|
||||
})
|
||||
);
|
||||
getProcessFilters(appId: number): Observable<UserProcessInstanceFilterRepresentation[]> {
|
||||
return from(this.callApiProcessFilters(appId)).pipe(
|
||||
map((response) => {
|
||||
const filters = [];
|
||||
response.data.forEach((filter) => {
|
||||
if (!this.isFilterAlreadyExisting(filters, filter.name)) {
|
||||
filters.push(filter);
|
||||
}
|
||||
});
|
||||
return filters;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,10 +65,7 @@ export class ProcessFilterService {
|
||||
* @returns Details of the filter
|
||||
*/
|
||||
getProcessFilterById(filterId: number, appId?: number): Observable<UserProcessInstanceFilterRepresentation> {
|
||||
return from(this.callApiProcessFilters(appId))
|
||||
.pipe(
|
||||
map((response) => response.data.find((filter) => filter.id === filterId))
|
||||
);
|
||||
return from(this.callApiProcessFilters(appId)).pipe(map((response) => response.data.find((filter) => filter.id === filterId)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,10 +76,7 @@ export class ProcessFilterService {
|
||||
* @returns Details of the filter
|
||||
*/
|
||||
getProcessFilterByName(filterName: string, appId?: number): Observable<UserProcessInstanceFilterRepresentation> {
|
||||
return from(this.callApiProcessFilters(appId))
|
||||
.pipe(
|
||||
map((response) => response.data.find((filter) => filter.name === filterName))
|
||||
);
|
||||
return from(this.callApiProcessFilters(appId)).pipe(map((response) => response.data.find((filter) => filter.name === filterName)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,7 +85,7 @@ export class ProcessFilterService {
|
||||
* @param appId ID of the target app
|
||||
* @returns Default filters just created
|
||||
*/
|
||||
createDefaultFilters(appId: number): Observable<FilterProcessRepresentationModel[]> {
|
||||
createDefaultFilters(appId: number): Observable<UserProcessInstanceFilterRepresentation[]> {
|
||||
const runningFilter = this.getRunningFilterInstance(appId, 0);
|
||||
const runningObservable = this.addProcessFilter(runningFilter);
|
||||
|
||||
@@ -107,39 +96,33 @@ export class ProcessFilterService {
|
||||
const allObservable = this.addProcessFilter(allFilter);
|
||||
|
||||
return new Observable((observer) => {
|
||||
forkJoin([
|
||||
runningObservable,
|
||||
completedObservable,
|
||||
allObservable
|
||||
]
|
||||
).subscribe(
|
||||
(res) => {
|
||||
const filters: FilterProcessRepresentationModel[] = [];
|
||||
res.forEach((filter) => {
|
||||
if (!this.isFilterAlreadyExisting(filters, filter.name)) {
|
||||
if (filter.name === runningFilter.name) {
|
||||
filters.push(new FilterProcessRepresentationModel({ ...filter, filter: runningFilter.filter, appId }));
|
||||
} else if (filter.name === completedFilter.name) {
|
||||
filters.push(new FilterProcessRepresentationModel({ ...filter, filter: completedFilter.filter, appId }));
|
||||
} else if (filter.name === allFilter.name) {
|
||||
filters.push(new FilterProcessRepresentationModel({ ...filter, filter: allFilter.filter, appId }));
|
||||
}
|
||||
forkJoin([runningObservable, completedObservable, allObservable]).subscribe((res) => {
|
||||
const filters: UserProcessInstanceFilterRepresentation[] = [];
|
||||
res.forEach((filter) => {
|
||||
if (!this.isFilterAlreadyExisting(filters, filter.name)) {
|
||||
if (filter.name === runningFilter.name) {
|
||||
filters.push({ ...filter, filter: runningFilter.filter, appId });
|
||||
} else if (filter.name === completedFilter.name) {
|
||||
filters.push({ ...filter, filter: completedFilter.filter, appId });
|
||||
} else if (filter.name === allFilter.name) {
|
||||
filters.push({ ...filter, filter: allFilter.filter, appId });
|
||||
}
|
||||
});
|
||||
observer.next(filters);
|
||||
observer.complete();
|
||||
}
|
||||
});
|
||||
observer.next(filters);
|
||||
observer.complete();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a filter with the given name already exists in the list of filters.
|
||||
*
|
||||
* @param filters - An array of FilterProcessRepresentationModel objects representing the existing filters.
|
||||
* @param filters - An array of objects representing the existing filters.
|
||||
* @param filterName - The name of the filter to check for existence.
|
||||
* @returns - True if a filter with the specified name already exists, false otherwise.
|
||||
*/
|
||||
isFilterAlreadyExisting(filters: FilterProcessRepresentationModel[], filterName: string): boolean {
|
||||
isFilterAlreadyExisting(filters: Partial<{ name: string }>[], filterName: string): boolean {
|
||||
return filters.some((existingFilter) => existingFilter.name === filterName);
|
||||
}
|
||||
|
||||
@@ -150,15 +133,15 @@ export class ProcessFilterService {
|
||||
* @param index of the filter (optional)
|
||||
* @returns Filter just created
|
||||
*/
|
||||
getRunningFilterInstance(appId: number, index?: number): FilterProcessRepresentationModel {
|
||||
return new FilterProcessRepresentationModel({
|
||||
getRunningFilterInstance(appId: number, index?: number): UserProcessInstanceFilterRepresentation {
|
||||
return {
|
||||
name: 'Running',
|
||||
appId,
|
||||
recent: true,
|
||||
icon: 'glyphicon-random',
|
||||
filter: { sort: 'created-desc', name: '', state: 'running' },
|
||||
index
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,7 +150,7 @@ export class ProcessFilterService {
|
||||
* @param filter The filter to add
|
||||
* @returns The filter just added
|
||||
*/
|
||||
addProcessFilter(filter: FilterProcessRepresentationModel): Observable<UserProcessInstanceFilterRepresentation> {
|
||||
addProcessFilter(filter: UserProcessInstanceFilterRepresentation): Observable<UserProcessInstanceFilterRepresentation> {
|
||||
return from(this.userFiltersApi.createUserProcessInstanceFilter(filter));
|
||||
}
|
||||
|
||||
@@ -185,25 +168,25 @@ export class ProcessFilterService {
|
||||
}
|
||||
}
|
||||
|
||||
getCompletedFilterInstance(appId: number, index?: number): FilterProcessRepresentationModel {
|
||||
return new FilterProcessRepresentationModel({
|
||||
getCompletedFilterInstance(appId: number, index?: number): UserProcessInstanceFilterRepresentation {
|
||||
return {
|
||||
name: 'Completed',
|
||||
appId,
|
||||
recent: false,
|
||||
icon: 'glyphicon-ok-sign',
|
||||
filter: { sort: 'created-desc', name: '', state: 'completed' },
|
||||
index
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
getAllFilterInstance(appId: number, index?: number): FilterProcessRepresentationModel {
|
||||
return new FilterProcessRepresentationModel({
|
||||
getAllFilterInstance(appId: number, index?: number): UserProcessInstanceFilterRepresentation {
|
||||
return {
|
||||
name: 'All',
|
||||
appId,
|
||||
recent: true,
|
||||
icon: 'glyphicon-th',
|
||||
filter: { sort: 'created-desc', name: '', state: 'all' },
|
||||
index
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -16,39 +16,62 @@
|
||||
*/
|
||||
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { exampleProcess, mockError, fakeProcessDef, fakeTasksList } from '../../mock';
|
||||
import { ProcessFilterParamRepresentationModel } from '../models/filter-process.model';
|
||||
import { ProcessInstanceVariable } from '../models/process-instance-variable.model';
|
||||
import { exampleProcess } from '../../mock';
|
||||
import { ProcessService } from './process.service';
|
||||
import { CoreModule, DateFnsUtils } from '@alfresco/adf-core';
|
||||
import { ProcessTestingModule } from '../../testing/process.testing.module';
|
||||
import { ProcessInstanceQueryRepresentation, ProcessDefinitionRepresentation, RestVariable } from '@alfresco/js-api';
|
||||
import { TaskDetailsModel } from '@alfresco/adf-process-services';
|
||||
|
||||
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'
|
||||
})
|
||||
]
|
||||
};
|
||||
|
||||
const fakeProcessDef: ProcessDefinitionRepresentation = {
|
||||
id: '32323',
|
||||
key: 'blah',
|
||||
name: 'Process 1'
|
||||
};
|
||||
|
||||
const mockError = {
|
||||
message: null,
|
||||
messageKey: 'GENERAL.ERROR.FORBIDDEN'
|
||||
};
|
||||
|
||||
describe('ProcessService', () => {
|
||||
let service: ProcessService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
CoreModule.forRoot(),
|
||||
ProcessTestingModule
|
||||
]
|
||||
imports: [CoreModule.forRoot(), ProcessTestingModule]
|
||||
});
|
||||
service = TestBed.inject(ProcessService);
|
||||
});
|
||||
|
||||
describe('process instances', () => {
|
||||
const filter = new ProcessFilterParamRepresentationModel({
|
||||
const filter: ProcessInstanceQueryRepresentation = {
|
||||
processDefinitionId: '1',
|
||||
appDefinitionId: '1',
|
||||
appDefinitionId: 1,
|
||||
page: 1,
|
||||
sort: 'created-asc',
|
||||
state: 'completed'
|
||||
});
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
spyOn(service.processInstancesApi, 'getProcessInstances')
|
||||
.and
|
||||
.returnValue(Promise.resolve({ data: [exampleProcess] }));
|
||||
spyOn(service.processInstancesApi, 'getProcessInstances').and.returnValue(Promise.resolve({ data: [exampleProcess] }));
|
||||
});
|
||||
|
||||
it('should return the correct number of instances', (done) => {
|
||||
@@ -70,13 +93,10 @@ describe('ProcessService', () => {
|
||||
});
|
||||
|
||||
describe('process instance', () => {
|
||||
|
||||
const processId = 'test';
|
||||
|
||||
beforeEach(() => {
|
||||
spyOn(service.processInstancesApi, 'getProcessInstance')
|
||||
.and
|
||||
.returnValue(Promise.resolve(exampleProcess));
|
||||
spyOn(service.processInstancesApi, 'getProcessInstance').and.returnValue(Promise.resolve(exampleProcess));
|
||||
});
|
||||
|
||||
it('should return the correct instance data', (done) => {
|
||||
@@ -95,9 +115,7 @@ describe('ProcessService', () => {
|
||||
let startNewProcessInstance: jasmine.Spy;
|
||||
|
||||
beforeEach(() => {
|
||||
startNewProcessInstance = spyOn(service.processInstancesApi, 'startNewProcessInstance')
|
||||
.and
|
||||
.returnValue(Promise.resolve(exampleProcess));
|
||||
startNewProcessInstance = spyOn(service.processInstancesApi, 'startNewProcessInstance').and.returnValue(Promise.resolve(exampleProcess));
|
||||
});
|
||||
|
||||
it('should call the API to create the process instance', () => {
|
||||
@@ -135,8 +153,7 @@ describe('ProcessService', () => {
|
||||
startNewProcessInstance = startNewProcessInstance.and.returnValue(Promise.reject(mockError));
|
||||
|
||||
service.startProcess(processDefId, processName).subscribe(
|
||||
() => {
|
||||
},
|
||||
() => {},
|
||||
(res) => {
|
||||
expect(res).toBe(mockError);
|
||||
done();
|
||||
@@ -147,8 +164,7 @@ describe('ProcessService', () => {
|
||||
it('should return a default error if no data is returned by the API', (done) => {
|
||||
startNewProcessInstance = startNewProcessInstance.and.returnValue(Promise.reject(new Error('Server error')));
|
||||
service.startProcess(processDefId, processName).subscribe(
|
||||
() => {
|
||||
},
|
||||
() => {},
|
||||
(err) => {
|
||||
expect(err.message).toBe('Server error');
|
||||
done();
|
||||
@@ -158,14 +174,11 @@ describe('ProcessService', () => {
|
||||
});
|
||||
|
||||
describe('cancel process instance', () => {
|
||||
|
||||
const processInstanceId = '1234';
|
||||
let deleteProcessInstance: jasmine.Spy;
|
||||
|
||||
beforeEach(() => {
|
||||
deleteProcessInstance = spyOn(service.processInstancesApi, 'deleteProcessInstance')
|
||||
.and
|
||||
.returnValue(Promise.resolve());
|
||||
deleteProcessInstance = spyOn(service.processInstancesApi, 'deleteProcessInstance').and.returnValue(Promise.resolve());
|
||||
});
|
||||
|
||||
it('should call service to delete process instances', () => {
|
||||
@@ -181,8 +194,7 @@ describe('ProcessService', () => {
|
||||
it('should pass on any error that is returned by the API', (done) => {
|
||||
deleteProcessInstance = deleteProcessInstance.and.returnValue(Promise.reject(mockError));
|
||||
service.cancelProcess(null).subscribe(
|
||||
() => {
|
||||
},
|
||||
() => {},
|
||||
(res) => {
|
||||
expect(res).toBe(mockError);
|
||||
done();
|
||||
@@ -193,8 +205,7 @@ describe('ProcessService', () => {
|
||||
it('should return a default error if no data is returned by the API', (done) => {
|
||||
deleteProcessInstance = deleteProcessInstance.and.returnValue(Promise.reject(new Error('Server error')));
|
||||
service.cancelProcess(null).subscribe(
|
||||
() => {
|
||||
},
|
||||
() => {},
|
||||
(err) => {
|
||||
expect(err.message).toBe('Server error');
|
||||
done();
|
||||
@@ -204,13 +215,12 @@ describe('ProcessService', () => {
|
||||
});
|
||||
|
||||
describe('process definitions', () => {
|
||||
|
||||
let getProcessDefinitions: jasmine.Spy;
|
||||
|
||||
beforeEach(() => {
|
||||
getProcessDefinitions = spyOn(service.processDefinitionsApi, 'getProcessDefinitions')
|
||||
.and
|
||||
.returnValue(Promise.resolve({ data: [fakeProcessDef, fakeProcessDef] }));
|
||||
getProcessDefinitions = spyOn(service.processDefinitionsApi, 'getProcessDefinitions').and.returnValue(
|
||||
Promise.resolve({ data: [fakeProcessDef, fakeProcessDef] })
|
||||
);
|
||||
});
|
||||
|
||||
it('should return the correct number of process defs', (done) => {
|
||||
@@ -241,8 +251,7 @@ describe('ProcessService', () => {
|
||||
it('should pass on any error that is returned by the API', (done) => {
|
||||
getProcessDefinitions = getProcessDefinitions.and.returnValue(Promise.reject(mockError));
|
||||
service.getProcessDefinitions().subscribe(
|
||||
() => {
|
||||
},
|
||||
() => {},
|
||||
(res) => {
|
||||
expect(res).toBe(mockError);
|
||||
done();
|
||||
@@ -253,8 +262,7 @@ describe('ProcessService', () => {
|
||||
it('should return a default error if no data is returned by the API', (done) => {
|
||||
getProcessDefinitions = getProcessDefinitions.and.returnValue(Promise.reject(new Error('Server error')));
|
||||
service.getProcessDefinitions().subscribe(
|
||||
() => {
|
||||
},
|
||||
() => {},
|
||||
(err) => {
|
||||
expect(err.message).toBe('Server error');
|
||||
done();
|
||||
@@ -264,14 +272,11 @@ describe('ProcessService', () => {
|
||||
});
|
||||
|
||||
describe('process instance tasks', () => {
|
||||
|
||||
const processId = '1001';
|
||||
let listTasks: jasmine.Spy;
|
||||
|
||||
beforeEach(() => {
|
||||
listTasks = spyOn(service.tasksApi, 'listTasks')
|
||||
.and
|
||||
.returnValue(Promise.resolve(fakeTasksList));
|
||||
listTasks = spyOn(service.tasksApi, 'listTasks').and.returnValue(Promise.resolve(fakeTasksList));
|
||||
});
|
||||
|
||||
it('should return the correct number of tasks', (done) => {
|
||||
@@ -315,8 +320,7 @@ describe('ProcessService', () => {
|
||||
it('should pass on any error that is returned by the API', (done) => {
|
||||
listTasks = listTasks.and.returnValue(Promise.reject(mockError));
|
||||
service.getProcessTasks(processId).subscribe(
|
||||
() => {
|
||||
},
|
||||
() => {},
|
||||
(res) => {
|
||||
expect(res).toBe(mockError);
|
||||
done();
|
||||
@@ -327,8 +331,7 @@ describe('ProcessService', () => {
|
||||
it('should return a default error if no data is returned by the API', (done) => {
|
||||
listTasks = listTasks.and.returnValue(Promise.reject(new Error('Server error')));
|
||||
service.getProcessTasks(processId).subscribe(
|
||||
() => {
|
||||
},
|
||||
() => {},
|
||||
(err) => {
|
||||
expect(err.message).toBe('Server error');
|
||||
done();
|
||||
@@ -338,29 +341,35 @@ describe('ProcessService', () => {
|
||||
});
|
||||
|
||||
describe('process variables', () => {
|
||||
|
||||
let getVariablesSpy: jasmine.Spy;
|
||||
let createOrUpdateProcessInstanceVariablesSpy: jasmine.Spy;
|
||||
let deleteProcessInstanceVariableSpy: jasmine.Spy;
|
||||
|
||||
beforeEach(() => {
|
||||
getVariablesSpy = spyOn(service.processInstanceVariablesApi, 'getProcessInstanceVariables').and.returnValue(Promise.resolve([{
|
||||
name: 'var1',
|
||||
value: 'Test1'
|
||||
}, {
|
||||
name: 'var3',
|
||||
value: 'Test3'
|
||||
}]));
|
||||
getVariablesSpy = spyOn(service.processInstanceVariablesApi, 'getProcessInstanceVariables').and.returnValue(
|
||||
Promise.resolve([
|
||||
{
|
||||
name: 'var1',
|
||||
value: 'Test1'
|
||||
},
|
||||
{
|
||||
name: 'var3',
|
||||
value: 'Test3'
|
||||
}
|
||||
])
|
||||
);
|
||||
|
||||
createOrUpdateProcessInstanceVariablesSpy = spyOn(service.processInstanceVariablesApi,
|
||||
'createOrUpdateProcessInstanceVariables').and.returnValue(Promise.resolve({} as any));
|
||||
createOrUpdateProcessInstanceVariablesSpy = spyOn(
|
||||
service.processInstanceVariablesApi,
|
||||
'createOrUpdateProcessInstanceVariables'
|
||||
).and.returnValue(Promise.resolve({} as any));
|
||||
|
||||
deleteProcessInstanceVariableSpy = spyOn(service.processInstanceVariablesApi,
|
||||
'deleteProcessInstanceVariable').and.returnValue(Promise.resolve());
|
||||
deleteProcessInstanceVariableSpy = spyOn(service.processInstanceVariablesApi, 'deleteProcessInstanceVariable').and.returnValue(
|
||||
Promise.resolve()
|
||||
);
|
||||
});
|
||||
|
||||
describe('get variables', () => {
|
||||
|
||||
it('should call service to fetch variables', () => {
|
||||
service.getProcessInstanceVariables(null);
|
||||
expect(getVariablesSpy).toHaveBeenCalled();
|
||||
@@ -369,8 +378,7 @@ describe('ProcessService', () => {
|
||||
it('should pass on any error that is returned by the API', (done) => {
|
||||
getVariablesSpy = getVariablesSpy.and.returnValue(Promise.reject(mockError));
|
||||
service.getProcessInstanceVariables(null).subscribe(
|
||||
() => {
|
||||
},
|
||||
() => {},
|
||||
(res) => {
|
||||
expect(res).toBe(mockError);
|
||||
done();
|
||||
@@ -381,8 +389,7 @@ describe('ProcessService', () => {
|
||||
it('should return a default error if no data is returned by the API', (done) => {
|
||||
getVariablesSpy = getVariablesSpy.and.returnValue(Promise.reject(new Error('Server error')));
|
||||
service.getProcessInstanceVariables(null).subscribe(
|
||||
() => {
|
||||
},
|
||||
() => {},
|
||||
(err) => {
|
||||
expect(err.message).toBe('Server error');
|
||||
done();
|
||||
@@ -392,13 +399,16 @@ describe('ProcessService', () => {
|
||||
});
|
||||
|
||||
describe('create or update variables', () => {
|
||||
const updatedVariables = [new ProcessInstanceVariable({
|
||||
name: 'var1',
|
||||
value: 'Test1'
|
||||
}), new ProcessInstanceVariable({
|
||||
name: 'var3',
|
||||
value: 'Test3'
|
||||
})];
|
||||
const updatedVariables: RestVariable[] = [
|
||||
{
|
||||
name: 'var1',
|
||||
value: 'Test1'
|
||||
},
|
||||
{
|
||||
name: 'var3',
|
||||
value: 'Test3'
|
||||
}
|
||||
];
|
||||
|
||||
it('should call service to create or update variables', () => {
|
||||
service.createOrUpdateProcessInstanceVariables('123', updatedVariables);
|
||||
@@ -408,8 +418,7 @@ describe('ProcessService', () => {
|
||||
it('should pass on any error that is returned by the API', (done) => {
|
||||
createOrUpdateProcessInstanceVariablesSpy = createOrUpdateProcessInstanceVariablesSpy.and.returnValue(Promise.reject(mockError));
|
||||
service.createOrUpdateProcessInstanceVariables('123', updatedVariables).subscribe(
|
||||
() => {
|
||||
},
|
||||
() => {},
|
||||
(err) => {
|
||||
expect(err).toBe(mockError);
|
||||
done();
|
||||
@@ -418,10 +427,11 @@ describe('ProcessService', () => {
|
||||
});
|
||||
|
||||
it('should return a default error if no data is returned by the API', (done) => {
|
||||
createOrUpdateProcessInstanceVariablesSpy = createOrUpdateProcessInstanceVariablesSpy.and.returnValue(Promise.reject(new Error('Server error')));
|
||||
createOrUpdateProcessInstanceVariablesSpy = createOrUpdateProcessInstanceVariablesSpy.and.returnValue(
|
||||
Promise.reject(new Error('Server error'))
|
||||
);
|
||||
service.createOrUpdateProcessInstanceVariables('123', updatedVariables).subscribe(
|
||||
() => {
|
||||
},
|
||||
() => {},
|
||||
(err) => {
|
||||
expect(err.message).toBe('Server error');
|
||||
done();
|
||||
@@ -434,8 +444,7 @@ describe('ProcessService', () => {
|
||||
it('should pass on any error that is returned by the API', (done) => {
|
||||
deleteProcessInstanceVariableSpy = deleteProcessInstanceVariableSpy.and.returnValue(Promise.reject(mockError));
|
||||
service.deleteProcessInstanceVariable('123', 'myVar').subscribe(
|
||||
() => {
|
||||
},
|
||||
() => {},
|
||||
(res) => {
|
||||
expect(res).toBe(mockError);
|
||||
done();
|
||||
@@ -446,8 +455,7 @@ describe('ProcessService', () => {
|
||||
it('should return a default error if no data is returned by the API', (done) => {
|
||||
deleteProcessInstanceVariableSpy = deleteProcessInstanceVariableSpy.and.returnValue(Promise.reject(new Error('Server error')));
|
||||
service.deleteProcessInstanceVariable('123', 'myVar').subscribe(
|
||||
() => {
|
||||
},
|
||||
() => {},
|
||||
(err) => {
|
||||
expect(err.message).toBe('Server error');
|
||||
done();
|
||||
|
@@ -18,54 +18,48 @@
|
||||
import { AlfrescoApiService, DateFnsUtils, FormValues } from '@alfresco/adf-core';
|
||||
import { Injectable } from '@angular/core';
|
||||
import {
|
||||
TasksApi,
|
||||
FormDefinitionRepresentation,
|
||||
ProcessDefinitionsApi,
|
||||
ProcessInstancesApi,
|
||||
RestVariable,
|
||||
ProcessInstanceAuditInfoRepresentation,
|
||||
ProcessInstanceQueryRepresentation,
|
||||
ProcessInstanceRepresentation,
|
||||
ProcessInstanceVariablesApi
|
||||
ProcessInstancesApi,
|
||||
ProcessInstanceVariablesApi,
|
||||
RestVariable,
|
||||
ResultListDataRepresentationProcessInstanceRepresentation,
|
||||
TasksApi,
|
||||
ProcessDefinitionRepresentation
|
||||
} from '@alfresco/js-api';
|
||||
import { Observable, from, throwError, of } from 'rxjs';
|
||||
import { from, Observable } from 'rxjs';
|
||||
import { TaskDetailsModel } from '../../task-list';
|
||||
import { ProcessFilterParamRepresentationModel } from '../models/filter-process.model';
|
||||
import { ProcessDefinitionRepresentation } from '../models/process-definition.model';
|
||||
import { ProcessInstanceVariable } from '../models/process-instance-variable.model';
|
||||
import { ProcessInstance } from '../models/process-instance.model';
|
||||
import { ProcessListModel } from '../models/process-list.model';
|
||||
import { map, catchError } from 'rxjs/operators';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { DatePipe } from '@angular/common';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ProcessService {
|
||||
|
||||
private _tasksApi: TasksApi;
|
||||
get tasksApi(): TasksApi {
|
||||
this._tasksApi = this._tasksApi ?? new TasksApi(this.alfrescoApiService.getInstance());
|
||||
return this._tasksApi;
|
||||
return (this._tasksApi ||= new TasksApi(this.alfrescoApiService.getInstance()));
|
||||
}
|
||||
|
||||
private _processDefinitionsApi: ProcessDefinitionsApi;
|
||||
get processDefinitionsApi(): ProcessDefinitionsApi {
|
||||
this._processDefinitionsApi = this._processDefinitionsApi ?? new ProcessDefinitionsApi(this.alfrescoApiService.getInstance());
|
||||
return this._processDefinitionsApi;
|
||||
return (this._processDefinitionsApi ||= new ProcessDefinitionsApi(this.alfrescoApiService.getInstance()));
|
||||
}
|
||||
|
||||
private _processInstancesApi: ProcessInstancesApi;
|
||||
get processInstancesApi(): ProcessInstancesApi {
|
||||
this._processInstancesApi = this._processInstancesApi ?? new ProcessInstancesApi(this.alfrescoApiService.getInstance());
|
||||
return this._processInstancesApi;
|
||||
return (this._processInstancesApi ||= new ProcessInstancesApi(this.alfrescoApiService.getInstance()));
|
||||
}
|
||||
|
||||
private _processInstanceVariablesApi: ProcessInstanceVariablesApi;
|
||||
get processInstanceVariablesApi(): ProcessInstanceVariablesApi {
|
||||
this._processInstanceVariablesApi = this._processInstanceVariablesApi ?? new ProcessInstanceVariablesApi(this.alfrescoApiService.getInstance());
|
||||
return this._processInstanceVariablesApi;
|
||||
return (this._processInstanceVariablesApi ||= new ProcessInstanceVariablesApi(this.alfrescoApiService.getInstance()));
|
||||
}
|
||||
|
||||
constructor(private alfrescoApiService: AlfrescoApiService) {
|
||||
}
|
||||
constructor(private alfrescoApiService: AlfrescoApiService) {}
|
||||
|
||||
/**
|
||||
* Gets process instances for a filter and optionally a process definition.
|
||||
@@ -74,20 +68,18 @@ export class ProcessService {
|
||||
* @param processDefinitionKey Limits returned instances to a process definition
|
||||
* @returns List of process instances
|
||||
*/
|
||||
getProcessInstances(requestNode: ProcessFilterParamRepresentationModel, processDefinitionKey?: string): Observable<ProcessListModel> {
|
||||
return from(this.processInstancesApi.getProcessInstances(requestNode))
|
||||
.pipe(
|
||||
map((res: any) => {
|
||||
if (processDefinitionKey) {
|
||||
const filtered = res.data.filter((process) => process.processDefinitionKey === processDefinitionKey);
|
||||
res.data = filtered;
|
||||
return res;
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
}),
|
||||
catchError((err) => this.handleProcessError(err))
|
||||
);
|
||||
getProcessInstances(
|
||||
requestNode: ProcessInstanceQueryRepresentation,
|
||||
processDefinitionKey?: string
|
||||
): Observable<ResultListDataRepresentationProcessInstanceRepresentation> {
|
||||
return from(this.processInstancesApi.getProcessInstances(requestNode)).pipe(
|
||||
map((res) => {
|
||||
if (processDefinitionKey) {
|
||||
res.data = res.data.filter((process) => process.processDefinitionKey === processDefinitionKey);
|
||||
}
|
||||
return res;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,18 +89,19 @@ export class ProcessService {
|
||||
* @param processDefinitionKey Limits returned instances to a process definition
|
||||
* @returns List of processes
|
||||
*/
|
||||
getProcesses(requestNode: ProcessFilterParamRepresentationModel, processDefinitionKey?: string): Observable<ProcessListModel> {
|
||||
return this.getProcessInstances(requestNode, processDefinitionKey)
|
||||
.pipe(
|
||||
map(response => ({
|
||||
...response,
|
||||
data: (response.data || []).map(instance => {
|
||||
instance.name = this.getProcessNameOrDescription(instance, 'medium');
|
||||
return instance;
|
||||
})
|
||||
})),
|
||||
catchError(() => of(new ProcessListModel({})))
|
||||
);
|
||||
getProcesses(
|
||||
requestNode: ProcessInstanceQueryRepresentation,
|
||||
processDefinitionKey?: string
|
||||
): Observable<ResultListDataRepresentationProcessInstanceRepresentation> {
|
||||
return this.getProcessInstances(requestNode, processDefinitionKey).pipe(
|
||||
map((response) => {
|
||||
response.data = (response.data || []).map((instance) => {
|
||||
instance.name = this.getProcessNameOrDescription(instance, 'medium');
|
||||
return instance;
|
||||
});
|
||||
return response;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -118,10 +111,7 @@ export class ProcessService {
|
||||
* @returns Binary PDF data
|
||||
*/
|
||||
fetchProcessAuditPdfById(processId: string): Observable<Blob> {
|
||||
return from(this.processInstancesApi.getProcessAuditPdf(processId))
|
||||
.pipe(
|
||||
catchError((err) => this.handleProcessError(err))
|
||||
);
|
||||
return from(this.processInstancesApi.getProcessAuditPdf(processId));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,11 +120,8 @@ export class ProcessService {
|
||||
* @param processId ID of the target process
|
||||
* @returns JSON data
|
||||
*/
|
||||
fetchProcessAuditJsonById(processId: string): Observable<any> {
|
||||
return from(this.processInstancesApi.getTaskAuditLog(processId))
|
||||
.pipe(
|
||||
catchError((err) => this.handleProcessError(err))
|
||||
);
|
||||
fetchProcessAuditJsonById(processId: string): Observable<ProcessInstanceAuditInfoRepresentation> {
|
||||
return from(this.processInstancesApi.getTaskAuditLog(processId));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -143,12 +130,8 @@ export class ProcessService {
|
||||
* @param processInstanceId ID of the target process
|
||||
* @returns Metadata for the instance
|
||||
*/
|
||||
getProcess(processInstanceId: string): Observable<ProcessInstance> {
|
||||
return from(this.processInstancesApi.getProcessInstance(processInstanceId))
|
||||
.pipe(
|
||||
map(this.toJson),
|
||||
catchError((err) => this.handleProcessError(err))
|
||||
);
|
||||
getProcess(processInstanceId: string): Observable<ProcessInstanceRepresentation> {
|
||||
return from(this.processInstancesApi.getProcessInstance(processInstanceId)).pipe(map(this.toJson));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -158,36 +141,26 @@ export class ProcessService {
|
||||
* @returns Form definition
|
||||
*/
|
||||
getStartFormDefinition(processId: string): Observable<any> {
|
||||
return from(this.processDefinitionsApi.getProcessDefinitionStartForm(processId))
|
||||
.pipe(
|
||||
map(this.toJson),
|
||||
catchError((err) => this.handleProcessError(err))
|
||||
);
|
||||
return from(this.processDefinitionsApi.getProcessDefinitionStartForm(processId)).pipe(map(this.toJson));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the start form instance for a given process.
|
||||
*
|
||||
* @param processId Process definition ID
|
||||
* @returns Form definition
|
||||
*/
|
||||
getStartFormInstance(processId: string): Observable<any> {
|
||||
return from(this.processInstancesApi.getProcessInstanceStartForm(processId))
|
||||
.pipe(
|
||||
map(this.toJson),
|
||||
catchError((err) => this.handleProcessError(err))
|
||||
);
|
||||
getStartFormInstance(processId: string): Observable<FormDefinitionRepresentation> {
|
||||
return from(this.processInstancesApi.getProcessInstanceStartForm(processId)).pipe(map(this.toJson));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a JSON representation of form data.
|
||||
*
|
||||
* @param res Object representing form data
|
||||
* @returns JSON data
|
||||
*/
|
||||
toJson(res: any) {
|
||||
private toJson(res: any) {
|
||||
if (res) {
|
||||
return res || {};
|
||||
}
|
||||
@@ -202,21 +175,23 @@ export class ProcessService {
|
||||
* @returns Array of task instance details
|
||||
*/
|
||||
getProcessTasks(processInstanceId: string, state?: string): Observable<TaskDetailsModel[]> {
|
||||
const taskOpts = state ? {
|
||||
processInstanceId,
|
||||
state
|
||||
} : {
|
||||
processInstanceId
|
||||
};
|
||||
return from(this.tasksApi.listTasks(taskOpts))
|
||||
.pipe(
|
||||
map(this.extractData),
|
||||
map((tasks) => tasks.map((task: any) => {
|
||||
const taskOpts = state
|
||||
? {
|
||||
processInstanceId,
|
||||
state
|
||||
}
|
||||
: {
|
||||
processInstanceId
|
||||
};
|
||||
return from(this.tasksApi.listTasks(taskOpts)).pipe(
|
||||
map(this.extractData),
|
||||
map((tasks) =>
|
||||
tasks.map((task: any) => {
|
||||
task.created = DateFnsUtils.formatDate(new Date(task.created), 'YYYY-MM-DD');
|
||||
return task;
|
||||
})),
|
||||
catchError((err) => this.handleProcessError(err))
|
||||
);
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -226,20 +201,15 @@ export class ProcessService {
|
||||
* @returns Array of process definitions
|
||||
*/
|
||||
getProcessDefinitions(appId?: number): Observable<ProcessDefinitionRepresentation[]> {
|
||||
const opts = appId ? {
|
||||
latest: true,
|
||||
appDefinitionId: appId
|
||||
} : {
|
||||
latest: true
|
||||
};
|
||||
return from(
|
||||
this.processDefinitionsApi.getProcessDefinitions(opts)
|
||||
)
|
||||
.pipe(
|
||||
map(this.extractData),
|
||||
map((processDefs) => processDefs.map((pd) => new ProcessDefinitionRepresentation(pd))),
|
||||
catchError((err) => this.handleProcessError(err))
|
||||
);
|
||||
const opts = appId
|
||||
? {
|
||||
latest: true,
|
||||
appDefinitionId: appId
|
||||
}
|
||||
: {
|
||||
latest: true
|
||||
};
|
||||
return from(this.processDefinitionsApi.getProcessDefinitions(opts)).pipe(map(this.extractData));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -252,7 +222,13 @@ export class ProcessService {
|
||||
* @param variables Array of process instance variables
|
||||
* @returns Details of the process instance just started
|
||||
*/
|
||||
startProcess(processDefinitionId: string, name: string, outcome?: string, startFormValues?: FormValues, variables?: ProcessInstanceVariable[]): Observable<ProcessInstance> {
|
||||
startProcess(
|
||||
processDefinitionId: string,
|
||||
name: string,
|
||||
outcome?: string,
|
||||
startFormValues?: FormValues,
|
||||
variables?: RestVariable[]
|
||||
): Observable<ProcessInstanceRepresentation> {
|
||||
const startRequest: any = {
|
||||
name,
|
||||
processDefinitionId
|
||||
@@ -266,13 +242,7 @@ export class ProcessService {
|
||||
if (variables) {
|
||||
startRequest.variables = variables;
|
||||
}
|
||||
return from(
|
||||
this.processInstancesApi.startNewProcessInstance(startRequest)
|
||||
)
|
||||
.pipe(
|
||||
map((pd) => new ProcessInstance(pd)),
|
||||
catchError((err) => this.handleProcessError(err))
|
||||
);
|
||||
return from(this.processInstancesApi.startNewProcessInstance(startRequest));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -282,12 +252,7 @@ export class ProcessService {
|
||||
* @returns Null response notifying when the operation is complete
|
||||
*/
|
||||
cancelProcess(processInstanceId: string): Observable<void> {
|
||||
return from(
|
||||
this.processInstancesApi.deleteProcessInstance(processInstanceId)
|
||||
)
|
||||
.pipe(
|
||||
catchError((err) => this.handleProcessError(err))
|
||||
);
|
||||
return from(this.processInstancesApi.deleteProcessInstance(processInstanceId));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -296,14 +261,8 @@ export class ProcessService {
|
||||
* @param processInstanceId ID of the target process
|
||||
* @returns Array of instance variable info
|
||||
*/
|
||||
getProcessInstanceVariables(processInstanceId: string): Observable<ProcessInstanceVariable[]> {
|
||||
return from(
|
||||
this.processInstanceVariablesApi.getProcessInstanceVariables(processInstanceId)
|
||||
)
|
||||
.pipe(
|
||||
map((processVars: any[]) => processVars.map((currentProcessVar) => new ProcessInstanceVariable(currentProcessVar))),
|
||||
catchError((err) => this.handleProcessError(err))
|
||||
);
|
||||
getProcessInstanceVariables(processInstanceId: string): Observable<RestVariable[]> {
|
||||
return from(this.processInstanceVariablesApi.getProcessInstanceVariables(processInstanceId));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -313,12 +272,8 @@ export class ProcessService {
|
||||
* @param variables Variables to update
|
||||
* @returns Array of instance variable info
|
||||
*/
|
||||
createOrUpdateProcessInstanceVariables(processInstanceId: string, variables: RestVariable[]): Observable<ProcessInstanceVariable[]> {
|
||||
return from(
|
||||
this.processInstanceVariablesApi.createOrUpdateProcessInstanceVariables(processInstanceId, variables)
|
||||
).pipe(
|
||||
catchError((err) => this.handleProcessError(err))
|
||||
);
|
||||
createOrUpdateProcessInstanceVariables(processInstanceId: string, variables: RestVariable[]): Observable<RestVariable[]> {
|
||||
return from(this.processInstanceVariablesApi.createOrUpdateProcessInstanceVariables(processInstanceId, variables));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -329,28 +284,18 @@ export class ProcessService {
|
||||
* @returns Null response notifying when the operation is complete
|
||||
*/
|
||||
deleteProcessInstanceVariable(processInstanceId: string, variableName: string): Observable<void> {
|
||||
return from(
|
||||
this.processInstanceVariablesApi.deleteProcessInstanceVariable(processInstanceId, variableName)
|
||||
)
|
||||
.pipe(
|
||||
catchError((err) => this.handleProcessError(err))
|
||||
);
|
||||
return from(this.processInstanceVariablesApi.deleteProcessInstanceVariable(processInstanceId, variableName));
|
||||
}
|
||||
|
||||
private extractData(res: any) {
|
||||
return res.data || {};
|
||||
}
|
||||
|
||||
private handleProcessError(error: any) {
|
||||
return throwError(error || 'Server error');
|
||||
}
|
||||
|
||||
private getProcessNameOrDescription(processInstance: ProcessInstanceRepresentation, dateFormat: string): string {
|
||||
let name = '';
|
||||
|
||||
if (processInstance) {
|
||||
name = processInstance.name ||
|
||||
processInstance.processDefinitionName + ' - ' + this.getFormatDate(processInstance.started, dateFormat);
|
||||
name = processInstance.name || processInstance.processDefinitionName + ' - ' + this.getFormatDate(processInstance.started, dateFormat);
|
||||
}
|
||||
|
||||
return name;
|
||||
|
@@ -18,15 +18,13 @@
|
||||
import { CoreTestingModule, UserInfoMode } from '@alfresco/adf-core';
|
||||
import { fakeEcmUser, fakeEcmUserNoImage } from '@alfresco/adf-content-services';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { BpmUserModel } from '../common/models/bpm-user.model';
|
||||
import { ProcessUserInfoComponent } from './process-user-info.component';
|
||||
import { HarnessLoader } from '@angular/cdk/testing';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { MatTabGroupHarness, MatTabHarness } from '@angular/material/tabs/testing';
|
||||
|
||||
const fakeBpmUser = new BpmUserModel({
|
||||
const fakeBpmUser: any = {
|
||||
apps: [],
|
||||
capabilities: null,
|
||||
company: 'fake-company',
|
||||
@@ -46,7 +44,7 @@ const fakeBpmUser = new BpmUserModel({
|
||||
tenantName: 'fake-tenant-name',
|
||||
tenantPictureId: 'fake-tenant-picture-id',
|
||||
type: 'fake-type'
|
||||
});
|
||||
};
|
||||
|
||||
describe('ProcessUserInfoComponent', () => {
|
||||
const profilePictureUrl = 'alfresco-logo.svg';
|
||||
@@ -71,7 +69,7 @@ describe('ProcessUserInfoComponent', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [CoreTestingModule, MatMenuModule]
|
||||
imports: [CoreTestingModule, ProcessUserInfoComponent]
|
||||
});
|
||||
fixture = TestBed.createComponent(ProcessUserInfoComponent);
|
||||
component = fixture.componentInstance;
|
||||
@@ -122,11 +120,10 @@ describe('ProcessUserInfoComponent', () => {
|
||||
});
|
||||
|
||||
it('should show last name if first name is null', async () => {
|
||||
const wrongBpmUser: BpmUserModel = new BpmUserModel({
|
||||
component.bpmUser = {
|
||||
firstName: null,
|
||||
lastName: 'fake-last-name'
|
||||
});
|
||||
component.bpmUser = wrongBpmUser;
|
||||
} as any;
|
||||
await whenFixtureReady();
|
||||
const fullNameElement = element.querySelector('#adf-userinfo-bpm-name-display');
|
||||
fixture.detectChanges();
|
||||
|
@@ -15,22 +15,28 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { UserInfoMode } from '@alfresco/adf-core';
|
||||
import { FullNamePipe, InitialUsernamePipe, UserInfoMode } from '@alfresco/adf-core';
|
||||
import { EcmUserModel, PeopleContentService } from '@alfresco/adf-content-services';
|
||||
import { Component, Input, OnDestroy, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||
import { MatMenuTrigger, MenuPositionX, MenuPositionY } from '@angular/material/menu';
|
||||
import { MatMenuModule, MatMenuTrigger, MenuPositionX, MenuPositionY } from '@angular/material/menu';
|
||||
import { Subject } from 'rxjs';
|
||||
import { PeopleProcessService } from '../common/services/people-process.service';
|
||||
import { BpmUserModel } from '../common/models/bpm-user.model';
|
||||
import { UserRepresentation } from '@alfresco/js-api';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatTabsModule } from '@angular/material/tabs';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-process-user-info',
|
||||
standalone: true,
|
||||
imports: [CommonModule, FullNamePipe, MatButtonModule, MatMenuModule, InitialUsernamePipe, MatTabsModule, TranslateModule, MatCardModule],
|
||||
templateUrl: './process-user-info.component.html',
|
||||
styleUrls: ['./process-user-info.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class ProcessUserInfoComponent implements OnDestroy {
|
||||
|
||||
@ViewChild(MatMenuTrigger) trigger: MatMenuTrigger;
|
||||
|
||||
/** Determines if user is logged in. */
|
||||
@@ -39,7 +45,7 @@ export class ProcessUserInfoComponent implements OnDestroy {
|
||||
|
||||
/** BPM user info. */
|
||||
@Input()
|
||||
bpmUser: BpmUserModel;
|
||||
bpmUser: UserRepresentation;
|
||||
|
||||
/** ECM user info. */
|
||||
@Input()
|
||||
@@ -80,8 +86,7 @@ export class ProcessUserInfoComponent implements OnDestroy {
|
||||
|
||||
private destroy$ = new Subject();
|
||||
|
||||
constructor(private peopleProcessService: PeopleProcessService, private peopleContentService: PeopleContentService) {
|
||||
}
|
||||
constructor(private peopleProcessService: PeopleProcessService, private peopleContentService: PeopleContentService) {}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.destroy$.next(true);
|
||||
|
@@ -16,28 +16,10 @@
|
||||
*/
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ProcessUserInfoComponent } from './process-user-info.component';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { MatTabsModule } from '@angular/material/tabs';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { FullNamePipe, InitialUsernamePipe, PipeModule } from '@alfresco/adf-core';
|
||||
|
||||
@NgModule({
|
||||
declarations: [ProcessUserInfoComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
MatButtonModule,
|
||||
MatMenuModule,
|
||||
MatTabsModule,
|
||||
MatCardModule,
|
||||
TranslateModule,
|
||||
PipeModule,
|
||||
FullNamePipe,
|
||||
InitialUsernamePipe
|
||||
],
|
||||
imports: [ProcessUserInfoComponent],
|
||||
exports: [ProcessUserInfoComponent]
|
||||
})
|
||||
export class ProcessUserInfoModule {}
|
||||
|
@@ -18,7 +18,7 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule, ModuleWithProviders } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { CoreModule, FormRenderingService, provideTranslations } from '@alfresco/adf-core';
|
||||
import { CoreModule, EmptyContentComponent, FormRenderingService, provideTranslations } from '@alfresco/adf-core';
|
||||
|
||||
import { MaterialModule } from './material.module';
|
||||
|
||||
@@ -48,7 +48,8 @@ import { ProcessUserInfoModule } from './process-user-info/process-user-info.mod
|
||||
ProcessUserInfoModule,
|
||||
AttachmentModule,
|
||||
PeopleModule,
|
||||
FormModule
|
||||
FormModule,
|
||||
EmptyContentComponent
|
||||
],
|
||||
providers: [provideTranslations('adf-process-services', 'assets/adf-process-services')],
|
||||
exports: [
|
||||
|
@@ -15,4 +15,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './public-api';
|
||||
export * from './task-comments.component';
|
||||
export * from './services/task-comments.service';
|
||||
export * from './task-comments.module';
|
||||
|
@@ -1,32 +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.
|
||||
*/
|
||||
|
||||
export const fakeUser1 = { id: 1, email: 'fake-email@dom.com', firstName: 'firstName', lastName: 'lastName' };
|
||||
|
||||
export const fakeUser2 = { id: 1001, email: 'some-one@somegroup.com', firstName: 'some', lastName: 'one' };
|
||||
|
||||
export const fakeTasksComment = {
|
||||
size: 2, total: 2, start: 0,
|
||||
data: [
|
||||
{
|
||||
id: 1, message: 'fake-message-1', created: '', createdBy: fakeUser1
|
||||
},
|
||||
{
|
||||
id: 2, message: 'fake-message-2', created: '', createdBy: fakeUser1
|
||||
}
|
||||
]
|
||||
};
|
@@ -1,22 +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.
|
||||
*/
|
||||
|
||||
export * from './task-comments.component';
|
||||
|
||||
export * from './services/task-comments.service';
|
||||
|
||||
export * from './task-comments.module';
|
@@ -1,84 +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 { TestBed } from '@angular/core/testing';
|
||||
import { CommentModel, CoreTestingModule } from '@alfresco/adf-core';
|
||||
import { fakeTasksComment, fakeUser1 } from '../mocks/task-comments.mock';
|
||||
import { TaskCommentsService } from './task-comments.service';
|
||||
|
||||
declare let jasmine: any;
|
||||
|
||||
describe('TaskCommentsService', () => {
|
||||
let service: TaskCommentsService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [CoreTestingModule]
|
||||
});
|
||||
service = TestBed.inject(TaskCommentsService);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
jasmine.Ajax.install();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jasmine.Ajax.uninstall();
|
||||
});
|
||||
|
||||
describe('Task comments', () => {
|
||||
it('should add a comment task ', (done) => {
|
||||
service.add('999', 'fake-comment-message').subscribe((res: CommentModel) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.id).not.toEqual(null);
|
||||
expect(res.message).toEqual('fake-comment-message');
|
||||
expect(res.created).not.toEqual(null);
|
||||
expect(res.createdBy.email).toEqual('fake-email@dom.com');
|
||||
expect(res.createdBy.firstName).toEqual('firstName');
|
||||
expect(res.createdBy.lastName).toEqual('lastName');
|
||||
done();
|
||||
});
|
||||
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify({
|
||||
id: '111',
|
||||
message: 'fake-comment-message',
|
||||
createdBy: fakeUser1,
|
||||
created: '2016-07-15T11:19:17.440+0000'
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the tasks comments ', (done) => {
|
||||
service.get('999').subscribe((res: CommentModel[]) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.length).toEqual(2);
|
||||
expect(res[0].message).toEqual('fake-message-1');
|
||||
expect(res[1].message).toEqual('fake-message-2');
|
||||
done();
|
||||
});
|
||||
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify(fakeTasksComment)
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@@ -15,12 +15,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AlfrescoApiService, CommentModel, CommentsService, User } from '@alfresco/adf-core';
|
||||
import { ActivitiCommentsApi, CommentRepresentation } from '@alfresco/js-api';
|
||||
import { AlfrescoApiService, CommentModel, CommentsService } from '@alfresco/adf-core';
|
||||
import { ActivitiCommentsApi } from '@alfresco/js-api';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { from, Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { UserProcessModel } from '../../common/models/user-process.model';
|
||||
import { PeopleProcessService } from '../../common/services/people-process.service';
|
||||
|
||||
@Injectable({
|
||||
@@ -42,17 +41,7 @@ export class TaskCommentsService implements CommentsService {
|
||||
* @returns Details for each comment
|
||||
*/
|
||||
get(id: string): Observable<CommentModel[]> {
|
||||
return from(this.commentsApi.getTaskComments(id)).pipe(
|
||||
map((response) => {
|
||||
const comments: CommentModel[] = [];
|
||||
|
||||
response.data.forEach((comment) => {
|
||||
this.addToComments(comments, comment);
|
||||
});
|
||||
|
||||
return comments;
|
||||
})
|
||||
);
|
||||
return from(this.commentsApi.getTaskComments(id)).pipe(map((response) => response.data.map((comment) => new CommentModel(comment))));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,32 +52,10 @@ export class TaskCommentsService implements CommentsService {
|
||||
* @returns Details about the comment
|
||||
*/
|
||||
add(id: string, message: string): Observable<CommentModel> {
|
||||
return from(this.commentsApi.addTaskComment({ message }, id)).pipe(map((response) => this.newCommentModel(response)));
|
||||
return from(this.commentsApi.addTaskComment({ message }, id)).pipe(map((response) => new CommentModel(response)));
|
||||
}
|
||||
|
||||
private addToComments(comments: CommentModel[], comment: CommentRepresentation): void {
|
||||
const user = new UserProcessModel(comment.createdBy);
|
||||
|
||||
const newComment: CommentRepresentation = {
|
||||
id: comment.id,
|
||||
message: comment.message,
|
||||
created: comment.created,
|
||||
createdBy: user
|
||||
};
|
||||
|
||||
comments.push(this.newCommentModel(newComment));
|
||||
}
|
||||
|
||||
private newCommentModel(representation: CommentRepresentation): CommentModel {
|
||||
return new CommentModel({
|
||||
id: representation.id,
|
||||
message: representation.message,
|
||||
created: representation.created,
|
||||
createdBy: new User(representation.createdBy)
|
||||
});
|
||||
}
|
||||
|
||||
getUserImage(user: UserProcessModel): string {
|
||||
return this.peopleProcessService.getUserImage(user);
|
||||
getUserImage(userId: string): string {
|
||||
return this.peopleProcessService.getUserImage(userId);
|
||||
}
|
||||
}
|
||||
|
@@ -16,17 +16,22 @@
|
||||
*/
|
||||
|
||||
import { Component, Input, ViewEncapsulation } from '@angular/core';
|
||||
import { ADF_COMMENTS_SERVICE } from '@alfresco/adf-core';
|
||||
import { ADF_COMMENTS_SERVICE, CommentsModule } from '@alfresco/adf-core';
|
||||
import { TaskCommentsService } from './services/task-comments.service';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-task-comments',
|
||||
standalone: true,
|
||||
imports: [CommonModule, CommentsModule],
|
||||
templateUrl: './task-comments.component.html',
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
providers: [{
|
||||
provide: ADF_COMMENTS_SERVICE,
|
||||
useClass: TaskCommentsService
|
||||
}]
|
||||
providers: [
|
||||
{
|
||||
provide: ADF_COMMENTS_SERVICE,
|
||||
useClass: TaskCommentsService
|
||||
}
|
||||
]
|
||||
})
|
||||
export class TaskCommentsComponent {
|
||||
/** The numeric ID of the task. */
|
||||
|
@@ -16,16 +16,10 @@
|
||||
*/
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { TaskCommentsComponent } from './task-comments.component';
|
||||
import { CoreModule } from '@alfresco/adf-core';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
CoreModule
|
||||
],
|
||||
declarations: [TaskCommentsComponent],
|
||||
imports: [TaskCommentsComponent],
|
||||
exports: [TaskCommentsComponent]
|
||||
})
|
||||
export class TaskCommentsModule {}
|
||||
|
@@ -57,7 +57,7 @@
|
||||
</div>
|
||||
</mat-form-field>
|
||||
<people-widget
|
||||
(peopleSelected)="getAssigneeId($event)"
|
||||
(peopleSelected)="setAssigneeId($event)"
|
||||
[field]="field"
|
||||
class="adf-people-widget-content"></people-widget>
|
||||
</div>
|
||||
|
@@ -247,7 +247,7 @@ describe('StartTaskComponent', () => {
|
||||
component.taskForm.controls['name'].setValue('fakeName');
|
||||
component.taskForm.controls['formKey'].setValue(1204);
|
||||
component.appId = 42;
|
||||
component.getAssigneeId(testUser.id);
|
||||
component.setAssigneeId(testUser.id);
|
||||
fixture.detectChanges();
|
||||
const createTaskButton = element.querySelector<HTMLElement>('#button-start');
|
||||
createTaskButton.click();
|
||||
|
@@ -24,7 +24,6 @@ import { TaskDetailsModel } from '../models/task-details.model';
|
||||
import { TaskListService } from './../services/tasklist.service';
|
||||
import { switchMap, defaultIfEmpty, takeUntil } from 'rxjs/operators';
|
||||
import { UntypedFormBuilder, AbstractControl, Validators, UntypedFormGroup, UntypedFormControl } from '@angular/forms';
|
||||
import { UserProcessModel } from '../../common/models/user-process.model';
|
||||
import { isValid } from 'date-fns';
|
||||
|
||||
const FORMAT_DATE = 'DD/MM/YYYY';
|
||||
@@ -106,7 +105,7 @@ export class StartTaskComponent implements OnInit, OnDestroy {
|
||||
this.taskForm.valueChanges.pipe(takeUntil(this.onDestroy$)).subscribe((taskFormValues) => this.setTaskDetails(taskFormValues));
|
||||
}
|
||||
|
||||
whitespaceValidator(control: UntypedFormControl): any {
|
||||
private whitespaceValidator(control: UntypedFormControl): any {
|
||||
if (control.value) {
|
||||
const isWhitespace = (control.value || '').trim().length === 0;
|
||||
const isControlValid = control.value.length === 0 || !isWhitespace;
|
||||
@@ -136,9 +135,10 @@ export class StartTaskComponent implements OnInit, OnDestroy {
|
||||
switchMap((createRes) =>
|
||||
this.attachForm(createRes.id, this.taskDetailsModel.formKey).pipe(
|
||||
defaultIfEmpty(createRes),
|
||||
switchMap((attachRes) =>
|
||||
this.assignTaskByUserId(createRes.id, this.assigneeId).pipe(defaultIfEmpty(attachRes ? attachRes : createRes))
|
||||
)
|
||||
switchMap((attachRes) => {
|
||||
const assigneeId = this.assigneeId ? this.assigneeId.toString() : null;
|
||||
return this.assignTaskByUserId(createRes.id, assigneeId).pipe(defaultIfEmpty(attachRes ? attachRes : createRes));
|
||||
})
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -154,7 +154,7 @@ export class StartTaskComponent implements OnInit, OnDestroy {
|
||||
);
|
||||
}
|
||||
|
||||
getAssigneeId(userId: number): void {
|
||||
setAssigneeId(userId: number): void {
|
||||
this.assigneeId = userId;
|
||||
}
|
||||
|
||||
@@ -162,10 +162,6 @@ export class StartTaskComponent implements OnInit, OnDestroy {
|
||||
this.cancel.emit();
|
||||
}
|
||||
|
||||
isUserNameEmpty(user: UserProcessModel): boolean {
|
||||
return !user || (this.isEmpty(user.firstName) && this.isEmpty(user.lastName));
|
||||
}
|
||||
|
||||
getDisplayUser(firstName: string, lastName: string, delimiter: string = '-'): string {
|
||||
firstName = firstName !== null ? firstName : '';
|
||||
lastName = lastName !== null ? lastName : '';
|
||||
@@ -209,10 +205,6 @@ export class StartTaskComponent implements OnInit, OnDestroy {
|
||||
return this.taskForm.get('description');
|
||||
}
|
||||
|
||||
get formKeyController(): AbstractControl {
|
||||
return this.taskForm.get('formKey');
|
||||
}
|
||||
|
||||
private attachForm(taskId: string, formKey: string): Observable<any> {
|
||||
let response: any = EMPTY;
|
||||
if (taskId && formKey) {
|
||||
@@ -221,7 +213,7 @@ export class StartTaskComponent implements OnInit, OnDestroy {
|
||||
return response;
|
||||
}
|
||||
|
||||
private assignTaskByUserId(taskId: string, userId: any): Observable<TaskDetailsModel> {
|
||||
private assignTaskByUserId(taskId: string, userId: string): Observable<TaskDetailsModel> {
|
||||
if (taskId && userId) {
|
||||
return this.taskService.assignTaskByUserId(taskId, userId);
|
||||
}
|
||||
@@ -231,8 +223,4 @@ export class StartTaskComponent implements OnInit, OnDestroy {
|
||||
private loadFormsTask(): void {
|
||||
this.forms$ = this.taskService.getFormList();
|
||||
}
|
||||
|
||||
private isEmpty(data: string): boolean {
|
||||
return data === undefined || data === null || data.trim().length === 0;
|
||||
}
|
||||
}
|
||||
|
@@ -51,14 +51,12 @@
|
||||
<adf-info-drawer-tab label="ADF_TASK_LIST.DETAILS.LABELS.INFO_DRAWER_TAB_DETAILS_TITLE">
|
||||
<div class="adf-assignment-container" *ngIf="showAssignee">
|
||||
<adf-people-search
|
||||
[headerTitle]="'ADF_TASK_LIST.DETAILS.LABELS.ADD_ASSIGNEE'"
|
||||
[actionLabel]="'ADF_TASK_LIST.PEOPLE.ADD_ASSIGNEE'"
|
||||
(searchPeople)="searchUser($event)"
|
||||
(success)="assignTaskToUser($event)"
|
||||
(closeSearch)="onCloseSearch()"
|
||||
[results]="peopleSearch">
|
||||
<ng-container adf-people-search-title>{{ 'ADF_TASK_LIST.DETAILS.LABELS.ADD_ASSIGNEE' | translate }}
|
||||
</ng-container>
|
||||
<ng-container adf-people-search-action-label>{{ 'ADF_TASK_LIST.PEOPLE.ADD_ASSIGNEE' | translate }}
|
||||
</ng-container>
|
||||
</adf-people-search>
|
||||
</div>
|
||||
<adf-task-header
|
||||
|
@@ -28,18 +28,18 @@ import { ProcessTestingModule } from '../../testing/process.testing.module';
|
||||
import { TaskService } from '../../form/services/task.service';
|
||||
import { TaskFormService } from '../../form/services/task-form.service';
|
||||
import { TaskCommentsService } from '../../task-comments/services/task-comments.service';
|
||||
import { UserProcessModel } from '../../common/models/user-process.model';
|
||||
import { PeopleProcessService } from '../../common/services/people-process.service';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { HarnessLoader } from '@angular/cdk/testing';
|
||||
import { MatDialogHarness } from '@angular/material/dialog/testing';
|
||||
import { LightUserRepresentation } from '@alfresco/js-api';
|
||||
|
||||
const fakeUser = new UserProcessModel({
|
||||
id: 'fake-id',
|
||||
const fakeUser: LightUserRepresentation = {
|
||||
id: 0,
|
||||
firstName: 'fake-name',
|
||||
lastName: 'fake-last',
|
||||
email: 'fake@mail.com'
|
||||
});
|
||||
};
|
||||
|
||||
const fakeTaskAssignResponse = new TaskDetailsModel({
|
||||
id: 'fake-id',
|
||||
@@ -385,18 +385,20 @@ describe('TaskDetailsComponent', () => {
|
||||
id: 1,
|
||||
firstName: 'fake-test-1',
|
||||
lastName: 'fake-last-1',
|
||||
email: 'fake-test-1@test.com'
|
||||
email: 'fake-test-1@test.com',
|
||||
avatarId: '1'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
firstName: 'fake-test-2',
|
||||
lastName: 'fake-last-2',
|
||||
email: 'fake-test-2@test.com'
|
||||
email: 'fake-test-2@test.com',
|
||||
avatarId: '2'
|
||||
}
|
||||
])
|
||||
);
|
||||
|
||||
let lastValue: UserProcessModel[];
|
||||
let lastValue: LightUserRepresentation[];
|
||||
component.peopleSearch.subscribe((users) => (lastValue = users));
|
||||
component.searchUser('fake-search-word');
|
||||
|
||||
@@ -410,7 +412,7 @@ describe('TaskDetailsComponent', () => {
|
||||
it('should return an empty list for not valid search', () => {
|
||||
spyOn(peopleProcessService, 'getWorkflowUsers').and.returnValue(of([]));
|
||||
|
||||
let lastValue: UserProcessModel[];
|
||||
let lastValue: LightUserRepresentation[];
|
||||
component.peopleSearch.subscribe((users) => (lastValue = users));
|
||||
component.searchUser('fake-search-word');
|
||||
|
||||
|
@@ -39,13 +39,12 @@ import {
|
||||
} from '@angular/core';
|
||||
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
|
||||
import { Observable, Observer, of, Subject } from 'rxjs';
|
||||
import { TaskQueryRequestRepresentationModel } from '../models/filter.model';
|
||||
import { TaskDetailsModel } from '../models/task-details.model';
|
||||
import { TaskListService } from './../services/tasklist.service';
|
||||
import { catchError, share, takeUntil } from 'rxjs/operators';
|
||||
import { TaskFormComponent } from './task-form/task-form.component';
|
||||
import { UserProcessModel } from '../../common/models/user-process.model';
|
||||
import { PeopleProcessService } from '../../common/services/people-process.service';
|
||||
import { LightUserRepresentation, TaskQueryRepresentation } from '@alfresco/js-api';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-task-details',
|
||||
@@ -164,16 +163,16 @@ export class TaskDetailsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
|
||||
taskDetails: TaskDetailsModel;
|
||||
taskFormName: string = null;
|
||||
taskPeople: UserProcessModel[] = [];
|
||||
taskPeople: LightUserRepresentation[] = [];
|
||||
noTaskDetailsTemplateComponent: TemplateRef<any>;
|
||||
showAssignee = false;
|
||||
showAttachForm = false;
|
||||
internalReadOnlyForm = false;
|
||||
errorDialogRef: MatDialogRef<TemplateRef<any>>;
|
||||
peopleSearch: Observable<UserProcessModel[]>;
|
||||
peopleSearch: Observable<LightUserRepresentation[]>;
|
||||
data: any;
|
||||
|
||||
private peopleSearchObserver: Observer<UserProcessModel[]>;
|
||||
private peopleSearchObserver: Observer<LightUserRepresentation[]>;
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
constructor(
|
||||
@@ -184,7 +183,7 @@ export class TaskDetailsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.peopleSearch = new Observable<UserProcessModel[]>((observer) => (this.peopleSearchObserver = observer)).pipe(share());
|
||||
this.peopleSearch = new Observable<LightUserRepresentation[]>((observer) => (this.peopleSearchObserver = observer)).pipe(share());
|
||||
|
||||
if (this.taskId) {
|
||||
this.loadDetails(this.taskId);
|
||||
@@ -299,7 +298,7 @@ export class TaskDetailsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
this.showAssignee = false;
|
||||
}
|
||||
|
||||
assignTaskToUser(selectedUser: UserProcessModel) {
|
||||
assignTaskToUser(selectedUser: LightUserRepresentation) {
|
||||
this.taskListService.assignTask(this.taskDetails.id, selectedUser).subscribe(() => {
|
||||
this.assignTask.emit();
|
||||
});
|
||||
@@ -363,16 +362,14 @@ export class TaskDetailsComponent implements OnInit, OnChanges, OnDestroy {
|
||||
}
|
||||
|
||||
if (this.taskDetails?.involvedPeople) {
|
||||
this.taskDetails.involvedPeople.forEach((user) => {
|
||||
this.taskPeople.push(new UserProcessModel(user));
|
||||
});
|
||||
this.taskPeople.push(...this.taskDetails.involvedPeople);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private loadNextTask(processInstanceId: string, processDefinitionId: string): void {
|
||||
const requestNode = new TaskQueryRequestRepresentationModel({
|
||||
const requestNode = new TaskQueryRepresentation({
|
||||
processInstanceId,
|
||||
processDefinitionId
|
||||
});
|
||||
|
@@ -20,15 +20,35 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { AppsProcessService } from '../../app-list/services/apps-process.service';
|
||||
import { AppConfigService } from '@alfresco/adf-core';
|
||||
import { of, throwError } from 'rxjs';
|
||||
import { FilterParamsModel, FilterRepresentationModel } from '../models/filter.model';
|
||||
import { TaskListService } from '../services/tasklist.service';
|
||||
import { TaskFilterService } from '../services/task-filter.service';
|
||||
import { TaskFiltersComponent } from './task-filters.component';
|
||||
import { ProcessTestingModule } from '../../testing/process.testing.module';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { fakeTaskFilters } from '../../mock/task/task-filters.mock';
|
||||
import { NavigationStart, Router } from '@angular/router';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { UserTaskFilterRepresentation } from '@alfresco/js-api';
|
||||
|
||||
const fakeTaskFilters = [
|
||||
new UserTaskFilterRepresentation({
|
||||
name: 'FakeInvolvedTasks',
|
||||
icon: 'glyphicon-align-left',
|
||||
id: 10,
|
||||
filter: { state: 'open', assignment: 'fake-involved' }
|
||||
}),
|
||||
new UserTaskFilterRepresentation({
|
||||
name: 'FakeMyTasks1',
|
||||
icon: 'glyphicon-ok-sign',
|
||||
id: 11,
|
||||
filter: { state: 'open', assignment: 'fake-assignee' }
|
||||
}),
|
||||
new UserTaskFilterRepresentation({
|
||||
name: 'FakeMyTasks2',
|
||||
icon: 'glyphicon-inbox',
|
||||
id: 12,
|
||||
filter: { state: 'open', assignment: 'fake-assignee' }
|
||||
})
|
||||
];
|
||||
|
||||
describe('TaskFiltersComponent', () => {
|
||||
let taskListService: TaskListService;
|
||||
@@ -114,7 +134,7 @@ describe('TaskFiltersComponent', () => {
|
||||
|
||||
it('should select the task filter based on the input by name param', () => {
|
||||
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(of(fakeTaskFilters));
|
||||
component.filterParam = new FilterParamsModel({ name: 'FakeMyTasks1' });
|
||||
component.filterParam = new UserTaskFilterRepresentation({ name: 'FakeMyTasks1' });
|
||||
|
||||
let lastValue: any;
|
||||
component.success.subscribe((res) => (lastValue = res));
|
||||
@@ -130,7 +150,7 @@ describe('TaskFiltersComponent', () => {
|
||||
|
||||
it('should select the task filter based on the input by index param', () => {
|
||||
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(of(fakeTaskFilters));
|
||||
component.filterParam = new FilterParamsModel({ index: 2 });
|
||||
component.filterParam = new UserTaskFilterRepresentation({ index: 2 });
|
||||
|
||||
let lastValue: any;
|
||||
component.success.subscribe((res) => (lastValue = res));
|
||||
@@ -147,7 +167,7 @@ describe('TaskFiltersComponent', () => {
|
||||
it('should select the task filter based on the input by id param', () => {
|
||||
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(of(fakeTaskFilters));
|
||||
|
||||
component.filterParam = new FilterParamsModel({ id: 10 });
|
||||
component.filterParam = new UserTaskFilterRepresentation({ id: 10 });
|
||||
|
||||
const appId = '1';
|
||||
const change = new SimpleChange(null, appId, true);
|
||||
@@ -166,7 +186,7 @@ describe('TaskFiltersComponent', () => {
|
||||
spyOn(component.filterSelected, 'emit');
|
||||
component.filters = fakeTaskFilters;
|
||||
|
||||
const filterParam = new FilterParamsModel({ id: 10 });
|
||||
const filterParam = new UserTaskFilterRepresentation({ id: 10 });
|
||||
const change = new SimpleChange(null, filterParam, true);
|
||||
component.filterParam = filterParam;
|
||||
|
||||
@@ -257,7 +277,7 @@ describe('TaskFiltersComponent', () => {
|
||||
});
|
||||
|
||||
it('should not change the current filter if no filter with taskid is found', () => {
|
||||
const filter = new FilterRepresentationModel({
|
||||
const filter = new UserTaskFilterRepresentation({
|
||||
name: 'FakeMyTasks',
|
||||
filter: { state: 'open', assignment: 'fake-assignee' }
|
||||
});
|
||||
@@ -300,7 +320,7 @@ describe('TaskFiltersComponent', () => {
|
||||
it('should reset selection when filterParam is a filter that does not exist', async () => {
|
||||
spyOn(taskFilterService, 'getTaskListFilters').and.returnValue(of(fakeTaskFilters));
|
||||
component.currentFilter = fakeTaskFilters[0];
|
||||
component.filterParam = new FilterRepresentationModel({ name: 'non-existing-filter' });
|
||||
component.filterParam = { name: 'non-existing-filter' };
|
||||
const appId = '1';
|
||||
|
||||
const change = new SimpleChange(null, appId, true);
|
||||
|
@@ -17,13 +17,13 @@
|
||||
|
||||
import { AppsProcessService } from '../../app-list/services/apps-process.service';
|
||||
import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges, ViewEncapsulation } from '@angular/core';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { FilterParamsModel, FilterRepresentationModel } from '../models/filter.model';
|
||||
import { Subject } from 'rxjs';
|
||||
import { TaskFilterService } from './../services/task-filter.service';
|
||||
import { TaskListService } from './../services/tasklist.service';
|
||||
import { IconModel } from '../../app-list/icon.model';
|
||||
import { ActivatedRoute, NavigationStart, Router } from '@angular/router';
|
||||
import { filter, takeUntil } from 'rxjs/operators';
|
||||
import { UserTaskFilterRepresentation } from '@alfresco/js-api';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-task-filters',
|
||||
@@ -37,15 +37,15 @@ export class TaskFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
* the default filter (the first one the list) is selected.
|
||||
*/
|
||||
@Input()
|
||||
filterParam: FilterParamsModel;
|
||||
filterParam: UserTaskFilterRepresentation;
|
||||
|
||||
/** Emitted when a filter is being clicked from the UI. */
|
||||
@Output()
|
||||
filterClicked = new EventEmitter<FilterRepresentationModel>();
|
||||
filterClicked = new EventEmitter<UserTaskFilterRepresentation>();
|
||||
|
||||
/** Emitted when a filter is being selected based on the filterParam input. */
|
||||
@Output()
|
||||
filterSelected = new EventEmitter<FilterRepresentationModel>();
|
||||
filterSelected = new EventEmitter<UserTaskFilterRepresentation>();
|
||||
|
||||
/** Emitted when the list is loaded. */
|
||||
@Output()
|
||||
@@ -67,11 +67,8 @@ export class TaskFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
@Input()
|
||||
showIcon: boolean;
|
||||
|
||||
filter$: Observable<FilterRepresentationModel>;
|
||||
|
||||
currentFilter: FilterRepresentationModel;
|
||||
|
||||
filters: FilterRepresentationModel[] = [];
|
||||
currentFilter: UserTaskFilterRepresentation;
|
||||
filters: UserTaskFilterRepresentation[] = [];
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
isTaskRoute: boolean;
|
||||
@@ -117,24 +114,10 @@ export class TaskFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
isActiveRoute(filterActive: FilterRepresentationModel): boolean {
|
||||
isActiveRoute(filterActive: UserTaskFilterRepresentation): boolean {
|
||||
return (this.isTaskActive || this.isTaskRoute) && this.currentFilter === filterActive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the task list filtered by appId or by appName
|
||||
*
|
||||
* @param appId application id
|
||||
* @param appName application name
|
||||
*/
|
||||
getFilters(appId?: number, appName?: string): void {
|
||||
if (appName) {
|
||||
this.getFiltersByAppName(appName);
|
||||
} else {
|
||||
this.getFiltersByAppId(appId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the filter list filtered by appId
|
||||
*
|
||||
@@ -142,7 +125,7 @@ export class TaskFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
*/
|
||||
getFiltersByAppId(appId?: number) {
|
||||
this.taskFilterService.getTaskListFilters(appId).subscribe(
|
||||
(res: FilterRepresentationModel[]) => {
|
||||
(res) => {
|
||||
if (res.length === 0 && this.isFilterListEmpty()) {
|
||||
this.createFiltersByAppId(appId);
|
||||
} else {
|
||||
@@ -179,9 +162,9 @@ export class TaskFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
*
|
||||
* @param appId application id
|
||||
*/
|
||||
createFiltersByAppId(appId?: number): void {
|
||||
private createFiltersByAppId(appId?: number): void {
|
||||
this.taskFilterService.createDefaultFilters(appId).subscribe(
|
||||
(resDefault: FilterRepresentationModel[]) => {
|
||||
(resDefault) => {
|
||||
this.resetFilter();
|
||||
this.filters = resDefault;
|
||||
this.selectFilter(this.filterParam);
|
||||
@@ -198,7 +181,7 @@ export class TaskFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
*
|
||||
* @param newFilter new filter model
|
||||
*/
|
||||
public selectFilter(newFilter: FilterParamsModel): void {
|
||||
public selectFilter(newFilter: UserTaskFilterRepresentation): void {
|
||||
if (newFilter) {
|
||||
this.currentFilter = this.filters.find(
|
||||
(entry, index) =>
|
||||
@@ -209,7 +192,7 @@ export class TaskFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
public selectFilterAndEmit(newFilter: FilterParamsModel) {
|
||||
private selectFilterAndEmit(newFilter: UserTaskFilterRepresentation) {
|
||||
this.selectFilter(newFilter);
|
||||
this.filterSelected.emit(this.currentFilter);
|
||||
}
|
||||
@@ -219,7 +202,7 @@ export class TaskFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
*
|
||||
* @param filterParams filter parameters model
|
||||
*/
|
||||
onFilterClick(filterParams: FilterParamsModel) {
|
||||
onFilterClick(filterParams: UserTaskFilterRepresentation) {
|
||||
this.selectFilter(filterParams);
|
||||
this.filterClicked.emit(this.currentFilter);
|
||||
}
|
||||
@@ -230,9 +213,9 @@ export class TaskFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
* @param taskId task id
|
||||
*/
|
||||
selectFilterWithTask(taskId: string): void {
|
||||
const filteredFilterList: FilterRepresentationModel[] = [];
|
||||
const filteredFilterList: UserTaskFilterRepresentation[] = [];
|
||||
this.taskListService.getFilterForTaskById(taskId, this.filters).subscribe(
|
||||
(filterModel: FilterRepresentationModel) => {
|
||||
(filterModel) => {
|
||||
filteredFilterList.push(filterModel);
|
||||
},
|
||||
(err) => {
|
||||
@@ -247,21 +230,12 @@ export class TaskFiltersComponent implements OnInit, OnChanges, OnDestroy {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Select as default task filter the first in the list
|
||||
*/
|
||||
public selectDefaultTaskFilter(): void {
|
||||
if (!this.isFilterListEmpty()) {
|
||||
this.currentFilter = this.filters[0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current filter
|
||||
*
|
||||
* @returns filter model
|
||||
*/
|
||||
getCurrentFilter(): FilterRepresentationModel {
|
||||
getCurrentFilter(): UserTaskFilterRepresentation {
|
||||
return this.currentFilter;
|
||||
}
|
||||
|
||||
|
@@ -21,7 +21,7 @@ import { TaskDetailsModel } from '../../models/task-details.model';
|
||||
import { TaskListService } from '../../services/tasklist.service';
|
||||
import { UserRepresentation } from '@alfresco/js-api';
|
||||
import { Observable } from 'rxjs';
|
||||
import { PeopleProcessService } from '../../../common/services/people-process.service';
|
||||
import { PeopleProcessService } from '../../../common';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-task-form',
|
||||
@@ -122,7 +122,6 @@ export class TaskFormComponent implements OnInit, OnChanges {
|
||||
taskDetails: TaskDetailsModel;
|
||||
currentLoggedUser: UserRepresentation;
|
||||
loading: boolean = false;
|
||||
completedTaskMessage: string;
|
||||
internalReadOnlyForm: boolean = false;
|
||||
|
||||
constructor(
|
||||
@@ -218,10 +217,6 @@ export class TaskFormComponent implements OnInit, OnChanges {
|
||||
return !this.taskDetails?.processDefinitionId;
|
||||
}
|
||||
|
||||
isTaskLoaded(): boolean {
|
||||
return !!this.taskDetails;
|
||||
}
|
||||
|
||||
isCompletedTask(): boolean {
|
||||
return !!this.taskDetails?.endDate;
|
||||
}
|
||||
@@ -314,10 +309,6 @@ export class TaskFormComponent implements OnInit, OnChanges {
|
||||
return this.isCandidateMember() && this.isAssignedToMe() && !this.isCompletedTask();
|
||||
}
|
||||
|
||||
reloadTask() {
|
||||
this.loadTask(this.taskId);
|
||||
}
|
||||
|
||||
onClaimTask(taskId: string) {
|
||||
this.taskClaimed.emit(taskId);
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user