mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ADF-2588] make comment component compatible with content (#3128)
This commit is contained in:
committed by
Eugenio Romano
parent
f985dd11d5
commit
653a510a5c
32
lib/core/comments/comment-list.component.html
Normal file
32
lib/core/comments/comment-list.component.html
Normal file
@@ -0,0 +1,32 @@
|
||||
<mat-list class="adf-comment-list">
|
||||
<mat-list-item *ngFor="let comment of comments"
|
||||
(click)="selectComment(comment)"
|
||||
class="adf-comment-list-item"
|
||||
[class.is-selected]="comment.isSelected"
|
||||
id="adf-comment-{{comment?.id}}">
|
||||
<div id="comment-user-icon" class="adf-comment-img-container">
|
||||
<div
|
||||
*ngIf="!isPictureDefined(comment.createdBy)"
|
||||
class="adf-comment-user-icon">
|
||||
{{getUserShortName(comment.createdBy)}}
|
||||
</div>
|
||||
<div>
|
||||
<img *ngIf="isPictureDefined(comment.createdBy)"
|
||||
class="adf-people-img"
|
||||
[src]="getUserImage(comment.createdBy)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="adf-comment-contents">
|
||||
<div matLine id="comment-user" class="adf-comment-user-name">
|
||||
{{comment.createdBy?.firstName}} {{comment.createdBy?.lastName}}
|
||||
</div>
|
||||
<div matLine id="comment-message" class="adf-comment-message">
|
||||
{{comment.message}}
|
||||
</div>
|
||||
<div matLine id="comment-time" class="adf-comment-message-time">
|
||||
{{transformDate(comment.created)}}
|
||||
</div>
|
||||
</div>
|
||||
</mat-list-item>
|
||||
</mat-list>
|
94
lib/core/comments/comment-list.component.scss
Normal file
94
lib/core/comments/comment-list.component.scss
Normal file
@@ -0,0 +1,94 @@
|
||||
@mixin adf-task-list-comment-list-theme($theme) {
|
||||
$primary: map-get($theme, primary);
|
||||
$primaryColor: mat-color($primary, 100);
|
||||
$rippleColor: mat-color($primary, 300);
|
||||
|
||||
.is-selected {
|
||||
background: mat-color($primary, 100);
|
||||
}
|
||||
|
||||
.adf {
|
||||
|
||||
&-comment-img-container {
|
||||
float: left;
|
||||
width: 40px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-self: flex-start;
|
||||
padding-top: 18px;
|
||||
}
|
||||
|
||||
&-comment-list-item {
|
||||
white-space: initial;
|
||||
display: table-row-group;
|
||||
padding-top: 12px;
|
||||
overflow: hidden;
|
||||
height: 100% !important;
|
||||
transition: background 0.8s;
|
||||
background-position: center;
|
||||
|
||||
&:hover {
|
||||
background: $primaryColor radial-gradient(circle, transparent 1%, $primaryColor 1%) center/15000%;
|
||||
}
|
||||
&:active {
|
||||
background-color: $rippleColor;
|
||||
background-size: 100%;
|
||||
transition: background 0s;
|
||||
}
|
||||
}
|
||||
|
||||
&-comment-user-icon {
|
||||
padding: 10px 5px;
|
||||
width: 30px;
|
||||
background-color: mat-color($primary);
|
||||
border-radius: 50%;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
height: 20px;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
&-comment-user-name {
|
||||
float: left;
|
||||
width: calc(100% - 10%);
|
||||
padding: 2px 10px;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
&-comment-message {
|
||||
float: left;
|
||||
width: calc(100% - 10px);
|
||||
padding: 2px 10px;
|
||||
font-style: italic;
|
||||
white-space: initial !important;
|
||||
font-size: 14px;
|
||||
letter-spacing: -0.2px;
|
||||
line-height: 1.43;
|
||||
opacity: 0.54;
|
||||
}
|
||||
|
||||
&-comment-message-time {
|
||||
float: left;
|
||||
width: calc(100% - 10%);
|
||||
padding: 2px 10px;
|
||||
font-size: 12px !important;
|
||||
opacity: 0.54;
|
||||
}
|
||||
|
||||
&-comment-contents {
|
||||
width: calc(100% - 10px);
|
||||
padding-top: 12px;
|
||||
padding-bottom: 12px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
&-people-img {
|
||||
border-radius: 90%;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
306
lib/core/comments/comment-list.component.spec.ts
Normal file
306
lib/core/comments/comment-list.component.spec.ts
Normal file
@@ -0,0 +1,306 @@
|
||||
/*!
|
||||
* @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 { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { DatePipe } from '@angular/common';
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { CommentModel, UserProcessModel } from '../models';
|
||||
import { CommentListComponent } from './comment-list.component';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { EcmUserService } from '../userinfo/services/ecm-user.service';
|
||||
import { PeopleProcessService } from '../services/people-process.service';
|
||||
|
||||
const testUser: UserProcessModel = new UserProcessModel({
|
||||
id: '1',
|
||||
firstName: 'Test',
|
||||
lastName: 'User',
|
||||
email: 'tu@domain.com'
|
||||
});
|
||||
const testDate = new Date();
|
||||
const processCommentOne: CommentModel = new CommentModel({
|
||||
id: 1,
|
||||
message: 'Test Comment',
|
||||
created: testDate.toDateString(),
|
||||
createdBy: testUser
|
||||
});
|
||||
|
||||
const processCommentTwo: CommentModel = new CommentModel({
|
||||
id: 2,
|
||||
message: '2nd Test Comment',
|
||||
created: new Date().toDateString(),
|
||||
createdBy: testUser
|
||||
});
|
||||
|
||||
const contentCommentUserPictureDefined: CommentModel = new CommentModel({
|
||||
id: 2,
|
||||
message: '2nd Test Comment',
|
||||
created: new Date().toDateString(),
|
||||
createdBy: {
|
||||
enabled: true,
|
||||
firstName: 'some',
|
||||
lastName: 'one',
|
||||
email: 'some-one@somegroup.com',
|
||||
emailNotificationsEnabled: true,
|
||||
company: {},
|
||||
id: 'fake-email@dom.com',
|
||||
avatarId: '001-001-001'
|
||||
}
|
||||
});
|
||||
|
||||
const processCommentUserPictureDefined: CommentModel = new CommentModel({
|
||||
id: 2,
|
||||
message: '2nd Test Comment',
|
||||
created: new Date().toDateString(),
|
||||
createdBy: {
|
||||
id: '1',
|
||||
firstName: 'Test',
|
||||
lastName: 'User',
|
||||
email: 'tu@domain.com',
|
||||
pictureId: '001-001-001'
|
||||
}
|
||||
});
|
||||
|
||||
const contentCommentUserNoPictureDefined: CommentModel = new CommentModel({
|
||||
id: 2,
|
||||
message: '2nd Test Comment',
|
||||
created: new Date().toDateString(),
|
||||
createdBy: {
|
||||
enabled: true,
|
||||
firstName: 'some',
|
||||
lastName: 'one',
|
||||
email: 'some-one@somegroup.com',
|
||||
emailNotificationsEnabled: true,
|
||||
company: {},
|
||||
id: 'fake-email@dom.com'
|
||||
}
|
||||
});
|
||||
|
||||
const processCommentUserNoPictureDefined: CommentModel = new CommentModel({
|
||||
id: 2,
|
||||
message: '2nd Test Comment',
|
||||
created: new Date().toDateString(),
|
||||
createdBy: {
|
||||
id: '1',
|
||||
firstName: 'Test',
|
||||
lastName: 'User',
|
||||
email: 'tu@domain.com'
|
||||
}
|
||||
});
|
||||
|
||||
describe('CommentListComponent', () => {
|
||||
|
||||
let commentList: CommentListComponent;
|
||||
let fixture: ComponentFixture<CommentListComponent>;
|
||||
let element: HTMLElement;
|
||||
let ecmUserService: EcmUserService;
|
||||
let peopleProcessService: PeopleProcessService;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [
|
||||
CommentListComponent
|
||||
],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
providers: [
|
||||
DatePipe,
|
||||
PeopleProcessService,
|
||||
EcmUserService
|
||||
]
|
||||
}).compileComponents().then(() => {
|
||||
|
||||
fixture = TestBed.createComponent(CommentListComponent);
|
||||
ecmUserService = TestBed.get(EcmUserService);
|
||||
peopleProcessService = TestBed.get(PeopleProcessService);
|
||||
commentList = fixture.componentInstance;
|
||||
element = fixture.nativeElement;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
spyOn(ecmUserService, 'getUserProfileImage').and.returnValue('content-user-image');
|
||||
spyOn(peopleProcessService, 'getUserImage').and.returnValue('process-user-image');
|
||||
});
|
||||
|
||||
it('should emit row click event', async(() => {
|
||||
commentList.comments = [processCommentOne];
|
||||
|
||||
commentList.clickRow.subscribe(selectedComment => {
|
||||
expect(selectedComment.id).toEqual(1);
|
||||
expect(selectedComment.message).toEqual('Test Comment');
|
||||
expect(selectedComment.createdBy).toEqual(testUser);
|
||||
expect(selectedComment.created).toEqual(testDate.toDateString());
|
||||
expect(selectedComment.isSelected).toBeTruthy();
|
||||
});
|
||||
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
let comment = fixture.debugElement.query(By.css('#adf-comment-1'));
|
||||
comment.triggerEventHandler('click', null);
|
||||
});
|
||||
}));
|
||||
|
||||
it('should deselect the previous selected comment when a new one is clicked', async(() => {
|
||||
processCommentOne.isSelected = true;
|
||||
commentList.selectedComment = processCommentOne;
|
||||
commentList.comments = [processCommentOne, processCommentTwo];
|
||||
|
||||
commentList.clickRow.subscribe(selectedComment => {
|
||||
fixture.detectChanges();
|
||||
let commentSelectedList = fixture.nativeElement.querySelectorAll('.is-selected');
|
||||
expect(commentSelectedList.length).toBe(1);
|
||||
expect(commentSelectedList[0].textContent).toContain('2nd Test Comment');
|
||||
});
|
||||
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
let comment = fixture.debugElement.query(By.css('#adf-comment-2'));
|
||||
comment.triggerEventHandler('click', null);
|
||||
});
|
||||
}));
|
||||
|
||||
it('should not show comment list if no input is given', async(() => {
|
||||
fixture.detectChanges();
|
||||
|
||||
fixture.whenStable().then(() => {
|
||||
expect(fixture.nativeElement.querySelector('adf-datatable')).toBeNull();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should show comment message when input is given', async(() => {
|
||||
commentList.comments = [processCommentOne];
|
||||
fixture.detectChanges();
|
||||
|
||||
fixture.whenStable().then(() => {
|
||||
let elements = fixture.nativeElement.querySelectorAll('#comment-message');
|
||||
expect(elements.length).toBe(1);
|
||||
expect(elements[0].innerText).toBe(processCommentOne.message);
|
||||
expect(fixture.nativeElement.querySelector('#comment-message:empty')).toBeNull();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should show comment user when input is given', async(() => {
|
||||
commentList.comments = [processCommentOne];
|
||||
fixture.detectChanges();
|
||||
|
||||
fixture.whenStable().then(() => {
|
||||
let elements = fixture.nativeElement.querySelectorAll('#comment-user');
|
||||
expect(elements.length).toBe(1);
|
||||
expect(elements[0].innerText).toBe(processCommentOne.createdBy.firstName + ' ' + processCommentOne.createdBy.lastName);
|
||||
expect(fixture.nativeElement.querySelector('#comment-user:empty')).toBeNull();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should show comment date time when input is given', async(() => {
|
||||
commentList.comments = [processCommentOne];
|
||||
fixture.detectChanges();
|
||||
|
||||
fixture.whenStable().then(() => {
|
||||
let elements = fixture.nativeElement.querySelectorAll('#comment-time');
|
||||
expect(elements.length).toBe(1);
|
||||
expect(elements[0].innerText).toBe(commentList.transformDate(testDate.toDateString()));
|
||||
expect(fixture.nativeElement.querySelector('#comment-time:empty')).toBeNull();
|
||||
});
|
||||
}));
|
||||
|
||||
it('comment date time should start with Today when comment date is today', async(() => {
|
||||
commentList.comments = [processCommentOne];
|
||||
fixture.detectChanges();
|
||||
|
||||
fixture.whenStable().then(() => {
|
||||
element = fixture.nativeElement.querySelector('#comment-time');
|
||||
expect(element.innerText).toContain('Today');
|
||||
});
|
||||
}));
|
||||
|
||||
it('comment date time should start with Yesterday when comment date is yesterday', async(() => {
|
||||
processCommentOne.created = new Date((Date.now() - 24 * 3600 * 1000));
|
||||
commentList.comments = [processCommentOne];
|
||||
fixture.detectChanges();
|
||||
|
||||
fixture.whenStable().then(() => {
|
||||
element = fixture.nativeElement.querySelector('#comment-time');
|
||||
expect(element.innerText).toContain('Yesterday');
|
||||
});
|
||||
}));
|
||||
|
||||
it('comment date time should not start with Today/Yesterday when comment date is before yesterday', async(() => {
|
||||
processCommentOne.created = new Date((Date.now() - 24 * 3600 * 1000 * 2));
|
||||
commentList.comments = [processCommentOne];
|
||||
fixture.detectChanges();
|
||||
|
||||
fixture.whenStable().then(() => {
|
||||
element = fixture.nativeElement.querySelector('#comment-time');
|
||||
expect(element.innerText).not.toContain('Today');
|
||||
expect(element.innerText).not.toContain('Yesterday');
|
||||
});
|
||||
}));
|
||||
|
||||
it('should show user icon when input is given', async(() => {
|
||||
commentList.comments = [processCommentOne];
|
||||
fixture.detectChanges();
|
||||
|
||||
fixture.whenStable().then(() => {
|
||||
let elements = fixture.nativeElement.querySelectorAll('#comment-user-icon');
|
||||
expect(elements.length).toBe(1);
|
||||
expect(elements[0].innerText).toContain(commentList.getUserShortName(processCommentOne.createdBy));
|
||||
expect(fixture.nativeElement.querySelector('#comment-user-icon:empty')).toBeNull();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should return content picture when is a content user with a picture', async(() => {
|
||||
commentList.comments = [contentCommentUserPictureDefined];
|
||||
fixture.detectChanges();
|
||||
|
||||
fixture.whenStable().then(() => {
|
||||
let elements = fixture.nativeElement.querySelectorAll('.adf-people-img');
|
||||
expect(elements.length).toBe(1);
|
||||
expect(fixture.nativeElement.getElementsByClassName('adf-people-img')[0].src).toContain('content-user-image');
|
||||
});
|
||||
}));
|
||||
|
||||
it('should return process picture when is a process user with a picture', async(() => {
|
||||
commentList.comments = [processCommentUserPictureDefined];
|
||||
fixture.detectChanges();
|
||||
|
||||
fixture.whenStable().then(() => {
|
||||
let elements = fixture.nativeElement.querySelectorAll('.adf-people-img');
|
||||
expect(elements.length).toBe(1);
|
||||
expect(fixture.nativeElement.getElementsByClassName('adf-people-img')[0].src).toContain('process-user-image');
|
||||
});
|
||||
}));
|
||||
|
||||
it('should return content short name when is a content user without a picture', async(() => {
|
||||
commentList.comments = [contentCommentUserNoPictureDefined];
|
||||
fixture.detectChanges();
|
||||
|
||||
fixture.whenStable().then(() => {
|
||||
let elements = fixture.nativeElement.querySelectorAll('.adf-comment-user-icon');
|
||||
expect(elements.length).toBe(1);
|
||||
});
|
||||
}));
|
||||
|
||||
it('should return process short name when is a process user without a picture', async(() => {
|
||||
commentList.comments = [processCommentUserNoPictureDefined];
|
||||
fixture.detectChanges();
|
||||
|
||||
fixture.whenStable().then(() => {
|
||||
let elements = fixture.nativeElement.querySelectorAll('.adf-comment-user-icon');
|
||||
expect(elements.length).toBe(1);
|
||||
});
|
||||
}));
|
||||
});
|
101
lib/core/comments/comment-list.component.ts
Normal file
101
lib/core/comments/comment-list.component.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
/*!
|
||||
* @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, Output, ViewEncapsulation } from '@angular/core';
|
||||
import { CommentModel } from '../models/comment.model';
|
||||
import { EcmUserService } from '../userinfo/services/ecm-user.service';
|
||||
import { PeopleProcessService } from '../services/people-process.service';
|
||||
import { DatePipe } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-comment-list',
|
||||
templateUrl: './comment-list.component.html',
|
||||
styleUrls: ['./comment-list.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
|
||||
export class CommentListComponent {
|
||||
|
||||
/** The comments data used to populate the list. */
|
||||
@Input()
|
||||
comments: CommentModel[];
|
||||
|
||||
/** Emitted when the user clicks on one of the comment rows. */
|
||||
@Output()
|
||||
clickRow: EventEmitter<CommentModel> = new EventEmitter<CommentModel>();
|
||||
|
||||
selectedComment: CommentModel;
|
||||
|
||||
constructor(private datePipe: DatePipe, public peopleProcessService: PeopleProcessService,
|
||||
public ecmUserService: EcmUserService) {
|
||||
}
|
||||
|
||||
selectComment(comment: CommentModel): void {
|
||||
if (this.selectedComment) {
|
||||
this.selectedComment.isSelected = false;
|
||||
}
|
||||
comment.isSelected = true;
|
||||
this.selectedComment = comment;
|
||||
this.clickRow.emit(this.selectedComment);
|
||||
}
|
||||
|
||||
getUserShortName(user: any): string {
|
||||
let shortName = '';
|
||||
if (user) {
|
||||
if (user.firstName) {
|
||||
shortName = user.firstName[0].toUpperCase();
|
||||
}
|
||||
if (user.lastName) {
|
||||
shortName += user.lastName[0].toUpperCase();
|
||||
}
|
||||
}
|
||||
return shortName;
|
||||
}
|
||||
|
||||
isPictureDefined(user: any): boolean {
|
||||
return user.pictureId || user.avatarId;
|
||||
}
|
||||
|
||||
getUserImage(user: any): string {
|
||||
if (this.isAContentUsers(user)) {
|
||||
return this.ecmUserService.getUserProfileImage(user.avatarId);
|
||||
} else {
|
||||
return this.peopleProcessService.getUserImage(user);
|
||||
}
|
||||
}
|
||||
|
||||
transformDate(aDate: string): string {
|
||||
let formattedDate: string;
|
||||
let givenDate = Number.parseInt(this.datePipe.transform(aDate, 'yMMdd'));
|
||||
let today = Number.parseInt(this.datePipe.transform(Date.now(), 'yMMdd'));
|
||||
if (givenDate === today) {
|
||||
formattedDate = 'Today, ' + this.datePipe.transform(aDate, 'hh:mm a');
|
||||
} else {
|
||||
let yesterday = Number.parseInt(this.datePipe.transform(Date.now() - 24 * 3600 * 1000, 'yMMdd'));
|
||||
if (givenDate === yesterday) {
|
||||
formattedDate = 'Yesterday, ' + this.datePipe.transform(aDate, 'hh:mm a');
|
||||
} else {
|
||||
formattedDate = this.datePipe.transform(aDate, 'MMM dd y, hh:mm a');
|
||||
}
|
||||
}
|
||||
return formattedDate;
|
||||
}
|
||||
|
||||
private isAContentUsers(user: any): boolean {
|
||||
return user.avatarId;
|
||||
}
|
||||
}
|
15
lib/core/comments/comments.component.html
Normal file
15
lib/core/comments/comments.component.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<div class="adf-comments-container">
|
||||
<div id="comment-header" class="adf-comments-header">
|
||||
{{'ADF_TASK_LIST.DETAILS.COMMENTS.HEADER' | translate: { count: comments?.length} }}
|
||||
</div>
|
||||
<div class="adf-comments-input-container" *ngIf="!isReadOnly()">
|
||||
<mat-form-field class="adf-full-width">
|
||||
<input matInput id="comment-input" placeholder="{{'ADF_TASK_LIST.DETAILS.COMMENTS.ADD' | translate}}" [(ngModel)]="message" (keyup.enter)="add()" (keyup.esc)="clear()">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div *ngIf="comments.length > 0">
|
||||
<adf-comment-list [comments]="comments">
|
||||
</adf-comment-list>
|
||||
</div>
|
||||
</div>
|
36
lib/core/comments/comments.component.scss
Normal file
36
lib/core/comments/comments.component.scss
Normal file
@@ -0,0 +1,36 @@
|
||||
@mixin adf-task-list-comment-theme($theme) {
|
||||
$foreground: map-get($theme, foreground);
|
||||
$header-border: 1px solid mat-color($foreground, divider);
|
||||
|
||||
.adf-comments-container {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.adf-comments-header {
|
||||
padding: 10px 20px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
border-bottom: $header-border;
|
||||
}
|
||||
|
||||
.adf-comments-input-container {
|
||||
padding: 0 15px;
|
||||
width: calc(100% - 30px);
|
||||
padding-top: 8px;
|
||||
border-bottom: $header-border;
|
||||
}
|
||||
|
||||
.adf-full-width {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
adf-comment-list {
|
||||
float: left;
|
||||
overflow: auto;
|
||||
height: calc(100% - 101px);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
}
|
344
lib/core/comments/comments.component.spec.ts
Normal file
344
lib/core/comments/comments.component.spec.ts
Normal file
@@ -0,0 +1,344 @@
|
||||
/*!
|
||||
* @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 { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { SimpleChange } from '@angular/core';
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { CommentProcessService } from '../services/comment-process.service';
|
||||
import { DatePipe } from '@angular/common';
|
||||
import { PeopleProcessService } from '../services/people-process.service';
|
||||
import { CommentListComponent } from './comment-list.component';
|
||||
import { CommentsComponent } from './comments.component';
|
||||
import { CommentContentService } from '../services/comment-content.service';
|
||||
import { EcmUserService } from '../userinfo/services/ecm-user.service';
|
||||
|
||||
describe('CommentsComponent', () => {
|
||||
|
||||
let component: CommentsComponent;
|
||||
let fixture: ComponentFixture<CommentsComponent>;
|
||||
let getProcessCommentsSpy: jasmine.Spy;
|
||||
let addProcessCommentSpy: jasmine.Spy;
|
||||
let addContentCommentSpy: jasmine.Spy;
|
||||
let getContentCommentsSpy: jasmine.Spy;
|
||||
let commentProcessService: CommentProcessService;
|
||||
let commentContentService: CommentContentService;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
],
|
||||
declarations: [
|
||||
CommentsComponent,
|
||||
CommentListComponent
|
||||
],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
providers: [
|
||||
DatePipe,
|
||||
PeopleProcessService,
|
||||
CommentProcessService,
|
||||
CommentContentService,
|
||||
EcmUserService
|
||||
]
|
||||
}).compileComponents();
|
||||
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(CommentsComponent);
|
||||
component = fixture.componentInstance;
|
||||
|
||||
commentProcessService = fixture.debugElement.injector.get(CommentProcessService);
|
||||
commentContentService = fixture.debugElement.injector.get(CommentContentService);
|
||||
|
||||
addContentCommentSpy = spyOn(commentContentService, 'addNodeComment').and.returnValue(Observable.of({
|
||||
id: 123,
|
||||
message: 'Test Comment',
|
||||
createdBy: {id: '999'}
|
||||
}));
|
||||
|
||||
getContentCommentsSpy = spyOn(commentContentService, 'getNodeComments').and.returnValue(Observable.of([
|
||||
{message: 'Test1', created: Date.now(), createdBy: {firstName: 'Admin', lastName: 'User'}},
|
||||
{message: 'Test2', created: Date.now(), createdBy: {firstName: 'Admin', lastName: 'User'}},
|
||||
{message: 'Test3', created: Date.now(), createdBy: {firstName: 'Admin', lastName: 'User'}}
|
||||
]));
|
||||
|
||||
getProcessCommentsSpy = spyOn(commentProcessService, 'getTaskComments').and.returnValue(Observable.of([
|
||||
{message: 'Test1', created: Date.now(), createdBy: {firstName: 'Admin', lastName: 'User'}},
|
||||
{message: 'Test2', created: Date.now(), createdBy: {firstName: 'Admin', lastName: 'User'}},
|
||||
{message: 'Test3', created: Date.now(), createdBy: {firstName: 'Admin', lastName: 'User'}}
|
||||
]));
|
||||
addProcessCommentSpy = spyOn(commentProcessService, 'addTaskComment').and.returnValue(Observable.of({
|
||||
id: 123,
|
||||
message: 'Test Comment',
|
||||
createdBy: {id: '999'}
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
it('should load comments when taskId specified', () => {
|
||||
let change = new SimpleChange(null, '123', true);
|
||||
component.ngOnChanges({'taskId': change});
|
||||
|
||||
expect(getProcessCommentsSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should load comments when nodeId specified', () => {
|
||||
let change = new SimpleChange(null, '123', true);
|
||||
component.ngOnChanges({'nodeId': change});
|
||||
|
||||
expect(getContentCommentsSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should emit an error when an error occurs loading comments', () => {
|
||||
let emitSpy = spyOn(component.error, 'emit');
|
||||
getProcessCommentsSpy.and.returnValue(Observable.throw({}));
|
||||
|
||||
let change = new SimpleChange(null, '123', true);
|
||||
component.ngOnChanges({'taskId': change});
|
||||
|
||||
expect(emitSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not load comments when no taskId is specified', () => {
|
||||
fixture.detectChanges();
|
||||
expect(getProcessCommentsSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should display comments when the task has comments', async(() => {
|
||||
let change = new SimpleChange(null, '123', true);
|
||||
component.ngOnChanges({'taskId': change});
|
||||
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.nativeElement.querySelectorAll('#comment-message').length).toBe(3);
|
||||
expect(fixture.nativeElement.querySelector('#comment-message:empty')).toBeNull();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should display comments count when the task has comments', async(() => {
|
||||
let change = new SimpleChange(null, '123', true);
|
||||
component.ngOnChanges({'taskId': change});
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
let element = fixture.nativeElement.querySelector('#comment-header');
|
||||
expect(element.innerText).toBe('ADF_TASK_LIST.DETAILS.COMMENTS.HEADER');
|
||||
});
|
||||
}));
|
||||
|
||||
it('should not display comments when the task has no comments', async(() => {
|
||||
component.taskId = '123';
|
||||
getProcessCommentsSpy.and.returnValue(Observable.of([]));
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.nativeElement.querySelector('#comment-container')).toBeNull();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should display comments input by default', async(() => {
|
||||
let change = new SimpleChange(null, '123', true);
|
||||
component.ngOnChanges({'taskId': change});
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.nativeElement.querySelector('#comment-input')).not.toBeNull();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should not display comments input when the task is readonly', async(() => {
|
||||
component.readOnly = true;
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(fixture.nativeElement.querySelector('#comment-input')).toBeNull();
|
||||
});
|
||||
}));
|
||||
|
||||
describe('change detection taskId', () => {
|
||||
|
||||
let change = new SimpleChange('123', '456', true);
|
||||
let nullChange = new SimpleChange('123', null, true);
|
||||
|
||||
beforeEach(async(() => {
|
||||
component.taskId = '123';
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
getProcessCommentsSpy.calls.reset();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should fetch new comments when taskId changed', () => {
|
||||
component.ngOnChanges({'taskId': change});
|
||||
expect(getProcessCommentsSpy).toHaveBeenCalledWith('456');
|
||||
});
|
||||
|
||||
it('should not fetch new comments when empty changeset made', () => {
|
||||
component.ngOnChanges({});
|
||||
expect(getProcessCommentsSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not fetch new comments when taskId changed to null', () => {
|
||||
component.ngOnChanges({'taskId': nullChange});
|
||||
expect(getProcessCommentsSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('change detection node', () => {
|
||||
|
||||
let change = new SimpleChange('123', '456', true);
|
||||
let nullChange = new SimpleChange('123', null, true);
|
||||
|
||||
beforeEach(async(() => {
|
||||
component.nodeId = '123';
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
getContentCommentsSpy.calls.reset();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should fetch new comments when nodeId changed', () => {
|
||||
component.ngOnChanges({'nodeId': change});
|
||||
expect(getContentCommentsSpy).toHaveBeenCalledWith('456');
|
||||
});
|
||||
|
||||
it('should not fetch new comments when empty changeset made', () => {
|
||||
component.ngOnChanges({});
|
||||
expect(getContentCommentsSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not fetch new comments when nodeId changed to null', () => {
|
||||
component.ngOnChanges({'nodeId': nullChange});
|
||||
expect(getContentCommentsSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Add comment task', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
component.taskId = '123';
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable();
|
||||
}));
|
||||
|
||||
it('should call service to add a comment when enter key is pressed', async(() => {
|
||||
let event = new KeyboardEvent('keyup', {'key': 'Enter'});
|
||||
let element = fixture.nativeElement.querySelector('#comment-input');
|
||||
component.message = 'Test Comment';
|
||||
element.dispatchEvent(event);
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(addProcessCommentSpy).toHaveBeenCalled();
|
||||
let elements = fixture.nativeElement.querySelectorAll('#comment-message');
|
||||
expect(elements.length).toBe(1);
|
||||
expect(elements[0].innerText).toBe('Test Comment');
|
||||
});
|
||||
}));
|
||||
|
||||
it('should not call service to add a comment when comment is empty', async(() => {
|
||||
let event = new KeyboardEvent('keyup', {'key': 'Enter'});
|
||||
let element = fixture.nativeElement.querySelector('#comment-input');
|
||||
component.message = '';
|
||||
element.dispatchEvent(event);
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(addProcessCommentSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should clear comment when escape key is pressed', async(() => {
|
||||
let event = new KeyboardEvent('keyup', {'key': 'Escape'});
|
||||
let element = fixture.nativeElement.querySelector('#comment-input');
|
||||
component.message = 'Test comment';
|
||||
element.dispatchEvent(event);
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
element = fixture.nativeElement.querySelector('#comment-input');
|
||||
expect(element.value).toBe('');
|
||||
});
|
||||
}));
|
||||
|
||||
it('should emit an error when an error occurs adding the comment', () => {
|
||||
let emitSpy = spyOn(component.error, 'emit');
|
||||
addProcessCommentSpy.and.returnValue(Observable.throw({}));
|
||||
component.message = 'Test comment';
|
||||
component.add();
|
||||
expect(emitSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('Add comment node', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
component.nodeId = '123';
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable();
|
||||
}));
|
||||
|
||||
it('should call service to add a comment when enter key is pressed', async(() => {
|
||||
let event = new KeyboardEvent('keyup', {'key': 'Enter'});
|
||||
let element = fixture.nativeElement.querySelector('#comment-input');
|
||||
component.message = 'Test Comment';
|
||||
element.dispatchEvent(event);
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(addContentCommentSpy).toHaveBeenCalled();
|
||||
let elements = fixture.nativeElement.querySelectorAll('#comment-message');
|
||||
expect(elements.length).toBe(1);
|
||||
expect(elements[0].innerText).toBe('Test Comment');
|
||||
});
|
||||
}));
|
||||
|
||||
it('should not call service to add a comment when comment is empty', async(() => {
|
||||
let event = new KeyboardEvent('keyup', {'key': 'Enter'});
|
||||
let element = fixture.nativeElement.querySelector('#comment-input');
|
||||
component.message = '';
|
||||
element.dispatchEvent(event);
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
expect(addContentCommentSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
}));
|
||||
|
||||
it('should clear comment when escape key is pressed', async(() => {
|
||||
let event = new KeyboardEvent('keyup', {'key': 'Escape'});
|
||||
let element = fixture.nativeElement.querySelector('#comment-input');
|
||||
component.message = 'Test comment';
|
||||
element.dispatchEvent(event);
|
||||
fixture.detectChanges();
|
||||
fixture.whenStable().then(() => {
|
||||
fixture.detectChanges();
|
||||
element = fixture.nativeElement.querySelector('#comment-input');
|
||||
expect(element.value).toBe('');
|
||||
});
|
||||
}));
|
||||
|
||||
it('should emit an error when an error occurs adding the comment', () => {
|
||||
let emitSpy = spyOn(component.error, 'emit');
|
||||
addContentCommentSpy.and.returnValue(Observable.throw({}));
|
||||
component.message = 'Test comment';
|
||||
component.add();
|
||||
expect(emitSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
179
lib/core/comments/comments.component.ts
Normal file
179
lib/core/comments/comments.component.ts
Normal file
@@ -0,0 +1,179 @@
|
||||
/*!
|
||||
* @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 { CommentProcessService } from '../services/comment-process.service';
|
||||
import { CommentContentService } from '../services/comment-content.service';
|
||||
import { CommentModel } from '../models/comment.model';
|
||||
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { Observer } from 'rxjs/Observer';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-comments',
|
||||
templateUrl: './comments.component.html',
|
||||
styleUrls: ['./comments.component.scss']
|
||||
})
|
||||
export class CommentsComponent implements OnChanges {
|
||||
|
||||
/** The numeric ID of the task. */
|
||||
@Input()
|
||||
taskId: string;
|
||||
|
||||
/** The numeric ID of the node. */
|
||||
@Input()
|
||||
nodeId: string;
|
||||
|
||||
/** Are the comments read only? */
|
||||
@Input()
|
||||
readOnly: boolean = false;
|
||||
|
||||
/** Emitted when an error occurs while displaying/adding a comment. */
|
||||
@Output()
|
||||
error: EventEmitter<any> = new EventEmitter<any>();
|
||||
|
||||
comments: CommentModel [] = [];
|
||||
|
||||
private commentObserver: Observer<CommentModel>;
|
||||
comment$: Observable<CommentModel>;
|
||||
|
||||
message: string;
|
||||
|
||||
beingAdded: boolean = false;
|
||||
|
||||
constructor(private commentProcessService: CommentProcessService, private commentContentService: CommentContentService) {
|
||||
this.comment$ = new Observable<CommentModel>(observer => this.commentObserver = observer).share();
|
||||
this.comment$.subscribe((comment: CommentModel) => {
|
||||
this.comments.push(comment);
|
||||
});
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
this.taskId = null;
|
||||
this.nodeId = null;
|
||||
|
||||
this.taskId = changes['taskId'] ? changes['taskId'].currentValue : null;
|
||||
this.nodeId = changes['nodeId'] ? changes['nodeId'].currentValue : null;
|
||||
|
||||
if (this.taskId || this.nodeId) {
|
||||
this.getComments();
|
||||
} else {
|
||||
this.resetComments();
|
||||
}
|
||||
}
|
||||
|
||||
private getComments(): void {
|
||||
this.resetComments();
|
||||
if (this.isATask()) {
|
||||
this.commentProcessService.getTaskComments(this.taskId).subscribe(
|
||||
(res: CommentModel[]) => {
|
||||
if (res && res instanceof Array) {
|
||||
res = res.sort((comment1: CommentModel, comment2: CommentModel) => {
|
||||
let date1 = new Date(comment1.created);
|
||||
let date2 = new Date(comment2.created);
|
||||
return date1 > date2 ? -1 : date1 < date2 ? 1 : 0;
|
||||
});
|
||||
res.forEach((comment) => {
|
||||
this.commentObserver.next(comment);
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
(err) => {
|
||||
this.error.emit(err);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (this.isANode()) {
|
||||
this.commentContentService.getNodeComments(this.nodeId).subscribe(
|
||||
(res: CommentModel[]) => {
|
||||
if (res && res instanceof Array) {
|
||||
|
||||
res = res.sort((comment1: CommentModel, comment2: CommentModel) => {
|
||||
const date1 = new Date(comment1.created);
|
||||
const date2 = new Date(comment2.created);
|
||||
return date1 > date2 ? -1 : date1 < date2 ? 1 : 0;
|
||||
});
|
||||
res.forEach((comment) => {
|
||||
this.commentObserver.next(comment);
|
||||
});
|
||||
}
|
||||
},
|
||||
(err) => {
|
||||
this.error.emit(err);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private resetComments(): void {
|
||||
this.comments = [];
|
||||
}
|
||||
|
||||
add(): void {
|
||||
if (this.message && this.message.trim() && !this.beingAdded) {
|
||||
this.beingAdded = true;
|
||||
if (this.isATask()) {
|
||||
this.commentProcessService.addTaskComment(this.taskId, this.message)
|
||||
.subscribe(
|
||||
(res: CommentModel) => {
|
||||
this.comments.unshift(res);
|
||||
this.message = '';
|
||||
this.beingAdded = false;
|
||||
|
||||
},
|
||||
(err) => {
|
||||
this.error.emit(err);
|
||||
this.beingAdded = false;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (this.isANode()) {
|
||||
this.commentContentService.addNodeComment(this.nodeId, this.message)
|
||||
.subscribe(
|
||||
(res: CommentModel) => {
|
||||
this.comments.unshift(res);
|
||||
this.message = '';
|
||||
this.beingAdded = false;
|
||||
|
||||
},
|
||||
(err) => {
|
||||
this.error.emit(err);
|
||||
this.beingAdded = false;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clear(): void {
|
||||
this.message = '';
|
||||
}
|
||||
|
||||
isReadOnly(): boolean {
|
||||
return this.readOnly;
|
||||
}
|
||||
|
||||
isATask(): boolean {
|
||||
return this.taskId ? true : false;
|
||||
}
|
||||
|
||||
isANode(): boolean {
|
||||
return this.nodeId ? true : false;
|
||||
}
|
||||
}
|
49
lib/core/comments/comments.module.ts
Normal file
49
lib/core/comments/comments.module.ts
Normal 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 { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { MaterialModule } from '../material.module';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { DataColumnModule } from '../data-column/data-column.module';
|
||||
import { DataTableModule } from '../datatable/datatable.module';
|
||||
|
||||
import { CommentListComponent } from './comment-list.component';
|
||||
import { CommentsComponent } from './comments.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
DataColumnModule,
|
||||
DataTableModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
MaterialModule,
|
||||
CommonModule,
|
||||
TranslateModule
|
||||
],
|
||||
declarations: [
|
||||
CommentListComponent,
|
||||
CommentsComponent
|
||||
],
|
||||
exports: [
|
||||
CommentListComponent,
|
||||
CommentsComponent
|
||||
]
|
||||
})
|
||||
export class CommentsModule {
|
||||
}
|
18
lib/core/comments/index.ts
Normal file
18
lib/core/comments/index.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
/*!
|
||||
* @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 './public-api';
|
19
lib/core/comments/public-api.ts
Normal file
19
lib/core/comments/public-api.ts
Normal file
@@ -0,0 +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.
|
||||
*/
|
||||
|
||||
export * from './comment-list.component';
|
||||
export * from './comments.component';
|
@@ -39,6 +39,7 @@ import { ViewerModule } from './viewer/viewer.module';
|
||||
import { FormModule } from './form/form.module';
|
||||
import { SidenavLayoutModule } from './sidenav-layout/sidenav-layout.module';
|
||||
import { SideBarActionModule } from './sidebar/sidebar-action.module';
|
||||
import { CommentsModule } from './comments/comments.module';
|
||||
|
||||
import { DirectiveModule } from './directives/directive.module';
|
||||
import { PipeModule } from './pipes/pipe.module';
|
||||
@@ -52,6 +53,7 @@ import { AuthenticationService } from './services/authentication.service';
|
||||
import { CardItemTypeService } from './card-view/services/card-item-types.service';
|
||||
import { CardViewUpdateService } from './card-view/services/card-view-update.service';
|
||||
import { CommentProcessService } from './services/comment-process.service';
|
||||
import { CommentContentService } from './services/comment-content.service';
|
||||
import { ContentService } from './services/content.service';
|
||||
import { CookieService } from './services/cookie.service';
|
||||
import { DeletedNodesApiService } from './services/deleted-nodes-api.service';
|
||||
@@ -116,6 +118,7 @@ export function providers() {
|
||||
SitesService,
|
||||
DiscoveryApiService,
|
||||
CommentProcessService,
|
||||
CommentContentService,
|
||||
SearchConfigurationService
|
||||
];
|
||||
}
|
||||
@@ -141,6 +144,7 @@ export function providers() {
|
||||
CardViewModule,
|
||||
CollapsableModule,
|
||||
FormModule,
|
||||
CommentsModule,
|
||||
LoginModule,
|
||||
LanguageMenuModule,
|
||||
InfoDrawerModule,
|
||||
@@ -174,6 +178,7 @@ export function providers() {
|
||||
CardViewModule,
|
||||
CollapsableModule,
|
||||
FormModule,
|
||||
CommentsModule,
|
||||
LoginModule,
|
||||
LanguageMenuModule,
|
||||
InfoDrawerModule,
|
||||
@@ -206,6 +211,7 @@ export class CoreModuleLazy {
|
||||
CardViewModule,
|
||||
CollapsableModule,
|
||||
FormModule,
|
||||
CommentsModule,
|
||||
LoginModule,
|
||||
LanguageMenuModule,
|
||||
InfoDrawerModule,
|
||||
@@ -239,6 +245,7 @@ export class CoreModuleLazy {
|
||||
CardViewModule,
|
||||
CollapsableModule,
|
||||
FormModule,
|
||||
CommentsModule,
|
||||
LoginModule,
|
||||
LanguageMenuModule,
|
||||
InfoDrawerModule,
|
||||
|
@@ -35,6 +35,7 @@ export * from './form/form.module';
|
||||
export * from './sidenav-layout/sidenav-layout.module';
|
||||
export * from './pipes/pipe.module';
|
||||
export * from './directives/directive.module';
|
||||
export * from './comments/comments.module';
|
||||
|
||||
export * from './viewer';
|
||||
export * from './userinfo';
|
||||
@@ -53,6 +54,7 @@ export * from './card-view';
|
||||
export * from './app-config';
|
||||
export * from './form';
|
||||
export * from './sidenav-layout';
|
||||
export * from './comments';
|
||||
|
||||
export * from './pipes';
|
||||
export * from './services';
|
||||
|
90
lib/core/mock/comment-content-service.mock.ts
Normal file
90
lib/core/mock/comment-content-service.mock.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
/*!
|
||||
* @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 let fakeUser1 = {
|
||||
'enabled': true,
|
||||
'firstName': 'firstName',
|
||||
'lastName': 'lastName',
|
||||
'email': 'fake-email@dom.com',
|
||||
'emailNotificationsEnabled': true,
|
||||
'company': {},
|
||||
'id': 'fake-email@dom.com',
|
||||
'avatarId': '123-123-123'
|
||||
};
|
||||
|
||||
export let fakeUser2 = {
|
||||
'enabled': true,
|
||||
'firstName': 'some',
|
||||
'lastName': 'one',
|
||||
'email': 'some-one@somegroup.com',
|
||||
'emailNotificationsEnabled': true,
|
||||
'company': {},
|
||||
'id': 'fake-email@dom.com',
|
||||
'avatarId': '001-001-001'
|
||||
};
|
||||
|
||||
export let fakeContentComments = {
|
||||
list: {
|
||||
'pagination': {
|
||||
'count': 4,
|
||||
'hasMoreItems': false,
|
||||
'totalItems': 4,
|
||||
'skipCount': 0,
|
||||
'maxItems': 100
|
||||
},
|
||||
entries: [{
|
||||
'entry': {
|
||||
'createdAt': '2018-03-27T10:55:45.725+0000',
|
||||
'createdBy': fakeUser1,
|
||||
'edited': false,
|
||||
'modifiedAt': '2018-03-27T10:55:45.725+0000',
|
||||
'canEdit': true,
|
||||
'modifiedBy': fakeUser1,
|
||||
'canDelete': true,
|
||||
'id': '35a0cea7-b6d0-4abc-9030-f4e461dd1ac7',
|
||||
'content': 'fake-message-1'
|
||||
}
|
||||
}, {
|
||||
'entry': {
|
||||
'createdAt': '2018-03-27T10:55:45.725+0000',
|
||||
'createdBy': fakeUser2,
|
||||
'edited': false,
|
||||
'modifiedAt': '2018-03-27T10:55:45.725+0000',
|
||||
'canEdit': true,
|
||||
'modifiedBy': fakeUser2,
|
||||
'canDelete': true,
|
||||
'id': '35a0cea7-b6d0-4abc-9030-f4e461dd1ac7',
|
||||
'content': 'fake-message-2'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
export let fakeContentComment = {
|
||||
'entry': {
|
||||
'createdAt': '2018-03-29T11:49:51.735+0000',
|
||||
'createdBy': fakeUser1,
|
||||
'edited': false,
|
||||
'modifiedAt': '2018-03-29T11:49:51.735+0000',
|
||||
'canEdit': true,
|
||||
'modifiedBy': fakeUser1,
|
||||
'canDelete': true,
|
||||
'id': '4d07cdc5-f00c-4391-b39d-a842b12478b2',
|
||||
'content': 'fake-comment-message'
|
||||
}
|
||||
};
|
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { CommentProcessModel } from '../models/comment-process.model';
|
||||
import { CommentModel } from '../models/comment.model';
|
||||
import { UserProcessModel } from '../models/user-process.model';
|
||||
|
||||
export let fakeUser1 = { id: 1, email: 'fake-email@dom.com', firstName: 'firstName', lastName: 'lastName' };
|
||||
@@ -34,7 +34,7 @@ export let fakeTasksComment = {
|
||||
]
|
||||
};
|
||||
|
||||
export let fakeProcessComment = new CommentProcessModel({id: 1, message: 'Test', created: new Date('2016-11-10T03:37:30.010+0000'), createdBy: new UserProcessModel({
|
||||
export let fakeProcessComment = new CommentModel({id: 1, message: 'Test', created: new Date('2016-11-10T03:37:30.010+0000'), createdBy: new UserProcessModel({
|
||||
id: 13,
|
||||
firstName: 'Wilbur',
|
||||
lastName: 'Adams',
|
||||
|
@@ -17,6 +17,11 @@
|
||||
|
||||
import { CommentRepresentation, LightUserRepresentation } from 'alfresco-js-api';
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* CommentProcessModel
|
||||
* (this model is deprecated in 2.3.0 in favour of CommentModel and will be removed in future revisions)
|
||||
*/
|
||||
export class CommentProcessModel implements CommentRepresentation {
|
||||
id: number;
|
||||
message: string;
|
||||
|
34
lib/core/models/comment.model.ts
Normal file
34
lib/core/models/comment.model.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
/*!
|
||||
* @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 CommentModel {
|
||||
id: number;
|
||||
message: string;
|
||||
created: Date;
|
||||
createdBy: any;
|
||||
isSelected: boolean;
|
||||
|
||||
constructor(obj?: any) {
|
||||
if (obj) {
|
||||
this.id = obj.id;
|
||||
this.message = obj.message;
|
||||
this.created = obj.created;
|
||||
this.createdBy = obj.createdBy;
|
||||
this.isSelected = obj.isSelected ? obj.isSelected : false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -19,6 +19,7 @@ export * from './file.model';
|
||||
export * from './permissions.enum';
|
||||
export * from './product-version.model';
|
||||
export * from './user-process.model';
|
||||
export * from './comment-process.model';
|
||||
export * from './comment.model';
|
||||
export * from './ecm-company.model';
|
||||
export * from './redirection.model';
|
||||
export * from './comment-process.model';
|
||||
|
91
lib/core/services/comment-content.service.spec.ts
Normal file
91
lib/core/services/comment-content.service.spec.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
/*!
|
||||
* @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 { CommentModel } from '../models/comment.model';
|
||||
import { fakeContentComment, fakeContentComments } from '../mock/comment-content-service.mock';
|
||||
import { CommentContentService } from './comment-content.service';
|
||||
import { LogService } from './log.service';
|
||||
import { StorageService } from './storage.service';
|
||||
|
||||
declare let jasmine: any;
|
||||
describe('Comment Content Service', () => {
|
||||
|
||||
let service: CommentContentService;
|
||||
|
||||
beforeEach((() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [
|
||||
CommentContentService,
|
||||
StorageService,
|
||||
LogService
|
||||
]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
service = TestBed.get(CommentContentService);
|
||||
|
||||
jasmine.Ajax.install();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jasmine.Ajax.uninstall();
|
||||
});
|
||||
|
||||
describe('Node comments', () => {
|
||||
|
||||
it('should add a comment node ', (done) => {
|
||||
service.addNodeComment('999', 'fake-comment-message').subscribe(
|
||||
(res: CommentModel) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.id).not.toEqual(null);
|
||||
expect(res.message).toEqual('fake-comment-message');
|
||||
expect(res.created).not.toEqual(null);
|
||||
expect(res.createdBy.email).toEqual('fake-email@dom.com');
|
||||
expect(res.createdBy.firstName).toEqual('firstName');
|
||||
expect(res.createdBy.lastName).toEqual('lastName');
|
||||
done();
|
||||
}
|
||||
);
|
||||
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
'status': 200,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify(fakeContentComment)
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the nodes comments ', (done) => {
|
||||
service.getNodeComments('999').subscribe(
|
||||
(res: CommentModel[]) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.length).toEqual(2);
|
||||
expect(res[0].message).toEqual('fake-message-1');
|
||||
expect(res[1].message).toEqual('fake-message-2');
|
||||
done();
|
||||
}
|
||||
);
|
||||
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
'status': 200,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify(fakeContentComments)
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
67
lib/core/services/comment-content.service.ts
Normal file
67
lib/core/services/comment-content.service.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
/*!
|
||||
* @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 { Observable } from 'rxjs/Observable';
|
||||
import { CommentModel } from '../models/comment.model';
|
||||
import { AlfrescoApiService } from '../services/alfresco-api.service';
|
||||
import { LogService } from '../services/log.service';
|
||||
import 'rxjs/add/observable/fromPromise';
|
||||
import 'rxjs/add/operator/catch';
|
||||
import 'rxjs/add/observable/throw';
|
||||
|
||||
@Injectable()
|
||||
export class CommentContentService {
|
||||
|
||||
constructor(private apiService: AlfrescoApiService,
|
||||
private logService: LogService) {
|
||||
}
|
||||
|
||||
addNodeComment(nodeId: string, message: string): Observable<CommentModel> {
|
||||
return Observable.fromPromise(this.apiService.getInstance().core.commentsApi.addComment(nodeId, {content: message}))
|
||||
.map((response: any) => {
|
||||
return new CommentModel({
|
||||
id: response.entry.id,
|
||||
message: response.entry.content,
|
||||
created: response.entry.createdAt,
|
||||
createdBy: response.entry.createdBy
|
||||
});
|
||||
}).catch(err => this.handleError(err));
|
||||
}
|
||||
|
||||
getNodeComments(nodeId: string): Observable<CommentModel[]> {
|
||||
return Observable.fromPromise(this.apiService.getInstance().core.commentsApi.getComments(nodeId))
|
||||
.map((response: any) => {
|
||||
const comments: CommentModel[] = [];
|
||||
response.list.entries.forEach((comment: any) => {
|
||||
comments.push(new CommentModel({
|
||||
id: comment.entry.id,
|
||||
message: comment.entry.content,
|
||||
created: comment.entry.createdAt,
|
||||
createdBy: comment.entry.createdBy
|
||||
}));
|
||||
});
|
||||
return comments;
|
||||
}).catch(err => this.handleError(err));
|
||||
}
|
||||
|
||||
private handleError(error: any) {
|
||||
this.logService.error(error);
|
||||
return Observable.throw(error || 'Server error');
|
||||
}
|
||||
|
||||
}
|
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import { async, TestBed } from '@angular/core/testing';
|
||||
import { CommentProcessModel } from '../models';
|
||||
import { CommentModel } from '../models/comment.model';
|
||||
import { fakeProcessComment, fakeTasksComment, fakeUser1 } from '../mock/comment-process-service.mock';
|
||||
import { CommentProcessService } from './comment-process.service';
|
||||
import { AlfrescoApiService } from './alfresco-api.service';
|
||||
@@ -142,7 +142,7 @@ describe('Comment ProcessService Service', () => {
|
||||
|
||||
it('should add a comment task ', (done) => {
|
||||
service.addTaskComment('999', 'fake-comment-message').subscribe(
|
||||
(res: CommentProcessModel) => {
|
||||
(res: CommentModel) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.id).not.toEqual(null);
|
||||
expect(res.message).toEqual('fake-comment-message');
|
||||
@@ -167,7 +167,7 @@ describe('Comment ProcessService Service', () => {
|
||||
|
||||
it('should return the tasks comments ', (done) => {
|
||||
service.getTaskComments('999').subscribe(
|
||||
(res: CommentProcessModel[]) => {
|
||||
(res: CommentModel[]) => {
|
||||
expect(res).toBeDefined();
|
||||
expect(res.length).toEqual(2);
|
||||
expect(res[0].message).toEqual('fake-message-1');
|
||||
|
@@ -17,7 +17,7 @@
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { CommentProcessModel } from '../models/comment-process.model';
|
||||
import { CommentModel } from '../models/comment.model';
|
||||
import { UserProcessModel } from '../models/user-process.model';
|
||||
import { AlfrescoApiService } from './alfresco-api.service';
|
||||
import { LogService } from './log.service';
|
||||
@@ -32,47 +32,57 @@ export class CommentProcessService {
|
||||
private logService: LogService) {
|
||||
}
|
||||
|
||||
addTaskComment(taskId: string, message: string): Observable<CommentProcessModel> {
|
||||
addTaskComment(taskId: string, message: string): Observable<CommentModel> {
|
||||
return Observable.fromPromise(this.apiService.getInstance().activiti.taskApi.addTaskComment({message: message}, taskId))
|
||||
.map(res => res)
|
||||
.map((response: CommentProcessModel) => {
|
||||
return new CommentProcessModel({id: response.id, message: response.message, created: response.created, createdBy: response.createdBy});
|
||||
.map((response: CommentModel) => {
|
||||
return new CommentModel({
|
||||
id: response.id,
|
||||
message: response.message,
|
||||
created: response.created,
|
||||
createdBy: response.createdBy
|
||||
});
|
||||
}).catch(err => this.handleError(err));
|
||||
|
||||
}
|
||||
|
||||
getTaskComments(taskId: string): Observable<CommentProcessModel[]> {
|
||||
getTaskComments(taskId: string): Observable<CommentModel[]> {
|
||||
return Observable.fromPromise(this.apiService.getInstance().activiti.taskApi.getTaskComments(taskId))
|
||||
.map(res => res)
|
||||
.map((response: any) => {
|
||||
let comments: CommentProcessModel[] = [];
|
||||
response.data.forEach((comment: CommentProcessModel) => {
|
||||
let comments: CommentModel[] = [];
|
||||
response.data.forEach((comment: CommentModel) => {
|
||||
let user = new UserProcessModel(comment.createdBy);
|
||||
comments.push(new CommentProcessModel({id: comment.id, message: comment.message, created: comment.created, createdBy: user}));
|
||||
comments.push(new CommentModel({id: comment.id, message: comment.message, created: comment.created, createdBy: user}));
|
||||
});
|
||||
return comments;
|
||||
}).catch(err => this.handleError(err));
|
||||
}
|
||||
|
||||
getProcessInstanceComments(processInstanceId: string): Observable<CommentProcessModel[]> {
|
||||
getProcessInstanceComments(processInstanceId: string): Observable<CommentModel[]> {
|
||||
return Observable.fromPromise(this.apiService.getInstance().activiti.commentsApi.getProcessInstanceComments(processInstanceId))
|
||||
.map(res => res)
|
||||
.map((response: any) => {
|
||||
let comments: CommentProcessModel[] = [];
|
||||
response.data.forEach((comment: CommentProcessModel) => {
|
||||
let comments: CommentModel[] = [];
|
||||
response.data.forEach((comment: CommentModel) => {
|
||||
let user = new UserProcessModel(comment.createdBy);
|
||||
comments.push(new CommentProcessModel({id: comment.id, message: comment.message, created: comment.created, createdBy: user}));
|
||||
comments.push(new CommentModel({id: comment.id, message: comment.message, created: comment.created, createdBy: user}));
|
||||
});
|
||||
return comments;
|
||||
}).catch(err => this.handleError(err));
|
||||
}
|
||||
|
||||
addProcessInstanceComment(processInstanceId: string, message: string): Observable<CommentProcessModel> {
|
||||
addProcessInstanceComment(processInstanceId: string, message: string): Observable<CommentModel> {
|
||||
return Observable.fromPromise(
|
||||
this.apiService.getInstance().activiti.commentsApi.addProcessInstanceComment({ message: message }, processInstanceId)
|
||||
this.apiService.getInstance().activiti.commentsApi.addProcessInstanceComment({message: message}, processInstanceId)
|
||||
)
|
||||
.map((response: CommentProcessModel) => {
|
||||
return new CommentProcessModel({id: response.id, message: response.message, created: response.created, createdBy: response.createdBy});
|
||||
.map((response: CommentModel) => {
|
||||
return new CommentModel({
|
||||
id: response.id,
|
||||
message: response.message,
|
||||
created: response.created,
|
||||
createdBy: response.createdBy
|
||||
});
|
||||
}).catch(err => this.handleError(err));
|
||||
|
||||
}
|
||||
|
@@ -47,3 +47,4 @@ export * from './sites.service';
|
||||
export * from './discovery-api.service';
|
||||
export * from './comment-process.service';
|
||||
export * from './search-configuration.service';
|
||||
export * from './comment-content.service';
|
||||
|
@@ -23,6 +23,8 @@
|
||||
@import '../viewer/components/imgViewer.component';
|
||||
@import '../form/components/form.component';
|
||||
@import '../sidebar/sidebar-action-menu.component';
|
||||
@import '../comments/comment-list.component';
|
||||
@import '../comments/comments.component';
|
||||
|
||||
@mixin adf-core-theme($theme) {
|
||||
@include adf-colors-theme($theme);
|
||||
@@ -48,6 +50,8 @@
|
||||
@include adf-text-viewer-theme($theme);
|
||||
@include adf-form-component-theme($theme);
|
||||
@include adf-sidebar-action-menu-theme($theme);
|
||||
@include adf-task-list-comment-list-theme($theme);
|
||||
@include adf-task-list-comment-theme($theme);
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user