[ADF-3540] Start Task Cloud by cli (#3954)

* [ADF-3538] start creating new folder for cloud components

* [ADF-3538] added new package to the script and the builds

* [ADF-3538] added some more changes to scripts

* [ADF-3538] - starting the new package

* Add a cloud component as example

* Skip the scss style

* remove useless codes

* Add i18n example

* remove useless code

* Simplify the hello component
Fix the wrong path

* add the app-list-cloud-component
add the app-details-cloud-component

* Fix process service cloud path

* Remove useless file

* [ADF-3540] Start Task Component APS2

* Generated startTaskCloudModule
* Generated start-task-cloud  component by cli
* Used  start-task-cloud in the demo shell

* * Added FormModule instead of  CoreModule
* Added StartTaskTestingModule
* Refactored startTaskCloud Component

* * Used FlexLayout
* Used Keylock api to fetch users
* Removed all css
* Refactored start-task-cloud component
* Removed form field from the starttask form
* Created UsedCloud model
* Added unit test to the recent changes
* Added mock objects

* * Added  unit test to the startTaskCloud component

* * Added documentation about startTaskCLoud component
* Changed runtimeBundle to appName
* Changed defaultTaskName to name

* * Generated people-cloud component
* Created initialUserName pipe

* * Fetching roles by userId
* Filtering Users with required roles
* Removed duplicates
* Generated initial-user-name pipe
* Generated people-cloud component
* Created roleCloud module

* * Rebased with development branch
* Created start-task-cloud-demo component in the demo-shell

* * Added unit tests to the start-task-cloud service
* Added unit test to the people-cloud component and userInitail pipe
* Updated start-task unit tests to the recent changes
* Created mock data

* * Updated people-cloud component with  error message* Updated unit tests

* * Included StartTaskCloud component in the demoShell* Created startTask demo component* Added create task button in the tasklist demo component

* * Added lodash

* * Fixed lodash import

* Add the start task into the cloud demo

* Fix the lodash import and @type

* Show the My task once the task has been created

* first change

* [ADF-3540] Improved start task component

* [ADF-3540] Fixed expression changed error

* [ADF-3540] Refactored code

* [ADF-3540] Fix lodash import error

* [ADF-3540] Remove lodash dependency

* [ADF-3540] Refatored code

* tmp

* [ADF-3540] Show/Hide current user as part of list

* [ADF-3340] Assign new task to current user when no assignee selected

* [ADF-3540] Rebased the latest changes

* [ADF-3540] Refactored code

* [ADF-3540] Improved user search logic for people component

* [ADF-3540] Moved user services to Core module

* [ADF-3540] Modified translation keys

* Add process-services-cloud into the license rule

* Fix wrong import for prod build

* Add license header

* Fix unit tests

* Fix proxy karma for content

* Fix proxy karma for process services

* Fix proxy karma for process cloud
This commit is contained in:
Deepak Paul
2018-11-29 20:06:51 +05:30
committed by Eugenio Romano
parent 5bea17fa6c
commit 2f0f33643b
49 changed files with 1961 additions and 94 deletions

View File

@@ -3,8 +3,17 @@
module.exports = function (config) {
config.set({
basePath: '',
basePath: '../../',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
files: [
{pattern: 'lib/core/i18n/**/en.json', included: false, served: true, watched: false},
{pattern: 'lib/config/app.config.json', included: false, served: true, watched: false},
],
proxies: {
'/base/assets/': '/base/lib/process-services-cloud/src/lib/assets/',
'/assets/adf-core/i18n/en.json': '/base/lib/core/i18n/en.json',
'/app.config.json': '/base/lib/config/app.config.json'
},
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),

View File

@@ -1,3 +1,19 @@
/*!
* @license
* Copyright 2016 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 { AppListCloudModule } from './app-list-cloud.module';
describe('AppListCloudModule', () => {

View File

@@ -14,5 +14,13 @@
"ALL_PROCESSES": "All Processes",
"RUNNING_PROCESSES": "Running Processes",
"COMPLETED_PROCESSES": "Completed Processes"
},
"ADF_CLOUD_START_TASK": {
"ERROR": {
"MESSAGE": "Enter a different value",
"REQUIRED": "Field required",
"DATE": "Date format DD/MM/YYYY",
"MAXIMUM_LENGTH": "Length exceeded, {{characters}} characters max."
}
}
}

View File

@@ -1,3 +1,19 @@
/*!
* @license
* Copyright 2016 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, OnChanges, AfterContentInit, ContentChild, Output, EventEmitter, SimpleChanges, SimpleChange, Input } from '@angular/core';
import { DataTableSchema, PaginatedComponent,
EmptyCustomContentDirective, AppConfigService,

View File

@@ -2,14 +2,14 @@
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the License);
* 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,
* 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.

View File

@@ -1,3 +1,19 @@
/*!
* @license
* Copyright 2016 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 { ProcessListCloudModule } from './process-list-cloud.module';
describe('ProcessListCloudModule', () => {

View File

@@ -1,3 +1,20 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ProcessListCloudComponent } from './components/process-list-cloud.component';

View File

@@ -22,6 +22,7 @@ import { TaskListCloudModule } from './task-list-cloud/task-list-cloud.module';
import { TaskCloudModule } from './task-cloud/task-cloud.module';
import { ProcessListCloudModule } from './process-list-cloud/process-list-cloud.module';
import { ProcessCloudModule } from './process-cloud/process-cloud.module';
import { StartTaskCloudModule } from './start-task-cloud/start-task-cloud.module';
@NgModule({
imports: [
@@ -29,7 +30,8 @@ import { ProcessCloudModule } from './process-cloud/process-cloud.module';
TaskListCloudModule,
TaskCloudModule,
ProcessListCloudModule,
ProcessCloudModule
ProcessCloudModule,
StartTaskCloudModule
],
providers: [
{
@@ -41,12 +43,13 @@ import { ProcessCloudModule } from './process-cloud/process-cloud.module';
}
}
],
declarations: [],
exports: [
AppListCloudModule,
TaskListCloudModule,
TaskCloudModule,
ProcessListCloudModule,
ProcessCloudModule]
ProcessCloudModule,
StartTaskCloudModule
]
})
export class ProcessServicesCloudModule { }

View File

@@ -0,0 +1,29 @@
<form>
<mat-form-field class="adf-people-cloud">
<mat-label id="assignee-id">{{'ADF_TASK_LIST.START_TASK.FORM.LABEL.ASSIGNEE' | translate}}</mat-label>
<input #inputValue
matInput
class="adf-cloud-input"
data-automation-id="adf-people-cloud-search-input"
type="text"
[formControl]="searchUser"
[matAutocomplete]="auto">
<mat-autocomplete autoActiveFirstOption class="adf-people-cloud-list"
#auto="matAutocomplete"
(optionSelected)="onSelect($event.option.value)"
[displayWith]="getDisplayName">
<mat-option *ngFor="let user of users$ | async; let i = index" [value]="user">
<div class="adf-people-cloud-row" id="adf-people-cloud-user-{{i}}">
<div [outerHTML]="user | usernameInitials:'adf-people-widget-pic'"></div>
<span class="adf-people-label-name"> {{user | fullName}}</span>
</div>
</mat-option>
</mat-autocomplete>
</mat-form-field>
<div class="adf-start-task-cloud-error">
<div *ngIf="dataError" fxLayout="row" fxLayoutAlign="start start" [@transitionMessages]="_subscriptAnimationState">
<div class="adf-start-task-cloud-error-message">{{ 'ADF_CLOUD_START_TASK.ERROR.MESSAGE' | translate }}</div>
<mat-icon class="adf-start-task-cloud-error-icon">warning</mat-icon>
</div>
</div>
</form>

View File

@@ -0,0 +1,62 @@
@mixin adf-cloud-people-theme($theme) {
$warn: map-get($theme, warn);
$primary: map-get($theme, primary);
$background: map-get($theme, background);
$foreground: map-get($theme, foreground);
.adf {
&-people-cloud {
width: 100%;
padding-top: 8px;
}
&-people-cloud-list {
margin: 5px 0;
padding: 10px 0;
}
&-people-cloud-row {
display: flex;
align-items: center;
}
&-people-cloud-pic {
background: mat-color($primary);
display: flex;
justify-content: center;
align-items: center;
width: 40px;
height: 40px;
border-radius: 100px;
color: mat-color($foreground, text);
font-weight: bolder;
font-size: 18px;
text-transform: uppercase;
}
&-start-task-cloud-error {
margin-top: -10px;
}
&-start-task-cloud-error {
position: absolute;
height: 20px;
&-message {
padding-right: 8px;
height: 16px;
font-size: 12px;
line-height: 1.33;
color: mat-color($warn);
width: auto;
}
&-icon {
font-size: 17px;
color: mat-color($warn);
}
}
}
}

View File

@@ -0,0 +1,138 @@
/*!
* @license
* Copyright 2016 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 { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { PeopleCloudComponent } from './people-cloud.component';
import { StartTaskCloudTestingModule } from '../../testing/start-task-cloud.testing.module';
import { LogService, setupTestBed, IdentityUserService, IdentityUserModel } from '@alfresco/adf-core';
import { mockUsers, mockRoles } from '../../mock/user-cloud.mock';
import { of } from 'rxjs';
import { ProcessServiceCloudTestingModule } from '../../../testing/process-service-cloud.testing.module';
describe('PeopleCloudComponent', () => {
let component: PeopleCloudComponent;
let fixture: ComponentFixture<PeopleCloudComponent>;
let element: HTMLElement;
let identityService: IdentityUserService;
let getRolesByUserIdSpy: jasmine.Spy;
let getUserSpy: jasmine.Spy;
setupTestBed({
imports: [ProcessServiceCloudTestingModule, StartTaskCloudTestingModule],
providers: [IdentityUserService, LogService]
});
beforeEach(() => {
fixture = TestBed.createComponent(PeopleCloudComponent);
component = fixture.componentInstance;
element = fixture.nativeElement;
identityService = TestBed.get(IdentityUserService);
getRolesByUserIdSpy = spyOn(identityService, 'getUserRoles').and.returnValue(of(mockRoles));
getUserSpy = spyOn(identityService, 'getUsers').and.returnValue(of(mockUsers));
});
it('should create PeopleCloudComponent', () => {
expect(component instanceof PeopleCloudComponent).toBeTruthy();
});
it('should able to fetch users', () => {
fixture.detectChanges();
expect(getUserSpy).toHaveBeenCalled();
});
it('should able to fetch roles by user id', async(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(getRolesByUserIdSpy).toHaveBeenCalled();
});
}));
it('should not list the current logged in user when showCurrentUser is false', async(() => {
spyOn(identityService, 'getCurrentUserInfo').and.returnValue(of(mockUsers[1]));
component.showCurrentUser = false;
fixture.detectChanges();
fixture.whenStable().then(() => {
const currentUser = component.users.find((user) => {
return user.username === mockUsers[1].username;
});
expect(currentUser).toBeUndefined();
});
}));
it('should show the users if the typed result match', async(() => {
component.users$ = of(<IdentityUserModel[]> mockUsers);
fixture.detectChanges();
let inputHTMLElement: HTMLInputElement = <HTMLInputElement> element.querySelector('input');
inputHTMLElement.focus();
inputHTMLElement.dispatchEvent(new Event('input'));
inputHTMLElement.dispatchEvent(new Event('keyup'));
inputHTMLElement.dispatchEvent(new Event('keydown'));
inputHTMLElement.value = 'M';
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(fixture.debugElement.query(By.css('mat-option'))).toBeDefined();
});
}));
it('should hide result list if input is empty', () => {
fixture.detectChanges();
let inputHTMLElement: HTMLInputElement = <HTMLInputElement> element.querySelector('input');
inputHTMLElement.focus();
inputHTMLElement.value = '';
inputHTMLElement.dispatchEvent(new Event('keyup'));
inputHTMLElement.dispatchEvent(new Event('input'));
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(fixture.debugElement.query(By.css('mat-option'))).toBeNull();
expect(fixture.debugElement.query(By.css('#adf-people-cloud-user-0'))).toBeNull();
});
});
it('should emit selectedUser if option is valid', async() => {
fixture.detectChanges();
let selectEmitSpy = spyOn(component.selectedUser, 'emit');
component.onSelect(new IdentityUserModel({ username: 'username'}));
fixture.whenStable().then(() => {
fixture.detectChanges();
expect(selectEmitSpy).toHaveBeenCalled();
});
});
it('should show an error message if the user is invalid', async(() => {
getUserSpy.and.returnValue(of([]));
getRolesByUserIdSpy.and.returnValue(of([]));
component.dataError = true;
fixture.detectChanges();
let inputHTMLElement: HTMLInputElement = <HTMLInputElement> element.querySelector('input');
inputHTMLElement.focus();
inputHTMLElement.dispatchEvent(new Event('input'));
inputHTMLElement.dispatchEvent(new Event('keyup'));
inputHTMLElement.dispatchEvent(new Event('keydown'));
inputHTMLElement.value = 'ZZZ';
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
const errorMessage = element.querySelector('.adf-start-task-cloud-error-message');
expect(element.querySelector('.adf-start-task-cloud-error')).not.toBeNull();
expect(errorMessage.textContent).toContain('ADF_CLOUD_START_TASK.ERROR.MESSAGE');
});
}));
});

View File

@@ -0,0 +1,110 @@
/*!
* @license
* Copyright 2016 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 { FormControl } from '@angular/forms';
import { Component, OnInit, Output, EventEmitter, ViewEncapsulation, Input } from '@angular/core';
import { Observable, of } from 'rxjs';
import { FullNamePipe, IdentityUserModel, IdentityUserService } from '@alfresco/adf-core';
import { trigger, state, style, transition, animate } from '@angular/animations';
@Component({
selector: 'adf-cloud-people',
templateUrl: './people-cloud.component.html',
styleUrls: ['./people-cloud.component.scss'],
animations: [
trigger('transitionMessages', [
state('enter', style({opacity: 1, transform: 'translateY(0%)'})),
transition('void => enter', [
style({opacity: 0, transform: 'translateY(-100%)'}),
animate('300ms cubic-bezier(0.55, 0, 0.55, 0.2)')
])
])
],
providers: [FullNamePipe],
encapsulation: ViewEncapsulation.None
})
export class PeopleCloudComponent implements OnInit {
static ROLE_ACTIVITI_ADMIN = 'ACTIVITI_ADMIN';
static ROLE_ACTIVITI_USER = 'ACTIVITI_USER';
static ROLE_ACTIVITI_MODELER = 'ACTIVITI_MODELER';
/** Show current user in the list or not. */
@Input()
showCurrentUser: boolean = true;
/** Emitted when a user is selected. */
@Output()
selectedUser: EventEmitter<IdentityUserModel> = new EventEmitter<IdentityUserModel>();
/** Emitted when an error occurs. */
@Output()
error: EventEmitter<any> = new EventEmitter<any>();
users$: Observable<IdentityUserModel[]>;
searchUser: FormControl = new FormControl();
_subscriptAnimationState: string = 'enter';
users: IdentityUserModel[] = [];
dataError = false;
currentUser: IdentityUserModel;
constructor(private identityUserService: IdentityUserService) { }
ngOnInit() {
this.loadUsers();
this.initSearch();
}
initSearch() {
this.searchUser.valueChanges.subscribe((keyword) => {
this.users$ = this.searchUsers(keyword);
});
}
private async loadUsers() {
const roles = [PeopleCloudComponent.ROLE_ACTIVITI_ADMIN, PeopleCloudComponent.ROLE_ACTIVITI_MODELER, PeopleCloudComponent.ROLE_ACTIVITI_USER];
if (this.showCurrentUser) {
this.users = await this.identityUserService.getUsersByRolesWithCurrentUser(roles);
} else {
this.users = await this.identityUserService.getUsersByRolesWithoutCurrentUser(roles);
}
}
private searchUsers(keyword: string): Observable<IdentityUserModel[]> {
const filteredUsers = this.users.filter((user) => {
return user.username.toLowerCase().indexOf(keyword.toString().toLowerCase()) !== -1;
});
this.dataError = filteredUsers.length === 0;
return of(filteredUsers);
}
onSelect(selectedUser: IdentityUserModel) {
this.selectedUser.emit(selectedUser);
this.dataError = false;
}
getDisplayName(user): string {
return FullNamePipe.prototype.transform(user);
}
}

View File

@@ -0,0 +1,89 @@
<mat-card>
<mat-card-header fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="10px" class="adf-cloud-start-task-heading">
<mat-card-title>{{'ADF_TASK_LIST.START_TASK.FORM.TITLE' | translate}}</mat-card-title>
</mat-card-header>
<form [formGroup]="taskForm" fxLayout="column" (ngSubmit)="saveTask()">
<mat-card-content>
<div class="adf-task-name">
<mat-form-field fxFlex>
<mat-label>{{'ADF_TASK_LIST.START_TASK.FORM.LABEL.NAME' | translate }}</mat-label>
<input
matInput
id="name_id"
class="form-control"
formControlName="name">
<mat-error *ngIf="nameController.hasError('required')">
{{ 'ADF_CLOUD_START_TASK.ERROR.REQUIRED' | translate }}
</mat-error>
<mat-error *ngIf="nameController.hasError('maxlength')">
{{ 'ADF_CLOUD_START_TASK.ERROR.MAXIMUM_LENGTH' | translate : { characters : maxNameLength } }}
</mat-error>
</mat-form-field>
</div>
<div class="input-row" fxLayout="row" fxLayout.lt-md="column" fxLayoutGap="20px" fxLayoutGap.lt-md="0px">
<mat-form-field fxFlex>
<mat-label>{{'ADF_TASK_LIST.START_TASK.FORM.LABEL.DESCRIPTION' | translate}}</mat-label>
<textarea
matInput
class="form-control"
id="description_id"
formControlName="description">
</textarea>
</mat-form-field>
<mat-form-field fxFlex>
<div style="height: 40px;">
<input matInput type="number" placeholder="Priority" formControlName="priority">
</div>
</mat-form-field>
</div>
<div class="input-row" fxLayout="row" fxLayout.lt-md="column" fxLayoutGap="20px" fxLayoutGap.lt-md="0px">
<mat-form-field fxFlex>
<input matInput
[matDatepicker]="taskDatePicker"
(keydown)="true"
(focusout)="onDateChanged($event.srcElement.value)"
placeholder="{{'ADF_TASK_LIST.START_TASK.FORM.LABEL.DATE'|translate}}"
[(ngModel)]="dueDate"
[ngModelOptions]="{standalone: true}"
id="date_id">
<mat-datepicker-toggle matSuffix [for]="taskDatePicker"></mat-datepicker-toggle>
<mat-datepicker #taskDatePicker
[touchUi]="true"
(dateChanged)="onDateChanged($event)">
</mat-datepicker>
<div class="adf-error-text-container">
<div *ngIf="dateError">
<div class="adf-error-text">{{'ADF_CLOUD_START_TASK.ERROR.DATE' | translate}}</div>
<mat-icon class="adf-error-icon">warning</mat-icon>
</div>
</div>
</mat-form-field>
<div fxFlex>
<adf-cloud-people (selectedUser)="onAssigneeSelect($event)"></adf-cloud-people>
</div>
</div>
</mat-card-content>
<mat-card-actions>
<div class="adf-cloud-start-task-footer" fxLayout="row" fxLayoutAlign="end end" >
<button
mat-button
type="button"
(click)="onCancel()"
id="button-cancel">
{{'ADF_TASK_LIST.START_TASK.FORM.ACTION.CANCEL'|translate}}
</button>
<button
color="primary"
type="submit" [disabled]="dateError || !taskForm.valid || submitted"
mat-button
id="button-start">
{{'ADF_TASK_LIST.START_TASK.FORM.ACTION.START'|translate}}
</button>
</div>
</mat-card-actions>
</form>
</mat-card>

View File

@@ -0,0 +1,34 @@
@mixin adf-start-task-cloud-theme($theme) {
$primary: map-get($theme, primary);
$accent: map-get($theme, accent);
$warn: map-get($theme, warn);
$foreground: map-get($theme, foreground);
$header-border: 1px solid mat-color($foreground, divider);
.adf-cloud-start-task-heading {
border-bottom: $header-border;
margin-bottom: 10px;
.mat-card-title {
font-weight: bold;
font-size: 18px;
}
}
.adf-cloud-start-task-footer {
padding: 4px;
font-size: 18px;
border-top: 1px solid #eee;
}
adf-cloud-start-task {
.adf {
&-cloud-start-task-footer {
.mat-button {
text-transform: uppercase !important;
}
}
}
}
}

View File

@@ -0,0 +1,240 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { setupTestBed, IdentityUserService } from '@alfresco/adf-core';
import {
AlfrescoApiService,
AppConfigService,
LogService,
StorageService,
UserPreferencesService,
IdentityUserModel
} from '@alfresco/adf-core';
import { StartTaskCloudService } from '../services/start-task-cloud.service';
import { StartTaskCloudComponent } from './start-task-cloud.component';
import { of, throwError } from 'rxjs';
import { taskDetailsMock } from '../mock/task-details.mock';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { ProcessServiceCloudTestingModule } from './../../testing/process-service-cloud.testing.module';
import { StartTaskCloudTestingModule } from '../testing/start-task-cloud.testing.module';
import { mockRoles, mockUsers } from '../mock/user-cloud.mock';
import { TaskDetailsCloudModel } from '../models/task-details-cloud.model';
describe('StartTaskCloudComponent', () => {
let component: StartTaskCloudComponent;
let fixture: ComponentFixture<StartTaskCloudComponent>;
let service: StartTaskCloudService;
let identityService: IdentityUserService;
let element: HTMLElement;
let createNewTaskSpy: jasmine.Spy;
let getRolesByUserIdSpy: jasmine.Spy;
let getUserSpy: jasmine.Spy;
setupTestBed({
imports: [ProcessServiceCloudTestingModule, StartTaskCloudTestingModule],
providers: [StartTaskCloudService, AlfrescoApiService, AppConfigService, LogService, StorageService, UserPreferencesService],
schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
});
beforeEach(async(() => {
fixture = TestBed.createComponent(StartTaskCloudComponent);
component = fixture.componentInstance;
element = fixture.nativeElement;
service = TestBed.get(StartTaskCloudService);
identityService = TestBed.get(IdentityUserService);
createNewTaskSpy = spyOn(service, 'createNewTask').and.returnValue(of(taskDetailsMock));
getRolesByUserIdSpy = spyOn(identityService, 'getUserRoles').and.returnValue(of(mockRoles));
getUserSpy = spyOn(identityService, 'getUsers').and.returnValue(of(mockUsers));
spyOn(identityService, 'getCurrentUserInfo').and.returnValue(of(new IdentityUserModel({username: 'currentUser'})));
fixture.detectChanges();
}));
it('should create instance of StartTaskCloudComponent', () => {
expect(component instanceof StartTaskCloudComponent).toBe(true, 'should create StartTaskCloudComponent');
});
it('should defined adf-cloud-people and fetch users ', () => {
component.ngOnInit();
fixture.detectChanges();
const peopleElement = fixture.debugElement.nativeElement.querySelector('adf-cloud-people');
expect(peopleElement).toBeDefined();
expect(getRolesByUserIdSpy).toHaveBeenCalled();
expect(getUserSpy).toHaveBeenCalled();
});
describe('create task', () => {
beforeEach(() => {
createNewTaskSpy.and.returnValue(of(
{
id: 91,
name: 'fakeName',
assignee: 'fake-assignee'
}
));
});
it('should create new task when start button is clicked', async(() => {
let successSpy = spyOn(component.success, 'emit');
component.taskForm.controls['name'].setValue('fakeName');
fixture.detectChanges();
let createTaskButton = <HTMLElement> element.querySelector('#button-start');
createTaskButton.click();
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(createNewTaskSpy).toHaveBeenCalled();
expect(successSpy).toHaveBeenCalled();
});
}));
it('should send on success event when the task is started', async(() => {
let successSpy = spyOn(component.success, 'emit');
component.taskForm.controls['name'].setValue('fakeName');
component.assigneeName = 'fake-assignee';
fixture.detectChanges();
let createTaskButton = <HTMLElement> element.querySelector('#button-start');
createTaskButton.click();
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(successSpy).toHaveBeenCalledWith({
id: 91,
name: 'fakeName',
assignee: 'fake-assignee'
});
});
}));
it('should send on success event when only name is given', async(() => {
let successSpy = spyOn(component.success, 'emit');
component.taskForm.controls['name'].setValue('fakeName');
fixture.detectChanges();
let createTaskButton = <HTMLElement> element.querySelector('#button-start');
createTaskButton.click();
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(successSpy).toHaveBeenCalled();
});
}));
it('should not emit success event when data not present', () => {
let successSpy = spyOn(component.success, 'emit');
component.taskForm.controls['name'].setValue('');
fixture.detectChanges();
let createTaskButton = <HTMLElement> element.querySelector('#button-start');
createTaskButton.click();
expect(createNewTaskSpy).not.toHaveBeenCalled();
expect(successSpy).not.toHaveBeenCalled();
});
it('should assign task when an assignee is selected', async(() => {
let successSpy = spyOn(component.success, 'emit');
component.taskForm.controls['name'].setValue('fakeName');
component.assigneeName = 'fake-assignee';
fixture.detectChanges();
let createTaskButton = <HTMLElement> element.querySelector('#button-start');
createTaskButton.click();
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(successSpy).toHaveBeenCalledWith({
id: 91,
name: 'fakeName',
assignee: 'fake-assignee'
});
});
}));
it('should assign task to the logged in user when assignee is not selected', async(() => {
component.taskForm.controls['name'].setValue('fakeName');
fixture.detectChanges();
let createTaskButton = <HTMLElement> element.querySelector('#button-start');
createTaskButton.click();
fixture.detectChanges();
fixture.whenStable().then(() => {
const taskRequest = new TaskDetailsCloudModel({ name: 'fakeName', assignee: 'currentUser'});
expect(createNewTaskSpy).toHaveBeenCalledWith(taskRequest);
});
}));
});
it('should show start task button', () => {
component.taskForm.controls['name'].setValue('fakeName');
fixture.detectChanges();
expect(element.querySelector('#button-start')).toBeDefined();
expect(element.querySelector('#button-start')).not.toBeNull();
expect(element.querySelector('#button-start').textContent).toContain('ADF_TASK_LIST.START_TASK.FORM.ACTION.START');
});
it('should disable start button if name is empty', () => {
component.taskForm.controls['name'].setValue('');
fixture.detectChanges();
let createTaskButton = fixture.nativeElement.querySelector('#button-start');
expect(createTaskButton.disabled).toBeTruthy();
});
it('should cancel start task on cancel button click', () => {
fixture.detectChanges();
let emitSpy = spyOn(component.cancel, 'emit');
let cancelTaskButton = fixture.nativeElement.querySelector('#button-cancel');
cancelTaskButton.click();
expect(emitSpy).not.toBeNull();
expect(emitSpy).toHaveBeenCalled();
});
it('should enable start button if name is filled out', () => {
component.taskForm.controls['name'].setValue('fakeName');
fixture.detectChanges();
let createTaskButton = fixture.nativeElement.querySelector('#button-start');
expect(createTaskButton.disabled).toBeFalsy();
});
it('should emit error when there is an error while creating task', () => {
component.taskForm.controls['name'].setValue('fakeName');
let errorSpy = spyOn(component.error, 'emit');
createNewTaskSpy.and.returnValue(throwError({}));
let createTaskButton = <HTMLElement> element.querySelector('#button-start');
fixture.detectChanges();
createTaskButton.click();
expect(errorSpy).toHaveBeenCalled();
});
it('should emit error when task name exceeds maximum length', () => {
component.maxNameLength = 2;
component.ngOnInit();
fixture.detectChanges();
let name = component.taskForm.controls['name'];
name.setValue('task');
fixture.detectChanges();
expect(name.valid).toBeFalsy();
name.setValue('ta');
fixture.detectChanges();
expect(name.valid).toBeTruthy();
});
it('should emit error when task name field is empty', () => {
fixture.detectChanges();
let name = component.taskForm.controls['name'];
name.setValue('');
fixture.detectChanges();
expect(name.valid).toBeFalsy();
name.setValue('task');
fixture.detectChanges();
expect(name.valid).toBeTruthy();
});
});

