From 860529058cedabb0cd3f2da32e89fd505ef74a31 Mon Sep 17 00:00:00 2001 From: Silviu Popa Date: Tue, 30 Apr 2019 12:13:10 +0300 Subject: [PATCH] [ADF-4409] DemoShell - ADF compatibility with Activiti 7 (#4646) * [ADF-4409] PorcessServicesCloud - add community page * [ADF-4409] - add process and task details page * [ADF-4409] fix lint and reset package-lock * [ADF-4409] - PR changes * [ADF-4409] - PR changes * [ADF-4409] - fix start task/process redirection * [ADF-4409] - fix unit tests --- demo-shell/resources/i18n/en.json | 3 +- demo-shell/src/app/app.module.ts | 18 ++- demo-shell/src/app/app.routes.ts | 37 +++++ .../app-layout/app-layout.component.ts | 1 + .../community/community-cloud.component.html | 36 +++++ .../community/community-cloud.component.ts | 68 +++++++++ .../community-filters.component.html | 31 ++++ .../community/community-filters.component.ts | 94 ++++++++++++ ...unity-process-details-cloud.component.html | 24 ++++ ...unity-process-details-cloud.component.scss | 14 ++ ...mmunity-process-details-cloud.component.ts | 49 +++++++ .../community-processes-cloud.component.html | 44 ++++++ .../community-processes-cloud.component.ts | 134 ++++++++++++++++++ ...mmunity-start-process-cloud.component.html | 7 + ...community-start-process-cloud.component.ts | 56 ++++++++ .../community-start-task-cloud.component.html | 5 + .../community-start-task-cloud.component.ts | 49 +++++++ .../community-task-cloud.component.html | 48 +++++++ .../community-task-cloud.component.ts | 131 +++++++++++++++++ ...ommunity-task-details-cloud.component.html | 21 +++ ...ommunity-task-details-cloud.component.scss | 20 +++ .../community-task-details-cloud.component.ts | 75 ++++++++++ .../src/lib/process-services-cloud.module.ts | 4 +- .../edit-process-filter-cloud.component.ts | 4 +- .../process-header-cloud.component.ts | 2 +- .../services/process-header-cloud.service.ts | 9 +- .../process-list-cloud.component.ts | 4 +- .../services/process-list-cloud.service.ts | 10 +- .../start-process-cloud.component.ts | 2 +- .../services/start-process-cloud.service.ts | 14 +- .../src/lib/services/base-cloud.service.ts | 35 +++++ .../lib/task/services/task-cloud.service.ts | 21 ++- .../people-cloud.component.spec.ts | 53 +++---- .../services/start-task-cloud.service.ts | 8 +- .../edit-task-filter-cloud.component.ts | 4 +- .../services/task-filter-cloud.service.ts | 1 - .../components/task-header-cloud.component.ts | 4 +- .../components/task-list-cloud.component.ts | 2 +- .../services/task-list-cloud.service.ts | 10 +- 39 files changed, 1074 insertions(+), 78 deletions(-) create mode 100644 demo-shell/src/app/components/cloud/community/community-cloud.component.html create mode 100644 demo-shell/src/app/components/cloud/community/community-cloud.component.ts create mode 100644 demo-shell/src/app/components/cloud/community/community-filters.component.html create mode 100644 demo-shell/src/app/components/cloud/community/community-filters.component.ts create mode 100644 demo-shell/src/app/components/cloud/community/community-process-details-cloud.component.html create mode 100644 demo-shell/src/app/components/cloud/community/community-process-details-cloud.component.scss create mode 100644 demo-shell/src/app/components/cloud/community/community-process-details-cloud.component.ts create mode 100644 demo-shell/src/app/components/cloud/community/community-processes-cloud.component.html create mode 100644 demo-shell/src/app/components/cloud/community/community-processes-cloud.component.ts create mode 100644 demo-shell/src/app/components/cloud/community/community-start-process-cloud.component.html create mode 100644 demo-shell/src/app/components/cloud/community/community-start-process-cloud.component.ts create mode 100644 demo-shell/src/app/components/cloud/community/community-start-task-cloud.component.html create mode 100644 demo-shell/src/app/components/cloud/community/community-start-task-cloud.component.ts create mode 100644 demo-shell/src/app/components/cloud/community/community-task-cloud.component.html create mode 100644 demo-shell/src/app/components/cloud/community/community-task-cloud.component.ts create mode 100644 demo-shell/src/app/components/cloud/community/community-task-details-cloud.component.html create mode 100644 demo-shell/src/app/components/cloud/community/community-task-details-cloud.component.scss create mode 100644 demo-shell/src/app/components/cloud/community/community-task-details-cloud.component.ts create mode 100644 lib/process-services-cloud/src/lib/services/base-cloud.service.ts diff --git a/demo-shell/resources/i18n/en.json b/demo-shell/resources/i18n/en.json index bb329b5568..ae7b463f39 100644 --- a/demo-shell/resources/i18n/en.json +++ b/demo-shell/resources/i18n/en.json @@ -95,7 +95,8 @@ "PEOPLE_GROUPS_CLOUD": "People/Group Cloud", "PEOPLE_CLOUD": "People Cloud Component", "GROUPS_CLOUD": "Groups Cloud Component", - "CONFIRM-DIALOG": "Confirmation Dialog" + "CONFIRM-DIALOG": "Confirmation Dialog", + "COMMUNITY": "Community" }, "TRASHCAN": { "ACTIONS": { diff --git a/demo-shell/src/app/app.module.ts b/demo-shell/src/app/app.module.ts index 60b2d6e54e..8ccd1eb82f 100644 --- a/demo-shell/src/app/app.module.ts +++ b/demo-shell/src/app/app.module.ts @@ -84,6 +84,14 @@ import { CloudSettingsComponent } from './components/cloud/cloud-settings.compon import { NestedMenuPositionDirective } from './components/cloud/directives/nested-menu-position.directive'; import { ConfirmDialogExampleComponent } from './components/confirm-dialog/confirm-dialog-example.component'; import { FormCloudDemoComponent } from './components/app-layout/cloud/form-demo/cloud-form-demo.component'; +import { CommunityCloudComponent } from './components/cloud/community/community-cloud.component'; +import { CommunityTasksCloudDemoComponent } from './components/cloud/community/community-task-cloud.component'; +import { CommunityCloudFiltersDemoComponent } from './components/cloud/community/community-filters.component'; +import { CommunityStartProcessCloudDemoComponent } from './components/cloud/community/community-start-process-cloud.component'; +import { CommunityStartTaskCloudDemoComponent } from './components/cloud/community/community-start-task-cloud.component'; +import { CommunityProcessDetailsCloudDemoComponent } from './components/cloud/community/community-process-details-cloud.component'; +import { CommunityProcessesCloudDemoComponent } from './components/cloud/community/community-processes-cloud.component'; +import { CommunityTaskDetailsCloudDemoComponent } from './components/cloud/community/community-task-details-cloud.component'; @NgModule({ imports: [ @@ -152,7 +160,15 @@ import { FormCloudDemoComponent } from './components/app-layout/cloud/form-demo/ NestedMenuPositionDirective, ConfirmDialogExampleComponent, FormCloudDemoComponent, - ConfirmDialogExampleComponent + ConfirmDialogExampleComponent, + CommunityCloudComponent, + CommunityTasksCloudDemoComponent, + CommunityCloudFiltersDemoComponent, + CommunityProcessesCloudDemoComponent, + CommunityStartProcessCloudDemoComponent, + CommunityStartTaskCloudDemoComponent, + CommunityProcessDetailsCloudDemoComponent, + CommunityTaskDetailsCloudDemoComponent ], providers: [ { diff --git a/demo-shell/src/app/app.routes.ts b/demo-shell/src/app/app.routes.ts index 10441b9c7c..175388d1a8 100644 --- a/demo-shell/src/app/app.routes.ts +++ b/demo-shell/src/app/app.routes.ts @@ -52,6 +52,13 @@ import { ProcessDetailsCloudDemoComponent } from './components/cloud/process-det import { TemplateDemoComponent } from './components/template-list/template-demo.component'; import { FormCloudDemoComponent } from './components/app-layout/cloud/form-demo/cloud-form-demo.component'; import { ConfirmDialogExampleComponent } from './components/confirm-dialog/confirm-dialog-example.component'; +import { CommunityTasksCloudDemoComponent } from './components/cloud/community/community-task-cloud.component'; +import { CommunityCloudComponent } from './components/cloud/community/community-cloud.component'; +import { CommunityStartProcessCloudDemoComponent } from './components/cloud/community/community-start-process-cloud.component'; +import { CommunityStartTaskCloudDemoComponent } from './components/cloud/community/community-start-task-cloud.component'; +import { CommunityProcessDetailsCloudDemoComponent } from './components/cloud/community/community-process-details-cloud.component'; +import { CommunityProcessesCloudDemoComponent } from './components/cloud/community/community-processes-cloud.component'; +import { CommunityTaskDetailsCloudDemoComponent } from './components/cloud/community/community-task-details-cloud.component'; export const appRoutes: Routes = [ { path: 'login', component: LoginComponent }, @@ -163,6 +170,36 @@ export const appRoutes: Routes = [ path: 'people-group-cloud', component: PeopleGroupCloudDemoComponent }, + { + path: 'community', + component: CommunityCloudComponent, + children: [ + { + path: 'tasks', + component: CommunityTasksCloudDemoComponent + }, + { + path: 'processes', + component: CommunityProcessesCloudDemoComponent + }, + { + path: 'start-task', + component: CommunityStartTaskCloudDemoComponent + }, + { + path: 'start-process', + component: CommunityStartProcessCloudDemoComponent + }, + { + path: 'task-details/:taskId', + component: CommunityTaskDetailsCloudDemoComponent + }, + { + path: 'process-details/:processInstanceId', + component: CommunityProcessDetailsCloudDemoComponent + } + ] + }, { path: ':appName', canActivate: [AuthGuardSsoRoleService], diff --git a/demo-shell/src/app/components/app-layout/app-layout.component.ts b/demo-shell/src/app/components/app-layout/app-layout.component.ts index 9344a33eab..7133e54810 100644 --- a/demo-shell/src/app/components/app-layout/app-layout.component.ts +++ b/demo-shell/src/app/components/app-layout/app-layout.component.ts @@ -48,6 +48,7 @@ export class AppLayoutComponent implements OnInit { { href: '/task-list', icon: 'assignment', title: 'APP_LAYOUT.TASK_LIST' }, { href: '/cloud', icon: 'cloud', title: 'APP_LAYOUT.PROCESS_CLOUD', children: [ { href: '/cloud/', icon: 'cloud', title: 'APP_LAYOUT.HOME' }, + { href: '/cloud/community', icon: 'cloud', title: 'APP_LAYOUT.COMMUNITY' }, { href: '/form-cloud', icon: 'poll', title: 'APP_LAYOUT.FORM' }, { href: '/cloud/people-group-cloud', icon: 'group', title: 'APP_LAYOUT.PEOPLE_GROUPS_CLOUD' } ]}, diff --git a/demo-shell/src/app/components/cloud/community/community-cloud.component.html b/demo-shell/src/app/components/cloud/community/community-cloud.component.html new file mode 100644 index 0000000000..051349524a --- /dev/null +++ b/demo-shell/src/app/components/cloud/community/community-cloud.component.html @@ -0,0 +1,36 @@ + + +
+ + + + + arrow_drop_down +
+ +
+
+ +
+
+ +
+
+ + + + + +
+
+
+ + + +
diff --git a/demo-shell/src/app/components/cloud/community/community-cloud.component.ts b/demo-shell/src/app/components/cloud/community/community-cloud.component.ts new file mode 100644 index 0000000000..6303699344 --- /dev/null +++ b/demo-shell/src/app/components/cloud/community/community-cloud.component.ts @@ -0,0 +1,68 @@ +/*! + * @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, ViewEncapsulation } from '@angular/core'; +import { Router, ActivatedRoute } from '@angular/router'; +import { CloudLayoutService } from '../services/cloud-layout.service'; + +@Component({ + templateUrl: './community-cloud.component.html', + styles: [`.adf-cloud-layout-overflow { + overflow: auto; + } + + .adf-cloud-layout-tab-body .mat-tab-body-wrapper { + height: 100% !important; + } + `], + encapsulation: ViewEncapsulation.None +}) +export class CommunityCloudComponent { + + appName: string = ''; + + constructor( + private router: Router, + private route: ActivatedRoute, + private cloudLayoutService: CloudLayoutService + ) { } + + ngOnInit() { + let root: string = ''; + if (this.route.snapshot && this.route.snapshot.firstChild) { + root = this.route.snapshot.firstChild.url[0].path; + } + + this.route.queryParams.subscribe((params) => { + if (root === 'tasks' && params.id) { + this.cloudLayoutService.setCurrentTaskFilterParam({ id: params.id }); + } + + if (root === 'processes' && params.id) { + this.cloudLayoutService.setCurrentProcessFilterParam({ id: params.id }); + } + }); + } + + onStartTask() { + this.router.navigate([`/cloud/community/start-task/`]); + } + + onStartProcess() { + this.router.navigate([`/cloud/community/start-process/`]); + } +} diff --git a/demo-shell/src/app/components/cloud/community/community-filters.component.html b/demo-shell/src/app/components/cloud/community/community-filters.component.html new file mode 100644 index 0000000000..7daa8b33ac --- /dev/null +++ b/demo-shell/src/app/components/cloud/community/community-filters.component.html @@ -0,0 +1,31 @@ + + + + + Task Filters + + + + + + + + + + Process Filters + + + + + + diff --git a/demo-shell/src/app/components/cloud/community/community-filters.component.ts b/demo-shell/src/app/components/cloud/community/community-filters.component.ts new file mode 100644 index 0000000000..39e64d288f --- /dev/null +++ b/demo-shell/src/app/components/cloud/community/community-filters.component.ts @@ -0,0 +1,94 @@ +/*! + * @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, ViewEncapsulation, Input, OnInit } from '@angular/core'; +import { Observable } from 'rxjs'; +import { Router, ActivatedRoute } from '@angular/router'; +import { CloudLayoutService } from '../services/cloud-layout.service'; +@Component({ + selector: 'app-community-cloud-filters-demo', + templateUrl: './community-filters.component.html', + encapsulation: ViewEncapsulation.None +}) +export class CommunityCloudFiltersDemoComponent implements OnInit { + + @Input() + appName: string = 'community'; + + currentTaskFilter$: Observable; + currentProcessFilter$: Observable; + + toggleTaskFilter = true; + toggleProcessFilter = true; + + expandTaskFilter = true; + expandProcessFilter = false; + + constructor( + private cloudLayoutService: CloudLayoutService, + private router: Router, + private route: ActivatedRoute + ) {} + + ngOnInit() { + this.currentTaskFilter$ = this.cloudLayoutService.getCurrentTaskFilterParam(); + this.currentProcessFilter$ = this.cloudLayoutService.getCurrentProcessFilterParam(); + let root = ''; + if (this.route.snapshot && this.route.snapshot.firstChild) { + root = this.route.snapshot.firstChild.url[0].path; + if (root === 'tasks') { + this.expandTaskFilter = true; + this.expandProcessFilter = false; + } else if (root === 'processes') { + this.expandProcessFilter = true; + this.expandTaskFilter = false; + } + } + } + + onTaskFilterSelected(filter) { + this.cloudLayoutService.setCurrentTaskFilterParam({id: filter.id}); + const currentFilter = Object.assign({}, filter); + this.router.navigate([`/cloud/community/tasks/`], { queryParams: currentFilter }); + } + + onProcessFilterSelected(filter) { + this.cloudLayoutService.setCurrentProcessFilterParam({id: filter.id}); + const currentFilter = Object.assign({}, filter); + this.router.navigate([`/cloud/community/processes/`], { queryParams: currentFilter }); + } + + onTaskFilterOpen(): boolean { + this.expandTaskFilter = true; + this.expandProcessFilter = false; + return this.toggleTaskFilter; + } + + onTaskFilterClose(): boolean { + return !this.toggleTaskFilter; + } + + onProcessFilterOpen(): boolean { + this.expandProcessFilter = true; + this.expandTaskFilter = false; + return this.toggleProcessFilter; + } + + onProcessFilterClose(): boolean { + return !this.toggleProcessFilter; + } +} diff --git a/demo-shell/src/app/components/cloud/community/community-process-details-cloud.component.html b/demo-shell/src/app/components/cloud/community/community-process-details-cloud.component.html new file mode 100644 index 0000000000..6fc529df18 --- /dev/null +++ b/demo-shell/src/app/components/cloud/community/community-process-details-cloud.component.html @@ -0,0 +1,24 @@ + + + +

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

+ +
+ + + + + + +
+ diff --git a/demo-shell/src/app/components/cloud/community/community-process-details-cloud.component.scss b/demo-shell/src/app/components/cloud/community/community-process-details-cloud.component.scss new file mode 100644 index 0000000000..3ad46f3b2c --- /dev/null +++ b/demo-shell/src/app/components/cloud/community/community-process-details-cloud.component.scss @@ -0,0 +1,14 @@ +.adf { + &-process-cloud-container { + display: flex; + } + + &-cloud-layout-overflow { + width:67%; + } + + &-process-cloud-header { + margin-left: 10px; + width: 25%; + } + } diff --git a/demo-shell/src/app/components/cloud/community/community-process-details-cloud.component.ts b/demo-shell/src/app/components/cloud/community/community-process-details-cloud.component.ts new file mode 100644 index 0000000000..aa959a46e9 --- /dev/null +++ b/demo-shell/src/app/components/cloud/community/community-process-details-cloud.component.ts @@ -0,0 +1,49 @@ +/*! + * @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: './community-process-details-cloud.component.html', + styleUrls: ['./community-process-details-cloud.component.scss'] +}) +export class CommunityProcessDetailsCloudDemoComponent { + + 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/community/`]); + } + + onRowClick(taskId: string) { + if (taskId) { + this.router.navigate([`/cloud/community/task-details/${taskId}`]); + } + } +} diff --git a/demo-shell/src/app/components/cloud/community/community-processes-cloud.component.html b/demo-shell/src/app/components/cloud/community/community-processes-cloud.component.html new file mode 100644 index 0000000000..fb5071c765 --- /dev/null +++ b/demo-shell/src/app/components/cloud/community/community-processes-cloud.component.html @@ -0,0 +1,44 @@ +
+ + +
+ + + + +
+ Selected rows: +
    +
  • {{ row.id }}
  • +
+
+
+
diff --git a/demo-shell/src/app/components/cloud/community/community-processes-cloud.component.ts b/demo-shell/src/app/components/cloud/community/community-processes-cloud.component.ts new file mode 100644 index 0000000000..c7d658b9b1 --- /dev/null +++ b/demo-shell/src/app/components/cloud/community/community-processes-cloud.component.ts @@ -0,0 +1,134 @@ +/*! + * @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, ViewChild, OnInit } from '@angular/core'; +import { + ProcessListCloudComponent, + ProcessFilterCloudModel, + ProcessListCloudSortingModel, + ProcessFiltersCloudComponent, + ProcessFilterCloudService +} from '@alfresco/adf-process-services-cloud'; + +import { ActivatedRoute, Router } from '@angular/router'; +import { UserPreferencesService, AppConfigService } from '@alfresco/adf-core'; +import { CloudLayoutService } from '../services/cloud-layout.service'; + +@Component({ + templateUrl: './community-processes-cloud.component.html' +}) +export class CommunityProcessesCloudDemoComponent implements OnInit { + + public static ACTION_SAVE_AS = 'saveAs'; + static PROCESS_FILTER_PROPERTY_KEYS = 'adf-edit-process-filter'; + + @ViewChild('processCloud') + processCloud: ProcessListCloudComponent; + + @ViewChild('processFiltersCloud') + processFiltersCloud: ProcessFiltersCloudComponent; + + appName: string = ''; + isFilterLoaded: boolean; + + filterId: string = ''; + sortArray: any = []; + selectedRow: any; + multiselect: boolean; + selectionMode: string; + selectedRows: string[] = []; + testingMode: boolean; + processFilterProperties: any = { filterProperties: [], sortProperties: [], actions: [] }; + + editedFilter: ProcessFilterCloudModel; + + constructor( + private route: ActivatedRoute, + private router: Router, + private cloudLayoutService: CloudLayoutService, + private userPreference: UserPreferencesService, + private processFilterCloudService: ProcessFilterCloudService, + private appConfig: AppConfigService) { + const properties = this.appConfig.get>(CommunityProcessesCloudDemoComponent.PROCESS_FILTER_PROPERTY_KEYS); + if (properties) { + this.processFilterProperties = properties; + } + } + + ngOnInit() { + this.isFilterLoaded = false; + this.route.parent.params.subscribe((params) => { + this.appName = params.appName; + }); + + this.route.queryParams.subscribe((params) => { + if (Object.keys(params).length > 0) { + this.isFilterLoaded = true; + this.onFilterChange(params); + this.filterId = params.id; + } else { + this.loadDefaultFilters(); + } + }); + + this.cloudLayoutService.getCurrentSettings() + .subscribe((settings) => this.setCurrentSettings(settings)); + } + + loadDefaultFilters() { + this.processFilterCloudService.getProcessFilters('community').subscribe( (filters: ProcessFilterCloudModel[]) => { + this.onFilterChange(filters[0]); + }); + } + + setCurrentSettings(settings) { + if (settings) { + this.multiselect = settings.multiselect; + this.testingMode = settings.testingMode; + this.selectionMode = settings.selectionMode; + } + } + + onChangePageSize(event) { + this.userPreference.paginationSize = event.maxItems; + } + + resetSelectedRows() { + this.selectedRows = []; + } + + onRowClick(processInstanceId) { + this.router.navigate([`/cloud/community/process-details/${processInstanceId}`]); + } + + onFilterChange(query: any) { + this.editedFilter = Object.assign({}, query); + this.sortArray = [new ProcessListCloudSortingModel({ orderBy: this.editedFilter.sort, direction: this.editedFilter.order })]; + } + + onProcessFilterAction(filterAction: any) { + this.cloudLayoutService.setCurrentProcessFilterParam({ id: filterAction.filter.id }); + if (filterAction.actionType === CommunityProcessesCloudDemoComponent.ACTION_SAVE_AS) { + this.router.navigate([`/cloud/community/processes/`], { queryParams: filterAction.filter }); + } + } + + onRowsSelected(nodes) { + this.resetSelectedRows(); + this.selectedRows = nodes.map((node) => node.obj.entry); + } +} diff --git a/demo-shell/src/app/components/cloud/community/community-start-process-cloud.component.html b/demo-shell/src/app/components/cloud/community/community-start-process-cloud.component.html new file mode 100644 index 0000000000..df2ca1cb8b --- /dev/null +++ b/demo-shell/src/app/components/cloud/community/community-start-process-cloud.component.html @@ -0,0 +1,7 @@ + + diff --git a/demo-shell/src/app/components/cloud/community/community-start-process-cloud.component.ts b/demo-shell/src/app/components/cloud/community/community-start-process-cloud.component.ts new file mode 100644 index 0000000000..54ab9090df --- /dev/null +++ b/demo-shell/src/app/components/cloud/community/community-start-process-cloud.component.ts @@ -0,0 +1,56 @@ +/*! + * @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, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +import { NotificationService, AppConfigService } from '@alfresco/adf-core'; +import { CloudLayoutService } from '../services/cloud-layout.service'; + +@Component({ + templateUrl: './community-start-process-cloud.component.html' +}) +export class CommunityStartProcessCloudDemoComponent implements OnInit { + + processName: string; + + constructor(private appConfig: AppConfigService, + private cloudLayoutService: CloudLayoutService, + private notificationService: NotificationService, + private router: Router) { + } + + ngOnInit() { + this.processName = this.appConfig.get('adf-start-process.name'); + } + + onStartProcessSuccess() { + this.cloudLayoutService.setCurrentProcessFilterParam({ key: 'running-processes' }); + this.router.navigate([`/cloud/community/processes`]); + } + + onCancelStartProcess() { + this.cloudLayoutService.setCurrentProcessFilterParam({ key: 'all-processes' }); + this.router.navigate([`/cloud/community/processes`]); + } + + openSnackMessage(event: any) { + this.notificationService.openSnackMessage( + event.response.body.message, + 4000 + ); + } +} diff --git a/demo-shell/src/app/components/cloud/community/community-start-task-cloud.component.html b/demo-shell/src/app/components/cloud/community/community-start-task-cloud.component.html new file mode 100644 index 0000000000..9975b99cc6 --- /dev/null +++ b/demo-shell/src/app/components/cloud/community/community-start-task-cloud.component.html @@ -0,0 +1,5 @@ + + diff --git a/demo-shell/src/app/components/cloud/community/community-start-task-cloud.component.ts b/demo-shell/src/app/components/cloud/community/community-start-task-cloud.component.ts new file mode 100644 index 0000000000..fda2cd29b2 --- /dev/null +++ b/demo-shell/src/app/components/cloud/community/community-start-task-cloud.component.ts @@ -0,0 +1,49 @@ +/*! + * @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 { Router } from '@angular/router'; +import { NotificationService } from '@alfresco/adf-core'; +import { CloudLayoutService } from '../services/cloud-layout.service'; +@Component({ + templateUrl: './community-start-task-cloud.component.html' +}) +export class CommunityStartTaskCloudDemoComponent { + + constructor( + private cloudLayoutService: CloudLayoutService, + private notificationService: NotificationService, + private router: Router) { + } + + onStartTaskSuccess() { + this.cloudLayoutService.setCurrentTaskFilterParam({key: 'community'}); + this.router.navigate([`/cloud/community/tasks`]); + } + + onCancelStartTask() { + this.cloudLayoutService.setCurrentTaskFilterParam({key: 'community'}); + this.router.navigate([`/cloud/community/tasks`]); + } + + openSnackMessage(event: any) { + this.notificationService.openSnackMessage( + event.response.body.message, + 4000 + ); + } +} diff --git a/demo-shell/src/app/components/cloud/community/community-task-cloud.component.html b/demo-shell/src/app/components/cloud/community/community-task-cloud.component.html new file mode 100644 index 0000000000..cf431267d5 --- /dev/null +++ b/demo-shell/src/app/components/cloud/community/community-task-cloud.component.html @@ -0,0 +1,48 @@ +
+ + +
+ + + + +
+ Selected rows: +
    +
  • {{ row.name }}
  • +
+
+
+
diff --git a/demo-shell/src/app/components/cloud/community/community-task-cloud.component.ts b/demo-shell/src/app/components/cloud/community/community-task-cloud.component.ts new file mode 100644 index 0000000000..1e77a51372 --- /dev/null +++ b/demo-shell/src/app/components/cloud/community/community-task-cloud.component.ts @@ -0,0 +1,131 @@ +/*! + * @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, ViewChild, OnInit } from '@angular/core'; +import { TaskListCloudComponent, TaskListCloudSortingModel, TaskFilterCloudModel, TaskFilterCloudService } from '@alfresco/adf-process-services-cloud'; +import { UserPreferencesService, AppConfigService } from '@alfresco/adf-core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { CloudLayoutService } from '../services/cloud-layout.service'; + +@Component({ + templateUrl: './community-task-cloud.component.html', + styles: [`.adf-cloud-layout-tab-body .mat-tab-body-wrapper { + height: 100%; + } + `] +}) +export class CommunityTasksCloudDemoComponent implements OnInit { + + public static ACTION_SAVE_AS = 'saveAs'; + static TASK_FILTER_PROPERTY_KEYS = 'adf-edit-task-filter'; + + @ViewChild('taskCloud') + taskCloud: TaskListCloudComponent; + + isFilterLoaded = false; + + selectedRow: any; + + sortArray: TaskListCloudSortingModel[]; + editedFilter: TaskFilterCloudModel; + taskFilterProperties: any = { filterProperties: [], sortProperties: [], actions: [] }; + + filterId; + multiselect: boolean; + selectedRows: string[] = []; + testingMode: boolean; + selectionMode: string; + taskDetailsRedirection: boolean; + + constructor( + private cloudLayoutService: CloudLayoutService, + private route: ActivatedRoute, + private router: Router, + private taskFilterCloudService: TaskFilterCloudService, + private userPreference: UserPreferencesService, + private appConfig: AppConfigService) { + + const properties = this.appConfig.get>(CommunityTasksCloudDemoComponent.TASK_FILTER_PROPERTY_KEYS); + if (properties) { + this.taskFilterProperties = properties; + } + } + + ngOnInit() { + this.isFilterLoaded = false; + this.route.queryParams.subscribe((params) => { + if (Object.keys(params).length > 0) { + this.isFilterLoaded = true; + this.onFilterChange(params); + this.filterId = params.id; + } else { + setTimeout( () => { + this.loadDefaultFilters(); + }); + } + }); + + this.cloudLayoutService.getCurrentSettings() + .subscribe((settings) => this.setCurrentSettings(settings)); + } + + loadDefaultFilters() { + this.taskFilterCloudService.getTaskListFilters('community').subscribe( (filters: TaskFilterCloudModel[]) => { + this.onFilterChange(filters[0]); + }); + } + + setCurrentSettings(settings) { + if (settings) { + this.multiselect = settings.multiselect; + this.testingMode = settings.testingMode; + this.selectionMode = settings.selectionMode; + this.taskDetailsRedirection = settings.taskDetailsRedirection; + } + } + + onChangePageSize(event) { + this.userPreference.paginationSize = event.maxItems; + } + + resetSelectedRows() { + this.selectedRows = []; + } + + onRowClick(taskId) { + if (!this.multiselect && this.selectionMode !== 'multiple' && this.taskDetailsRedirection) { + this.router.navigate([`/cloud/community/task-details/${taskId}`]); + } + } + + onRowsSelected(nodes) { + this.resetSelectedRows(); + this.selectedRows = nodes.map((node) => node.obj.entry); + } + + onFilterChange(filter: any) { + this.editedFilter = Object.assign({}, filter); + this.sortArray = [new TaskListCloudSortingModel({ orderBy: this.editedFilter.sort, direction: this.editedFilter.order })]; + } + + onTaskFilterAction(filterAction: any) { + this.cloudLayoutService.setCurrentTaskFilterParam({ id: filterAction.filter.id }); + if (filterAction.actionType === CommunityTasksCloudDemoComponent.ACTION_SAVE_AS) { + this.router.navigate([`/cloud/community/tasks/`], { queryParams: filterAction.filter }); + } + } +} diff --git a/demo-shell/src/app/components/cloud/community/community-task-details-cloud.component.html b/demo-shell/src/app/components/cloud/community/community-task-details-cloud.component.html new file mode 100644 index 0000000000..541e5c8549 --- /dev/null +++ b/demo-shell/src/app/components/cloud/community/community-task-details-cloud.component.html @@ -0,0 +1,21 @@ +

Simple page to show the taskId: {{ taskId }} of the app: {{ appName }}

+ +
+
+
+ + +
+ + +
+
diff --git a/demo-shell/src/app/components/cloud/community/community-task-details-cloud.component.scss b/demo-shell/src/app/components/cloud/community/community-task-details-cloud.component.scss new file mode 100644 index 0000000000..e97ca949e4 --- /dev/null +++ b/demo-shell/src/app/components/cloud/community/community-task-details-cloud.component.scss @@ -0,0 +1,20 @@ + +.adf { + + &-task-detail-container { + display: flex; + } + + &-task-tiitle { + margin-left:15px; + } + + &-task-control { + width:70%; + } + + &-demop-card-container { + width:30%; + font-family: inherit; + } +} diff --git a/demo-shell/src/app/components/cloud/community/community-task-details-cloud.component.ts b/demo-shell/src/app/components/cloud/community/community-task-details-cloud.component.ts new file mode 100644 index 0000000000..b08e56669b --- /dev/null +++ b/demo-shell/src/app/components/cloud/community/community-task-details-cloud.component.ts @@ -0,0 +1,75 @@ +/*! + * @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'; +import { UploadCloudWidgetComponent } from '@alfresco/adf-process-services-cloud'; +import { NotificationService, FormRenderingService } from '@alfresco/adf-core'; + +@Component({ + templateUrl: './community-task-details-cloud.component.html', + styleUrls: ['./community-task-details-cloud.component.scss'] +}) +export class CommunityTaskDetailsCloudDemoComponent { + + taskId: string; + appName: string; + + constructor( + private route: ActivatedRoute, + private router: Router, + private formRenderingService: FormRenderingService, + private notificationService: NotificationService + ) { + this.route.params.subscribe((params) => { + this.taskId = params.taskId; + }); + this.route.parent.params.subscribe((params) => { + this.appName = params.appName; + }); + this.formRenderingService.setComponentTypeResolver('upload', () => UploadCloudWidgetComponent, true); + + } + + isTaskValid(): boolean { + return this.appName !== undefined && this.taskId !== undefined; + } + + goBack() { + this.router.navigate([`/cloud/community/`]); + } + + onCompletedTask() { + this.goBack(); + } + + onUnclaimTask() { + this.goBack(); + } + + onClaimTask() { + this.goBack(); + } + + onTaskCompleted() { + this.goBack(); + } + + onFormSaved() { + this.notificationService.openSnackMessage('Task has been saved successfully'); + } +} diff --git a/lib/process-services-cloud/src/lib/process-services-cloud.module.ts b/lib/process-services-cloud/src/lib/process-services-cloud.module.ts index 1289adf9e3..01aa3ed579 100644 --- a/lib/process-services-cloud/src/lib/process-services-cloud.module.ts +++ b/lib/process-services-cloud/src/lib/process-services-cloud.module.ts @@ -23,6 +23,7 @@ import { ProcessCloudModule } from './process/process-cloud.module'; import { GroupCloudModule } from './group/group-cloud.module'; import { FormCloudModule } from './form/form-cloud.module'; import { TaskFormModule } from './task/task-form/task-form.module'; +import { BaseCloudService } from './services/base-cloud.service'; @NgModule({ imports: [ @@ -42,7 +43,8 @@ import { TaskFormModule } from './task/task-form/task-form.module'; name: 'adf-process-services-cloud', source: 'assets/adf-process-services-cloud' } - } + }, + BaseCloudService ], exports: [ AppListCloudModule, diff --git a/lib/process-services-cloud/src/lib/process/process-filters/components/edit-process-filter-cloud.component.ts b/lib/process-services-cloud/src/lib/process/process-filters/components/edit-process-filter-cloud.component.ts index d13275505a..60a652d011 100644 --- a/lib/process-services-cloud/src/lib/process/process-filters/components/edit-process-filter-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/process/process-filters/components/edit-process-filter-cloud.component.ts @@ -219,7 +219,7 @@ export class EditProcessFilterCloudComponent implements OnInit, OnChanges { } } - createSortProperties(): any { + get createSortProperties(): any { this.checkMandatorySortProperties(); const sortProperties = this.sortProperties.map((property: string) => { return { label: property.charAt(0).toUpperCase() + property.slice(1), value: property }; @@ -505,7 +505,7 @@ export class EditProcessFilterCloudComponent implements OnInit, OnChanges { type: 'select', key: 'sort', value: currentProcessFilter.sort || this.createSortProperties[0].value, - options: this.createSortProperties() + options: this.createSortProperties }), new ProcessFilterProperties({ label: 'ADF_CLOUD_EDIT_PROCESS_FILTER.LABEL.DIRECTION', 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 index d6eddbe24d..7f2becdd81 100644 --- 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 @@ -47,7 +47,7 @@ export class ProcessHeaderCloudComponent implements OnChanges { } ngOnChanges() { - if (this.appName && this.processInstanceId) { + if ((this.appName || this.appName === '') && this.processInstanceId) { this.loadProcessInstanceDetails(this.appName, this.processInstanceId); } } 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 index 3eb4eedcd4..939d978173 100644 --- 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 @@ -20,11 +20,12 @@ import { Injectable } from '@angular/core'; import { Observable, from, throwError } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; import { ProcessInstanceCloud } from '../../start-process/models/process-instance-cloud.model'; +import { BaseCloudService } from '../../../services/base-cloud.service'; @Injectable({ providedIn: 'root' }) -export class ProcessHeaderCloudService { +export class ProcessHeaderCloudService extends BaseCloudService { contextRoot: string; contentTypes = ['application/json']; accepts = ['application/json']; @@ -33,6 +34,7 @@ export class ProcessHeaderCloudService { constructor(private alfrescoApiService: AlfrescoApiService, private appConfigService: AppConfigService, private logService: LogService) { + super(); this.contextRoot = this.appConfigService.get('bpmHost', ''); } @@ -43,9 +45,8 @@ export class ProcessHeaderCloudService { * @returns Process instance details */ getProcessInstanceById(appName: string, processInstanceId: string): Observable { - if (appName && processInstanceId) { - - const queryUrl = `${this.contextRoot}/${appName}/query/v1/process-instances/${processInstanceId}`; + if ((appName || appName === '') && processInstanceId) { + const queryUrl = `${this.getBasePath(appName)}/query/v1/process-instances/${processInstanceId}`; return from(this.alfrescoApiService.getInstance() .oauth2Auth.callCustomApi(queryUrl, 'GET', null, null, null, diff --git a/lib/process-services-cloud/src/lib/process/process-list/components/process-list-cloud.component.ts b/lib/process-services-cloud/src/lib/process/process-list/components/process-list-cloud.component.ts index 84139f196e..076f2a9da9 100644 --- a/lib/process-services-cloud/src/lib/process/process-list/components/process-list-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/process/process-list/components/process-list-cloud.component.ts @@ -43,7 +43,7 @@ export class ProcessListCloudComponent extends DataTableSchema implements OnChan /** The name of the application. */ @Input() - appName: string = ''; + appName: string; /** Name of the initiator of the process. */ @Input() @@ -156,7 +156,7 @@ export class ProcessListCloudComponent extends DataTableSchema implements OnChan reload() { this.requestNode = this.createRequestNode(); - if (this.requestNode.appName) { + if (this.requestNode.appName || this.requestNode.appName === '') { this.load(this.requestNode); } else { this.rows = []; diff --git a/lib/process-services-cloud/src/lib/process/process-list/services/process-list-cloud.service.ts b/lib/process-services-cloud/src/lib/process/process-list/services/process-list-cloud.service.ts index 32047521f9..418954ec6d 100644 --- a/lib/process-services-cloud/src/lib/process/process-list/services/process-list-cloud.service.ts +++ b/lib/process-services-cloud/src/lib/process/process-list/services/process-list-cloud.service.ts @@ -19,8 +19,10 @@ import { AlfrescoApiService, AppConfigService, LogService } from '@alfresco/adf- import { ProcessQueryCloudRequestModel } from '../models/process-cloud-query-request.model'; import { Observable, from, throwError } from 'rxjs'; import { ProcessListCloudSortingModel } from '../models/process-list-sorting.model'; +import { BaseCloudService } from '../../../services/base-cloud.service'; + @Injectable() -export class ProcessListCloudService { +export class ProcessListCloudService extends BaseCloudService { contentTypes = ['application/json']; accepts = ['application/json']; @@ -28,6 +30,7 @@ export class ProcessListCloudService { constructor(private apiService: AlfrescoApiService, private appConfigService: AppConfigService, private logService: LogService) { + super(); } /** @@ -36,7 +39,7 @@ export class ProcessListCloudService { * @returns Process information */ getProcessByRequest(requestNode: ProcessQueryCloudRequestModel): Observable { - if (requestNode.appName) { + if (requestNode.appName || requestNode.appName === '') { const queryUrl = this.buildQueryUrl(requestNode); const queryParams = this.buildQueryParams(requestNode); const sortingParams = this.buildSortingParam(requestNode.sorting); @@ -55,7 +58,8 @@ export class ProcessListCloudService { } } private buildQueryUrl(requestNode: ProcessQueryCloudRequestModel) { - return `${this.appConfigService.get('bpmHost', '')}/${requestNode.appName}/query/v1/process-instances`; + this.contextRoot = this.appConfigService.get('bpmHost', ''); + return `${this.getBasePath(requestNode.appName)}/query/v1/process-instances`; } private isPropertyValueValid(requestNode, property) { diff --git a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.ts b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.ts index 9814ad4f66..cbc55641bd 100755 --- a/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/process/start-process/components/start-process-cloud.component.ts @@ -122,7 +122,7 @@ export class StartProcessCloudComponent implements OnChanges, OnInit { } private getProcessDefinitionList(processDefinitionName: string): ProcessDefinitionCloud[] { - return this.processDefinitionList.filter((option) => option.name.toLowerCase().includes(processDefinitionName.toLowerCase())); + return this.processDefinitionList.filter((option) => option.name && option.name.toLowerCase().includes(processDefinitionName.toLowerCase())); } private getProcessIfExists(processDefinitionName: string): ProcessDefinitionCloud { diff --git a/lib/process-services-cloud/src/lib/process/start-process/services/start-process-cloud.service.ts b/lib/process-services-cloud/src/lib/process/start-process/services/start-process-cloud.service.ts index 0e4af4c6b2..d5368d843a 100755 --- a/lib/process-services-cloud/src/lib/process/start-process/services/start-process-cloud.service.ts +++ b/lib/process-services-cloud/src/lib/process/start-process/services/start-process-cloud.service.ts @@ -22,11 +22,12 @@ import { map, catchError } from 'rxjs/operators'; import { ProcessInstanceCloud } from '../models/process-instance-cloud.model'; import { ProcessPayloadCloud } from '../models/process-payload-cloud.model'; import { ProcessDefinitionCloud } from '../models/process-definition-cloud.model'; +import { BaseCloudService } from '../../../services/base-cloud.service'; @Injectable({ providedIn: 'root' }) -export class StartProcessCloudService { +export class StartProcessCloudService extends BaseCloudService { contextRoot: string; contentTypes = ['application/json']; @@ -34,8 +35,9 @@ export class StartProcessCloudService { returnType = Object; constructor(private alfrescoApiService: AlfrescoApiService, - private appConfigService: AppConfigService, - private logService: LogService) { + private logService: LogService, + private appConfigService: AppConfigService) { + super(); this.contextRoot = this.appConfigService.get('bpmHost', ''); } @@ -46,8 +48,8 @@ export class StartProcessCloudService { */ getProcessDefinitions(appName: string): Observable { - if (appName) { - const queryUrl = `${this.contextRoot}/${appName}/rb/v1/process-definitions`; + if (appName || appName === '') { + const queryUrl = `${this.getBasePath(appName)}/rb/v1/process-definitions`; return from(this.alfrescoApiService.getInstance() .oauth2Auth.callCustomApi(queryUrl, 'GET', @@ -75,7 +77,7 @@ export class StartProcessCloudService { */ startProcess(appName: string, requestPayload: ProcessPayloadCloud): Observable { - const queryUrl = `${this.contextRoot}/${appName}/rb/v1/process-instances`; + const queryUrl = `${this.getBasePath(appName)}/rb/v1/process-instances`; return from(this.alfrescoApiService.getInstance() .oauth2Auth.callCustomApi(queryUrl, 'POST', diff --git a/lib/process-services-cloud/src/lib/services/base-cloud.service.ts b/lib/process-services-cloud/src/lib/services/base-cloud.service.ts new file mode 100644 index 0000000000..b253d34c3c --- /dev/null +++ b/lib/process-services-cloud/src/lib/services/base-cloud.service.ts @@ -0,0 +1,35 @@ +/*! + * @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 { Injectable } from '@angular/core'; + +@Injectable() +export class BaseCloudService { + + public contextRoot: string; + + getBasePath(appName: string) { + if (this.isValidAppName(appName)) { + return `${this.contextRoot}/${appName}`; + } + return this.contextRoot; + } + + private isValidAppName(appName: string) { + return appName && appName !== ''; + } +} diff --git a/lib/process-services-cloud/src/lib/task/services/task-cloud.service.ts b/lib/process-services-cloud/src/lib/task/services/task-cloud.service.ts index 706839aecd..a6af517e40 100644 --- a/lib/process-services-cloud/src/lib/task/services/task-cloud.service.ts +++ b/lib/process-services-cloud/src/lib/task/services/task-cloud.service.ts @@ -20,13 +20,13 @@ import { AlfrescoApiService, LogService, AppConfigService, IdentityUserService } import { from, throwError, Observable } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; import { TaskDetailsCloudModel } from '../start-task/models/task-details-cloud.model'; +import { BaseCloudService } from '../../services/base-cloud.service'; @Injectable({ providedIn: 'root' }) -export class TaskCloudService { +export class TaskCloudService extends BaseCloudService { - contextRoot: string; contentTypes = ['application/json']; accepts = ['application/json']; returnType = Object; @@ -37,6 +37,7 @@ export class TaskCloudService { private logService: LogService, private identityUserService: IdentityUserService ) { + super(); this.contextRoot = this.appConfigService.get('bpmHost', ''); } @@ -102,8 +103,7 @@ export class TaskCloudService { */ claimTask(appName: string, taskId: string, assignee: string): Observable { if (appName && taskId) { - - const queryUrl = `${this.contextRoot}/${appName}/rb/v1/tasks/${taskId}/claim?assignee=${assignee}`; + const queryUrl = `${this.getBasePath(appName)}/rb/v1/tasks/${taskId}/claim?assignee=${assignee}`; return from(this.apiService.getInstance() .oauth2Auth.callCustomApi(queryUrl, 'POST', null, null, null, @@ -130,8 +130,7 @@ export class TaskCloudService { */ unclaimTask(appName: string, taskId: string): Observable { if (appName && taskId) { - - const queryUrl = `${this.contextRoot}/${appName}/rb/v1/tasks/${taskId}/release`; + const queryUrl = `${this.getBasePath(appName)}/rb/v1/tasks/${taskId}/release`; return from(this.apiService.getInstance() .oauth2Auth.callCustomApi(queryUrl, 'POST', null, null, null, @@ -157,9 +156,8 @@ export class TaskCloudService { * @returns Task details */ getTaskById(appName: string, taskId: string): Observable { - if (appName && taskId) { - - const queryUrl = `${this.contextRoot}/${appName}/query/v1/tasks/${taskId}`; + if ((appName || appName === '') && taskId) { + const queryUrl = `${this.getBasePath(appName)}/query/v1/tasks/${taskId}`; return from(this.apiService.getInstance() .oauth2Auth.callCustomApi(queryUrl, 'GET', null, null, null, @@ -189,8 +187,7 @@ export class TaskCloudService { if (appName && taskId) { updatePayload.payloadType = 'UpdateTaskPayload'; - - const queryUrl = `${this.contextRoot}/${appName}/rb/v1/tasks/${taskId}`; + const queryUrl = `${this.getBasePath(appName)}/rb/v1/tasks/${taskId}`; return from(this.apiService.getInstance() .oauth2Auth.callCustomApi(queryUrl, 'PUT', null, null, null, @@ -210,7 +207,7 @@ export class TaskCloudService { } private buildCompleteTaskUrl(appName: string, taskId: string): string { - return `${this.appConfigService.get('bpmHost')}/${appName}/rb/v1/tasks/${taskId}/complete`; + return `${this.getBasePath(appName)}/rb/v1/tasks/${taskId}/complete`; } private handleError(error: any) { diff --git a/lib/process-services-cloud/src/lib/task/start-task/components/people-cloud/people-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/task/start-task/components/people-cloud/people-cloud.component.spec.ts index 7469ca0c67..01a171afae 100644 --- a/lib/process-services-cloud/src/lib/task/start-task/components/people-cloud/people-cloud.component.spec.ts +++ b/lib/process-services-cloud/src/lib/task/start-task/components/people-cloud/people-cloud.component.spec.ts @@ -17,7 +17,7 @@ import { PeopleCloudComponent } from './people-cloud.component'; import { ComponentFixture, TestBed, async } from '@angular/core/testing'; -import { IdentityUserService, AlfrescoApiService, AlfrescoApiServiceMock, CoreModule, IdentityUserModel } from '@alfresco/adf-core'; +import { IdentityUserService, AlfrescoApiService, CoreModule, IdentityUserModel, setupTestBed } from '@alfresco/adf-core'; import { ProcessServiceCloudTestingModule } from '../../../../testing/process-service-cloud.testing.module'; import { of } from 'rxjs'; import { mockUsers } from '../../mock/user-cloud.mock'; @@ -43,31 +43,23 @@ describe('PeopleCloudComponent', () => { { id: mockUsers[2].id, username: mockUsers[2].username } ]; - beforeEach(async(() => { - TestBed.configureTestingModule({ - imports: [ - CoreModule.forRoot(), - ProcessServiceCloudTestingModule, - StartTaskCloudModule - ], - providers: [ - IdentityUserService - ] - }) - .overrideComponent(PeopleCloudComponent, { - set: { - providers: [ - { provide: AlfrescoApiService, useClass: AlfrescoApiServiceMock } - ] - } - }).compileComponents(); - })); + setupTestBed({ + imports: [ + CoreModule.forRoot(), + ProcessServiceCloudTestingModule, + StartTaskCloudModule + ], + providers: [ + IdentityUserService + ] + }); beforeEach(() => { fixture = TestBed.createComponent(PeopleCloudComponent); component = fixture.componentInstance; identityService = TestBed.get(IdentityUserService); alfrescoApiService = TestBed.get(AlfrescoApiService); + spyOn(alfrescoApiService, 'getInstance').and.returnValue(mock); }); it('should create PeopleCloudComponent', () => { @@ -79,7 +71,6 @@ describe('PeopleCloudComponent', () => { let findUsersByNameSpy: jasmine.Spy; beforeEach(async(() => { - spyOn(alfrescoApiService, 'getInstance').and.returnValue(mock); findUsersByNameSpy = spyOn(identityService, 'findUsersByName').and.returnValue(of(mockUsers)); fixture.detectChanges(); element = fixture.nativeElement; @@ -173,7 +164,6 @@ describe('PeopleCloudComponent', () => { let findUsersByNameSpy: jasmine.Spy; beforeEach(async(() => { - spyOn(alfrescoApiService, 'getInstance').and.returnValue(mock); findUsersByNameSpy = spyOn(identityService, 'findUsersByName').and.returnValue(of(mockUsers)); checkUserHasAccessSpy = spyOn(identityService, 'checkUserHasClientApp').and.returnValue(of(true)); checkUserHasAnyClientAppRoleSpy = spyOn(identityService, 'checkUserHasAnyClientAppRole').and.returnValue(of(true)); @@ -318,7 +308,6 @@ describe('PeopleCloudComponent', () => { beforeEach(async(() => { component.roles = ['mock-role-1', 'mock-role-2']; - spyOn(alfrescoApiService, 'getInstance').and.returnValue(mock); spyOn(identityService, 'findUsersByName').and.returnValue(of(mockUsers)); checkUserHasRoleSpy = spyOn(identityService, 'checkUserHasRole').and.returnValue(of(true)); fixture.detectChanges(); @@ -458,6 +447,7 @@ describe('PeopleCloudComponent', () => { component.preSelectUsers = mockPreselectedUsers; fixture.detectChanges(); element = fixture.nativeElement; + alfrescoApiService = TestBed.get(AlfrescoApiService); })); afterEach(() => { @@ -473,8 +463,9 @@ describe('PeopleCloudComponent', () => { }); })); - it('should pre-select all preSelectUsers when mode=multiple', async(() => { + it('should pre-select all preSelectUsers when mode=multiple validation disabled', async(() => { component.mode = 'multiple'; + fixture.detectChanges(); component.ngOnChanges({ 'preSelectUsers': change }); fixture.detectChanges(); fixture.whenStable().then(() => { @@ -496,15 +487,11 @@ describe('PeopleCloudComponent', () => { component.mode = 'multiple'; component.validate = true; component.preSelectUsers = mockPreselectedUsers; - fixture.detectChanges(); element = fixture.nativeElement; + alfrescoApiService = TestBed.get(AlfrescoApiService); + fixture.detectChanges(); })); - afterEach(() => { - fixture.destroy(); - TestBed.resetTestingModule(); - }); - it('should show chip list when mode=multiple', async(() => { fixture.detectChanges(); fixture.whenStable().then(() => { @@ -514,9 +501,9 @@ describe('PeopleCloudComponent', () => { })); it('should pre-select all preSelectUsers when mode=multiple', async(() => { - fixture.detectChanges(); spyOn(component, 'searchUser').and.returnValue(Promise.resolve(mockPreselectedUsers)); component.mode = 'multiple'; + fixture.detectChanges(); component.ngOnChanges({ 'preSelectUsers': change }); fixture.detectChanges(); fixture.whenStable().then(() => { @@ -527,7 +514,6 @@ describe('PeopleCloudComponent', () => { })); it('should emit removeUser when a selected user is removed if mode=multiple', async(() => { - fixture.detectChanges(); const removeUserSpy = spyOn(component.removeUser, 'emit'); component.mode = 'multiple'; fixture.detectChanges(); @@ -559,6 +545,7 @@ describe('PeopleCloudComponent', () => { const findByIdSpy = spyOn(identityService, 'findUserById').and.returnValue(of(mockUsers[0])); component.mode = 'multiple'; component.validate = true; + fixture.detectChanges(); component.preSelectUsers = [{ id: mockUsers[0].id }, { id: mockUsers[1].id }]; component.ngOnChanges({ 'preSelectUsers': change }); fixture.detectChanges(); @@ -587,6 +574,7 @@ describe('PeopleCloudComponent', () => { it('should filter user by email if validate true', async(() => { const findUserByEmailSpy = spyOn(identityService, 'findUserByEmail').and.returnValue(of(mockUsers)); + fixture.detectChanges(); component.mode = 'multiple'; component.validate = true; component.preSelectUsers = [{ email: mockUsers[1].email }, { email: mockUsers[2].email }]; @@ -604,6 +592,7 @@ describe('PeopleCloudComponent', () => { const findUserByIdSpy = spyOn(identityService, 'findUserById').and.returnValue(of(mockUsers[0])); component.mode = 'single'; component.validate = true; + fixture.detectChanges(); component.preSelectUsers = [{ id: mockUsers[0].id }]; fixture.detectChanges(); fixture.whenStable().then(() => { diff --git a/lib/process-services-cloud/src/lib/task/start-task/services/start-task-cloud.service.ts b/lib/process-services-cloud/src/lib/task/start-task/services/start-task-cloud.service.ts index 99c3e150fa..419ccbc529 100644 --- a/lib/process-services-cloud/src/lib/task/start-task/services/start-task-cloud.service.ts +++ b/lib/process-services-cloud/src/lib/task/start-task/services/start-task-cloud.service.ts @@ -25,15 +25,16 @@ import { from, Observable, throwError } from 'rxjs'; import { StartTaskCloudRequestModel } from '../models/start-task-cloud-request.model'; import { TaskDetailsCloudModel, StartTaskCloudResponseModel } from '../models/task-details-cloud.model'; import { map, catchError } from 'rxjs/operators'; +import { BaseCloudService } from '../../../services/base-cloud.service'; @Injectable() -export class StartTaskCloudService { +export class StartTaskCloudService extends BaseCloudService { constructor( private apiService: AlfrescoApiService, private appConfigService: AppConfigService, private logService: LogService - ) {} + ) { super(); } /** * Creates a new standalone task. @@ -62,7 +63,8 @@ export class StartTaskCloudService { } private buildCreateTaskUrl(appName: string): any { - return `${this.appConfigService.get('bpmHost')}/${appName}/rb/v1/tasks`; + this.contextRoot = this.appConfigService.get('bpmHost'); + return `${this.getBasePath(appName)}/rb/v1/tasks`; } private buildRequestBody(taskDetails: any) { diff --git a/lib/process-services-cloud/src/lib/task/task-filters/components/edit-task-filter-cloud.component.ts b/lib/process-services-cloud/src/lib/task/task-filters/components/edit-task-filter-cloud.component.ts index 2771a3ecce..36b4fa0317 100644 --- a/lib/process-services-cloud/src/lib/task/task-filters/components/edit-task-filter-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/task/task-filters/components/edit-task-filter-cloud.component.ts @@ -231,7 +231,7 @@ export class EditTaskFilterCloudComponent implements OnInit, OnChanges { return this.filterProperties.indexOf(EditTaskFilterCloudComponent.LAST_MODIFIED) >= 0; } - createSortProperties(): any { + get createSortProperties(): any { this.checkMandatorySortProperties(); const sortProperties = this.sortProperties.map((property: string) => { return { label: property.charAt(0).toUpperCase() + property.slice(1), value: property }; @@ -523,7 +523,7 @@ export class EditTaskFilterCloudComponent implements OnInit, OnChanges { type: 'select', key: 'sort', value: currentTaskFilter.sort || this.createSortProperties[0].value, - options: this.createSortProperties() + options: this.createSortProperties }), new TaskFilterProperties({ label: 'ADF_CLOUD_EDIT_TASK_FILTER.LABEL.DIRECTION', diff --git a/lib/process-services-cloud/src/lib/task/task-filters/services/task-filter-cloud.service.ts b/lib/process-services-cloud/src/lib/task/task-filters/services/task-filter-cloud.service.ts index 90ed79d974..2aa79df927 100644 --- a/lib/process-services-cloud/src/lib/task/task-filters/services/task-filter-cloud.service.ts +++ b/lib/process-services-cloud/src/lib/task/task-filters/services/task-filter-cloud.service.ts @@ -52,7 +52,6 @@ export class TaskFilterCloudService { const username = this.getUsername(); const key = `task-filters-${appName}-${username}`; const filters = JSON.parse(this.storage.getItem(key) || '[]'); - if (filters.length === 0) { this.createDefaultFilters(appName); } else { diff --git a/lib/process-services-cloud/src/lib/task/task-header/components/task-header-cloud.component.ts b/lib/process-services-cloud/src/lib/task/task-header/components/task-header-cloud.component.ts index 9ec9bda32b..1b726e4429 100644 --- a/lib/process-services-cloud/src/lib/task/task-header/components/task-header-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/task/task-header/components/task-header-cloud.component.ts @@ -67,7 +67,7 @@ export class TaskHeaderCloudComponent implements OnInit { ) { } ngOnInit() { - if (this.appName && this.taskId) { + if ((this.appName || this.appName === '') && this.taskId) { this.loadTaskDetailsById(this.appName, this.taskId); } @@ -226,7 +226,7 @@ export class TaskHeaderCloudComponent implements OnInit { } isTaskValid() { - return this.appName && this.taskId; + return (this.appName || this.appName === '') && this.taskId; } isTaskAssigned() { diff --git a/lib/process-services-cloud/src/lib/task/task-list/components/task-list-cloud.component.ts b/lib/process-services-cloud/src/lib/task/task-list/components/task-list-cloud.component.ts index 7355f7c4ea..034844cd3f 100644 --- a/lib/process-services-cloud/src/lib/task/task-list/components/task-list-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/task/task-list/components/task-list-cloud.component.ts @@ -193,7 +193,7 @@ export class TaskListCloudComponent extends DataTableSchema implements OnChanges reload() { this.requestNode = this.createRequestNode(); - if (this.requestNode.appName) { + if (this.requestNode.appName || this.requestNode.appName === '') { this.load(this.requestNode); } else { this.rows = []; diff --git a/lib/process-services-cloud/src/lib/task/task-list/services/task-list-cloud.service.ts b/lib/process-services-cloud/src/lib/task/task-list/services/task-list-cloud.service.ts index 717847862a..8cfcf69794 100644 --- a/lib/process-services-cloud/src/lib/task/task-list/services/task-list-cloud.service.ts +++ b/lib/process-services-cloud/src/lib/task/task-list/services/task-list-cloud.service.ts @@ -20,13 +20,15 @@ import { AlfrescoApiService, AppConfigService, LogService } from '@alfresco/adf- import { TaskQueryCloudRequestModel } from '../models/filter-cloud-model'; import { Observable, from, throwError } from 'rxjs'; import { TaskListCloudSortingModel } from '../models/task-list-sorting.model'; +import { BaseCloudService } from '../../../services/base-cloud.service'; @Injectable() -export class TaskListCloudService { +export class TaskListCloudService extends BaseCloudService { constructor(private apiService: AlfrescoApiService, private appConfigService: AppConfigService, private logService: LogService) { + super(); } contentTypes = ['application/json']; @@ -38,7 +40,8 @@ export class TaskListCloudService { * @returns Task information */ getTaskByRequest(requestNode: TaskQueryCloudRequestModel): Observable { - if (requestNode.appName) { + + if (requestNode.appName || requestNode.appName === '') { const queryUrl = this.buildQueryUrl(requestNode); const queryParams = this.buildQueryParams(requestNode); const sortingParams = this.buildSortingParam(requestNode.sorting); @@ -58,7 +61,8 @@ export class TaskListCloudService { } private buildQueryUrl(requestNode: TaskQueryCloudRequestModel) { - return `${this.appConfigService.get('bpmHost', '')}/${requestNode.appName}/query/v1/tasks`; + this.contextRoot = this.appConfigService.get('bpmHost', ''); + return `${this.getBasePath(requestNode.appName)}/query/v1/tasks`; } private buildQueryParams(requestNode: TaskQueryCloudRequestModel) {