mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-09-09 18:03:21 +00:00
[ADF-794] Add people assignment component (#1977)
* Add people component * exported people service * added people-list component to show the involved user list * changed people-search component layout * changed people-list usage in people component * changed people-list data table from custom template to data adapter * changes people-search component related to people-list * changes in activiti-people related to people-list and people-search component * changed data adapter to direct data column setting to data-table * removed ngChanges and added User and UserEvent models * added User and UserEvent model in emitter and other emitter handler * added user event model * changed activiti-people component with latest UX changes * addedand changed translate keys to the components * added hasUser method to check the condition in html * fixed tslint issue and test case issue in activiti-people component * added test case for actviti-people-list component * test case added for activiti-people-search component * changed activiti-people test cases according to latest UX changes * added description for activiti-people component * changed test case to fix component.upgradeElement issue * changes requested by Vito Albano #1 * splitted getDisplayUser into getDisplayUser and getInitialUsername
This commit is contained in:
@@ -425,6 +425,31 @@ The purpose of the component is populate the local variable called `properties`
|
||||
"description": "string"
|
||||
}
|
||||
```
|
||||
## Task People Component
|
||||
|
||||
This component displays involved users to a specified task
|
||||
|
||||
```html
|
||||
<activiti-people
|
||||
[people]="YOUR_INVOLVED_PEOPLE_LIST"
|
||||
[taskId]="YOUR_TASK_ID"
|
||||
[readOnly]="YOUR_READ_ONLY_FLAG">
|
||||
</activiti-people>
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Properties
|
||||
|
||||
| Name | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| people | User[] | The array of User object to display |
|
||||
| taskId | string | The numeric ID of the task |
|
||||
| readOnly | boolean | The boolean flag |
|
||||
|
||||
#### Events
|
||||
|
||||
No Events
|
||||
|
||||
## Build from sources
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
@@ -36,11 +36,13 @@ import {
|
||||
ActivitiStartTaskButton,
|
||||
ActivitiPeopleSearch,
|
||||
TaskAttachmentListComponent,
|
||||
ActivitiCreateTaskAttachmentComponent
|
||||
ActivitiCreateTaskAttachmentComponent,
|
||||
ActivitiPeopleList
|
||||
} from './src/components/index';
|
||||
|
||||
export * from './src/components/index';
|
||||
export * from './src/services/activiti-tasklist.service';
|
||||
export * from './src/services/activiti-people.service';
|
||||
export * from './src/models/index';
|
||||
|
||||
export const ACTIVITI_TASKLIST_DIRECTIVES: any[] = [
|
||||
@@ -56,7 +58,8 @@ export const ACTIVITI_TASKLIST_DIRECTIVES: any[] = [
|
||||
ActivitiStartTaskButton,
|
||||
ActivitiPeopleSearch,
|
||||
TaskAttachmentListComponent,
|
||||
ActivitiCreateTaskAttachmentComponent
|
||||
ActivitiCreateTaskAttachmentComponent,
|
||||
ActivitiPeopleList
|
||||
];
|
||||
|
||||
export const ACTIVITI_TASKLIST_PROVIDERS: any[] = [
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<alfresco-datatable
|
||||
[rows]="users"
|
||||
[actions]="hasActions()"
|
||||
(rowClick)="selectUser($event)"
|
||||
(showRowActionsMenu)="onShowRowActionsMenu($event)"
|
||||
(executeRowAction)="onExecuteRowAction($event)">
|
||||
</alfresco-datatable>
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
/*!
|
||||
* @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 { Observable } from 'rxjs/Observable';
|
||||
import { CoreModule, AlfrescoTranslationService } from 'ng2-alfresco-core';
|
||||
import { ActivitiPeopleList } from './activiti-people-list.component';
|
||||
import { User, UserEventModel } from '../models/index';
|
||||
import { DataTableModule, ObjectDataRow, DataRowEvent, DataRowActionEvent } from 'ng2-alfresco-datatable';
|
||||
|
||||
declare let jasmine: any;
|
||||
|
||||
const fakeUser: User = new User({
|
||||
id: '1',
|
||||
firstName: 'fake-name',
|
||||
lastName: 'fake-last',
|
||||
email: 'fake@mail.com'
|
||||
});
|
||||
|
||||
describe('ActivitiPeopleList', () => {
|
||||
|
||||
let activitiPeopleListComponent: ActivitiPeopleList;
|
||||
let fixture: ComponentFixture<ActivitiPeopleList>;
|
||||
let element: HTMLElement;
|
||||
let componentHandler;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
CoreModule.forRoot(),
|
||||
DataTableModule
|
||||
],
|
||||
declarations: [
|
||||
ActivitiPeopleList
|
||||
]
|
||||
}).compileComponents().then(() => {
|
||||
|
||||
let translateService = TestBed.get(AlfrescoTranslationService);
|
||||
spyOn(translateService, 'addTranslationFolder').and.stub();
|
||||
spyOn(translateService.translate, 'get').and.callFake((key) => { return Observable.of(key); });
|
||||
|
||||
fixture = TestBed.createComponent(ActivitiPeopleList);
|
||||
activitiPeopleListComponent = fixture.componentInstance;
|
||||
element = fixture.nativeElement;
|
||||
componentHandler = jasmine.createSpyObj('componentHandler', [
|
||||
'upgradeAllRegistered'
|
||||
]);
|
||||
|
||||
window['componentHandler'] = componentHandler;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should emit row click event', (done) => {
|
||||
let row = new ObjectDataRow(fakeUser);
|
||||
let rowEvent = new DataRowEvent(row, null);
|
||||
|
||||
activitiPeopleListComponent.clickRow.subscribe(selectedUser => {
|
||||
expect(selectedUser.id).toEqual('1');
|
||||
expect(selectedUser.email).toEqual('fake@mail.com');
|
||||
expect(activitiPeopleListComponent.user.id).toEqual('1');
|
||||
expect(activitiPeopleListComponent.user.email).toEqual('fake@mail.com');
|
||||
done();
|
||||
});
|
||||
|
||||
activitiPeopleListComponent.selectUser(rowEvent);
|
||||
});
|
||||
|
||||
it('should emit row action event', (done) => {
|
||||
let row = new ObjectDataRow(fakeUser);
|
||||
let removeObj = {
|
||||
name: 'remove',
|
||||
title: 'Remove'
|
||||
};
|
||||
let rowActionEvent = new DataRowActionEvent(row, removeObj);
|
||||
|
||||
activitiPeopleListComponent.clickAction.subscribe((selectedAction: UserEventModel) => {
|
||||
expect(selectedAction.type).toEqual('remove');
|
||||
expect(selectedAction.value.id).toEqual('1');
|
||||
expect(selectedAction.value.email).toEqual('fake@mail.com');
|
||||
done();
|
||||
});
|
||||
|
||||
activitiPeopleListComponent.onExecuteRowAction(rowActionEvent);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,99 @@
|
||||
/*!
|
||||
* @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, Input, Output, EventEmitter, ViewChild, ContentChild } from '@angular/core';
|
||||
import { User, UserEventModel } from '../models/index';
|
||||
import { DataColumnListComponent } from 'ng2-alfresco-core';
|
||||
import { DataTableComponent } from 'ng2-alfresco-datatable';
|
||||
|
||||
declare let componentHandler: any;
|
||||
|
||||
@Component({
|
||||
selector: 'activiti-people-list',
|
||||
templateUrl: './activiti-people-list.component.html',
|
||||
styleUrls: ['./activiti-people-list.component.css']
|
||||
})
|
||||
|
||||
export class ActivitiPeopleList {
|
||||
|
||||
@ContentChild(DataColumnListComponent) columnList: DataColumnListComponent;
|
||||
|
||||
@ViewChild(DataTableComponent)
|
||||
peopleDataTable: DataTableComponent;
|
||||
|
||||
@Input()
|
||||
users: User[];
|
||||
|
||||
@Input()
|
||||
actions: boolean = false;
|
||||
|
||||
@Output()
|
||||
clickRow: EventEmitter<User> = new EventEmitter<User>();
|
||||
|
||||
@Output()
|
||||
clickAction: EventEmitter<UserEventModel> = new EventEmitter<UserEventModel>();
|
||||
|
||||
user: User;
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngAfterContentInit() {
|
||||
this.peopleDataTable.columnList = this.columnList;
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.setupMaterialComponents(componentHandler);
|
||||
}
|
||||
|
||||
setupMaterialComponents(handler?: any): boolean {
|
||||
// workaround for MDL issues with dynamic components
|
||||
let isUpgraded: boolean = false;
|
||||
if (handler) {
|
||||
handler.upgradeAllRegistered();
|
||||
isUpgraded = true;
|
||||
}
|
||||
return isUpgraded;
|
||||
}
|
||||
|
||||
selectUser(event: any) {
|
||||
this.user = event.value.obj;
|
||||
this.clickRow.emit(this.user);
|
||||
}
|
||||
|
||||
hasActions(): boolean {
|
||||
return this.actions;
|
||||
}
|
||||
|
||||
onShowRowActionsMenu(event: any) {
|
||||
|
||||
let removeAction = {
|
||||
title: 'Remove',
|
||||
name: 'remove'
|
||||
};
|
||||
|
||||
event.value.actions = [
|
||||
removeAction
|
||||
];
|
||||
}
|
||||
|
||||
onExecuteRowAction(event: any) {
|
||||
let args = event.value;
|
||||
let action = args.action;
|
||||
this.clickAction.emit(new UserEventModel({type: action.name, value: args.row.obj}));
|
||||
}
|
||||
}
|
||||
+57
-1
@@ -33,4 +33,60 @@
|
||||
|
||||
.mdl-chip-search-people__text{
|
||||
padding-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.search-text-header{
|
||||
font-weight: bold;
|
||||
opacity: 0.54;
|
||||
}
|
||||
|
||||
.search-list-container{
|
||||
max-height: 152px;
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
activiti-people-list >>> alfresco-datatable >>> thead {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.search-list-action-container {
|
||||
border-top: 1px solid #eee;
|
||||
text-align: right;
|
||||
padding: 5px 0px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.search-list-action-container>button{
|
||||
opacity: 0.54;
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.search-list-action-container>button:hover{
|
||||
color: rgb(255, 152, 0);
|
||||
}
|
||||
|
||||
activiti-people-list >>> alfresco-datatable >>> .people-full-name {
|
||||
font-family: 'Muli';
|
||||
}
|
||||
|
||||
activiti-people-list >>> alfresco-datatable >>> .people-pic {
|
||||
background: #ffc800;
|
||||
padding: 10px 6px;
|
||||
border-radius: 100px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
font-weight: bolder;
|
||||
font-size: 16px;
|
||||
font-family: Muli;
|
||||
text-transform: uppercase;
|
||||
min-width: 30px;
|
||||
}
|
||||
|
||||
activiti-people-list >>> alfresco-datatable >>> td.mdl-data-table__cell--non-numeric.non-selectable.data-cell{
|
||||
padding: 4px 12px;
|
||||
}
|
||||
|
||||
.mdl-textfield {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
+32
-14
@@ -1,15 +1,33 @@
|
||||
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
|
||||
<input class="mdl-textfield__input" type="text" id="userSearchText" [value]="" [formControl]="searchUser"/>
|
||||
<label class="mdl-textfield__label" for="userSearchText">Search user</label>
|
||||
</div>
|
||||
<ul class='mdl-list'>
|
||||
<li class="mdl-list__item fix-element-user-list" *ngFor="let user of userList">
|
||||
<button (click)="onRowClick(user)" id="user-{{user.id}}" class="mdl-chip mdl-chip--contact mdl-chip-search-people">
|
||||
<img class="mdl-chip__contact" [src]="iconImageUrl" />
|
||||
<span class="mdl-chip__text mdl-chip-search-people__text">{{getDisplayUser(user)}}</span>
|
||||
</button>
|
||||
</li>
|
||||
<div *ngIf="userList?.length === 0" id="no-user-found">
|
||||
{{'PEOPLE.SEARCH.NO_USERS' | translate }}
|
||||
<div class="search-text-header">{{ 'TASK_DETAILS.LABELS.ADD_PEOPLE' | translate }}</div>
|
||||
<div class="search-text-container">
|
||||
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
|
||||
<input class="mdl-textfield__input" type="text" id="userSearchText" [value]="" [formControl]="searchUser"/>
|
||||
<label class="mdl-textfield__label" for="userSearchText">Search user</label>
|
||||
</div>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="search-list-container" id="search-people-list" *ngIf="hasUsers()">
|
||||
<activiti-people-list
|
||||
[users]="users"
|
||||
(clickRow)="onRowClick($event)">
|
||||
<data-columns>
|
||||
<data-column key="firstName">
|
||||
<ng-template let-entry="$implicit">
|
||||
<div class="people-pic">{{getInitialUserName(entry.row.obj.firstName, entry.row.obj.lastName)}}</div>
|
||||
</ng-template>
|
||||
</data-column>
|
||||
<data-column key="email" class="full-width">
|
||||
<ng-template let-entry="$implicit">
|
||||
<div class="people-full-name">{{ getDisplayUser(entry.row.obj.firstName, entry.row.obj.lastName, ' ') }}</div>
|
||||
</ng-template>
|
||||
</data-column>
|
||||
</data-columns>
|
||||
</activiti-people-list>
|
||||
</div>
|
||||
<div class="search-list-action-container">
|
||||
<button type="button" id="close-people-search" (click)="closeSearchList()" class="mdl-button close">
|
||||
{{'PEOPLE.DIALOG_CLOSE' | translate }}
|
||||
</button>
|
||||
<button type="button" id="add-people" (click)="addInvolvedUser()" class="mdl-button close">
|
||||
{{'PEOPLE.ADD_USER' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
+23
-18
@@ -19,6 +19,8 @@ import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { CoreModule, AlfrescoTranslationService } from 'ng2-alfresco-core';
|
||||
import { ActivitiPeopleSearch } from './activiti-people-search.component';
|
||||
import { ActivitiPeopleList } from './activiti-people-list.component';
|
||||
import { DataTableModule } from 'ng2-alfresco-datatable';
|
||||
import { User } from '../models/user.model';
|
||||
|
||||
declare let jasmine: any;
|
||||
@@ -49,10 +51,12 @@ describe('ActivitiPeopleSearch', () => {
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
CoreModule.forRoot()
|
||||
CoreModule.forRoot(),
|
||||
DataTableModule
|
||||
],
|
||||
declarations: [
|
||||
ActivitiPeopleSearch
|
||||
ActivitiPeopleSearch,
|
||||
ActivitiPeopleList
|
||||
]
|
||||
}).compileComponents().then(() => {
|
||||
|
||||
@@ -78,28 +82,25 @@ describe('ActivitiPeopleSearch', () => {
|
||||
expect(element.querySelector('#userSearchText')).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should show no user found to involve message', () => {
|
||||
it('should hide people-list container', () => {
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable()
|
||||
.then(() => {
|
||||
expect(element.querySelector('#no-user-found')).not.toBeNull();
|
||||
expect(element.querySelector('#no-user-found').textContent).toContain('PEOPLE.SEARCH.NO_USERS');
|
||||
expect(element.querySelector('#search-people-list')).toBeNull();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('should show user which can be involved ', (done) => {
|
||||
activitiPeopleSearchComponent.onSearch.subscribe(() => {
|
||||
activitiPeopleSearchComponent.searchPeople.subscribe(() => {
|
||||
activitiPeopleSearchComponent.results = Observable.of(userArray);
|
||||
activitiPeopleSearchComponent.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable()
|
||||
.then(() => {
|
||||
expect(element.querySelector('#user-1')).not.toBeNull();
|
||||
expect(element.querySelector('#user-1').textContent)
|
||||
.toContain('fake-name - fake-last');
|
||||
expect(element.querySelector('#user-2')).not.toBeNull();
|
||||
expect(element.querySelector('#user-2').textContent)
|
||||
.toContain('fake-involve-name - fake-involve-last');
|
||||
let gatewayElement: any = element.querySelector('#search-people-list tbody');
|
||||
expect(gatewayElement).not.toBeNull();
|
||||
expect(gatewayElement.children.length).toBe(2);
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -110,7 +111,7 @@ describe('ActivitiPeopleSearch', () => {
|
||||
});
|
||||
|
||||
it('should send an event when an user is clicked', (done) => {
|
||||
activitiPeopleSearchComponent.onRowClicked.subscribe((user) => {
|
||||
activitiPeopleSearchComponent.success.subscribe((user) => {
|
||||
expect(user).toBeDefined();
|
||||
expect(user.firstName).toBe('fake-name');
|
||||
done();
|
||||
@@ -120,8 +121,9 @@ describe('ActivitiPeopleSearch', () => {
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable()
|
||||
.then(() => {
|
||||
let userToSelect = <HTMLElement> element.querySelector('#user-1');
|
||||
userToSelect.click();
|
||||
activitiPeopleSearchComponent.onRowClick(fakeUser);
|
||||
let addUserButton = <HTMLElement> element.querySelector('#add-people');
|
||||
addUserButton.click();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -129,13 +131,16 @@ describe('ActivitiPeopleSearch', () => {
|
||||
activitiPeopleSearchComponent.results = Observable.of(userArray);
|
||||
activitiPeopleSearchComponent.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
let userToSelect = <HTMLElement> element.querySelector('#user-1');
|
||||
userToSelect.click();
|
||||
activitiPeopleSearchComponent.onRowClick(fakeUser);
|
||||
let addUserButton = <HTMLElement> element.querySelector('#add-people');
|
||||
addUserButton.click();
|
||||
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable()
|
||||
.then(() => {
|
||||
expect(element.querySelector('#user-1')).toBeNull();
|
||||
let gatewayElement: any = element.querySelector('#search-people-list tbody');
|
||||
expect(gatewayElement).not.toBeNull();
|
||||
expect(gatewayElement.children.length).toBe(1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
+40
-17
@@ -32,21 +32,23 @@ declare var require: any;
|
||||
|
||||
export class ActivitiPeopleSearch implements OnInit, AfterViewInit {
|
||||
|
||||
@Input()
|
||||
iconImageUrl: string = require('../assets/images/user.jpg');
|
||||
|
||||
@Input()
|
||||
results: Observable<User[]>;
|
||||
|
||||
@Output()
|
||||
onSearch: EventEmitter<any> = new EventEmitter();
|
||||
searchPeople: EventEmitter<any> = new EventEmitter();
|
||||
|
||||
@Output()
|
||||
onRowClicked: EventEmitter<any> = new EventEmitter();
|
||||
success: EventEmitter<User> = new EventEmitter<User>();
|
||||
|
||||
@Output()
|
||||
closeSearch = new EventEmitter();
|
||||
|
||||
searchUser: FormControl = new FormControl();
|
||||
|
||||
userList: User[] = [];
|
||||
users: User[] = [];
|
||||
|
||||
selectedUser: User;
|
||||
|
||||
constructor(private translateService: AlfrescoTranslationService) {
|
||||
if (translateService) {
|
||||
@@ -58,16 +60,16 @@ export class ActivitiPeopleSearch implements OnInit, AfterViewInit {
|
||||
.debounceTime(200)
|
||||
.subscribe((event: string) => {
|
||||
if (event && event.trim()) {
|
||||
this.onSearch.emit(event);
|
||||
this.searchPeople.emit(event);
|
||||
} else {
|
||||
this.userList = [];
|
||||
this.users = [];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.results.subscribe((list) => {
|
||||
this.userList = list;
|
||||
this.users = list;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -85,17 +87,38 @@ export class ActivitiPeopleSearch implements OnInit, AfterViewInit {
|
||||
return isUpgraded;
|
||||
}
|
||||
|
||||
onRowClick(userClicked: User) {
|
||||
this.onRowClicked.emit(userClicked);
|
||||
this.userList = this.userList.filter((user) => {
|
||||
onRowClick(user: User) {
|
||||
this.selectedUser = user;
|
||||
}
|
||||
|
||||
closeSearchList() {
|
||||
this.closeSearch.emit();
|
||||
}
|
||||
|
||||
addInvolvedUser() {
|
||||
if (this.selectedUser === undefined) {
|
||||
return;
|
||||
}
|
||||
this.success.emit(this.selectedUser);
|
||||
this.users = this.users.filter((user) => {
|
||||
this.searchUser.reset();
|
||||
return user.id !== userClicked.id;
|
||||
return user.id !== this.selectedUser.id;
|
||||
});
|
||||
}
|
||||
|
||||
getDisplayUser(user: User): string {
|
||||
let firstName = user.firstName && user.firstName !== 'null' ? user.firstName : 'N/A';
|
||||
let lastName = user.lastName && user.lastName !== 'null' ? user.lastName : 'N/A';
|
||||
return firstName + ' - ' + lastName;
|
||||
getDisplayUser(firstName: string, lastName: string, delimiter: string = '-'): string {
|
||||
firstName = (firstName !== null ? firstName : '');
|
||||
lastName = (lastName !== null ? lastName : '');
|
||||
return firstName + delimiter + lastName;
|
||||
}
|
||||
|
||||
getInitialUserName(firstName: string, lastName: string) {
|
||||
firstName = (firstName !== null && firstName !== '' ? firstName[0] : '');
|
||||
lastName = (lastName !== null && lastName !== '' ? lastName[0] : '');
|
||||
return this.getDisplayUser(firstName, lastName, '');
|
||||
}
|
||||
|
||||
hasUsers() {
|
||||
return (this.users && this.users.length > 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,74 @@
|
||||
:host {
|
||||
.assignment-header{
|
||||
width: 100%;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding: 6px 20px;
|
||||
}
|
||||
|
||||
.assigment-count{
|
||||
float: left;
|
||||
padding: 10px 0px;
|
||||
font-weight: bolder;
|
||||
font-family: Muli;
|
||||
opacity: 0.54;
|
||||
}
|
||||
|
||||
.add-people{
|
||||
float: right;
|
||||
padding: 8px;
|
||||
height: 26px;
|
||||
opacity: 0.54;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.add-people:hover{
|
||||
color: #ff9100;
|
||||
}
|
||||
|
||||
.assignment-top-container{
|
||||
border-top: 2px solid #eee;
|
||||
margin: 8px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.assignment-container{
|
||||
padding: 10px 20px;
|
||||
border-bottom: 1px solid #eee;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.activiti-label {
|
||||
.assignment-list-container {
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
activiti-people-list >>> alfresco-datatable >>> thead {
|
||||
display: none;
|
||||
}
|
||||
|
||||
activiti-people-list >>> alfresco-datatable >>> .people-full-name {
|
||||
font-family: 'Muli';
|
||||
}
|
||||
|
||||
activiti-people-list >>> alfresco-datatable >>> .people-email {
|
||||
font-family: 'Muli';
|
||||
opacity: 0.54;
|
||||
}
|
||||
|
||||
activiti-people-list >>> alfresco-datatable >>> .people-edit-label {
|
||||
font-family: 'Muli';
|
||||
}
|
||||
|
||||
activiti-people-list >>> alfresco-datatable >>> .people-pic {
|
||||
background: #ffc800;
|
||||
padding: 12px 10px;
|
||||
border-radius: 100px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
font-weight: bolder;
|
||||
font-size: 18px;
|
||||
font-family: Muli;
|
||||
text-transform: uppercase
|
||||
}
|
||||
|
||||
.material-icons.people__icon:hover {
|
||||
color: rgb(255, 152, 0);
|
||||
}
|
||||
|
||||
.add-people-dialog__content {
|
||||
padding: 20px 24px 2px;
|
||||
}
|
||||
|
||||
.mdl-tooltip {
|
||||
will-change: unset;
|
||||
}
|
||||
|
||||
.material-icons {
|
||||
cursor: pointer;
|
||||
activiti-people-list >>> alfresco-datatable >>> td.mdl-data-table__cell--non-numeric.non-selectable.data-cell{
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
+39
-33
@@ -1,36 +1,42 @@
|
||||
<span class="activiti-label mdl-badge" id="people-title"
|
||||
[attr.data-badge]="people?.length">{{ 'TASK_DETAILS.LABELS.PEOPLE' | translate }}</span>
|
||||
<div *ngIf="!readOnly" id="addPeople" (click)="showDialog()" class="icon material-icons people__icon">add</div>
|
||||
<div *ngIf="!readOnly" class="mdl-tooltip" data-mdl-for="addPeople">
|
||||
Add a person
|
||||
</div>
|
||||
<div class="menu-container" *ngIf="people?.length > 0">
|
||||
<ul class='mdl-list'>
|
||||
<li class="mdl-list__item" *ngFor="let user of people">
|
||||
<span class="mdl-chip mdl-chip--contact mdl-chip--deletable">
|
||||
<img class="mdl-chip__contact" [src]="iconImageUrl" />
|
||||
<span id="user-{{user.id}}" class="mdl-chip__text">{{getDisplayUser(user)}}</span>
|
||||
<a *ngIf="!readOnly" class="mdl-chip__action"><i id="remove-{{user.id}}" (click)="removeInvolvedUser(user)" class="material-icons people__icon">cancel</i></a>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div *ngIf="people?.length === 0" id="no-people-label">
|
||||
{{ 'TASK_DETAILS.PEOPLE.NONE' | translate }}
|
||||
</div>
|
||||
|
||||
<dialog class="mdl-dialog" id="add-people-dialog" #dialog>
|
||||
<h4 class="mdl-dialog__title" id="add-people-dialog-title">Involve User</h4>
|
||||
<div class="mdl-dialog__content add-people-dialog__content">
|
||||
<activiti-people-search (onSearch)="searchUser($event)"
|
||||
(onRowClicked)="involveUser($event)"
|
||||
[results]="peopleSearch$"
|
||||
[iconImageUrl]="iconImageUrl" #activitipeoplesearch>
|
||||
<div class="mdl-grid mdl-shadow--2dp assignment-top-container">
|
||||
<div class="assignment-header">
|
||||
<div *ngIf="hasPeople()" class="assigment-count" id="people-title">
|
||||
{{ 'TASK_DETAILS.LABELS.PEOPLE' | translate }} {{ ' (' + people.length + ')' }}
|
||||
</div>
|
||||
<div *ngIf="!hasPeople()" class="assigment-count" id="no-people-label">
|
||||
{{ 'TASK_DETAILS.PEOPLE.NONE' | translate }}
|
||||
</div>
|
||||
<div *ngIf="isEditMode()" class="add-people" (click)="onAddAssignement()">
|
||||
<i class="material-icons">person_add</i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="assignment-container" *ngIf="showAssignment">
|
||||
<activiti-people-search
|
||||
(searchPeople)="searchUser($event)"
|
||||
(success)="involveUser($event)"
|
||||
(closeSearch)="onCloseSearch()"
|
||||
[results]="peopleSearch$">
|
||||
</activiti-people-search>
|
||||
</div>
|
||||
<div class="mdl-dialog__actions">
|
||||
<button type="button" id="close-people-dialog" (click)="closeDialog()" class="mdl-button close">
|
||||
{{'PEOPLE.DIALOG_CLOSE' | translate }}
|
||||
</button>
|
||||
<div class="assignment-list-container" id="assignment-people-list" *ngIf="hasPeople()">
|
||||
<activiti-people-list
|
||||
[users]="people"
|
||||
[actions]="isEditMode()"
|
||||
(clickAction)="onClickAction($event)">
|
||||
<data-columns>
|
||||
<data-column key="firstName">
|
||||
<ng-template let-entry="$implicit">
|
||||
<div class="people-pic">{{getInitialUserName(entry.row.obj.firstName, entry.row.obj.lastName)}}</div>
|
||||
</ng-template>
|
||||
</data-column>
|
||||
<data-column key="email" class="full-width">
|
||||
<ng-template let-entry="$implicit">
|
||||
<div class="people-full-name">{{ getDisplayUser(entry.row.obj.firstName, entry.row.obj.lastName, ' ') }}</div>
|
||||
<div class="people-email">{{ entry.row.obj.email }}</div>
|
||||
<div class="people-edit-label">can edit</div>
|
||||
</ng-template>
|
||||
</data-column>
|
||||
</data-columns>
|
||||
</activiti-people-list>
|
||||
</div>
|
||||
</dialog>
|
||||
</div>
|
||||
|
||||
+51
-71
@@ -16,12 +16,14 @@
|
||||
*/
|
||||
|
||||
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
||||
import { Observable } from 'rxjs/Rx';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { CoreModule, AlfrescoTranslationService, LogService } from 'ng2-alfresco-core';
|
||||
import { ActivitiPeopleService } from '../services/activiti-people.service';
|
||||
import { ActivitiPeople } from './activiti-people.component';
|
||||
import { ActivitiPeopleSearch } from './activiti-people-search.component';
|
||||
import { ActivitiPeopleList } from './activiti-people-list.component';
|
||||
import { ActivitiPeople } from './activiti-people.component';
|
||||
import { DataTableModule } from 'ng2-alfresco-datatable';
|
||||
import { User } from '../models/user.model';
|
||||
import { ActivitiPeopleService } from '../services/activiti-people.service';
|
||||
|
||||
declare let jasmine: any;
|
||||
|
||||
@@ -32,7 +34,7 @@ const fakeUser: User = new User({
|
||||
email: 'fake@mail.com'
|
||||
});
|
||||
|
||||
const fakeUserToInvolve: User = new User({
|
||||
const fakeSecondUser: User = new User({
|
||||
id: 'fake-involve-id',
|
||||
firstName: 'fake-involve-name',
|
||||
lastName: 'fake-involve-last',
|
||||
@@ -45,21 +47,25 @@ describe('ActivitiPeople', () => {
|
||||
let fixture: ComponentFixture<ActivitiPeople>;
|
||||
let element: HTMLElement;
|
||||
let componentHandler;
|
||||
let userArray = [fakeUser, fakeSecondUser];
|
||||
let logService: LogService;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
CoreModule.forRoot()
|
||||
CoreModule.forRoot(),
|
||||
DataTableModule
|
||||
],
|
||||
declarations: [
|
||||
ActivitiPeople,
|
||||
ActivitiPeopleSearch
|
||||
ActivitiPeopleSearch,
|
||||
ActivitiPeopleList,
|
||||
ActivitiPeople
|
||||
],
|
||||
providers: [
|
||||
ActivitiPeopleService
|
||||
]
|
||||
}).compileComponents().then(() => {
|
||||
|
||||
logService = TestBed.get(LogService);
|
||||
|
||||
let translateService = TestBed.get(AlfrescoTranslationService);
|
||||
@@ -74,16 +80,24 @@ describe('ActivitiPeople', () => {
|
||||
]);
|
||||
|
||||
window['componentHandler'] = componentHandler;
|
||||
|
||||
activitiPeopleComponent.people = [];
|
||||
activitiPeopleComponent.readOnly = true;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should show people component title', () => {
|
||||
expect(element.querySelector('#people-title')).toBeDefined();
|
||||
expect(element.querySelector('#people-title')).not.toBeNull();
|
||||
});
|
||||
it('should show people component title', async(() => {
|
||||
activitiPeopleComponent.people = [...userArray];
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable()
|
||||
.then(() => {
|
||||
expect(element.querySelector('#people-title')).toBeDefined();
|
||||
expect(element.querySelector('#people-title')).not.toBeNull();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should show no people involved message', () => {
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable()
|
||||
.then(() => {
|
||||
expect(element.querySelector('#no-people-label')).not.toBeNull();
|
||||
@@ -91,51 +105,11 @@ describe('ActivitiPeople', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('when interact with people dialog', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
activitiPeopleComponent.taskId = 'fake-task-id';
|
||||
activitiPeopleComponent.people = [];
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should show dialog when clicked on add', () => {
|
||||
expect(element.querySelector('#addPeople')).not.toBeNull();
|
||||
activitiPeopleComponent.showDialog();
|
||||
|
||||
expect(element.querySelector('#add-people-dialog')).not.toBeNull();
|
||||
expect(element.querySelector('#add-people-dialog-title')).not.toBeNull();
|
||||
expect(element.querySelector('#add-people-dialog-title').textContent).toContain('Involve User');
|
||||
});
|
||||
|
||||
it('should close dialog when clicked on cancel', () => {
|
||||
activitiPeopleComponent.showDialog();
|
||||
expect(element.querySelector('#addPeople')).not.toBeNull();
|
||||
activitiPeopleComponent.closeDialog();
|
||||
let dialogWindow = <HTMLElement> element.querySelector('#add-people-dialog');
|
||||
expect(dialogWindow.getAttribute('open')).toBeNull();
|
||||
});
|
||||
|
||||
it('should reset search input when the dialog is closed', () => {
|
||||
let userInputSearch: HTMLInputElement;
|
||||
activitiPeopleComponent.showDialog();
|
||||
expect(element.querySelector('#addPeople')).not.toBeNull();
|
||||
userInputSearch = <HTMLInputElement> element.querySelector('#userSearchText');
|
||||
userInputSearch.value = 'fake-search-value';
|
||||
activitiPeopleComponent.closeDialog();
|
||||
activitiPeopleComponent.showDialog();
|
||||
userInputSearch = <HTMLInputElement> element.querySelector('#userSearchText');
|
||||
|
||||
expect(userInputSearch).not.toBeNull();
|
||||
expect(userInputSearch.value).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when there are involved people', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
activitiPeopleComponent.taskId = 'fake-task-id';
|
||||
activitiPeopleComponent.people.push(fakeUser);
|
||||
activitiPeopleComponent.people.push(...userArray);
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
@@ -147,11 +121,14 @@ describe('ActivitiPeople', () => {
|
||||
jasmine.Ajax.uninstall();
|
||||
});
|
||||
|
||||
it('should show people involved', () => {
|
||||
expect(element.querySelector('#user-fake-id')).not.toBeNull();
|
||||
expect(element.querySelector('#user-fake-id').textContent).toContain('fake-name');
|
||||
expect(element.querySelector('#user-fake-id').textContent).toContain('fake-last');
|
||||
});
|
||||
it('should show people involved', async(() => {
|
||||
fixture.whenStable()
|
||||
.then(() => {
|
||||
let gatewayElement: any = element.querySelector('#assignment-people-list tbody');
|
||||
expect(gatewayElement).not.toBeNull();
|
||||
expect(gatewayElement.children.length).toBe(2);
|
||||
});
|
||||
}));
|
||||
|
||||
it('should remove pepole involved', async(() => {
|
||||
activitiPeopleComponent.removeInvolvedUser(fakeUser);
|
||||
@@ -161,21 +138,23 @@ describe('ActivitiPeople', () => {
|
||||
fixture.whenStable()
|
||||
.then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(element.querySelector('#user-fake-id')).toBeNull();
|
||||
let gatewayElement: any = element.querySelector('#assignment-people-list tbody');
|
||||
expect(gatewayElement).not.toBeNull();
|
||||
expect(gatewayElement.children.length).toBe(1);
|
||||
});
|
||||
}));
|
||||
|
||||
it('should involve pepole', async(() => {
|
||||
activitiPeopleComponent.involveUser(fakeUserToInvolve);
|
||||
activitiPeopleComponent.involveUser(fakeUser);
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
status: 200
|
||||
});
|
||||
fixture.whenStable()
|
||||
.then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(element.querySelector('#user-fake-involve-id')).not.toBeNull();
|
||||
expect(element.querySelector('#user-fake-involve-id').textContent)
|
||||
.toBe('fake-involve-name fake-involve-last');
|
||||
let gatewayElement: any = element.querySelector('#assignment-people-list tbody');
|
||||
expect(gatewayElement).not.toBeNull();
|
||||
expect(gatewayElement.children.length).toBe(3);
|
||||
});
|
||||
}));
|
||||
|
||||
@@ -226,6 +205,8 @@ describe('ActivitiPeople', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
jasmine.Ajax.install();
|
||||
activitiPeopleComponent.people.push(...userArray);
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -243,8 +224,6 @@ describe('ActivitiPeople', () => {
|
||||
}));
|
||||
|
||||
it('should not remove user if remove involved user fail', async(() => {
|
||||
activitiPeopleComponent.people.push(fakeUser);
|
||||
fixture.detectChanges();
|
||||
activitiPeopleComponent.removeInvolvedUser(fakeUser);
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
status: 403
|
||||
@@ -252,22 +231,23 @@ describe('ActivitiPeople', () => {
|
||||
fixture.whenStable()
|
||||
.then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(element.querySelector('#user-fake-id')).not.toBeNull();
|
||||
expect(element.querySelector('#user-fake-id').textContent)
|
||||
.toBe('fake-name fake-last');
|
||||
let gatewayElement: any = element.querySelector('#assignment-people-list tbody');
|
||||
expect(gatewayElement).not.toBeNull();
|
||||
expect(gatewayElement.children.length).toBe(2);
|
||||
});
|
||||
}));
|
||||
|
||||
it('should not involve user if involve user fail', async(() => {
|
||||
activitiPeopleComponent.involveUser(fakeUserToInvolve);
|
||||
activitiPeopleComponent.involveUser(fakeUser);
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
status: 403
|
||||
});
|
||||
fixture.whenStable()
|
||||
.then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(element.querySelector('#user-fake-id')).toBeNull();
|
||||
expect(element.querySelector('#no-people-label').textContent).toContain('TASK_DETAILS.PEOPLE.NONE');
|
||||
let gatewayElement: any = element.querySelector('#assignment-people-list tbody');
|
||||
expect(gatewayElement).not.toBeNull();
|
||||
expect(gatewayElement.children.length).toBe(2);
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, Input, ViewChild } from '@angular/core';
|
||||
import { Component, Input, AfterViewInit } from '@angular/core';
|
||||
import { Observer, Observable } from 'rxjs/Rx';
|
||||
import { AlfrescoTranslationService, LogService } from 'ng2-alfresco-core';
|
||||
import { User } from '../models/user.model';
|
||||
import { User, UserEventModel } from '../models/index';
|
||||
import { ActivitiPeopleService } from '../services/activiti-people.service';
|
||||
|
||||
declare let dialogPolyfill: any;
|
||||
declare let componentHandler: any;
|
||||
declare var require: any;
|
||||
|
||||
@Component({
|
||||
@@ -29,7 +29,7 @@ declare var require: any;
|
||||
templateUrl: './activiti-people.component.html',
|
||||
styleUrls: ['./activiti-people.component.css']
|
||||
})
|
||||
export class ActivitiPeople {
|
||||
export class ActivitiPeople implements AfterViewInit {
|
||||
|
||||
@Input()
|
||||
iconImageUrl: string = require('../assets/images/user.jpg');
|
||||
@@ -43,11 +43,7 @@ export class ActivitiPeople {
|
||||
@Input()
|
||||
readOnly: boolean = false;
|
||||
|
||||
@ViewChild('dialog')
|
||||
dialog: any;
|
||||
|
||||
@ViewChild('activitipeoplesearch')
|
||||
activitipeoplesearch: any;
|
||||
showAssignment: boolean = false;
|
||||
|
||||
private peopleSearchObserver: Observer<User[]>;
|
||||
peopleSearch$: Observable<User[]>;
|
||||
@@ -66,21 +62,18 @@ export class ActivitiPeople {
|
||||
this.peopleSearch$ = new Observable<User[]>(observer => this.peopleSearchObserver = observer).share();
|
||||
}
|
||||
|
||||
public showDialog() {
|
||||
if (!this.dialog.nativeElement.showModal) {
|
||||
dialogPolyfill.registerDialog(this.dialog.nativeElement);
|
||||
}
|
||||
if (this.dialog) {
|
||||
this.dialog.nativeElement.showModal();
|
||||
}
|
||||
ngAfterViewInit() {
|
||||
this.setupMaterialComponents(componentHandler);
|
||||
}
|
||||
|
||||
public closeDialog() {
|
||||
if (this.dialog) {
|
||||
this.dialog.nativeElement.close();
|
||||
this.peopleSearchObserver.next([]);
|
||||
this.activitipeoplesearch.searchUser.reset();
|
||||
setupMaterialComponents(handler?: any): boolean {
|
||||
// workaround for MDL issues with dynamic components
|
||||
let isUpgraded: boolean = false;
|
||||
if (handler) {
|
||||
handler.upgradeAllRegistered();
|
||||
isUpgraded = true;
|
||||
}
|
||||
return isUpgraded;
|
||||
}
|
||||
|
||||
searchUser(searchedWord: string) {
|
||||
@@ -91,9 +84,10 @@ export class ActivitiPeople {
|
||||
}
|
||||
|
||||
involveUser(user: User) {
|
||||
this.showAssignment = false;
|
||||
this.peopleService.involveUserWithTask(this.taskId, user.id.toString())
|
||||
.subscribe(() => {
|
||||
this.people.push(user);
|
||||
this.people = [...this.people, user];
|
||||
}, error => this.logService.error('Impossible to involve user with task'));
|
||||
}
|
||||
|
||||
@@ -106,10 +100,38 @@ export class ActivitiPeople {
|
||||
}, error => this.logService.error('Impossible to remove involved user from task'));
|
||||
}
|
||||
|
||||
getDisplayUser(user: User): string {
|
||||
let firstName = user.firstName && user.firstName !== 'null' ? user.firstName : 'N/A';
|
||||
let lastName = user.lastName && user.lastName !== 'null' ? user.lastName : 'N/A';
|
||||
return firstName + ' ' + lastName;
|
||||
getDisplayUser(firstName: string, lastName: string, delimiter: string = '-'): string {
|
||||
firstName = (firstName !== null ? firstName : '');
|
||||
lastName = (lastName !== null ? lastName : '');
|
||||
return firstName + delimiter + lastName;
|
||||
}
|
||||
|
||||
getInitialUserName(firstName: string, lastName: string) {
|
||||
firstName = (firstName !== null && firstName !== '' ? firstName[0] : '');
|
||||
lastName = (lastName !== null && lastName !== '' ? lastName[0] : '');
|
||||
return this.getDisplayUser(firstName, lastName, '');
|
||||
}
|
||||
|
||||
onAddAssignement() {
|
||||
this.showAssignment = true;
|
||||
}
|
||||
|
||||
onClickAction(event: UserEventModel) {
|
||||
if (event.type === 'remove') {
|
||||
this.removeInvolvedUser(event.value);
|
||||
}
|
||||
}
|
||||
|
||||
hasPeople() {
|
||||
return this.people && this.people.length > 0;
|
||||
}
|
||||
|
||||
isEditMode() {
|
||||
return !this.readOnly;
|
||||
}
|
||||
|
||||
onCloseSearch() {
|
||||
this.showAssignment = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,3 +28,4 @@ export * from './activiti-task-details.component';
|
||||
export * from './activiti-start-task.component';
|
||||
export * from './activiti-people-search.component';
|
||||
export * from './adf-create-task-attachment.component';
|
||||
export * from './activiti-people-list.component';
|
||||
|
||||
@@ -12,9 +12,10 @@
|
||||
"ASSIGNEE": "Assignee",
|
||||
"DUE": "Due",
|
||||
"FORM": "Form",
|
||||
"PEOPLE": "People",
|
||||
"PEOPLE": "People this task is shared with",
|
||||
"COMMENTS": "Comments",
|
||||
"CHECKLIST": "Checklist"
|
||||
"CHECKLIST": "Checklist",
|
||||
"ADD_PEOPLE": "Add people & groups"
|
||||
},
|
||||
"BUTTON": {
|
||||
"COMPLETE": "Complete",
|
||||
@@ -84,6 +85,7 @@
|
||||
},
|
||||
"PEOPLE": {
|
||||
"DIALOG_CLOSE": "CLOSE",
|
||||
"ADD_USER": "ADD",
|
||||
"SEARCH": {
|
||||
"NO_USERS": "No user found to involve"
|
||||
}
|
||||
|
||||
@@ -21,3 +21,4 @@ export * from './icon.model';
|
||||
export * from './user.model';
|
||||
export * from './task-details.model';
|
||||
export * from './task-details.event';
|
||||
export * from './user-event.model';
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*!
|
||||
* @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 object represent the User Event.
|
||||
*
|
||||
*
|
||||
* @returns {UserEventModel} .
|
||||
*/
|
||||
export class UserEventModel {
|
||||
type: string = '';
|
||||
value: any = {};
|
||||
|
||||
constructor(obj?: any) {
|
||||
this.type = obj && obj.type;
|
||||
this.value = obj && obj.value || {};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user