View File

@@ -0,0 +1,197 @@
/*!
* @license
* Copyright 2016 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, EventEmitter, Input, OnInit, Output, ViewEncapsulation, OnDestroy } from '@angular/core';
import { DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core';
import { MOMENT_DATE_FORMATS, MomentDateAdapter } from '@alfresco/adf-core';
import moment from 'moment-es6';
import { Moment } from 'moment';
import { Observable, Subscription } from 'rxjs';
import { FormBuilder, AbstractControl, Validators, FormGroup, FormControl } from '@angular/forms';
import { StartTaskCloudService } from '../services/start-task-cloud.service';
import { TaskDetailsCloudModel } from '../models/task-details-cloud.model';
import {
LogService,
UserPreferencesService,
IdentityUserService,
IdentityUserModel
} from '@alfresco/adf-core';
@Component({
selector: 'adf-cloud-start-task',
templateUrl: './start-task-cloud.component.html',
styleUrls: ['./start-task-cloud.component.scss'],
providers: [
{ provide: DateAdapter, useClass: MomentDateAdapter },
{ provide: MAT_DATE_FORMATS, useValue: MOMENT_DATE_FORMATS }],
encapsulation: ViewEncapsulation.None
})
export class StartTaskCloudComponent implements OnInit, OnDestroy {
static MAX_NAME_LENGTH = 255;
public DATE_FORMAT: string = 'DD/MM/YYYY';
/** (required) Name of the app. */
@Input()
appName: string;
/** Maximum length of the task name. */
@Input()
maxNameLength: number = StartTaskCloudComponent.MAX_NAME_LENGTH;
/** Name of the task. */
@Input()
name: string = '';
/** Emitted when the task is successfully created. */
@Output()
success: EventEmitter<any> = new EventEmitter<any>();
/** Emitted when the cancel button is clicked by the user. */
@Output()
cancel: EventEmitter<void> = new EventEmitter<void>();
/** Emitted when an error occurs. */
@Output()
error: EventEmitter<any> = new EventEmitter<any>();
users$: Observable<any[]>;
taskId: string;
dueDate: Date;
submitted = false;
assigneeName: string;
dateError: boolean;
taskForm: FormGroup;
currentUser: IdentityUserModel;
private localeSub: Subscription;
private createTaskSub: Subscription;
constructor(private taskService: StartTaskCloudService,
private dateAdapter: DateAdapter<Moment>,
private preferences: UserPreferencesService,
private formBuilder: FormBuilder,
private identityUserService: IdentityUserService,
private logService: LogService) {
}
ngOnInit() {
this.localeSub = this.preferences.locale$.subscribe((locale) => {
this.dateAdapter.setLocale(locale);
});
this.loadCurrentUser();
this.buildForm();
}
ngOnDestroy() {
if (this.localeSub) {
this.localeSub.unsubscribe();
}
if (this.createTaskSub) {
this.createTaskSub.unsubscribe();
}
}
buildForm() {
this.taskForm = this.formBuilder.group({
name: new FormControl(this.name, [Validators.required, Validators.maxLength(this.getMaxNameLength())]),
priority: new FormControl(),
description: new FormControl()
});
}
private getMaxNameLength(): number {
return this.maxNameLength > StartTaskCloudComponent.MAX_NAME_LENGTH ?
StartTaskCloudComponent.MAX_NAME_LENGTH : this.maxNameLength;
}
private async loadCurrentUser() {
this.currentUser = await this.identityUserService.getCurrentUserInfo().toPromise();
}
public saveTask() {
this.submitted = true;
const newTask = Object.assign(this.taskForm.value);
newTask.appName = this.getAppName();
newTask.dueDate = this.getDueDate();
newTask.assignee = this.getAssigneeName();
this.createNewTask(new TaskDetailsCloudModel(newTask));
}
private createNewTask(newTask: TaskDetailsCloudModel) {
this.createTaskSub = this.taskService.createNewTask(newTask)
.subscribe(
(res: any) => {
this.submitted = false;
this.success.emit(res);
},
(err) => {
this.submitted = false;
this.error.emit(err);
this.logService.error('An error occurred while creating new task');
});
}
public onCancel() {
this.cancel.emit();
}
private getDueDate(): Date {
return this.dueDate;
}
private getAppName(): string {
return this.appName ? this.appName : '';
}
private getAssigneeName(): string {
return this.assigneeName ? this.assigneeName : this.currentUser.username;
}
onDateChanged(newDateValue) {
this.dateError = false;
if (newDateValue) {
let momentDate = moment(newDateValue, this.DATE_FORMAT, true);
if (!momentDate.isValid()) {
this.dateError = true;
}
}
}
onAssigneeSelect(assignee: IdentityUserModel) {
this.assigneeName = assignee ? assignee.username : '';
}
get nameController(): AbstractControl {
return this.taskForm.get('name');
}
get priorityController(): AbstractControl {
return this.taskForm.get('priority');
}
}

