[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
This commit is contained in:
Silviu Popa
2019-04-30 12:13:10 +03:00
committed by Eugenio Romano
parent 5f3d665ab5
commit 860529058c
39 changed files with 1074 additions and 78 deletions

View File

@@ -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": {

View File

@@ -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: [
{

View File

@@ -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],

View File

@@ -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' }
]},

View File

@@ -0,0 +1,36 @@
<mat-tab-group fxFill class="adf-cloud-layout-tab-body">
<mat-tab label="{{'PS_CLOUD_TAB.APPS_TAB' | translate}}">
<div fxFill fxLayout>
<adf-sidenav-layout fxFlex [sidenavMin]="70" [sidenavMax]="270" [stepOver]="780">
<adf-sidenav-layout-navigation>
<ng-template>
<adf-sidebar-action-menu [expanded]="true" [width]="205" title="{{'ADF_SIDEBAR_ACTION_MENU.BUTTON.CREATE' | translate}}">
<mat-icon adf-sidebar-menu-title-icon>arrow_drop_down</mat-icon>
<div adf-sidebar-menu-options>
<button mat-menu-item data-automation-id="btn-start-task" (click)="onStartTask()">
<mat-icon>assessment</mat-icon>
<span>{{'ADF_SIDEBAR_ACTION_MENU.BUTTON.NEW_TASK' | translate}}</span>
</button>
</div>
<div adf-sidebar-menu-options>
<button mat-menu-item data-automation-id="btn-start-process" (click)="onStartProcess()">
<mat-icon>assessment</mat-icon>
<span>{{'ADF_SIDEBAR_ACTION_MENU.BUTTON.NEW_PROCESS' | translate}}</span>
</button>
</div>
</adf-sidebar-action-menu>
<app-community-cloud-filters-demo></app-community-cloud-filters-demo>
</ng-template>
</adf-sidenav-layout-navigation>
<adf-sidenav-layout-content>
<ng-template>
<router-outlet></router-outlet>
</ng-template>
</adf-sidenav-layout-content>
</adf-sidenav-layout>
</div>
</mat-tab>
<mat-tab label="{{'PS_CLOUD_TAB.SETTINGS_TAB' | translate}}">
<app-cloud-settings></app-cloud-settings>
</mat-tab>
</mat-tab-group>

View File

@@ -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/`]);
}
}

View File

@@ -0,0 +1,31 @@
<mat-accordion>
<mat-expansion-panel [expanded]="expandTaskFilter" (opened)="onTaskFilterOpen()" (closed)="onTaskFilterClose()" data-automation-id='Task Filters'>
<mat-expansion-panel-header>
<mat-panel-title>
Task Filters
</mat-panel-title>
</mat-expansion-panel-header>
<adf-cloud-task-filters
*ngIf="expandTaskFilter"
[appName]="appName"
[showIcons]="true"
[filterParam]="currentTaskFilter$ | async"
(filterClick)="onTaskFilterSelected($event)">
</adf-cloud-task-filters>
</mat-expansion-panel>
<mat-expansion-panel [expanded]="expandProcessFilter" (opened)="onProcessFilterOpen()" (closed)="onProcessFilterClose()" data-automation-id='Process Filters'>
<mat-expansion-panel-header>
<mat-panel-title>
Process Filters
</mat-panel-title>
</mat-expansion-panel-header>
<adf-cloud-process-filters
*ngIf="expandProcessFilter"
[appName]="appName"
[showIcons]="true"
[filterParam]="currentProcessFilter$ | async"
(filterClick)="onProcessFilterSelected($event)">
</adf-cloud-process-filters>
</mat-expansion-panel>
</mat-accordion>

View File

@@ -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<any>;
currentProcessFilter$: Observable<any>;
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;
}
}

View File

@@ -0,0 +1,24 @@
<button data-automation-id="go-back" mat-icon-button (click)="onGoBack()">
<mat-icon>arrow_back</mat-icon> Go Back
</button>
<h4 data-automation-id="process-details-header">Simple page to show the process instance: {{ processInstanceId }} of the app: {{ appName }}</h4>
<div class="adf-process-cloud-container">
<adf-cloud-task-list
fxFlex
class="adf-cloud-layout-overflow"
[processInstanceId]="processInstanceId"
(rowClick)="onRowClick($event)"
#taskCloud>
</adf-cloud-task-list>
<adf-cloud-process-header
class="adf-process-cloud-header"
[appName]="''"
[processInstanceId]="processInstanceId">
</adf-cloud-process-header>
</div>

View File

@@ -0,0 +1,14 @@
.adf {
&-process-cloud-container {
display: flex;
}
&-cloud-layout-overflow {
width:67%;
}
&-process-cloud-header {
margin-left: 10px;
width: 25%;
}
}

View File

@@ -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}`]);
}
}
}

View File

