From 574cc9c1a6eda8da55686d1ba57302ea517247f6 Mon Sep 17 00:00:00 2001 From: Deepak Paul Date: Wed, 13 Mar 2019 17:03:40 +0530 Subject: [PATCH] [ADF-4123] Process Cloud Instance Details Header component (#4418) * [ADF-4123] Added service to get process instance details * [ADF-4123] Added process header component * [ADF-4123] Added more properties to model * [ADF-4123] Exported process sidebar * [ADF-4123] Added new process instance details demo component * [ADF-4123] Added tests for module * [ADF-4123] Added tests for process-header * [ADF-4123] Added documentation --- demo-shell/src/app/app.module.ts | 2 + demo-shell/src/app/app.routes.ts | 6 + .../process-details-cloud-demo.component.html | 11 + .../process-details-cloud-demo.component.scss | 0 .../process-details-cloud-demo.component.ts | 43 ++++ .../cloud/processes-cloud-demo.component.ts | 4 +- .../images/adf-cloud-process-header.png | Bin 0 -> 14781 bytes .../process-header-cloud.component.md | 51 ++++ .../process-header-cloud.service.md | 31 +++ .../src/lib/i18n/en.json | 15 ++ .../src/lib/process/process-cloud.module.ts | 5 +- .../process-header-cloud.component.html | 5 + .../process-header-cloud.component.scss | 0 .../process-header-cloud.component.spec.ts | 230 ++++++++++++++++++ .../process-header-cloud.component.ts | 142 +++++++++++ .../process-header-cloud.module.spec.ts | 30 +++ .../process-header-cloud.module.ts | 38 +++ .../lib/process/process-header/public-api.ts | 20 ++ .../services/process-header-cloud.service.ts | 71 ++++++ .../src/lib/process/public-api.ts | 1 + .../models/process-instance-cloud.model.ts | 8 + 21 files changed, 710 insertions(+), 3 deletions(-) create mode 100644 demo-shell/src/app/components/app-layout/cloud/process-details-cloud-demo.component.html create mode 100644 demo-shell/src/app/components/app-layout/cloud/process-details-cloud-demo.component.scss create mode 100644 demo-shell/src/app/components/app-layout/cloud/process-details-cloud-demo.component.ts create mode 100644 docs/docassets/images/adf-cloud-process-header.png create mode 100644 docs/process-services-cloud/process-header-cloud.component.md create mode 100644 docs/process-services-cloud/process-header-cloud.service.md create mode 100644 lib/process-services-cloud/src/lib/process/process-header/components/process-header-cloud.component.html create mode 100644 lib/process-services-cloud/src/lib/process/process-header/components/process-header-cloud.component.scss create mode 100644 lib/process-services-cloud/src/lib/process/process-header/components/process-header-cloud.component.spec.ts create mode 100644 lib/process-services-cloud/src/lib/process/process-header/components/process-header-cloud.component.ts create mode 100644 lib/process-services-cloud/src/lib/process/process-header/process-header-cloud.module.spec.ts create mode 100644 lib/process-services-cloud/src/lib/process/process-header/process-header-cloud.module.ts create mode 100644 lib/process-services-cloud/src/lib/process/process-header/public-api.ts create mode 100644 lib/process-services-cloud/src/lib/process/process-header/services/process-header-cloud.service.ts diff --git a/demo-shell/src/app/app.module.ts b/demo-shell/src/app/app.module.ts index 84914b8208..cf0bbe05fc 100644 --- a/demo-shell/src/app/app.module.ts +++ b/demo-shell/src/app/app.module.ts @@ -79,6 +79,7 @@ import { TemplateDemoComponent } from './components/template-list/template-demo. import { PeopleGroupCloudDemoComponent } from './components/app-layout/cloud/people-groups-cloud-demo.component'; import { CloudSettingsComponent } from './components/app-layout/cloud/cloud-settings.component'; import { AppExtensionsModule } from './app-extension.module'; +import { ProcessDetailsCloudDemoComponent } from './components/app-layout/cloud/process-details-cloud-demo.component'; @NgModule({ imports: [ @@ -137,6 +138,7 @@ import { AppExtensionsModule } from './app-extension.module'; TasksCloudDemoComponent, ProcessesCloudDemoComponent, TaskDetailsCloudDemoComponent, + ProcessDetailsCloudDemoComponent, StartTaskCloudDemoComponent, StartProcessCloudDemoComponent, CloudBreadcrumbsComponent, diff --git a/demo-shell/src/app/app.routes.ts b/demo-shell/src/app/app.routes.ts index 99e0abbf53..b4c596abc3 100644 --- a/demo-shell/src/app/app.routes.ts +++ b/demo-shell/src/app/app.routes.ts @@ -48,6 +48,7 @@ import { StartTaskCloudDemoComponent } from './components/app-layout/cloud/start import { StartProcessCloudDemoComponent } from './components/app-layout/cloud/start-process-cloud-demo.component'; import { TemplateDemoComponent } from './components/template-list/template-demo.component'; import { PeopleGroupCloudDemoComponent } from './components/app-layout/cloud/people-groups-cloud-demo.component'; +import { ProcessDetailsCloudDemoComponent } from './components/app-layout/cloud/process-details-cloud-demo.component'; export const appRoutes: Routes = [ { path: 'login', component: LoginComponent }, @@ -182,7 +183,12 @@ export const appRoutes: Routes = [ { path: 'task-details/:taskId', component: TaskDetailsCloudDemoComponent + }, + { + path: 'process-details/:processInstanceId', + component: ProcessDetailsCloudDemoComponent } + ] } ] diff --git a/demo-shell/src/app/components/app-layout/cloud/process-details-cloud-demo.component.html b/demo-shell/src/app/components/app-layout/cloud/process-details-cloud-demo.component.html new file mode 100644 index 0000000000..41041217c3 --- /dev/null +++ b/demo-shell/src/app/components/app-layout/cloud/process-details-cloud-demo.component.html @@ -0,0 +1,11 @@ + + + +

Simple page to show the process instance: {{ processInstanceId }} of the app: {{ appName }}

+ + + diff --git a/demo-shell/src/app/components/app-layout/cloud/process-details-cloud-demo.component.scss b/demo-shell/src/app/components/app-layout/cloud/process-details-cloud-demo.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/demo-shell/src/app/components/app-layout/cloud/process-details-cloud-demo.component.ts b/demo-shell/src/app/components/app-layout/cloud/process-details-cloud-demo.component.ts new file mode 100644 index 0000000000..cfbb6c696c --- /dev/null +++ b/demo-shell/src/app/components/app-layout/cloud/process-details-cloud-demo.component.ts @@ -0,0 +1,43 @@ +/*! + * @license + * Copyright 2019 Alfresco Software, Ltd. + * + * 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 { Component } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; + +@Component({ + templateUrl: './process-details-cloud-demo.component.html', + styleUrls: ['./process-details-cloud-demo.component.scss'] +}) +export class ProcessDetailsCloudDemoComponent { + + processInstanceId: string; + appName: string; + + constructor(private route: ActivatedRoute, private router: Router) { + this.route.params.subscribe((params) => { + this.processInstanceId = params.processInstanceId; + }); + + this.route.parent.params.subscribe((params) => { + this.appName = params.appName; + }); + } + + onGoBack() { + this.router.navigate([`/cloud/${this.appName}/`]); + } +} diff --git a/demo-shell/src/app/components/app-layout/cloud/processes-cloud-demo.component.ts b/demo-shell/src/app/components/app-layout/cloud/processes-cloud-demo.component.ts index 0f51bdcdda..9ff71c4c4c 100644 --- a/demo-shell/src/app/components/app-layout/cloud/processes-cloud-demo.component.ts +++ b/demo-shell/src/app/components/app-layout/cloud/processes-cloud-demo.component.ts @@ -100,8 +100,8 @@ export class ProcessesCloudDemoComponent implements OnInit { this.selectedRows = []; } - onRowClick($event) { - this.selectedRow = $event; + onRowClick(processInstanceId) { + this.router.navigate([`/cloud/${this.appName}/process-details/${processInstanceId}`]); } onFilterChange(query: any) { diff --git a/docs/docassets/images/adf-cloud-process-header.png b/docs/docassets/images/adf-cloud-process-header.png new file mode 100644 index 0000000000000000000000000000000000000000..c49fb43769b971f1c972f37463acfd312c2d6584 GIT binary patch literal 14781 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 + +``` + +## Class members + +### Properties + +| Name | Type | Default value | Description | +| ---- | ---- | ------------- | ----------- | +| appName | `string` | | (Required) The name of the application. | +| processInstanceId | `string` | | (Required) The id of the process instance. | + +## Details + +The component populates an internal array of +[CardViewModel](../core/card-view.component.md) with the information that we want to display. + +By default all properties are displayed: + +**_id_**, **_name_**, **_description_**, **_status_**, **_initiator_**, **_startDate_**, **_lastModified_**, **_parentId_**, **_businessKey_**. + +However, you can also choose which properties to show using a configuration in `app.config.json`: + +```json + "adf-cloud-process-header": { + "presets": { + "properties" : [ "name", "status", "initiator", "parentId"] + } + } +``` + +With this configuration, only the four listed properties will be shown. diff --git a/docs/process-services-cloud/process-header-cloud.service.md b/docs/process-services-cloud/process-header-cloud.service.md new file mode 100644 index 0000000000..02753a1c32 --- /dev/null +++ b/docs/process-services-cloud/process-header-cloud.service.md @@ -0,0 +1,31 @@ +--- +Title: Process Header Cloud Service +Added: v3.0.0 +Status: Experimental +Last reviewed: 2019-03-08 +--- + +# [Process Header Cloud Service](../../lib/process-services-cloud/src/lib/process/process-header/services/process-header-cloud.service.ts "Defined in process-header-cloud.service.ts") + +Manages cloud process instances. + +## Class members + +### Methods + +- **getProcessInstanceById**(appName: `string`, processInstanceId: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`ProcessInstanceCloud`](../../lib/process-services-cloud/src/lib/process/start-process/models/process-instance-cloud.model.ts)`>`
+ Gets details of a process instance. + - _appName:_ `string` - Name of the app + - _processInstanceId:_ `string` - ID of the process instance whose details you want + - **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`ProcessInstanceCloud`](../../lib/process-services-cloud/src/lib/process/start-process/models/process-instance-cloud.model.ts)`>` - Process instance details + +## Details + +The methods work in much the same way as the equivalent methods in the +[Processlist Cloud Component](./process-list-cloud.component.md) +but they use the cloud variants of the classes for return values. See the +[Processlist Cloud Service](./process-list-cloud.service.md) page for usage examples. + +## See also + +- [Processlist Cloud Service](./process-list-cloud.service.md) diff --git a/lib/process-services-cloud/src/lib/i18n/en.json b/lib/process-services-cloud/src/lib/i18n/en.json index a3bdb851f0..8cd8599f4a 100644 --- a/lib/process-services-cloud/src/lib/i18n/en.json +++ b/lib/process-services-cloud/src/lib/i18n/en.json @@ -204,5 +204,20 @@ "FORM_VALIDATION": { "INVALID_FIELD": "Enter a different value" } + }, + "ADF_CLOUD_PROCESS_HEADER": { + "PROPERTIES": { + "ID": "ID", + "NAME": "Name", + "DESCRIPTION": "Description", + "DESCRIPTION_DEFAULT": "No description", + "STATUS": "Status", + "BUSINESS_KEY": "Business Key", + "INITIATOR": "Initiator", + "START_DATE": "Start Date", + "LAST_MODIFIED": "Last Modified", + "PARENT_ID": "Parent Id", + "NONE": "None" + } } } diff --git a/lib/process-services-cloud/src/lib/process/process-cloud.module.ts b/lib/process-services-cloud/src/lib/process/process-cloud.module.ts index 8a9bf46ac1..757c16713b 100644 --- a/lib/process-services-cloud/src/lib/process/process-cloud.module.ts +++ b/lib/process-services-cloud/src/lib/process/process-cloud.module.ts @@ -20,18 +20,21 @@ import { ProcessFiltersCloudModule } from './process-filters/process-filters-clo import { ProcessListCloudModule } from './process-list/process-list-cloud.module'; import { StartProcessCloudModule } from './start-process/start-process-cloud.module'; import { CoreModule } from '@alfresco/adf-core'; +import { ProcessHeaderCloudModule } from './process-header/public-api'; @NgModule({ imports: [ ProcessFiltersCloudModule, ProcessListCloudModule, StartProcessCloudModule, + ProcessHeaderCloudModule, CoreModule ], exports: [ ProcessFiltersCloudModule, ProcessListCloudModule, - StartProcessCloudModule + StartProcessCloudModule, + ProcessHeaderCloudModule ] }) export class ProcessCloudModule { } diff --git a/lib/process-services-cloud/src/lib/process/process-header/components/process-header-cloud.component.html b/lib/process-services-cloud/src/lib/process/process-header/components/process-header-cloud.component.html new file mode 100644 index 0000000000..6889a8ef65 --- /dev/null +++ b/lib/process-services-cloud/src/lib/process/process-header/components/process-header-cloud.component.html @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/lib/process-services-cloud/src/lib/process/process-header/components/process-header-cloud.component.scss b/lib/process-services-cloud/src/lib/process/process-header/components/process-header-cloud.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lib/process-services-cloud/src/lib/process/process-header/components/process-header-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/process/process-header/components/process-header-cloud.component.spec.ts new file mode 100644 index 0000000000..92a3f36bbb --- /dev/null +++ b/lib/process-services-cloud/src/lib/process/process-header/components/process-header-cloud.component.spec.ts @@ -0,0 +1,230 @@ +/*! + * @license + * Copyright 2019 Alfresco Software, Ltd. + * + * 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 { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { setupTestBed, AppConfigService } from '@alfresco/adf-core'; +import { By } from '@angular/platform-browser'; +import { of } from 'rxjs'; +import { ProcessServiceCloudTestingModule } from '../../../testing/process-service-cloud.testing.module'; +import { ProcessHeaderCloudComponent } from './process-header-cloud.component'; +import { ProcessHeaderCloudModule } from '../process-header-cloud.module'; +import { ProcessHeaderCloudService } from '../services/process-header-cloud.service'; + +const processInstanceDetailsCloudMock = { + appName: 'app-form-mau', + businessKey: 'MyBusinessKey', + description: 'new desc', + id: '00fcc4ab-4290-11e9-b133-0a586460016a', + initiator: 'devopsuser', + lastModified: 1552152187081, + name: 'new name', + parentId: '00fcc4ab-4290-11e9-b133-0a586460016b', + startDate: 1552152187080, + status: 'RUNNING' +}; + +describe('ProcessHeaderCloudComponent', () => { + let component: ProcessHeaderCloudComponent; + let fixture: ComponentFixture; + let service: ProcessHeaderCloudService; + let appConfigService: AppConfigService; + + setupTestBed({ + imports: [ + ProcessServiceCloudTestingModule, + ProcessHeaderCloudModule + ] + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ProcessHeaderCloudComponent); + component = fixture.componentInstance; + service = TestBed.get(ProcessHeaderCloudService); + appConfigService = TestBed.get(AppConfigService); + spyOn(service, 'getProcessInstanceById').and.returnValue(of(processInstanceDetailsCloudMock)); + component.appName = 'myApp'; + component.processInstanceId = 'sdfsdf-323'; + }); + + it('should render empty component if no process instance details are provided', async(() => { + component.appName = undefined; + component.processInstanceId = undefined; + + component.ngOnChanges(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + expect(component.properties).toBeUndefined(); + }); + })); + + it('should display process instance id', async(() => { + component.ngOnChanges(); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + const formNameEl = fixture.debugElement.query(By.css('[data-automation-id="card-textitem-value-id"] span')); + expect(formNameEl.nativeElement.innerText).toBe('00fcc4ab-4290-11e9-b133-0a586460016a'); + }); + })); + + it('should display name', async(() => { + component.ngOnChanges(); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + const formNameEl = fixture.debugElement.query(By.css('[data-automation-id="card-textitem-value-name"] span')); + expect(formNameEl.nativeElement.innerText).toBe('new name'); + }); + })); + + it('should display description', async(() => { + component.ngOnChanges(); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + const formNameEl = fixture.debugElement.query(By.css('[data-automation-id="card-textitem-value-description"] span')); + expect(formNameEl.nativeElement.innerText).toBe('new desc'); + }); + })); + + it('should display placeholder if no description is avilable', async(() => { + processInstanceDetailsCloudMock.description = null; + component.ngOnChanges(); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + const valueEl = fixture.debugElement.query(By.css('[data-automation-id="card-textitem-value-description"] span')); + expect(valueEl.nativeElement.innerText).toBe('ADF_CLOUD_PROCESS_HEADER.PROPERTIES.DESCRIPTION_DEFAULT'); + }); + + })); + + it('should display status', async(() => { + component.ngOnChanges(); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + const formNameEl = fixture.debugElement.query(By.css('[data-automation-id="card-textitem-value-status"] span')); + expect(formNameEl.nativeElement.innerText).toBe('RUNNING'); + }); + })); + + it('should display initiator', async(() => { + component.ngOnChanges(); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + const formNameEl = fixture.debugElement.query(By.css('[data-automation-id="card-textitem-value-initiator"] span')); + expect(formNameEl.nativeElement.innerText).toBe('devopsuser'); + }); + })); + + it('should display start date', async(() => { + component.ngOnChanges(); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + const valueEl = fixture.debugElement.query(By.css('[data-automation-id="header-startDate"] .adf-property-value')); + expect(valueEl.nativeElement.innerText.trim()).toBe('09-03-2019'); + }); + })); + + it('should display lastModified date', async(() => { + component.ngOnChanges(); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + const valueEl = fixture.debugElement.query(By.css('[data-automation-id="header-lastModified"] .adf-property-value')); + expect(valueEl.nativeElement.innerText.trim()).toBe('09-03-2019'); + }); + })); + + it('should display parentId', async(() => { + component.ngOnChanges(); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + const formNameEl = fixture.debugElement.query(By.css('[data-automation-id="card-textitem-value-parentId"] span')); + expect(formNameEl.nativeElement.innerText).toBe('00fcc4ab-4290-11e9-b133-0a586460016b'); + }); + })); + + it('should display default value when parentId is not available', async(() => { + processInstanceDetailsCloudMock.parentId = null; + component.ngOnChanges(); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + const formNameEl = fixture.debugElement.query(By.css('[data-automation-id="card-textitem-value-parentId"] span')); + expect(formNameEl.nativeElement.innerText).toBe('ADF_CLOUD_PROCESS_HEADER.PROPERTIES.NONE'); + }); + })); + + it('should display businessKey', async(() => { + component.ngOnChanges(); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + const formNameEl = fixture.debugElement.query(By.css('[data-automation-id="card-textitem-value-businessKey"] span')); + expect(formNameEl.nativeElement.innerText).toBe('MyBusinessKey'); + }); + })); + + it('should display default value when businessKey is not available', async(() => { + processInstanceDetailsCloudMock.businessKey = null; + component.ngOnChanges(); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + const formNameEl = fixture.debugElement.query(By.css('[data-automation-id="card-textitem-value-businessKey"] span')); + expect(formNameEl.nativeElement.innerText).toBe('ADF_CLOUD_PROCESS_HEADER.PROPERTIES.NONE'); + }); + })); + + describe('Config Filtering', () => { + + it('should show only the properties from the configuration file', async(() => { + spyOn(appConfigService, 'get').and.returnValue(['name', 'status']); + component.ngOnChanges(); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + const propertyList = fixture.debugElement.queryAll(By.css('.adf-property-list .adf-property')); + expect(propertyList).toBeDefined(); + expect(propertyList).not.toBeNull(); + expect(propertyList.length).toBe(2); + expect(propertyList[0].nativeElement.textContent).toContain('ADF_CLOUD_PROCESS_HEADER.PROPERTIES.NAME'); + expect(propertyList[1].nativeElement.textContent).toContain('ADF_CLOUD_PROCESS_HEADER.PROPERTIES.STATUS'); + }); + })); + + it('should show all the default properties if there is no configuration', async(() => { + spyOn(appConfigService, 'get').and.returnValue(null); + component.ngOnChanges(); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + const propertyList = fixture.debugElement.queryAll(By.css('.adf-property-list .adf-property')); + expect(propertyList).toBeDefined(); + expect(propertyList).not.toBeNull(); + expect(propertyList.length).toBe(component.properties.length); + expect(propertyList[0].nativeElement.textContent).toContain('ADF_CLOUD_PROCESS_HEADER.PROPERTIES.ID'); + expect(propertyList[1].nativeElement.textContent).toContain('ADF_CLOUD_PROCESS_HEADER.PROPERTIES.NAME'); + }); + })); + }); +}); diff --git a/lib/process-services-cloud/src/lib/process/process-header/components/process-header-cloud.component.ts b/lib/process-services-cloud/src/lib/process/process-header/components/process-header-cloud.component.ts new file mode 100644 index 0000000000..ed47b083a2 --- /dev/null +++ b/lib/process-services-cloud/src/lib/process/process-header/components/process-header-cloud.component.ts @@ -0,0 +1,142 @@ +/*! + * @license + * Copyright 2019 Alfresco Software, Ltd. + * + * 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 { Component, Input, OnChanges } from '@angular/core'; +import { CardViewItem, CardViewTextItemModel, TranslationService, AppConfigService, CardViewDateItemModel, CardViewBaseItemModel } from '@alfresco/adf-core'; +import { ProcessInstanceCloud } from '../../start-process/public-api'; +import { ProcessHeaderCloudService } from '../services/process-header-cloud.service'; + +@Component({ + selector: 'adf-cloud-process-header', + templateUrl: './process-header-cloud.component.html', + styleUrls: ['./process-header-cloud.component.scss'] +}) + +export class ProcessHeaderCloudComponent implements OnChanges { + + /** (Required) The name of the application. */ + @Input() + appName: string; + + /** (Required) The id of the process instance. */ + @Input() + processInstanceId: string; + + processInstanceDetails: ProcessInstanceCloud = new ProcessInstanceCloud(); + + properties: CardViewItem[]; + + constructor( + private processHeaderCloudService: ProcessHeaderCloudService, + private translationService: TranslationService, + private appConfig: AppConfigService) { + } + + ngOnChanges() { + if (this.appName && this.processInstanceId) { + this.loadProcessInstanceDetails(this.appName, this.processInstanceId); + } + } + + private loadProcessInstanceDetails(appName: string, processInstanceId: string) { + this.processHeaderCloudService.getProcessInstanceById(appName, processInstanceId).subscribe( + (processInstanceDetails) => { + this.processInstanceDetails = processInstanceDetails; + this.refreshData(); + }); + } + + /** + * Refresh the card data + */ + refreshData() { + if (this.processInstanceDetails) { + const defaultProperties = this.initDefaultProperties(); + const filteredProperties: string[] = this.appConfig.get('adf-cloud-process-header.presets.properties'); + this.properties = defaultProperties.filter((cardItem) => this.isValidSelection(filteredProperties, cardItem)); + } + } + + private initDefaultProperties(): any[] { + return [ + new CardViewTextItemModel( + { + label: 'ADF_CLOUD_PROCESS_HEADER.PROPERTIES.ID', + value: this.processInstanceDetails.id, + key: 'id' + }), + new CardViewTextItemModel( + { + label: 'ADF_CLOUD_PROCESS_HEADER.PROPERTIES.NAME', + value: this.processInstanceDetails.name, + key: 'name' + }), + new CardViewTextItemModel( + { + label: 'ADF_CLOUD_PROCESS_HEADER.PROPERTIES.DESCRIPTION', + value: this.processInstanceDetails.description, + key: 'description', + default: this.translationService.instant('ADF_CLOUD_PROCESS_HEADER.PROPERTIES.DESCRIPTION_DEFAULT') + }), + new CardViewTextItemModel( + { + label: 'ADF_CLOUD_PROCESS_HEADER.PROPERTIES.STATUS', + value: this.processInstanceDetails.status, + key: 'status' + }), + new CardViewTextItemModel( + { + label: 'ADF_CLOUD_PROCESS_HEADER.PROPERTIES.INITIATOR', + value: this.processInstanceDetails.initiator, + key: 'initiator' + }), + new CardViewDateItemModel( + { + label: 'ADF_CLOUD_PROCESS_HEADER.PROPERTIES.START_DATE', + value: this.processInstanceDetails.startDate, + format: 'DD-MM-YYYY', + key: 'startDate' + }), + new CardViewDateItemModel( + { + label: 'ADF_CLOUD_PROCESS_HEADER.PROPERTIES.LAST_MODIFIED', + value: this.processInstanceDetails.lastModified, + format: 'DD-MM-YYYY', + key: 'lastModified' + }), + new CardViewTextItemModel( + { + label: 'ADF_CLOUD_PROCESS_HEADER.PROPERTIES.PARENT_ID', + value: this.processInstanceDetails.parentId, + key: 'parentId', + default: this.translationService.instant('ADF_CLOUD_PROCESS_HEADER.PROPERTIES.NONE') + }), + new CardViewTextItemModel( + { + label: 'ADF_CLOUD_PROCESS_HEADER.PROPERTIES.BUSINESS_KEY', + value: this.processInstanceDetails.businessKey, + key: 'businessKey', + default: this.translationService.instant('ADF_CLOUD_PROCESS_HEADER.PROPERTIES.NONE') + }) + ]; + } + + private isValidSelection(filteredProperties: string[], cardItem: CardViewBaseItemModel): boolean { + return filteredProperties ? filteredProperties.indexOf(cardItem.key) >= 0 : true; + } + +} diff --git a/lib/process-services-cloud/src/lib/process/process-header/process-header-cloud.module.spec.ts b/lib/process-services-cloud/src/lib/process/process-header/process-header-cloud.module.spec.ts new file mode 100644 index 0000000000..72e2627563 --- /dev/null +++ b/lib/process-services-cloud/src/lib/process/process-header/process-header-cloud.module.spec.ts @@ -0,0 +1,30 @@ +/*! + * @license + * Copyright 2019 Alfresco Software, Ltd. + * + * 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 { ProcessHeaderCloudModule } from './process-header-cloud.module'; + +describe('ProcessHeaderCloudModule', () => { + let processHeaderCloudModule: ProcessHeaderCloudModule; + + beforeEach(() => { + processHeaderCloudModule = new ProcessHeaderCloudModule(); + }); + + it('should create an instance', () => { + expect(processHeaderCloudModule).toBeTruthy(); + }); +}); diff --git a/lib/process-services-cloud/src/lib/process/process-header/process-header-cloud.module.ts b/lib/process-services-cloud/src/lib/process/process-header/process-header-cloud.module.ts new file mode 100644 index 0000000000..6517768503 --- /dev/null +++ b/lib/process-services-cloud/src/lib/process/process-header/process-header-cloud.module.ts @@ -0,0 +1,38 @@ +/*! + * @license + * Copyright 2019 Alfresco Software, Ltd. + * + * 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 { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { MaterialModule } from '../../material.module'; +import { DataTableModule, TemplateModule, CoreModule } from '@alfresco/adf-core'; +import { ProcessHeaderCloudService } from '../process-header/services/process-header-cloud.service'; +import { ProcessHeaderCloudComponent } from './components/process-header-cloud.component'; + +@NgModule({ + imports: [ + CommonModule, + MaterialModule, + DataTableModule, + TemplateModule, + CoreModule + + ], + declarations: [ProcessHeaderCloudComponent], + exports: [ProcessHeaderCloudComponent], + providers: [ProcessHeaderCloudService] +}) +export class ProcessHeaderCloudModule { } diff --git a/lib/process-services-cloud/src/lib/process/process-header/public-api.ts b/lib/process-services-cloud/src/lib/process/process-header/public-api.ts new file mode 100644 index 0000000000..7f952041a5 --- /dev/null +++ b/lib/process-services-cloud/src/lib/process/process-header/public-api.ts @@ -0,0 +1,20 @@ +/*! + * @license + * Copyright 2019 Alfresco Software, Ltd. + * + * 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-header-cloud.module'; +export * from './components/process-header-cloud.component'; +export * from './services/process-header-cloud.service'; diff --git a/lib/process-services-cloud/src/lib/process/process-header/services/process-header-cloud.service.ts b/lib/process-services-cloud/src/lib/process/process-header/services/process-header-cloud.service.ts new file mode 100644 index 0000000000..3e5551ee2e --- /dev/null +++ b/lib/process-services-cloud/src/lib/process/process-header/services/process-header-cloud.service.ts @@ -0,0 +1,71 @@ +/*! + * @license + * Copyright 2019 Alfresco Software, Ltd. + * + * 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 { AlfrescoApiService, LogService, AppConfigService } from '@alfresco/adf-core'; +import { Injectable } from '@angular/core'; +import { Observable, from, throwError } from 'rxjs'; +import { catchError, map } from 'rxjs/operators'; +import { ProcessInstanceCloud } from '../../start-process/public-api'; + +@Injectable({ + providedIn: 'root' +}) +export class ProcessHeaderCloudService { + contextRoot: string; + contentTypes = ['application/json']; + accepts = ['application/json']; + returnType = Object; + + constructor(private alfrescoApiService: AlfrescoApiService, + private appConfigService: AppConfigService, + private logService: LogService) { + this.contextRoot = this.appConfigService.get('bpmHost', ''); + } + + /** + * Gets details of a process instance. + * @param appName Name of the app + * @param processInstanceId ID of the process instance whose details you want + * @returns Process instance details + */ + getProcessInstanceById(appName: string, processInstanceId: string): Observable { + if (appName && processInstanceId) { + + let queryUrl = `${this.contextRoot}/${appName}-query/v1/process-instances/${processInstanceId}`; + return from(this.alfrescoApiService.getInstance() + .oauth2Auth.callCustomApi(queryUrl, 'GET', + null, null, null, + null, null, + this.contentTypes, this.accepts, + this.returnType, null, null) + ).pipe( + map((res: any) => { + return new ProcessInstanceCloud(res.entry); + }), + catchError((err) => this.handleError(err)) + ); + } else { + this.logService.error('AppName and ProcessInstanceId are mandatory for querying a task'); + return throwError('AppName/ProcessInstanceId not configured'); + } + } + + private handleError(error: any) { + this.logService.error(error); + return throwError(error || 'Server error'); + } +} diff --git a/lib/process-services-cloud/src/lib/process/public-api.ts b/lib/process-services-cloud/src/lib/process/public-api.ts index 1bcad182f9..8080aec215 100644 --- a/lib/process-services-cloud/src/lib/process/public-api.ts +++ b/lib/process-services-cloud/src/lib/process/public-api.ts @@ -18,5 +18,6 @@ export * from './process-list/public-api'; export * from './process-filters/public-api'; export * from './start-process/public-api'; +export * from './process-header/public-api'; export * from './process-cloud.module'; diff --git a/lib/process-services-cloud/src/lib/process/start-process/models/process-instance-cloud.model.ts b/lib/process-services-cloud/src/lib/process/start-process/models/process-instance-cloud.model.ts index f97b85bd7c..e9b21545b4 100755 --- a/lib/process-services-cloud/src/lib/process/start-process/models/process-instance-cloud.model.ts +++ b/lib/process-services-cloud/src/lib/process/start-process/models/process-instance-cloud.model.ts @@ -19,9 +19,13 @@ export class ProcessInstanceCloud { appName: string; id: string; name: string; + description: string; startDate: Date; initiator: string; status: string; + businessKey: string; + lastModified: Date; + parentId: string; processDefinitionId: string; processDefinitionKey: string; @@ -29,9 +33,13 @@ export class ProcessInstanceCloud { this.appName = obj && obj.appName || null; this.id = obj && obj.id || null; this.name = obj && obj.name || null; + this.description = obj && obj.description || null; this.startDate = obj && obj.startDate || null; this.initiator = obj && obj.initiator || null; this.status = obj && obj.status || null; + this.businessKey = obj && obj.businessKey || null; + this.lastModified = obj && obj.lastModified || null; + this.parentId = obj && obj.parentId || null; this.processDefinitionId = obj && obj.processDefinitionId || null; this.processDefinitionKey = obj && obj.processDefinitionKey || null; }