mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-26 17:24:56 +00:00
parent
2e0bde5ef3
commit
e7c6638778
@ -0,0 +1,51 @@
|
||||
/*!
|
||||
* @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 { AppDefinitionRepresentationModel } from '../models/filter.model';
|
||||
|
||||
export var deployedApps = [new AppDefinitionRepresentationModel({
|
||||
id: '1',
|
||||
name: 'App1',
|
||||
icon: 'icon1',
|
||||
deploymentId: '1'
|
||||
}), new AppDefinitionRepresentationModel({
|
||||
id: '2',
|
||||
name: 'App2',
|
||||
icon: 'icon2',
|
||||
deploymentId: '2'
|
||||
}), new AppDefinitionRepresentationModel({
|
||||
id: '3',
|
||||
name: 'App3',
|
||||
icon: 'icon3',
|
||||
deploymentId: '3'
|
||||
})];
|
||||
export var nonDeployedApps = [new AppDefinitionRepresentationModel({
|
||||
id: '1',
|
||||
name: '1',
|
||||
icon: 'icon1'
|
||||
}), new AppDefinitionRepresentationModel({
|
||||
id: '1',
|
||||
name: '2',
|
||||
icon: 'icon2'
|
||||
}), new AppDefinitionRepresentationModel({
|
||||
id: '1',
|
||||
name: '3',
|
||||
icon: 'icon3'
|
||||
})];
|
||||
export var defaultApp = [new AppDefinitionRepresentationModel({
|
||||
defaultAppId: 'tasks'
|
||||
})];
|
@ -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.
|
||||
*/
|
||||
|
||||
export var mockTaskDetailsComponent = {
|
||||
noTaskDetailsTemplateComponent: null
|
||||
};
|
@ -0,0 +1,166 @@
|
||||
/*!
|
||||
* @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 { DebugElement } from '@angular/core';
|
||||
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { Observable } from 'rxjs/Rx';
|
||||
|
||||
import { AlfrescoTranslationService, CoreModule } from 'ng2-alfresco-core';
|
||||
|
||||
import { ActivitiApps } from './activiti-apps.component';
|
||||
import { ActivitiTaskListService } from './../services/activiti-tasklist.service';
|
||||
import { TranslationMock } from './../assets/translation.service.mock';
|
||||
import { defaultApp, deployedApps, nonDeployedApps } from './../assets/activiti-apps.mock';
|
||||
|
||||
describe('ActivitiApps', () => {
|
||||
|
||||
let componentHandler: any;
|
||||
let component: ActivitiApps;
|
||||
let fixture: ComponentFixture<ActivitiApps>;
|
||||
let debugElement: DebugElement;
|
||||
let service: ActivitiTaskListService;
|
||||
let getAppsSpy: jasmine.Spy;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
CoreModule
|
||||
],
|
||||
declarations: [
|
||||
ActivitiApps
|
||||
],
|
||||
providers: [
|
||||
{ provide: AlfrescoTranslationService, useClass: TranslationMock },
|
||||
ActivitiTaskListService
|
||||
]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
fixture = TestBed.createComponent(ActivitiApps);
|
||||
component = fixture.componentInstance;
|
||||
debugElement = fixture.debugElement;
|
||||
service = fixture.debugElement.injector.get(ActivitiTaskListService);
|
||||
|
||||
getAppsSpy = spyOn(service, 'getDeployedApplications').and.returnValue(Observable.of());
|
||||
|
||||
componentHandler = jasmine.createSpyObj('componentHandler', [
|
||||
'upgradeAllRegistered',
|
||||
'upgradeElement'
|
||||
]);
|
||||
window['componentHandler'] = componentHandler;
|
||||
});
|
||||
|
||||
it('should load apps on init', () => {
|
||||
fixture.detectChanges();
|
||||
expect(getAppsSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should emit an error when an error occurs loading apps', () => {
|
||||
let emitSpy = spyOn(component.error, 'emit');
|
||||
getAppsSpy.and.returnValue(Observable.throw({}));
|
||||
fixture.detectChanges();
|
||||
expect(emitSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('layout', () => {
|
||||
|
||||
it('should display a grid by default', () => {
|
||||
fixture.detectChanges();
|
||||
expect(component.isGrid()).toBe(true);
|
||||
expect(component.isList()).toBe(false);
|
||||
});
|
||||
|
||||
it('should display a grid when configured to', () => {
|
||||
component.layoutType = ActivitiApps.LAYOUT_GRID;
|
||||
fixture.detectChanges();
|
||||
expect(component.isGrid()).toBe(true);
|
||||
expect(component.isList()).toBe(false);
|
||||
});
|
||||
|
||||
it('should display a list when configured to', () => {
|
||||
component.layoutType = ActivitiApps.LAYOUT_LIST;
|
||||
fixture.detectChanges();
|
||||
expect(component.isGrid()).toBe(false);
|
||||
expect(component.isList()).toBe(true);
|
||||
});
|
||||
|
||||
it('should throw an exception on init if unknown type configured', () => {
|
||||
component.layoutType = 'unknown';
|
||||
expect(component.ngOnInit).toThrowError();
|
||||
});
|
||||
});
|
||||
|
||||
describe('display apps', () => {
|
||||
|
||||
it('should display all deployed apps', () => {
|
||||
getAppsSpy.and.returnValue(Observable.of(deployedApps));
|
||||
fixture.detectChanges();
|
||||
expect(debugElement.queryAll(By.css('h1')).length).toBe(3);
|
||||
});
|
||||
|
||||
it('should not display undeployed apps', () => {
|
||||
getAppsSpy.and.returnValue(Observable.of(nonDeployedApps));
|
||||
fixture.detectChanges();
|
||||
expect(debugElement.queryAll(By.css('h1')).length).toBe(0);
|
||||
});
|
||||
|
||||
it('should display default app', () => {
|
||||
getAppsSpy.and.returnValue(Observable.of(defaultApp));
|
||||
fixture.detectChanges();
|
||||
expect(debugElement.queryAll(By.css('h1')).length).toBe(1);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('select apps', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
getAppsSpy.and.returnValue(Observable.of(deployedApps));
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should initially have no app selected', () => {
|
||||
let selectedEls = debugElement.queryAll(By.css('.selectedIcon'));
|
||||
expect(selectedEls.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should emit a click event when app selected', () => {
|
||||
spyOn(component.appClick, 'emit');
|
||||
component.selectApp(deployedApps[1]);
|
||||
expect(component.appClick.emit).toHaveBeenCalledWith(deployedApps[1]);
|
||||
});
|
||||
|
||||
it('should have one app shown as selected after app selected', () => {
|
||||
component.selectApp(deployedApps[1]);
|
||||
fixture.detectChanges();
|
||||
let selectedEls = debugElement.queryAll(By.css('.selectedIcon'));
|
||||
expect(selectedEls.length).toBe(1);
|
||||
});
|
||||
|
||||
it('should have the correct app shown as selected after app selected', () => {
|
||||
component.selectApp(deployedApps[1]);
|
||||
fixture.detectChanges();
|
||||
let appEls = debugElement.queryAll(By.css('.mdl-grid > div'));
|
||||
expect(appEls[1].query(By.css('.selectedIcon'))).not.toBeNull();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import { Component, OnInit, Output, EventEmitter, Input } from '@angular/core';
|
||||
import { AlfrescoTranslationService, AlfrescoAuthenticationService } from 'ng2-alfresco-core';
|
||||
import { AlfrescoTranslationService } from 'ng2-alfresco-core';
|
||||
import { ActivitiTaskListService } from './../services/activiti-tasklist.service';
|
||||
import { AppDefinitionRepresentationModel } from '../models/filter.model';
|
||||
import { IconModel } from '../models/icon.model';
|
||||
@ -48,6 +48,9 @@ export class ActivitiApps implements OnInit {
|
||||
@Output()
|
||||
appClick: EventEmitter<AppDefinitionRepresentationModel> = new EventEmitter<AppDefinitionRepresentationModel>();
|
||||
|
||||
@Output()
|
||||
error: EventEmitter<any> = new EventEmitter<any>();
|
||||
|
||||
private appsObserver: Observer<AppDefinitionRepresentationModel>;
|
||||
apps$: Observable<AppDefinitionRepresentationModel>;
|
||||
|
||||
@ -59,11 +62,10 @@ export class ActivitiApps implements OnInit {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param auth
|
||||
* @param translate
|
||||
* @param translate Translate service
|
||||
* @param activitiTaskList Task service
|
||||
*/
|
||||
constructor(private auth: AlfrescoAuthenticationService,
|
||||
private translate: AlfrescoTranslationService,
|
||||
constructor(private translate: AlfrescoTranslationService,
|
||||
private activitiTaskList: ActivitiTaskListService) {
|
||||
|
||||
if (translate) {
|
||||
@ -85,8 +87,8 @@ export class ActivitiApps implements OnInit {
|
||||
this.load();
|
||||
}
|
||||
|
||||
public load(name?: string) {
|
||||
this.activitiTaskList.getDeployedApplications(name).subscribe(
|
||||
private load() {
|
||||
this.activitiTaskList.getDeployedApplications().subscribe(
|
||||
(res) => {
|
||||
res.forEach((app: AppDefinitionRepresentationModel) => {
|
||||
if (app.defaultAppId === ActivitiApps.DEFAULT_TASKS_APP) {
|
||||
@ -100,7 +102,7 @@ export class ActivitiApps implements OnInit {
|
||||
});
|
||||
},
|
||||
(err) => {
|
||||
console.log(err);
|
||||
this.error.emit(err);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
[attr.data-badge]="comments?.length">{{ 'TASK_DETAILS.LABELS.COMMENTS' |translate }}</span>
|
||||
<div *ngIf="!readOnly" id="addComment" (click)="showDialog()" class="icon material-icons">add</div>
|
||||
<div *ngIf="!readOnly" class="mdl-tooltip" for="addComment">
|
||||
Add a comment
|
||||
{{ 'TASK_DETAILS.COMMENTS.ADD' | translate }}
|
||||
</div>
|
||||
|
||||
<div class="menu-container" *ngIf="comments?.length > 0">
|
||||
@ -15,21 +15,21 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div *ngIf="comments?.length === 0">
|
||||
<div *ngIf="comments?.length === 0" data-automation-id="comments-none">
|
||||
{{ 'TASK_DETAILS.COMMENTS.NONE' | translate }}
|
||||
</div>
|
||||
|
||||
|
||||
<dialog class="mdl-dialog" #dialog>
|
||||
<h4 class="mdl-dialog__title">New comment</h4>
|
||||
<h4 class="mdl-dialog__title">{{ 'TASK_DETAILS.COMMENTS.DIALOG.TITLE' | translate }}</h4>
|
||||
<div class="mdl-dialog__content">
|
||||
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
|
||||
<textarea class="mdl-textfield__input" type="text" [(ngModel)]="message" rows="1" id="commentText"></textarea>
|
||||
<label class="mdl-textfield__label" for="commentText">Message</label>
|
||||
<label class="mdl-textfield__label" for="commentText">{{ 'TASK_DETAILS.COMMENTS.DIALOG.LABELS.MESSAGE' | translate }}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mdl-dialog__actions">
|
||||
<button type="button" (click)="add()" class="mdl-button">Add Comment</button>
|
||||
<button type="button" (click)="cancel()" class="mdl-button close">Cancel</button>
|
||||
<button type="button" (click)="add()" class="mdl-button">{{ 'TASK_DETAILS.COMMENTS.DIALOG.BUTTON.ADD' | translate }}</button>
|
||||
<button type="button" (click)="cancel()" class="mdl-button close">{{ 'TASK_DETAILS.COMMENTS.DIALOG.BUTTON.CANCEL' | translate }}</button>
|
||||
</div>
|
||||
</dialog>
|
||||
|
@ -0,0 +1,191 @@
|
||||
/*!
|
||||
* @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 { SimpleChange } from '@angular/core';
|
||||
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { Observable } from 'rxjs/Rx';
|
||||
|
||||
import { AlfrescoTranslationService, CoreModule } from 'ng2-alfresco-core';
|
||||
import { ActivitiFormModule } from 'ng2-activiti-form';
|
||||
|
||||
import { ActivitiComments } from './activiti-comments.component';
|
||||
import { ActivitiTaskListService } from './../services/activiti-tasklist.service';
|
||||
import { TranslationMock } from './../assets/translation.service.mock';
|
||||
|
||||
describe('ActivitiTaskDetails', () => {
|
||||
|
||||
let componentHandler: any;
|
||||
let service: ActivitiTaskListService;
|
||||
let component: ActivitiComments;
|
||||
let fixture: ComponentFixture<ActivitiComments>;
|
||||
let getCommentsSpy: jasmine.Spy;
|
||||
let addCommentSpy: jasmine.Spy;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
CoreModule,
|
||||
ActivitiFormModule
|
||||
],
|
||||
declarations: [
|
||||
ActivitiComments
|
||||
],
|
||||
providers: [
|
||||
{ provide: AlfrescoTranslationService, useClass: TranslationMock },
|
||||
ActivitiTaskListService
|
||||
]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
fixture = TestBed.createComponent(ActivitiComments);
|
||||
component = fixture.componentInstance;
|
||||
service = fixture.debugElement.injector.get(ActivitiTaskListService);
|
||||
|
||||
getCommentsSpy = spyOn(service, 'getTaskComments').and.returnValue(Observable.of([{
|
||||
message: 'Test1'
|
||||
}, {
|
||||
message: 'Test2'
|
||||
}, {
|
||||
message: 'Test3'
|
||||
}]));
|
||||
addCommentSpy = spyOn(service, 'addTaskComment').and.returnValue(Observable.of({id: 123, message: 'Test'}));
|
||||
|
||||
componentHandler = jasmine.createSpyObj('componentHandler', [
|
||||
'upgradeAllRegistered',
|
||||
'upgradeElement'
|
||||
]);
|
||||
window['componentHandler'] = componentHandler;
|
||||
});
|
||||
|
||||
it('should load comments when taskId specified', () => {
|
||||
component.taskId = '123';
|
||||
fixture.detectChanges();
|
||||
expect(getCommentsSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should emit an error when an error occurs loading comments', () => {
|
||||
let emitSpy = spyOn(component.error, 'emit');
|
||||
getCommentsSpy.and.returnValue(Observable.throw({}));
|
||||
component.taskId = '123';
|
||||
fixture.detectChanges();
|
||||
expect(emitSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not comments when no taskId is specified', () => {
|
||||
fixture.detectChanges();
|
||||
expect(getCommentsSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should display comments when the task has comments', async(() => {
|
||||
component.taskId = '123';
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.queryAll(By.css('ul.mdl-list li')).length).toBe(3);
|
||||
});
|
||||
}));
|
||||
|
||||
it('should not display comments when the task has no comments', async(() => {
|
||||
component.taskId = '123';
|
||||
getCommentsSpy.and.returnValue(Observable.of([]));
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.queryAll(By.css('ul.mdl-list li')).length).toBe(0);
|
||||
});
|
||||
}));
|
||||
|
||||
describe('change detection', () => {
|
||||
|
||||
let change = new SimpleChange('123', '456');
|
||||
let nullChange = new SimpleChange('123', null);
|
||||
|
||||
beforeEach(async(() => {
|
||||
component.taskId = '123';
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
getCommentsSpy.calls.reset();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should fetch new comments when taskId changed', () => {
|
||||
component.ngOnChanges({ 'taskId': change });
|
||||
expect(getCommentsSpy).toHaveBeenCalledWith('456');
|
||||
});
|
||||
|
||||
it('should NOT fetch new comments when empty changeset made', () => {
|
||||
component.ngOnChanges({});
|
||||
expect(getCommentsSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should NOT fetch new comments when taskId changed to null', () => {
|
||||
component.ngOnChanges({ 'taskId': nullChange });
|
||||
expect(getCommentsSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should set a placeholder message when taskId changed to null', () => {
|
||||
component.ngOnChanges({ 'taskId': nullChange });
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.query(By.css('[data-automation-id="comments-none"]'))).not.toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Add comment', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
component.taskId = '123';
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable();
|
||||
}));
|
||||
|
||||
it('should display a dialog to the user when the Add button clicked', () => {
|
||||
let dialogEl = fixture.debugElement.query(By.css('.mdl-dialog')).nativeElement;
|
||||
let showSpy: jasmine.Spy = spyOn(dialogEl, 'showModal');
|
||||
component.showDialog();
|
||||
expect(showSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call service to add a comment', () => {
|
||||
component.showDialog();
|
||||
component.message = 'Test comment';
|
||||
component.add();
|
||||
expect(addCommentSpy).toHaveBeenCalledWith('123', 'Test comment');
|
||||
});
|
||||
|
||||
it('should emit an error when an error occurs adding the comment', () => {
|
||||
let emitSpy = spyOn(component.error, 'emit');
|
||||
addCommentSpy.and.returnValue(Observable.throw({}));
|
||||
component.showDialog();
|
||||
component.message = 'Test comment';
|
||||
component.add();
|
||||
expect(emitSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should close add dialog when close button clicked', () => {
|
||||
let dialogEl = fixture.debugElement.query(By.css('.mdl-dialog')).nativeElement;
|
||||
let closeSpy: jasmine.Spy = spyOn(dialogEl, 'close');
|
||||
component.showDialog();
|
||||
component.cancel();
|
||||
expect(closeSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
@ -15,8 +15,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, Input, OnInit, ViewChild, OnChanges, SimpleChanges } from '@angular/core';
|
||||
import { AlfrescoTranslationService, AlfrescoAuthenticationService } from 'ng2-alfresco-core';
|
||||
import { Component, Input, Output, OnInit, ViewChild, OnChanges, SimpleChanges, EventEmitter } from '@angular/core';
|
||||
import { AlfrescoTranslationService } from 'ng2-alfresco-core';
|
||||
import { ActivitiTaskListService } from './../services/activiti-tasklist.service';
|
||||
import { Comment } from '../models/comment.model';
|
||||
import { Observer, Observable } from 'rxjs/Rx';
|
||||
@ -36,6 +36,9 @@ export class ActivitiComments implements OnInit, OnChanges {
|
||||
@Input()
|
||||
readOnly: boolean = false;
|
||||
|
||||
@Output()
|
||||
error: EventEmitter<any> = new EventEmitter<any>();
|
||||
|
||||
@ViewChild('dialog')
|
||||
dialog: any;
|
||||
|
||||
@ -48,11 +51,10 @@ export class ActivitiComments implements OnInit, OnChanges {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param auth
|
||||
* @param translate
|
||||
* @param translate Translation service
|
||||
* @param activitiTaskList Task service
|
||||
*/
|
||||
constructor(private auth: AlfrescoAuthenticationService,
|
||||
private translate: AlfrescoTranslationService,
|
||||
constructor(private translate: AlfrescoTranslationService,
|
||||
private activitiTaskList: ActivitiTaskListService) {
|
||||
|
||||
if (translate) {
|
||||
@ -60,25 +62,28 @@ export class ActivitiComments implements OnInit, OnChanges {
|
||||
}
|
||||
|
||||
this.comment$ = new Observable<Comment>(observer => this.commentObserver = observer).share();
|
||||
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.comment$.subscribe((comment: Comment) => {
|
||||
this.comments.push(comment);
|
||||
});
|
||||
this.getTaskComments(this.taskId);
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
let taskId = changes['taskId'];
|
||||
if (taskId && taskId.currentValue) {
|
||||
this.getTaskComments(taskId.currentValue);
|
||||
return;
|
||||
if (taskId) {
|
||||
if (taskId.currentValue) {
|
||||
this.getTaskComments(taskId.currentValue);
|
||||
} else {
|
||||
this.resetComments();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public getTaskComments(taskId: string) {
|
||||
this.comments = [];
|
||||
private getTaskComments(taskId: string) {
|
||||
this.resetComments();
|
||||
if (taskId) {
|
||||
this.activitiTaskList.getTaskComments(taskId).subscribe(
|
||||
(res: Comment[]) => {
|
||||
@ -87,21 +92,23 @@ export class ActivitiComments implements OnInit, OnChanges {
|
||||
});
|
||||
},
|
||||
(err) => {
|
||||
console.log(err);
|
||||
this.error.emit(err);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
this.comments = [];
|
||||
this.resetComments();
|
||||
}
|
||||
}
|
||||
|
||||
private resetComments() {
|
||||
this.comments = [];
|
||||
}
|
||||
|
||||
public showDialog() {
|
||||
if (this.dialog) {
|
||||
if (!this.dialog.nativeElement.showModal) {
|
||||
dialogPolyfill.registerDialog(this.dialog.nativeElement);
|
||||
}
|
||||
this.dialog.nativeElement.showModal();
|
||||
if (!this.dialog.nativeElement.showModal) {
|
||||
dialogPolyfill.registerDialog(this.dialog.nativeElement);
|
||||
}
|
||||
this.dialog.nativeElement.showModal();
|
||||
}
|
||||
|
||||
public add() {
|
||||
@ -111,7 +118,7 @@ export class ActivitiComments implements OnInit, OnChanges {
|
||||
this.message = '';
|
||||
},
|
||||
(err) => {
|
||||
console.log(err);
|
||||
this.error.emit(err);
|
||||
}
|
||||
);
|
||||
this.cancel();
|
||||
|
@ -1,16 +1,19 @@
|
||||
<div *ngIf="taskDetails">
|
||||
<div class="mdl-grid">
|
||||
<div class="mdl-cell mdl-cell--4-col">
|
||||
<div class="mdl-cell mdl-cell--4-col" data-automation-id="header-assignee">
|
||||
<span class="activiti-task-header__label">{{ 'TASK_DETAILS.LABELS.ASSIGNEE' | translate }}: </span>
|
||||
<span class="activiti-task-header__value">{{taskDetails.assignee.lastName }}</span>
|
||||
<span class="activiti-task-header__value" *ngIf="hasAssignee()">{{ taskDetails.assignee.firstName }} {{ taskDetails.assignee.lastName }}</span>
|
||||
<span class="activiti-task-header__value" *ngIf="!hasAssignee()">{{ 'TASK_DETAILS.ASSIGNEE.NONE' | translate }}</span>
|
||||
</div>
|
||||
<div class="mdl-cell mdl-cell--4-col">
|
||||
<div class="mdl-cell mdl-cell--4-col" data-automation-id="header-due-date">
|
||||
<span class="activiti-task-header__label">{{ 'TASK_DETAILS.LABELS.DUE' | translate }}: </span>
|
||||
<span class="activiti-task-header__value">{{taskDetails?.dueDate ? taskDetails.dueDate : ('TASK_DETAILS.DUE.NONE' |translate) }}</span>
|
||||
<span class="activiti-task-header__value" *ngIf="taskDetails?.dueDate">{{ taskDetails.dueDate }}</span>
|
||||
<span class="activiti-task-header__value" *ngIf="!taskDetails?.dueDate">{{ 'TASK_DETAILS.DUE.NONE' |translate }}</span>
|
||||
</div>
|
||||
<div *ngIf="formName" class="mdl-cell mdl-cell--4-col">
|
||||
<div *ngIf="formName" class="mdl-cell mdl-cell--4-col" data-automation-id="header-form-name">
|
||||
<span class="activiti-task-header__label">{{ 'TASK_DETAILS.LABELS.FORM' | translate }}: </span>
|
||||
<span class="activiti-task-header__value">{{formName}}</span>
|
||||
<span class="activiti-task-header__value" *ngIf="formName">{{ formName }}</span>
|
||||
<span class="activiti-task-header__value" *ngIf="!formName">{{ 'TASK_DETAILS.FORM.NONE' | translate }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -0,0 +1,108 @@
|
||||
/*!
|
||||
* @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 { AlfrescoTranslationService, CoreModule } from 'ng2-alfresco-core';
|
||||
|
||||
import { ActivitiTaskHeader } from './activiti-task-header.component';
|
||||
import { TranslationMock } from './../assets/translation.service.mock';
|
||||
import { taskDetailsMock } from './../assets/task-details.mock';
|
||||
import { TaskDetailsModel } from '../models/task-details.model';
|
||||
|
||||
describe('ActivitiTaskHeader', () => {
|
||||
|
||||
let componentHandler: any;
|
||||
let component: ActivitiTaskHeader;
|
||||
let fixture: ComponentFixture<ActivitiTaskHeader>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
CoreModule
|
||||
],
|
||||
declarations: [
|
||||
ActivitiTaskHeader
|
||||
],
|
||||
providers: [
|
||||
{ provide: AlfrescoTranslationService, useClass: TranslationMock }
|
||||
]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
fixture = TestBed.createComponent(ActivitiTaskHeader);
|
||||
component = fixture.componentInstance;
|
||||
|
||||
component.taskDetails = new TaskDetailsModel(taskDetailsMock);
|
||||
|
||||
componentHandler = jasmine.createSpyObj('componentHandler', [
|
||||
'upgradeAllRegistered',
|
||||
'upgradeElement'
|
||||
]);
|
||||
window['componentHandler'] = componentHandler;
|
||||
});
|
||||
|
||||
it('should render empty component if no form details provided', () => {
|
||||
component.taskDetails = undefined;
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.children.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should display assignee', () => {
|
||||
fixture.detectChanges();
|
||||
let formNameEl = fixture.debugElement.query(By.css('[data-automation-id="header-assignee"] .activiti-task-header__value'));
|
||||
expect(formNameEl.nativeElement.innerText).toBe('Wilbur Adams');
|
||||
});
|
||||
|
||||
it('should display placeholder if no assignee', () => {
|
||||
component.taskDetails.assignee = null;
|
||||
fixture.detectChanges();
|
||||
let valueEl = fixture.debugElement.query(By.css('[data-automation-id="header-assignee"] .activiti-task-header__value'));
|
||||
expect(valueEl.nativeElement.innerText).toBe('TASK_DETAILS.ASSIGNEE.NONE');
|
||||
});
|
||||
|
||||
it('should display due date', () => {
|
||||
component.taskDetails.dueDate = '2016-11-03T15:25:42.749+0000';
|
||||
fixture.detectChanges();
|
||||
let valueEl = fixture.debugElement.query(By.css('[data-automation-id="header-due-date"] .activiti-task-header__value'));
|
||||
expect(valueEl.nativeElement.innerText).toBe('2016-11-03T15:25:42.749+0000');
|
||||
});
|
||||
|
||||
it('should display placeholder if no due date', () => {
|
||||
component.taskDetails.dueDate = null;
|
||||
fixture.detectChanges();
|
||||
let valueEl = fixture.debugElement.query(By.css('[data-automation-id="header-due-date"] .activiti-task-header__value'));
|
||||
expect(valueEl.nativeElement.innerText).toBe('TASK_DETAILS.DUE.NONE');
|
||||
});
|
||||
|
||||
it('should display form name', () => {
|
||||
component.formName = 'test form';
|
||||
fixture.detectChanges();
|
||||
let valueEl = fixture.debugElement.query(By.css('[data-automation-id="header-form-name"] .activiti-task-header__value'));
|
||||
expect(valueEl.nativeElement.innerText).toBe('test form');
|
||||
});
|
||||
|
||||
it('should not display form name if no form name provided', () => {
|
||||
fixture.detectChanges();
|
||||
let valueEl = fixture.debugElement.query(By.css('[data-automation-id="header-form-name"] .activiti-task-header__value'));
|
||||
expect(valueEl).toBeNull();
|
||||
});
|
||||
|
||||
});
|
@ -28,7 +28,7 @@ import { TaskDetailsModel } from '../models/task-details.model';
|
||||
export class ActivitiTaskHeader {
|
||||
|
||||
@Input()
|
||||
formName: string = 'No form';
|
||||
formName: string = null;
|
||||
|
||||
@Input()
|
||||
taskDetails: TaskDetailsModel;
|
||||
@ -38,4 +38,8 @@ export class ActivitiTaskHeader {
|
||||
translate.addTranslationFolder('node_modules/ng2-activiti-tasklist/src');
|
||||
}
|
||||
}
|
||||
|
||||
public hasAssignee(): boolean {
|
||||
return (this.taskDetails && this.taskDetails.assignee) ? true : false;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,38 @@
|
||||
/*!
|
||||
* @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 { NoTaskDetailsTemplateComponent } from './no-task-detail-template.component';
|
||||
import { ActivitiTaskDetails } from './activiti-task-details.component';
|
||||
|
||||
describe('NoTaskDetailsTemplateComponent', () => {
|
||||
|
||||
let component: NoTaskDetailsTemplateComponent;
|
||||
let detailsComponent: ActivitiTaskDetails;
|
||||
|
||||
beforeEach(() => {
|
||||
detailsComponent = new ActivitiTaskDetails(null, null, null, null);
|
||||
component = new NoTaskDetailsTemplateComponent(detailsComponent);
|
||||
});
|
||||
|
||||
it('should set "no task details" template on task details component', () => {
|
||||
let testTemplate = 'blah blah';
|
||||
component.template = testTemplate;
|
||||
component.ngAfterContentInit();
|
||||
expect(detailsComponent.noTaskDetailsTemplateComponent).toBe(testTemplate);
|
||||
});
|
||||
|
||||
});
|
@ -25,11 +25,25 @@
|
||||
"DUE": {
|
||||
"NONE": "No due date."
|
||||
},
|
||||
"ASSIGNEE": {
|
||||
"NONE": "No assignee."
|
||||
},
|
||||
"PEOPLE": {
|
||||
"NONE": "No people involved."
|
||||
},
|
||||
"COMMENTS": {
|
||||
"NONE": "No comments."
|
||||
"NONE": "No comments.",
|
||||
"ADD": "Add a comment",
|
||||
"DIALOG": {
|
||||
"TITLE": "New comment",
|
||||
"LABELS": {
|
||||
"MESSAGE": "Message"
|
||||
},
|
||||
"BUTTON": {
|
||||
"ADD": "Add Comment",
|
||||
"CANCEL": "Cancel"
|
||||
}
|
||||
}
|
||||
},
|
||||
"CHECKLIST": {
|
||||
"NONE": "No checklist."
|
||||
|
Loading…
x
Reference in New Issue
Block a user