@@ -0,0 +1,44 @@
<div fxLayout="column" fxFill fxLayoutGap="2px">
<adf-cloud-edit-process-filter
[id]="filterId"
[appName]="'community'"
[filterProperties]="processFilterProperties.filterProperties"
[sortProperties]="processFilterProperties.sortProperties"
[actions]="processFilterProperties.actions"
(filterChange)="onFilterChange($event)"
(action)="onProcessFilterAction($event)">
</adf-cloud-edit-process-filter>
<div fxLayout="column" fxFlex fxLayoutAlign="space-between" *ngIf="editedFilter">
<adf-cloud-process-list #processCloud
fxFlex
[appName]="''"
class="adf-cloud-layout-overflow"
[initiator]="editedFilter.initiator"
[processDefinitionId]="editedFilter.processDefinitionId"
[processDefinitionKey]="editedFilter.processDefinitionKey"
[id]="editedFilter.processInstanceId"
[status]="editedFilter.status"
[name]="editedFilter.processName"
[businessKey]="editedFilter.businessKey"
[lastModifiedFrom]="editedFilter.lastModifiedFrom"
[lastModifiedTo]="editedFilter.lastModifiedTo"
[sorting]="sortArray"
[selectionMode]="selectionMode"
[multiselect]="multiselect"
(rowClick)="onRowClick($event)"
(rowsSelected)="onRowsSelected($event)">
</adf-cloud-process-list>
<adf-pagination
[target]="processCloud"
(changePageSize)="onChangePageSize($event)"
(nextPage)="resetSelectedRows()"
(prevPage)="resetSelectedRows()">
</adf-pagination>
<div *ngIf="testingMode">
Selected rows:
<ul>
<li *ngFor="let row of selectedRows">{{ row.id }}</li>
</ul>
</div>
</div>
</div>

View File

@@ -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<Array<any>>(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);
}
}

View File

@@ -0,0 +1,7 @@
<adf-cloud-start-process
[name]="processName"
[appName]="''"
(error)="openSnackMessage($event)"
(success)="onStartProcessSuccess()"
(cancel)="onCancelStartProcess()">
</adf-cloud-start-process>

View File

@@ -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<string>('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
);
}
}

View File

@@ -0,0 +1,5 @@
<adf-cloud-start-task
(error)="openSnackMessage($event)"
(success)="onStartTaskSuccess()"
(cancel)="onCancelStartTask()">
</adf-cloud-start-task>

View File

@@ -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
);
}
}

View File

@@ -0,0 +1,48 @@
<div fxLayout="column" fxFill fxLayoutGap="2px">
<adf-cloud-edit-task-filter
[id]="filterId"
[appName]="'community'"
[filterProperties]="taskFilterProperties.filterProperties"
[sortProperties]="taskFilterProperties.sortProperties"
[actions]="taskFilterProperties.actions"
(action)="onTaskFilterAction($event)"
(filterChange)="onFilterChange($event)">
</adf-cloud-edit-task-filter>
<div fxLayout="column" fxFlex fxLayoutAlign="space-between" *ngIf="editedFilter">
<adf-cloud-task-list #taskCloud
fxFlex
[appName]="''"
class="adf-cloud-layout-overflow"
[processDefinitionId]="editedFilter.processDefinitionId"
[processInstanceId]="editedFilter.processInstanceId"
[name]="editedFilter.taskName"
[id]="editedFilter.taskId"
[parentTaskId]="editedFilter.parentTaskId"
[priority]="editedFilter.priority"
[owner]="editedFilter.owner"
[lastModifiedFrom]="editedFilter.lastModifiedFrom"
[lastModifiedTo]="editedFilter.lastModifiedTo"
[status]="editedFilter.status"
[assignee]="editedFilter.assignee"
[createdDate]="editedFilter.createdDate"
[dueDate]="editedFilter.dueDate"
[sorting]="sortArray"
[multiselect]="multiselect"
[selectionMode]="selectionMode"
(rowClick)="onRowClick($event)"
(rowsSelected)="onRowsSelected($event)">
</adf-cloud-task-list>
<adf-pagination
[target]="taskCloud"
(changePageSize)="onChangePageSize($event)"
(nextPage)="resetSelectedRows()"
(prevPage)="resetSelectedRows()">
</adf-pagination>
<div *ngIf="testingMode">
Selected rows:
<ul>
<li *ngFor="let row of selectedRows" [attr.data-automation-id]="row.id">{{ row.name }}</li>
</ul>
</div>
</div>
</div>

View File

@@ -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<Array<any>>(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 });
}
}
}

View File

@@ -0,0 +1,21 @@
<h4 data-automation-id="task-details-header">Simple page to show the taskId: {{ taskId }} of the app: {{ appName }}</h4>
<div fxLayout="column" fxFill fxLayoutGap="2px">
<div fxLayout="row" fxFill>
<div fxLayout="column" fxFlex="80%">
<adf-task-form-cloud
[appName]="''"
[taskId]="taskId"
(cancelClick)="goBack()"
(taskClaimed)="onClaimTask()"
(taskCompleted)="onTaskCompleted()"
(taskUnclaimed)="onUnclaimTask()"
(formSaved)="onFormSaved()">
</adf-task-form-cloud>
</div>
<adf-cloud-task-header fxFlex
[appName]="''"
[taskId]="taskId">
</adf-cloud-task-header>
</div>
</div>

View File

@@ -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;
}
}

View File

@@ -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');
}
}

View File

@@ -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,

View File

@@ -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 <ProcessFilterOptions> { 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',

View File

@@ -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);
}
}

View File

@@ -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<ProcessInstanceCloud> {
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,

View File

@@ -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 = [];

View File

@@ -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<any> {
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) {

View File

@@ -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 {

View File

@@ -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<ProcessDefinitionCloud[]> {
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<ProcessInstanceCloud> {
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',

View File

@@ -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 !== '';
}
}

View File

@@ -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<TaskDetailsCloudModel> {
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<TaskDetailsCloudModel> {
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<TaskDetailsCloudModel> {
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) {

View File

@@ -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 = <any> 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 = <any> 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 = <any> [{ 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 = <any> [{ 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 = <any> [{ id: mockUsers[0].id }];
fixture.detectChanges();
fixture.whenStable().then(() => {

View File

@@ -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) {

View File

@@ -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 <FilterOptions> { 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',

View File

@@ -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 {

View File

@@ -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() {

View File

@@ -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 = [];

View File

@@ -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<any> {
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) {