View File

@@ -0,0 +1,20 @@
/*!
* @license
* Copyright 2016 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 { TaskDetailsCloudModel } from '../models/task-details-cloud.model';
export let taskDetailsMock = new TaskDetailsCloudModel({ assignee: 'fake-assigne', name: 'fake-name' });

View File

@@ -0,0 +1,30 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export const mockUsers = [
{ id: 'fake-id-1', username: 'first-name-1 last-name-1', firstName: 'first-name-1', lastName: 'last-name-1', email: 'abc@xyz.com' },
{ id: 'fake-id-2', username: 'first-name-2 last-name-2', firstName: 'first-name-2', lastName: 'last-name-2', email: 'abcd@xyz.com'},
{ id: 'fake-id-3', username: 'first-name-3 last-name-3', firstName: 'first-name-3', lastName: 'last-name-3', email: 'abcde@xyz.com' }
];
export const mockRoles = [
{ id: 'id-1', name: 'MOCK-ADMIN-ROLE'},
{ id: 'id-2', name: 'MOCK-USER-ROLE'},
{ id: 'id-3', name: 'MOCK_MODELER-ROLE' },
{ id: 'id-4', name: 'MOCK-ROLE-1' },
{ id: 'id-5', name: 'MOCK-ROLE-2'}
];

View File

@@ -0,0 +1,36 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export class StartTaskCloudRequestModel {
name: string;
description: string;
assignee: string;
priority: string;
dueDate: Date;
payloadType: string;
constructor(obj?: any) {
if (obj) {
this.name = obj.name || null;
this.description = obj.description || null;
this.assignee = obj.assignee || null;
this.priority = obj.priority || null;
this.dueDate = obj.dueDate || null;
this.payloadType = 'CreateTaskPayload';
}
}
}

View File

@@ -0,0 +1,79 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export class TaskDetailsCloudModel {
id: string;
name: string;
appName: string;
assignee: string;
appVersion: string;
createdDate: Date;
claimedDate: Date;
formKey: any;
category: any;
description: string;
dueDate: Date;
lastModified: Date;
lastModifiedTo: Date;
lastModifiedFrom: Date;
owner: any;
parentTaskId: number;
priority: number;
processDefinitionId: string;
processInstanceId: string;
serviceType: any;
status: string;
standAlone: boolean;
serviceName: string;
serviceFullName: string;
serviceVersion: string;
constructor(obj?: any) {
if (obj) {
this.id = obj.id || null;
this.name = obj.name || null;
this.appName = obj.appName || null;
this.assignee = obj.assignee || null;
this.appVersion = obj.appVersion || null;
this.createdDate = obj.createdDate || null;
this.claimedDate = obj.claimedDate || null;
this.formKey = obj.formKey || null;
this.description = obj.description || null;
this.dueDate = obj.dueDate || null;
this.lastModified = obj.lastModified || null;
this.lastModifiedTo = obj.lastModifiedTo || null;
this.lastModifiedFrom = obj.lastModifiedFrom || null;
this.owner = obj.owner || null;
this.parentTaskId = obj.parentTaskId || null;
this.priority = obj.priority || null;
this.processDefinitionId = obj.processDefinitionId || null;
this.processInstanceId = obj.processInstanceId || null;
this.serviceType = obj.serviceType || null;
this.status = obj.status || null;
this.standAlone = obj.standAlone || null;
this.serviceName = obj.serviceName || null;
this.serviceName = obj.serviceName || null;
this.serviceFullName = obj.serviceFullName || null;
this.serviceVersion = obj.serviceVersion || null;
}
}
}
export interface StartTaskCloudResponseModel {
entry: TaskDetailsCloudModel;
}

View File

@@ -0,0 +1,22 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export * from './models/task-details-cloud.model';
export * from './services/start-task-cloud.service';
export * from './components/start-task-cloud.component';
export * from './components/people-cloud/people-cloud.component';
export * from './start-task-cloud.module';

View File

@@ -0,0 +1,78 @@
/*!
* @license
* Copyright 2016 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 { TestBed } from '@angular/core/testing';
import { setupTestBed } from '@alfresco/adf-core';
import { StartTaskCloudService } from './start-task-cloud.service';
import { StartTaskCloudTestingModule } from '../testing/start-task-cloud.testing.module';
import { of, throwError } from 'rxjs';
import { taskDetailsMock } from '../mock/task-details.mock';
import { TaskDetailsCloudModel } from '../models/task-details-cloud.model';
import { HttpErrorResponse } from '@angular/common/http';
import {
AlfrescoApiService,
AppConfigService,
LogService,
StorageService
} from '@alfresco/adf-core';
describe('StartTaskCloudService', () => {
let service: StartTaskCloudService;
setupTestBed({
imports: [StartTaskCloudTestingModule],
providers: [StartTaskCloudService, AlfrescoApiService, AppConfigService, LogService, StorageService]
});
beforeEach(() => {
service = TestBed.get(StartTaskCloudService);
});
it('should able to create a new task ', (done) => {
spyOn(service, 'createNewTask').and.returnValue(of({id: 'fake-id', name: 'fake-name'}));
service.createNewTask(taskDetailsMock).subscribe(
(res: TaskDetailsCloudModel) => {
expect(res).toBeDefined();
expect(res.id).toEqual('fake-id');
expect(res.name).toEqual('fake-name');
done();
}
);
});
it('Should not able to create a task if error occurred', () => {
const errorResponse = new HttpErrorResponse({
error: 'Mock Error',
status: 404, statusText: 'Not Found'
});
spyOn(service, 'createNewTask').and.returnValue(throwError(errorResponse));
service.createNewTask(taskDetailsMock)
.subscribe(
() => {
fail('expected an error, not applications');
},
(error) => {
expect(error.status).toEqual(404);
expect(error.statusText).toEqual('Not Found');
expect(error.error).toEqual('Mock Error');
}
);
});
});

View File

@@ -0,0 +1,71 @@
/*!
* @license
* Copyright 2016 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';
import {
AlfrescoApiService,
AppConfigService,
LogService
} from '@alfresco/adf-core';
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';
@Injectable()
export class StartTaskCloudService {
constructor(
private apiService: AlfrescoApiService,
private appConfigService: AppConfigService,
private logService: LogService
) {}
createNewTask(taskDetails: TaskDetailsCloudModel): Observable<TaskDetailsCloudModel> {
let queryUrl = this.buildCreateTaskUrl(taskDetails.appName);
const bodyParam = JSON.stringify(this.buildRequestBody(taskDetails));
const httpMethod = 'POST', pathParams = {}, queryParams = {}, headerParams = {},
formParams = {}, authNames = [], contentTypes = ['application/json'], accepts = ['application/json'];
return from(
this.apiService
.getInstance()
.oauth2Auth.callCustomApi(
queryUrl, httpMethod, pathParams, queryParams,
headerParams, formParams, bodyParam, authNames,
contentTypes, accepts, Object, null, null)
).pipe(
map((response: StartTaskCloudResponseModel) => {
return new TaskDetailsCloudModel(response.entry);
}),
catchError((err) => this.handleError(err))
);
}
private buildCreateTaskUrl(appName: string): any {
return `${this.appConfigService.get('bpmHost')}/${appName}-rb/v1/tasks`;
}
private buildRequestBody(taskDetails: any) {
return new StartTaskCloudRequestModel(taskDetails);
}
private handleError(error: any) {
this.logService.error(error);
return throwError(error || 'Server error');
}
}

View File

@@ -0,0 +1,55 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FlexLayoutModule } from '@angular/flex-layout';
import { MaterialModule } from '../material.module';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TemplateModule, TranslateLoaderService, FormModule, PipeModule } from '@alfresco/adf-core';
import { StartTaskCloudComponent } from './components/start-task-cloud.component';
import { StartTaskCloudService } from './services/start-task-cloud.service';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { PeopleCloudComponent } from './components/people-cloud/people-cloud.component';
@NgModule({
imports: [
CommonModule,
PipeModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: TranslateLoaderService
}
}),
TemplateModule,
FlexLayoutModule,
MaterialModule,
FormsModule,
ReactiveFormsModule,
FormModule
],
declarations: [StartTaskCloudComponent, PeopleCloudComponent],
providers: [
StartTaskCloudService
],
exports: [
StartTaskCloudComponent,
PeopleCloudComponent
]
})
export class StartTaskCloudModule { }

View File

@@ -0,0 +1,49 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { NgModule } from '@angular/core';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { CommonModule } from '@angular/common';
import { FlexLayoutModule } from '@angular/flex-layout';
import { MaterialModule } from '../../material.module';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TemplateModule, TranslateLoaderService, FormModule, PipeModule } from '@alfresco/adf-core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { StartTaskCloudModule } from '../start-task-cloud.module';
@NgModule({
imports: [
CommonModule,
NoopAnimationsModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: TranslateLoaderService
}
}),
TemplateModule,
FlexLayoutModule,
MaterialModule,
FormsModule,
ReactiveFormsModule,
FormModule,
PipeModule,
StartTaskCloudModule
]
})
export class StartTaskCloudTestingModule { }

View File

@@ -2,10 +2,15 @@
@import './../app-list-cloud/components/app-list-cloud.component';
@import './../task-cloud/task-filters-cloud/task-filters-cloud.component.scss';
@import './../process-list-cloud/components/process-list-cloud.component.scss';
@import './../start-task-cloud/components/start-task-cloud.component';
@import './../start-task-cloud/components/people-cloud/people-cloud.component';
@mixin adf-process-services-cloud-theme($theme) {
@include adf-cloud-app-list-theme($theme);
@include adf-cloud-app-details-theme($theme);
@include adf-cloud-task-filters-theme($theme);
@include adf-process-filters-cloud-theme($theme);
@include adf-start-task-cloud-theme($theme);
@include adf-cloud-people-theme($theme);
}

View File

@@ -1,3 +1,20 @@
/*!
* @license
* Copyright 2016 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 { TaskCloudModule } from './task-cloud.module';
describe('TaskCloudModule', () => {

View File

@@ -1,3 +1,20 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { TaskFiltersCloudComponent } from './task-filters-cloud/task-filters-cloud.component';

View File

@@ -2,18 +2,19 @@
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the License);
* 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,
* 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 { ObjectDataColumn } from '@alfresco/adf-core';
export const fakeTaskCloudList = {

View File

@@ -1,3 +1,20 @@
/*!
* @license
* Copyright 2016 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 { TaskListCloudModule } from './task-list-cloud.module';
describe('TaskListCloudModule', () => {

View File

@@ -1,3 +1,20 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MaterialModule } from '../material.module';

View File

@@ -20,3 +20,4 @@ export * from './lib/app-list-cloud/public-api';
export * from './lib/task-list-cloud/public-api';
export * from './lib/task-cloud/public-api';
export * from './lib/process-list-cloud/public_api';
export * from './lib/start-task-cloud/public-api';

View File

@@ -1,3 +1,19 @@
/*!
* @license
* Copyright 2016 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.
*/
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
import 'core-js/es7/reflect';